diff --git a/bit/reader.go b/bit/reader.go index ac82891..0e8446e 100644 --- a/bit/reader.go +++ b/bit/reader.go @@ -49,6 +49,11 @@ func (r *Reader) ReadBits(bits uint) (n uint64) { return } +// discards up to bits bits. returns a bool indicating wheter any errors occured. +func (r *Reader) DiscardBits(n int) { + r.ReadBits(uint(n)) +} + // ReadByte reads a single byte, regardless of alignment. func (r *Reader) ReadByte() (byte, error) { if r.bits == 0 { @@ -73,6 +78,17 @@ func (r *Reader) Read(buf []byte) (int, error) { return len(buf), nil } +// discards N byte of data on the reader or until EOF +func (r *Reader) DiscardBytes(n int) { + for i := 0; i < n; i++ { + _, err := r.ReadByte() + if err != nil { + r.err = err + return + } + } +} + // ReadUbitVar reads a prefixed uint value. A prefix is 2 bits wide, followed // by the 4 least-significant bits, then a variable number of most-significant // bits based on the prefix. diff --git a/main.go b/main.go index 6a0dcc2..a928b2b 100644 --- a/main.go +++ b/main.go @@ -9,7 +9,7 @@ import ( "fmt" "io" "os" - "reflect" + // "reflect" "runtime/pprof" "strings" ) @@ -123,12 +123,15 @@ func main() { c := make(chan maybe, 32) p := newParser(r) + delete(p.ewl, EBaseGameEvents_GE_SosStartSoundEvent) + delete(p.ewl, EDotaUserMessages_DOTA_UM_SpectatorPlayerUnitOrders) + delete(p.ewl, EDotaUserMessages_DOTA_UM_SpectatorPlayerClick) go p.run(c) for m := range c { if m.error != nil { fmt.Fprintln(os.Stderr, m.error) } else { - fmt.Println(reflect.TypeOf(m.Message)) + // fmt.Println(reflect.TypeOf(m.Message)) } } if p.err != nil { diff --git a/parser.go b/parser.go index cc1badd..a1be3d5 100644 --- a/parser.go +++ b/parser.go @@ -72,8 +72,13 @@ func (p *parser) emitChildren(pkt *dota.CDemoPacket, c chan maybe) { for { t := entityType(br.ReadUBitVar()) s := br.ReadVarInt() - b := p.scratch[:s] - br.Read(b) + + if p.ewl[t] { + br.Read(p.scratch[:s]) + } else { + br.DiscardBytes(int(s)) + continue + } switch err := br.Err(); err { case nil: @@ -85,14 +90,10 @@ func (p *parser) emitChildren(pkt *dota.CDemoPacket, c chan maybe) { return } - if !p.ewl[t] { - continue - } - - p.pbuf.SetBuf(b) + p.pbuf.SetBuf(p.scratch[:s]) e, err := messages.BuildEntity(t) if err != nil { - c <- maybe{error: wrap(err, "skipping entity of size %d, type %s", len(b), t)} + c <- maybe{error: wrap(err, "skipping entity of size %d, type %s", s, t)} continue } if err := p.pbuf.Unmarshal(e); err != nil {