mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-23 00:21:26 +01:00
Initial commit
This commit is contained in:
commit
9380770492
18
build.gradle
Normal file
18
build.gradle
Normal file
@ -0,0 +1,18 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group 'fr.themode.minestom'
|
||||
version '1.0'
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testCompile group: 'junit', name: 'junit', version: '4.12'
|
||||
implementation 'com.github.Adamaq01:ozao-net:2.3.1'
|
||||
}
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
#Thu Aug 01 13:49:10 CEST 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip
|
172
gradlew
vendored
Normal file
172
gradlew
vendored
Normal file
@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
84
gradlew.bat
vendored
Normal file
84
gradlew.bat
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
2
settings.gradle
Normal file
2
settings.gradle
Normal file
@ -0,0 +1,2 @@
|
||||
rootProject.name = 'Minestom'
|
||||
|
61
src/main/java/fr/themode/minestom/Main.java
Normal file
61
src/main/java/fr/themode/minestom/Main.java
Normal file
@ -0,0 +1,61 @@
|
||||
package fr.themode.minestom;
|
||||
|
||||
import fr.adamaq01.ozao.net.packet.Packet;
|
||||
import fr.adamaq01.ozao.net.server.Connection;
|
||||
import fr.adamaq01.ozao.net.server.Server;
|
||||
import fr.adamaq01.ozao.net.server.ServerHandler;
|
||||
import fr.adamaq01.ozao.net.server.backend.tcp.TCPServer;
|
||||
import fr.themode.minestom.net.ConnectionManager;
|
||||
import fr.themode.minestom.net.PacketProcessor;
|
||||
import fr.themode.minestom.net.protocol.MinecraftProtocol;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class Main {
|
||||
|
||||
private static ConnectionManager connectionManager;
|
||||
private static PacketProcessor packetProcessor;
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
connectionManager = new ConnectionManager();
|
||||
packetProcessor = new PacketProcessor(connectionManager);
|
||||
|
||||
Server server = new TCPServer(new MinecraftProtocol()).addHandler(new ServerHandler() {
|
||||
@Override
|
||||
public void onConnect(Server server, Connection connection) {
|
||||
System.out.println("A connection");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect(Server server, Connection connection) {
|
||||
System.out.println("A DISCONNECTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(Server server, Connection connection, Packet packet) {
|
||||
try {
|
||||
packetProcessor.process(connection, packet);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(Server server, Connection connection, Throwable cause) {
|
||||
cause.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
server.bind(25565);
|
||||
System.out.println("Server started");
|
||||
|
||||
}
|
||||
|
||||
}
|
25
src/main/java/fr/themode/minestom/entity/GameMode.java
Normal file
25
src/main/java/fr/themode/minestom/entity/GameMode.java
Normal file
@ -0,0 +1,25 @@
|
||||
package fr.themode.minestom.entity;
|
||||
|
||||
public enum GameMode {
|
||||
|
||||
SURVIVAL((byte) 0), CREATIVE((byte) 1), ADVENTURE((byte) 2), SPECTATOR((byte) 3);
|
||||
|
||||
private byte id;
|
||||
private boolean hardcore;
|
||||
|
||||
GameMode(byte id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setHardcore(boolean hardcore) {
|
||||
this.hardcore = hardcore;
|
||||
}
|
||||
|
||||
public byte getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public boolean isHardcore() {
|
||||
return hardcore;
|
||||
}
|
||||
}
|
12
src/main/java/fr/themode/minestom/entity/Player.java
Normal file
12
src/main/java/fr/themode/minestom/entity/Player.java
Normal file
@ -0,0 +1,12 @@
|
||||
package fr.themode.minestom.entity;
|
||||
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
|
||||
public class Player {
|
||||
|
||||
private PlayerConnection playerConnection;
|
||||
|
||||
public PlayerConnection getPlayerConnection() {
|
||||
return playerConnection;
|
||||
}
|
||||
}
|
24
src/main/java/fr/themode/minestom/net/ConnectionManager.java
Normal file
24
src/main/java/fr/themode/minestom/net/ConnectionManager.java
Normal file
@ -0,0 +1,24 @@
|
||||
package fr.themode.minestom.net;
|
||||
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class ConnectionManager {
|
||||
|
||||
private Set<PlayerConnection> connections = new HashSet<>();
|
||||
private Map<PlayerConnection, Player> connectionPlayerMap = new HashMap<>();
|
||||
|
||||
public Player getPlayer(PlayerConnection connection) {
|
||||
return connectionPlayerMap.get(connection);
|
||||
}
|
||||
|
||||
// Is only used at LoginStartPacket#process
|
||||
public void createPlayer(PlayerConnection connection) {
|
||||
this.connectionPlayerMap.put(connection, new Player());
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package fr.themode.minestom.net;
|
||||
|
||||
public enum ConnectionState {
|
||||
|
||||
UNKNOWN, STATUS, LOGIN, PLAY;
|
||||
|
||||
}
|
80
src/main/java/fr/themode/minestom/net/PacketProcessor.java
Normal file
80
src/main/java/fr/themode/minestom/net/PacketProcessor.java
Normal file
@ -0,0 +1,80 @@
|
||||
package fr.themode.minestom.net;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.adamaq01.ozao.net.packet.Packet;
|
||||
import fr.adamaq01.ozao.net.server.Connection;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
||||
import fr.themode.minestom.net.packet.client.ClientPreplayPacket;
|
||||
import fr.themode.minestom.net.packet.client.handler.ClientLoginPacketsHandler;
|
||||
import fr.themode.minestom.net.packet.client.handler.ClientPlayPacketsHandler;
|
||||
import fr.themode.minestom.net.packet.client.handler.ClientStatusPacketsHandler;
|
||||
import fr.themode.minestom.net.packet.client.handshake.HandshakePacket;
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static fr.themode.minestom.net.protocol.MinecraftProtocol.PACKET_ID_IDENTIFIER;
|
||||
|
||||
public class PacketProcessor {
|
||||
|
||||
private Map<Connection, PlayerConnection> connectionPlayerConnectionMap = new HashMap<>();
|
||||
|
||||
private ConnectionManager connectionManager;
|
||||
|
||||
// Protocols
|
||||
private ClientStatusPacketsHandler statusPacketsHandler;
|
||||
private ClientLoginPacketsHandler loginPacketsHandler;
|
||||
private ClientPlayPacketsHandler playPacketsHandler;
|
||||
|
||||
public PacketProcessor(ConnectionManager connectionManager) {
|
||||
this.connectionManager = connectionManager;
|
||||
|
||||
this.statusPacketsHandler = new ClientStatusPacketsHandler();
|
||||
this.loginPacketsHandler = new ClientLoginPacketsHandler();
|
||||
this.playPacketsHandler = new ClientPlayPacketsHandler();
|
||||
}
|
||||
|
||||
public void process(Connection connection, Packet packet) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
int id = packet.get(PACKET_ID_IDENTIFIER);
|
||||
System.out.println("RECEIVED ID: " + id);
|
||||
Buffer buffer = packet.getPayload();
|
||||
connectionPlayerConnectionMap.get(connection);
|
||||
PlayerConnection playerConnection = connectionPlayerConnectionMap.computeIfAbsent(connection, c -> new PlayerConnection(c));
|
||||
ConnectionState connectionState = playerConnection.getConnectionState();
|
||||
|
||||
if (connectionState == ConnectionState.UNKNOWN) {
|
||||
// Should be handshake packet
|
||||
if (id == 0) {
|
||||
HandshakePacket handshakePacket = new HandshakePacket();
|
||||
handshakePacket.read(buffer);
|
||||
handshakePacket.process(playerConnection, connectionManager);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (connectionState) {
|
||||
case PLAY:
|
||||
Player player = connectionManager.getPlayer(playerConnection);
|
||||
ClientPlayPacket playPacket = (ClientPlayPacket) playPacketsHandler.getPacketClass(id).getDeclaredConstructor().newInstance();
|
||||
playPacket.read(buffer);
|
||||
playPacket.process(player);
|
||||
break;
|
||||
case LOGIN:
|
||||
ClientPreplayPacket loginPacket = (ClientPreplayPacket) loginPacketsHandler.getPacketClass(id).getDeclaredConstructor().newInstance();
|
||||
loginPacket.read(buffer);
|
||||
loginPacket.process(playerConnection, connectionManager);
|
||||
break;
|
||||
case STATUS:
|
||||
ClientPreplayPacket statusPacket = (ClientPreplayPacket) statusPacketsHandler.getPacketClass(id).getDeclaredConstructor().newInstance();
|
||||
statusPacket.read(buffer);
|
||||
statusPacket.process(playerConnection, connectionManager);
|
||||
break;
|
||||
case UNKNOWN:
|
||||
// Ignore packet (unexpected)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package fr.themode.minestom.net.packet.client;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
|
||||
public interface ClientPacket {
|
||||
|
||||
void read(Buffer buffer);
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package fr.themode.minestom.net.packet.client;
|
||||
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.net.packet.client.ClientPacket;
|
||||
|
||||
public interface ClientPlayPacket extends ClientPacket {
|
||||
|
||||
void process(Player player);
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package fr.themode.minestom.net.packet.client;
|
||||
|
||||
import fr.themode.minestom.net.ConnectionManager;
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
|
||||
public interface ClientPreplayPacket extends ClientPacket {
|
||||
|
||||
void process(PlayerConnection connection, ConnectionManager connectionManager);
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package fr.themode.minestom.net.packet.client.handler;
|
||||
|
||||
import fr.themode.minestom.net.packet.client.login.LoginStartPacket;
|
||||
|
||||
public class ClientLoginPacketsHandler extends ClientPacketsHandler {
|
||||
|
||||
public ClientLoginPacketsHandler() {
|
||||
register(0, LoginStartPacket.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package fr.themode.minestom.net.packet.client.handler;
|
||||
|
||||
import fr.themode.minestom.net.packet.client.ClientPacket;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ClientPacketsHandler {
|
||||
|
||||
private Map<Integer, Class<? extends ClientPacket>> idPacketMap = new HashMap<>();
|
||||
|
||||
public void register(int id, Class<? extends ClientPacket> packet) {
|
||||
this.idPacketMap.put(id, packet);
|
||||
}
|
||||
|
||||
public Class<? extends ClientPacket> getPacketClass(int id) {
|
||||
return idPacketMap.get(id);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package fr.themode.minestom.net.packet.client.handler;
|
||||
|
||||
import fr.themode.minestom.net.packet.client.play.ClientPluginMessagePacket;
|
||||
import fr.themode.minestom.net.packet.client.play.ClientSettingsPacket;
|
||||
|
||||
public class ClientPlayPacketsHandler extends ClientPacketsHandler {
|
||||
|
||||
public ClientPlayPacketsHandler() {
|
||||
register(0x05, ClientSettingsPacket.class);
|
||||
register(0x0B, ClientPluginMessagePacket.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package fr.themode.minestom.net.packet.client.handler;
|
||||
|
||||
import fr.themode.minestom.net.packet.client.status.PingPacket;
|
||||
import fr.themode.minestom.net.packet.client.status.StatusRequestPacket;
|
||||
|
||||
public class ClientStatusPacketsHandler extends ClientPacketsHandler {
|
||||
|
||||
public ClientStatusPacketsHandler() {
|
||||
register(0x00, StatusRequestPacket.class);
|
||||
register(0x01, PingPacket.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package fr.themode.minestom.net.packet.client.handshake;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.net.ConnectionManager;
|
||||
import fr.themode.minestom.net.ConnectionState;
|
||||
import fr.themode.minestom.net.packet.client.ClientPreplayPacket;
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
|
||||
import static fr.themode.minestom.utils.Utils.readString;
|
||||
import static fr.themode.minestom.utils.Utils.readVarInt;
|
||||
|
||||
public class HandshakePacket implements ClientPreplayPacket {
|
||||
|
||||
private int nextState;
|
||||
|
||||
@Override
|
||||
public void read(Buffer buffer) {
|
||||
int protocolVersion = readVarInt(buffer);
|
||||
String serverAddress = readString(buffer);
|
||||
short serverPort = buffer.getShort();
|
||||
this.nextState = readVarInt(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(PlayerConnection connection, ConnectionManager connectionManager) {
|
||||
switch (nextState) {
|
||||
case 1:
|
||||
connection.setConnectionState(ConnectionState.STATUS);
|
||||
break;
|
||||
case 2:
|
||||
connection.setConnectionState(ConnectionState.LOGIN);
|
||||
break;
|
||||
default:
|
||||
// Unexpected error
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package fr.themode.minestom.net.packet.client.login;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.entity.GameMode;
|
||||
import fr.themode.minestom.net.ConnectionManager;
|
||||
import fr.themode.minestom.net.ConnectionState;
|
||||
import fr.themode.minestom.net.packet.client.ClientPreplayPacket;
|
||||
import fr.themode.minestom.net.packet.server.login.JoinGamePacket;
|
||||
import fr.themode.minestom.net.packet.server.login.LoginSuccessPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.SpawnPositionPacket;
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
import fr.themode.minestom.world.Dimension;
|
||||
|
||||
public class LoginStartPacket implements ClientPreplayPacket {
|
||||
|
||||
private String username;
|
||||
|
||||
@Override
|
||||
public void process(PlayerConnection connection, ConnectionManager connectionManager) {
|
||||
// TODO send encryption request OR directly login success
|
||||
LoginSuccessPacket successPacket = new LoginSuccessPacket(username);
|
||||
connection.sendPacket(successPacket);
|
||||
|
||||
connection.setConnectionState(ConnectionState.PLAY);
|
||||
connectionManager.createPlayer(connection);
|
||||
|
||||
// TODO complete login sequence with optionals packets
|
||||
JoinGamePacket joinGamePacket = new JoinGamePacket();
|
||||
joinGamePacket.entityId = 32;
|
||||
joinGamePacket.gameMode = GameMode.SURVIVAL;
|
||||
joinGamePacket.dimension = Dimension.OVERWORLD;
|
||||
joinGamePacket.maxPlayers = 0;
|
||||
joinGamePacket.levelType = "default";
|
||||
joinGamePacket.reducedDebugInfo = false;
|
||||
|
||||
connection.sendPacket(joinGamePacket);
|
||||
|
||||
// TODO minecraft:brand plugin message
|
||||
|
||||
// TODO send server difficulty
|
||||
|
||||
// TODO player abilities
|
||||
|
||||
SpawnPositionPacket spawnPositionPacket = new SpawnPositionPacket();
|
||||
spawnPositionPacket.x = 50;
|
||||
spawnPositionPacket.y = 50;
|
||||
spawnPositionPacket.z = 50;
|
||||
|
||||
// connection.sendPacket(spawnPositionPacket);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(Buffer buffer) {
|
||||
this.username = Utils.readString(buffer);
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package fr.themode.minestom.net.packet.client.play;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
|
||||
public class ClientPluginMessagePacket implements ClientPlayPacket {
|
||||
|
||||
private String identifier;
|
||||
private byte[] data;
|
||||
|
||||
@Override
|
||||
public void process(Player player) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(Buffer buffer) {
|
||||
this.identifier = Utils.readString(buffer);
|
||||
this.data = buffer.getAllBytes();
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package fr.themode.minestom.net.packet.client.play;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
|
||||
public class ClientSettingsPacket implements ClientPlayPacket {
|
||||
|
||||
private String locale;
|
||||
private byte viewDistance;
|
||||
// TODO chat mode
|
||||
private boolean chatColors;
|
||||
private byte displayedSkinParts;
|
||||
// TODO main hand
|
||||
|
||||
@Override
|
||||
public void process(Player player) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(Buffer buffer) {
|
||||
this.locale = Utils.readString(buffer);
|
||||
this.viewDistance = buffer.getByte();
|
||||
Utils.readVarInt(buffer); // chat mode
|
||||
this.chatColors = buffer.getBoolean();
|
||||
this.displayedSkinParts = buffer.getByte();
|
||||
Utils.readVarInt(buffer); // main hand
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package fr.themode.minestom.net.packet.client.play;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
||||
|
||||
public class TestPacket implements ClientPlayPacket {
|
||||
|
||||
@Override
|
||||
public void process(Player player) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(Buffer buffer) {
|
||||
System.out.println("Hey c'est moi");
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package fr.themode.minestom.net.packet.client.status;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.net.ConnectionManager;
|
||||
import fr.themode.minestom.net.packet.client.ClientPreplayPacket;
|
||||
import fr.themode.minestom.net.packet.server.status.PongPacket;
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
|
||||
public class PingPacket implements ClientPreplayPacket {
|
||||
|
||||
private long number;
|
||||
|
||||
@Override
|
||||
public void process(PlayerConnection connection, ConnectionManager connectionManager) {
|
||||
PongPacket pongPacket = new PongPacket(number);
|
||||
connection.sendPacket(pongPacket);
|
||||
connection.getConnection().close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(Buffer buffer) {
|
||||
this.number = buffer.getLong();
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package fr.themode.minestom.net.packet.client.status;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.net.ConnectionManager;
|
||||
import fr.themode.minestom.net.packet.client.ClientPreplayPacket;
|
||||
import fr.themode.minestom.net.packet.server.handshake.ResponsePacket;
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
|
||||
public class StatusRequestPacket implements ClientPreplayPacket {
|
||||
|
||||
@Override
|
||||
public void process(PlayerConnection connection, ConnectionManager connectionManager) {
|
||||
ResponsePacket responsePacket = new ResponsePacket();
|
||||
connection.sendPacket(responsePacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(Buffer buffer) {
|
||||
// Empty
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package fr.themode.minestom.net.packet.server;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
|
||||
public interface ServerPacket {
|
||||
|
||||
void write(Buffer buffer);
|
||||
|
||||
int getId();
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package fr.themode.minestom.net.packet.server.handshake;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
|
||||
public class ResponsePacket implements ServerPacket {
|
||||
|
||||
private static final String JSON_EXAMPLE = "{\n" +
|
||||
" \"version\": {\n" +
|
||||
" \"name\": \"1.14.4\",\n" +
|
||||
" \"protocol\": 498\n" +
|
||||
" },\n" +
|
||||
" \"players\": {\n" +
|
||||
" \"max\": 100,\n" +
|
||||
" \"online\": 1,\n" +
|
||||
" \"sample\": [\n" +
|
||||
" {\n" +
|
||||
" \"name\": \"TheMode\",\n" +
|
||||
" \"id\": \"4566e69f-c907-48ee-8d71-d7ba5aa00d20\"\n" +
|
||||
" }\n" +
|
||||
" ]\n" +
|
||||
" },\t\n" +
|
||||
" \"description\": {\n" +
|
||||
" \"text\": \"Wallah les cubes\"\n" +
|
||||
" },\n" +
|
||||
" \"favicon\": \"data:image/png;base64,<data>\"\n" +
|
||||
"}";
|
||||
|
||||
@Override
|
||||
public void write(Buffer buffer) {
|
||||
Utils.writeString(buffer, JSON_EXAMPLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x00;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package fr.themode.minestom.net.packet.server.login;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.entity.GameMode;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
import fr.themode.minestom.world.Dimension;
|
||||
|
||||
public class JoinGamePacket implements ServerPacket {
|
||||
|
||||
public int entityId;
|
||||
public GameMode gameMode = GameMode.SURVIVAL;
|
||||
public Dimension dimension = Dimension.OVERWORLD;
|
||||
public byte maxPlayers = 0; // Unused
|
||||
public String levelType = "default";
|
||||
public boolean reducedDebugInfo = false;
|
||||
|
||||
@Override
|
||||
public void write(Buffer buffer) {
|
||||
int gameModeId = gameMode.getId();
|
||||
if (gameMode.isHardcore())
|
||||
gameModeId |= 8;
|
||||
|
||||
buffer.putInt(entityId);
|
||||
buffer.putByte((byte) gameModeId);
|
||||
buffer.putInt(dimension.getId());
|
||||
buffer.putByte(maxPlayers);
|
||||
Utils.writeString(buffer, levelType);
|
||||
Utils.writeVarInt(buffer, 8);
|
||||
buffer.putBoolean(reducedDebugInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x25;
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package fr.themode.minestom.net.packet.server.login;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class LoginSuccessPacket implements ServerPacket {
|
||||
|
||||
public String username;
|
||||
|
||||
public LoginSuccessPacket(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Buffer buffer) {
|
||||
Utils.writeString(buffer, UUID.randomUUID().toString()); // TODO mojang auth
|
||||
Utils.writeString(buffer, username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x02;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package fr.themode.minestom.net.packet.server.play;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
|
||||
public class SpawnPositionPacket implements ServerPacket {
|
||||
|
||||
public int x, y, z;
|
||||
|
||||
@Override
|
||||
public void write(Buffer buffer) {
|
||||
Utils.writePosition(buffer, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x49;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package fr.themode.minestom.net.packet.server.play;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
|
||||
public class WindowItemsPacket implements ServerPacket {
|
||||
|
||||
public byte windowId;
|
||||
public short count;
|
||||
|
||||
// TODO slot data (Array of Slot)
|
||||
|
||||
@Override
|
||||
public void write(Buffer buffer) {
|
||||
buffer.putByte(windowId);
|
||||
buffer.putShort(count);
|
||||
// TODO replace with actual array of slot
|
||||
buffer.putBoolean(false); // Not present
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x15;
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package fr.themode.minestom.net.packet.server.status;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
|
||||
public class PongPacket implements ServerPacket {
|
||||
|
||||
public long number;
|
||||
|
||||
public PongPacket(long number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Buffer buffer) {
|
||||
buffer.putLong(number);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x01;
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package fr.themode.minestom.net.player;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.adamaq01.ozao.net.packet.Packet;
|
||||
import fr.adamaq01.ozao.net.server.Connection;
|
||||
import fr.themode.minestom.net.ConnectionState;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
|
||||
import static fr.themode.minestom.net.protocol.MinecraftProtocol.PACKET_ID_IDENTIFIER;
|
||||
|
||||
public class PlayerConnection {
|
||||
|
||||
private Connection connection;
|
||||
private ConnectionState connectionState;
|
||||
|
||||
public PlayerConnection(Connection connection) {
|
||||
this.connection = connection;
|
||||
this.connectionState = ConnectionState.UNKNOWN;
|
||||
}
|
||||
|
||||
public void sendPacket(ServerPacket serverPacket) {
|
||||
Packet packet = Packet.create();
|
||||
Buffer buffer = packet.getPayload();
|
||||
serverPacket.write(buffer);
|
||||
packet.put(PACKET_ID_IDENTIFIER, serverPacket.getId());
|
||||
|
||||
this.connection.sendPacket(packet);
|
||||
}
|
||||
|
||||
public Connection getConnection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
public void setConnectionState(ConnectionState connectionState) {
|
||||
this.connectionState = connectionState;
|
||||
}
|
||||
|
||||
public ConnectionState getConnectionState() {
|
||||
return connectionState;
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package fr.themode.minestom.net.protocol;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.adamaq01.ozao.net.packet.Packet;
|
||||
import fr.adamaq01.ozao.net.protocol.Protocol;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import static fr.themode.minestom.utils.Utils.readVarInt;
|
||||
import static fr.themode.minestom.utils.Utils.writeVarInt;
|
||||
|
||||
public class MinecraftProtocol extends Protocol {
|
||||
|
||||
public static final String PACKET_ID_IDENTIFIER = "id";
|
||||
|
||||
public MinecraftProtocol() {
|
||||
super("minecraft");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(Buffer buffer) {
|
||||
int length = readVarInt(buffer);
|
||||
int realLength = buffer.slice(buffer.readerIndex()).length();
|
||||
int id = readVarInt(buffer);
|
||||
buffer.readerIndex(0);
|
||||
return length == realLength && id >= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(Packet packet) {
|
||||
return packet.get("id") != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Buffer> cut(Buffer buffer) {
|
||||
ArrayList<Buffer> buffers = new ArrayList<>();
|
||||
int read = 0;
|
||||
while (read < buffer.length()) {
|
||||
int lengthLength = buffer.readerIndex(read).readerIndex();
|
||||
int length = readVarInt(buffer);
|
||||
lengthLength = buffer.readerIndex() - lengthLength;
|
||||
buffers.add(buffer.sliceCopy(read, length + lengthLength));
|
||||
read += length + lengthLength;
|
||||
}
|
||||
return buffers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet decode(Buffer buffer) {
|
||||
int length = readVarInt(buffer);
|
||||
int id = readVarInt(buffer);
|
||||
Buffer packetPayload = buffer.sliceCopy(buffer.readerIndex());
|
||||
return Packet.create(packetPayload).put(PACKET_ID_IDENTIFIER, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Buffer encode(Packet packet) {
|
||||
Buffer buffer = Buffer.create();
|
||||
Buffer idAndPayload = Buffer.create();
|
||||
writeVarInt(idAndPayload, packet.get(PACKET_ID_IDENTIFIER));
|
||||
idAndPayload.putBuffer(packet.getPayload());
|
||||
writeVarInt(buffer, idAndPayload.length());
|
||||
buffer.putBuffer(idAndPayload);
|
||||
return buffer;
|
||||
}
|
||||
}
|
111
src/main/java/fr/themode/minestom/utils/Utils.java
Normal file
111
src/main/java/fr/themode/minestom/utils/Utils.java
Normal file
@ -0,0 +1,111 @@
|
||||
package fr.themode.minestom.utils;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
public class Utils {
|
||||
|
||||
public static void writeString(Buffer buffer, String value) {
|
||||
byte[] bytes = new byte[0];
|
||||
try {
|
||||
bytes = value.getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (bytes.length > 32767) {
|
||||
System.out.println("String too big (was " + value.length() + " bytes encoded, max " + 32767 + ")");
|
||||
} else {
|
||||
writeVarInt(buffer, bytes.length);
|
||||
buffer.putBytes(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
public static String readString(Buffer buffer) {
|
||||
int length = readVarInt(buffer);
|
||||
byte bytes[] = buffer.getBytes(length);
|
||||
try {
|
||||
return new String(bytes, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void writeVarInt(Buffer buffer, int value) {
|
||||
do {
|
||||
byte temp = (byte) (value & 0b01111111);
|
||||
value >>>= 7;
|
||||
if (value != 0) {
|
||||
temp |= 0b10000000;
|
||||
}
|
||||
buffer.putByte(temp);
|
||||
} while (value != 0);
|
||||
}
|
||||
|
||||
public static int readVarInt(Buffer buffer) {
|
||||
int numRead = 0;
|
||||
int result = 0;
|
||||
byte read;
|
||||
do {
|
||||
read = buffer.getByte();
|
||||
int value = (read & 0b01111111);
|
||||
result |= (value << (7 * numRead));
|
||||
|
||||
numRead++;
|
||||
if (numRead > 5) {
|
||||
throw new RuntimeException("VarInt is too big");
|
||||
}
|
||||
} while ((read & 0b10000000) != 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ??
|
||||
public static int lengthVarInt(int value) {
|
||||
int i = 0;
|
||||
do {
|
||||
i++;
|
||||
byte temp = (byte) (value & 0b01111111);
|
||||
value >>>= 7;
|
||||
if (value != 0) {
|
||||
temp |= 0b10000000;
|
||||
}
|
||||
} while (value != 0);
|
||||
return i;
|
||||
}
|
||||
|
||||
public static void writeVarLong(Buffer buffer, long value) {
|
||||
do {
|
||||
byte temp = (byte) (value & 0b01111111);
|
||||
value >>>= 7;
|
||||
if (value != 0) {
|
||||
temp |= 0b10000000;
|
||||
}
|
||||
buffer.putByte(temp);
|
||||
} while (value != 0);
|
||||
}
|
||||
|
||||
public static long readVarLong(Buffer buffer) {
|
||||
int numRead = 0;
|
||||
long result = 0;
|
||||
byte read;
|
||||
do {
|
||||
read = buffer.getByte();
|
||||
int value = (read & 0b01111111);
|
||||
result |= (value << (7 * numRead));
|
||||
|
||||
numRead++;
|
||||
if (numRead > 10) {
|
||||
throw new RuntimeException("VarLong is too big");
|
||||
}
|
||||
} while ((read & 0b10000000) != 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void writePosition(Buffer buffer, int x, int y, int z) {
|
||||
buffer.putLong(((x & 0x3FFFFFF) << 38) | ((y & 0xFFF) << 26) | (z & 0x3FFFFFF));
|
||||
}
|
||||
|
||||
}
|
16
src/main/java/fr/themode/minestom/world/Difficulty.java
Normal file
16
src/main/java/fr/themode/minestom/world/Difficulty.java
Normal file
@ -0,0 +1,16 @@
|
||||
package fr.themode.minestom.world;
|
||||
|
||||
public enum Difficulty {
|
||||
|
||||
PEACEFUL((byte) 0), EASY((byte) 1), NORMAL((byte) 2), HARD((byte) 3);
|
||||
|
||||
private byte id;
|
||||
|
||||
Difficulty(byte id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public byte getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
16
src/main/java/fr/themode/minestom/world/Dimension.java
Normal file
16
src/main/java/fr/themode/minestom/world/Dimension.java
Normal file
@ -0,0 +1,16 @@
|
||||
package fr.themode.minestom.world;
|
||||
|
||||
public enum Dimension {
|
||||
|
||||
NETHER(-1), OVERWORLD(0), END(1);
|
||||
|
||||
private int id;
|
||||
|
||||
Dimension(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user