@@ -35,6 +35,42 @@ type sendTableParser interface {
35
35
OnEntity (h st.EntityHandler )
36
36
}
37
37
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
+
38
74
/*
39
75
Parser can parse a CS:GO demo.
40
76
Creating a new instance is done via NewParser().
@@ -50,8 +86,6 @@ Example (without error handling):
50
86
f, _ := os.Open("/path/to/demo.dem")
51
87
p := dem.NewParser(f)
52
88
defer p.Close()
53
- header := p.ParseHeader()
54
- fmt.Println("Map:", header.MapName)
55
89
p.RegisterEventHandler(func(e events.BombExplode) {
56
90
fmt.Printf(e.Site, "went BOOM!")
57
91
})
@@ -70,9 +104,9 @@ type parser struct {
70
104
msgDispatcher * dp.Dispatcher // Net-message dispatcher
71
105
gameEventHandler gameEventHandler
72
106
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
76
110
gameState * gameState
77
111
demoInfoProvider demoInfoProvider // Provides demo infos to other packages that the core package depends on
78
112
err error // Contains a error that occurred during parsing if any
@@ -129,20 +163,14 @@ func (p *parser) ServerClasses() st.ServerClasses {
129
163
return p .stParser .ServerClasses ()
130
164
}
131
165
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
-
138
166
// GameState returns the current game-state.
139
167
// It contains most of the relevant information about the game such as players, teams, scores, grenades etc.
140
168
func (p * parser ) GameState () GameState {
141
169
return p .gameState
142
170
}
143
171
144
172
// 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).
146
174
func (p * parser ) CurrentFrame () int {
147
175
return p .currentFrame
148
176
}
@@ -168,7 +196,7 @@ func (p *parser) TickRate() float64 {
168
196
return - 1
169
197
}
170
198
171
- func legacyTickRate (h common. DemoHeader ) float64 {
199
+ func legacyTickRate (h header ) float64 {
172
200
if h .PlaybackTime == 0 {
173
201
return 0
174
202
}
@@ -192,7 +220,7 @@ func (p *parser) TickTime() time.Duration {
192
220
return - 1
193
221
}
194
222
195
- func legayTickTime (h common. DemoHeader ) time.Duration {
223
+ func legayTickTime (h header ) time.Duration {
196
224
if h .PlaybackTicks == 0 {
197
225
return 0
198
226
}
@@ -410,7 +438,7 @@ type ParserConfig struct {
410
438
// MsgQueueBufferSize defines the size of the internal net-message queue.
411
439
// For large demos, fast i/o and slow CPUs higher numbers are suggested and vice versa.
412
440
// 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 ()
414
442
// based on the number of ticks in the demo (nubmer of ticks = buffer size);
415
443
// this is the default behavior for DefaultParserConfig.
416
444
// Zero enforces sequential parsing.
0 commit comments