restructuring

master
Jordan Orelli 8 years ago
parent a18553a3ec
commit f28f5ecc4e

@ -11,6 +11,8 @@ import (
"os" "os"
"runtime/pprof" "runtime/pprof"
"strings" "strings"
"github.com/golang/protobuf/proto"
) )
const ( const (
@ -120,11 +122,13 @@ func main() {
bail(1, "input error: %v", err) bail(1, "input error: %v", err)
} }
c := make(chan proto.Message, 32)
p := newParser(r) p := newParser(r)
if err := p.start(); err != nil { go p.run(c)
bail(1, "parse error: %v", err) for msg := range c {
fmt.Println(msg)
} }
if err := p.run(); err != nil && err != io.EOF { if p.err != nil {
bail(1, "run error: %v", err) fmt.Println(err)
} }
} }

@ -7,8 +7,8 @@ import (
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"github.com/golang/snappy" "github.com/golang/snappy"
"github.com/jordanorelli/hyperstone/bit" // "github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota" // "github.com/jordanorelli/hyperstone/dota"
) )
type parser struct { type parser struct {
@ -17,82 +17,72 @@ type parser struct {
scratch []byte scratch []byte
pbuf *proto.Buffer pbuf *proto.Buffer
err error
} }
func newParser(r io.Reader) *parser { func newParser(r io.Reader) *parser {
br := bufio.NewReaderSize(r, 1<<16) return &parser{
return &parser{source: br, scratch: make([]byte, 1<<17), pbuf: new(proto.Buffer)} source: bufio.NewReaderSize(r, 1<<16),
scratch: make([]byte, 1<<17),
pbuf: new(proto.Buffer),
}
} }
func (p *parser) start() error { func (p *parser) run(out chan proto.Message) {
defer close(out)
ok, err := p.checkHeader() ok, err := p.checkHeader()
if err != nil { if err != nil {
return wrap(err, "parser start error") p.err = wrap(err, "parser start error")
} }
if !ok { if !ok {
return fmt.Errorf("parser start error: invalid header") p.err = fmt.Errorf("parser start error: invalid header")
} }
if _, err := p.source.Discard(8); err != nil { if _, err := p.source.Discard(8); err != nil {
return wrap(err, "parser start error") p.err = wrap(err, "parser start error")
} }
return nil
}
func (p *parser) run() error {
for { for {
gram, err := p.readPacket() pkt, err := p.readPacket()
if err != nil { if err != nil {
return wrap(err, "read packet error in run loop") p.err = wrap(err, "read packet error in run loop")
return
} }
p.handlePacket(gram) msg, err := pkt.Open(&messages, p.pbuf)
}
}
func (p *parser) handlePacket(d *packet) error {
if len(d.body) == 0 {
return nil
}
msg, err := d.Open(&messages, p.pbuf)
if err != nil {
fmt.Printf("packet open error: %v\n", err)
return nil
}
switch v := msg.(type) {
case *dota.CDemoPacket:
p.handleDemoPacket(v)
}
return nil
}
func (p *parser) handleDemoPacket(packet *dota.CDemoPacket) error {
br := bit.NewBytesReader(packet.GetData())
for {
t := entityType(br.ReadUBitVar())
s := br.ReadVarInt()
b := p.scratch[:s]
br.Read(b)
p.pbuf.SetBuf(b)
switch err := br.Err(); err {
case nil:
break
case io.EOF:
return nil
default:
return err
}
e, err := messages.BuildEntity(t)
if err != nil { if err != nil {
fmt.Printf("\tskipping entity of size %d, type %s: %v\n", len(b), t, err) p.err = wrap(err, "open packet error in run loop")
continue return
}
if err := p.pbuf.Unmarshal(e); err != nil {
fmt.Printf("entity unmarshal error: %v\n", err)
} }
out <- msg
} }
} }
//
// func (p *parser) handleDemoPacket(packet *dota.CDemoPacket) error {
// br := bit.NewBytesReader(packet.GetData())
// for {
// t := entityType(br.ReadUBitVar())
// s := br.ReadVarInt()
// b := p.scratch[:s]
// br.Read(b)
// p.pbuf.SetBuf(b)
// switch err := br.Err(); err {
// case nil:
// break
// case io.EOF:
// return nil
// default:
// return err
// }
// e, err := messages.BuildEntity(t)
// if err != nil {
// fmt.Printf("\tskipping entity of size %d, type %s: %v\n", len(b), t, err)
// continue
// }
// if err := p.pbuf.Unmarshal(e); err != nil {
// fmt.Printf("entity unmarshal error: %v\n", err)
// }
// }
// }
// DecodeVarint reads a varint-encoded integer from the source reader. // DecodeVarint reads a varint-encoded integer from the source reader.
// It returns the value as a uin64 and any errors encountered. The reader will // It returns the value as a uin64 and any errors encountered. The reader will
// be advanced by the number of bytes needed to consume this value. On error, // be advanced by the number of bytes needed to consume this value. On error,

Loading…
Cancel
Save