Skip to content

Commit 8f7845c

Browse files
authored
Merge pull request #106 from markus-wa/issue-69-events-players-nil
events: fix nil Player values after disconnect
2 parents 8d9f249 + 703ddf5 commit 8f7845c

File tree

8 files changed

+45
-9
lines changed

8 files changed

+45
-9
lines changed

common/player.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type Player struct {
3434
Team Team
3535
TeamState *TeamState // When keeping the reference make sure you notice when the player changes teams
3636
IsBot bool
37+
IsConnected bool
3738
IsDucking bool
3839
IsDefusing bool
3940
HasDefuseKit bool

datatables.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ func (p *Parser) bindNewPlayer(playerEntity st.IEntity) {
204204
pl.EntityID = entityID
205205
pl.Entity = playerEntity
206206
pl.AdditionalPlayerInformation = &p.additionalPlayerInfo[entityID]
207+
pl.IsConnected = true
207208

208209
playerEntity.OnDestroy(func() {
209210
delete(p.gameState.playersByEntityID, entityID)

datatables_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func TestParser_BindNewPlayer_Issue98(t *testing.T) {
4242
player := fakePlayerEntity(2)
4343
p.bindNewPlayer(player)
4444

45-
assert.Len(t, p.GameState().Participants().All(), 1)
45+
assert.Len(t, p.GameState().Participants().Connected(), 1)
4646
}
4747

4848
func TestParser_BindNewPlayer_Issue98_Reconnect(t *testing.T) {

fake/participants.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ func (ptcp *Participants) All() []*common.Player {
2626
return ptcp.Called().Get(0).([]*common.Player)
2727
}
2828

29+
// Connected is a mock-implementation of IParticipants.Connected().
30+
func (ptcp *Participants) Connected() []*common.Player {
31+
return ptcp.Called().Get(0).([]*common.Player)
32+
}
33+
2934
// Playing is a mock-implementation of IParticipants.Playing().
3035
func (ptcp *Participants) Playing() []*common.Player {
3136
return ptcp.Called().Get(0).([]*common.Player)

game_events.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,9 +374,9 @@ func (geh gameEventHandler) playerDisconnect(desc *msg.CSVCMsg_GameEventListDesc
374374
geh.dispatch(events.PlayerDisconnected{
375375
Player: pl,
376376
})
377-
}
378377

379-
delete(geh.gameState().playersByUserID, uid)
378+
geh.playerByUserID(uid).IsConnected = false
379+
}
380380
}
381381

382382
func (geh gameEventHandler) playerTeam(desc *msg.CSVCMsg_GameEventListDescriptorT, ge *msg.CSVCMsg_GameEvent) {

game_state.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ func (ptcp Participants) ByUserID() map[int]*common.Player {
150150
for k, v := range ptcp.playersByUserID {
151151
// We need to check if the player entity hasn't been destroyed yet
152152
// See https://github.com/markus-wa/demoinfocs-golang/issues/98
153-
if v.Entity != nil {
153+
if v.IsConnected && v.Entity != nil {
154154
res[k] = v
155155
}
156156
}
@@ -168,9 +168,19 @@ func (ptcp Participants) ByEntityID() map[int]*common.Player {
168168
return res
169169
}
170170

171-
// All returns all currently connected players & spectators.
171+
// All returns all currently known players & spectators, including disconnected ones, of the demo.
172172
// The returned slice is a snapshot and is not updated on changes.
173173
func (ptcp Participants) All() []*common.Player {
174+
res := make([]*common.Player, 0, len(ptcp.playersByUserID))
175+
for _, p := range ptcp.playersByUserID {
176+
res = append(res, p)
177+
}
178+
return res
179+
}
180+
181+
// Connected returns all currently connected players & spectators.
182+
// The returned slice is a snapshot and is not updated on changes.
183+
func (ptcp Participants) Connected() []*common.Player {
174184
res, original := ptcp.initalizeSliceFromByUserID()
175185
for _, p := range original {
176186
res = append(res, p)

game_state_test.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,19 +134,35 @@ func TestParticipants_FindByHandle_InvalidEntityHandle(t *testing.T) {
134134
assert.Nil(t, found)
135135
}
136136

137-
func TestParticipants_SuppressNoEntity(t *testing.T) {
137+
func TestParticipants_Connected_SuppressNoEntity(t *testing.T) {
138138
gs := newGameState()
139139
pl := newPlayer()
140140
gs.playersByUserID[0] = pl
141-
gs.playersByUserID[1] = common.NewPlayer(0, func() int { return 0 })
141+
pl2 := common.NewPlayer(0, func() int { return 0 })
142+
pl2.IsConnected = true
143+
gs.playersByUserID[1] = pl2
142144

143-
allPlayers := gs.Participants().All()
145+
allPlayers := gs.Participants().Connected()
146+
147+
assert.ElementsMatch(t, []*common.Player{pl}, allPlayers)
148+
}
149+
150+
func TestParticipants_Connected_SuppressNotConnected(t *testing.T) {
151+
gs := newGameState()
152+
pl := newPlayer()
153+
gs.playersByUserID[0] = pl
154+
pl2 := newPlayer()
155+
pl2.IsConnected = false
156+
gs.playersByUserID[1] = pl2
157+
158+
allPlayers := gs.Participants().Connected()
144159

145160
assert.ElementsMatch(t, []*common.Player{pl}, allPlayers)
146161
}
147162

148163
func newPlayer() *common.Player {
149164
pl := common.NewPlayer(0, func() int { return 0 })
150165
pl.Entity = new(st.Entity)
166+
pl.IsConnected = true
151167
return pl
152168
}

participants_interface.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@ type IParticipants interface {
2020
// The returned map is a snapshot and is not updated on changes (not a reference to the actual, underlying map).
2121
// Includes spectators.
2222
ByEntityID() map[int]*common.Player
23-
// All returns all currently connected players & spectators.
23+
// All returns all currently known players & spectators, including disconnected ones, of the demo.
2424
// The returned slice is a snapshot and is not updated on changes.
2525
All() []*common.Player
26+
// Connected returns all currently connected players & spectators.
27+
// The returned slice is a snapshot and is not updated on changes.
28+
Connected() []*common.Player
2629
// Playing returns all players that aren't spectating or unassigned.
2730
// The returned slice is a snapshot and is not updated on changes.
2831
Playing() []*common.Player

0 commit comments

Comments
 (0)