diff --git a/protocol/src/main/java/mc/protocol/State.java b/protocol/src/main/java/mc/protocol/State.java index 00c3a2e..a2a7d35 100644 --- a/protocol/src/main/java/mc/protocol/State.java +++ b/protocol/src/main/java/mc/protocol/State.java @@ -7,10 +7,7 @@ import mc.protocol.packets.Packet; import mc.protocol.packets.PingPacket; import mc.protocol.packets.ServerSidePacket; import mc.protocol.packets.client.*; -import mc.protocol.packets.server.DisconnectPacket; -import mc.protocol.packets.server.JoinGamePacket; -import mc.protocol.packets.server.LoginSuccessPacket; -import mc.protocol.packets.server.StatusServerResponse; +import mc.protocol.packets.server.*; import javax.annotation.Nullable; import java.util.Collections; @@ -51,7 +48,10 @@ public enum State { 0x09, PluginMessagePacket.class ), // client bound - Map.of(JoinGamePacket.class, 0x23) + Map.of( + JoinGamePacket.class, 0x23, + SpawnPositionPacket.class, 0x46 + ) ); @Nullable diff --git a/protocol/src/main/java/mc/protocol/io/NetByteBuf.java b/protocol/src/main/java/mc/protocol/io/NetByteBuf.java index 1b038e8..b76ba17 100644 --- a/protocol/src/main/java/mc/protocol/io/NetByteBuf.java +++ b/protocol/src/main/java/mc/protocol/io/NetByteBuf.java @@ -32,6 +32,8 @@ import java.util.UUID; * | | | | этого числа). | * | VarInt | >= 1 ; <= 5 | Число от -2147483648 и 2147483647 | 32-bit число с плавающей размерностью от 1 до 5 байт | * | VarLong | >= 1 ; <= 10 | Число от -9223372036854775808 и 9223372036854775807 | 64-bit число с плавающей размерностью от 1 до 10 байт | + * | Position | 8 | 64-bit число разделённое на три части: x, y, z | Кодируется формулой: | + * | | | | ((x & 0x3FFFFFF) << 38) | ((y & 0xFFF) << 26) | (z & 0x3FFFFFF) | * * [1] - Single-precision floating-point format * [2] - Double-precision floating-point format diff --git a/protocol/src/main/java/mc/protocol/model/Location.java b/protocol/src/main/java/mc/protocol/model/Location.java new file mode 100644 index 0000000..697f64b --- /dev/null +++ b/protocol/src/main/java/mc/protocol/model/Location.java @@ -0,0 +1,12 @@ +package mc.protocol.model; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@AllArgsConstructor +@Data +public class Location { + private double x; + private double y; + private double z; +} diff --git a/protocol/src/main/java/mc/protocol/packets/server/SpawnPositionPacket.java b/protocol/src/main/java/mc/protocol/packets/server/SpawnPositionPacket.java new file mode 100644 index 0000000..41a3d10 --- /dev/null +++ b/protocol/src/main/java/mc/protocol/packets/server/SpawnPositionPacket.java @@ -0,0 +1,41 @@ +package mc.protocol.packets.server; + +import lombok.Data; +import mc.protocol.io.NetByteBuf; +import mc.protocol.model.Location; +import mc.protocol.packets.ServerSidePacket; + +/** + * Спавн позиция игрока. + * + *
Используется призаходе игрока на сервер.
+ * + *Структура пакета
+ *+ * | FIELD | TYPE | NOTES | + * |----------|----------|-----------------------| + * | Location | Position | Локация спавна игрока | + *+ * + * @see Spawn Position + */ +@Data +public class SpawnPositionPacket implements ServerSidePacket { + + private Location spawn; + + @Override + public void writeSelf(NetByteBuf netByteBuf) { + long spawnSerialized = + ((long) (floorDouble(spawn.getX()) & 0x3FFFFFF) << 38) + | ((long) (floorDouble(spawn.getY()) & 0xFFF) << 26) + | (floorDouble(spawn.getZ()) & 0x3FFFFFF); + netByteBuf.writeLong(spawnSerialized); + } + + private static int floorDouble(double value) { + int i = (int) value; + return value < (double) i ? i - 1 : i; + } + +} diff --git a/server/src/main/java/mc/server/PacketHandler.java b/server/src/main/java/mc/server/PacketHandler.java index f3c8a67..611a686 100644 --- a/server/src/main/java/mc/server/PacketHandler.java +++ b/server/src/main/java/mc/server/PacketHandler.java @@ -3,6 +3,7 @@ package mc.server; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import mc.protocol.*; +import mc.protocol.model.Location; import mc.protocol.model.ServerInfo; import mc.protocol.packets.PingPacket; import mc.protocol.packets.client.HandshakePacket; @@ -10,6 +11,7 @@ import mc.protocol.packets.client.LoginStartPacket; import mc.protocol.packets.client.StatusServerRequestPacket; import mc.protocol.packets.server.JoinGamePacket; import mc.protocol.packets.server.LoginSuccessPacket; +import mc.protocol.packets.server.SpawnPositionPacket; import mc.protocol.packets.server.StatusServerResponse; import mc.protocol.serializer.TextSerializer; import mc.server.config.Config; @@ -78,6 +80,12 @@ public class PacketHandler { log.info("{}", joinGamePacket); channel.getCtx().write(joinGamePacket); + SpawnPositionPacket spawnPositionPacket = new SpawnPositionPacket(); + spawnPositionPacket.setSpawn(new Location(0d, 63d, 0d)); + + log.info("{}", spawnPositionPacket); + channel.getCtx().write(spawnPositionPacket); + channel.getCtx().flush(); }