@@ -35,6 +35,42 @@ type sendTableParser interface {
3535 OnEntity (h st.EntityHandler )
3636}
3737
38+ // header contains information from a demo's header.
39+ type header struct {
40+ Filestamp string // aka. File-type, must be HL2DEMO
41+ NetworkProtocol int // Not sure what this is for
42+ ServerName string // Server's 'hostname' config value
43+ ClientName string // Usually 'GOTV Demo'
44+ MapName string // E.g. de_cache, de_nuke, cs_office, etc.
45+ GameDirectory string // Usually 'csgo'
46+ PlaybackTime time.Duration // Demo duration in seconds (= PlaybackTicks / Server's tickrate)
47+ PlaybackTicks int // Game duration in ticks (= PlaybackTime * Server's tickrate)
48+ PlaybackFrames int // Amount of 'frames' aka demo-ticks recorded (= PlaybackTime * Demo's recording rate)
49+ }
50+
51+ // FrameRate returns the frame rate of the demo (frames / demo-ticks per second).
52+ // Not necessarily the tick-rate the server ran on during the game.
53+ //
54+ // Returns 0 if PlaybackTime or PlaybackFrames are 0 (corrupt demo headers).
55+ func (h * header ) FrameRate () float64 {
56+ if h .PlaybackTime == 0 {
57+ return 0
58+ }
59+
60+ return float64 (h .PlaybackFrames ) / h .PlaybackTime .Seconds ()
61+ }
62+
63+ // FrameTime returns the time a frame / demo-tick takes in seconds.
64+ //
65+ // Returns 0 if PlaybackTime or PlaybackFrames are 0 (corrupt demo headers).
66+ func (h * header ) FrameTime () time.Duration {
67+ if h .PlaybackFrames == 0 {
68+ return 0
69+ }
70+
71+ return time .Duration (h .PlaybackTime .Nanoseconds () / int64 (h .PlaybackFrames ))
72+ }
73+
3874/*
3975Parser can parse a CS:GO demo.
4076Creating a new instance is done via NewParser().
@@ -50,8 +86,6 @@ Example (without error handling):
5086 f, _ := os.Open("/path/to/demo.dem")
5187 p := dem.NewParser(f)
5288 defer p.Close()
53- header := p.ParseHeader()
54- fmt.Println("Map:", header.MapName)
5589 p.RegisterEventHandler(func(e events.BombExplode) {
5690 fmt.Printf(e.Site, "went BOOM!")
5791 })
@@ -70,9 +104,9 @@ type parser struct {
70104 msgDispatcher * dp.Dispatcher // Net-message dispatcher
71105 gameEventHandler gameEventHandler
72106 eventDispatcher * dp.Dispatcher
73- currentFrame int // Demo-frame, not ingame-tick
74- tickInterval float32 // Duration between ticks in seconds
75- header * common. DemoHeader // Pointer so we can check for nil
107+ currentFrame int // Demo-frame, not ingame-tick
108+ tickInterval float32 // Duration between ticks in seconds
109+ header * header // Pointer so we can check for nil
76110 gameState * gameState
77111 demoInfoProvider demoInfoProvider // Provides demo infos to other packages that the core package depends on
78112 err error // Contains a error that occurred during parsing if any
@@ -129,20 +163,14 @@ func (p *parser) ServerClasses() st.ServerClasses {
129163 return p .stParser .ServerClasses ()
130164}
131165
132- // Header returns the DemoHeader which contains the demo's metadata.
133- // Only possible after ParserHeader() has been called.
134- func (p * parser ) Header () common.DemoHeader {
135- return * p .header
136- }
137-
138166// GameState returns the current game-state.
139167// It contains most of the relevant information about the game such as players, teams, scores, grenades etc.
140168func (p * parser ) GameState () GameState {
141169 return p .gameState
142170}
143171
144172// CurrentFrame return the number of the current frame, aka. 'demo-tick' (Since demos often have a different tick-rate than the game).
145- // Starts with frame 0, should go up to DemoHeader .PlaybackFrames but might not be the case (usually it's just close to it).
173+ // Starts with frame 0, should go up to header .PlaybackFrames but might not be the case (usually it's just close to it).
146174func (p * parser ) CurrentFrame () int {
147175 return p .currentFrame
148176}
@@ -168,7 +196,7 @@ func (p *parser) TickRate() float64 {
168196 return - 1
169197}
170198
171- func legacyTickRate (h common. DemoHeader ) float64 {
199+ func legacyTickRate (h header ) float64 {
172200 if h .PlaybackTime == 0 {
173201 return 0
174202 }
@@ -192,7 +220,7 @@ func (p *parser) TickTime() time.Duration {
192220 return - 1
193221}
194222
195- func legayTickTime (h common. DemoHeader ) time.Duration {
223+ func legayTickTime (h header ) time.Duration {
196224 if h .PlaybackTicks == 0 {
197225 return 0
198226 }
@@ -410,7 +438,7 @@ type ParserConfig struct {
410438 // MsgQueueBufferSize defines the size of the internal net-message queue.
411439 // For large demos, fast i/o and slow CPUs higher numbers are suggested and vice versa.
412440 // The buffer size can easily be in the hundred-thousands to low millions for the best performance.
413- // A negative value will make the Parser automatically decide the buffer size during ParseHeader ()
441+ // A negative value will make the Parser automatically decide the buffer size during parseHeader ()
414442 // based on the number of ticks in the demo (nubmer of ticks = buffer size);
415443 // this is the default behavior for DefaultParserConfig.
416444 // Zero enforces sequential parsing.
0 commit comments