Skip to content

Commit

Permalink
Merge Fixed crash when switching to an invalid ped drawable (mr-466)
Browse files Browse the repository at this point in the history
558eecb - fix: fixed crash when switching to an invalid ped drawable
  • Loading branch information
prikolium-cfx committed Aug 15, 2024
2 parents 1884fe7 + 558eecb commit 09c04d4
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
8 changes: 7 additions & 1 deletion code/client/shared/Hooking.FlexStruct.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@ namespace hook
template<typename T>
const T& Get(int32_t offset)
{
return *(T*)((uintptr_t)this + offset);
return *(const T*)((uintptr_t)this + offset);
}

template<typename T>
void Set(int32_t offset, const T& value)
{
*(T*)((uintptr_t)this + offset) = value;
}

template<typename T>
T& At(int32_t offset)
{
return *(T*)((uintptr_t)this + offset);
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include <StdInc.h>

#include <Hooking.h>
#include <Hooking.Stubs.h>
#include <Hooking.FlexStruct.h>

static void (*orig_CPedVariationStream__ApplyStreamPedFiles)(hook::FlexStruct* pPed, void* pNewVarData, void* pPSGfx);
static uint32_t off_CPed__m_CClothController;

// CPed holds non-owning pointers to each component's characterClothController.
// ApplyStreamPedFiles should update all of these, since they will stop existing soon afterwards.
// However, if a new component does not have a texture or drawable, the update loop will skip it without nulling the existing pointer.
static void CPedVariationStream__ApplyStreamPedFiles(hook::FlexStruct* pPed, void* pNewVarData, void* pPSGfx)
{
void** controllers = pPed->At<void*[]>(off_CPed__m_CClothController);
void* oldControllers[12];

for (int i = 0; i < 12; ++i)
{
oldControllers[i] = controllers[i];
}

orig_CPedVariationStream__ApplyStreamPedFiles(pPed, pNewVarData, pPSGfx);

for (int i = 0; i < 12; ++i)
{
if (controllers[i] && controllers[i] == oldControllers[i])
{
// We're still holding a pointer to the old controller!
trace("Stale cloth controller pointer crash prevented [CFX-1735]\n");
controllers[i] = nullptr;
}
}
}

static HookFunction hookFunction([]
{
orig_CPedVariationStream__ApplyStreamPedFiles = hook::trampoline(hook::get_call(hook::get_pattern("4C 8B C3 48 8B D6 E8 ? ? ? ? 48 8B D7", 6)), &CPedVariationStream__ApplyStreamPedFiles);

off_CPed__m_CClothController = *(uint32_t*)hook::get_pattern<char>("40 88 B8 ? ? ? ? 4A 89 BC E6", 11);
});

0 comments on commit 09c04d4

Please sign in to comment.