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
This commit is contained in:
BruceChen 2026-03-19 00:13:57 +08:00
parent 41a701b6b2
commit bb18399523

View file

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