Commit graph

26 commits

Author SHA1 Message Date
copilot-swe-agent[bot]
654a16907b Modernize data carriers to records and add primary constructors
Convert 14 data carrier classes to records:
- VillagerInfo, MapIcon, EnchantmentData: non-positional records (mutable properties)
- ForgeMod, SkinInfo, VillagerTrade, Node, Response: positional records
- CommandNode: sealed positional record
- CommandArgumentDescriptor: readonly record struct
- ColorRGBA: record struct (multiple constructors preserved)
- RecipeConfig, Recipe, BannerLayer: non-positional records

Add primary constructors to 6 classes:
- DataTypes, Protocol18Terrain, Protocol18Forge, ItemMovingHelper,
  LastSeenMessageList, Acknowledgment, SuggestionTooltip

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-24 01:31:17 +00:00
copilot-swe-agent[bot]
81b756292e Fix all compilation warnings (CS9107, CS8600, CS8604, CS8618, CS0168, CS0169, CS0649)
- Fix CS9107: Replace lowercase primary constructor parameter refs with
  PascalCase base class properties in 90+ StructuredComponent files
- Fix CS8618: Add null! initializers for late-initialized properties
- Fix CS8600: Use nullable out parameters in World.cs, ChatParser.cs
- Fix CS8604: Add null guard in Compiler.cs, fix null-conditional in McClient.cs
- Fix CS0168: Replace unused variable with discard in DataTypes.cs
- Fix CS0169: Remove unused motionY field from McClient.cs
- Fix CS0649: Remove never-assigned steps field, simplify ClientIsMoving()
- Initialize client/handler with null! to avoid CS8618 cascade

Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com>
Agent-Logs-Url: https://github.com/milutinke/Minecraft-Console-Client/sessions/7fcee1b2-21e2-4457-b01b-5e0a1f07752f
2026-03-24 01:25:50 +00:00
copilot-swe-agent[bot]
640a4e39b7 Fix CS9107 warnings: use base class properties instead of captured primary constructor parameters
Replace lowercase primary constructor parameter references (dataTypes.,
subComponentRegistry., itemPalette.) with PascalCase base class property
references (DataTypes., SubComponentRegistry., ItemPalette.) in method
bodies of all StructuredComponent and SubComponent subclasses.

This eliminates CS9107 warnings where subclass primary constructor
parameters shadow the base class properties they are assigned to.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-24 01:16:05 +00:00
copilot-swe-agent[bot]
94bf42710a refactor: use pattern matching for null checks (is null / is not null)
Convert remaining == null to is null and != null to is not null
across 17 files in CommandHandler/ArgumentType, StructuredComponents,
and DeclareCommands for idiomatic C# style.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-24 00:47:03 +00:00
Anon
af405e5632 Fixed Profile Component crashing on 1.21.9 2026-03-22 21:53:13 +01:00
BruceChen
c0c4c078c0 fix: use HashedStack for container_click and fix enchantments parsing for 1.21.5+
Two bugs fixed:

1. EnchantmentsComponent was reading a trailing ShowTooltip boolean that
   was removed from the wire format in MC 1.21.5. Created
   EnchantmentsComponent1215 and StoredEnchantmentsComponent1215 that
   omit the boolean. Used by StructuredComponentsRegistry1215 and 12111.

2. MC 1.21.5+ changed ServerboundContainerClickPacket to use HashedStack
   (item holder id + count + hashed component patch map) instead of full
   ItemStack for changed slots and carried item. Added GetHashedItemSlot()
   in DataTypes.cs and gated SendWindowAction in Protocol18.cs to use it
   for 1.21.5+. Since MCC doesn't track component hashes, an empty
   HashedPatchMap is sent; the server detects stateId mismatch and resyncs.

Tested: AutoFishing bot successfully catches fish on MC 1.21.11 with
enchanted fishing rods (Lure III + Luck of the Sea III).

Made-with: Cursor
2026-03-22 02:18:01 +08:00
BruceChen
6c36dc341a feat: add version routing, structured components, and metadata for MC 1.21.11
- Add MC_1_21_11_Version constant (protocol 774)
- Create StructuredComponentsRegistry12111 with 104 components (8 new:
  use_effects, minimum_attack_charge, damage_type, attack_range,
  piercing_weapon, kinetic_weapon, swing_animation, zombie_nautilus/variant)
