string table updates

master
Jordan Orelli 8 years ago
parent 4f20e1aac1
commit 227ebfd445

@ -0,0 +1,46 @@
package main
type intRing struct {
items []int
next int // index of the next available slot
full bool // whether or not we've filled the ring
base int // index in items of the virtual zero index
}
func newIntRing(size int) *intRing {
return &intRing{
items: make([]int, size),
}
}
func (r *intRing) add(i int) {
r.items[r.next] = i
r.next = r.incr(r.next)
if !r.full && r.next == 0 {
r.full = true
}
if r.full {
r.base = r.incr(r.base)
}
}
func (r *intRing) incr(i int) int {
if i == len(r.items)-1 {
return 0
}
return i + 1
}
func (r *intRing) at(i int) int {
idx := r.base + i
for idx >= len(r.items) {
idx -= len(r.items)
}
return r.items[idx]
}
func (r *intRing) clear() {
r.next = 0
r.full = false
r.base = 0
}

@ -40,13 +40,14 @@ func newStringTables() *stringTables {
} }
type stringTable struct { type stringTable struct {
name string
entries []stringTableEntry entries []stringTableEntry
byteSize int byteSize int
bitSize int // this is in the protobuf message but I don't know what it does. bitSize int // this is in the protobuf message but I don't know what it does.
} }
func (s stringTable) String() string { func (s stringTable) String() string {
return fmt.Sprintf("{%s}", s.entries) return fmt.Sprintf("{%s %s}", s.name, s.entries)
} }
func (t *stringTable) create(br *bit.BufReader, entries int) { func (t *stringTable) create(br *bit.BufReader, entries int) {
@ -111,10 +112,10 @@ func (s *stringTables) handle(m proto.Message) {
case *dota.CSVCMsg_CreateStringTable: case *dota.CSVCMsg_CreateStringTable:
prettyPrint(m) prettyPrint(m)
s.handleCreate(v) s.handleCreate(v)
fmt.Println(s) // fmt.Println(s)
case *dota.CSVCMsg_UpdateStringTable: case *dota.CSVCMsg_UpdateStringTable:
// prettyPrint(m) prettyPrint(m)
// s.handleUpdate(v) s.handleUpdate(v)
case *dota.CSVCMsg_ClearAllStringTables: case *dota.CSVCMsg_ClearAllStringTables:
// prettyPrint(m) // prettyPrint(m)
case *dota.CDemoStringTables: case *dota.CDemoStringTables:
@ -125,9 +126,9 @@ func (s *stringTables) handle(m proto.Message) {
func (s *stringTables) handleCreate(m *dota.CSVCMsg_CreateStringTable) { func (s *stringTables) handleCreate(m *dota.CSVCMsg_CreateStringTable) {
fmt.Printf("create %s\n", m.GetName()) fmt.Printf("create %s\n", m.GetName())
if m.GetUserDataFixedSize() { if m.GetUserDataFixedSize() {
s.tables = append(s.tables, stringTable{byteSize: int(m.GetUserDataSize()), bitSize: int(m.GetUserDataSizeBits())}) s.tables = append(s.tables, stringTable{name: m.GetName(), byteSize: int(m.GetUserDataSize()), bitSize: int(m.GetUserDataSizeBits())})
} else { } else {
s.tables = append(s.tables, stringTable{}) s.tables = append(s.tables, stringTable{name: m.GetName()})
} }
s.idx[m.GetName()] = &s.tables[len(s.tables)-1] s.idx[m.GetName()] = &s.tables[len(s.tables)-1]
table := &s.tables[len(s.tables)-1] table := &s.tables[len(s.tables)-1]
@ -154,22 +155,71 @@ func (s *stringTables) handleCreate(m *dota.CSVCMsg_CreateStringTable) {
s.br.SetSource(sd) s.br.SetSource(sd)
table.create(s.br, int(m.GetNumEntries())) table.create(s.br, int(m.GetNumEntries()))
fmt.Println(table)
} }
// type CSVCMsg_UpdateStringTable struct {
// TableId *int32
// NumChangedEntries *int32
// StringData []byte
// }
func (s *stringTables) handleUpdate(m *dota.CSVCMsg_UpdateStringTable) { func (s *stringTables) handleUpdate(m *dota.CSVCMsg_UpdateStringTable) {
// hazard // hazard
table := s.tables[m.GetTableId()] table := &s.tables[m.GetTableId()]
s.br.SetSource(m.GetStringData()) s.br.SetSource(m.GetStringData())
fmt.Printf("update %s\n", table.name)
table.update(s.br, int(m.GetNumChangedEntries())) table.update(s.br, int(m.GetNumChangedEntries()))
} }
func (t *stringTable) update(br *bit.BufReader, changed int) { func (t *stringTable) update(br *bit.BufReader, changed int) {
var (
idx = -1
entry *stringTableEntry
)
h := newIntRing(32)
for i := 0; i < changed; i++ {
// sequential index flag should rarely be true in update
if bit.ReadBool(br) {
idx++
} else {
idx = int(bit.ReadVarInt(br)) + 1
}
h.add(idx)
for idx > len(t.entries)-1 {
t.entries = append(t.entries, stringTableEntry{})
}
entry = &t.entries[idx]
fmt.Printf("%s -> ", entry)
// key flag
if bit.ReadBool(br) {
// backreading flag
if bit.ReadBool(br) {
prev, pLen := h.at(int(br.ReadBits(5))), int(br.ReadBits(5))
if prev < len(t.entries) {
prevEntry := &t.entries[prev]
entry.key = prevEntry.key[:pLen] + bit.ReadString(br)
} else {
panic("backread error")
}
} else {
entry.key = bit.ReadString(br)
}
}
// value flag
if bit.ReadBool(br) {
if t.byteSize != 0 {
if entry.value == nil {
entry.value = make([]byte, t.byteSize)
}
} else {
size, _ := int(br.ReadBits(14)), br.ReadBits(3)
if len(entry.value) < size {
entry.value = make([]byte, size)
} else {
entry.value = entry.value[:size]
}
}
br.Read(entry.value)
}
fmt.Printf("%s\n", entry)
}
} }

Loading…
Cancel
Save