Skip to content

Commit 944a72d

Browse files
authored
fix nil pointer dereference for valid demo (#162) (#163)
we just assume it's a bot since all human players were parsed correctly in the demo where this problem was encountered.
1 parent dbcfdea commit 944a72d

File tree

5 files changed

+29
-10
lines changed

5 files changed

+29
-10
lines changed

common/player.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ type Player struct {
4949
IsDefusing bool
5050
IsPlanting bool
5151
IsReloading bool
52+
IsUnknown bool // Used to identify unknown/broken players. see https://github.com/markus-wa/demoinfocs-golang/issues/162
5253
HasDefuseKit bool
5354
HasHelmet bool
5455
}

datatables.go

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -193,21 +193,33 @@ func (p *Parser) bindNewPlayer(playerEntity st.IEntity) {
193193
isNew := false
194194
pl := p.gameState.playersByEntityID[entityID]
195195
if pl == nil {
196-
pl = p.gameState.playersByUserID[rp.userID]
196+
if rp != nil {
197+
pl = p.gameState.playersByUserID[rp.userID]
197198

198-
if pl == nil {
199-
isNew = true
199+
if pl == nil {
200+
isNew = true
200201

201-
// TODO: read tickRate from CVARs as fallback
202+
pl = common.NewPlayer(p.demoInfoProvider)
203+
pl.Name = rp.name
204+
pl.SteamID = rp.xuid
205+
pl.IsBot = rp.isFakePlayer || rp.guid == "BOT"
206+
pl.UserID = rp.userID
207+
}
208+
} else {
209+
// see #162.
210+
// GOTV doesn't crash here either so we just initialize this player with default values.
211+
// this happens in some demos since November 2019 for players that were are actually connected.
212+
// in GOTV these players are just called "unknown".
202213
pl = common.NewPlayer(p.demoInfoProvider)
203-
pl.Name = rp.name
204-
pl.SteamID = rp.xuid
205-
pl.IsBot = rp.isFakePlayer || rp.guid == "BOT"
206-
pl.UserID = rp.userID
214+
pl.Name = "unknown"
215+
pl.IsUnknown = true
207216
}
208217
}
209218
p.gameState.playersByEntityID[entityID] = pl
210-
p.gameState.playersByUserID[rp.userID] = pl
219+
220+
if rp != nil {
221+
p.gameState.playersByUserID[rp.userID] = pl
222+
}
211223

212224
pl.EntityID = entityID
213225
pl.Entity = playerEntity

game_events.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,11 @@ func (geh gameEventHandler) weaponFire(data map[string]*msg.CSVCMsg_GameEventKey
282282

283283
func (geh gameEventHandler) weaponReload(data map[string]*msg.CSVCMsg_GameEventKeyT) {
284284
pl := geh.playerByUserID32(data["userid"].GetValShort())
285+
if pl == nil {
286+
// see #162, "unknown" players since November 2019 update
287+
return
288+
}
289+
285290
pl.IsReloading = true
286291
geh.dispatch(events.WeaponReload{
287292
Player: pl,

parser.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ func (p demoInfoProvider) IngameTick() int {
280280
}
281281

282282
func (p demoInfoProvider) TickRate() float64 {
283+
// TODO: read tickRate from CVARs as fallback
283284
return p.parser.header.TickRate()
284285
}
285286

test/cs-demos

Submodule cs-demos updated from fd76b0a to e8d2851

0 commit comments

Comments
 (0)