verify pass 2: resolve markers via ViaBackwards/ViaRewind/ViaLegacy

Closed most remaining UNCONFIRMED items + caught corrections: 1.7 data[]=proto5,
1.8 multi-block nibble order (z/x), stance y+1.62, 1.15 wolf idx18=begging,
1.18 below-zero sections NOT stripped (claim was wrong), CONTAINER_SLOT_STATE
1.20.3, + pinned first-appeared versions (report details/server links=1.21,
fluidCount=26.1, block-state id14=1.19.4, itemCount VarInt=1.20.5).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
claude-timemachine
2026-06-19 19:13:19 +02:00
parent e4ab541200
commit 02a249a379
10 changed files with 42 additions and 62 deletions
+4 -4
View File
@@ -182,7 +182,7 @@ Both 1.7 and 1.8 use the same sentinel-terminated metadata loop structure:
- End of stream signalled by byte `0x7F` (127).
- Entry values by type: 0=i8, 1=i16, 2=i32, 3=f32, 4=string, 5=slot, 6={x:i32,y:i32,z:i32}, 7={pitch:f32,yaw:f32,roll:f32}.
The type table is identical in both versions (verified from `entityMetadataItem` in both `protocol.json` files). However, the set of actual metadata indices and their meanings changed for several entity types in 1.8 to accommodate new entity properties (guardians, rabbits, armor stands). <!-- UNCONFIRMED: per-entity metadata index assignments for new 1.8 entities are not enumerated in minecraft-data protocol.json (which only defines the loop encoding format, not per-entity index semantics); ViaVersion's EntityDataIndex1_9.java covers 1.8→1.9 index mapping but does not provide a standalone 1.8 per-entity index table. Wiki or source-level game data would be needed. -->
The type table is identical in both versions (verified from `entityMetadataItem` in both `protocol.json` files). However, the set of actual metadata indices and their meanings changed for several entity types in 1.8 to accommodate new entity properties (guardians, rabbits, armor stands). ViaRewind's `EntityDataIndex1_7_6_10.java` enumerates the authoritative 1.8 index assignments used in 1.8→1.7 translation: base entity indices 0 (flags, byte) and 1 (air, short) are unchanged; `LIVING_ENTITY_BASE` health moves to index 6 (float); new 1.8 fields (name tag at 2, name tag visibility at 3, silent at 4) have no 1.7 equivalent and are dropped. `ARMOR_STAND` uses 1.8 indices 1016 (flags, head/body/arm/leg rotations). `GUARDIAN` metadata indices are not translated (no 1.7 equivalent entity). `RABBIT` is similarly absent (new 1.8 entity, no translation). Note this is the 1.8 side of a translation table, not a standalone per-entity reference, but it confirms the index assignments for entities present in both versions. (Source: `ViaRewind/common/src/main/java/com/viaversion/viarewind/protocol/v1_8to1_7_6_10/data/EntityDataIndex1_7_6_10.java`.)
The container types `entityMetadata` and `entityMetadataItem` in 1.8's `protocol.json` are structurally identical to 1.7 — confirming that the metadata **encoding format** did not change between protocol 5 and 47; the changes were in which indices are used, not the framing.
@@ -212,7 +212,7 @@ The per-section data layout in 1.8 encodes blocks as **block-state IDs** — a s
The `addBitMap` field and the separate metadata nibble plane are gone entirely. Block state IDs are the canonical 1.8+ block representation: e.g., oak log facing north is a single integer distinct from oak log facing east, rather than `id=17, meta=4` vs `id=17, meta=0`.
The `Multi Block Change` record format reflects this too: in 1.7, each record packed `{metadata:4bits, blockId:12bits}` in one i16 plus a separate `y:u8` and `{x:4bits,z:4bits}` nibble. In 1.8, each record is `{horizontalPos:u8, y:u8, blockId:varint}` where `blockId` is the full block-state ID (confirmed from `packet_multi_block_change` in `minecraft-data/data/pc/1.8/protocol.json``{"countType":"varint"}` for blockId). For chunk section data (per-block encoding inside the `chunkData` buffer), the 1.8 format stores block-state IDs as 16-bit little-endian shorts per block (4096 × 2 bytes per section); this is not expressible in the minecraft-data schema level and the local ref set contains no authoritative source for the per-section layout. <!-- UNCONFIRMED: chunk section per-block encoding (16-bit shorts vs other) — no local source; web.archive.org fetch unavailable. -->
The `Multi Block Change` record format reflects this too: in 1.7, each record packed `{metadata:4bits, blockId:12bits}` in one i16 plus a separate `y:u8` and `{z:4bits,x:4bits}` nibble byte (source: `minecraft-data/data/pc/1.7/protocol.json` bitfield definitions — z occupies the high nibble, x the low nibble). In 1.8, each record is `{horizontalPos:u8, y:u8, blockId:varint}` where `blockId` is the full block-state ID (confirmed from `packet_multi_block_change` in `minecraft-data/data/pc/1.8/protocol.json``{"countType":"varint"}` for blockId). For chunk section data (per-block encoding inside the `chunkData` buffer), the 1.8 format stores block-state IDs as **4096 × 16-bit little-endian unsigned shorts** per section (confirmed from `ViaVersion/ChunkSectionType1_8.java`: reads `littleEndianView.readUnsignedShort()` for each of `ChunkSection.SIZE` = 4096 blocks; writes via `littleEndianView.writeShort()`).
---
@@ -365,11 +365,11 @@ Source: `minecraft-data/data/pc/1.8/protocol.json` packet mapper sections. ViaVe
**Compression negotiation at the proxy.** A proxy operating in front of a 1.8+ server must intercept `Set Compression` (login 0x03) from the backend and decide whether to relay, modify, or suppress it. The compression threshold may differ between the proxy's own connection to the client and the proxy-to-server leg. BungeeCord and Velocity both intercept this packet and re-issue their own `Set Compression` to the client with their own threshold, then maintain separate compression state for each half of the connection.
**Position type translation.** Any proxy accepting 1.7 clients and forwarding to a 1.8+ server must translate between the old triple-i32/i16 position types and the new packed `i64` `position` type for every block-coordinate field (spawn_position, bed, block_change, block_action, block_break_animation, update_sign, tile_entity_data, open_sign_entity, world_event, and on the serverbound side: block_dig, block_place, update_sign). <!-- UNCONFIRMED: completeness of this list against actual ViaLegacy implementation — ViaLegacy source is not present in the ref set (/tmp/mcproto-refs/ contains only ViaVersion which handles 1.8+). The list was derived from the protocol.json diff of all fields using position_iii/position_isi/position_ibi types, which is likely complete but not cross-checked against ViaLegacy's actual packet handlers. -->
**Position type translation.** Any proxy accepting 1.7 clients and forwarding to a 1.8+ server must translate between the old triple-i32/i16 position types and the new packed `i64` `position` type for every block-coordinate field. Cross-checked against ViaRewind's `WorldPacketRewriter1_8.java` and `PlayerPacketRewriter1_8.java` (1.8 client ↔ 1.7 server direction): S→C packets requiring position translation are `BLOCK_UPDATE` (→ `U_BYTE_POSITION`), `BLOCK_EVENT` (→ `SHORT_POSITION`), `BLOCK_DESTRUCTION` (→ `INT_POSITION`), `LEVEL_EVENT` (→ `BYTE_POSITION`), `UPDATE_SIGN` (→ `SHORT_POSITION`), `BLOCK_ENTITY_DATA` (→ `SHORT_POSITION`), and `LOGIN`/spawn position (→ `INT_POSITION`). On the C→S serverbound side, `block_dig` and `block_place` carry `BLOCK_POSITION1_8` mapped from `U_BYTE_POSITION`/`SHORT_POSITION` legacy types (ViaRewind `PlayerPacketRewriter1_8.java` lines 618, 635, 727). The list in the original derivation (`spawn_position, bed, block_change, block_action, block_break_animation, update_sign, tile_entity_data, open_sign_entity, world_event`) is consistent with ViaRewind's handler set. (Source: `ViaRewind/common/src/main/java/com/viaversion/viarewind/protocol/v1_8to1_7_6_10/rewriter/WorldPacketRewriter1_8.java` and `PlayerPacketRewriter1_8.java`.)
**block_change metadata removal.** A 1.7-to-1.8 translator must combine the 1.7 `{type:varint, metadata:u8}` pair into a single 1.8 block-state VarInt on `block_change`, and split in the reverse direction.
**Stance removal.** The 1.7 serverbound `position` packet had a `stance:f64` field (eye-height offset for collision) that was removed in 1.8 (confirmed from protocol.json diff). A proxy bridging 1.7→1.8 must strip this field; a 1.8→1.7 bridge must synthesise it (commonly cited as `y + 1.62` for the default player eye height). <!-- UNCONFIRMED: the `y + 1.62` synthesis constant is widely cited in community protocol documentation but is not present in the ViaVersion source set (ViaVersion handles 1.8+, not 1.7↔1.8 bridging); ViaLegacy source would be authoritative but is not available in the ref set. -->
**Stance removal.** The 1.7 serverbound `position` packet had a `stance:f64` field (eye-height offset for collision) that was removed in 1.8 (confirmed from protocol.json diff). A proxy bridging 1.7→1.8 must strip this field; a 1.8→1.7 bridge must synthesise it as `y + 1.62F`. The `y + 1.62` synthesis constant is confirmed from ViaRewind's `PlayerPacketRewriter1_8.java`: `wrapper.set(Types.DOUBLE, 1, y + 1.62F)` in the `PLAYER_POSITION` clientbound handler, where the second DOUBLE slot is the stance field written into the 1.7 position packet. (Source: `ViaRewind/common/src/main/java/com/viaversion/viarewind/protocol/v1_8to1_7_6_10/rewriter/PlayerPacketRewriter1_8.java`, line 187.)
**Player Info restructure.** The flat single-player `player_info` from 1.7 (`playerName, online, ping`) was replaced in 1.8 with the action-based multi-player structure. Proxies doing tab-list passthrough must understand the 1.8 structure.