From 60a307593d8f0d97c6464402bb0f21634456a5f2 Mon Sep 17 00:00:00 2001 From: AkiVer Date: Sat, 30 Dec 2023 12:52:18 +0100 Subject: [PATCH] fix: panic on bot_takeover events --- pkg/demoinfocs/common/common_test.go | 6 +++--- pkg/demoinfocs/common/hostage.go | 2 +- pkg/demoinfocs/common/hostage_test.go | 2 +- pkg/demoinfocs/common/inferno.go | 2 +- pkg/demoinfocs/common/inferno_test.go | 2 +- pkg/demoinfocs/common/player.go | 12 +++++++++--- pkg/demoinfocs/common/player_test.go | 25 ++++++++++++++++++++++++- pkg/demoinfocs/events/events_test.go | 2 +- pkg/demoinfocs/parser.go | 4 ++-- 9 files changed, 43 insertions(+), 14 deletions(-) diff --git a/pkg/demoinfocs/common/common_test.go b/pkg/demoinfocs/common/common_test.go index 5fac082a..c88417fe 100644 --- a/pkg/demoinfocs/common/common_test.go +++ b/pkg/demoinfocs/common/common_test.go @@ -212,7 +212,7 @@ type fakeProp struct { type demoInfoProviderMock struct { tickRate float64 ingameTick int - playersByHandle map[int]*Player + playersByHandle map[uint64]*Player entitiesByHandle map[uint64]st.Entity playerResourceEntity st.Entity equipment *Equipment @@ -235,12 +235,12 @@ func (p demoInfoProviderMock) IngameTick() int { return p.ingameTick } -func (p demoInfoProviderMock) FindPlayerByHandle(handle int) *Player { +func (p demoInfoProviderMock) FindPlayerByHandle(handle uint64) *Player { return p.playersByHandle[handle] } func (p demoInfoProviderMock) FindPlayerByPawnHandle(handle uint64) *Player { - return p.playersByHandle[int(handle)] + return p.playersByHandle[handle] } func (p demoInfoProviderMock) PlayerResourceEntity() st.Entity { diff --git a/pkg/demoinfocs/common/hostage.go b/pkg/demoinfocs/common/hostage.go index 123227ce..9431844b 100644 --- a/pkg/demoinfocs/common/hostage.go +++ b/pkg/demoinfocs/common/hostage.go @@ -57,7 +57,7 @@ func (hostage *Hostage) Leader() *Player { return hostage.demoInfoProvider.FindPlayerByPawnHandle(getUInt64(hostage.Entity, "m_leader")) } - return hostage.demoInfoProvider.FindPlayerByHandle(getInt(hostage.Entity, "m_leader")) + return hostage.demoInfoProvider.FindPlayerByHandle(uint64(getInt(hostage.Entity, "m_leader"))) } // NewHostage creates a hostage. diff --git a/pkg/demoinfocs/common/hostage_test.go b/pkg/demoinfocs/common/hostage_test.go index 9dabe31b..68cf4894 100644 --- a/pkg/demoinfocs/common/hostage_test.go +++ b/pkg/demoinfocs/common/hostage_test.go @@ -12,7 +12,7 @@ func TestHostage_Leader(t *testing.T) { player := new(Player) player.EntityID = 10 provider := demoInfoProviderMock{ - playersByHandle: map[int]*Player{10: player}, + playersByHandle: map[uint64]*Player{10: player}, } hostage := hostageWithProperty("m_leader", st.PropertyValue{IntVal: 10}, provider) diff --git a/pkg/demoinfocs/common/inferno.go b/pkg/demoinfocs/common/inferno.go index 9b627258..4c4a892f 100644 --- a/pkg/demoinfocs/common/inferno.go +++ b/pkg/demoinfocs/common/inferno.go @@ -57,7 +57,7 @@ func (inf *Inferno) Thrower() *Player { return inf.demoInfoProvider.FindPlayerByPawnHandle(handleProp.Handle()) } - return inf.demoInfoProvider.FindPlayerByHandle(handleProp.Int()) + return inf.demoInfoProvider.FindPlayerByHandle(uint64(handleProp.Int())) } // Fires returns all fires (past + present). diff --git a/pkg/demoinfocs/common/inferno_test.go b/pkg/demoinfocs/common/inferno_test.go index 84cbad26..bb6bc88d 100644 --- a/pkg/demoinfocs/common/inferno_test.go +++ b/pkg/demoinfocs/common/inferno_test.go @@ -116,7 +116,7 @@ func TestInferno_Thrower(t *testing.T) { player := new(Player) provider := demoInfoProviderMock{ - playersByHandle: map[int]*Player{1: player}, + playersByHandle: map[uint64]*Player{1: player}, } assert.Equal(t, player, NewInferno(provider, entity, nil).Thrower()) diff --git a/pkg/demoinfocs/common/player.go b/pkg/demoinfocs/common/player.go index c65fb0c1..33f63d31 100644 --- a/pkg/demoinfocs/common/player.go +++ b/pkg/demoinfocs/common/player.go @@ -347,9 +347,15 @@ func (p *Player) ControlledBot() *Player { return nil } - botHandle := p.Entity.Property("m_iControlledBotEntIndex").Value().IntVal + if p.demoInfoProvider.IsSource2() { + controllerHandler := p.Entity.Property("m_hOriginalControllerOfCurrentPawn").Value().S2UInt64() + + return p.demoInfoProvider.FindPlayerByHandle(controllerHandler) + } + + botHandle := p.Entity.Property("m_iControlledBotEntIndex").Value().Int() - return p.demoInfoProvider.FindPlayerByHandle(botHandle) + return p.demoInfoProvider.FindPlayerByHandle(uint64(botHandle)) } // Health returns the player's health points, normally 0-100. @@ -796,7 +802,7 @@ func (p *Player) IsGrabbingHostage() bool { type demoInfoProvider interface { IngameTick() int // current in-game tick, used for IsBlinded() TickRate() float64 // in-game tick rate, used for Player.IsBlinded() - FindPlayerByHandle(handle int) *Player + FindPlayerByHandle(handle uint64) *Player FindPlayerByPawnHandle(handle uint64) *Player PlayerResourceEntity() st.Entity FindWeaponByEntityID(id int) *Equipment diff --git a/pkg/demoinfocs/common/player_test.go b/pkg/demoinfocs/common/player_test.go index 93473760..48c9d77f 100644 --- a/pkg/demoinfocs/common/player_test.go +++ b/pkg/demoinfocs/common/player_test.go @@ -331,7 +331,7 @@ func TestPlayer_ControlledBot(t *testing.T) { IsBot: true, } demoInfoProvider := &demoInfoProviderMock{ - playersByHandle: map[int]*Player{ + playersByHandle: map[uint64]*Player{ 12: dave, }, } @@ -347,6 +347,29 @@ func TestPlayer_ControlledBot(t *testing.T) { assert.Same(t, dave, pl.ControlledBot()) } +func TestPlayer_ControlledBotS2(t *testing.T) { + dave := &Player{ + Name: "Dave", + IsBot: true, + } + demoInfoProvider := &demoInfoProviderMock{ + playersByHandle: map[uint64]*Player{ + 12: dave, + }, + isSource2: true, + } + + pl := playerWithProperty("m_hOriginalControllerOfCurrentPawn", st.PropertyValue{Any: uint64(0)}) + pl.demoInfoProvider = demoInfoProvider + + assert.Nil(t, pl.ControlledBot()) + + pl = playerWithProperty("m_hOriginalControllerOfCurrentPawn", st.PropertyValue{Any: uint64(12)}) + pl.demoInfoProvider = demoInfoProvider + + assert.Same(t, dave, pl.ControlledBot()) +} + /* TODO: fix for CS2 func TestPlayer_Armor(t *testing.T) { diff --git a/pkg/demoinfocs/events/events_test.go b/pkg/demoinfocs/events/events_test.go index a5552067..13dc4001 100644 --- a/pkg/demoinfocs/events/events_test.go +++ b/pkg/demoinfocs/events/events_test.go @@ -75,7 +75,7 @@ func (p demoInfoProviderMock) TickRate() float64 { return 128 } -func (p demoInfoProviderMock) FindPlayerByHandle(int) *common.Player { +func (p demoInfoProviderMock) FindPlayerByHandle(uint64) *common.Player { return nil } diff --git a/pkg/demoinfocs/parser.go b/pkg/demoinfocs/parser.go index 7f545dd5..94f79c38 100644 --- a/pkg/demoinfocs/parser.go +++ b/pkg/demoinfocs/parser.go @@ -447,8 +447,8 @@ func (p demoInfoProvider) TickRate() float64 { return p.parser.TickRate() } -func (p demoInfoProvider) FindPlayerByHandle(handle int) *common.Player { - return p.parser.gameState.Participants().FindByHandle(handle) +func (p demoInfoProvider) FindPlayerByHandle(handle uint64) *common.Player { + return p.parser.gameState.Participants().FindByHandle64(handle) } func (p demoInfoProvider) FindPlayerByPawnHandle(handle uint64) *common.Player {