Rewrite JoinGame packet for supported versions

This commit is contained in:
Nanit 2021-10-30 13:23:03 +03:00
parent cc5f92086a
commit e931773ce8
4 changed files with 103 additions and 22 deletions

View File

@ -4,6 +4,7 @@ import net.kyori.adventure.nbt.CompoundBinaryTag;
import ru.nanit.limbo.protocol.ByteMessage; import ru.nanit.limbo.protocol.ByteMessage;
import ru.nanit.limbo.protocol.PacketOut; import ru.nanit.limbo.protocol.PacketOut;
import ru.nanit.limbo.protocol.registry.Version; import ru.nanit.limbo.protocol.registry.Version;
import ru.nanit.limbo.world.Dimension;
public class PacketJoinGame implements PacketOut { public class PacketJoinGame implements PacketOut {
@ -13,7 +14,7 @@ public class PacketJoinGame implements PacketOut {
private int previousGameMode = -1; private int previousGameMode = -1;
private String[] worldNames; private String[] worldNames;
private CompoundBinaryTag dimensionCodec; private CompoundBinaryTag dimensionCodec;
private CompoundBinaryTag dimension; private Dimension dimension;
private String worldName; private String worldName;
private long hashedSeed; private long hashedSeed;
private int maxPlayers; private int maxPlayers;
@ -47,7 +48,7 @@ public class PacketJoinGame implements PacketOut {
this.dimensionCodec = dimensionCodec; this.dimensionCodec = dimensionCodec;
} }
public void setDimension(CompoundBinaryTag dimension) { public void setDimension(Dimension dimension) {
this.dimension = dimension; this.dimension = dimension;
} }
@ -86,20 +87,69 @@ public class PacketJoinGame implements PacketOut {
@Override @Override
public void encode(ByteMessage msg, Version version) { public void encode(ByteMessage msg, Version version) {
msg.writeInt(entityId); msg.writeInt(entityId);
msg.writeBoolean(isHardcore);
msg.writeByte(gameMode); if (version.fromTo(Version.V1_8, Version.V1_13_2)) {
msg.writeByte(previousGameMode); msg.writeByte(gameMode);
msg.writeStringsArray(worldNames); msg.writeByte(dimension.getId());
msg.writeCompoundTag(dimensionCodec); msg.writeByte(0); // Difficulty
msg.writeCompoundTag(dimension); msg.writeByte(maxPlayers);
msg.writeString(worldName); msg.writeString("flat"); // Level type
msg.writeLong(hashedSeed); msg.writeBoolean(reducedDebugInfo);
msg.writeVarInt(maxPlayers); }
msg.writeVarInt(viewDistance);
msg.writeBoolean(reducedDebugInfo); if (version.fromTo(Version.V1_14, Version.V1_14_4)) {
msg.writeBoolean(enableRespawnScreen); msg.writeByte(gameMode);
msg.writeBoolean(isDebug); msg.writeByte(dimension.getId());
msg.writeBoolean(isFlat); 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);
}
} }
} }

View File

@ -13,6 +13,7 @@ public enum Version {
V1_9_2(109), V1_9_2(109),
V1_9_4(110), V1_9_4(110),
V1_10(210), V1_10(210),
// 1.10-1.10.2 has same protocol numbers
V1_11(315), V1_11(315),
V1_11_1(316), V1_11_1(316),
// 1.11.2 has same protocol number // 1.11.2 has same protocol number
@ -82,6 +83,14 @@ public enum Version {
return this.protocolNumber <= another.protocolNumber; 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() { public static Version getMin() {
return V1_8; return V1_8;
} }

View File

@ -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;
}
}

View File

@ -12,7 +12,7 @@ import java.io.InputStream;
public final class DimensionRegistry { public final class DimensionRegistry {
private CompoundBinaryTag defaultDimension; private Dimension defaultDimension;
private CompoundBinaryTag codec; private CompoundBinaryTag codec;
@ -20,7 +20,7 @@ public final class DimensionRegistry {
return codec; return codec;
} }
public CompoundBinaryTag getDefaultDimension() { public Dimension getDefaultDimension() {
return defaultDimension; return defaultDimension;
} }
@ -39,16 +39,16 @@ public final class DimensionRegistry {
switch (def.toLowerCase()) { switch (def.toLowerCase()) {
case "overworld": case "overworld":
defaultDimension = overWorld; defaultDimension = new Dimension(0, overWorld);
break; break;
case "nether": case "nether":
defaultDimension = nether; defaultDimension = new Dimension(-1, nether);
break; break;
case "the_end": case "the_end":
defaultDimension = theEnd; defaultDimension = new Dimension(1, theEnd);
break; break;
default: default:
defaultDimension = theEnd; defaultDimension = new Dimension(1, theEnd);
Logger.warning("Undefined dimension type: '%s'. Using THE_END as default", def); Logger.warning("Undefined dimension type: '%s'. Using THE_END as default", def);
break; break;
} }