Skip to content

Write protocol enum fields by name where the version maps them - #4079

Closed
u9g wants to merge 1 commit into
PrismarineJS:masterfrom
u9g:fix/mapped-enum-fields
Closed

Write protocol enum fields by name where the version maps them#4079
u9g wants to merge 1 commit into
PrismarineJS:masterfrom
u9g:fix/mapped-enum-fields

Conversation

@u9g

@u9g u9g commented Sep 7, 2026

Copy link
Copy Markdown
Member

bot.activateEntity, bot.respawn and bot.wake send nothing on the versions whose schema describes the field as a mapper.

  • 26.1 maps use_entity.hand (main_hand/off_hand) and client_command.actionId (perform_respawn/request_stats/request_gamerule_values).
  • 1.21.6+ maps entity_action.actionId, which bed.js writes as 2.
  • game.js wrote the post-win_game respawn as { action: 0 }; no version has an action field on that packet.

protodef's compiled mapper writes the name and throws on anything else (ProtoDef-io/node-protodef#176), so each of these raises SizeOf error ... is not in the mappings value on the serializer stream and the packet never reaches the server. Before that change the numeric form happened to serialize to the same bytes, so nothing on the wire changes here.

enumField(registry, packet, field, index) returns the mapped name when the version's schema maps the field and the index otherwise.

Two regression tests in test/internalTest.js drive activateEntity and respawn against the mock server, which parses what the bot writes, so a value the serializer rejects fails the test. Also checked against a live 26.1 server (JartexNetwork, ViaVersion): right-clicking an NPC raised the serializer error and did nothing before the change, and completes the interaction after it.

26.1 describes use_entity.hand and client_command.actionId as mappers, and
1.21.6+ does the same for entity_action.actionId. protodef writes a mapper by
name and throws on anything else, so activateEntity, respawn and wake sent
nothing at all on those versions. game.js also wrote the respawn command with
an `action` field, which no version has.

enumField takes the index the protocol documents and returns the name when the
version's schema maps the field.
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Tests more than 1.5x slower than master (durations are noisy, so this is informational):

   5178ms ->   12709ms  mineflayer_external 1.19.3v nether
   8080ms ->   13690ms  mineflayer_external 1.19.4v nether

@u9g

u9g commented Sep 7, 2026

Copy link
Copy Markdown
Member Author

Closing as a duplicate: #4076 and #4077 came out of parallel sessions on the same bug a little earlier and cover the same call sites (client_command, entity_action, game.js's action field), with use_entity handled by a fixup on #4066. Nothing here is additional.

@u9g u9g closed this Sep 7, 2026

@extremeheat extremeheat 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.

The more correct thing to do is fix the data by making it consistent upstream. Alot of the features for this kind of thing are code smells

@extremeheat

Copy link
Copy Markdown
Member

Could be worthwhile to make a script that verifies that between all the versions that an identically named field doesn't switch between integer and mapper type. That would make it easier to fix. Could be added to a protocol test too to catch this kind of thing

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.

2 participants