diff --git a/src/main/java/ru/nanit/limbo/protocol/packets/play/PacketJoinGame.java b/src/main/java/ru/nanit/limbo/protocol/packets/play/PacketJoinGame.java index 2b0e605..0aa8ffa 100644 --- a/src/main/java/ru/nanit/limbo/protocol/packets/play/PacketJoinGame.java +++ b/src/main/java/ru/nanit/limbo/protocol/packets/play/PacketJoinGame.java @@ -4,6 +4,7 @@ import net.kyori.adventure.nbt.CompoundBinaryTag; import ru.nanit.limbo.protocol.ByteMessage; import ru.nanit.limbo.protocol.PacketOut; import ru.nanit.limbo.protocol.registry.Version; +import ru.nanit.limbo.world.Dimension; public class PacketJoinGame implements PacketOut { @@ -13,7 +14,7 @@ public class PacketJoinGame implements PacketOut { private int previousGameMode = -1; private String[] worldNames; private CompoundBinaryTag dimensionCodec; - private CompoundBinaryTag dimension; + private Dimension dimension; private String worldName; private long hashedSeed; private int maxPlayers; @@ -47,7 +48,7 @@ public class PacketJoinGame implements PacketOut { this.dimensionCodec = dimensionCodec; } - public void setDimension(CompoundBinaryTag dimension) { + public void setDimension(Dimension dimension) { this.dimension = dimension; } @@ -86,20 +87,69 @@ public class PacketJoinGame implements PacketOut { @Override public void encode(ByteMessage msg, Version version) { msg.writeInt(entityId); - msg.writeBoolean(isHardcore); - msg.writeByte(gameMode); - msg.writeByte(previousGameMode); - msg.writeStringsArray(worldNames); - msg.writeCompoundTag(dimensionCodec); - msg.writeCompoundTag(dimension); - msg.writeString(worldName); - msg.writeLong(hashedSeed); - msg.writeVarInt(maxPlayers); - msg.writeVarInt(viewDistance); - msg.writeBoolean(reducedDebugInfo); - msg.writeBoolean(enableRespawnScreen); - msg.writeBoolean(isDebug); - msg.writeBoolean(isFlat); + + if (version.fromTo(Version.V1_8, Version.V1_13_2)) { + msg.writeByte(gameMode); + msg.writeByte(dimension.getId()); + msg.writeByte(0); // Difficulty + msg.writeByte(maxPlayers); + msg.writeString("flat"); // Level type + msg.writeBoolean(reducedDebugInfo); + } + + if (version.fromTo(Version.V1_14, Version.V1_14_4)) { + msg.writeByte(gameMode); + msg.writeByte(dimension.getId()); + msg.writeByte(maxPlayers); + msg.writeString("flat"); // Level type + msg.writeVarInt(viewDistance); + msg.writeBoolean(reducedDebugInfo); + } + + if (version.fromTo(Version.V1_15, Version.V1_15_2)) { + msg.writeByte(gameMode); + msg.writeByte(dimension.getId()); + msg.writeLong(hashedSeed); + msg.writeByte(maxPlayers); + msg.writeString("flat"); // Level type + msg.writeVarInt(viewDistance); + msg.writeBoolean(reducedDebugInfo); + msg.writeBoolean(enableRespawnScreen); + } + + if (version.fromTo(Version.V1_16, Version.V1_16_1)) { + msg.writeBoolean(isHardcore); + msg.writeByte(gameMode); + msg.writeByte(previousGameMode); + msg.writeStringsArray(worldNames); + msg.writeCompoundTag(dimensionCodec); + msg.writeInt(dimension.getId()); + msg.writeString(worldName); + msg.writeLong(hashedSeed); + msg.writeByte(maxPlayers); + msg.writeVarInt(viewDistance); + msg.writeBoolean(reducedDebugInfo); + msg.writeBoolean(enableRespawnScreen); + msg.writeBoolean(isDebug); + msg.writeBoolean(isFlat); + } + + if (version.fromTo(Version.V1_16_2, Version.V1_17_1)) { + msg.writeBoolean(isHardcore); + msg.writeByte(gameMode); + msg.writeByte(previousGameMode); + msg.writeStringsArray(worldNames); + msg.writeCompoundTag(dimensionCodec); + msg.writeCompoundTag(dimension.getData()); + msg.writeString(worldName); + msg.writeLong(hashedSeed); + msg.writeVarInt(maxPlayers); + msg.writeVarInt(viewDistance); + msg.writeBoolean(reducedDebugInfo); + msg.writeBoolean(enableRespawnScreen); + msg.writeBoolean(isDebug); + msg.writeBoolean(isFlat); + } } } diff --git a/src/main/java/ru/nanit/limbo/protocol/registry/Version.java b/src/main/java/ru/nanit/limbo/protocol/registry/Version.java index cfceb3a..8dde6f9 100644 --- a/src/main/java/ru/nanit/limbo/protocol/registry/Version.java +++ b/src/main/java/ru/nanit/limbo/protocol/registry/Version.java @@ -13,6 +13,7 @@ public enum Version { V1_9_2(109), V1_9_4(110), V1_10(210), + // 1.10-1.10.2 has same protocol numbers V1_11(315), V1_11_1(316), // 1.11.2 has same protocol number @@ -82,6 +83,14 @@ public enum Version { return this.protocolNumber <= another.protocolNumber; } + public boolean between(Version min, Version max) { + return this.protocolNumber > min.protocolNumber && this.protocolNumber < max.protocolNumber; + } + + public boolean fromTo(Version min, Version max) { + return this.protocolNumber >= min.protocolNumber && this.protocolNumber <= max.protocolNumber; + } + public static Version getMin() { return V1_8; } diff --git a/src/main/java/ru/nanit/limbo/world/Dimension.java b/src/main/java/ru/nanit/limbo/world/Dimension.java new file mode 100644 index 0000000..ba25302 --- /dev/null +++ b/src/main/java/ru/nanit/limbo/world/Dimension.java @@ -0,0 +1,22 @@ +package ru.nanit.limbo.world; + +import net.kyori.adventure.nbt.CompoundBinaryTag; + +public class Dimension { + + private final int id; + private final CompoundBinaryTag data; + + public Dimension(int id, CompoundBinaryTag data) { + this.id = id; + this.data = data; + } + + public int getId() { + return id; + } + + public CompoundBinaryTag getData() { + return data; + } +} diff --git a/src/main/java/ru/nanit/limbo/world/DimensionRegistry.java b/src/main/java/ru/nanit/limbo/world/DimensionRegistry.java index b86469e..7a977c8 100644 --- a/src/main/java/ru/nanit/limbo/world/DimensionRegistry.java +++ b/src/main/java/ru/nanit/limbo/world/DimensionRegistry.java @@ -12,7 +12,7 @@ import java.io.InputStream; public final class DimensionRegistry { - private CompoundBinaryTag defaultDimension; + private Dimension defaultDimension; private CompoundBinaryTag codec; @@ -20,7 +20,7 @@ public final class DimensionRegistry { return codec; } - public CompoundBinaryTag getDefaultDimension() { + public Dimension getDefaultDimension() { return defaultDimension; } @@ -39,16 +39,16 @@ public final class DimensionRegistry { switch (def.toLowerCase()) { case "overworld": - defaultDimension = overWorld; + defaultDimension = new Dimension(0, overWorld); break; case "nether": - defaultDimension = nether; + defaultDimension = new Dimension(-1, nether); break; case "the_end": - defaultDimension = theEnd; + defaultDimension = new Dimension(1, theEnd); break; default: - defaultDimension = theEnd; + defaultDimension = new Dimension(1, theEnd); Logger.warning("Undefined dimension type: '%s'. Using THE_END as default", def); break; }