typeSpec type

ahhhhhh this feels good.
types
Jordan Orelli 8 years ago
parent 8025667a58
commit 78b07284ca

@ -2,7 +2,6 @@ package ent
import ( import (
"github.com/jordanorelli/hyperstone/bit" "github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
) )
var atom_types = map[string]typeFn{ var atom_types = map[string]typeFn{
@ -15,9 +14,8 @@ var atom_types = map[string]typeFn{
}, },
} }
func atomType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe { func atomType(spec *typeSpec, env *Env) tÿpe {
var_type := env.symbol(int(flat.GetVarTypeSym())) if t, ok := atom_types[spec.typeName]; ok {
if t, ok := atom_types[var_type]; ok {
Debug.Printf(" atom type") Debug.Printf(" atom type")
return t return t
} }

@ -12,7 +12,7 @@ type field struct {
func (f *field) fromProto(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) error { func (f *field) fromProto(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) error {
Debug.Printf("parse flat field: %s", prettyFlatField(flat, env)) Debug.Printf("parse flat field: %s", prettyFlatField(flat, env))
t := parseType(flat, env) t := parseFieldType(flat, env)
if t == nil { if t == nil {
return fmt.Errorf("unable to parse type %s", prettyFlatField(flat, env)) return fmt.Errorf("unable to parse type %s", prettyFlatField(flat, env))
} }

@ -4,7 +4,6 @@ import (
"math" "math"
"github.com/jordanorelli/hyperstone/bit" "github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
) )
const ( const (
@ -13,42 +12,38 @@ const (
f_center f_center
) )
func floatType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe { func floatType(spec *typeSpec, env *Env) tÿpe {
switch env.symbol(int(flat.GetVarTypeSym())) { switch spec.typeName {
case "CNetworkedQuantizedFloat": case "CNetworkedQuantizedFloat":
return qFloatType(flat, env) return qFloatType(spec, env)
case "float32": case "float32":
default: default:
return nil return nil
} }
if env.symbol(int(flat.GetVarEncoderSym())) == "coord" { if spec.encoder == "coord" {
return nil return nil
} }
if env.symbol(int(flat.GetFieldSerializerNameSym())) == "simulationtime" { if spec.serializer == "simulationtime" {
return nil return nil
} }
switch flat.GetBitCount() { switch spec.bits {
case 0, 32: case 0, 32:
Debug.Printf(" std float type") Debug.Printf(" std float type")
return typeFn(float_t) return typeFn(float_t)
default: default:
return qFloatType(flat, env) return qFloatType(spec, env)
} }
} }
func qFloatType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe { func qFloatType(spec *typeSpec, env *Env) tÿpe {
if flat.GetBitCount() < 0 { if spec.bits < 0 {
return typeError("quantized float has invalid negative bit count specifier") return typeError("quantized float has invalid negative bit count specifier")
} }
if flat.GetHighValue()-flat.GetLowValue() < 0 { if spec.high-spec.low < 0 {
return typeError("quantized float has invalid negative range") return typeError("quantized float has invalid negative range")
} }
t := qfloat_t{
bits: uint(flat.GetBitCount()), t := qfloat_t{typeSpec: *spec}
low: flat.GetLowValue(),
high: flat.GetHighValue(),
flags: int(flat.GetEncodeFlags()) & 0x7,
}
t.span = t.high - t.low t.span = t.high - t.low
t.intervals = uint(1<<t.bits - 1) t.intervals = uint(1<<t.bits - 1)
t.interval = t.span / float32(t.intervals) t.interval = t.span / float32(t.intervals)
@ -72,10 +67,7 @@ func qFloatType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe {
} }
type qfloat_t struct { type qfloat_t struct {
bits uint typeSpec
low float32
high float32
flags int
span float32 // total range of values span float32 // total range of values
intervals uint // number of intervals in the quantization range intervals uint // number of intervals in the quantization range
interval float32 // width of one interval interval float32 // width of one interval

@ -2,15 +2,14 @@ package ent
import ( import (
"github.com/jordanorelli/hyperstone/bit" "github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
) )
// a handle represents a soft pointer to an entity. handles are represented by // a handle represents a soft pointer to an entity. handles are represented by
// IDs and can cross the client-server divide. // IDs and can cross the client-server divide.
type handle int type handle int
func handleType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe { func handleType(spec *typeSpec, env *Env) tÿpe {
if env.symbol(int(flat.GetVarTypeSym())) != "CGameSceneNodeHandle" { if spec.typeName != "CGameSceneNodeHandle" {
return nil return nil
} }

@ -2,11 +2,10 @@ package ent
import ( import (
"github.com/jordanorelli/hyperstone/bit" "github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
) )
func hSeqType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe { func hSeqType(spec *typeSpec, env *Env) tÿpe {
if env.symbol(int(flat.GetVarTypeSym())) != "HSequence" { if spec.typeName != "HSequence" {
return nil return nil
} }

@ -2,14 +2,13 @@ package ent
import ( import (
"github.com/jordanorelli/hyperstone/bit" "github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
) )
func qAngleType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe { func qAngleType(spec *typeSpec, env *Env) tÿpe {
if env.symbol(int(flat.GetVarTypeSym())) != "QAngle" { if spec.typeName != "QAngle" {
return nil return nil
} }
switch flat.GetBitCount() { switch spec.bits {
case 0: case 0:
Debug.Printf(" qangle type") Debug.Printf(" qangle type")
return typeFn(func(r bit.Reader) (value, error) { return typeFn(func(r bit.Reader) (value, error) {

@ -15,12 +15,18 @@ type typeFn func(bit.Reader) (value, error)
func (fn typeFn) read(r bit.Reader) (value, error) { return fn(r) } func (fn typeFn) read(r bit.Reader) (value, error) { return fn(r) }
type typeParseFn func(*dota.ProtoFlattenedSerializerFieldT, *Env) tÿpe type typeParseFn func(*typeSpec, *Env) tÿpe
func parseType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe { func parseFieldType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe {
spec := new(typeSpec)
spec.fromProto(flat, env)
return parseTypeSpec(spec, env)
}
func parseTypeSpec(spec *typeSpec, env *Env) tÿpe {
coalesce := func(fns ...typeParseFn) tÿpe { coalesce := func(fns ...typeParseFn) tÿpe {
for _, fn := range fns { for _, fn := range fns {
if t := fn(flat, env); t != nil { if t := fn(spec, env); t != nil {
return t return t
} }
} }
@ -43,3 +49,39 @@ func (e error_t) Error() string { return string(e) }
func (e error_t) read(r bit.Reader) (value, error) { func (e error_t) read(r bit.Reader) (value, error) {
return nil, fmt.Errorf("type error: %s", string(e)) return nil, fmt.Errorf("type error: %s", string(e))
} }
type typeSpec struct {
name string
typeName string
bits uint
low float32
high float32
flags int
serializer string
serializerV int
send string
encoder string
}
func (s *typeSpec) fromProto(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) {
s.name = env.symbol(int(flat.GetVarNameSym()))
s.typeName = env.symbol(int(flat.GetVarTypeSym()))
if flat.GetBitCount() < 0 {
// this would cause ridiculously long reads later if we let it overflow
panic("negative bit count: data is likely corrupt")
}
s.bits = uint(flat.GetBitCount())
s.low = flat.GetLowValue()
s.high = flat.GetHighValue()
s.flags = int(flat.GetEncodeFlags())
if flat.FieldSerializerNameSym != nil {
s.serializer = env.symbol(int(*flat.FieldSerializerNameSym))
}
s.serializerV = int(flat.GetFieldSerializerVersion())
if flat.SendNodeSym != nil {
s.send = env.symbol(int(*flat.SendNodeSym))
}
if flat.VarEncoderSym != nil {
s.encoder = env.symbol(int(*flat.VarEncoderSym))
}
}

Loading…
Cancel
Save