mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
DataCache: harden mdl error handling logic
Rebuild 'CMDLCache::GetPhysicsGeometry()' and properly handle missing cache pointers. Also cleaned up various methods in CMDLCache and renamed 'studiophysicscache_t' to 'studiophysicsref_t'. The changes made the 'old_gather_props' convar hack redundant and has thus been removed.
This commit is contained in:
parent
ad4e8c241b
commit
0f3a40ee1f
@ -26,9 +26,9 @@ std::unordered_set<MDLHandle_t> g_vBadMDLHandles;
|
||||
// *a3 -
|
||||
// Output : a pointer to the studiohdr_t object
|
||||
//-----------------------------------------------------------------------------
|
||||
studiohdr_t* CMDLCache::FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3)
|
||||
studiohdr_t* CMDLCache::FindMDL(CMDLCache* const cache, const MDLHandle_t handle, void* a3)
|
||||
{
|
||||
studiodata_t* pStudioData = cache->GetStudioData(handle);
|
||||
studiodata_t* const pStudioData = cache->GetStudioData(handle);
|
||||
|
||||
if (!pStudioData)
|
||||
{
|
||||
@ -106,7 +106,7 @@ studiohdr_t* CMDLCache::FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3)
|
||||
// *pStudioData -
|
||||
// *a3 -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLCache::FindCachedMDL(CMDLCache* cache, studiodata_t* pStudioData, void* a3)
|
||||
void CMDLCache::FindCachedMDL(CMDLCache* const cache, studiodata_t* const pStudioData, void* a3)
|
||||
{
|
||||
if (a3)
|
||||
{
|
||||
@ -130,7 +130,7 @@ void CMDLCache::FindCachedMDL(CMDLCache* cache, studiodata_t* pStudioData, void*
|
||||
// *a4 -
|
||||
// Output : a pointer to the studiohdr_t object
|
||||
//-----------------------------------------------------------------------------
|
||||
studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, studiodata_t* pStudioData, void* a4)
|
||||
studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* const cache, const MDLHandle_t handle, studiodata_t* pStudioData, void* a4)
|
||||
{
|
||||
AUTO_LOCK(pStudioData->m_Mutex);
|
||||
|
||||
@ -221,33 +221,75 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, st
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the studiohdr from cache pool by handle
|
||||
// Purpose: gets the studio physics cache from cache pool by handle
|
||||
// Input : *this -
|
||||
// handle -
|
||||
// Output : a pointer to the studiohdr_t object
|
||||
// Output : a pointer to the studiophysicsref_t object
|
||||
//-----------------------------------------------------------------------------
|
||||
vcollide_t* CMDLCache::GetVCollide(CMDLCache* cache, MDLHandle_t handle)
|
||||
studiophysicsref_t* CMDLCache::GetStudioPhysicsCache(const MDLHandle_t handle)
|
||||
{
|
||||
if (!handle)
|
||||
if (handle == MDLHANDLE_INVALID)
|
||||
return nullptr;
|
||||
|
||||
const studiodata_t* const studioData = GetStudioData(handle);
|
||||
|
||||
if (!studioData)
|
||||
{
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Attempted to get vcollide with no handle.\n");
|
||||
Warning(eDLL_T::ENGINE, "Attempted to load studio physics ref on model \"%s\" with no studio data!\n", GetModelName(handle));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const studiodata_t* const pStudioData = cache->GetStudioData(handle);
|
||||
const studiocache_t* const dataCache = pStudioData->GetStudioCache();
|
||||
const studiocache_t* const studioCache = studioData->GetStudioCache();
|
||||
|
||||
if (dataCache && dataCache != DC_INVALID_HANDLE)
|
||||
if (!studioCache || studioCache == DC_INVALID_HANDLE)
|
||||
{
|
||||
CStudioVCollide* const pVCollide = dataCache->GetPhysicsCache()->GetStudioVCollide();
|
||||
|
||||
if (pVCollide)
|
||||
{
|
||||
return pVCollide->GetVCollide();
|
||||
}
|
||||
Warning(eDLL_T::ENGINE, "Attempted to load studio physics ref on model \"%s\" with invalid studio cache!\n", GetModelName(handle));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return studioCache->GetPhysicsCache();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the vcollide data from cache pool by handle
|
||||
// Input : *this -
|
||||
// handle -
|
||||
// Output : a pointer to the vcollide_t object
|
||||
//-----------------------------------------------------------------------------
|
||||
vcollide_t* CMDLCache::GetVCollide(CMDLCache* const cache, const MDLHandle_t handle)
|
||||
{
|
||||
studiophysicsref_t* const physicsCache = cache->GetStudioPhysicsCache(handle);
|
||||
|
||||
if (!physicsCache)
|
||||
return nullptr;
|
||||
|
||||
CStudioVCollide* const pVCollide = physicsCache->GetStudioVCollide();
|
||||
|
||||
if (!pVCollide)
|
||||
return nullptr;
|
||||
|
||||
return pVCollide->GetVCollide();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the physics geometry data from cache pool by handle
|
||||
// Input : *this -
|
||||
// handle -
|
||||
// Output : a pointer to the physics geometry descriptor
|
||||
//-----------------------------------------------------------------------------
|
||||
void* CMDLCache::GetPhysicsGeometry(CMDLCache* const cache, const MDLHandle_t handle)
|
||||
{
|
||||
studiophysicsref_t* const physicsCache = cache->GetStudioPhysicsCache(handle);
|
||||
|
||||
if (!physicsCache)
|
||||
return nullptr;
|
||||
|
||||
CStudioPhysicsGeoms* const physicsGeoms = physicsCache->GetPhysicsGeoms();
|
||||
|
||||
if (!physicsGeoms)
|
||||
return nullptr;
|
||||
|
||||
return physicsGeoms->GetGeometryData();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -256,7 +298,7 @@ vcollide_t* CMDLCache::GetVCollide(CMDLCache* cache, MDLHandle_t handle)
|
||||
// handle -
|
||||
// Output : a pointer to the studiohwdata_t object
|
||||
//-----------------------------------------------------------------------------
|
||||
studiohwdata_t* CMDLCache::GetHardwareData(CMDLCache* cache, MDLHandle_t handle)
|
||||
studiohwdata_t* CMDLCache::GetHardwareData(CMDLCache* const cache, const MDLHandle_t handle)
|
||||
{
|
||||
const studiodata_t* pStudioData = cache->GetStudioData(handle);
|
||||
|
||||
@ -272,43 +314,39 @@ studiohwdata_t* CMDLCache::GetHardwareData(CMDLCache* cache, MDLHandle_t handle)
|
||||
|
||||
const studiocache_t* const dataCache = pStudioData->GetStudioCache();
|
||||
|
||||
if (dataCache)
|
||||
{
|
||||
if (dataCache == DC_INVALID_HANDLE)
|
||||
return nullptr;
|
||||
if (!dataCache || dataCache == DC_INVALID_HANDLE)
|
||||
return nullptr;
|
||||
|
||||
studiophysicscache_t* const physicsCache = dataCache->GetPhysicsCache();
|
||||
studiophysicsref_t* const physicsCache = dataCache->GetPhysicsCache();
|
||||
|
||||
AcquireSRWLockExclusive(g_pMDLLock);
|
||||
CStudioHWDataRef__SetFlags(reinterpret_cast<CStudioHWDataRef*>(physicsCache), 1i64); // !!! DECLARED INLINE IN < S3 !!!
|
||||
ReleaseSRWLockExclusive(g_pMDLLock);
|
||||
}
|
||||
AcquireSRWLockExclusive(g_pMDLLock);
|
||||
CMDLCache__CheckData(physicsCache, 1i64); // !!! DECLARED INLINE IN < S3 !!!
|
||||
ReleaseSRWLockExclusive(g_pMDLLock);
|
||||
|
||||
if ((pStudioData->m_nFlags & STUDIODATA_FLAGS_STUDIOMESH_LOADED))
|
||||
return pStudioData->GetHardwareDataRef()->GetHardwareData();
|
||||
else
|
||||
return nullptr;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the error model
|
||||
// Output : *studiohdr_t
|
||||
//-----------------------------------------------------------------------------
|
||||
studiohdr_t* CMDLCache::GetErrorModel(void)
|
||||
{
|
||||
// !TODO [AMOS]: mdl/error.rmdl fallback is not supported (yet) in the new GatherProps solution!
|
||||
if (!old_gather_props->GetBool())
|
||||
old_gather_props->SetValue(true);
|
||||
|
||||
return g_pMDLFallback->m_pErrorHDR;
|
||||
}
|
||||
MDLHandle_t CMDLCache::GetErrorModelHandle(void)
|
||||
{
|
||||
return g_pMDLFallback->m_hErrorMDL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if this model handle is within the set of bad models
|
||||
// Input : handle -
|
||||
// Output : true if exist, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMDLCache::IsKnownBadModel(MDLHandle_t handle)
|
||||
bool CMDLCache::IsKnownBadModel(const MDLHandle_t handle)
|
||||
{
|
||||
auto p = g_vBadMDLHandles.insert(handle);
|
||||
return !p.second;
|
||||
@ -321,4 +359,5 @@ void VMDLCache::Detour(const bool bAttach) const
|
||||
DetourSetup(&CMDLCache__FindUncachedMDL, &CMDLCache::FindUncachedMDL, bAttach);
|
||||
DetourSetup(&CMDLCache__GetHardwareData, &CMDLCache::GetHardwareData, bAttach);
|
||||
DetourSetup(&CMDLCache__GetVCollide, &CMDLCache::GetVCollide, bAttach);
|
||||
DetourSetup(&CMDLCache__GetPhysicsGeometry, &CMDLCache::GetPhysicsGeometry, bAttach);
|
||||
}
|
||||
|
@ -52,14 +52,18 @@ private:
|
||||
|
||||
class CStudioPhysicsGeoms : public CRefCounted<>
|
||||
{
|
||||
int unk1;
|
||||
public:
|
||||
void* GetGeometryData() { return m_pGeomDataDesc; }
|
||||
|
||||
private:
|
||||
// TODO: ptr to another ptr to geometry data; requires reversing.
|
||||
void* m_pGeomDataDesc;
|
||||
int unk2;
|
||||
__int16 unk3;
|
||||
__int16 unk4;
|
||||
short unk3;
|
||||
short unk4;
|
||||
};
|
||||
|
||||
struct studiophysicscache_t
|
||||
struct studiophysicsref_t
|
||||
{
|
||||
inline CStudioVCollide* GetStudioVCollide() const { return m_pVCollide; }
|
||||
inline CStudioPhysicsGeoms* GetPhysicsGeoms() const { return m_pPhysicsGeoms; }
|
||||
@ -77,10 +81,10 @@ struct studiophysicscache_t
|
||||
struct studiocache_t
|
||||
{
|
||||
inline studiohdr_t* GetStudioHdr() const { return m_pStudioHdr; }
|
||||
inline studiophysicscache_t* GetPhysicsCache() const { return m_pPhysicsCache; }
|
||||
inline studiophysicsref_t* GetPhysicsCache() const { return m_pPhysicsCache; }
|
||||
|
||||
studiohdr_t* m_pStudioHdr;
|
||||
studiophysicscache_t* m_pPhysicsCache;
|
||||
studiophysicsref_t* m_pPhysicsCache;
|
||||
const char* m_szPropName;
|
||||
uint8_t m_pUnknown[98];
|
||||
};
|
||||
@ -122,44 +126,50 @@ struct studiodata_t
|
||||
extern RMDLFallBack_t* g_pMDLFallback;
|
||||
extern std::unordered_set<MDLHandle_t> g_vBadMDLHandles;
|
||||
|
||||
class CMDLCache : public IMDLCache
|
||||
class CMDLCache : public CTier1AppSystem<IMDLCache>
|
||||
{
|
||||
public:
|
||||
static studiohdr_t* FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3);
|
||||
static void FindCachedMDL(CMDLCache* cache, studiodata_t* pStudioData, void* a3);
|
||||
static studiohdr_t* FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, studiodata_t* pStudioData, void* a4);
|
||||
static studiohdr_t* FindMDL(CMDLCache* const cache, const MDLHandle_t handle, void* a3);
|
||||
static void FindCachedMDL(CMDLCache* const cache, studiodata_t* const pStudioData, void* a3);
|
||||
static studiohdr_t* FindUncachedMDL(CMDLCache* const cache, const MDLHandle_t handle, studiodata_t* const pStudioData, void* a4);
|
||||
|
||||
studiophysicsref_t* GetStudioPhysicsCache(const MDLHandle_t handle);
|
||||
|
||||
static vcollide_t* GetVCollide(CMDLCache* const cache, const MDLHandle_t handle);
|
||||
static void* GetPhysicsGeometry(CMDLCache* const cache, const MDLHandle_t handle);
|
||||
|
||||
static studiohwdata_t* GetHardwareData(CMDLCache* const cache, const MDLHandle_t handle);
|
||||
|
||||
static vcollide_t* GetVCollide(CMDLCache* cache, MDLHandle_t handle);
|
||||
static studiohwdata_t* GetHardwareData(CMDLCache* cache, MDLHandle_t handle);
|
||||
static studiohdr_t* GetErrorModel(void);
|
||||
static bool IsKnownBadModel(MDLHandle_t handle);
|
||||
static MDLHandle_t GetErrorModelHandle(void);
|
||||
static bool IsKnownBadModel(const MDLHandle_t handle);
|
||||
|
||||
|
||||
inline studiodata_t* GetStudioData(MDLHandle_t handle)
|
||||
inline studiodata_t* GetStudioData(const MDLHandle_t handle)
|
||||
{
|
||||
EnterCriticalSection(&m_MDLMutex);
|
||||
studiodata_t* pStudioData = m_MDLDict.Element(handle);
|
||||
studiodata_t* const studioData = m_MDLDict.Element(handle);
|
||||
LeaveCriticalSection(&m_MDLMutex);
|
||||
|
||||
return pStudioData;
|
||||
return studioData;
|
||||
}
|
||||
|
||||
inline const char* GetModelName(MDLHandle_t handle)
|
||||
inline const char* GetModelName(const MDLHandle_t handle)
|
||||
{
|
||||
EnterCriticalSection(&m_MDLMutex);
|
||||
const char* szModelName = m_MDLDict.GetElementName(handle);
|
||||
const char* const modelName = m_MDLDict.GetElementName(handle);
|
||||
LeaveCriticalSection(&m_MDLMutex);
|
||||
|
||||
return szModelName;
|
||||
return modelName;
|
||||
}
|
||||
|
||||
inline void* GetMaterialTable(MDLHandle_t handle)
|
||||
inline void* GetMaterialTable(const MDLHandle_t handle)
|
||||
{
|
||||
EnterCriticalSection(&m_MDLMutex);
|
||||
studiodata_t* pStudioData = m_MDLDict.Element(handle);
|
||||
studiodata_t* const studioData = m_MDLDict.Element(handle);
|
||||
LeaveCriticalSection(&m_MDLMutex);
|
||||
|
||||
return &pStudioData->m_pMaterialTable;
|
||||
return &studioData->m_pMaterialTable;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -168,14 +178,15 @@ private:
|
||||
// !TODO: reverse the rest
|
||||
};
|
||||
|
||||
inline studiohdr_t*(*CMDLCache__FindMDL)(CMDLCache* pCache, MDLHandle_t handle, void* a3);
|
||||
inline void(*CMDLCache__FindCachedMDL)(CMDLCache* pCache, studiodata_t* pStudioData, void* a3);
|
||||
inline studiohdr_t*(*CMDLCache__FindMDL)(CMDLCache* const pCache, const MDLHandle_t handle, void* a3);
|
||||
inline void(*CMDLCache__FindCachedMDL)(CMDLCache* const pCache, studiodata_t* const pStudioData, void* a3);
|
||||
inline studiohdr_t*(*CMDLCache__FindUncachedMDL)(CMDLCache* const pCache, MDLHandle_t handle, studiodata_t* const pStudioData, void* a4);
|
||||
|
||||
inline studiohdr_t*(*CMDLCache__FindUncachedMDL)(CMDLCache* pCache, MDLHandle_t handle, studiodata_t* pStudioData, void* a4);
|
||||
inline vcollide_t*(*CMDLCache__GetVCollide)(CMDLCache* pCache, MDLHandle_t handle);
|
||||
inline studiohwdata_t* (*CMDLCache__GetHardwareData)(CMDLCache* const pCache, const MDLHandle_t handle);
|
||||
inline vcollide_t*(*CMDLCache__GetVCollide)(CMDLCache* const pCache, const MDLHandle_t handle);
|
||||
inline void* (*CMDLCache__GetPhysicsGeometry)(CMDLCache* const pCache, const MDLHandle_t handle);
|
||||
|
||||
inline studiohwdata_t*(*CMDLCache__GetHardwareData)(CMDLCache* pCache, MDLHandle_t handle);
|
||||
inline bool(*CStudioHWDataRef__SetFlags)(CStudioHWDataRef* ref, int64_t flags); // Probably incorrect name.
|
||||
inline bool(*CMDLCache__CheckData)(void* const ref, const int64_t type); // Probably incorrect name.
|
||||
|
||||
inline CMDLCache* g_pMDLCache = nullptr;
|
||||
inline PSRWLOCK g_pMDLLock = nullptr; // Possibly a member? research required.
|
||||
@ -188,9 +199,10 @@ class VMDLCache : public IDetour
|
||||
LogFunAdr("CMDLCache::FindMDL", CMDLCache__FindMDL);
|
||||
LogFunAdr("CMDLCache::FindCachedMDL", CMDLCache__FindCachedMDL);
|
||||
LogFunAdr("CMDLCache::FindUncachedMDL", CMDLCache__FindUncachedMDL);
|
||||
LogFunAdr("CMDLCache::GetVCollide", CMDLCache__GetVCollide);
|
||||
LogFunAdr("CMDLCache::GetHardwareData", CMDLCache__GetHardwareData);
|
||||
LogFunAdr("CStudioHWDataRef::SetFlags", CStudioHWDataRef__SetFlags);
|
||||
LogFunAdr("CMDLCache::GetVCollide", CMDLCache__GetVCollide);
|
||||
LogFunAdr("CMDLCache::GetPhysicsGeometry", CMDLCache__GetPhysicsGeometry);
|
||||
LogFunAdr("CMDLCache::CheckData", CMDLCache__CheckData);
|
||||
|
||||
LogVarAdr("g_MDLCache", g_pMDLCache);
|
||||
LogVarAdr("g_MDLLock", g_pMDLLock);
|
||||
@ -200,9 +212,10 @@ class VMDLCache : public IDetour
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F1 0F B7 EA").GetPtr(CMDLCache__FindMDL);
|
||||
g_GameDll.FindPatternSIMD("4D 85 C0 74 7A 48 89 6C 24 ??").GetPtr(CMDLCache__FindCachedMDL);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 20 48 8B E9 0F B7 FA").GetPtr(CMDLCache__FindUncachedMDL);
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 0F B7 DA FF 15 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 8D 14 5B 48 8D 0D ?? ?? ?? ?? 48 8B 5C D0 ?? FF 15 ?? ?? ?? ?? 48 8B 03 48 8B 48 08").GetPtr(CMDLCache__GetVCollide);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 0F B7 DA FF 15 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 8D 14 5B 48 8D 0D ?? ?? ?? ?? 48 8B 7C D0 ?? FF 15 ?? ?? ?? ?? 48 8B 1F").GetPtr(CMDLCache__GetHardwareData);
|
||||
g_GameDll.FindPatternSIMD("48 83 EC 08 4C 8D 14 12").GetPtr(CStudioHWDataRef__SetFlags);
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 0F B7 DA FF 15 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 8D 14 5B 48 8D 0D ?? ?? ?? ?? 48 8B 5C D0 ?? FF 15 ?? ?? ?? ?? 48 8B 03 48 8B 48 08").GetPtr(CMDLCache__GetVCollide);
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 B8 ?? ?? ?? ?? 0F B7 DA").GetPtr(CMDLCache__GetPhysicsGeometry);
|
||||
g_GameDll.FindPatternSIMD("48 83 EC 08 4C 8D 14 12").GetPtr(CMDLCache__CheckData);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
|
@ -266,18 +266,6 @@ void Mod_ProcessPakQueue()
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
|
||||
// The old gather props is set if a model couldn't be
|
||||
// loaded properly. If we unload level assets, we just
|
||||
// enable the new implementation again and re-evaluate
|
||||
// on the next level load. If we load a missing/bad
|
||||
// model again, we toggle the old implementation as
|
||||
// the helper functions for this implementation have
|
||||
// been restored in the SDK, and modified to support
|
||||
// stubbing missing model assets. See the function
|
||||
// 'CMDLCache::GetErrorModel' for more information.
|
||||
if (old_gather_props->GetBool())
|
||||
old_gather_props->SetValue(false);
|
||||
|
||||
g_pakLoadApi->UnloadPak(*(PakHandle_t*)v10);
|
||||
Mod_UnloadPakFile(); // Unload mod pak files.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user