Bypass cl_movespeedkey restrictions via negative values
Players can set untrusted forwardmove/sidemove/upmove speed values by using negative cl_movespeedkey values.
The game client has limitations related to cl_movespeedkey. Let's look at the code:
void __cdecl CL_CreateMove(float frametime, usercmd_s *cmd, int active)
{
...
// this means that client speeds will not exceed the maximum speed with the current weapon, regardless of cl_forwardspeed / cl_backspeed / cl_sidespeed / cl_upspeed
v51 = gEngfuncs.GetClientMaxspeed();
if ( v51 != 0.0 )
{
v70 = sqrt(cmd->forwardmove * cmd->forwardmove + cmd->sidemove * cmd->sidemove + cmd->upmove * cmd->upmove);
if ( v70 > v51 )
{
v71 = v51 / v70;
cmd->forwardmove = cmd->forwardmove * v71;
cmd->sidemove = cmd->sidemove * v71;
cmd->upmove = v71 * cmd->upmove;
}
}
// condition for the executed +speed command
if ( in_speed.state & 1 )
{
v52 = cl_movespeedkey->value;
if ( v52 > 0.51999998 ) // this check only for positive values, not negative ones
v52 = 0.51999998;
cmd->forwardmove = cmd->forwardmove * v52;
cmd->sidemove = cmd->sidemove * v52;
cmd->upmove = v52 * cmd->upmove;
}
...
Thus, the player can execute cl_movespeedkey -1;+speed in the console and his speed values will be equal to the maximum allowed speed of the weapon, for example 250 for a knife or usp in CS 1.6. If the player executes cl_movespeedkey -2, then the speeds will increase twice from the maximum allowed, i.e. they will become 500 instead of 250, and so on.
Untrusted speed values are used in hacks for air strafes to increase the speed and range of jumps. The player can use them, for example, to boost the speed of circle jumps with +strafe. Video (10aa):
https://www.youtube.com/watch?v=S81jv6vDwOI
To fix this bug, I think a check for negative values needs to be added to the client code:
v52 = cl_movespeedkey->value;
if ( v52 > 0.51999998 ) // check for positive values
v52 = 0.51999998;
if ( v52 < 0 ) // check for negative values
v52 = 0;
cmd->forwardmove = cmd->forwardmove * v52;
cmd->sidemove = cmd->sidemove * v52;
cmd->upmove = v52 * cmd->upmove;