Skip to content

Fix lpVec3 encoding, add vecDelta for 26.3 - #1539

Open
mc-zuri wants to merge 3 commits into
PrismarineJS:masterfrom
mc-zuri:pc/26.2-26.3
Open

mc-zuri wants to merge 3 commits into
PrismarineJS:masterfrom
mc-zuri:pc/26.2-26.3

Conversation

@mc-zuri

@mc-zuri mc-zuri commented Sep 20, 2026

Copy link
Copy Markdown

Three datatype fixes found by round-tripping packets generated by a vanilla 26.2 / 26.3 server byte-for-byte through the protocol. Each commit stands alone and comes with unit tests built on real vanilla bytes.

  • lpVec3 read the continued scale as a signed int. Vanilla masks it to unsigned, so a component of 8589934592 or more came back with every component's sign flipped and the wrong magnitude. Writing was already correct.
  • vecDelta is a new native type for the 26.3 rel_entity_move / entity_move_look layout. onGround and the step count share one var-int, which a protocol definition cannot split apart. The value is { onGround, dX, dY, dZ } or { onGround, steps: [{ ticks, dX, dY, dZ }] }.
  • test: packetTest had no value for ItemStackTemplate (minecraft-data#1267), so 26.1 packet_advancements threw before writing anything.

A vector longer than 3 carries scale >> 2 in a trailing var-int. The
scale is clamped to 1.7179869183e10, so that var-int runs up to
2^32 - 1, and LpVec3.read masks it back to unsigned:

  scale |= ((long)VarInt.read(input) & 4294967295L) << 2

readVarInt returns an int, so from 2^31 up (a component of 8589934592
or more) the scale came out negative: every component flipped sign and
the magnitude collapsed, and the value no longer wrote back to the bytes
it was read from. The writer was already right.

Adds vanilla 26.3 bytes for scale >> 2 at each var-int length, either
side of 2^31 and at the clamp.
26.3 replaced the three i16 deltas and the trailing onGround boolean of
rel_entity_move and entity_move_look with a VecDelta behind a packed
var-int:

  writeVarInt(entityId)
  writeVarInt((onGround ? 1 : 0) | stepCount << 1)
  VecDelta.write(...)

A step count of 0 is VecDelta.Linear, the same three i16 as before.
Anything higher is VecDelta.Stepped, that many
{ varint ticks, i16, i16, i16 } records. The count comes out of the
var-int by a shift, which a protocol definition cannot express, so
minecraft-data declares the field as a vecDelta native and the type
reads and writes the var-int together with the delta it governs.

The value is { onGround, dX, dY, dZ } or { onGround, steps: [{ ticks,
dX, dY, dZ }] }, keeping the field names those packets had.

Tested against the bytes a vanilla 26.3 server writes for both forms,
and through an interpreted and a compiled protocol since the type is
registered for each separately.
minecraft-data#1267 moved the 26.1 item fields that cannot be empty
(advancement icons, use_remainder, bundle and container contents) onto
a new ItemStackTemplate type. packetTest builds every packet from a
table of values per type and had none for it, so 26.1 packet_advancements
threw "No value for type ItemStackTemplate" before writing anything.
It takes the same fields as a filled Slot, so reuse that value.
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.

1 participant