master
Jordan Orelli 8 years ago
parent cf1f6e39fd
commit cccd4c4c1b

@ -0,0 +1,72 @@
package main
import (
"fmt"
"github.com/golang/protobuf/proto"
"github.com/golang/snappy"
"github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
)
// datagram represents the top-level envelope in the dota replay format. All
// data in the replay file is packed into datagram frames of at most 65kb.
type dataGram struct {
cmd dota.EDemoCommands
tick int64
compressed bool
body []byte
}
func (g dataGram) String() string {
if len(g.body) > 30 {
return fmt.Sprintf("{dataGram cmd: %v tick: %v compressed: %t size: %d body: %q...}", g.cmd, g.tick, g.compressed, len(g.body), g.body[:27])
}
return fmt.Sprintf("{dataGram cmd: %v tick: %v compressed: %t size: %d body: %q}", g.cmd, g.tick, g.compressed, len(g.body), g.body)
}
func (g *dataGram) check(dump bool) error {
if g.cmd != dota.EDemoCommands_DEM_Packet {
return fmt.Errorf("wrong command type in openPacket: %v", g.cmd)
}
if g.compressed {
buf, err := snappy.Decode(nil, g.body)
if err != nil {
return wrap(err, "open packet error: could not decode body")
}
g.body = buf
g.compressed = false
}
packet := new(dota.CDemoPacket)
if err := proto.Unmarshal(g.body, packet); err != nil {
return wrap(err, "onPacket unable to unmarshal message body")
}
if dump {
br := bit.NewBytesReader(packet.GetData())
for {
t := br.ReadUBitVar()
s := br.ReadVarInt()
b := make([]byte, s)
br.Read(b)
if br.Err() != nil {
break
}
fmt.Printf("\t%v\n", entity{t: uint32(t), size: uint32(s), body: b})
e := entFactory.BuildMessage(int(t))
if e == nil {
fmt.Printf("\tno known entity for type id %d\n", int(t))
continue
}
err := proto.Unmarshal(b, e)
if err != nil {
fmt.Printf("entity unmarshal error: %v\n", err)
} else {
fmt.Printf("\t\t%v\n", e)
}
}
}
return nil
}

@ -0,0 +1,18 @@
package main
import (
"fmt"
)
type entity struct {
t uint32
size uint32
body []byte
}
func (e entity) String() string {
if len(e.body) < 32 {
return fmt.Sprintf("{entity type: %d size: %d data: %x}", e.t, e.size, e.body)
}
return fmt.Sprintf("{entity type: %d size: %d data: %x...}", e.t, e.size, e.body[:32])
}

@ -1,86 +0,0 @@
package main
import (
"fmt"
"github.com/golang/protobuf/proto"
"github.com/golang/snappy"
"github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
)
// message represents the top-level envelope in the dota replay format. Each
// datum is contained within a message envelope. Each message envelope is at
// most 1<<16 bytes.
type message struct {
cmd dota.EDemoCommands
tick int64
compressed bool
body []byte
}
func (m message) String() string {
if len(m.body) > 30 {
return fmt.Sprintf("{cmd: %v tick: %v compressed: %t size: %d body: %q...}", m.cmd, m.tick, m.compressed, len(m.body), m.body[:27])
}
return fmt.Sprintf("{cmd: %v tick: %v compressed: %t size: %d body: %q}", m.cmd, m.tick, m.compressed, len(m.body), m.body)
}
type entity struct {
t uint32
size uint32
body []byte
}
func (e entity) String() string {
if len(e.body) < 32 {
return fmt.Sprintf("{%v %v %x}", e.t, e.size, e.body)
}
return fmt.Sprintf("{%v %v %x...}", e.t, e.size, e.body[:32])
}
func (m *message) check(dump bool) error {
if m.cmd != dota.EDemoCommands_DEM_Packet {
return fmt.Errorf("wrong command type in openPacket: %v", m.cmd)
}
if m.compressed {
buf, err := snappy.Decode(nil, m.body)
if err != nil {
return wrap(err, "open packet error: could not decode body")
}
m.body = buf
m.compressed = false
}
packet := new(dota.CDemoPacket)
if err := proto.Unmarshal(m.body, packet); err != nil {
return wrap(err, "onPacket unable to unmarshal message body")
}
if dump {
br := bit.NewBytesReader(packet.GetData())
for {
t := br.ReadUBitVar()
s := br.ReadVarInt()
b := make([]byte, s)
br.Read(b)
if br.Err() != nil {
break
}
fmt.Printf("\t%v\n", entity{t: uint32(t), size: uint32(s), body: b})
e := entFactory.BuildMessage(int(t))
if e == nil {
fmt.Printf("\tno known entity for type id %d\n", int(t))
continue
}
err := proto.Unmarshal(b, e)
if err != nil {
fmt.Printf("entity unmarshal error: %v\n", err)
} else {
fmt.Printf("\t\t%v\n", e)
}
}
}
return nil
}

@ -133,7 +133,7 @@ func (p *parser) readCommand() (dota.EDemoCommands, bool, error) {
return dota.EDemoCommands(n), compressed, nil
}
func (p *parser) readMessage() (*message, error) {
func (p *parser) readMessage() (*dataGram, error) {
cmd, compressed, err := p.readCommand()
if err != nil {
return nil, wrap(err, "readMessage couldn't get a command")
@ -155,9 +155,9 @@ func (p *parser) readMessage() (*message, error) {
return nil, wrap(err, "readMessage couldn't read message body")
}
// TODO: pool these!
return &message{cmd, int64(tick), compressed, buf}, nil
return &dataGram{cmd, int64(tick), compressed, buf}, nil
}
// TODO: pool these!
return &message{cmd, int64(tick), compressed, nil}, nil
return &dataGram{cmd, int64(tick), compressed, nil}, nil
}

Loading…
Cancel
Save