diff --git a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java index cfc11b608..d65771644 100644 --- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java +++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java @@ -37,7 +37,7 @@ public enum ProtocolVersion { MINECRAFT_1_15_2(578, "1.15.2"), MINECRAFT_1_16(735, "1.16"), MINECRAFT_1_16_1(736, "1.16.1"), - MINECRAFT_1_16_2(738, "1.16.2"); + MINECRAFT_1_16_2(740, "1.16.2"); private final int protocol; private final String name; diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/registry/DimensionRegistry.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/registry/DimensionRegistry.java index 22bf61977..6fdf4d88d 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/registry/DimensionRegistry.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/registry/DimensionRegistry.java @@ -79,27 +79,22 @@ public final class DimensionRegistry { * Encodes the stored Dimension registry as CompoundTag. * @return the CompoundTag containing identifier:type mappings */ - public CompoundTag encodeRegistry() { - CompoundTag ret = new CompoundTag(); + public ListTag encodeRegistry() { ListTag list = new ListTag(TagType.COMPOUND); for (DimensionData iter : registeredDimensions.values()) { list.add(iter.encodeAsCompundTag()); } - ret.put("dimension", list); - return ret; + return list; } /** * Decodes a CompoundTag storing a dimension registry. * @param toParse CompoundTag containing a dimension registry */ - public static ImmutableSet fromGameData(CompoundTag toParse) { - Preconditions.checkNotNull(toParse, "CompoundTag cannot be null"); - Preconditions.checkArgument(toParse.contains("dimension", TagType.LIST), - "CompoundTag does not contain a dimension list"); - ListTag dimensions = toParse.getList("dimension"); + public static ImmutableSet fromGameData(ListTag toParse) { + Preconditions.checkNotNull(toParse, "ListTag cannot be null"); ImmutableSet.Builder mappings = ImmutableSet.builder(); - for (Tag iter : dimensions) { + for (Tag iter : toParse) { if (iter instanceof CompoundTag) { mappings.add(DimensionData.decodeCompoundTag((CompoundTag) iter)); } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java index 2b89b575c..f2a969dbf 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java @@ -141,39 +141,45 @@ public enum StateRegistry { map(0x0E, MINECRAFT_1_9, false), map(0x10, MINECRAFT_1_13, false), map(0x11, MINECRAFT_1_15, false), - map(0x10, MINECRAFT_1_16, false)); + map(0x10, MINECRAFT_1_16, false), + map(0x0F, MINECRAFT_1_16_2, false)); clientbound.register(AvailableCommands.class, AvailableCommands::new, map(0x11, MINECRAFT_1_13, false), map(0x12, MINECRAFT_1_15, false), - map(0x11, MINECRAFT_1_16, false)); + map(0x11, MINECRAFT_1_16, false), + map(0x10, MINECRAFT_1_16_2, false)); clientbound.register(PluginMessage.class, PluginMessage::new, map(0x3F, MINECRAFT_1_8, false), map(0x18, MINECRAFT_1_9, false), map(0x19, MINECRAFT_1_13, false), map(0x18, MINECRAFT_1_14, false), map(0x19, MINECRAFT_1_15, false), - map(0x18, MINECRAFT_1_16, false)); + map(0x18, MINECRAFT_1_16, false), + map(0x17, MINECRAFT_1_16_2, false)); clientbound.register(Disconnect.class, Disconnect::new, map(0x40, MINECRAFT_1_8, false), map(0x1A, MINECRAFT_1_9, false), map(0x1B, MINECRAFT_1_13, false), map(0x1A, MINECRAFT_1_14, false), map(0x1B, MINECRAFT_1_15, false), - map(0x1A, MINECRAFT_1_16, false)); + map(0x1A, MINECRAFT_1_16, false), + map(0x19, MINECRAFT_1_16_2, false)); clientbound.register(KeepAlive.class, KeepAlive::new, map(0x00, MINECRAFT_1_8, false), map(0x1F, MINECRAFT_1_9, false), map(0x21, MINECRAFT_1_13, false), map(0x20, MINECRAFT_1_14, false), map(0x21, MINECRAFT_1_15, false), - map(0x20, MINECRAFT_1_16, false)); + map(0x20, MINECRAFT_1_16, false), + map(0x1F, MINECRAFT_1_16_2, false)); clientbound.register(JoinGame.class, JoinGame::new, map(0x01, MINECRAFT_1_8, false), map(0x23, MINECRAFT_1_9, false), map(0x25, MINECRAFT_1_13, false), map(0x25, MINECRAFT_1_14, false), map(0x26, MINECRAFT_1_15, false), - map(0x25, MINECRAFT_1_16, false)); + map(0x25, MINECRAFT_1_16, false), + map(0x24, MINECRAFT_1_16_2, false)); clientbound.register(Respawn.class, Respawn::new, map(0x07, MINECRAFT_1_8, true), map(0x33, MINECRAFT_1_9, true), @@ -182,7 +188,8 @@ public enum StateRegistry { map(0x38, MINECRAFT_1_13, true), map(0x3A, MINECRAFT_1_14, true), map(0x3B, MINECRAFT_1_15, true), - map(0x3A, MINECRAFT_1_16, true)); + map(0x3A, MINECRAFT_1_16, true), + map(0x39, MINECRAFT_1_16_2, true)); clientbound.register(ResourcePackRequest.class, ResourcePackRequest::new, map(0x48, MINECRAFT_1_8, true), map(0x32, MINECRAFT_1_9, true), @@ -191,7 +198,8 @@ public enum StateRegistry { map(0x37, MINECRAFT_1_13, true), map(0x39, MINECRAFT_1_14, true), map(0x3A, MINECRAFT_1_15, true), - map(0x39, MINECRAFT_1_16, true)); + map(0x39, MINECRAFT_1_16, true), + map(0x38, MINECRAFT_1_16_2, true)); clientbound.register(HeaderAndFooter.class, HeaderAndFooter::new, map(0x47, MINECRAFT_1_8, true), map(0x48, MINECRAFT_1_9, true), @@ -218,7 +226,8 @@ public enum StateRegistry { map(0x30, MINECRAFT_1_13, false), map(0x33, MINECRAFT_1_14, false), map(0x34, MINECRAFT_1_15, false), - map(0x33, MINECRAFT_1_16, false)); + map(0x33, MINECRAFT_1_16, false), + map(0x32, MINECRAFT_1_16_2, false)); } }, LOGIN { diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/JoinGame.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/JoinGame.java index 3dd55a265..468d2f4e8 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/JoinGame.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/JoinGame.java @@ -8,6 +8,9 @@ import com.velocitypowered.proxy.connection.registry.DimensionInfo; import com.velocitypowered.proxy.connection.registry.DimensionRegistry; import com.velocitypowered.proxy.protocol.*; import io.netty.buffer.ByteBuf; +import net.kyori.nbt.CompoundTag; +import net.kyori.nbt.ListTag; +import net.kyori.nbt.TagType; import org.checkerframework.checker.nullness.qual.Nullable; public class JoinGame implements MinecraftPacket { @@ -26,6 +29,7 @@ public class JoinGame implements MinecraftPacket { private DimensionRegistry dimensionRegistry; // 1.16+ private DimensionInfo dimensionInfo; // 1.16+ private short previousGamemode; // 1.16+ + private CompoundTag biomeRegistry; // 1.16.2+ public int getEntityId() { return entityId; @@ -127,6 +131,14 @@ public class JoinGame implements MinecraftPacket { this.isHardcore = isHardcore; } + public CompoundTag getBiomeRegistry() { + return biomeRegistry; + } + + public void setBiomeRegistry(CompoundTag biomeRegistry) { + this.biomeRegistry = biomeRegistry; + } + @Override public String toString() { return "JoinGame{" @@ -162,7 +174,17 @@ public class JoinGame implements MinecraftPacket { if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) { this.previousGamemode = buf.readByte(); ImmutableSet levelNames = ImmutableSet.copyOf(ProtocolUtils.readStringArray(buf)); - ImmutableSet readData = DimensionRegistry.fromGameData(ProtocolUtils.readCompoundTag(buf)); + CompoundTag registryContainer = ProtocolUtils.readCompoundTag(buf); + ListTag dimensionRegistryContainer = null; + if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) { + dimensionRegistryContainer = registryContainer.getCompound("minecraft:dimension_type") + .getList("value", TagType.COMPOUND); + this.biomeRegistry = registryContainer.getCompound("minecraft:worldgen/biome"); + } else { + dimensionRegistryContainer = registryContainer.getList("dimension", TagType.COMPOUND); + } + ImmutableSet readData = + DimensionRegistry.fromGameData(dimensionRegistryContainer); this.dimensionRegistry = new DimensionRegistry(readData, levelNames); dimensionIdentifier = ProtocolUtils.readString(buf); levelName = ProtocolUtils.readString(buf); @@ -212,7 +234,18 @@ public class JoinGame implements MinecraftPacket { buf.writeByte(previousGamemode); ProtocolUtils.writeStringArray(buf, dimensionRegistry.getLevelNames().toArray( new String[dimensionRegistry.getLevelNames().size()])); - ProtocolUtils.writeCompoundTag(buf, dimensionRegistry.encodeRegistry()); + CompoundTag registryContainer = new CompoundTag(); + ListTag encodedDimensionRegistry = dimensionRegistry.encodeRegistry(); + if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) { + CompoundTag dimensionRegistryDummy = new CompoundTag(); + dimensionRegistryDummy.putString("type", "minecraft:dimension_type"); + dimensionRegistryDummy.put("value", encodedDimensionRegistry); + registryContainer.put("minecraft:dimension_type", dimensionRegistryDummy); + registryContainer.put("minecraft:worldgen/biome", biomeRegistry); + } else { + registryContainer.put("dimension", encodedDimensionRegistry); + } + ProtocolUtils.writeCompoundTag(buf, registryContainer); ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier()); ProtocolUtils.writeString(buf, dimensionInfo.getLevelName()); } else if (version.compareTo(ProtocolVersion.MINECRAFT_1_9_1) >= 0) {