Fix crash when loading arena maps caused by recent BSP crash fix

CMaterial and CMaterialGlue derive from the same abstract classes. The function that builds the culling map uses IMaterialInternal, which is used by CMaterial, CMaterialInternal and CMaterialSubRect. Added a check for CMaterialGlue as these are valid too.
This commit is contained in:
Kawe Mazidjatari 2022-10-05 01:59:22 +02:00
parent 70153d209c
commit a68fda98c1
4 changed files with 7 additions and 5 deletions

View File

@ -400,7 +400,7 @@ void* __fastcall BuildPropStaticFrustumCullMap(int64_t a1, int64_t a2, unsigned
if (reinterpret_cast<uintptr_t>(v68) < g_GameDll.m_RunTimeData.m_pSectionBase || // Check bounds (data is mostly within the '.data' segment.
reinterpret_cast<uintptr_t>(v68) > g_GameDll.m_ExceptionTable.m_pSectionBase || error)
{
if (!IsMaterialVFTable(reinterpret_cast<void**>(v68))) // Last chance.
if (!IsMaterialInternal(reinterpret_cast<void**>(v68))) // Last chance.
{
error = true;
continue;

View File

@ -1,5 +1,4 @@
#pragma once
#include "materialsystem/cshaderglue.h"
#pragma pack(push, 1) // Without this MSVC might get the idea to align our members to completely fuck the offsets up.

View File

@ -7,6 +7,7 @@
#include "tier1/cvar.h"
#include "rtech/rtech_utils.h"
#include "filesystem/filesystem.h"
#include "materialsystem/cmaterialglue.h"
#include "materialsystem/cmaterialsystem.h"
//---------------------------------------------------------------------------------
@ -85,7 +86,7 @@ void* __fastcall DispatchDrawCall(int64_t a1, uint64_t a2, int a3, int a4, int64
// Input : **pCandidate -
// Output : true if valid and material, false otherwise
//-----------------------------------------------------------------------------
bool IsMaterialVFTable(void** pCandidate)
bool IsMaterialInternal(void** pCandidate)
{
// NOTE: this is a dirty fix, but for running technically broken BSP's, this is the only fix
// besides going bare metal inline assembly (which on its own isn't directly the problem, but
@ -99,13 +100,15 @@ bool IsMaterialVFTable(void** pCandidate)
// The first member of the CMaterial data structure should be its VFTable pointer, anything else is invalid.
__try
{
if (*pCandidate == g_pMaterialVFTable)
if (*pCandidate == g_pMaterialVFTable ||
*pCandidate == g_pMaterialGlueVFTable)
return true;
}
__except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
{
return false;
}
return false;
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -26,7 +26,7 @@ inline int* g_nUnfreeStreamingTextureMemory = nullptr;
inline int* g_nUnusableStreamingTextureMemory = nullptr;
#endif // !DEDICATED
bool IsMaterialVFTable(void** pCandidate);
bool IsMaterialInternal(void** pCandidate);
void CMaterialSystem_Attach();
void CMaterialSystem_Detach();
///////////////////////////////////////////////////////////////////////////////