Example #1
0
// Internal parser for callback OnCDemoPacket, responsible for extracting
// multiple inner packets from a single CDemoPacket. This is the main structure
// that contains all other data types in the demo file.
func (p *Parser) onCDemoPacket(m *dota.CDemoPacket) error {
	// Create a slice to store pending mesages. Messages are read first as
	// pending messages then sorted before dispatch.
	ms := make(pendingMessages, 0, 2)

	// Read all messages from the buffer. Messages are packed serially as
	// {type, size, data}. We keep reading until until less than a byte remains.
	r := newReader(m.GetData())
	for r.remBytes() > 0 {
		t := int32(r.readUBitVar())
		size := r.readVarUint32()
		buf := r.readBytes(size)
		ms = append(ms, &pendingMessage{p.Tick, t, buf})
	}

	// Sort messages to ensure dependencies are met. For example, we need to
	// process string tables before game events that may reference them.
	sort.Sort(ms)

	// Dispatch messages in order, returning on handler error.
	for _, m := range ms {
		if err := p.Callbacks.callByPacketType(m.t, m.buf); err != nil {
			return err
		}
	}

	return nil
}
Example #2
0
// Internal parser for callback OnCDemoPacket, responsible for extracting
// multiple inner packets from a single CDemoPacket. This is the main structure
// that contains all other data types in the demo file.
func (p *Parser) onCDemoPacket(m *dota.CDemoPacket) error {
	// Create a slice to store pending mesages. Messages are read first as
	// pending messages then sorted before dispatch.
	ms := make(pendingMessages, 0)

	// Read all messages from the buffer. Messages are packed serially as
	// {type, size, data}. We keep reading until until less than a byte remains.
	r := NewReader(m.GetData())
	for r.remBytes() > 0 {
		t := int32(r.readUBitVar())
		size := int(r.readVarUint32())
		buf := r.readBytes(size)
		ms = append(ms, &pendingMessage{p.Tick, t, buf})
	}

	// Sort messages to ensure dependencies are met. For example, we need to
	// process string tables before game events that may reference them.
	sort.Sort(ms)

	// Dispatch messages in order.
	for _, m := range ms {
		// Skip message we don't have a definition for (yet)
		// XXX TODO: remove this when we get updated protos.
		if m.t == 400 {
			continue
		}

		// Call each packet, panic if we encounter an error.
		// XXX TODO: this should return the error up the chain. Panic for debugging.
		if err := p.CallByPacketType(m.t, m.buf); err != nil {
			panic(err)
		}
	}

	return nil
}