From 4944497f5a92e1a7e899351f59c4b7e518b033f9 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 00:19:08 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20StructuredComponents=20batch=202=20audit?= =?UTF-8?q?=20=E2=80=94=20BlockPredicate=20and=20PropertySubComponent=20se?= =?UTF-8?q?rialization?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audited all 8 batch-2 components (enchantments, stored_enchantments, can_place_on, can_break, lodestone_tracker, firework_explosion, fireworks, banner_patterns, suspicious_stew_effects, bees) against official 1.20.6 decompiled STREAM_CODEC definitions. Found and fixed 3 bugs in BlockPredicate/PropertySubComponent: 1. BlockPredicateSubcomponent.Serialize(): missing HasNbt bool write. Parse reads the bool but Serialize skipped writing it, causing all subsequent fields to be offset by one byte. 2. BlockPredicateSubcomponent.Serialize(): missing Properties list count VarInt write. Parse reads VarInt count before iterating, but Serialize only wrote the elements without the preceding count. 3. PropertySubComponent: RangedMatcher min/max values must use Optional encoding (Bool prefix + conditional String), matching the official ByteBufCodecs.either(ExactMatcher, RangedMatcher) where RangedMatcher uses ByteBufCodecs.optional(STRING_UTF8) for both min and max fields. Previously read/wrote plain Strings unconditionally. Remaining 6 components (enchantments, stored_enchantments, lodestone_tracker, firework_explosion, fireworks, banner_patterns, suspicious_stew_effects, bees) verified correct — no changes needed. Made-with: Cursor --- .../1_20_6/BlockPredicateSubcomponent.cs | 4 +++- .../1_20_6/PropertySubComponent.cs | 20 +++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent.cs index 9a562840..c8bf2369 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent.cs @@ -50,18 +50,20 @@ public class BlockPredicateSubcomponent(DataTypes dataTypes, SubComponentRegistr data.AddRange(BlockSet.Serialize()); } - // Properites + // Properties data.AddRange(DataTypes.GetBool(HasProperities)); if (HasProperities) { if(Properties == null || Properties.Count == 0) throw new ArgumentNullException($"Can not serialize a BlockPredicate when the Properties is empty but HasProperties is true!"); + data.AddRange(DataTypes.GetVarInt(Properties.Count)); foreach (var property in Properties) data.AddRange(property.Serialize()); } // NBT + data.AddRange(DataTypes.GetBool(HasNbt)); if (HasNbt) { if(Nbt == null) diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent.cs index 0b8e41eb..6170dffa 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent.cs @@ -18,11 +18,13 @@ public class PropertySubComponent(DataTypes dataTypes, SubComponentRegistry subC IsExactMatch = dataTypes.ReadNextBool(data); if (IsExactMatch) - ExactValue = dataTypes.ReadNextString(data); - else // Ranged Match { - MinValue = dataTypes.ReadNextString(data); - MaxValue = dataTypes.ReadNextString(data); + ExactValue = dataTypes.ReadNextString(data); + } + else + { + MinValue = dataTypes.ReadNextBool(data) ? dataTypes.ReadNextString(data) : null; + MaxValue = dataTypes.ReadNextBool(data) ? dataTypes.ReadNextString(data) : null; } } @@ -45,11 +47,13 @@ public class PropertySubComponent(DataTypes dataTypes, SubComponentRegistry subC } else { - if (string.IsNullOrEmpty(MinValue?.Trim()) || string.IsNullOrEmpty(MaxValue?.Trim())) - throw new ArgumentNullException($"Can not serialize a Property sub-component if the MinValue or MaxValue is null or empty when the type is not Exact Match!"); + data.AddRange(DataTypes.GetBool(MinValue != null)); + if (MinValue != null) + data.AddRange(DataTypes.GetString(MinValue)); - data.AddRange(DataTypes.GetString(MinValue)); - data.AddRange(DataTypes.GetString(MaxValue)); + data.AddRange(DataTypes.GetBool(MaxValue != null)); + if (MaxValue != null) + data.AddRange(DataTypes.GetString(MaxValue)); } return new Queue(data);