From 88e9c671da3ea4244885fe16acc2fc4904facea8 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 21 Mar 2026 14:05:06 +0800 Subject: [PATCH] feat: add version routing and metadata reading for MC 1.21.9 - Route block/entity/item/packet/metadata palettes to new 1219 variants for protocol >= 773, and raise upper-bound guards from MC_1_21_7 to MC_1_21_9 so terrain, inventory, and entity handling are enabled. - Add DataTypes readers for three new entity metadata serializer types: CopperGolemState and WeatheringCopperState (both VarInt), and ResolvableProfile (composite: Either with optional name/UUID/properties + PlayerSkin.Patch with 4 optional fields for body/cape/elytra texture ResourceLocations and model type). Made-with: Cursor --- .../Mapping/EntityMetadataPalette.cs | 3 +- .../Protocol/Handlers/DataTypes.cs | 61 +++++++++++++++++++ .../Protocol/Handlers/PacketType18Handler.cs | 3 +- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/MinecraftClient/Mapping/EntityMetadataPalette.cs b/MinecraftClient/Mapping/EntityMetadataPalette.cs index 7cdb194a..60acef8c 100644 --- a/MinecraftClient/Mapping/EntityMetadataPalette.cs +++ b/MinecraftClient/Mapping/EntityMetadataPalette.cs @@ -24,7 +24,8 @@ public abstract class EntityMetadataPalette <= Protocol18Handler.MC_1_19_3_Version => new EntityMetadataPalette1193(), // 1.19.3 < Protocol18Handler.MC_1_20_6_Version => new EntityMetadataPalette1194(), // 1.19.4 - 1.20.4 <= Protocol18Handler.MC_1_21_4_Version => new EntityMetadataPalette1206(), // 1.20.6 - 1.21.4 - <= Protocol18Handler.MC_1_21_7_Version => new EntityMetadataPalette1215(), // 1.21.5 - 1.21.7 + <= Protocol18Handler.MC_1_21_7_Version => new EntityMetadataPalette1215(), // 1.21.5 - 1.21.8 + <= Protocol18Handler.MC_1_21_9_Version => new EntityMetadataPalette1219(), // 1.21.9 - 1.21.10 _ => throw new NotImplementedException() }; } diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index ab46dca7..db6b8c1e 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -907,6 +907,13 @@ namespace MinecraftClient.Protocol.Handlers case EntityMetaDataType.ArmadilloState: // Armadillo state (1.20.6+) value = ReadNextVarInt(cache); break; + case EntityMetaDataType.CopperGolemState: // Copper Golem state (1.21.9+) + case EntityMetaDataType.WeatheringCopperState: // Weathering Copper state (1.21.9+) + value = ReadNextVarInt(cache); + break; + case EntityMetaDataType.ResolvableProfile: // ResolvableProfile (1.21.9+) + ReadNextResolvableProfile(cache); + break; case EntityMetaDataType.Vector3: // Vector 3f value = new List { @@ -938,6 +945,60 @@ namespace MinecraftClient.Protocol.Handlers } } + /// + /// Consume bytes for a ResolvableProfile (1.21.9+). + /// Wire: Either(GameProfile, Partial) + PlayerSkin.Patch + /// + private void ReadNextResolvableProfile(Queue cache) + { + bool isFullProfile = ReadNextBool(cache); // Either flag: true=GameProfile, false=Partial + if (isFullProfile) + { + ReadNextUUID(cache); // UUID + ReadNextString(cache); // player name (max 16 chars) + ReadGameProfileProperties(cache); + } + else + { + // Partial: optional name, optional UUID, properties + if (ReadNextBool(cache)) + ReadNextString(cache); // optional player name + if (ReadNextBool(cache)) + ReadNextUUID(cache); // optional UUID + ReadGameProfileProperties(cache); + } + + // PlayerSkin.Patch: 4 optional fields + // body (optional ResourceLocation string) + if (ReadNextBool(cache)) + ReadNextString(cache); + // cape + if (ReadNextBool(cache)) + ReadNextString(cache); + // elytra + if (ReadNextBool(cache)) + ReadNextString(cache); + // model (optional bool: true=SLIM, false=WIDE) + if (ReadNextBool(cache)) + ReadNextBool(cache); + } + + /// + /// Read GameProfile properties (PropertyMap): VarInt count, then per entry: + /// name string, value string, optional signature string. + /// + private void ReadGameProfileProperties(Queue cache) + { + int count = ReadNextVarInt(cache); + for (int i = 0; i < count; i++) + { + ReadNextString(cache); // property name + ReadNextString(cache); // property value + if (ReadNextBool(cache)) // has signature? + ReadNextString(cache); // signature + } + } + /// /// Currently not handled. Reading data only /// diff --git a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs index bcb3f466..6a608dba 100644 --- a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs +++ b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs @@ -48,8 +48,9 @@ namespace MinecraftClient.Protocol.Handlers { PacketTypePalette p = protocol switch { - > Protocol18Handler.MC_1_21_7_Version => throw new NotImplementedException(Translations + > Protocol18Handler.MC_1_21_9_Version => throw new NotImplementedException(Translations .exception_palette_packet), + <= Protocol18Handler.MC_1_21_9_Version and > Protocol18Handler.MC_1_21_7_Version => new PacketPalette1219(), <= Protocol18Handler.MC_1_21_7_Version and > Protocol18Handler.MC_1_21_5_Version => new PacketPalette1216(), <= Protocol18Handler.MC_1_21_5_Version and > Protocol18Handler.MC_1_21_4_Version => new PacketPalette1215(), <= Protocol18Handler.MC_1_21_4_Version and > Protocol18Handler.MC_1_21_2_Version => new PacketPalette1214(),