pc/protocol: entity_teleport layout for 1.21.2+ (velocity, f32 rotation, relative flags) - #1273
Conversation
…ative flags since 1.21.2 ClientboundTeleportEntityPacket changed in 1.21.2 to the same layout as the player position packet: PositionMoveRotation (position, delta movement, f32 yaw/pitch), a Set<Relative> written as a 32-bit int, then onGround. minecraft-data still described the pre-1.21.2 layout (i8 rotation, no velocity, no flags), so every entity_teleport on 1.21.3+ failed with 'Chunk size is 67 but only 33 was read'. Applied to 1.21.3 through 1.21.11 (proto.yml + rebuilt protocol.json) and 26.1 (protocol.json only).
Lets consumers pick the entity_teleport handler once per bot instead of sniffing packet.flags on every packet (PrismarineJS/mineflayer#4062).
…sRelativeFlags entity_teleport is a hot packet, so choose between the 1.21.2+ relative layout and the byte-rotation layout at inject time (like player_info) instead of testing packet.flags on every packet. The feature comes from PrismarineJS/minecraft-data#1273 alongside the layout change; older data resolves it to false and keeps the legacy path.
|
Can you double check in the decompiled code ? |
|
Yes — double-checked in the decompiled sources for 1.21.4, 1.21.11 and 26.1 (same layout in all three):
public static final StreamCodec<FriendlyByteBuf, ClientboundTeleportEntityPacket> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.VAR_INT, ClientboundTeleportEntityPacket::id,
PositionMoveRotation.STREAM_CODEC, ClientboundTeleportEntityPacket::change,
Relative.SET_STREAM_CODEC, ClientboundTeleportEntityPacket::relatives,
ByteBufCodecs.BOOL, ClientboundTeleportEntityPacket::onGround,
ClientboundTeleportEntityPacket::new
);
StreamCodec.composite(
Vec3.STREAM_CODEC, PositionMoveRotation::position, // 3 x f64
Vec3.STREAM_CODEC, PositionMoveRotation::deltaMovement, // 3 x f64
ByteBufCodecs.FLOAT, PositionMoveRotation::yRot, // f32
ByteBufCodecs.FLOAT, PositionMoveRotation::xRot // f32
);
public static final StreamCodec<ByteBuf, Set<Relative>> SET_STREAM_CODEC = ByteBufCodecs.INT.map(Relative::unpack, Relative::pack);i.e. a plain 32-bit int (4 bytes), confirming a So the wire format is: Also noticed the 26.1 hunk was missing from the pushed commit (d5256da only touched 1.21.3–1.21.11 + features.json) — pushed c12191f applying the same layout to |
…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>
Since 1.21.2
ClientboundTeleportEntityPackethas the same layout as the player position packet:PositionMoveRotation(position, delta movement, f32 yaw/pitch), aSet<Relative>written as a 32-bit int, thenonGround. minecraft-data still described the pre-1.21.2 layout (i8 rotation, no velocity, no flags), so everyentity_teleporton 1.21.3+ fails to parse (Chunk size is 67 but only 33 was read, PrismarineJS/mineflayer#3759).Verified against a captured 1.21.4 packet from a Velocity/ViaVersion network:
1 + 5 + 24 + 24 + 8 + 4 + 1 = 67, which is the chunk size in the error. The flags field reuses
PositionUpdateRelatives(already defined forpacket_positionon these versions), so consumers can treat both packets the same way.Applied to 1.21.3 through 1.21.11 (
proto.yml,protocol.jsonrebuilt withnpm run build) and 26.1 (protocol.jsononly, it has noproto.yml). Decompiled 26.1ClientboundTeleportEntityPacket/Relative.SET_STREAM_CODEC = ByteBufCodecs.INTconfirm the same layout there.Relation to the open PRs: #1154 covers only 1.21.3; #1251 covers 1.21.4–1.21.11 but encodes the relatives as a 9-bit
bitfield, which protodef reads as 2 bytes, not the 4 bytes vanilla writes, so those packets would still be partial reads. This PR supersedes both.The mineflayer side (consuming the relative flags in the
entity_teleporthandler) is in a separate PR.