Added interpolated_shoot_position

While the old fix was working, it was a bit too much noticeable while
surfing, this is an issue we don't want.
We need a proper check for cheaters too.
This commit is contained in:
Kamay Xutax 2024-08-27 22:44:41 +02:00
parent 273ac76745
commit 22cfdaabc9
4 changed files with 75 additions and 31 deletions

View file

@ -3145,33 +3145,42 @@ void _Host_RunFrame (float time)
#ifndef SWDS #ifndef SWDS
const auto CalcInterpolationAmount = [&]() const auto CalcInterpolationAmount = [&]()
{ {
// TODO_ENHANCED: // TODO_ENHANCED:
// Notice_Enhanced: // This check permits to fix interpolation problems on the
// This check permits to fix interpolation problems on the // local player that valve has been (fucking finally)
// local player that valve has been (fucking finally) // caring about on counter-strike 2.
// caring about on counter-strike 2. //
// // To recall the original issue, the
// To recall the original issue, the // problem that Valve cared about is that interpolation
// problem that Valve cared about is that interpolation // had some problems with interpolating the local
// had some problems with interpolating the local // player because the screen would never in the first
// player because the screen would never in the first // place match the tick "screen", because interpolation
// place match the tick "screen", because interpolation // amount could never reach 0.0 or 1.0
// amount could never reach 0.0 or 1.0 //
// // Valve solution was to introduce bugs with lag
// Valve solution was to introduce bugs with lag // compensating the local player and made the game worse,
// compensating the local player and made the game worse, // introducing a new way for cheaters to cheat even more
// introducing a new way for cheaters to cheat even more // on their games.
// on their games. // I'm joking, but you can clearly see the outcome anyway.
// I'm joking, but you can clearly see the outcome anyway. //
// // My solution is to simply set interpolation amount
// My solution is to simply set interpolation amount // to 0.0 when a tick arrives.
// to 0.0 when a tick arrives. //
// // So when we shoot, we get the frame we shot with an
// So when we shoot, we get the frame we shot with an // interpolation amount at 0.0, perfectly aligned to user
// interpolation amount at 0.0, perfectly aligned to user // commands which is ideal for us.
// commands which is ideal for us. //
// // README_ENHANCED:
// Now includes smoothing. // Unfortunately, some players still notice it with low enough fps.
// This is a problem; we return then to lag compensating the local player.
// Two choices here:
//
// 1) For precision we might need to send camera position, that is proven to work.
// 2) Send interpolation_amount so we calculate it server and in runcommand.
//
// Both works, but the first one requires validation,
// the second doesn't at the expense of some unprecisions due to floats.
// The first one is the easier route to avoid issues.
static ConVar cl_interpolation_amount_fix("cl_interpolation_amount_fix", "0", FCVAR_HIDDEN); static ConVar cl_interpolation_amount_fix("cl_interpolation_amount_fix", "0", FCVAR_HIDDEN);

View file

@ -1330,6 +1330,17 @@ void CInput::CreateMove ( int sequence_number, float input_sample_frametime, boo
} }
#endif #endif
C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer();
if (pPlayer)
{
cmd->interpolated_shoot_position = pPlayer->Weapon_ShootPosition();
}
else
{
cmd->interpolated_shoot_position.Init();
}
pVerified->m_cmd = *cmd; pVerified->m_cmd = *cmd;
pVerified->m_crc = cmd->GetChecksum(); pVerified->m_crc = cmd->GetChecksum();
} }

View file