- Add 6 new component classes for 1.21.11 wire formats
- Add RegistryEitherHolderComponent for holderRegistry-backed EitherHolder
- Add ZombieNautilusVariant and HumanoidArm cases in DataTypes.ReadNextMetadata
- Update all version routing in Protocol18, PacketType18Handler,
  EntityMetadataPalette, StructuredComponentsHandler, and ProtocolHandler
- Bump MCHighestVersion to 1.21.11

Made-with: Cursor
2026-03-22 00:56:04 +08:00
BruceChen
8df39ba74a feat: add MC 1.21.5 (protocol 770) support
Full protocol adaptation for Minecraft 1.21.5:

- Protocol version mapping: 770 -> 1.21.5
- Packet palette: AddExperienceOrb removed (S2C), TestInstanceBlockStatus
  added (S2C), SetTestBlock and TestInstanceBlockAction added (C2S)
- Entity metadata palette: 5 new serializer types (OptionalLivingEntityReference,
  CowVariant, WolfSoundVariant, PigVariant, ChickenVariant), OPTIONAL_UUID
  replaced by OPTIONAL_LIVING_ENTITY_REFERENCE
- Item palette: 11 new items (Bush, FireflyBush, DryShortGrass, DryTallGrass,
  Wildflowers, LeafLitter, CactusFlower, TestBlock, TestInstanceBlock,
  BlueEgg, BrownEgg)
- Entity palette: Potion split into SplashPotion and LingeringPotion
- Block palette: 9 new blocks (bush, cactus_flower, firefly_bush, leaf_litter,
  short_dry_grass, tall_dry_grass, test_block, test_instance_block, wildflowers)
- Structured components: 31 new components including tooltip_display, weapon,
  blocks_attacks, potion_duration_scale, provides_trim_material,
  provides_banner_patterns, break_sound, and 25 entity variant components;
  unbreakable changed from Bool to Unit; instrument changed to EitherHolder

Made-with: Cursor
2026-03-21 00:48:27 +08:00
BruceChen
57a0dedb33 feat: add packet palette, data components, and protocol fixes for MC 1.21.2
Packet Palette (Phase 2.1):
- Create PacketPalette1212.cs with complete ID mapping for protocol 768
  (131 clientbound + 60 serverbound play packets, plus config packets)
- Add new PacketTypesIn enum values: EntityPositionSync, MoveMinecartAlongTrack,
  PlayerRotation, RecipeBookAdd/Remove/Settings, SetCursorItem, SetHeldSlot,
  SetPlayerInventory
- Add new PacketTypesOut enum values: BundleItemSelected, ClientTickEnd
- Update PacketType18Handler routing for 1.21.2

Data Components (Phase 1.4):
- Create StructuredComponentsRegistry1212 with 67 components (was 57 in 1.21)
  reflecting the new 1.21.2 DataComponents ordering
- Implement 11 new component parsers: ConsumableComponent, UseRemainderComponent,
  UseCooldownComponent, DamageResistantComponent, EnchantableComponent,
  EquippableComponent, RepairableComponent, GliderComponent, TooltipStyleComponent,
  DeathProtectionComponent, ItemModelComponent
- Create FoodComponent1212 (simplified: nutrition/saturation/canAlwaysEat only;
  eatSeconds/effects/usingConvertsTo moved to consumable/use_remainder)
- Create SubComponentRegistry1212 and route in StructuredComponentsHandler

Protocol Fixes:
- Fix PlayerPositionAndLook packet for 1.21.2 (new format: teleportId first,
  added deltaMovement Vec3, flags as Int instead of Byte)
- Fix login success packet (remove strictErrorHandling read for >= 1.21.2)
- Fix ClientSettings/ClientInformation packet (add particleStatus VarInt)
- Add SetHeldSlot as alias for HeldItemChange in packet handler

Verified: MCC connects to 1.21.2 vanilla server, stays connected, chat works.
Made-with: Cursor
2026-03-20 03:25:20 +08:00
BruceChen
896263acc8 fix: resolve entity tracking, container interaction, and enchantment mapping issues for 1.21
- SpawnEntity packet handler now registers non-player entities via OnSpawnEntity
  for protocol >= 1.20.2 (previously only players were tracked, causing 'entity near'
  to find nothing)
- PlaceBlock gains lookAtBlock option that sends a position/rotation update before the
  block placement packet, fixing containers not opening via useblock
- Enchantment registry IDs are now dynamically parsed from server RegistryData
  (minecraft:enchantment), fixing incorrect enchantment name display in 1.21
