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
Jordan Orelli 8 years ago
parent b73b917084
commit 8b4c666284

@ -6,13 +6,7 @@ import (
"github.com/jordanorelli/hyperstone/dota"
)
// classInfo container contains info about entity classes found in a given
// replay
type classInfo struct {
names map[int]string
}
func (c *classInfo) handle(m proto.Message) {
func dumpClasses(m proto.Message) {
v, ok := m.(*dota.CDemoClassInfo)
if !ok {
return
@ -20,6 +14,5 @@ func (c *classInfo) handle(m proto.Message) {
for _, class := range v.GetClasses() {
fmt.Printf("class-id: %d network-name: %s table-name: %s\n", class.GetClassId(), class.GetNetworkName(), class.GetTableName())
c.names[int(class.GetClassId())] = class.GetNetworkName()
}
}

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

@ -3,7 +3,9 @@ package main
import (
"fmt"
"github.com/golang/protobuf/proto"
"github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
"github.com/jordanorelli/hyperstone/ent"
)
// type CSVCMsg_PacketEntities struct {
@ -20,12 +22,41 @@ import (
// }
func dumpEntities(m proto.Message) {
ctx := ent.NewContext()
switch v := m.(type) {
case *dota.CDemoSendTables:
ctx.MergeSendTables(v)
case *dota.CDemoClassInfo:
ctx.MergeClassInfo(v)
case *dota.CSVCMsg_PacketEntities:
data := v.GetEntityData()
if len(data) > 32 {
data = data[:32]
}
fmt.Printf("{MaxEntries: %d UpdatedEntries: %v IsDelta: %t UpdateBaseline: %t Baseline: %d DeltaFrom: %d EntityData: %x PendingFullFrame: %t ActiveSpawngroupHandle: %d}\n", v.GetMaxEntries(), v.GetUpdatedEntries(), v.GetIsDelta(), v.GetUpdateBaseline(), v.GetBaseline(), v.GetDeltaFrom(), data, v.GetPendingFullFrame(), v.GetActiveSpawngroupHandle())
br := bit.NewBytesReader(data)
id := -1
for i := 0; i < int(v.GetUpdatedEntries()); i++ {
id++
// there may be a jump indicator, indicating how many id positions
// to skip.
id += int(bit.ReadUBitVar(br))
// next two bits encode one of four entity mutate operations
switch br.ReadBits(2) {
case 0:
// update
case 1:
// leave
case 2:
ctx.CreateEntity(id, br)
case 3:
// delete
}
}
}
}

@ -124,14 +124,11 @@ func main() {
handle = printTypes
case "pretty":
handle = prettyPrint
case "send-tables":
handle = sendTables
case "string-tables":
st := newStringTables()
handle = st.handle
case "class-info":
ci := new(classInfo)
handle = ci.handle
handle = dumpClasses
case "entities":
handle = dumpEntities
default:

@ -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…
Cancel
Save