Skip to content

Commit

Permalink
physenv: testing a fix for another crash
Browse files Browse the repository at this point in the history
  • Loading branch information
RaphaelIT7 committed Nov 19, 2024
1 parent 5a9cd8e commit b041a01
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 29 deletions.
86 changes: 59 additions & 27 deletions source/modules/physenv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,15 +248,28 @@ class CLuaPhysicsObjectEvent : public IPhysicsObjectEvent
int m_iObjectSleepFunction;
};

struct ILuaPhysicsEnvironment;
static int IPhysicsEnvironment_TypeID = -1;
PushReferenced_LuaClass(ILuaPhysicsEnvironment, IPhysicsEnvironment_TypeID)
Get_LuaClass(ILuaPhysicsEnvironment, IPhysicsEnvironment_TypeID, "IPhysicsEnvironment")

static std::unordered_map<IPhysicsEnvironment*, ILuaPhysicsEnvironment*> g_pEnvironmentToLua;
struct ILuaPhysicsEnvironment
{
ILuaPhysicsEnvironment(IPhysicsEnvironment* env)
{
pEnvironment = env;
g_pEnvironmentToLua[env] = this;
}

~ILuaPhysicsEnvironment()
{
Delete_ILuaPhysicsEnvironment(this);

g_pEnvironmentToLua.erase(g_pEnvironmentToLua.find(pEnvironment));
physics->DestroyEnvironment(pEnvironment);
pEnvironment = NULL;

if (pObjectEvent)
delete pObjectEvent;

Expand All @@ -273,10 +286,6 @@ struct ILuaPhysicsEnvironment
//CLuaPhysicsCollisionEvent* pCollisionEvent = NULL;
};

static int IPhysicsEnvironment_TypeID = -1;
PushReferenced_LuaClass(ILuaPhysicsEnvironment, IPhysicsEnvironment_TypeID)
Get_LuaClass(ILuaPhysicsEnvironment, IPhysicsEnvironment_TypeID, "IPhysicsEnvironment")

static int IPhysicsCollisionSet_TypeID = -1;
PushReferenced_LuaClass(IPhysicsCollisionSet, IPhysicsCollisionSet_TypeID)
Get_LuaClass(IPhysicsCollisionSet, IPhysicsCollisionSet_TypeID, "IPhysicsCollisionSet")
Expand All @@ -299,13 +308,13 @@ Get_LuaClass(ICollisionQuery, ICollisionQuery_TypeID, "ICollisionQuery")

static Push_LuaClass(Vector, GarrysMod::Lua::Type::Vector)

inline IPhysicsEnvironment* GetPhysicsEnvironment(int iStackPos, bool bError)
static IPhysicsEnvironment* GetPhysicsEnvironment(int iStackPos, bool bError)
{
ILuaPhysicsEnvironment* pEnvironment = Get_ILuaPhysicsEnvironment(iStackPos, bError);
if (!pEnvironment->pEnvironment && bError)
ILuaPhysicsEnvironment* pLuaEnv = Get_ILuaPhysicsEnvironment(iStackPos, bError);
if (bError && (!pLuaEnv || !pLuaEnv->pEnvironment))
g_Lua->ThrowError(triedNull_ILuaPhysicsEnvironment.c_str());

return pEnvironment->pEnvironment;
return pLuaEnv->pEnvironment;
}

LUA_FUNCTION_STATIC(physenv_CreateEnvironment)
Expand Down Expand Up @@ -370,34 +379,58 @@ LUA_FUNCTION_STATIC(physenv_GetActiveEnvironmentByIndex)
LUA->ThrowError("Failed to get IPhysics!");

int index = (int)LUA->CheckNumber(1);
Push_ILuaPhysicsEnvironment(new ILuaPhysicsEnvironment(physics->GetActiveEnvironmentByIndex(index)));
IPhysicsEnvironment* pEnvironment = physics->GetActiveEnvironmentByIndex(index);
if (!pEnvironment)
{
Push_ILuaPhysicsEnvironment(NULL);
return 1;
}

auto it = g_pEnvironmentToLua.find(pEnvironment);
if (it != g_pEnvironmentToLua.end())
{
Push_ILuaPhysicsEnvironment(it->second);
return 1;
}

Push_ILuaPhysicsEnvironment(new ILuaPhysicsEnvironment(pEnvironment));
return 1;
}

