Skip to content

Commit

Permalink
fix(core/rdr3): train config index crash workaround
Browse files Browse the repository at this point in the history
  • Loading branch information
Disquse committed Oct 12, 2023
1 parent 37fa83b commit 3454f95
Showing 1 changed file with 63 additions and 0 deletions.
63 changes: 63 additions & 0 deletions code/components/gta-core-rdr3/src/PatchTrainConfigCrash.cpp
@@ -0,0 +1,63 @@
#include <StdInc.h>

#include "atArray.h"
#include "Hooking.h"
#include "Hooking.Stubs.h"

struct CTrainToken
{
void* vtable;
char pad_8[0xC1];
unsigned char m_trainConfigIndex;
char pad_CA[6];
};

struct CTrainConfigs
{
atArray<void*> m_trainConfigs;
atArray<void*> m_trainGroups;
};

static uint32_t GetTrainTokenMethodOffset; // CTrain

static CTrainToken* GetTrainToken(void* train)
{
return (*(CTrainToken*(__fastcall**)(void*))(*(uint64_t*)train + GetTrainTokenMethodOffset))(train);
}

static CTrainConfigs* g_trainConfigs;

static bool (*g_origRequestTrainCarriageAssets)(void*);

static bool RequestTrainCarriageAssets(void* train)
{
const auto trainToken = (train) ? GetTrainToken(train) : nullptr;

// Ensure that our train has a train token
if (!trainToken)
{
return false;
}

// Bail out if token's train config index is invalid (usually 0xFF)
if (trainToken->m_trainConfigIndex >= g_trainConfigs->m_trainConfigs.GetCount())
{
return false;
}

return g_origRequestTrainCarriageAssets(train);
}

static HookFunction hookFunction([]()
{
static_assert(sizeof(CTrainToken) == 0xD0);
static_assert(sizeof(CTrainConfigs) == 0x20);

auto location = hook::get_pattern<char>("44 0F B7 74 DA 28 45 85 F6 0F", -0x4A);

g_origRequestTrainCarriageAssets = hook::trampoline(location, RequestTrainCarriageAssets);

g_trainConfigs = hook::get_address<CTrainConfigs*>(location + 0x3B);

GetTrainTokenMethodOffset = *(uint32_t*)(location + 0x21);
});

0 comments on commit 3454f95

Please sign in to comment.