From e2dbba3146c4b6d08785e7038c5db2a78ed03044 Mon Sep 17 00:00:00 2001 From: trml Date: Mon, 25 Oct 2021 02:34:28 +0200 Subject: [PATCH] Network clipping for entityex in CPickup and CProjectile, snap gamecontroller before gameworld, bound checks for switchers in client --- src/game/client/components/items.cpp | 6 +++--- src/game/client/prediction/entities/pickup.cpp | 2 +- .../client/prediction/entities/projectile.cpp | 2 +- src/game/server/entities/pickup.cpp | 15 +++++++++------ src/game/server/entities/projectile.cpp | 6 +++--- src/game/server/gamecontext.cpp | 3 ++- 6 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/game/client/components/items.cpp b/src/game/client/components/items.cpp index 089186c65..1e2801187 100644 --- a/src/game/client/components/items.cpp +++ b/src/game/client/components/items.cpp @@ -318,7 +318,7 @@ void CItems::OnRender() { for(auto *pProj = (CProjectile *)GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PROJECTILE); pProj; pProj = (CProjectile *)pProj->NextEntity()) { - if(!IsSuper && pProj->m_Number > 0 && !Collision()->m_pSwitchers[pProj->m_Number].m_Status[OwnTeam] && (pProj->m_Explosive ? BlinkingProjEx : BlinkingProj)) + if(!IsSuper && pProj->m_Number > 0 && pProj->m_Number < Collision()->m_NumSwitchers && !Collision()->m_pSwitchers[pProj->m_Number].m_Status[OwnTeam] && (pProj->m_Explosive ? BlinkingProjEx : BlinkingProj)) continue; CProjectileData Data = pProj->GetData(); @@ -334,7 +334,7 @@ void CItems::OnRender() } for(auto *pPickup = (CPickup *)GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PICKUP); pPickup; pPickup = (CPickup *)pPickup->NextEntity()) { - if(!IsSuper && pPickup->m_Layer == LAYER_SWITCH && pPickup->m_Number > 0 && !Collision()->m_pSwitchers[pPickup->m_Number].m_Status[OwnTeam] && BlinkingPickup) + if(!IsSuper && pPickup->m_Layer == LAYER_SWITCH && pPickup->m_Number > 0 && pPickup->m_Number < Collision()->m_NumSwitchers && !Collision()->m_pSwitchers[pPickup->m_Number].m_Status[OwnTeam] && BlinkingPickup) continue; if(pPickup->InDDNetTile()) @@ -358,7 +358,7 @@ void CItems::OnRender() bool Inactive = false; if(pEntEx) - Inactive = !IsSuper && pEntEx->m_SwitchNumber > 0 && !Collision()->m_pSwitchers[pEntEx->m_SwitchNumber].m_Status[OwnTeam]; + Inactive = !IsSuper && pEntEx->m_SwitchNumber > 0 && pEntEx->m_SwitchNumber < Collision()->m_NumSwitchers && !Collision()->m_pSwitchers[pEntEx->m_SwitchNumber].m_Status[OwnTeam]; if(Item.m_Type == NETOBJTYPE_PROJECTILE || Item.m_Type == NETOBJTYPE_DDNETPROJECTILE) { diff --git a/src/game/client/prediction/entities/pickup.cpp b/src/game/client/prediction/entities/pickup.cpp index 4b2e7c0c0..9697dae3b 100644 --- a/src/game/client/prediction/entities/pickup.cpp +++ b/src/game/client/prediction/entities/pickup.cpp @@ -17,7 +17,7 @@ void CPickup::Tick() { if(GameWorld()->m_WorldConfig.m_IsVanilla && distance(m_Pos, pChr->m_Pos) >= 20.0f * 2) // pickup distance is shorter on vanilla due to using ClosestEntity continue; - if(m_Layer == LAYER_SWITCH && m_Number > 0 && !GameWorld()->Collision()->m_pSwitchers[m_Number].m_Status[pChr->Team()]) + if(m_Layer == LAYER_SWITCH && m_Number > 0 && m_Number < Collision()->m_NumSwitchers && !GameWorld()->Collision()->m_pSwitchers[m_Number].m_Status[pChr->Team()]) continue; bool sound = false; // player picked us up, is someone was hooking us, let them go diff --git a/src/game/client/prediction/entities/projectile.cpp b/src/game/client/prediction/entities/projectile.cpp index 38ce4d216..af8ce92fc 100644 --- a/src/game/client/prediction/entities/projectile.cpp +++ b/src/game/client/prediction/entities/projectile.cpp @@ -110,7 +110,7 @@ void CProjectile::Tick() CCharacter *apEnts[MAX_CLIENTS]; int Num = GameWorld()->FindEntities(CurPos, 1.0f, (CEntity **)apEnts, MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER); for(int i = 0; i < Num; ++i) - if(apEnts[i] && (m_Layer != LAYER_SWITCH || (m_Layer == LAYER_SWITCH && m_Number > 0 && GameWorld()->Collision()->m_pSwitchers[m_Number].m_Status[apEnts[i]->Team()]))) + if(apEnts[i] && (m_Layer != LAYER_SWITCH || (m_Layer == LAYER_SWITCH && m_Number > 0 && m_Number < Collision()->m_NumSwitchers && GameWorld()->Collision()->m_pSwitchers[m_Number].m_Status[apEnts[i]->Team()]))) apEnts[i]->Freeze(); } if(Collide && m_Bouncing != 0) diff --git a/src/game/server/entities/pickup.cpp b/src/game/server/entities/pickup.cpp index 6017ddd13..40a92594f 100644 --- a/src/game/server/entities/pickup.cpp +++ b/src/game/server/entities/pickup.cpp @@ -160,13 +160,16 @@ void CPickup::Snap(int SnappingClient) if(SnappingClient > -1 && (GameServer()->m_apPlayers[SnappingClient]->GetTeam() == -1 || GameServer()->m_apPlayers[SnappingClient]->IsPaused()) && GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID != SPEC_FREEVIEW) Char = GameServer()->GetPlayerChar(GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID); - CNetObj_EntityEx *pEntData = static_cast(Server()->SnapNewItem(NETOBJTYPE_ENTITYEX, GetID(), sizeof(CNetObj_EntityEx))); - if(!pEntData) - return; + if(!NetworkClipped(SnappingClient)) + { + CNetObj_EntityEx *pEntData = static_cast(Server()->SnapNewItem(NETOBJTYPE_ENTITYEX, GetID(), sizeof(CNetObj_EntityEx))); + if(!pEntData) + return; - pEntData->m_SwitchNumber = m_Number; - pEntData->m_Layer = m_Layer; - pEntData->m_EntityClass = ENTITYCLASS_PICKUP; + pEntData->m_SwitchNumber = m_Number; + pEntData->m_Layer = m_Layer; + pEntData->m_EntityClass = ENTITYCLASS_PICKUP; + } int SnappingClientVersion = SnappingClient >= 0 ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR; if(SnappingClientVersion < VERSION_DDNET_SWITCH) diff --git a/src/game/server/entities/projectile.cpp b/src/game/server/entities/projectile.cpp index 09cf1835a..bd6e5c6fe 100644 --- a/src/game/server/entities/projectile.cpp +++ b/src/game/server/entities/projectile.cpp @@ -300,6 +300,9 @@ void CProjectile::Snap(int SnappingClient) { float Ct = (Server()->Tick() - m_StartTick) / (float)Server()->TickSpeed(); + if(NetworkClipped(SnappingClient, GetPos(Ct))) + return; + if(m_LifeSpan == -2) { CNetObj_EntityEx *pEntData = static_cast(Server()->SnapNewItem(NETOBJTYPE_ENTITYEX, GetID(), sizeof(CNetObj_EntityEx))); @@ -311,9 +314,6 @@ void CProjectile::Snap(int SnappingClient) pEntData->m_EntityClass = ENTITYCLASS_PROJECTILE; } - if(NetworkClipped(SnappingClient, GetPos(Ct))) - return; - int SnappingClientVersion = SnappingClient >= 0 ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR; if(SnappingClientVersion < VERSION_DDNET_SWITCH) { diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index a7e524620..86da5ec26 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -3617,6 +3617,8 @@ void CGameContext::OnSnap(int ClientID) Server()->SendMsg(&Msg, MSGFLAG_RECORD | MSGFLAG_NOSEND, ClientID); } + m_pController->Snap(ClientID); + for(auto &pPlayer : m_apPlayers) { if(pPlayer) @@ -3627,7 +3629,6 @@ void CGameContext::OnSnap(int ClientID) m_apPlayers[ClientID]->FakeSnap(); m_World.Snap(ClientID); - m_pController->Snap(ClientID); m_Events.Snap(ClientID); } void CGameContext::OnPreSnap() {}