Probe pathfinding start stop wrappers
This commit is contained in:
@@ -92,6 +92,10 @@ namespace
|
||||
constexpr uint32_t kGameStateRunning = 2;
|
||||
constexpr uintptr_t kGpsSystemTickRva = 0x0E6B62C;
|
||||
constexpr uintptr_t kTrafficSystemPathfindingRva = 0x0AD1234;
|
||||
constexpr uintptr_t kStopPathfindingA = 0x11C20A8;
|
||||
constexpr uintptr_t kStopPathfindingB = 0x11C2148;
|
||||
constexpr uintptr_t kStartPathfindingA = 0x11C21FC;
|
||||
constexpr uintptr_t kStartPathfindingB = 0x11C22B0;
|
||||
|
||||
HMODULE gModule = nullptr;
|
||||
std::mutex gLogMutex;
|
||||
@@ -101,10 +105,20 @@ uint32_t gUpdateLogCount = 0;
|
||||
bool gScannedExecutable = false;
|
||||
uint32_t gGpsTickLogCount = 0;
|
||||
uint32_t gTrafficPathfindingLogCount = 0;
|
||||
uint32_t gStopPathfindingALogCount = 0;
|
||||
uint32_t gStopPathfindingBLogCount = 0;
|
||||
uint32_t gStartPathfindingALogCount = 0;
|
||||
uint32_t gStartPathfindingBLogCount = 0;
|
||||
uint64_t gLogStartTick = 0;
|
||||
uint64_t gLogFrequency = 0;
|
||||
|
||||
using ProbeFunc = void (*)(void* aThis, void* a2, void* a3, void* a4);
|
||||
ProbeFunc gOriginalGpsSystemTick = nullptr;
|
||||
ProbeFunc gOriginalTrafficSystemPathfinding = nullptr;
|
||||
ProbeFunc gOriginalStopPathfindingA = nullptr;
|
||||
ProbeFunc gOriginalStopPathfindingB = nullptr;
|
||||
ProbeFunc gOriginalStartPathfindingA = nullptr;
|
||||
ProbeFunc gOriginalStartPathfindingB = nullptr;
|
||||
|
||||
std::filesystem::path GetLogPath()
|
||||
{
|
||||
@@ -133,7 +147,16 @@ void Log(std::string_view aMessage)
|
||||
return;
|
||||
}
|
||||
|
||||
out << std::put_time(&localTime, "%Y-%m-%d %H:%M:%S") << " " << aMessage << "\n";
|
||||
uint64_t elapsedMs = 0;
|
||||
if (gLogStartTick && gLogFrequency)
|
||||
{
|
||||
LARGE_INTEGER counter{};
|
||||
QueryPerformanceCounter(&counter);
|
||||
elapsedMs = static_cast<uint64_t>((counter.QuadPart - gLogStartTick) * 1000 / gLogFrequency);
|
||||
}
|
||||
|
||||
out << std::put_time(&localTime, "%Y-%m-%d %H:%M:%S") << "." << std::setw(3) << std::setfill('0')
|
||||
<< elapsedMs % 1000 << std::setfill(' ') << " +" << elapsedMs << "ms " << aMessage << "\n";
|
||||
}
|
||||
|
||||
void LogRed4ext(std::string_view aMessage)
|
||||
@@ -149,9 +172,15 @@ void LogRed4ext(std::string_view aMessage)
|
||||
|
||||
void LogHookCall(const char* aName, uint32_t aCount, void* aThis, void* a2, void* a3, void* a4)
|
||||
{
|
||||
const auto imageBase = reinterpret_cast<uintptr_t>(GetModuleHandleW(nullptr));
|
||||
const auto ret = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
|
||||
std::ostringstream line;
|
||||
line << "hook " << aName << " call=" << aCount << " this=" << aThis << " a2=" << a2 << " a3=" << a3
|
||||
<< " a4=" << a4;
|
||||
if (ret && imageBase && ret >= imageBase)
|
||||
{
|
||||
line << " ret_rva=0x" << std::hex << (ret - imageBase) << std::dec;
|
||||
}
|
||||
LogRed4ext(line.str());
|
||||
}
|
||||
|
||||
@@ -340,6 +369,62 @@ void DetourTrafficSystemPathfinding(void* aThis, void* a2, void* a3, void* a4)
|
||||
}
|
||||
}
|
||||
|
||||
void DetourStopPathfindingA(void* aThis, void* a2, void* a3, void* a4)
|
||||
{
|
||||
if (gStopPathfindingALogCount < 32)
|
||||
{
|
||||
LogHookCall("StopPathfindingA", gStopPathfindingALogCount, aThis, a2, a3, a4);
|
||||
++gStopPathfindingALogCount;
|
||||
}
|
||||
|
||||
if (gOriginalStopPathfindingA)
|
||||
{
|
||||
gOriginalStopPathfindingA(aThis, a2, a3, a4);
|
||||
}
|
||||
}
|
||||
|
||||
void DetourStopPathfindingB(void* aThis, void* a2, void* a3, void* a4)
|
||||
{
|
||||
if (gStopPathfindingBLogCount < 32)
|
||||
{
|
||||
LogHookCall("StopPathfindingB", gStopPathfindingBLogCount, aThis, a2, a3, a4);
|
||||
++gStopPathfindingBLogCount;
|
||||
}
|
||||
|
||||
if (gOriginalStopPathfindingB)
|
||||
{
|
||||
gOriginalStopPathfindingB(aThis, a2, a3, a4);
|
||||
}
|
||||
}
|
||||
|
||||
void DetourStartPathfindingA(void* aThis, void* a2, void* a3, void* a4)
|
||||
{
|
||||
if (gStartPathfindingALogCount < 32)
|
||||
{
|
||||
LogHookCall("StartPathfindingA", gStartPathfindingALogCount, aThis, a2, a3, a4);
|
||||
++gStartPathfindingALogCount;
|
||||
}
|
||||
|
||||
if (gOriginalStartPathfindingA)
|
||||
{
|
||||
gOriginalStartPathfindingA(aThis, a2, a3, a4);
|
||||
}
|
||||
}
|
||||
|
||||
void DetourStartPathfindingB(void* aThis, void* a2, void* a3, void* a4)
|
||||
{
|
||||
if (gStartPathfindingBLogCount < 32)
|
||||
{
|
||||
LogHookCall("StartPathfindingB", gStartPathfindingBLogCount, aThis, a2, a3, a4);
|
||||
++gStartPathfindingBLogCount;
|
||||
}
|
||||
|
||||
if (gOriginalStartPathfindingB)
|
||||
{
|
||||
gOriginalStartPathfindingB(aThis, a2, a3, a4);
|
||||
}
|
||||
}
|
||||
|
||||
void AttachProbeHook(const char* aName, uintptr_t aRva, void* aDetour, void** aOriginal)
|
||||
{
|
||||
if (!gSdk || !gSdk->hooking || !gSdk->hooking->Attach)
|
||||
@@ -414,6 +499,12 @@ BOOL APIENTRY DllMain(HMODULE aModule, DWORD aReason, LPVOID)
|
||||
if (aReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
gModule = aModule;
|
||||
LARGE_INTEGER frequency{};
|
||||
LARGE_INTEGER counter{};
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
QueryPerformanceCounter(&counter);
|
||||
gLogFrequency = static_cast<uint64_t>(frequency.QuadPart);
|
||||
gLogStartTick = static_cast<uint64_t>(counter.QuadPart);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -443,12 +534,24 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4e
|
||||
AttachProbeHook("TrafficSystem_Pathfinding", kTrafficSystemPathfindingRva,
|
||||
reinterpret_cast<void*>(&DetourTrafficSystemPathfinding),
|
||||
reinterpret_cast<void**>(&gOriginalTrafficSystemPathfinding));
|
||||
AttachProbeHook("StopPathfindingA", kStopPathfindingA, reinterpret_cast<void*>(&DetourStopPathfindingA),
|
||||
reinterpret_cast<void**>(&gOriginalStopPathfindingA));
|
||||
AttachProbeHook("StopPathfindingB", kStopPathfindingB, reinterpret_cast<void*>(&DetourStopPathfindingB),
|
||||
reinterpret_cast<void**>(&gOriginalStopPathfindingB));
|
||||
AttachProbeHook("StartPathfindingA", kStartPathfindingA, reinterpret_cast<void*>(&DetourStartPathfindingA),
|
||||
reinterpret_cast<void**>(&gOriginalStartPathfindingA));
|
||||
AttachProbeHook("StartPathfindingB", kStartPathfindingB, reinterpret_cast<void*>(&DetourStartPathfindingB),
|
||||
reinterpret_cast<void**>(&gOriginalStartPathfindingB));
|
||||
}
|
||||
|
||||
if (aReason == RED4ext::v1::EMainReason::Unload)
|
||||
{
|
||||
DetachProbeHook("GPSSystem/Tick", kGpsSystemTickRva);
|
||||
DetachProbeHook("TrafficSystem_Pathfinding", kTrafficSystemPathfindingRva);
|
||||
DetachProbeHook("StopPathfindingA", kStopPathfindingA);
|
||||
DetachProbeHook("StopPathfindingB", kStopPathfindingB);
|
||||
DetachProbeHook("StartPathfindingA", kStartPathfindingA);
|
||||
DetachProbeHook("StartPathfindingB", kStartPathfindingB);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user