Skip to content

Commit

Permalink
remove deprecated Player.Velocity() & Player.PreviousFramePosition du…
Browse files Browse the repository at this point in the history
…e to performance concerns
  • Loading branch information
markus-wa committed Sep 4, 2024
1 parent df0da13 commit ad06761
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 137 deletions.
66 changes: 19 additions & 47 deletions pkg/demoinfocs/common/player.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,23 @@ import (
type Player struct {
demoInfoProvider demoInfoProvider // provider for demo info such as tick-rate or current tick

SteamID64 uint64 // 64-bit representation of the user's Steam ID. See https://developer.valvesoftware.com/wiki/SteamID
LastAlivePosition r3.Vector // Deprecated: will be removed in v5 due to performance concerns, track this yourself.
UserID int // Mostly used in game-events to address this player
Name string // Steam / in-game user name
Inventory map[int]*Equipment // All weapons / equipment the player is currently carrying. See also Weapons().
AmmoLeft [32]int // Ammo left for special weapons (e.g. grenades), index corresponds Equipment.AmmoType
EntityID int // Usually the same as Entity.ID() but may be different between player death and re-spawn.
Entity st.Entity // May be nil between player-death and re-spawn
FlashDuration float32 // Blindness duration from the flashbang currently affecting the player (seconds)
FlashTick int // In-game tick at which the player was last flashed
TeamState *TeamState // When keeping the reference make sure you notice when the player changes teams
Team Team // Team identifier for the player (e.g. TeamTerrorists or TeamCounterTerrorists).
IsBot bool // True if this is a bot-entity. See also IsControllingBot and ControlledBot().
IsConnected bool
IsDefusing bool
IsPlanting bool
IsReloading bool
IsUnknown bool // Used to identify unknown/broken players. see https://github.com/markus-wa/demoinfocs-golang/issues/162
PreviousFramePosition r3.Vector // Deprecated: may be removed in v5 due to performance concerns, track this yourself.
SteamID64 uint64 // 64-bit representation of the user's Steam ID. See https://developer.valvesoftware.com/wiki/SteamID
UserID int // Mostly used in game-events to address this player
Name string // Steam / in-game user name
Inventory map[int]*Equipment // All weapons / equipment the player is currently carrying. See also Weapons().
AmmoLeft [32]int // Ammo left for special weapons (e.g. grenades), index corresponds Equipment.AmmoType
EntityID int // Usually the same as Entity.ID() but may be different between player death and re-spawn.
Entity st.Entity // May be nil between player-death and re-spawn
FlashDuration float32 // Blindness duration from the flashbang currently affecting the player (seconds)
FlashTick int // In-game tick at which the player was last flashed
TeamState *TeamState // When keeping the reference make sure you notice when the player changes teams
Team Team // Team identifier for the player (e.g. TeamTerrorists or TeamCounterTerrorists).
IsBot bool // True if this is a bot-entity. See also IsControllingBot and ControlledBot().
IsConnected bool
IsDefusing bool
IsPlanting bool
IsReloading bool
IsUnknown bool // Used to identify unknown/broken players. see https://github.com/markus-wa/demoinfocs-golang/issues/162
}

func (p *Player) PlayerPawnEntity() st.Entity {
Expand Down Expand Up @@ -536,31 +534,6 @@ func (p *Player) PositionEyes() r3.Vector {
return pos
}

// Velocity returns the player's velocity.
// Deprecated: will be removed due to performance concerns, you will need to track this yourself.
func (p *Player) Velocity() r3.Vector {
if p.demoInfoProvider.IsSource2() {
t := 64.0
diff := p.Position().Sub(p.PreviousFramePosition)

return r3.Vector{
X: diff.X * t,
Y: diff.Y * t,
Z: diff.Z * t,
}
}

if p.Entity == nil {
return r3.Vector{}
}

return r3.Vector{
X: float64(p.Entity.PropertyValueMust("localdata.m_vecVelocity[0]").FloatVal),
Y: float64(p.Entity.PropertyValueMust("localdata.m_vecVelocity[1]").FloatVal),
Z: float64(p.Entity.PropertyValueMust("localdata.m_vecVelocity[2]").FloatVal),
}
}

// see https://github.com/ValveSoftware/source-sdk-2013/blob/master/mp/src/public/const.h#L146-L188
const (
flOnGround = 1 << iota
Expand Down Expand Up @@ -827,9 +800,8 @@ type demoInfoProvider interface {
// Intended for internal use only.
func NewPlayer(demoInfoProvider demoInfoProvider) *Player {
return &Player{
Inventory: make(map[int]*Equipment),
demoInfoProvider: demoInfoProvider,
PreviousFramePosition: r3.Vector{},
Inventory: make(map[int]*Equipment),
demoInfoProvider: demoInfoProvider,
}
}

Expand Down
61 changes: 0 additions & 61 deletions pkg/demoinfocs/common/player_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,67 +438,6 @@ func TestPlayer_PositionEyes_EntityNil(t *testing.T) {
assert.Empty(t, pl.PositionEyes())
}

func TestPlayer_Velocity(t *testing.T) {
entity := new(stfake.Entity)
entity.On("PropertyValueMust", "localdata.m_vecVelocity[0]").Return(st.PropertyValue{FloatVal: 1})
entity.On("PropertyValueMust", "localdata.m_vecVelocity[1]").Return(st.PropertyValue{FloatVal: 2})
entity.On("PropertyValueMust", "localdata.m_vecVelocity[2]").Return(st.PropertyValue{FloatVal: 3})

pl := &Player{Entity: entity}
pl.demoInfoProvider = s1DemoInfoProvider

expected := r3.Vector{X: 1, Y: 2, Z: 3}
assert.Equal(t, expected, pl.Velocity())
}

func createPlayerForVelocityTest() *Player {
controllerEntity := entityWithProperties([]fakeProp{
{propName: "m_hPlayerPawn", value: st.PropertyValue{Any: uint64(1), S2: true}},
{propName: "m_hPawn", value: st.PropertyValue{Any: uint64(1), S2: true}},
})
pawnEntity := new(stfake.Entity)
position := r3.Vector{X: 20, Y: 300, Z: 100}

pawnEntity.On("Position").Return(position)

pl := &Player{
Entity: controllerEntity,
}

demoInfoProvider := demoInfoProviderMock{
isSource2: true,
entitiesByHandle: map[uint64]st.Entity{
1: pawnEntity,
},
}
pl.demoInfoProvider = demoInfoProvider

return pl
}

func TestPlayer_VelocityS2(t *testing.T) {
pl := createPlayerForVelocityTest()
pl.PreviousFramePosition = r3.Vector{X: 10, Y: 200, Z: 50}

expected := r3.Vector{X: 640, Y: 6400, Z: 3200}
assert.Equal(t, expected, pl.Velocity())
}

func TestPlayer_VelocityDidNotChangeS2(t *testing.T) {
pl := createPlayerForVelocityTest()
pl.PreviousFramePosition = r3.Vector{X: 20, Y: 300, Z: 100}

expected := r3.Vector{X: 0, Y: 0, Z: 0}
assert.Equal(t, expected, pl.Velocity())
}

func TestPlayer_Velocity_EntityNil(t *testing.T) {
pl := new(Player)
pl.demoInfoProvider = s1DemoInfoProvider

assert.Empty(t, pl.Velocity())
}

func TestPlayer_ClanTag(t *testing.T) {
pl := playerWithResourceProperty("m_szClan", st.PropertyValue{Any: "SuperClan"})
pl.demoInfoProvider = demoInfoProviderMock{
Expand Down
19 changes: 0 additions & 19 deletions pkg/demoinfocs/datatables.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,13 +478,6 @@ func (p *parser) bindNewPlayerS1(playerEntity st.Entity) {
pl.Entity = nil
})

// Position
playerEntity.OnPositionUpdate(func(pos r3.Vector) {
if pl.IsAlive() {
pl.LastAlivePosition = pos
}
})

// General info
playerEntity.Property("m_iTeamNum").OnUpdate(func(val st.PropertyValue) {
pl.Team = common.Team(val.IntVal)
Expand Down Expand Up @@ -632,18 +625,6 @@ func (p *parser) bindNewPlayerPawnS2(pawnEntity st.Entity) {
p.bindPlayerWeaponsS2(pawnEntity, pl)
})

// Position
pawnEntity.OnPositionUpdate(func(pos r3.Vector) {
pl := getPlayerFromPawnEntity(pawnEntity)
if pl == nil {
return
}

if pl.IsAlive() {
pl.LastAlivePosition = pos
}
})

pawnEntity.Property("m_flFlashDuration").OnUpdate(func(val st.PropertyValue) {
pl := getPlayerFromPawnEntity(pawnEntity)
if pl == nil {
Expand Down
4 changes: 0 additions & 4 deletions pkg/demoinfocs/parsing.go
Original file line number Diff line number Diff line change
Expand Up @@ -537,10 +537,6 @@ func (p *parser) handleFrameParsed(*frameParsedTokenType) {

p.currentFrame++
p.eventDispatcher.Dispatch(events.FrameDone{})

if p.isSource2() {
p.updatePlayersPreviousFramePosition()
}
}

// CS2 demos playback info are available in the CDemoFileInfo message that should be parsed at the end of the demo.
Expand Down
6 changes: 0 additions & 6 deletions pkg/demoinfocs/s2_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,9 +383,3 @@ func (p *parser) handleDemoFileHeader(msg *msgs2.CDemoFileHeader) {
p.header.MapName = msg.GetMapName()
p.header.NetworkProtocol = int(msg.GetNetworkProtocol())
}

func (p *parser) updatePlayersPreviousFramePosition() {
for _, player := range p.GameState().Participants().Playing() {
player.PreviousFramePosition = player.Position()
}
}

0 comments on commit ad06761

Please sign in to comment.