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:
@@ -4120,11 +4120,6 @@
|
||||
"type": [
|
||||
"bitfield",
|
||||
[
|
||||
{
|
||||
"name": "unused",
|
||||
"size": 2,
|
||||
"signed": false
|
||||
},
|
||||
{
|
||||
"name": "allows_restricted",
|
||||
"size": 1,
|
||||
@@ -11697,4 +11692,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2803,11 +2803,6 @@
|
||||
"type": [
|
||||
"bitfield",
|
||||
[
|
||||
{
|
||||
"name": "unused",
|
||||
"size": 2,
|
||||
"signed": false
|
||||
},
|
||||
{
|
||||
"name": "allows_restricted",
|
||||
"size": 1,
|
||||
@@ -10259,4 +10254,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3822,11 +3822,6 @@
|
||||
"type": [
|
||||
"bitfield",
|
||||
[
|
||||
{
|
||||
"name": "unused",
|
||||
"size": 2,
|
||||
"signed": false
|
||||
},
|
||||
{
|
||||
"name": "allows_restricted",
|
||||
"size": 1,
|
||||
@@ -11399,4 +11394,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4112,11 +4112,6 @@
|
||||
"type": [
|
||||
"bitfield",
|
||||
[
|
||||
{
|
||||
"name": "unused",
|
||||
"size": 2,
|
||||
"signed": false
|
||||
},
|
||||
{
|
||||
"name": "allows_restricted",
|
||||
"size": 1,
|
||||
|
||||
@@ -4112,11 +4112,6 @@
|
||||
"type": [
|
||||
"bitfield",
|
||||
[
|
||||
{
|
||||
"name": "unused",
|
||||
"size": 2,
|
||||
"signed": false
|
||||
},
|
||||
{
|
||||
"name": "allows_restricted",
|
||||
"size": 1,
|
||||
@@ -5726,12 +5721,15 @@
|
||||
"mappings": {
|
||||
"0": "empty",
|
||||
"1": "any_fuel",
|
||||
"2": "item",
|
||||
"3": "item_stack",
|
||||
"4": "tag",
|
||||
"5": "smithing_trim",
|
||||
"6": "with_remainder",
|
||||
"7": "composite"
|
||||
"2": "with_any_potion",
|
||||
"3": "only_with_component",
|
||||
"4": "item",
|
||||
"5": "item_stack",
|
||||
"6": "tag",
|
||||
"7": "dyed",
|
||||
"8": "smithing_trim",
|
||||
"9": "with_remainder",
|
||||
"10": "composite"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -5745,9 +5743,44 @@
|
||||
"fields": {
|
||||
"empty": "void",
|
||||
"any_fuel": "void",
|
||||
"with_any_potion": [
|
||||
"container",
|
||||
[
|
||||
{
|
||||
"name": "display",
|
||||
"type": "SlotDisplay"
|
||||
}
|
||||
]
|
||||
],
|
||||
"only_with_component": [
|
||||
"container",
|
||||
[
|
||||
{
|
||||
"name": "source",
|
||||
"type": "SlotDisplay"
|
||||
},
|
||||
{
|
||||
"name": "component",
|
||||
"type": "IDSet"
|
||||
}
|
||||
]
|
||||
],
|
||||
"item": "varint",
|
||||
"item_stack": "Slot",
|
||||
"tag": "string",
|
||||
"dyed": [
|
||||
"container",
|
||||
[
|
||||
{
|
||||
"name": "dye",
|
||||
"type": "SlotDisplay"
|
||||
},
|
||||
{
|
||||
"name": "target",
|
||||
"type": "SlotDisplay"
|
||||
}
|
||||
]
|
||||
],
|
||||
"smithing_trim": [
|
||||
"container",
|
||||
[
|
||||
@@ -11779,4 +11812,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by strom. DO NOT EDIT.
|
||||
// source: minecraft-data/pc/1.12.2/protocol.json (sha256:21c57208db654a5e14a34cb696570080df179c5c642e53b16120399eee9232be)
|
||||
// version: v0.6.6-0.20260805175346-53d366ae5301+dirty (go1.26.2)
|
||||
// version: v0.6.6-0.20260805191907-f4c27628815b+dirty (go1.26.2)
|
||||
package v1_12_2
|
||||
|
||||
import (
|
||||
@@ -432,17 +432,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
|
||||
}
|
||||
@@ -2810,10 +2810,10 @@ func (ret *PlayToClientPacketAdvancements) Decode(r io.ReadSeeker) (err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataPresentValue.Flags.Unused = PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataFlagsPacked << 0 >> 3
|
||||
PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataPresentValue.Flags.Hidden = PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataFlagsPacked<<29>>31 == 1
|
||||
PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataPresentValue.Flags.ShowToast = PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataFlagsPacked<<30>>31 == 1
|
||||
PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataPresentValue.Flags.HasBackgroundTexture = PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataFlagsPacked<<31>>31 == 1
|
||||
PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataPresentValue.Flags.HasBackgroundTexture = PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataFlagsPacked>>0&1 == 1
|
||||
PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataPresentValue.Flags.ShowToast = PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataFlagsPacked>>1&1 == 1
|
||||
PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataPresentValue.Flags.Hidden = PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataFlagsPacked>>2&1 == 1
|
||||
PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataPresentValue.Flags.Unused = PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataFlagsPacked >> 3 & 536870911
|
||||
switch PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataPresentValue.Flags.HasBackgroundTexture {
|
||||
case true:
|
||||
var PlayToClientPacketAdvancementsAdvancementMappingElementValueDisplayDataBackgroundTexture1Tmp string
|
||||
|
||||
+1108
-17
File diff suppressed because it is too large
Load Diff
+1114
-23
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+1204
-30
File diff suppressed because it is too large
Load Diff
+1204
-30
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
}
|
||||
|
||||
+1204
-30
File diff suppressed because it is too large
Load Diff
+1204
-30
File diff suppressed because it is too large
Load Diff
@@ -225,7 +225,7 @@ func MultiTypeFix(s string, t *CaseExprType) (e ast.Expr) {
|
||||
*t = ct
|
||||
return
|
||||
}
|
||||
if *t == ct {
|
||||
if *t == ct || (*t == CaseExprTypeOnlyNumber && ct == CaseExprTypeNumber) || (*t == CaseExprTypeOnlyBool && ct == CaseExprTypeBool) || (*t == CaseExprTypeNumber && ct == CaseExprTypeOnlyNumber) || (*t == CaseExprTypeBool && ct == CaseExprTypeOnlyBool) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -400,6 +400,7 @@ func BitFieldDecoder(g *Generator, varToSet ast.Expr, dataRaw any, name string)
|
||||
}
|
||||
s = append(s, packedVarStmt)
|
||||
s = append(s, stmts...)
|
||||
slices.Reverse(data)
|
||||
lShiftBy := 0
|
||||
for _, field := range data {
|
||||
var fieldTypeProtodef string
|
||||
@@ -413,16 +414,13 @@ func BitFieldDecoder(g *Generator, varToSet ast.Expr, dataRaw any, name string)
|
||||
return
|
||||
}
|
||||
|
||||
rShiftBy := totalSize - field.Size
|
||||
fieldToSet := SelectorExprAndStr(varToSet, util2.CamelCase(field.Name))
|
||||
|
||||
mask := (1 << field.Size) - 1
|
||||
var getDataExpr ast.Expr
|
||||
getDataExpr = RightShift(
|
||||
LeftShift(
|
||||
Ident(packed),
|
||||
NumLit(lShiftBy)),
|
||||
NumLit(rShiftBy),
|
||||
)
|
||||
getDataExpr = BinAnd(
|
||||
RightShift(Ident(packed), NumLit(lShiftBy)),
|
||||
NumLit(mask))
|
||||
if fieldTypeProtodef == "bool" {
|
||||
getDataExpr = Equals(getDataExpr, NumLit(1))
|
||||
} else if fieldTypeProtodef != packedTypeProtodef {
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"slices"
|
||||
"strconv"
|
||||
|
||||
"github.com/admin-else/strom/mc/proto_generator/protodef"
|
||||
util2 "github.com/admin-else/strom/mc/util"
|
||||
@@ -152,7 +151,16 @@ func BitFieldEncoder(g *Generator, varToSet ast.Expr, dataRaw any, name string)
|
||||
}
|
||||
packedVarName := name + "Packed"
|
||||
packedExpr := Ident(packedVarName)
|
||||
packedTypeStr := "uint" + strconv.Itoa(totalSize)
|
||||
packedTypeStr := "uint8"
|
||||
if totalSize > 8 {
|
||||
packedTypeStr = "uint16"
|
||||
}
|
||||
if totalSize > 16 {
|
||||
packedTypeStr = "uint32"
|
||||
}
|
||||
if totalSize > 32 {
|
||||
packedTypeStr = "uint64"
|
||||
}
|
||||
|
||||
s = append(s, VarStmt(packedVarName, Ident(packedTypeStr)))
|
||||
|
||||
@@ -185,7 +193,17 @@ func BitFieldEncoder(g *Generator, varToSet ast.Expr, dataRaw any, name string)
|
||||
shiftBy += field.Size
|
||||
}
|
||||
|
||||
encodePacked, err := g.VisitEncoder(packedExpr, "u"+strconv.Itoa(totalSize), name)
|
||||
packedProtoType := "u8"
|
||||
if totalSize > 8 {
|
||||
packedProtoType = "u16"
|
||||
}
|
||||
if totalSize > 16 {
|
||||
packedProtoType = "u32"
|
||||
}
|
||||
if totalSize > 32 {
|
||||
packedProtoType = "u64"
|
||||
}
|
||||
encodePacked, err := g.VisitEncoder(packedExpr, packedProtoType, name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user