Commit graph

9 commits

Author SHA1 Message Date
BruceChen
a36ba23ba6 fix: StructuredComponents batch 1 audit — TrimComponent, ProfileComponent, WrittenBookContent, and NBT serialization
Audited all 8 high-complexity structured components against official 1.20.6
decompiled STREAM_CODEC definitions. Found and fixed bugs in 3 components
plus a systemic NBT serialization issue:

TrimComponent (ID 35):
- Serialize had TrimPatternType and ShowInTooltip incorrectly nested inside
  the TrimMaterialType==0 branch; moved them outside to match Parse logic
- Description fields (TrimMaterial.description, TrimPattern.description) were
  read/written as String but official codec uses ComponentSerialization
  (NBT Tag format); changed to ReadNextNbt/GetNbt

ProfileComponent (ID 46):
- Serialize was missing the HasUniqueId Bool prefix before UUID
- Serialize only wrote properties when count > 0 but omitted the VarInt count
  prefix entirely when empty; now always writes VarInt count

WrittenBookContentComponent (ID 34):
- Page content uses Filterable<Component> where Component is NBT-encoded via
  ComponentSerialization.STREAM_CODEC, not plain String; changed Parse to use
  ReadNextNbt and Serialize to use GetNbt
- Added RawContentNbt/FilteredContentNbt fields to BookPage record for
  round-trip NBT preservation
