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:
@@ -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