Fix world border speed: varlong, not varint (regressed in 1.19) - #1200
Fix world border speed: varlong, not varint (regressed in 1.19)#1200atiweb wants to merge 4 commits into
Conversation
ClientboundInitializeBorderPacket and ClientboundSetBorderLerpSizePacket encode the border lerp time as a VarLong in vanilla (long lerpTime, writeVarLong/readVarLong). minecraft-data had speed correct as varlong in 1.17-1.18.2, but it regressed to varint in 1.19 and was never fixed - wrong for every version from 1.19 to 1.21.11. VarInt and VarLong encode identically below 2^28 ms (~74h), so this only breaks on long (multi-day) border interpolations, where the multi-byte VarLong mis-parses as a VarInt. Verified readVarLong/writeVarLong against the Mojang server jars for 1.19.4 and 1.21.3-1.21.9. 1.19 and 1.19.2 also needed varlong re-declared as a native type (it had been dropped when the field regressed to varint and nothing else used it); later versions already declare it. proto.yml edited, protocol.json regenerated with npm run build.
300231e to
964d484
Compare
|
CI is failing on protocol.json desync, please run |
Master moved 1.21.11 to its own data/pc/1.21.11/proto.yml and repointed pc/latest at 26.1, so the merge left 1.21.11's protocol.json (already fixed) desynced from its new, unfixed yaml. Applied speed: varlong there too and reran npm run build; 26.1 now picks up the fix from pc/latest as well (its ClientboundInitializeBorderPacket reads a VarLong too). All 21 affected versions are varlong; validate and the schema tests pass.
|
Since this is a data type change ( |
|
Good question — I checked, and there's no function readVarLong (buffer, offset) { return readVarInt(buffer, offset) }
function writeVarLong (value, buffer, offset) { return writeVarInt(value, buffer, offset) }
function sizeOfVarLong (value) { return sizeOfVarInt(value) }and Round-tripping One correction to my own PR description, since you're looking closely: the "~74h" threshold I quoted was wrong. VarInt and VarLong share the same LEB128 encoding, so the bytes are identical for any given value; what differs is only what a reader accepts. In nmp specifically, because |
|
So not a real 'long' varint. |
Problem
packet_initialize_world_borderandpacket_world_border_lerp_sizeboth define theirspeedfield (the border lerp time) asvarint. In the vanilla client/server it is a VarLong:This is a regression. minecraft-data had
speedcorrect asvarlongin 1.17–1.18.2, but it was changed tovarintin 1.19 and never corrected, so it has been wrong for every version from 1.19 through 1.21.11:speedvarlong✓varint✗Impact
A VarInt and a VarLong encode to identical bytes for values below 2^28 (~74h expressed in ms), which is why this seldom surfaces. But a long border interpolation — a slow multi-day border shrink (
/worldborder set <size> <seconds>with a large duration) — emits a VarLong that needs 5+ bytes, which a VarInt reader mis-parses (wrong value, then stream desync). These packets are clientbound, so it affects any consumer decoding them.Verification
readVarLong/writeVarLongconfirmed against the official Mojang server jars for 1.19.4 (where the regression begins) and 1.21.3 / 1.21.5 / 1.21.6 / 1.21.8 / 1.21.9; 1.17–1.18 already shipped the correctvarlong.Change
speed: varint→speed: varlongin both packets, for 1.19 → 1.21.11.proto.ymledited andprotocol.jsonregenerated withnpm run build(32 files, +64/−64; no other content touched).node compileProtocol.jsvalidate passes for all versions.