This commit is contained in:
JSaurusRex 2024-09-05 20:31:41 +03:00 committed by GitHub
commit 5b2c089155
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 68 additions and 19 deletions

View file

@ -1019,11 +1019,11 @@ void CClient::Render()
GameClient()->OnRender();
DebugRender();
if(State() == IClient::STATE_ONLINE && g_Config.m_ClAntiPingLimit)
{
int64_t Now = time_get();
g_Config.m_ClAntiPing = (m_PredictedTime.Get(Now) - m_aGameTime[g_Config.m_ClDummy].Get(Now)) * 1000 / (float)time_freq() > g_Config.m_ClAntiPingLimit;
}
// if(State() == IClient::STATE_ONLINE && g_Config.m_ClAntiPingLimit)
// {
// int64_t Now = time_get();
// g_Config.m_ClAntiPing = (m_PredictedTime.Get(Now) - m_aGameTime[g_Config.m_ClDummy].Get(Now)) * 1000 / (float)time_freq() > g_Config.m_ClAntiPingLimit;
// }
}
const char *CClient::LoadMap(const char *pName, const char *pFilename, SHA256_DIGEST *pWantedSha256, unsigned WantedCrc)

View file

@ -13,7 +13,8 @@
// client
MACRO_CONFIG_INT(ClPredict, cl_predict, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Predict client movements")
MACRO_CONFIG_INT(ClPredictDummy, cl_predict_dummy, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Predict dummy movements")
MACRO_CONFIG_INT(ClAntiPingLimit, cl_antiping_limit, 0, 0, 200, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Antiping limit (0 to disable)")
MACRO_CONFIG_INT(ClAntiPingLimit, cl_antiping_limit, 0, 0, 200, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Adds delay to antiping (0 to disable)")
MACRO_CONFIG_INT(ClAntiPingpercent, cl_antiping_percent, 100, 0, 100, CFGFLAG_CLIENT | CFGFLAG_SAVE, "how far ahead Antiping predicts, ignored when antiping limit is used")
MACRO_CONFIG_INT(ClAntiPing, cl_antiping, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Enable antiping, i. e. more aggressive prediction.")
MACRO_CONFIG_INT(ClAntiPingPlayers, cl_antiping_players, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Predict other player's movement more aggressively (only enabled if cl_antiping is set to 1)")
MACRO_CONFIG_INT(ClAntiPingGrenade, cl_antiping_grenade, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Predict grenades (only enabled if cl_antiping is set to 1)")

View file

@ -58,9 +58,11 @@ void CItems::RenderProjectile(const CProjectileData *pCurrent, int ItemId)
bool IsOtherTeam = (pCurrent->m_ExtraInfo && pCurrent->m_Owner >= 0 && m_pClient->IsOtherTeam(pCurrent->m_Owner));
int predictTick = GameClient()->GetPredictionTick();
float Ct;
if(m_pClient->Predict() && m_pClient->AntiPingGrenade() && LocalPlayerInGame && !IsOtherTeam)
Ct = ((float)(Client()->PredGameTick(g_Config.m_ClDummy) - 1 - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (float)Client()->GameTickSpeed();
Ct = ((float)(predictTick - 1 - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (float)Client()->GameTickSpeed();
else
Ct = (Client()->PrevGameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) / (float)Client()->GameTickSpeed() + s_LastGameTickTime;
if(Ct < 0)
@ -304,9 +306,11 @@ void CItems::RenderLaser(const CLaserData *pCurrent, bool IsPredicted)
{
Dir = normalize_pre_length(Pos - From, Len);
int predictTick = GameClient()->GetPredictionTick();
float Ticks;
if(IsPredicted)
Ticks = (float)(Client()->PredGameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy);
Ticks = (float)(predictTick - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy);
else
Ticks = (float)(Client()->GameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) + Client()->IntraGameTick(g_Config.m_ClDummy);
float Ms = (Ticks / Client()->GameTickSpeed()) * 1000.0f;
@ -377,7 +381,7 @@ void CItems::OnRender()
auto &aSwitchers = GameClient()->Switchers();
if(UsePredicted)
{
for(auto *pProj = (CProjectile *)GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PROJECTILE); pProj; pProj = (CProjectile *)pProj->NextEntity())
for(auto *pProj = (CProjectile *)GameClient()->m_PrevPredictedWorld.FindFirst(CGameWorld::ENTTYPE_PROJECTILE); pProj; pProj = (CProjectile *)pProj->NextEntity())
{
if(!IsSuper && pProj->m_Number > 0 && pProj->m_Number < (int)aSwitchers.size() && !aSwitchers[pProj->m_Number].m_aStatus[SwitcherTeam] && (pProj->m_Explosive ? BlinkingProjEx : BlinkingProj))
continue;
@ -385,7 +389,7 @@ void CItems::OnRender()
CProjectileData Data = pProj->GetData();
RenderProjectile(&Data, pProj->GetId());
}
for(CEntity *pEnt = GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_LASER); pEnt; pEnt = pEnt->NextEntity())
for(CEntity *pEnt = GameClient()->m_PrevPredictedWorld.FindFirst(CGameWorld::ENTTYPE_LASER); pEnt; pEnt = pEnt->NextEntity())
{
auto *const pLaser = dynamic_cast<CLaser *>(pEnt);
if(!pLaser || pLaser->GetOwner() < 0 || !GameClient()->m_aClients[pLaser->GetOwner()].m_IsPredictedLocal)
@ -393,7 +397,7 @@ void CItems::OnRender()
CLaserData Data = pLaser->GetData();
RenderLaser(&Data, true);
}
for(auto *pPickup = (CPickup *)GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PICKUP); pPickup; pPickup = (CPickup *)pPickup->NextEntity())
for(auto *pPickup = (CPickup *)GameClient()->m_PrevPredictedWorld.FindFirst(CGameWorld::ENTTYPE_PICKUP); pPickup; pPickup = (CPickup *)pPickup->NextEntity())
{
if(!IsSuper && pPickup->m_Layer == LAYER_SWITCH && pPickup->m_Number > 0 && pPickup->m_Number < (int)aSwitchers.size() && !aSwitchers[pPickup->m_Number].m_aStatus[SwitcherTeam] && BlinkingPickup)
continue;
@ -601,7 +605,10 @@ void CItems::ReconstructSmokeTrail(const CProjectileData *pCurrent, int DestroyT
LocalPlayerInGame = m_pClient->m_aClients[m_pClient->m_Snap.m_pLocalInfo->m_ClientId].m_Team != TEAM_SPECTATORS;
if(!m_pClient->AntiPingGunfire() || !LocalPlayerInGame)
return;
if(Client()->PredGameTick(g_Config.m_ClDummy) == pCurrent->m_StartTick)
int predictTick = GameClient()->GetPredictionTick();
if(predictTick == pCurrent->m_StartTick)
return;
// get positions
@ -625,7 +632,7 @@ void CItems::ReconstructSmokeTrail(const CProjectileData *pCurrent, int DestroyT
Speed = pTuning->m_GunSpeed;
}
float Pt = ((float)(Client()->PredGameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (float)Client()->GameTickSpeed();
float Pt = ((float)(predictTick - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (float)Client()->GameTickSpeed();
if(Pt < 0)
return; // projectile haven't been shot yet

View file

@ -2100,6 +2100,25 @@ void CGameClient::UpdateEditorIngameMoved()
}
}
int CGameClient::GetPredictionTick()
{
int predictTick = Client()->GetPredictionTime() * Client()->GameTickSpeed() / 1000.0f;
float predictPercentage = 1 - g_Config.m_ClAntiPingpercent / 100.0f;
int predictMin = std::floor(predictTick * predictPercentage);
int predictMin2 = g_Config.m_ClAntiPingLimit * Client()->GameTickSpeed() / 1000.0f;
if (g_Config.m_ClAntiPingLimit != 0)
predictMin = predictMin2;
predictTick = Client()->PredGameTick(g_Config.m_ClDummy) - predictMin;
if(predictTick < Client()->GameTick(g_Config.m_ClDummy) + 1)
{
predictTick = Client()->GameTick(g_Config.m_ClDummy) + 1;
}
return predictTick;
}
void CGameClient::OnPredict()
{
// store the previous values so we can detect prediction errors
@ -2156,20 +2175,33 @@ void CGameClient::OnPredict()
CCharacter *pDummyChar = 0;
if(PredictDummy())
pDummyChar = m_PredictedWorld.GetCharacterById(m_PredictedDummyId);
int predictTick = GetPredictionTick();
// predict
for(int Tick = Client()->GameTick(g_Config.m_ClDummy) + 1; Tick <= Client()->PredGameTick(g_Config.m_ClDummy); Tick++)
{
// fetch the previous characters
if(Tick == Client()->PredGameTick(g_Config.m_ClDummy))
if(Tick == predictTick)
{
m_PrevPredictedWorld.CopyWorld(&m_PredictedWorld);
m_PredictedPrevChar = pLocalChar->GetCore();
for(int i = 0; i < MAX_CLIENTS; i++)
if(CCharacter *pChar = m_PredictedWorld.GetCharacterById(i))
m_aClients[i].m_PrevPredicted = pChar->GetCore();
}
if(Tick == Client()->PredGameTick(g_Config.m_ClDummy))
{
m_PredictedPrevChar = pLocalChar->GetCore();
m_aClients[m_Snap.m_LocalClientId].m_PrevPredicted = pLocalChar->GetCore();
if(pDummyChar)
m_aClients[m_PredictedDummyId].m_PrevPredicted = pDummyChar->GetCore();
}
if(Tick == predictTick)
{
m_PrevPredictedWorld.CopyWorld(&m_PredictedWorld);
}
// optionally allow some movement in freeze by not predicting freeze the last one to two ticks
if(g_Config.m_ClPredictFreeze == 2 && Client()->PredGameTick(g_Config.m_ClDummy) - 1 - Client()->PredGameTick(g_Config.m_ClDummy) % 2 <= Tick)
pLocalChar->m_CanMoveInFreeze = true;
@ -2193,14 +2225,22 @@ void CGameClient::OnPredict()
m_PredictedWorld.Tick();
// fetch the current characters
if(Tick == Client()->PredGameTick(g_Config.m_ClDummy))
if(Tick == predictTick)
{
m_PredictedChar = pLocalChar->GetCore();
for(int i = 0; i < MAX_CLIENTS; i++)
if(CCharacter *pChar = m_PredictedWorld.GetCharacterById(i))
m_aClients[i].m_Predicted = pChar->GetCore();
}
if(Tick == Client()->PredGameTick(g_Config.m_ClDummy))
{
m_PredictedChar = pLocalChar->GetCore();
m_aClients[m_Snap.m_LocalClientId].m_Predicted = pLocalChar->GetCore();
if(pDummyChar)
m_aClients[m_PredictedDummyId].m_Predicted = pDummyChar->GetCore();
}
for(int i = 0; i < MAX_CLIENTS; i++)
if(CCharacter *pChar = m_PredictedWorld.GetCharacterById(i))
{

View file

@ -499,6 +499,7 @@ public:
CRenderTools m_RenderTools;
void OnReset();
int GetPredictionTick();
size_t ComponentCount() { return m_vpAll.size(); }