fix: add EntityMetadataPalette1206 for correct 1.20.6+ entity metadata parsing

1.20.6 introduced three new EntityDataSerializer types compared to 1.20.4:
- PARTICLES (id 18) - list of particles, inserted after PARTICLE
- WOLF_VARIANT (id 23) - wolf variant holder, inserted after CAT_VARIANT
- ARMADILLO_STATE (id 28) - armadillo state, inserted after SNIFFER_STATE

These insertions shifted subsequent serializer IDs, causing the 1.19.4
palette (EntityMetadataPalette1194) to misidentify metadata types on
1.20.6+ servers. This could lead to incorrect byte consumption and
potential packet parse failures when entities with affected metadata
types (e.g. wolves, armadillos, area effect clouds with particles)
were present.

Changes:
- Add Particles, WolfVariant, ArmadilloState to EntityMetaDataType enum
- Create EntityMetadataPalette1206 with correct 31-entry ID mapping
- Route 1.20.6+ to the new palette in EntityMetadataPalette.GetPalette()
- Add read logic for the three new types in DataTypes.cs

Verified on 1.21.1 vanilla server: cat, wolf, frog, armadillo, painting
entities all spawn without metadata parse errors.

Made-with: Cursor
This commit is contained in:
BruceChen 2026-03-20 01:43:48 +08:00
parent ee02974abe
commit e1cb18c6f8
4 changed files with 77 additions and 3 deletions

View file

@ -36,6 +36,10 @@ public enum EntityMetaDataType
Nbt,
Particle,
/// <summary>
/// List of Particle (1.20.6+)
/// </summary>
Particles,
/// <summary>
/// VarInt x3
/// </summary>
VillagerData,
@ -48,6 +52,10 @@ public enum EntityMetaDataType
/// VarInt
/// </summary>
CatVariant,
/// <summary>
/// VarInt (1.20.6+)
/// </summary>
WolfVariant,
FrogVariant,
/// <summary>
/// String + Position
@ -66,6 +74,10 @@ public enum EntityMetaDataType
/// </summary>
SnifferState,
/// <summary>
/// VarInt (1.20.6+)
/// </summary>
ArmadilloState,
/// <summary>
/// Float x3
/// </summary>
Vector3,

View file

@ -22,7 +22,8 @@ public abstract class EntityMetadataPalette
<= Protocol18Handler.MC_1_12_2_Version => new EntityMetadataPalette1122(), // 1.9 - 1.12.2
<= Protocol18Handler.MC_1_19_2_Version => new EntityMetadataPalette1191(), // 1.13 - 1.19.2
<= Protocol18Handler.MC_1_19_3_Version => new EntityMetadataPalette1193(), // 1.19.3
<= Protocol18Handler.MC_1_21_Version => new EntityMetadataPalette1194(), // 1.19.4 - 1.21 +
< Protocol18Handler.MC_1_20_6_Version => new EntityMetadataPalette1194(), // 1.19.4 - 1.20.4
<= Protocol18Handler.MC_1_21_Version => new EntityMetadataPalette1206(), // 1.20.6 - 1.21
_ => throw new NotImplementedException()
};
}

View file

@ -0,0 +1,51 @@
using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityMetadataPalettes;
/// <summary>
/// For 1.20.6+
/// Added PARTICLES (id 18), WOLF_VARIANT (id 23), ARMADILLO_STATE (id 28)
/// compared to 1.19.4 palette.
/// </summary>
public class EntityMetadataPalette1206 : EntityMetadataPalette
{
private readonly Dictionary<int, EntityMetaDataType> entityMetadataMappings = new()
{
{ 0, EntityMetaDataType.Byte },
{ 1, EntityMetaDataType.VarInt },
{ 2, EntityMetaDataType.VarLong },
{ 3, EntityMetaDataType.Float },
{ 4, EntityMetaDataType.String },
{ 5, EntityMetaDataType.Chat },
{ 6, EntityMetaDataType.OptionalChat },
{ 7, EntityMetaDataType.Slot },
{ 8, EntityMetaDataType.Boolean },
{ 9, EntityMetaDataType.Rotation },
{ 10, EntityMetaDataType.Position },
{ 11, EntityMetaDataType.OptionalPosition },
{ 12, EntityMetaDataType.Direction },
{ 13, EntityMetaDataType.OptionalUuid },
{ 14, EntityMetaDataType.BlockId },
{ 15, EntityMetaDataType.OptionalBlockId },
{ 16, EntityMetaDataType.Nbt },
{ 17, EntityMetaDataType.Particle },
{ 18, EntityMetaDataType.Particles },
{ 19, EntityMetaDataType.VillagerData },
{ 20, EntityMetaDataType.OptionalVarInt },
{ 21, EntityMetaDataType.Pose },
{ 22, EntityMetaDataType.CatVariant },
{ 23, EntityMetaDataType.WolfVariant },
{ 24, EntityMetaDataType.FrogVariant },
{ 25, EntityMetaDataType.OptionalGlobalPosition },
{ 26, EntityMetaDataType.PaintingVariant },
{ 27, EntityMetaDataType.SnifferState },
{ 28, EntityMetaDataType.ArmadilloState },
{ 29, EntityMetaDataType.Vector3 },
{ 30, EntityMetaDataType.Quaternion },
};
public override Dictionary<int, EntityMetaDataType> GetEntityMetadataMappingsList()
{
return entityMetadataMappings;
}
}

View file

@ -842,9 +842,13 @@ namespace MinecraftClient.Protocol.Handlers
value = ReadNextNbt(cache);
break;
case EntityMetaDataType.Particle: // Particle
// Skip data only, not used
ReadParticleData(cache, itemPalette);
break;
case EntityMetaDataType.Particles: // List of Particle (1.20.6+)
int particleCount = ReadNextVarInt(cache);
for (int i = 0; i < particleCount; i++)
ReadParticleData(cache, itemPalette);
break;
case EntityMetaDataType.VillagerData: // Villager Data (3x VarInt)
value = new List<int>
{
@ -869,7 +873,10 @@ namespace MinecraftClient.Protocol.Handlers
case EntityMetaDataType.CatVariant: // Cat Variant
value = ReadNextVarInt(cache);
break;
case EntityMetaDataType.FrogVariant: // Frog Varint
case EntityMetaDataType.WolfVariant: // Wolf Variant (1.20.6+)
value = ReadNextVarInt(cache);
break;
case EntityMetaDataType.FrogVariant: // Frog Variant
value = ReadNextVarInt(cache);
break;
case EntityMetaDataType.GlobalPosition: // GlobalPos
@ -892,6 +899,9 @@ namespace MinecraftClient.Protocol.Handlers
case EntityMetaDataType.SnifferState: // Sniffer state
value = ReadNextVarInt(cache);
break;
case EntityMetaDataType.ArmadilloState: // Armadillo state (1.20.6+)
value = ReadNextVarInt(cache);
break;
case EntityMetaDataType.Vector3: // Vector 3f
value = new List<float>
{