- Removed unnecessary ChatParser.ParseText on title (it's a plain string)

DataTypes.GetNbt:
- Added TAG_String root support for 1.20.4+ (chat components like "Page 1"
  are encoded as TAG_String, not TAG_Compound)
- Fixed root name handling: versions >= 1.20.2 omit the root compound name,
  but GetNbt was unconditionally writing it

Components confirmed correct (no changes needed):
- FoodComponentComponent (ID 20), ToolComponent (ID 22),
  InstrumentComponent (ID 40), PotionContentsComponent (ID 31),
  AttributeModifiersComponent (ID 12)

Made-with: Cursor
2026-03-20 00:09:05 +08:00
BruceChen
79a0dff8cd Fix enchantment name display for 1.20.6 structured components
EnchantmentsComponent (used by both regular and stored enchantments)
was directly casting the registry VarInt ID to the Enchantments enum
via (Enchantments)id. However, the Enchantments enum is ordered
alphabetically (AquaAffinity=0, BaneOfArthropods=1, ..., Sharpness=32)
while the 1.20.6 registry uses a completely different order
(protection=0, fire_protection=1, ..., sharpness=13). This caused all
enchantment names to display incorrectly (e.g. Sharpness V shown as
"Unknown Enchantment with ID: 32").

Changes:
- Parse now uses EnchantmentMapping.GetEnchantmentByRegistryId1206()
  to properly map registry IDs to enum values via the existing
  1.20.6+ mapping table
- Serialize now uses EnchantmentMapping.GetRegistryId1206ByEnchantment()
  to convert enum values back to registry IDs (reverse lookup)
- Fixed translation key prefix: "Enchantments.minecraft." (wrong) ->
  "enchantment.minecraft." (matches en_us.json resource keys)
- Fixed 3 long-standing typos in the Enchantments enum that prevented
  translation lookup from matching resource keys:
  - DepthStrieder -> DepthStrider (depth_strieder vs depth_strider)
  - Efficency -> Efficiency (efficency vs efficiency)
  - Loyality -> Loyalty (loyality vs loyalty)

Verified on vanilla 1.20.6 server: items with sharpness, efficiency,
unbreaking, fortune, mending, and bane_of_arthropods all display
correct localized names (锋利, 效率, 耐久, 时运, 经验修补, 节肢杀手).

Made-with: Cursor
2026-03-19 02:01:15 +08:00
BruceChen
1e2b853b14 Fix PotionContentsComponent and InstrumentComponent serialization for 1.20.6
Both components had incorrect Parse/Serialize implementations that would
cause packet deserialization misalignment when encountered in-game.

PotionContentsComponent (3 bugs):
- Serialize unconditionally wrote VarInt(PotionId) and Int(CustomColor)
  even when HasPotionId/HasCustomColor was false. The official format
  (PotionContents.STREAM_CODEC) uses Optional encoding: Bool(hasValue)
  followed by the value only when true. The extra bytes caused all
  subsequent fields in the packet to be read at wrong offsets.
- Serialize omitted the VarInt(count) prefix for the custom effects list.
  The official codec uses ByteBufCodecs.list() which always writes a
  VarInt count header before the list elements.
- Also fixed typo: PotiononId -> PotionId.

InstrumentComponent (3 bugs):
- The official Instrument.STREAM_CODEC uses ByteBufCodecs.holder() which
  encodes as VarInt(holderId): 0 = inline data, N>0 = registry ref (N-1).
  The SoundEvent field inside uses the same holder pattern. The old code
  unconditionally read SoundName (ResourceLocation) and HasFixedRange/
  FixedRange even when SoundEventHolderId != 0 (registry reference case
  has no inline data).
- UseDuration was read/written as Float, but the official codec uses
  ByteBufCodecs.VAR_INT. This caused a 4-byte vs variable-length
  mismatch that would shift all subsequent data.
- HasFixedRange was read unconditionally when SoundEventHolderId == 0,
  but FixedRange was also read unconditionally. The official SoundEvent
  DIRECT_STREAM_CODEC uses Optional<Float> encoding: Bool(hasValue)
  followed by Float only when true.

These components are used for potion items and goat horns respectively.
Verified against official 1.20.6 decompiled source:
- net.minecraft.world.item.alchemy.PotionContents (STREAM_CODEC)
- net.minecraft.world.item.Instrument (STREAM_CODEC/DIRECT_STREAM_CODEC)
- net.minecraft.sounds.SoundEvent (STREAM_CODEC/DIRECT_STREAM_CODEC)
- net.minecraft.network.codec.ByteBufCodecs (holder/optional/list)

Made-with: Cursor
2026-03-19 01:44:23 +08:00
BruceChen
56f2426c1f Fix StructuredComponent serialization correctness for 1.20.6
Audited all 58 StructuredComponent subclasses against the official Minecraft
1.20.6 decompiled source to verify Parse()/Serialize() symmetry. Found and
fixed four bugs across four components:

1. ContainerComponent: Parse() skipped null item slots (empty slots in a
   container) but Serialize() looped NumberOfItems times using Items[i],
   causing IndexOutOfRangeException when any slot was empty. The official
   ItemContainerContents uses OPTIONAL_STREAM_CODEC which serializes empty
   slots as VarInt(0). Fixed: Parse now stores all slots including nulls,
   Serialize uses Items.Count and iterates all entries. GetItemSlot(null)
   correctly writes VarInt(0) for empty slots.

2. ChargedProjectilesComponent: Used Items.OfType<Item>() in Serialize()
   which silently dropped null entries, causing the serialized count to
   differ from the written VarInt header. The official ChargedProjectiles
   uses STREAM_CODEC (non-optional, no empty slots allowed). Fixed: Items
   list is now List<Item> (non-nullable), Parse defensively skips nulls,
   Serialize writes Items.Count matching the actual list.

3. BundleContentsComponent: Same issue as ChargedProjectilesComponent.
   Applied the same fix pattern.

4. FoodComponentComponent: Two type mismatches vs the official
   FoodProperties.DIRECT_STREAM_CODEC:
   - Saturation was declared as bool and read with ReadNextBool (1 byte),
     but the protocol sends it as float (4 bytes). This caused all
     subsequent fields in the component to be read at wrong offsets,
     corrupting CanAlwaysEat, SecondsToEat, and the effects list.
   - NumberOfEffects was serialized with GetFloat() instead of GetVarInt(),
     writing 4 bytes of IEEE 754 float instead of a variable-length integer.
   Fixed both Parse and Serialize to use correct types.

Also removed redundant NumberOfItems/NumberOfEffects fields from components
where the count is derivable from the list length, and replaced
ArgumentNullException with cleaner patterns.

Tested end-to-end on vanilla 1.20.6 server: item receiving (diamond_sword,
golden_apple, diamond_pickaxe), inventory slot movement (click to pick up
and place), and inventory listing all work correctly with no server-side
protocol errors.

Made-with: Cursor
2026-03-19 01:37:56 +08:00
Anon
7bd213a154 Fixed the potion component crash 2024-12-04 21:25:22 +01:00
Anon
0da4a718cb Implemented all structured components, renamed them all to a better format 2024-10-05 13:37:52 +02:00
Anon
4dea688ca2 Added more structured components 2024-09-11 20:58:24 +02:00
Anon
49319fe781 Added more components + added item palette reference 2024-09-11 20:35:23 +02:00
Anon
76e873ed54 WIP: Added some strctured components 2024-09-11 19:12:31 +02:00