Skip to content

Commit

Permalink
Fix engineSetPoolCapacity conflicts with removeWorldModel (multitheft…
Browse files Browse the repository at this point in the history
…auto#3466)

Fixes crash when engineSetPoolCapacity is used after removeWorldModel
Fixes hiddden memory leak in building removal logic
  • Loading branch information
TheNormalnij authored Jun 16, 2024
1 parent bf9b97d commit 53e03d0
Show file tree
Hide file tree
Showing 14 changed files with 924 additions and 812 deletions.
719 changes: 719 additions & 0 deletions Client/game_sa/CBuildingRemovalSA.cpp

Large diffs are not rendered by default.

45 changes: 45 additions & 0 deletions Client/game_sa/CBuildingRemovalSA.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* LICENSE: See LICENSE in the top level directory
* FILE: game_sa/CBuildingRemovalSA.h
* PURPOSE: Header file for building removal class
*
* Multi Theft Auto is available from http://www.multitheftauto.com/
*
*****************************************************************************/

#pragma once

#include <CVector.h>
#include <CVector2D.h>

#include <game/CBuildingRemoval.h>

class CBuildingRemovalSA : public CBuildingRemoval
{
public:
CBuildingRemovalSA();

SBuildingRemoval* GetBuildingRemoval(CEntitySAInterface* pInterface) override;

void RemoveBuilding(uint16_t usModelToRemove, float fDistance, float fX, float fY, float fZ, char cInterior, size_t* pOutAmount = NULL) override;
bool RestoreBuilding(uint16_t usModelToRestore, float fDistance, float fX, float fY, float fZ, char cInterior, size_t* pOutAmount = NULL) override;
bool IsRemovedModelInRadius(SIPLInst* pInst) override;
bool IsModelRemoved(uint16_t modelID) override;
void ClearRemovedBuildingLists(uint* pOutAmount = NULL) override;
void AddDataBuilding(CEntitySAInterface* pInterface) override;
void RemoveWorldBuildingFromLists(CEntitySAInterface* pInterface) override;
void AddBinaryBuilding(CEntitySAInterface* pInterface) override;
bool IsObjectRemoved(CEntitySAInterface* pInterface) override;
bool IsDataModelRemoved(uint16_t usModelID) override;
bool IsEntityRemoved(CEntitySAInterface* pInterface) override;
void DropCaches();

private:
std::multimap<uint16_t, SBuildingRemoval*>* m_pBuildingRemovals;
std::multimap<uint16_t, sDataBuildingRemovalItem*>* m_pDataBuildings;
std::multimap<uint16_t, sBuildingRemovalItem*>* m_pBinaryBuildings;
std::map<DWORD, bool> m_pRemovedEntities;
std::map<DWORD, bool> m_pAddedEntities;
};
4 changes: 4 additions & 0 deletions Client/game_sa/CGameSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#include "CWorldSA.h"
#include "D3DResourceSystemSA.h"
#include "CIplStoreSA.h"
#include "CBuildingRemovalSA.h"

extern CGameSA* pGame;

Expand Down Expand Up @@ -141,6 +142,7 @@ CGameSA::CGameSA()
m_pIplStore = new CIplStoreSA();
m_pCoverManager = new CCoverManagerSA();
m_pPlantManager = new CPlantManagerSA();
m_pBuildingRemoval = new CBuildingRemovalSA();

// Normal weapon types (WEAPONSKILL_STD)
for (int i = 0; i < NUM_WeaponInfosStdSkill; i++)
Expand Down Expand Up @@ -278,6 +280,7 @@ CGameSA::~CGameSA()
delete reinterpret_cast<CPointLightsSA*>(m_pPointLights);
delete static_cast<CColStoreSA*>(m_collisionStore);
delete static_cast<CIplStore*>(m_pIplStore);
delete static_cast<CBuildingRemovalSA*>(m_pBuildingRemoval);
delete m_pCoverManager;
delete m_pPlantManager;

Expand Down Expand Up @@ -1003,6 +1006,7 @@ bool CGameSA::SetBuildingPoolSize(size_t size)
RemoveAllBuildings();
}

((CBuildingRemovalSA*)GetBuildingRemoval())->DropCaches();
bool status = m_pPools->GetBuildingsPool().Resize(size);

if (shouldRemoveBuilding)
Expand Down
2 changes: 2 additions & 0 deletions Client/game_sa/CGameSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ class CGameSA : public CGame
CIplStore* GetIplStore() { return m_pIplStore; };
CCoverManagerSA* GetCoverManager() const noexcept { return m_pCoverManager; };
CPlantManagerSA* GetPlantManager() const noexcept { return m_pPlantManager; };
CBuildingRemoval* GetBuildingRemoval() { return m_pBuildingRemoval; }

CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD);
CModelInfo* GetModelInfo(DWORD dwModelID, bool bCanBeInvalid = false);
Expand Down Expand Up @@ -339,6 +340,7 @@ class CGameSA : public CGame
CObjectGroupPhysicalProperties* m_pObjectGroupPhysicalProperties;
CCoverManagerSA* m_pCoverManager;
CPlantManagerSA* m_pPlantManager;
CBuildingRemoval* m_pBuildingRemoval;

CPad* m_pPad;
CAERadioTrackManager* m_pCAERadioTrackManager;
Expand Down
676 changes: 0 additions & 676 deletions Client/game_sa/CWorldSA.cpp

Large diffs are not rendered by default.

21 changes: 1 addition & 20 deletions Client/game_sa/CWorldSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,32 +68,13 @@ class CWorldSA : public CWorld
bool GetOcclusionsEnabled();
void FindWorldPositionForRailTrackPosition(float fRailTrackPosition, int iTrackId, CVector* pOutVecPosition);
int FindClosestRailTrackNode(const CVector& vecPosition, uchar& ucOutTrackId, float& fOutRailDistance);

void RemoveBuilding(unsigned short usModelToRemove, float fDistance, float fX, float fY, float fZ, char cInterior, uint* pOutAmount = NULL);
bool IsRemovedModelInRadius(SIPLInst* pInst);
bool IsModelRemoved(unsigned short modelID);
void ClearRemovedBuildingLists(uint* pOutAmount = NULL);
bool RestoreBuilding(unsigned short usModelToRestore, float fDistance, float fX, float fY, float fZ, char cInterior, uint* pOutAmount = NULL);
SBuildingRemoval* GetBuildingRemoval(CEntitySAInterface* pInterface);
void AddDataBuilding(CEntitySAInterface* pInterface);
void RemoveWorldBuildingFromLists(CEntitySAInterface* pInterface);
void AddBinaryBuilding(CEntitySAInterface* pInterface);
bool IsObjectRemoved(CEntitySAInterface* pInterface);
bool IsDataModelRemoved(unsigned short usModelID);
bool IsEntityRemoved(CEntitySAInterface* pInterface);
bool CalculateImpactPosition(const CVector& vecInputStart, CVector& vecInputEnd);
bool CalculateImpactPosition(const CVector& vecInputStart, CVector& vecInputEnd);

CSurfaceType* GetSurfaceInfo() override;
void ResetAllSurfaceInfo() override;
bool ResetSurfaceInfo(short sSurfaceID) override;

private:
std::multimap<unsigned short, SBuildingRemoval*>* m_pBuildingRemovals;
std::multimap<unsigned short, sDataBuildingRemovalItem*>* m_pDataBuildings;
std::multimap<unsigned short, sBuildingRemovalItem*>* m_pBinaryBuildings;
std::map<unsigned short, unsigned short>* m_pRemovedObjects;
std::map<DWORD, bool> m_pRemovedEntities;
std::map<DWORD, bool> m_pAddedEntities;
float m_fAircraftMaxHeight;
CSurfaceType* m_pSurfaceInfo;
};
3 changes: 2 additions & 1 deletion Client/mods/deathmatch/logic/CClientGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <game/CWeaponStatManager.h>
#include <game/CWeather.h>
#include <game/Task.h>
#include <game/CBuildingRemoval.h>
#include <windowsx.h>
#include "CServerInfo.h"

Expand Down Expand Up @@ -3425,7 +3426,7 @@ void CClientGame::Event_OnIngame()

g_pMultiplayer->DeleteAndDisableGangTags();

g_pGame->GetWorld()->ClearRemovedBuildingLists();
g_pGame->GetBuildingRemoval()->ClearRemovedBuildingLists();
g_pGame->GetWorld()->SetOcclusionsEnabled(true);

g_pGame->ResetModelLodDistances();
Expand Down
3 changes: 2 additions & 1 deletion Client/mods/deathmatch/logic/CPacketHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <game/CWeaponStat.h>
#include <game/CWeaponStatManager.h>
#include <game/CWeather.h>
#include <game/CBuildingRemoval.h>
#include "net/SyncStructures.h"
#include "CServerInfo.h"

Expand Down Expand Up @@ -2641,7 +2642,7 @@ void CPacketHandler::Packet_MapInfo(NetBitStreamInterface& bitStream)
{
bitStream.Read(cInterior);
}
g_pGame->GetWorld()->RemoveBuilding(usModel, fRadius, fX, fY, fZ, cInterior);
g_pGame->GetBuildingRemoval()->RemoveBuilding(usModel, fRadius, fX, fY, fZ, cInterior);
}

