Skip to content

[ALL] Player thinks break if executed before any player command is run #1179

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Fraeven
Copy link

@Fraeven Fraeven commented Apr 2, 2025

Description

If the server attempts to run frame-based think functions on a player before they have received a command, the think functions will break.

Why

Working backwards here:

  1. When the player's think function is run, gpGlobals->curtime is 0 which results in the next execution never occurring. Ex. think function in tf_player.cpp
  2. gpGlobals->curtime is 0 here because player_command.cpp: CPlayerMove::RunCommand sets gpGlobals->curtime based on the player's m_nTicks value, which was 0.
  3. m_nTicks is set to 0 because it itself is only set in a few places. It normally appears to be set after a player joins the server by player.cpp: RunNullCommand. (SetTimeBase sets m_nTicks).
  4. RunNullCommand is run based on the cvar sv_player_usercommand_timeout which has a default value of 3. In some mods or if this value is set to be higher than 3, RunNullCommand may not be run before the server attempts to run the player's think functions, ultimately causing them to stop.

Replication

Note, this does not appear to be easily replicable in live TF2, but can be reproduced reliably in Frog Fortress 2 by increasing the sv_player_usercommand_timeout cvar and in Open Fortress without needing to do so (where the issue was discovered after updating to the latest SDK).

Replication Steps

  1. Set the following cvars in listenserver.cfg:
sv_cheats 1
sv_player_usercommand_timeout 15
  1. Run Frog Fortress 2 and start a listen server.
  2. After connecting, join a team then execute kill in console.
  3. The player will be in a stuck state and unable to respawn normally due to TFPlayerThink no longer being run.

Video examples

Normal (sv_player_usercommand_timeout = 3)
https://youtu.be/POhGMmfN128

Replicated (sv_player_usercommand_timeout = 10)
https://youtu.be/LBzJElDipgQ

The Fix

There are probably several different ways to fix this, but the simplest fix I came up with was to simply set m_nTicks with SetTimeBase when the player is created.

If there would be any other preferred method of doing so I'm happy to adapt.

Bitl added a commit to FIREFIGHT-RELOADED/FIREFIGHT-RELOADED-src-sdk-2013 that referenced this pull request Apr 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant