diff --git a/ent/decoders.go b/ent/decoders.go index ca0814b..c806102 100644 --- a/ent/decoders.go +++ b/ent/decoders.go @@ -1,7 +1,7 @@ package ent import ( - "strings" + // "strings" "github.com/jordanorelli/hyperstone/bit" ) @@ -33,6 +33,8 @@ func newFieldDecoder(n *Namespace, f *Field) decoder { case "CGameSceneNodeHandle": // ehhh maybe no? return decodeVarInt32 + case "CUtlStringToken": + return symbolDecoder(n) } // the field is itself an entity contained within the outer entity. @@ -40,12 +42,27 @@ func newFieldDecoder(n *Namespace, f *Field) decoder { return entityDecoder(f.class) } - Debug.Printf("type spec: %v", parseTypeName(n, typeName)) - - switch { - case strings.HasPrefix(typeName, "CHandle"): - return decodeVarInt32 + // for compound types such as handles, vectors (in the c++ std::vector + // sense), and arrays + ts := parseTypeName(n, typeName) + switch ts.kind { + case t_element: + Debug.Printf("weird typespec: we shouldn't have elements here: %v", ts) + return func(bit.Reader) interface{} { + Info.Fatalf("unable to decode element of type: %v", ts.name) + return nil + } + case t_object: + return func(br bit.Reader) interface{} { + Debug.Printf("unable to decode object of type: %v", ts.name) + return decodeVarInt32(br) + } + case t_array: + return arrayDecoder(n, f, ts) + case t_template: + return templateDecoder(f, ts) } + return nil } @@ -183,3 +200,27 @@ func qangleDecoder(f *Field) decoder { } } } + +func arrayDecoder(n *Namespace, f *Field, ts typeSpec) decoder { + return decodeVarInt32 +} + +func templateDecoder(f *Field, ts typeSpec) decoder { + switch ts.template { + case "CHandle": + return decodeVarInt32 + case "CStrongHandle": + return decodeVarInt64 + case "CUtlVector": + return decodeVarInt32 + } + return nil +} + +// so far a sanity check on the values I'm seeing out of this seem wrong. +func symbolDecoder(n *Namespace) decoder { + return func(br bit.Reader) interface{} { + u := bit.ReadVarInt32(br) + return n.Symbol(int(u)) + } +} diff --git a/ent/selection.go b/ent/selection.go index 0d30f40..681016b 100644 --- a/ent/selection.go +++ b/ent/selection.go @@ -29,13 +29,15 @@ func (s selection) fill(offset int, displayPath string, dest slotted, br bit.Rea if fn == nil { switch v := dest.(type) { case *Entity: + Debug.Printf("%s %s (%s)", s, fmt.Sprintf("%s.%s", displayPath, dest.slotName(slot)), dest.slotType(slot)) Info.Fatalf("%v entity has no decoder for slot %d (%v)", v.Class, slot, v.Class.Fields[slot]) default: Info.Fatalf("slotted value %v has no decoder for slot %d", dest, slot) } } - val := fn(br) old := dest.slotValue(slot) + Debug.Printf("%s %s (%s): %v", s, fmt.Sprintf("%s.%s", displayPath, dest.slotName(slot)), dest.slotType(slot), old) + val := fn(br) dest.setSlotValue(slot, val) Debug.Printf("%s %s (%s): %v -> %v", s, fmt.Sprintf("%s.%s", displayPath, dest.slotName(slot)), dest.slotType(slot), old, val) return nil @@ -43,6 +45,7 @@ func (s selection) fill(offset int, displayPath string, dest slotted, br bit.Rea v := dest.slotValue(slot) vs, ok := v.(slotted) if !ok { + Info.Fatalf("child selection %s at offset %d refers to a slot (%d: %s) that contains a non-slotted type: %s", s, offset, slot, fmt.Sprintf("%s.%s", displayPath, dest.slotName(slot)), dest.slotType(slot)) return fmt.Errorf("child selection refers to a slot that doesn't contain a slotted value") } return s.fill(offset+1, fmt.Sprintf("%s.%s", displayPath, dest.slotName(slot)), vs, br)