bool bOcclusionsEnabled = true;
Expand Down
7 changes: 4 additions & 3 deletions Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <game/CWeapon.h>
#include <game/CWeaponStat.h>
#include <game/CWeaponStatManager.h>
#include <game/CBuildingRemoval.h>
#include <game/Task.h>

using std::list;
Expand Down Expand Up @@ -6711,20 +6712,20 @@ bool CStaticFunctionDefinitions::AreTrafficLightsLocked(bool& bLocked)
bool CStaticFunctionDefinitions::RemoveWorldBuilding(unsigned short usModelToRemove, float fRadius, float fX, float fY, float fZ, char cInterior,
uint& uiOutAmount)
{
g_pGame->GetWorld()->RemoveBuilding(usModelToRemove, fRadius, fX, fY, fZ, cInterior, &uiOutAmount);
g_pGame->GetBuildingRemoval()->RemoveBuilding(usModelToRemove, fRadius, fX, fY, fZ, cInterior, &uiOutAmount);
return true;
}

bool CStaticFunctionDefinitions::RestoreWorldBuildings(uint& uiOutAmount)
{
g_pGame->GetWorld()->ClearRemovedBuildingLists(&uiOutAmount);
g_pGame->GetBuildingRemoval()->ClearRemovedBuildingLists(&uiOutAmount);
return true;
}

bool CStaticFunctionDefinitions::RestoreWorldBuilding(unsigned short usModelToRestore, float fRadius, float fX, float fY, float fZ, char cInterior,
uint& uiOutAmount)
{
return g_pGame->GetWorld()->RestoreBuilding(usModelToRestore, fRadius, fX, fY, fZ, cInterior, &uiOutAmount);
return g_pGame->GetBuildingRemoval()->RestoreBuilding(usModelToRestore, fRadius, fX, fY, fZ, cInterior, &uiOutAmount);
}

bool CStaticFunctionDefinitions::GetSkyGradient(unsigned char& ucTopRed, unsigned char& ucTopGreen, unsigned char& ucTopBlue, unsigned char& ucBottomRed,
Expand Down
7 changes: 4 additions & 3 deletions Client/mods/deathmatch/logic/rpc/CWorldRPCs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <game/CGarage.h>
#include <game/CClock.h>
#include <game/CWeaponStatManager.h>
#include <game/CBuildingRemoval.h>
#include "CWorldRPCs.h"

void CWorldRPCs::LoadFunctions()
Expand Down Expand Up @@ -582,7 +583,7 @@ void CWorldRPCs::RemoveWorldModel(NetBitStreamInterface& bitStream)
{
bitStream.Read(cInterior);
}
g_pGame->GetWorld()->RemoveBuilding(usModel, fRadius, fX, fY, fZ, cInterior);
g_pGame->GetBuildingRemoval()->RemoveBuilding(usModel, fRadius, fX, fY, fZ, cInterior);
}
}

Expand All @@ -597,13 +598,13 @@ void CWorldRPCs::RestoreWorldModel(NetBitStreamInterface& bitStream)
{
bitStream.Read(cInterior);
}
g_pGame->GetWorld()->RestoreBuilding(usModel, fRadius, fX, fY, fZ, cInterior);
g_pGame->GetBuildingRemoval()->RestoreBuilding(usModel, fRadius, fX, fY, fZ, cInterior);
}
}

void CWorldRPCs::RestoreAllWorldModels(NetBitStreamInterface& bitStream)
{
g_pGame->GetWorld()->ClearRemovedBuildingLists();
g_pGame->GetBuildingRemoval()->ClearRemovedBuildingLists();
}