static std::vector<ILuaPhysicsEnvironment*> g_pCurrentEnvironment;
Symbols::CBaseEntity_VPhysicsDestroyObject func_CBaseEntity_VPhysicsDestroyObject;
LUA_FUNCTION_STATIC(physenv_DestroyEnvironment)
{
if (!physics)
LUA->ThrowError("Failed to get IPhysics!");

ILuaPhysicsEnvironment* pLuaEnv = Get_ILuaPhysicsEnvironment(1, true);
for (ILuaPhysicsEnvironment* ppLuaEnv : g_pCurrentEnvironment)
{
if (pLuaEnv == ppLuaEnv)
LUA->ThrowError("Tried to delete a IPhysicsEnvironment that is simulating!"); // Don't even dare.....
}


CPhysicsEnvironment* pEnvironment = (CPhysicsEnvironment*)pLuaEnv->pEnvironment;
if (pLuaEnv->pEnvironment)
{
int index = -1;
for (int i = pEnvironment->m_objects.Count(); --i >= 0; )
if (func_CBaseEntity_VPhysicsDestroyObject)
{
IPhysicsObject* pObject = pEnvironment->m_objects[i];
CBaseEntity* pEntity = (CBaseEntity*)pObject->GetGameData();
if (pEntity)
for (int i = pEnvironment->m_objects.Count(); --i >= 0; )
{

IPhysicsObject* pObject = pEnvironment->m_objects[i];
CBaseEntity* pEntity = (CBaseEntity*)pObject->GetGameData();
if (pEntity)
{
//pEntity->VPhysicsUpdate(NULL); // Since the vtables are broken since ~4 functions were removed, this should currently call VPhysicsDestroyObject
func_CBaseEntity_VPhysicsDestroyObject(pEntity); // I'm like 100% certain that the workaround above caused some unholy behavior.
}
}
}

physics->DestroyEnvironment(pEnvironment);
}

Delete_ILuaPhysicsEnvironment(pLuaEnv);
delete pLuaEnv;

return 0;
}
Expand Down Expand Up @@ -749,7 +782,6 @@ LUA_FUNCTION_STATIC(IPhysicsEnvironment_EnableDeleteQueue)
}

Symbols::CBaseEntity_VPhysicsUpdate func_CBaseEntity_VPhysicsUpdate;
ILuaPhysicsEnvironment* g_pCurrentEnvironment = NULL;
LUA_FUNCTION_STATIC(IPhysicsEnvironment_Simulate)
{
ILuaPhysicsEnvironment* pLuaEnv = Get_ILuaPhysicsEnvironment(1, true);
Expand All @@ -759,8 +791,7 @@ LUA_FUNCTION_STATIC(IPhysicsEnvironment_Simulate)
bool onlyEntities = LUA->GetBool(3);

VPROF_BUDGET("HolyLib(Lua) - IPhysicsEnvironment::Simulate", VPROF_BUDGETGROUP_HOLYLIB);
ILuaPhysicsEnvironment* pOldEnvironment = g_pCurrentEnvironment; // Simulating a environment in a already simulating environment? sounds fun :^
g_pCurrentEnvironment = pLuaEnv;
g_pCurrentEnvironment.push_back(pLuaEnv);
if (!onlyEntities)
pEnvironment->Simulate(deltaTime);

Expand Down Expand Up @@ -804,13 +835,13 @@ LUA_FUNCTION_STATIC(IPhysicsEnvironment_Simulate)
}
}*/

g_pCurrentEnvironment = pOldEnvironment;
g_pCurrentEnvironment.pop_back();
return 0;
}

