@@ -19,31 +19,32 @@ import (
1919// After parsing the header Parser.ParseNextFrame() and Parser.ParseToEnd() can be used to parse the demo.
2020// Use Parser.RegisterEventHandler() to receive notifications about events.
2121type Parser struct {
22- bitReader * bit.BitReader
23- stParser st.SendTableParser
24- msgDispatcher dp.Dispatcher
25- eventDispatcher dp.Dispatcher
26- msgQueue chan interface {}
27- gameState GameState
28- currentFrame int
29- bombsiteA bombsite
30- bombsiteB bombsite
31- header * common.DemoHeader // Pointer so we can check for nil
32- equipmentMapping map [* st.ServerClass ]common.EquipmentElement
33- rawPlayers map [int ]* playerInfo
34- entityIDToPlayers map [int ]* common.Player // Temporary storage since we need to map players from entityID to userID later
35- additionalPlayerInfo [maxPlayers ]common.AdditionalPlayerInformation
36- entities map [int ]* st.Entity
37- modelPreCache []string // Used to find out whether a weapon is a p250 or cz for example (same id)
38- weapons [maxEntities ]common.Equipment // Used to remember what a weapon is (p250 / cz etc.)
39- triggers map [int ]* boundingBoxInformation
40- instanceBaselines map [int ][]byte
41- preprocessedBaselines map [int ]map [int ]st.PropValue
42- gameEventDescs map [int32 ]* msg.CSVCMsg_GameEventListDescriptorT
43- stringTables []* msg.CSVCMsg_CreateStringTable
44- cancelChan chan struct {}
45- err error
46- errLock sync.Mutex
22+ bitReader * bit.BitReader
23+ stParser st.SendTableParser
24+ msgDispatcher dp.Dispatcher
25+ additionalNetMessageCreators map [int ]NetMessageCreator
26+ eventDispatcher dp.Dispatcher
27+ msgQueue chan interface {}
28+ gameState GameState
29+ currentFrame int
30+ bombsiteA bombsite
31+ bombsiteB bombsite
32+ header * common.DemoHeader // Pointer so we can check for nil
33+ equipmentMapping map [* st.ServerClass ]common.EquipmentElement
34+ rawPlayers map [int ]* playerInfo
35+ entityIDToPlayers map [int ]* common.Player // Temporary storage since we need to map players from entityID to userID later
36+ additionalPlayerInfo [maxPlayers ]common.AdditionalPlayerInformation
37+ entities map [int ]* st.Entity
38+ modelPreCache []string // Used to find out whether a weapon is a p250 or cz for example (same id)
39+ weapons [maxEntities ]common.Equipment // Used to remember what a weapon is (p250 / cz etc.)
40+ triggers map [int ]* boundingBoxInformation
41+ instanceBaselines map [int ][]byte
42+ preprocessedBaselines map [int ]map [int ]st.PropValue
43+ gameEventDescs map [int32 ]* msg.CSVCMsg_GameEventListDescriptorT
44+ stringTables []* msg.CSVCMsg_CreateStringTable
45+ cancelChan chan struct {}
46+ err error
47+ errLock sync.Mutex
4748}
4849
4950type bombsite struct {
@@ -100,17 +101,33 @@ func (p *Parser) Progress() float32 {
100101// Must be of type func(<EventType>) where EventType is the kind of event that is handled.
101102// To catch all events func(interface{}) can be used.
102103// Parameter handler has to be of type interface{} because lolnogenerics.
103- // Returns a identifier with which the handler can be removed via UnregisterEventHandler()
104+ // Returns a identifier with which the handler can be removed via UnregisterEventHandler().
104105func (p * Parser ) RegisterEventHandler (handler interface {}) dp.HandlerIdentifier {
105106 return p .eventDispatcher .RegisterHandler (handler )
106107}
107108
108- // UnregisterEventHandler removes a handler via identifier.
109- // The identifier is returned at registration by RegisterEventHandler()
109+ // UnregisterEventHandler removes a game event handler via identifier.
110+ // The identifier is returned at registration by RegisterEventHandler().
110111func (p * Parser ) UnregisterEventHandler (identifier dp.HandlerIdentifier ) {
111112 p .eventDispatcher .UnregisterHandler (identifier )
112113}
113114
115+ // RegisterNetMessageHandler registers a handler for net-messages.
116+ // Must be of type func(*<EventType>) where EventType is the kind of event that is handled.
117+ // To catch all events func(interface{}) can be used.
118+ // Parameter handler has to be of type interface{} because lolnogenerics.
119+ // Returns a identifier with which the handler can be removed via UnregisterNetMessageHandler().
120+ // This is a beta feature and may be changed or replaced without notice.
121+ func (p * Parser ) RegisterNetMessageHandler (handler interface {}) dp.HandlerIdentifier {
122+ return p .msgDispatcher .RegisterHandler (handler )
123+ }
124+
125+ // UnregisterNetMessageHandler removes a net-message handler via identifier.
126+ // The identifier is returned at registration by RegisterNetMessageHandler().
127+ func (p * Parser ) UnregisterNetMessageHandler (identifier dp.HandlerIdentifier ) {
128+ p .msgDispatcher .UnregisterHandler (identifier )
129+ }
130+
114131func (p * Parser ) error () (err error ) {
115132 p .errLock .Lock ()
116133 err = p .err
@@ -143,6 +160,12 @@ type ParserConfig struct {
143160 // this is the default behavior for DefaultParserConfig.
144161 // Zero enforces sequential parsing.
145162 MsgQueueBufferSize int
163+ // AdditionalNetMessageCreators maps net-message-IDs to creators (instantiators).
164+ // The creators should return a new instance of the correct protobuf-message type (from the msg package).
165+ // Interesting net-message-IDs can easily be discovered with the build-tag 'debugdemoinfocs'; when looking for 'UnhandledMessage'.
166+ // Check out demopacket.go to see which net-messages are already being parsed by default.
167+ // This is a beta feature and may be changed or replaced without notice.
168+ AdditionalNetMessageCreators map [int ]NetMessageCreator
146169}
147170
148171// DefaultParserConfig is the default Parser configuration used by NewParser().
@@ -182,6 +205,8 @@ func NewParserWithConfig(demostream io.Reader, config ParserConfig) *Parser {
182205 p .initMsgQueue (config .MsgQueueBufferSize )
183206 }
184207
208+ p .additionalNetMessageCreators = config .AdditionalNetMessageCreators
209+
185210 return & p
186211}
187212
0 commit comments