void CWorldRPCs::SetSyncIntervals(NetBitStreamInterface& bitStream)
Expand Down
23 changes: 12 additions & 11 deletions Client/multiplayer_sa/CMultiplayerSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "StdInc.h"
#include <game/CWorld.h>
#include <game/CBuildingRemoval.h>
#include <game/CAnimBlendAssocGroup.h>
#include <game/CPedDamageResponse.h>
#include <game/CEventList.h>
Expand Down Expand Up @@ -5853,15 +5854,15 @@ bool CheckRemovedModelNoSet()
bNextHookSetModel = false;
bCodePathCheck = bNextHookSetModel;
pLODInterface = NULL;
CWorld* pWorld = pGameInterface->GetWorld();
CBuildingRemoval* pBuildingRemoval = pGameInterface->GetBuildingRemoval();
// You never know.
if (pWorld)
if (pBuildingRemoval)
{
// Is the model in question even removed?
if (pWorld->IsModelRemoved(pEntityWorldAdd->m_nModelIndex))
if (pBuildingRemoval->IsModelRemoved(pEntityWorldAdd->m_nModelIndex))
{
// is the replaced model in the spherical radius of any building removal
if (pGameInterface->GetWorld()->IsRemovedModelInRadius(pEntityWorldAdd))
if (pGameInterface->GetBuildingRemoval()->IsRemovedModelInRadius(pEntityWorldAdd))
{
// if it is next hook remove it from the world
return true;
Expand Down Expand Up @@ -5912,7 +5913,7 @@ void HideEntitySomehow()
// Init pInterface with the Initial model
CEntitySAInterface* pInterface = pLODInterface;
// Grab the removal for the interface
SBuildingRemoval* pBuildingRemoval = pGameInterface->GetWorld()->GetBuildingRemoval(pInterface);
SBuildingRemoval* pBuildingRemoval = pGameInterface->GetBuildingRemoval()->GetBuildingRemoval(pInterface);
// Remove down the LOD tree
if (pBuildingRemoval && pInterface && pInterface != NULL && pInterface->bIsProcObject == 0 &&
(pInterface->nType == ENTITY_TYPE_BUILDING || pInterface->nType == ENTITY_TYPE_DUMMY))
Expand All @@ -5932,7 +5933,7 @@ void HideEntitySomehow()
if (pInterface && pInterface != NULL && pInterface->bIsProcObject == 0 &&
(pInterface->nType == ENTITY_TYPE_BUILDING || pInterface->nType == ENTITY_TYPE_DUMMY))
{
pGameInterface->GetWorld()->AddBinaryBuilding(pInterface);
pGameInterface->GetBuildingRemoval()->AddBinaryBuilding(pInterface);
}
}
// Reset our next hook variable
Expand Down Expand Up @@ -5962,7 +5963,7 @@ void StorePointerToBuilding()
{
if (pBuildingAdd != NULL)
{
pGameInterface->GetWorld()->AddDataBuilding(pBuildingAdd);
pGameInterface->GetBuildingRemoval()->AddDataBuilding(pBuildingAdd);
}
}

Expand Down Expand Up @@ -5991,7 +5992,7 @@ bool CheckForRemoval()
// Init pInterface with the Initial model
CEntitySAInterface* pInterface = pLODInterface;
// Remove down the LOD tree
if (pGameInterface->GetWorld()->IsObjectRemoved(pInterface))
if (pGameInterface->GetBuildingRemoval()->IsObjectRemoved(pInterface))
{
return true;
}
Expand Down Expand Up @@ -6020,7 +6021,7 @@ void _declspec(naked) Hook_CWorld_ADD_CPopulation_ConvertToRealObject()
void RemoveObjectIfNeeded()
{
TIMING_CHECKPOINT("+RemoveObjectIfNeeded");
SBuildingRemoval* pBuildingRemoval = pGameInterface->GetWorld()->GetBuildingRemoval(pLODInterface);
SBuildingRemoval* pBuildingRemoval = pGameInterface->GetBuildingRemoval()->GetBuildingRemoval(pLODInterface);
if (pBuildingRemoval != NULL)
{
if ((DWORD)(pBuildingAdd->vtbl) != VTBL_CPlaceable)
Expand Down Expand Up @@ -6069,7 +6070,7 @@ void RemovePointerToBuilding()
{
if (pBuildingRemove->nType == ENTITY_TYPE_BUILDING || pBuildingRemove->nType == ENTITY_TYPE_DUMMY || pBuildingRemove->nType == ENTITY_TYPE_OBJECT)
{
pGameInterface->GetWorld()->RemoveWorldBuildingFromLists(pBuildingRemove);
pGameInterface->GetBuildingRemoval()->RemoveWorldBuildingFromLists(pBuildingRemove);
}
}

Expand Down Expand Up @@ -6099,7 +6100,7 @@ void _declspec(naked) HOOK_CWorld_Remove_CPopulation_ConvertToDummyObject()
// if it's replaced get rid of it
void RemoveDummyIfReplaced()
{
SBuildingRemoval* pBuildingRemoval = pGameInterface->GetWorld()->GetBuildingRemoval(pLODInterface);
SBuildingRemoval* pBuildingRemoval = pGameInterface->GetBuildingRemoval()->GetBuildingRemoval(pLODInterface);
if (pBuildingRemoval != NULL)
{
if ((DWORD)(pBuildingAdd->vtbl) != VTBL_CPlaceable)
Expand Down
Loading

0 comments on commit 53e03d0

Please sign in to comment.