pc 26.3: protocol and data fixes for 26.3 (stacked on #1300) - #1301
DallasCarraher wants to merge 26 commits into
Conversation
Co-authored-by: extremeheat <13713600+extremeheat@users.noreply.github.com>
Registers protocol 776 (26.2) with real generated data: blocks, items, entities, recipes, language, commands, protocol.json (regenerated from proto.yml), loot tables, and the rest of the per-version files. Also adds a 1.20.3 windows.json with the crafter menu (missing since 1.20.3) so 26.2's windows entry is accurate. Extracted from the 26.2 portion of PrismarineJS#1287, which additionally carries unrelated fixes for 1.13.1, 1.14.2, 1.9.1 and a broader commands.json refresh across older versions. This commit isolates just the 26.2 data so it can be reviewed and merged independently of that larger changeset. effects/enchantments/instruments are borrowed from 26.1 since those registries are unchanged in 26.2. Full mocha suite passes (1887 passing, 1 pending, 0 failing). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Addresses review feedback on this PR: - sulfur_cube_content duplicated ItemStackTemplate's shape inline instead of referencing it. Verified against the real 26.2 server jar: net.minecraft.world.item.component.SulfurCubeContent is a record with a single field of type net.minecraft.world.item.ItemStackTemplate (no array wrapper) — Mojang's own internal type has the same name and shape minecraft-data already used. Now just `if sulfur_cube_content: ItemStackTemplate`. - packet_spectator_action: verified this is a genuine rename, not a new packet alongside the old one. Decompiled the real 26.2 server jar: net/minecraft/network/protocol/game/ServerboundSpectatorActionPacket exists (a Record with one field, `OptionalInt spectateEntityId`, handled via `handleSpectatorAction`); no ServerboundSpectateEntityPacket class exists anywhere in the jar. Matches this PR's existing encoding (`entityId?: varint`) exactly — no data change needed for this one. - Separately: rebasing this branch onto pc_26_2 silently regressed PrismarineJS#1267's ItemStackTemplate fix throughout data/pc/latest/proto.yml — git's merge applied both sides' overlapping edits to this file in a way that dropped PrismarineJS#1267's hunks without flagging a conflict. Restored all of it (intangible_projectile NBT, and ItemStackTemplate at use_remainder/charged_projectiles/bundle_contents/container/particle item/SlotDisplay item_stack/advancement icon) and regenerated data/pc/26.2/protocol.json from the corrected proto.yml. Full test suite still green: 1887 passing, 1 pending, 0 failing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ng, cubemob metadata, bee size, knockback_resistance min All five verified by decompiling the real 26.2 server jar (versions/26.2/server-26.2.jar) with CFR, cross-referenced against extremeheat/extracted_minecraft_data where cited in review. - packet_entity_teleport: the pc_26_2 rebase also silently dropped PrismarineJS#1273's 1.21.2+ layout fix (dx/dy/dz, f32 yaw/pitch, PositionUpdateRelatives flags) the same way it dropped PrismarineJS#1267's ItemStackTemplate fix. Restored — ClientboundTeleportEntityPacket still uses PositionMoveRotation in 26.2, confirmed against the real class. - packet_spectator_action: entityId?: varint (protodef presence-byte optional) doesn't match vanilla's wire format. Decompiled ByteBufCodecs.OPTIONAL_VAR_INT: it maps a single raw VarInt directly (no separate presence byte) — 0 = absent, n = entity id (n - 1). Changed to `entityId: optvarint`, the same sentinel-varint alias already used for entity metadata's optional_block_state/ optional_unsigned_int. - data/pc/26.2/entities.json: slime/magma_cube/sulfur_cube were missing the `baby`/`age_locked` metadata keys AgeableMob defines (confirmed via SynchedEntityData.defineId call order in AgeableMob/AbstractCubeMob/SulfurCube bytecode), and sulfur_cube had max_fuse/from_bucket swapped. Fixed all three to mob_flags, baby, age_locked, size, max_fuse, from_bucket. - bee width/height: EntityTypes.BEE registers .sized(0.55f, 0.5f) in 26.2; entities.json still had 26.1's 0.7/0.6. Fixed. - data/pc/26.2/attributes.json: knockbackResistance's min was 0.0; Attributes.KNOCKBACK_RESISTANCE registers RangedAttribute(default 0.0, min -2.0, max 1.0). Fixed. Full test suite still green: 1887 passing, 1 pending, 0 failing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
# Conflicts: # data/dataPaths.json # data/pc/common/versions.json # data/pc/latest/proto.yml
Two independent gaps found live-testing 26.3 against a real Realm with mineflayer: - packet_success (login, toClient) was missing the sessionId: UUID field that 26.2 (protocol 776) already added. Client-side parsing under-read every login success packet by 16 bytes. - configuration.toClient's packet ID table was missing CLIENTBOUND_POST_EFFECTS at 0x0a, shifting every packet from store_cookie (0x0b) through code_of_conduct (0x14) down by one slot versus the real server. Confirmed by decompiling net.minecraft.network.protocol.configuration.ConfigurationProtocols from the official 26.3 server jar and reading addPacket() call order (same technique as PrismarineJS#1298/26.1.2's packet ID fixes). Concretely, ID 0x0f was mapped to custom_report_details but is actually select_known_packs — since mineflayer's client.once('select_known_packs') listener never fired under the wrong name, the client never sent the required response, and the server silently stalled in the configuration state forever (steady keep_alive, nothing else). Added packet_post_effects (a single postEffects: List<Identifier> field, confirmed via javap on ClientboundPostEffectsPacket's STREAM_CODEC) and resequenced 0x0a-0x14 to match. With both fixes, a real client now completes the full configuration handshake (select_known_packs -> registry_data -> tags -> finish_configuration) and enters the play state. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Live-testing against a real 26.3 Realm (with the configuration-state fix from 12aa21b already applied) got the bot into the play state, but it immediately misread the join-game packet as low_disk_space_warning and crashed decoding a player_chat-shaped packet. Same root cause as the configuration-state bug: Mojang inserted new packets between 26.1.2 and 26.3 (net.minecraft.network.protocol.game.GameProtocols), shifting every later packet ID by one or more slots versus what protocol.json had. Decompiled the official 26.3 server jar's GameProtocols class (deobfuscated, per PrismarineJS/mineflayer#3888's proven method for the same bug class at protocol 775) to get the true addPacket() registration order for both play.toClient (144 packets) and play.toServer (69 packets), then programmatically realigned the existing packet name tables against that ground truth, preserving names for unchanged packets and identifying genuinely new ones with no prior schema: - clientbound: add_transient_block, swing_animation, and post_effects (the same new packet from the configuration-state fix, now also sent in play state and copied into play.toClient.types) - serverbound: punch (replaces the old arm_animation/swing packet) and spectator_action (new OptionalInt entity id, distinct from the existing teleport_to_entity packet, which keeps the old "spectate" semantics) Field layouts for the new packets were read directly from each class's STREAM_CODEC via javap rather than guessed from wire bytes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ortation schema Found live-testing against a 26.3 Realm right after the play-state packet ID drift fix (previous commit): the bot entered play, correctly parsed the join-game and a wide range of world/entity packets, then got kicked with "Failed to decode packet 'serverbound/minecraft:accept_teleportation'" the first time it echoed a teleport confirmation back. Decompiling ServerboundAcceptTeleportationPacket from the 26.3 server jar shows Mojang widened this packet beyond the old single teleportId varint - it now also carries the x/y/z/yRot/xRot being confirmed. protocol.json still only declared teleportId, so the fields minecraft-protocol's compiler had never seen in this schema were of course not on the wire the server required, and it rejected the payload as malformed rather than an unknown extra field. Companion fix in mineflayer's physics.js populates the new fields; sending them is a no-op on older protocol versions since protodef only serializes fields declared for the running schema. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Found live-testing against a 26.3 Realm: after the play-state ID and teleport_confirm fixes (previous two commits), the bot got much further - correctly parsed login and dozens of packet types, including block entities with legible NBT (sign text decoded perfectly) - but crashed in prismarine-chunk's loadParsedLight with a light-section array coming up far short of what the corresponding mask claimed. Decompiled ByteBufCodecs.BIT_SET from the official 26.3 server jar (the codec used for skyLightMask/blockLightMask/emptySkyLightMask/ emptyBlockLightMask in ClientboundLightUpdatePacketData): it now calls FriendlyByteBuf.readByteArray()/writeByteArray() + BitSet.valueOf(byte[]), not the varint-count-of-longs encoding every other supported version uses (confirmed against the still-correct 1.21.9/773 schema, which uses readLongArray()/BitSet.valueOf(long[]) for the same codec). Manually decoding a captured chunk packet byte-for-byte confirmed it: reading the masks as longs produced impossible bit positions (up to 120, for a chunk with far fewer than 120 sections) while reading them as raw bytes lines up exactly with the real per-section light data that follows. Companion prismarine-chunk fix (BitArray.fromByteArray, version-gated to 26.3+) is in the pc-26.3 branch there. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Found live-testing mineflayer against a local 26.3 server: decompiling ServerGamePacketListenerImpl showed the server only clears its per-tick receivedPositionThisTick/receivedMovementThisTick bookkeeping when it receives a serverbound tick_end packet (handleClientTickEnd). A client that never sends tick_end gets that flag stuck true after its first position-bearing move packet, so the *second* one ever sent -- no matter how much later -- gets it kicked with multiplayer.disconnect.invalid_player_movement. The tick_end packet (empty container, protocol name "tick_end") has existed in the wire protocol since 1.21.3, but nothing in prismarine land currently sends it. Add a feature flag so client implementations can gate sending it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Tested this branch against a real Paper 26.3-8-dev server (protocol 777) and found two more packet differences that cause read errors on every connection. Both verified by decompiling the classes from 1.
|
Follow-up: 26.3 also needs its own
|
| entity | 26.1 | 26.3 (measured) | delta |
|---|---|---|---|
| cow | 30 | 30 | 0 |
| donkey | 36 | 37 | +1 |
| egg | 39 | 40 | +1 |
| ender_dragon | 43 | 44 | +1 |
| experience_orb | 49 | 50 | +1 |
| item | 71 | 72 | +1 |
| skeleton | 115 | 118 | +3 |
| wither_skull | 147 | 151 | +4 |
| wolf | 148 | 152 | +4 |
| zombie | 150 | 154 | +4 |
Shift boundaries look like ID 33-36 (+1), 146-147 (+4), 149-150 (+5).
Symptom
Items lying in the world decode as item_display instead of item, so they
never appear in bot.entities and collect_item-style logic can never see
them. entity_metadata is affected too (e.g. particle → sonic_boom values
misalign and trigger PartialReadError).
Also: packet_recipe_book_add
The IDSet inside RecipeDisplayEntry.craftingRequirements still partial-reads
(Unexpected buffer end while reading VarInt). Since RecipeDisplayEntry's
field list matches the decompiled class otherwise, I suspect the IDSet
(HolderSet) shape rather than the entry itself. I worked around it by replacing
the packet's type with restBuffer (keeps the packet ID mapping intact, just
discards the body) — login, chunks, movement and entity sync all work with that.
Happy to open a PR with the full measured table and a patched pc/26.3/entities.json
(putting the 29 non-summonable entities into the remaining free IDs) if useful.
Thanks again for this branch.
… fields Per review on PrismarineJS#1301 (@maebahesioru, verified against a live Paper 26.3-8-dev / protocol 777 server and by decompiling paper-26.3.jar): - packet_login (play/toClient) was missing onlineMode: bool, added by 26.3 between worldState and enforcesSecureChat. Every login packet was under-reading by exactly 1 byte without it. - packet_advancements (play/toClient) advancementMapping entries are now PositionedAdvancement records: appended x: f32 and y: f32 after sendsTelemtryData. Without them the packet over-read badly.
rel_entity_move / entity_move_look / sync_entity_position all crashed with
"Chunk size is N but only M was read" / PartialReadError once more than one
entity was nearby, because 26.3 replaced the old flat delta encodings with
new ones (decompiled from the real 26.3 server jar):
- ClientboundMoveEntityPacket (rel_entity_move / entity_move_look): the old
3x-i16 dX/dY/dZ is gone. It's now a packed `properties` varint (bit 0 =
onGround, remaining bits = stepCount via VecDelta's packProperties/
unpackStepCount) followed by either the old flat 3x-i16 format when
stepCount <= 0, or `stepCount` chained {ticks: varint, dX, dY, dZ: i16}
DeltaStep entries when an entity's position wasn't sent every tick. A
lone, regularly-ticked entity almost always hits the stepCount<=0 path,
which is why this needed several nearby mobs/players to reproduce.
Handled via a new custom protodef type (`entityDelta`, registered in
node-minecraft-protocol) since the sub-count depends on a runtime-derived
value (properties >>> 1), which plain declarative container/switch can't
express.
- ClientboundEntityPositionSyncPacket (sync_entity_position): the old flat
x/y/z/dx/dy/dz fields are gone. `position` is now a PositionPath: a
varint type discriminator (0 = Linear, an absolute x/y/z f64) or (1 =
Stepped, a varint-counted list of {x, y, z: f64, tickOffset: varint}
absolute-position steps). Unlike VecDelta this carries full double
positions per step, not fixed-point shorts, so it's expressed with plain
declarative mapper+switch+array, no custom type needed.
Confirmed via `javap -c -p` on VecDelta, VecDelta$Stepped$DeltaStep,
ClientboundMoveEntityPacket(.Pos/.PosRot), PositionPath(.Linear/.Stepped),
PositionStep and their STREAM_CODECs in the real 26.3 server jar.
protodef's container SizeOf compiler can only inline an `anon: true` field
when its type is a literal inline ["container", ...] or ["switch", ...]
array (see containerInlining() in protodef's compiler-structures.js) --
not a bare string reference to a registered native type, even a
container-shaped one. Referencing the custom `entityDelta` type as an anon
field blew up the compiled protocol with "Cannot inline anonymous type:
entityDelta" as soon as a client actually connected (caught by testing
against a local 26.3 server with multiple moving entities, not just
unit-testing the type's read/write/sizeOf in isolation).
Give it a real field name ("move") instead: packet_rel_entity_move /
packet_entity_move_look now have `move: { onGround, steps }` rather than
flattened onGround/steps fields at the packet root. Paired with the
mineflayer change reading packet.move.steps instead of packet.steps.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Follow-up to 2fc2152 (fix packet_login onlineMode and packet_advancements position fields). That commit correctly identified that advancement entries now carry an x/y position pair, but placed it wrong: it added x/y *inside* the Advancement container (after sendsTelemtryData) while *also* leaving the pre-26.3 xCord/yCord fields inside displayData. That duplicate/misplaced pair caused catastrophic misalignment on the next advancements packet (PartialReadError: string field expecting a size >1MB), since every Advancement carried two extra floats that aren't actually on the wire there. Root cause, decompiled from the real 26.3 server jar (ClientboundUpdateAdvancementsPacket, $PositionedAdvancement, AdvancementHolder, Advancement, DisplayInfo, AdvancementRequirements, AdvancementProgress, CriterionProgress STREAM_CODECs): - ClientboundUpdateAdvancementsPacket.added is a List<PositionedAdvancement>, not a map keyed by id directly. - PositionedAdvancement.STREAM_CODEC = composite(AdvancementHolder, x: f32, y: f32) -- x/y are siblings of the advancement itself, not fields inside it. - AdvancementHolder.STREAM_CODEC = composite(id: Identifier, value: Advancement) -- matches the existing key/value entry shape. - Advancement.STREAM_CODEC only sends 4 fields: parent (optional Identifier), display (optional DisplayInfo), requirements (AdvancementRequirements), sendsTelemetryEvent (bool). rewards/criteria/ name are server-only and never hit the wire. - DisplayInfo.STREAM_CODEC has no x/y at all anymore (title, description, icon, type, flags int, optional background identifier) -- the xCord/yCord fields inside displayData are stale leftovers from an older MC version's layout and don't exist on 26.3's wire format. - AdvancementRequirements (array<array<string>>), AdvancementProgress (map<string, CriterionProgress>), and CriterionProgress (option<Instant>) were also checked against their STREAM_CODECs and match the existing requirements/progressMapping/criterionProgress schema, so those were left alone. Fix: remove xCord/yCord from inside displayData, and move x/y out of the advancementMapping entry's `value` container to be siblings of `key`/ `value` at the entry level, matching PositionedAdvancement{advancement: {id, value}, x, y}. Note: this commit only touches the packet_advancements region. The working tree also has unrelated in-progress changes to the metadata_entry switch table (recipe_book_add/entity_metadata work, a separate concurrent task) -- staged and committed this fix as an isolated blob built from HEAD plus only this change, to avoid stepping on that work. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Pushed a follow-up commit (0604243) fixing the `packet_advancements` schema properly. The previous commit in this PR (2fc2152) correctly identified that Re-decompiled the 26.3 server jar end to end this time (
Verified with a schema-level round-trip test (serialize a sample |
…ale dataPaths row dataPaths.json's pc["26.3"].entities pointed at pc/26.1 — two versions stale, not even pc/26.2. Since 26.1->26.2 already shifted 28 entity internalIds (including player 155->156) from newly inserted entity types, and 26.3 sits two versions past that, the stale pointer meant mineflayer's entityDataByInternalId table looked up the wrong internalId for every spawn_entity packet: player entities were never recognized as type 'player', so bot.players[username].entity never linked up. Symptom: "Can't see player X nearby" even standing right next to them. Root cause confirmed by decompiling the 26.3 server jar's net.minecraft.world.entity.EntityTypes static initializer (the actual entity registration order, not the alphabetical EntityTypeIds constants) via javap bytecode. Diffing that 161-entry registration order against pc/26.2's 158-entry entities.json shows a clean insertion-only diff: 3 new entities (cushion, poplar_boat, poplar_chest_boat), zero removals, zero reordering elsewhere. player moves from internalId 156 (26.2) to 159 (26.3). New entities' dimensions/category/ metadata were read from their EntityType.Builder registration calls and defineSynchedData bytecode in the same decompile. Also audited the rest of the pc["26.3"] dataPaths row: it was a verbatim copy of the pc["26.1"] row with only protocol/version bumped, missing the wave of updates pc["26.2"]'s row already picked up from 26.1 (attributes, blocks, items, biomes, blockCollisionShapes, blockLoot, commands, entityLoot, foods, language, loginPacket, materials, particles, recipes, sounds, tints, windows). Repointed all of those to pc/26.2 as a strict improvement (1-version-stale using already-known- good data, vs. 2-versions-stale) without decompile-regenerating each one; left effects/enchantments/instruments/mapIcons alone since pc/26.2's row also keeps those at their older pointers, suggesting they're legitimately unchanged. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…icle registry IDs, and world_particles layout Four related protodef bugs found live against a real 26.3 Realm and a local offline-mode 26.3 test server (DEBUG=minecraft-protocol), all traced to the same root cause: several enum/registry orderings drifted in 26.3 and the schema still used their pre-26.3 numbering. 1. entityMetadataEntry's `type` mapper (byte/int/.../particles/...) was the pre-26.3 EntityDataSerializers order. Decompiling net.minecraft.network.syncher.EntityDataSerializers's static initializer (registerSerializer() call order) shows optional_uuid was removed entirely in 26.3 and replaced by optional_living_entity_reference (still wire- compatible, still a plain UUID), and boolean/rotations/block_pos/ optional_block_pos/direction/block_state/optional_block_state/particle/ particles were all reshuffled around it. Renumbered all 44 entries and added the two new ones (optional_living_entity_reference, dye_color). This was the direct cause of the reported "Chunk size is 18 but only 14 was read" on a sonic_boom particles entry. 2. SlotDisplay's "tag" variant (used inside RecipeDisplay ingredients and packet_recipe_book_add's craftingRequirements) was typed as a plain "string", but TagSlotDisplay.STREAM_CODEC decompiles to ByteBufCodecs.holderSet(Registries.ITEM) -- the same registryEntryHolderSet (IDSet) encoding used everywhere else, not a bare tag-name string. Fixed to "IDSet". This was the actual cause of the reported "PartialReadError ... reading VarInt" on packet_recipe_book_add: a 0x00 discriminator byte (IDSet's "named tag" case) was being misread as a zero-length string, shifting every subsequent SlotDisplay's type byte by one field. 3. The "Particle" container's own `type` mapper (angry_villager/block/.../ sonic_boom/...) was also pre-26.3: decompiling net.minecraft.core.particles.ParticleTypes's static initializer (registerXxx() call order against BuiltInRegistries.PARTICLE_TYPE) gives a completely different, longer ordering -- 128 entries vs the old ~117, with new geyser/geyser_base/geyser_poof/geyser_plume/sulfur_bubbles/ noxious_gas(_cloud)/red_poplar_leaves/orange_poplar_leaves/ yellow_poplar_leaves/sulfur_cube_goo types inserted and trial_spawner_detected_player(_ominous) renamed to trial_spawner_detection(_ominous). sonic_boom moved 28->35, note moved 58->68 (a byte that used to mean "note" now means "vibration"), etc. Rebuilt the full 128-entry mapper from the decompiled order and added data-switch cases for the four new geyser variants (GeyserParticleOptions/ GeyserBaseParticleOptions STREAM_CODECs: waterBlocks:i32, plus burstImpulseBase:f32 for the non-plain geyser variants). This mapper is shared by entity_metadata's particle/particles fields and by packet_world_particles, so it was silently corrupting both. 4. packet_world_particles (ClientboundLevelParticlesPacket) itself had a stale pre-26.x field layout: `particle` used to be the last field with flat offsetX/Y/Z + a single velocityOffset float + an i32 amount. The 26.3 STREAM_CODEC (decompiled composite(...)) puts `particle` FIRST, has six float fields (xDist/yDist/zDist/xMaxSpeed/yMaxSpeed/zMaxSpeed, not four), amount is a varint not i32, and there's a new trailing randomizationType enum (default/alternative/alternative_with_speed) that didn't exist before. Found live once particle mapper fix PrismarineJS#3 above stopped masking it (was reading a real "vibration" particle's sub-payload as if it were the void "note" particle, corrupting everything after it). All four confirmed against the real 26.3 server jar (net.minecraft.network.syncher.EntityDataSerializers, net.minecraft.core.particles.ParticleTypes/ParticleType/GeyserParticleOptions/ GeyserBaseParticleOptions, net.minecraft.world.item.crafting.display. SlotDisplay$TagSlotDisplay, net.minecraft.network.protocol.game. ClientboundLevelParticlesPacket/$RandomizationType via javap) and re-verified live: a bot connected to a local offline-mode 26.3 test server now parses packet_recipe_book_add (crafting table recipe with a #minecraft:planks IDSet ingredient), and packet_world_particles for note/sonic_boom/item/vibration particles (the last carrying a live entity-tracking vibration source), with zero PartialReadError/chunk-size-mismatch console spam across a multi-minute session with several mobs (warden, sniffer, breeze, copper_golem, villager) alive. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…n/max
StatePropertiesPredicate$RangedMatcher.minValue/maxValue are each
Optional<String> (ByteBufCodecs.optional(STRING_UTF8): a presence bool
then the string), confirmed by decompiling the real 26.3 server jar.
The schema had them as bare strings, so any block-property range
matcher missing a min or max (very common - e.g. a single-sided
"waterlogged" check) desynced the byte stream one bit early, cascading
into the following nbt field as a bogus huge array-length read
("array size is abnormally large") - same failure class as the
earlier packet_advancements bug in this PR.
Reproduced live against a running 26.3 server: a dropped/held item
carrying can_place_on with an open-ended waterlogged range (minValue
present, maxValue absent) now decodes cleanly in both entity_metadata
and set_slot, with zero PartialReadError and a stable connection
afterward. Verified independently with a schema-level round trip
(createPacketBuffer/parsePacketBuffer) covering minValue-only,
maxValue-only, and neither-present cases.
|
Pushed fixes for the two fully-specified items from the review above (thanks @maebahesioru):
Not included yet: the 26.3 About the failing I'm deliberately not running The real fix is deciding how |
|
Thanks @extremeheat, understood on one update PR at a time. I'll hold off on further changes here and rebase this onto the regenerated Since this PR is stacked on #1300, the |
…or the 121 new items and 90 new blocks 26.3's dataPaths row pointed these at pc/26.2, but 26.3 inserted poplar wood, concrete/wool slabs and stairs, cushions, maps, etc. mid-registry, shifting IDs. IDs/states come from the server jar's registry report; attributes for new entries are approximated from analogues. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…mponentType/pot_decorations Two more wire-ID bugs, both found live via PACKET_DEBUG capture of dropped packets against a real 26.3 Realm and local-test-server-26.3, and both confirmed by javap on server-26.3.jar. 1. entityMetadataEntry `type` mapper: the previous fix numbered the serializers by *declaration* order in EntityDataSerializers (which includes helper fields and puts BLOCK_STATE/PARTICLE early). Wire IDs follow the registerSerializer(...) *call* order instead: boolean=8, rotations=9, block_pos=10 ... optional_living_entity_reference=13, block_state=14, optional_block_state=15, particle=16, particles=17, villager_data=18, optional_unsigned_int=19, pose=20, ..., optional_global_pos=33. Symptom was PartialReadError on every entity_metadata packet for villagers/players (type 18 read as optional_global_pos), dropping names/health/pose. 2. SlotComponentType: 26.3 registers 122 data components, the schema had 110, so every ID from 40 on was shifted. Reordered to the DataComponents register() call order. Added codecs for the new components whose STREAM_CODEC is fully readable from bytecode (attack_animation and interact_animation reuse SwingAnimation, cushion/color, waxed, villager_food, mob_visibility, sign_text_front/back, sulfur_cube_content) and dropped map_color, which 26.3 no longer registers. pot_decorations is now four Optional<ItemStackTemplate> fields (was an array of item ids); this was the direct cause of the PartialReadError on the 72 KB advancements packet, whose decorated-pot icon carries that component. Still read as void (no codec yet; they use nested loot-number providers / larger schemas): block_transformer, compostable, cooking_fuel, brewing_fuel, provides_pottery_pattern. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Pushed three more commits to this branch (heads-up, since I'd said I'd hold off until the rebase onto the regenerated #1300 scaffold; these are all fixes found live against a real 26.3 Realm and the local 26.3 server, and I'll rebase the whole stack once #1300 is refreshed):
Happy to split these into separate PRs if that's easier to review. |
…ort features.json data/pc/26.3 was pointing its protocol source at the shared pc/latest/proto.yml, which had never been updated for any of the 26.3-era fixes (SlotComponentType, entity_metadata ordering/naming, ItemBlockPredicate, particle registry, the stepped entity-move/position-sync encoding, packet_teams/packet_advancements/ packet_map_chunk layout, and the play/configuration packet ID insertions) — every one of those had only ever been hand-patched into protocol.json, so 'npm run build' regenerated a completely different (stale) file and CI's "protocol.json is desynced from yaml" check failed. Froze data/pc/26.3/proto.yml from a copy of pc/26.2's (last known-good, in-sync) proto.yml and applied each documented 26.3 fix to it directly, repointed dataPaths.json's pc/26.3 "proto" entry at pc/26.3 instead of pc/latest, and left pc/latest untouched. protocol.json is now the direct 'npm run build' output of this frozen yaml. Also fixed the protodef-validator failure on packet_rel_entity_move/ packet_entity_move_look's new entityDelta type (needs a `types` entry so the validator's protocol-schema pass registers it, even though it has no compiled body of its own — the real reader lives in node-minecraft-protocol), and resorted features.json (clientTickEndPacket was appended out of alphabetical order). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WSuum5hJoePw4kJdMjxdKx
The earlier light-mask fix (count-of-longs -> count-of-bytes) only retyped
the four mask fields on packet_map_chunk. packet_update_light still read
skyLightMask/blockLightMask/emptySkyLightMask/emptyBlockLightMask as
array<i64>, so every standalone light update was misparsed: either a
PartialReadError ("Chunk size is N but only M was read"), or, when the
misread happened to fit, i64 elements (protodef SignedBigInt, whose
valueOf() is a BigInt) reached prismarine-chunk's fromByteArray and threw
"Cannot mix BigInt and other types". Both are connection-fatal in practice:
the client stops servicing traffic and the keepalive times out.
javap on server-26.3.jar: ClientboundLightUpdatePacket and
ClientboundLevelChunkWithLightPacket both embed
ClientboundLightUpdatePacketData.STREAM_CODEC, whose four masks are all
ByteBufCodecs.BIT_SET (ByteBufCodecs$15: FriendlyByteBuf.readByteArray ->
BitSet.valueOf(byte[])). It is the only BIT_SET user in the protocol
package, so no other packet needs the same change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CI on this PR (which tests the merge with master) failed "26.1 / protocol.json is desynced from yaml". The 26.2 commits on this branch froze data/pc/26.1/proto.yml from pc/latest and repointed 26.1 at it, but master has since changed 26.1's protocol.json by editing pc/latest/proto.yml (PrismarineJS#1278 InteractionHand main_hand/off_hand mappers, PrismarineJS#1295 entity_action enum names). The merge took master's newer JSON alongside this branch's older frozen yaml. Applied master's pc/latest/proto.yml diff since the merge base to pc/26.1/proto.yml (it was an identical copy) and regenerated. 26.1's protocol.json is now byte-identical to master's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings the frozen 26.2 and 26.3 proto.yml in line with what master did to pc/latest (and what the previous commit ported to 26.1): - PrismarineJS#1278: `hand` on open_book, arm_animation, block_place and use_item is now a main_hand/off_hand mapper instead of a bare varint. - PrismarineJS#1295: entity_action actionId names follow Mojang's ServerboundPlayerCommandPacket.Action (leave_bed -> stop_sleeping, start/stop_horse_jump -> start/stop_riding_jump, open_vehicle_inventory -> open_inventory, start_elytra_flying -> start_fall_flying). Wire format is unchanged: numeric writes still pass through the mappers, and the start/stop_sprinting names are the same. The resulting packet definitions are identical to 26.1's. mineflayer's elytraFly still sends 'start_elytra_flying' under entityActionUsesStringMapper, which is the same break master already has on 26.1 and is handled by PrismarineJS/mineflayer#4120. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks for pushing the fixes and for the credit — I've been following the commits. On the remaining Makes sense to hold off until #1300 is regenerated before rebasing the stack. |
Summary
Protocol and data fixes that make pc 26.3 (protocol 777) usable end to end. With the full stack applied, mineflayer logs in, completes configuration, spawns, and stays connected on a real 26.3 Realm and a vanilla 26.3 server. It tracks entities and players, loads chunks and light, and handles inventory, recipes and advancements without
PartialReadErrors.Every fix was found in live testing and confirmed by decompiling the official 26.3 server jar (
javap -c -pon the relevantSTREAM_CODECs and registration order), not inferred from captured bytes alone.State of this PR (2026-09-23)
pc_26_3scaffold), which needs regenerating against current master now that 26.2 (Add Minecraft PC 26.2 data (protocol 776) #1298) has merged. Once it is, I'll rebase this branch onto it as asked, one update PR at a time.c9acdcec…2003e226,03d96de1, mergec8823767); those are superseded by Add Minecraft PC 26.2 data (protocol 776) #1298.ebd0242e(clientTickEndPacketfeature), which belongs to Add clientTickEndPacket feature flag (1.21.3+) #1304.build (24)) is green against master as of924e26d6.Fixes
Packet IDs and packet layouts
packet_success: added the missingsessionId: UUID.post_effectsat0x0a, shiftingstore_cookiethroughcode_of_conduct. Before this,select_known_packswas read ascustom_report_detailsand the connection stalled forever.GameProtocolsregistration order (144 clientbound, 69 serverbound), with schemas for the 5 new packets.accept_teleportation(serverboundteleport_confirm) now carries x/y/z/yRot/xRot. Consumer side: Send resolved position/rotation in accept_teleportation for 26.3+ mineflayer#4125.packet_login(play): addedonlineMode: boolbetweenworldStateandenforcesSecureChat. Reported by @maebahesioru against Paper 26.3.packet_advancements:PositionedAdvancementx/y moved to be siblings ofkey/value, and the staledisplayData.xCord/yCordremoved.packet_world_particles:particlemoved first, three max-speed floats added,countis avarint, and a trailingrandomizationTypeenum added.rel_entity_move/entity_move_lookuse a newentityDeltatype (reader in pc 26.3: add entityDelta type for the new stepped entity-move encoding node-minecraft-protocol#1538), andsync_entity_positionuses the newPositionPath(linear or stepped).Light data
ByteBufCodecs.BIT_SET=readByteArray→BitSet.valueOf(byte[])(a varint count of bytes, not longs), on bothmap_chunkandupdate_light.update_lightwas missed at first. Its masks decoded asi64, which either raised aPartialReadErroror handedBigIntvalues to prismarine-chunk and killed the connection. Consumer side: pc 26.3: read/write light-section masks as byte arrays, not long arrays prismarine-chunk#334.Registries and enums
entityMetadataEntrytypes followEntityDataSerializers.registerSerializer(...)call order (not declaration order). New entries:optional_living_entity_referenceanddye_color.SlotComponentTypereordered to the 122 componentsDataComponentsregisters (every id from 40 up had shifted).pot_decorationsis now fouroption<ItemStackTemplate>. Addedattack_animation,interact_animation,cushion/color,waxed,sulfur_cube_content,villager_food,mob_visibilityandsign_text_front/back; removedmap_color.Particletype mapper rebuilt fromParticleTypes(128 entries, with the new geyser variants).SlotDisplaytagis anIDSet, not a string.ItemBlockPropertyminValue/maxValueareoption<string>. An open-ended range desynced the stream and dropped the connection.handfields aremain_hand/off_handmappers, andentity_actionuses Mojang's action names, matching master's pc/26.1: map every InteractionHand field to main_hand/off_hand #1278/Fix PC protocol enum inconsistencies in difficulty, game-state reasons, and entity actions packet fields #1295 for 26.1. The bytes on the wire are unchanged.Data files
entities.jsonregenerated fromEntityTypesregistration order (161 entries;playeris 159).items/blocks/foods/recipes/blockCollisionShapesregenerated for 26.3's 121 new items and 90 new blocks, using the server's--reportsregistries.dataPaths.json26.3 row repointed from 26.1 to 26.2.Features
playerActionHasChangeDestroyDirection(26.3):CHANGE_DESTROY_DIRECTIONwas inserted at id 1 of the player-action enum. Consumer side: pc 26.3: use the shifted player-action ids for digging and releasing the held item mineflayer#4146.Build hygiene
proto.yml, andprotocol.jsonis the directnpm run buildoutput. 26.1's frozen yaml includes master's post-freeze changes (pc/26.1: map every InteractionHand field to main_hand/off_hand #1278, Fix PC protocol enum inconsistencies in difficulty, game-state reasons, and entity actions packet fields #1295), andfeatures.jsonis sorted.Known gaps
block_transformer,compostable,cooking_fuel,brewing_fuelandprovides_pottery_patternhave correct ids but no codec yet (they read as void). An item carrying one will desync.villager_foodandsign_text_*are guesses. Their types and order come from bytecode.playerActionHasChangeDestroyDirectionis gated to 26.3 only, because 26.1/26.2 are unverified.elytraFlystill sendsstart_elytra_flying, which no longer exists after Fix PC protocol enum inconsistencies in difficulty, game-state reasons, and entity actions packet fields #1295's rename. It needs Handle standardized minecraft-data entity action mappers mineflayer#4120.Test plan
npm testintools/js(schema validation, yaml↔json sync, audits) passes on the branch and on a trial merge with current master.createSerializer/createDeserializer) for the advancements,ItemBlockPredicate, entity-delta and light-update changes. Replayed 379 captured packets, including a 72 KBadvancementspacket, with zero parse errors.entity_metadata,advancementsandrecipe_book_adddecode cleanly; nearby players link tobot.players.update_lightand 9,900map_chunkpackets, 7 deaths and respawns, and zero decode errors.🤖 Generated with Claude Code