Skip to content

Fix pc/26.1 client_command actionId: plain varint, not a mapper - #1284

Closed
u9g wants to merge 2 commits into
PrismarineJS:masterfrom
u9g:fix/26-1-client-command-varint
Closed

u9g wants to merge 2 commits into
PrismarineJS:masterfrom
u9g:fix/26-1-client-command-varint

Conversation

@u9g

@u9g u9g commented Sep 9, 2026 •

Copy link
Copy Markdown
Member
  • packet_client_command.actionId in pc/26.1 is a varint, as in every other pc protocol.json (1.9 through 1.21.11).
  • The wire format is unchanged: vanilla 26.1 writes the Action enum ordinal (writeEnum), so 0 = perform_respawn, 1 = request_stats, 2 = request_gamerule_values.
  • A client that writes actionId: 0 serializes on 26.1; with the mapper it threw SizeOf error for undefined : 0 is not in the mappings value, the serializer stream errored and the server timed the connection out (disconnect.timeout).

Verified against a local vanilla 26.1 server: /kill on a mineflayer bot now ends in a clean auto-respawn (health 20, alive, no serializer error). The protocol passes protodef-validator with the repo's extra types.

Sibling of #1278, which does the same for use_entity.hand, the only other 26.1-only mapper in toServer.

The vanilla packet writes the Action enum ordinal (writeEnum) on 26.1 exactly as on 1.21.11, and pc/26.1 is the only protocol.json that declares the field as a mapper. The strict compiled mapper (node-protodef PrismarineJS#176) throws on the numeric id every client writes, so the auto-respawn after death errors the serializer stream and the server times the connection out.
@extremeheat

Copy link
Copy Markdown
Member

Seems like this should be other way around. Is it a fixed enum or variable field ?

protocol.json for pc/26.1 is generated from this yaml; `npm run build` reproduces the committed protocol.json.
@extremeheat

extremeheat commented Sep 11, 2026 •

Copy link
Copy Markdown
Member

We should likely eliminate all the number datatypes for enums across the protocol data as numerical enum values can't be kept stable when insertions/removals happen in the middle. This can clean up code quite a bit as there are several instances of downstream switching on this kind of thing on top of it being good protocol documentation

@rom1504 rom1504 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Astra agent review — AI-generated, not manually written by the maintainer.

Reviewed at the maintainer's request. I inspected the current diff and discussion and locally reproduced named-value serialization before/after with ProtoDef 1.19.0. The inline finding concerns silent behavior changes for callers using the existing named API; no live-server test was run.

}
}
]
"type": "varint"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Astra agent review — AI-generated, not manually written by the maintainer.

This also changes already-valid named commands silently: with ProtoDef 1.19.0, actionId: 'request_stats' changes from byte 01 to 00, and 'request_gamerule_values' changes from 02 to 00. Both now become perform_respawn, so stats/gamerule callers receive no requested response. I reproduced this using the changed field type. Could we retain the mapper and adapt numeric callers, or provide an explicit compatibility path for named writes? A serializer regression covering all three commands would catch this; the respawn-only validation cannot.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, the mapper should stay. Named writes like 'request_stats' would otherwise silently turn into perform_respawn, as you found. #1295 has since made client_command.actionId a mapper in every pc version, so the premise here ("varint like every other version") no longer holds and 26.1 is already consistent on master. Closing this; the fix belongs in the callers, which should write 'perform_respawn' rather than 0.

@u9g

u9g commented Sep 19, 2026

Copy link
Copy Markdown
Member Author

Closing in favor of the direction in #1295: client_command.actionId is now a mapper in every pc version, so 26.1 is consistent as-is. @extremeheat's point stands: enum names are the stable API, and numeric writes belong in the callers.

@u9g u9g closed this Sep 19, 2026
@u9g
u9g deleted the fix/26-1-client-command-varint branch September 19, 2026 14:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants