From bb18399523e65d257381210091358ac8406de56e Mon Sep 17 00:00:00 2001 From: BruceChen Date: Thu, 19 Mar 2026 00:13:57 +0800 Subject: [PATCH] Use dynamic dimension registry lookup in JoinGame and Respawn packets The JoinGame and Respawn packet handlers for 1.20.6+ used hardcoded switch expressions to map dimension type VarInt IDs to names: 0 => overworld, 1 => overworld_caves, 2 => the_end, 3 => the_nether This only works for vanilla servers with exactly 4 default dimensions. Modded servers (Forge/Fabric/NeoForge) or servers with custom datapacks can register additional dimensions with IDs beyond 0-3, causing the switch to fall through to the default "overworld" for any non-vanilla dimension. This means players in modded dimensions would have incorrect world parameters (height, lighting, etc.). Fix: Replace both hardcoded switch expressions with World.GetDimensionNameById(), which looks up the VarInt ID in the dimension ID map populated during the RegistryData phase. Also fixes two pre-existing issues in the SetDimension dispatch: - JoinGame (pre-1.20.2 path): The `case < MC_1_20_6_Version` guard was technically correct within its enclosing `if` block, but changed to `default` for clarity and future-proofing. - Respawn: The `case <= MC_1_20_6_Version` guard excluded protocol versions above 766 (e.g. 1.21 / protocol 767), meaning SetDimension was never called for those versions. Changed to `default` so all versions >= 1.19 properly update the dimension. Made-with: Cursor --- .../Protocol/Handlers/Protocol18.cs | 28 ++++--------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 3a0abe27..dab9f2e0 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -753,10 +753,9 @@ namespace MinecraftClient.Protocol.Handlers { case >= MC_1_16_2_Version and <= MC_1_18_2_Version: World.StoreOneDimension(dimensionName, dimensionType!); - // World.SetDimension(dimensionName); - World.SetDimension(dimensionName); + World.SetDimension(dimensionName); break; - case < MC_1_20_6_Version: + default: World.SetDimension(dimensionTypeName!); break; } @@ -808,17 +807,9 @@ namespace MinecraftClient.Protocol.Handlers { dataTypes.ReadNextBool(packetData); // Do limited crafting - // Dimension Type (string bellow 1.20.6, VarInt for 1.20.6+) var dimensionTypeName = protocolVersion < MC_1_20_6_Version - ? dataTypes.ReadNextString(packetData) // < 1.20.6 - : (dataTypes.ReadNextVarInt(packetData) switch // 1.20.6+ // TODO: Use values from the registry - { - 0 => "minecraft:overworld", - 1 => "minecraft:overworld_caves", - 2 => "minecraft:the_end", - 3 => "minecraft:the_nether", - _ => null - } ?? "minecraft:overworld"); + ? dataTypes.ReadNextString(packetData) + : World.GetDimensionNameById(dataTypes.ReadNextVarInt(packetData)); dataTypes.ReadNextString(packetData); // Dimension Name (World Name) - 1.16 and above @@ -1282,14 +1273,7 @@ namespace MinecraftClient.Protocol.Handlers switch (protocolVersion) { case >= MC_1_20_6_Version: - dimensionTypeNameRespawn = dataTypes.ReadNextVarInt(packetData) switch // 1.20.6+ // TODO: Use values from the registry - { - 0 => "minecraft:overworld", - 1 => "minecraft:overworld_caves", - 2 => "minecraft:the_end", - 3 => "minecraft:the_nether", - _ => null - } ?? "minecraft:overworld"; + dimensionTypeNameRespawn = World.GetDimensionNameById(dataTypes.ReadNextVarInt(packetData)); break; case >= MC_1_19_Version: dimensionTypeNameRespawn = @@ -1328,7 +1312,7 @@ namespace MinecraftClient.Protocol.Handlers World.StoreOneDimension(dimensionName, dimensionTypeRespawn!); World.SetDimension(dimensionName); break; - case <= MC_1_20_6_Version: + default: World.SetDimension(dimensionTypeNameRespawn!); break; }