LUA_FUNCTION_STATIC(physenv_GetCurrentEnvironment)
{
Push_ILuaPhysicsEnvironment(g_pCurrentEnvironment);
Push_ILuaPhysicsEnvironment(g_pCurrentEnvironment.back());
return 1;
}

Expand Down Expand Up @@ -1674,12 +1705,10 @@ bool hook_GMod_Util_IsPhysicsObjectValid(IPhysicsObject* obj)
* NOTE: This only ocurrs when you delete a Environment that still has objects?
*/
/*Detouring::Hook detour_CBaseEntity_GMOD_VPhysicsTest;
void* hook_CBaseEntity_GMOD_VPhysicsTest(CBaseEntity* pEnt, IPhysicsObject* obj)
void hook_CBaseEntity_GMOD_VPhysicsTest(CBaseEntity* pEnt, IPhysicsObject* obj)
{
// NUKE THE FUNCTION for now.
void* ret = detour_CBaseEntity_GMOD_VPhysicsTest.GetTrampoline<Symbols::CBaseEntity_GMOD_VPhysicsTest>()(pEnt, obj);
Msg("%p\n", ret);
return ret;
// detour_CBaseEntity_GMOD_VPhysicsTest.GetTrampoline<Symbols::CBaseEntity_GMOD_VPhysicsTest>()(pEnt, obj);
}*/

/*
Expand Down Expand Up @@ -2003,4 +2032,7 @@ void CPhysEnvModule::InitDetour(bool bPreServer)

func_CBaseEntity_VPhysicsUpdate = (Symbols::CBaseEntity_VPhysicsUpdate)Detour::GetFunction(server_loader.GetModule(), Symbols::CBaseEntity_VPhysicsUpdateSym);
Detour::CheckValue("get function", "CBaseEntity::VPhysicsUpdate", func_CBaseEntity_VPhysicsUpdate != NULL);

func_CBaseEntity_VPhysicsDestroyObject = (Symbols::CBaseEntity_VPhysicsDestroyObject)Detour::GetFunction(server_loader.GetModule(), Symbols::CBaseEntity_VPhysicsDestroyObjectSym);
Detour::CheckValue("get function", "CBaseEntity::VPhysicsDestroyObject", func_CBaseEntity_VPhysicsDestroyObject != NULL);
}
4 changes: 4 additions & 0 deletions source/symbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ namespace Symbols
Symbol::FromName("_ZN11CBaseEntity17GMOD_VPhysicsTestEP14IPhysicsObject"),
};

const std::vector<Symbol> CBaseEntity_VPhysicsDestroyObjectSym = {
Symbol::FromName("_ZN11CBaseEntity21VPhysicsDestroyObjectEv"),
};

const std::vector<Symbol> CGetSym = { // 64x ToDo
Symbol::FromName("get"),
};
Expand Down
5 changes: 4 additions & 1 deletion source/symbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,12 @@ namespace Symbols
typedef void (*CBaseEntity_VPhysicsUpdate)(void* fancy_class, void* obj);
extern const std::vector<Symbol> CBaseEntity_VPhysicsUpdateSym;

typedef void* (*CBaseEntity_GMOD_VPhysicsTest)(void* fancy_class, void* obj);
typedef void (*CBaseEntity_GMOD_VPhysicsTest)(void* fancy_class, void* obj);
extern const std::vector<Symbol> CBaseEntity_GMOD_VPhysicsTestSym;

typedef void (*CBaseEntity_VPhysicsDestroyObject)(void* fancy_class);
extern const std::vector<Symbol> CBaseEntity_VPhysicsDestroyObjectSym;

extern const std::vector<Symbol> CGetSym;

//---------------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion source/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ struct LuaUserData { // ToDo: Maybe implement this also for other things?

int iReference = -1;
int iTableReference = -1;
int pAdditionalData = -1; // Used by HLTVClient.
int pAdditionalData = NULL; // Used by HLTVClient.
};

// This one is special
Expand Down

0 comments on commit b041a01

Please sign in to comment.