@ -119,6 +119,9 @@ void FX_FireBullets(
float flSoundTime float flSoundTime
) )
{ {
// Fallback if failed to find the interpolated shoot position.
Vector vHookedOrigin = vOrigin;
if (weapon_accuracy_noinaccuracy.GetBool()) if (weapon_accuracy_noinaccuracy.GetBool())
{ {
fInaccuracy = 0.0f; fInaccuracy = 0.0f;
@ -132,6 +135,19 @@ void FX_FireBullets(
CCSPlayer *pPlayer = ToCSPlayer( UTIL_PlayerByIndex( iPlayerIndex) ); CCSPlayer *pPlayer = ToCSPlayer( UTIL_PlayerByIndex( iPlayerIndex) );
#endif #endif
// TODO_ENHANCED:
// Check if interpolated_shoot_position is within interpolation bounds! (between old shoot pos and new)
// This is to check for cheaters abusing the shooting position.
if (pPlayer)
{
#ifdef CLIENT_DLL
if (pPlayer->m_pCurrentCommand) { vHookedOrigin = pPlayer->m_pCurrentCommand->interpolated_shoot_position; }
#else
if (pPlayer->GetCurrentCommand()) { vHookedOrigin = pPlayer->GetCurrentCommand()->interpolated_shoot_position; }
#endif
}
const char * weaponAlias = WeaponIDToAlias( iWeaponID ); const char * weaponAlias = WeaponIDToAlias( iWeaponID );
if ( !weaponAlias ) if ( !weaponAlias )
@ -195,7 +211,7 @@ void FX_FireBullets(
// Dispatch one message for all the bullet impacts and sounds. // Dispatch one message for all the bullet impacts and sounds.
TE_FireBullets( TE_FireBullets(
iPlayerIndex, iPlayerIndex,
vOrigin, vHookedOrigin,
vAngles, vAngles,
iWeaponID, iWeaponID,
iMode, iMode,
@ -250,7 +266,7 @@ void FX_FireBullets(
if ( bDoEffects) if ( bDoEffects)
{ {
FX_WeaponSound( iPlayerIndex, sound_type, vOrigin, pWeaponInfo, flSoundTime ); FX_WeaponSound( iPlayerIndex, sound_type, vHookedOrigin, pWeaponInfo, flSoundTime );
} }
@ -301,7 +317,7 @@ void FX_FireBullets(
#endif #endif
pPlayer->FireBullet( pPlayer->FireBullet(
iBullet, iBullet,
vOrigin, vHookedOrigin,
vAngles, vAngles,
flRange, flRange,
iPenetration, iPenetration,

View file

@ -105,6 +105,8 @@ public:
#if defined( HL2_DLL ) || defined( HL2_CLIENT_DLL ) #if defined( HL2_DLL ) || defined( HL2_CLIENT_DLL )
entitygroundcontact.RemoveAll(); entitygroundcontact.RemoveAll();
#endif #endif
interpolated_shoot_position.Init();
} }
CUserCmd& operator =( const CUserCmd& src ) CUserCmd& operator =( const CUserCmd& src )
@ -137,6 +139,7 @@ public:
entitygroundcontact = src.entitygroundcontact; entitygroundcontact = src.entitygroundcontact;
#endif #endif
interpolated_shoot_position = src.interpolated_shoot_position;
return *this; return *this;
} }
@ -165,6 +168,7 @@ public:
CRC32_ProcessBuffer(&crc, &mousedy, sizeof(mousedy)); CRC32_ProcessBuffer(&crc, &mousedy, sizeof(mousedy));
CRC32_ProcessBuffer(&crc, simulationdata, sizeof(simulationdata)); CRC32_ProcessBuffer(&crc, simulationdata, sizeof(simulationdata));
CRC32_ProcessBuffer(&crc, &debug_hitboxes, sizeof(debug_hitboxes)); CRC32_ProcessBuffer(&crc, &debug_hitboxes, sizeof(debug_hitboxes));
CRC32_ProcessBuffer( &crc, &interpolated_shoot_position, sizeof(interpolated_shoot_position));
CRC32_Final( &crc ); CRC32_Final( &crc );
return crc; return crc;
@ -179,7 +183,8 @@ public:
upmove = 0.f; upmove = 0.f;
buttons = 0; buttons = 0;
impulse = 0; impulse = 0;
debug_hitboxes = DEBUG_HITBOXES_OFF; debug_hitboxes = DEBUG_HITBOXES_OFF;
interpolated_shoot_position.Init();
} }
// For matching server and client commands for debugging // For matching server and client commands for debugging
@ -226,6 +231,9 @@ public:
uint8 debug_hitboxes; uint8 debug_hitboxes;
// TODO_ENHANCED: check README_ENHANCED in host.cpp!
Vector interpolated_shoot_position;
// Back channel to communicate IK state // Back channel to communicate IK state
#if defined( HL2_DLL ) || defined( HL2_CLIENT_DLL ) #if defined( HL2_DLL ) || defined( HL2_CLIENT_DLL )
CUtlVector< CEntityGroundContact > entitygroundcontact; CUtlVector< CEntityGroundContact > entitygroundcontact;