fix: correct bitfield decoder using mask extraction, fix command_node

- Switch bitfield decoder from shift-based to mask-based extraction (var>>pos & mask)
  fixes non-power-of-2 bitfields like 6-bit command_node flags
- Fix MultiTypeFix to handle CaseExprTypeOnlyNumber/OnlyBool variants
- Update minecraft-data command_node bitfield order for all 1.21.8+ versions
  to LSB-first convention (matches reverse encoder/decoder)
- Implement SwitchDecoder for extraNodeData via compareTo visitor
- DeclareCommands now decodes successfully (was EOF)
- Add 6 regression tests (entity_equipment, metadata, recipes, commands)
This commit is contained in:
OpenCode
2026-08-05 22:29:08 +02:00
parent f4c2762881
commit e58499ed09
17 changed files with 8532 additions and 263 deletions
+199 -10
View File
@@ -1,6 +1,6 @@
// Code generated by strom. DO NOT EDIT.
// source: minecraft-data/pc/1.8/protocol.json (sha256:79fe774bfc255dd281899c004fbb9c7adc40fb107de9353da1dd0371ea4b53af)
// version: v0.6.6-0.20260805175346-53d366ae5301+dirty (go1.26.2)
// version: v0.6.6-0.20260805191907-f4c27628815b+dirty (go1.26.2)
package v1_8
import (
@@ -82,8 +82,90 @@ func (ret *EntityMetadata) Decode(r io.ReadSeeker) (err error) {
if err != nil {
return
}
entry.Anon.Type = EntityMetadataInnerAnonPacked << 0 >> 5
entry.Anon.Key = EntityMetadataInnerAnonPacked << 3 >> 3
entry.Anon.Key = EntityMetadataInnerAnonPacked >> 0 & 31
entry.Anon.Type = EntityMetadataInnerAnonPacked >> 5 & 7
switch entry.Anon.Type {
case 0:
var EntityMetadataInnerValue0Tmp int8
err = binary.Read(r, binary.BigEndian, &EntityMetadataInnerValue0Tmp)
if err != nil {
return
}
entry.Value = EntityMetadataInnerValue0Tmp
case 1:
var EntityMetadataInnerValue1Tmp int16
err = binary.Read(r, binary.BigEndian, &EntityMetadataInnerValue1Tmp)
if err != nil {
return
}
entry.Value = EntityMetadataInnerValue1Tmp
case 2:
var EntityMetadataInnerValue2Tmp int32
err = binary.Read(r, binary.BigEndian, &EntityMetadataInnerValue2Tmp)
if err != nil {
return
}
entry.Value = EntityMetadataInnerValue2Tmp
case 3:
var EntityMetadataInnerValue3Tmp float32
err = binary.Read(r, binary.BigEndian, &EntityMetadataInnerValue3Tmp)
if err != nil {
return
}
entry.Value = EntityMetadataInnerValue3Tmp
case 4:
var EntityMetadataInnerValue4Tmp string
EntityMetadataInnerValue4Tmp, err = proto_base.DecodeString(r)
if err != nil {
return
}
entry.Value = EntityMetadataInnerValue4Tmp
case 5:
var EntityMetadataInnerValue5Tmp Slot
err = EntityMetadataInnerValue5Tmp.Decode(r)
if err != nil {
return
}
entry.Value = EntityMetadataInnerValue5Tmp
case 6:
var EntityMetadataInnerValue6Tmp struct {
X int32
Y int32
Z int32
}
err = binary.Read(r, binary.BigEndian, &EntityMetadataInnerValue6Tmp.X)
if err != nil {
return
}
err = binary.Read(r, binary.BigEndian, &EntityMetadataInnerValue6Tmp.Y)
if err != nil {
return
}
err = binary.Read(r, binary.BigEndian, &EntityMetadataInnerValue6Tmp.Z)
if err != nil {
return
}
entry.Value = EntityMetadataInnerValue6Tmp
case 7:
var EntityMetadataInnerValue7Tmp struct {
Pitch float32
Yaw float32
Roll float32
}
err = binary.Read(r, binary.BigEndian, &EntityMetadataInnerValue7Tmp.Pitch)
if err != nil {
return
}
err = binary.Read(r, binary.BigEndian, &EntityMetadataInnerValue7Tmp.Yaw)
if err != nil {
return
}
err = binary.Read(r, binary.BigEndian, &EntityMetadataInnerValue7Tmp.Roll)
if err != nil {
return
}
entry.Value = EntityMetadataInnerValue7Tmp
}
ret.Val[id] = entry
}
return
@@ -97,6 +179,113 @@ func (ret *EntityMetadata) Encode(w io.Writer) (err error) {
if err != nil {
return
}
switch v.Anon.Type {
case 0:
EntityMetadataValue, ok := v.Value.(int8)
if !ok {
err = proto_base.BadTypeError
return
}
err = binary.Write(w, binary.BigEndian, EntityMetadataValue)
if err != nil {
return
}
case 1:
EntityMetadataValue, ok := v.Value.(int16)
if !ok {
err = proto_base.BadTypeError
return
}
err = binary.Write(w, binary.BigEndian, EntityMetadataValue)
if err != nil {
return
}
case 2:
EntityMetadataValue, ok := v.Value.(int32)
if !ok {
err = proto_base.BadTypeError
return
}
err = binary.Write(w, binary.BigEndian, EntityMetadataValue)
if err != nil {
return
}
case 3:
EntityMetadataValue, ok := v.Value.(float32)
if !ok {
err = proto_base.BadTypeError
return
}
err = binary.Write(w, binary.BigEndian, EntityMetadataValue)
if err != nil {
return
}
case 4:
EntityMetadataValue, ok := v.Value.(string)
if !ok {
err = proto_base.BadTypeError
return
}
err = proto_base.EncodeString(w, EntityMetadataValue)
if err != nil {
return
}
case 5:
EntityMetadataValue, ok := v.Value.(Slot)
if !ok {
err = proto_base.BadTypeError
return
}
EntityMetadataValueEncTmp := EntityMetadataValue
err = EntityMetadataValueEncTmp.Encode(w)
if err != nil {
return
}
case 6:
EntityMetadataValue, ok := v.Value.(struct {
X int32
Y int32
Z int32
})
if !ok {
err = proto_base.BadTypeError
return
}
err = binary.Write(w, binary.BigEndian, EntityMetadataValue.X)
if err != nil {
return
}
err = binary.Write(w, binary.BigEndian, EntityMetadataValue.Y)
if err != nil {
return
}
err = binary.Write(w, binary.BigEndian, EntityMetadataValue.Z)
if err != nil {
return
}
case 7:
EntityMetadataValue, ok := v.Value.(struct {
Pitch float32
Yaw float32
Roll float32
})
if !ok {
err = proto_base.BadTypeError
return
}
err = binary.Write(w, binary.BigEndian, EntityMetadataValue.Pitch)
if err != nil {
return
}
err = binary.Write(w, binary.BigEndian, EntityMetadataValue.Yaw)
if err != nil {
return
}
err = binary.Write(w, binary.BigEndian, EntityMetadataValue.Roll)
if err != nil {
return
}
}
}
err = binary.Write(w, binary.BigEndian, uint8(127))
if err != nil {
@@ -130,17 +319,17 @@ func (ret *Position) Decode(r io.ReadSeeker) (err error) {
if err != nil {
return
}
ret.X = int32(PositionPacked << 0 >> 38)
if ret.X >= 1<<25 {
ret.X -= 1 << 26
ret.Z = int32(PositionPacked >> 0 & 67108863)
if ret.Z >= 1<<25 {
ret.Z -= 1 << 26
}
ret.Y = int16(PositionPacked << 26 >> 52)
ret.Y = int16(PositionPacked >> 26 & 4095)
if ret.Y >= 1<<11 {
ret.Y -= 1 << 12
}
ret.Z = int32(PositionPacked << 38 >> 38)
if ret.Z >= 1<<25 {
ret.Z -= 1 << 26
ret.X = int32(PositionPacked >> 38 & 67108863)
if ret.X >= 1<<25 {
ret.X -= 1 << 26
}
return
}