Skip to content

Commit

Permalink
Fix engineFreeModel crashes (PR #3195)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheNormalnij committed Sep 27, 2023
1 parent 0b6908b commit c289c22
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 16 deletions.
38 changes: 25 additions & 13 deletions Client/mods/deathmatch/logic/CClientModel.cpp
Expand Up @@ -78,30 +78,49 @@ bool CClientModel::Allocate(ushort usParentID)
return false;
}

// You can call it only in destructor for DFF.
bool CClientModel::Deallocate()
{
if (!m_bAllocatedByUs)
return false;

SetParentResource(nullptr);

CModelInfo* pModelInfo = g_pGame->GetModelInfo(m_iModelID, true);
if (!pModelInfo || !pModelInfo->IsValid())
return false;

SetParentResource(nullptr);
if (m_eModelType != eClientModelType::TXD)
{
// Remove model info
pModelInfo->DeallocateModel();
}

return true;
}

void CClientModel::RestoreEntitiesUsingThisModel()
{
CModelInfo* pModelInfo = g_pGame->GetModelInfo(m_iModelID, true);
if (!pModelInfo || !pModelInfo->IsValid())
return;

switch (m_eModelType)
{
case eClientModelType::PED:
case eClientModelType::OBJECT:
case eClientModelType::VEHICLE:
return DeallocateDFF(pModelInfo);
RestoreDFF(pModelInfo);
return;
case eClientModelType::TXD:
return DeallocateTXD(pModelInfo);
RestoreTXD(pModelInfo);
return;
default:
return false;
return;
}
}

bool CClientModel::DeallocateDFF(CModelInfo* pModelInfo)
void CClientModel::RestoreDFF(CModelInfo* pModelInfo)
{
auto unloadModelsAndCallEvents = [&](auto iterBegin, auto iterEnd, unsigned short usParentID, auto setElementModelLambda) {
for (auto iter = iterBegin; iter != iterEnd; iter++)
Expand Down Expand Up @@ -164,11 +183,6 @@ bool CClientModel::DeallocateDFF(CModelInfo* pModelInfo)

// Restore DFF/TXD
g_pClientGame->GetManager()->GetDFFManager()->RestoreModel(m_iModelID);

// Remove model info
pModelInfo->DeallocateModel();

return true;
}

bool CClientModel::AllocateTXD(std::string &strTxdName)
Expand All @@ -182,7 +196,7 @@ bool CClientModel::AllocateTXD(std::string &strTxdName)
return false;
}

bool CClientModel::DeallocateTXD(CModelInfo* pModelInfo)
void CClientModel::RestoreTXD(CModelInfo* pModelInfo)
{
uint uiTextureDictonarySlotID = pModelInfo->GetModel() - MAX_MODEL_DFF_ID;

Expand All @@ -196,6 +210,4 @@ bool CClientModel::DeallocateTXD(CModelInfo* pModelInfo)

g_pGame->GetPools()->RemoveTextureDictonarySlot(uiTextureDictonarySlotID);
g_pGame->GetStreaming()->SetStreamingInfo(pModelInfo->GetModel(), 0, 0, 0, -1);

return true;
}
5 changes: 3 additions & 2 deletions Client/mods/deathmatch/logic/CClientModel.h
Expand Up @@ -42,10 +42,11 @@ class CClientModel final
bool Deallocate(void);
void SetParentResource(CResource* pResource) { m_pParentResource = pResource; }
CResource* GetParentResource(void) const { return m_pParentResource; }
void RestoreEntitiesUsingThisModel();

private:
bool DeallocateDFF(CModelInfo* pModelInfo);
bool DeallocateTXD(CModelInfo* pModelInfo);
void RestoreDFF(CModelInfo* pModelInfo);
void RestoreTXD(CModelInfo* pModelInfo);

protected:
CClientManager* m_pManager;
Expand Down
2 changes: 1 addition & 1 deletion Client/mods/deathmatch/logic/CClientModelManager.cpp
Expand Up @@ -49,7 +49,7 @@ bool CClientModelManager::Remove(const std::shared_ptr<CClientModel>& pModel)
int modelId = pModel->GetModelID();
if (m_Models[modelId] != nullptr)
{
m_Models[modelId]->Deallocate();
m_Models[modelId]->RestoreEntitiesUsingThisModel();
m_Models[modelId] = nullptr;
m_modelCount--;
return true;
Expand Down

0 comments on commit c289c22

Please sign in to comment.