- AttributeModifiersComponent uses base SubComponent type to avoid InvalidCastException
  when parsing 1.21-specific attribute subcomponents

Made-with: Cursor
2026-03-20 02:35:52 +08:00
BruceChen
c23c229eb2 feat: protocol 767 (1.21) packet handling and AttributeSubComponent update
- Add AttributeSubComponent121 that uses ResourceLocation(string) instead
  of UUID+Name, matching the 1.21 attribute modifier wire format change.
  Register it in SubComponentRegistry121 via new ReplaceSubComponent method.
- Add ProjectilePower packet handler: reads 1 double (accelerationPower)
  for 1.21+, or 3 doubles (xPower/yPower/zPower) for 1.20.6.
- Add CustomReportDetails and ServerLinks packet handlers in both Play
  and Configuration phases, consuming all fields to prevent byte offset
  errors on 1.21 servers.

Made-with: Cursor
2026-03-20 01:22:25 +08:00
BruceChen
cc10f4effa refactor: StructuredComponents batch 5 audit — remove redundant count fields
Audited batch 5 components (ChargedProjectiles, BundleContents, Container,
WritableBookContent, BlockState, PotDecorations) against official 1.20.6
decompiled STREAM_CODEC definitions. All network encodings were correct.

Removed redundant NumberOfItems/NumberOfPages/NumberOfProperties fields from
ContainerComponent, WritableBlookContentComponent, BlockStateComponent, and
PotDecorationsComponent. Serialize now uses the actual collection .Count
instead of a potentially stale cached value, matching the pattern already
used by ContainerComponent's Serialize and other components.

Also modernized loop style (foreach with deconstruction where applicable)
and fixed a typo in an exception message ("setialize" -> "serialize").

Made-with: Cursor
2026-03-20 00:45:50 +08:00
BruceChen
5e416d6b72 fix: StructuredComponents batch 4 audit — CustomName, ItemName, Lore use NBT encoding
In 1.20.6+, ComponentSerialization.STREAM_CODEC uses
ByteBufCodecs.fromCodecWithRegistries (NBT tag format), not plain string.
The previous implementation incorrectly used ReadNextString/GetString
for custom_name (5), item_name (6), and lore (7) components.

Fixed all three to use ReadNextNbt/GetNbt, preserving raw NBT data for
round-trip serialization while still extracting readable text via
ChatParser.ParseText(Dictionary).

Other batch 4 components (custom_data, entity_data, bucket_entity_data,
block_entity_data, debug_stick_state, map_decorations, recipes, lock,
container_loot, intangible_projectile — all NBT; hide_additional_tooltip,
hide_tooltip, fire_resistant, creative_slot_lock — all Unit/Empty;
note_block_sound — ResourceLocation string) were verified correct.

Made-with: Cursor
2026-03-20 00:33:50 +08:00
BruceChen
c689343371 fix: StructuredComponents batch 3 audit — EnchantmentGlintOverrideComponent type correction
Audited all 14 simple binary components (batch 3): max_stack_size,
max_damage, damage, unbreakable, rarity, custom_model_data, repair_cost,
enchantment_glint_override, ominous_bottle_amplifier, dyed_color,
map_color, map_id, map_post_processing, base_color.

Found and fixed 1 bug:
- EnchantmentGlintOverrideComponent: was reading/writing VarInt but the
  official STREAM_CODEC uses ByteBufCodecs.BOOL (single byte boolean).
  Changed property type from int to bool, Parse from ReadNextVarInt to
  ReadNextBool, and Serialize from GetVarInt to GetBool.

All other 13 components matched the official 1.20.6 STREAM_CODEC
definitions exactly.

Verified in-game: connected to 1.20.6 vanilla server, received items
with enchantment_glint_override=true/false, dyed_color, map_color,
map_id, base_color, unbreakable, rarity, custom_model_data, repair_cost,
damage, max_damage. All parsed and serialized correctly with no errors.

Made-with: Cursor
2026-03-20 00:25:28 +08:00
BruceChen
4944497f5a fix: StructuredComponents batch 2 audit — BlockPredicate and PropertySubComponent serialization
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
2026-03-20 00:19:08 +08:00
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
f83e7c5707 Preliminary 1.21 Support 2024-12-06 16:45:48 +01: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
Anon
63b027d84a First Version of Structured Components 2024-09-01 20:42:39 +02:00