stop calling things send tables
there is no entity or type called send tables, that's just the label for the message. it's sending a flattened representation of datatype specifications.master
parent
b73b917084
commit
8b4c666284
@ -1,20 +0,0 @@
|
||||
package dt
|
||||
|
||||
import (
|
||||
"github.com/jordanorelli/hyperstone/dota"
|
||||
)
|
||||
|
||||
type Serializer struct {
|
||||
Name Symbol
|
||||
Version int
|
||||
Fields []*Field
|
||||
}
|
||||
|
||||
func (s *Serializer) fromProto(v *dota.ProtoFlattenedSerializerT, st *SymbolTable, fields []Field) {
|
||||
s.Name = st.Symbol(int(v.GetSerializerNameSym()))
|
||||
s.Version = int(v.GetSerializerVersion())
|
||||
s.Fields = make([]*Field, len(v.GetFieldsIndex()))
|
||||
for i, fi := range v.GetFieldsIndex() {
|
||||
s.Fields[i] = &fields[fi]
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
package dt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/jordanorelli/hyperstone/dota"
|
||||
)
|
||||
|
||||
// TableSet represents a collection of tables.
|
||||
type TableSet struct {
|
||||
SymbolTable
|
||||
Fields []Field
|
||||
Serializers []Serializer
|
||||
}
|
||||
|
||||
func (t *TableSet) DebugPrint(w io.Writer) {
|
||||
fmt.Fprintln(w, "Symbols:")
|
||||
for _, sym := range t.SymbolTable {
|
||||
fmt.Fprintf(w, "\t%s\n", sym)
|
||||
}
|
||||
fmt.Fprintln(w, "Fields:")
|
||||
for _, f := range t.Fields {
|
||||
fmt.Fprintf(w, "\t%s\n", f)
|
||||
}
|
||||
fmt.Fprintln(w, "Serializers:")
|
||||
for _, s := range t.Serializers {
|
||||
fmt.Fprintf(w, "\t%s (%d):\n", s.Name, s.Version)
|
||||
for _, f := range s.Fields {
|
||||
fmt.Fprintf(w, "\t\t%s\n", f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ParseFlattened parses a flattened TableSet definition, as defined by the
|
||||
// Dota replay protobufs.
|
||||
func ParseFlattened(m *dota.CSVCMsg_FlattenedSerializer) *TableSet {
|
||||
ts := &TableSet{SymbolTable: SymbolTable(m.GetSymbols())}
|
||||
ts.parseFields(m.GetFields())
|
||||
ts.parseSerializers(m.GetSerializers())
|
||||
return ts
|
||||
}
|
||||
|
||||
func (ts *TableSet) parseFields(flat []*dota.ProtoFlattenedSerializerFieldT) {
|
||||
ts.Fields = make([]Field, len(flat))
|
||||
for i, f := range flat {
|
||||
ts.Fields[i].fromProto(f, &ts.SymbolTable)
|
||||
}
|
||||
}
|
||||
|
||||
func (ts *TableSet) parseSerializers(flat []*dota.ProtoFlattenedSerializerT) {
|
||||
ts.Serializers = make([]Serializer, len(flat))
|
||||
for i, s := range flat {
|
||||
ts.Serializers[i].fromProto(s, &ts.SymbolTable, ts.Fields)
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package ent
|
||||
|
||||
import (
|
||||
"github.com/jordanorelli/hyperstone/dota"
|
||||
)
|
||||
|
||||
// Class represents a set of constraints around an Entity.
|
||||
type Class struct {
|
||||
Name Symbol
|
||||
Version int
|
||||
Fields []*Field
|
||||
}
|
||||
|
||||
type classId struct {
|
||||
name Symbol
|
||||
version int
|
||||
}
|
||||
|
||||
func (c *Class) fromProto(v *dota.ProtoFlattenedSerializerT, fields []Field) {
|
||||
c.Fields = make([]*Field, len(v.GetFieldsIndex()))
|
||||
for i, fi := range v.GetFieldsIndex() {
|
||||
c.Fields[i] = &fields[fi]
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package ent
|
||||
|
||||
import (
|
||||
"github.com/jordanorelli/hyperstone/bit"
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
Namespace
|
||||
entities map[int]Entity
|
||||
}
|
||||
|
||||
func NewContext() *Context {
|
||||
return &Context{entities: make(map[int]Entity)}
|
||||
}
|
||||
|
||||
func (c *Context) CreateEntity(id int, r bit.Reader) {
|
||||
}
|
||||
|
||||
func (c *Context) GetEntity(id int) Entity {
|
||||
return Entity{}
|
||||
}
|
||||
|
||||
func (c *Context) DeleteEntity(id int) {
|
||||
}
|
||||
|
||||
func (c *Context) LeaveEntity(id int) {
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package ent
|
||||
|
||||
type Entity struct {
|
||||
}
|
||||
|
||||
func (e *Entity) Update(raw []byte) {
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package dt
|
||||
package ent
|
||||
|
||||
import (
|
||||
"bytes"
|
@ -0,0 +1,86 @@
|
||||
package ent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
|
||||
"github.com/jordanorelli/hyperstone/bit"
|
||||
"github.com/jordanorelli/hyperstone/dota"
|
||||
)
|
||||
|
||||
// Namespace registers the names of known classess, associating their ids to
|
||||
// their network types.
|
||||
type Namespace struct {
|
||||
SymbolTable
|
||||
idBits int
|
||||
|
||||
// maps ClassInfo ids to class names
|
||||
classIds map[int]string
|
||||
|
||||
// maps classes to their {name, version} id pairs
|
||||
classes map[classId]*Class
|
||||
|
||||
// maps a class name to every version of the class
|
||||
classesByName map[string]map[int]*Class
|
||||
}
|
||||
|
||||
// Merges in the ClassInfo data found in the replay protobufs
|
||||
func (n *Namespace) MergeClassInfo(ci *dota.CDemoClassInfo) {
|
||||
if n.classIds == nil {
|
||||
n.classIds = make(map[int]string, len(ci.GetClasses()))
|
||||
}
|
||||
for _, class := range ci.GetClasses() {
|
||||
n.classIds[int(class.GetClassId())] = class.GetNetworkName()
|
||||
}
|
||||
n.idBits = int(math.Floor(math.Log2(float64(len(n.classIds))))) + 1
|
||||
}
|
||||
|
||||
func (n *Namespace) MergeSendTables(st *dota.CDemoSendTables) {
|
||||
// sendtables only has one field, a binary data field.
|
||||
data := st.GetData()
|
||||
br := bit.NewBytesReader(data)
|
||||
|
||||
// body is length-prefixed
|
||||
size := int(bit.ReadVarInt(br))
|
||||
|
||||
buf := make([]byte, size)
|
||||
br.Read(buf)
|
||||
|
||||
flat := dota.CSVCMsg_FlattenedSerializer{}
|
||||
if err := proto.Unmarshal(buf, &flat); err != nil {
|
||||
fmt.Printf("error: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
n.SymbolTable = SymbolTable(flat.GetSymbols())
|
||||
|
||||
fields := make([]Field, len(flat.GetFields()))
|
||||
for i, f := range flat.GetFields() {
|
||||
fields[i].fromProto(f, &n.SymbolTable)
|
||||
}
|
||||
|
||||
n.classes = make(map[classId]*Class, len(flat.GetSerializers()))
|
||||
n.classesByName = make(map[string]map[int]*Class, len(flat.GetSerializers()))
|
||||
|
||||
for _, c := range flat.GetSerializers() {
|
||||
class := Class{}
|
||||
class.fromProto(c, fields)
|
||||
|
||||
name := n.Symbol(int(c.GetSerializerNameSym()))
|
||||
version := int(c.GetSerializerVersion())
|
||||
id := classId{name: name, version: version}
|
||||
n.classes[id] = &class
|
||||
|
||||
if n.classesByName[name.String()] == nil {
|
||||
n.classesByName[name.String()] = map[int]*Class{version: &class}
|
||||
} else {
|
||||
n.classesByName[name.String()][version] = &class
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (n *Namespace) ReadClassId(r bit.Reader) int {
|
||||
return int(r.ReadBits(uint(n.idBits)))
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package dt
|
||||
package ent
|
||||
|
||||
// the internal representation of table data refers to all labels as
|
||||
// interned strings (symbols). This array of string contains the mapping of
|
@ -1,38 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
|
||||
"github.com/jordanorelli/hyperstone/bit"
|
||||
"github.com/jordanorelli/hyperstone/dota"
|
||||
"github.com/jordanorelli/hyperstone/dt"
|
||||
)
|
||||
|
||||
func sendTables(m proto.Message) {
|
||||
v, ok := m.(*dota.CDemoSendTables)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// sendtables only has one field, a binary data field.
|
||||
data := v.GetData()
|
||||
br := bit.NewBytesReader(data)
|
||||
|
||||
// body is length-prefixed
|
||||
size := int(bit.ReadVarInt(br))
|
||||
|
||||
buf := make([]byte, size)
|
||||
br.Read(buf)
|
||||
|
||||
serializer := dota.CSVCMsg_FlattenedSerializer{}
|
||||
if err := proto.Unmarshal(buf, &serializer); err != nil {
|
||||
fmt.Printf("error: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
ts := dt.ParseFlattened(&serializer)
|
||||
ts.DebugPrint(os.Stdout)
|
||||
}
|
Loading…
Reference in New Issue