Probe pathfinding start stop wrappers
This commit is contained in:
@@ -92,6 +92,10 @@ namespace
|
|||||||
constexpr uint32_t kGameStateRunning = 2;
|
constexpr uint32_t kGameStateRunning = 2;
|
||||||
constexpr uintptr_t kGpsSystemTickRva = 0x0E6B62C;
|
constexpr uintptr_t kGpsSystemTickRva = 0x0E6B62C;
|
||||||
constexpr uintptr_t kTrafficSystemPathfindingRva = 0x0AD1234;
|
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;
|
HMODULE gModule = nullptr;
|
||||||
std::mutex gLogMutex;
|
std::mutex gLogMutex;
|
||||||
@@ -101,10 +105,20 @@ uint32_t gUpdateLogCount = 0;
|
|||||||
bool gScannedExecutable = false;
|
bool gScannedExecutable = false;
|
||||||
uint32_t gGpsTickLogCount = 0;
|
uint32_t gGpsTickLogCount = 0;
|
||||||
uint32_t gTrafficPathfindingLogCount = 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);
|
using ProbeFunc = void (*)(void* aThis, void* a2, void* a3, void* a4);
|
||||||
ProbeFunc gOriginalGpsSystemTick = nullptr;
|
ProbeFunc gOriginalGpsSystemTick = nullptr;
|
||||||
ProbeFunc gOriginalTrafficSystemPathfinding = nullptr;
|
ProbeFunc gOriginalTrafficSystemPathfinding = nullptr;
|
||||||
|
ProbeFunc gOriginalStopPathfindingA = nullptr;
|
||||||
|
ProbeFunc gOriginalStopPathfindingB = nullptr;
|
||||||
|
ProbeFunc gOriginalStartPathfindingA = nullptr;
|
||||||
|
ProbeFunc gOriginalStartPathfindingB = nullptr;
|
||||||
|
|
||||||
std::filesystem::path GetLogPath()
|
std::filesystem::path GetLogPath()
|
||||||
{
|
{
|
||||||
@@ -133,7 +147,16 @@ void Log(std::string_view aMessage)
|
|||||||
return;
|
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)
|
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)
|
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;
|
std::ostringstream line;
|
||||||
line << "hook " << aName << " call=" << aCount << " this=" << aThis << " a2=" << a2 << " a3=" << a3
|
line << "hook " << aName << " call=" << aCount << " this=" << aThis << " a2=" << a2 << " a3=" << a3
|
||||||
<< " a4=" << a4;
|
<< " a4=" << a4;
|
||||||
|
if (ret && imageBase && ret >= imageBase)
|
||||||
|
{
|
||||||
|
line << " ret_rva=0x" << std::hex << (ret - imageBase) << std::dec;
|
||||||
|
}
|
||||||
LogRed4ext(line.str());
|
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)
|
void AttachProbeHook(const char* aName, uintptr_t aRva, void* aDetour, void** aOriginal)
|
||||||
{
|
{
|
||||||
if (!gSdk || !gSdk->hooking || !gSdk->hooking->Attach)
|
if (!gSdk || !gSdk->hooking || !gSdk->hooking->Attach)
|
||||||
@@ -414,6 +499,12 @@ BOOL APIENTRY DllMain(HMODULE aModule, DWORD aReason, LPVOID)
|
|||||||
if (aReason == DLL_PROCESS_ATTACH)
|
if (aReason == DLL_PROCESS_ATTACH)
|
||||||
{
|
{
|
||||||
gModule = aModule;
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -443,12 +534,24 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4e
|
|||||||
AttachProbeHook("TrafficSystem_Pathfinding", kTrafficSystemPathfindingRva,
|
AttachProbeHook("TrafficSystem_Pathfinding", kTrafficSystemPathfindingRva,
|
||||||
reinterpret_cast<void*>(&DetourTrafficSystemPathfinding),
|
reinterpret_cast<void*>(&DetourTrafficSystemPathfinding),
|
||||||
reinterpret_cast<void**>(&gOriginalTrafficSystemPathfinding));
|
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)
|
if (aReason == RED4ext::v1::EMainReason::Unload)
|
||||||
{
|
{
|
||||||
DetachProbeHook("GPSSystem/Tick", kGpsSystemTickRva);
|
DetachProbeHook("GPSSystem/Tick", kGpsSystemTickRva);
|
||||||
DetachProbeHook("TrafficSystem_Pathfinding", kTrafficSystemPathfindingRva);
|
DetachProbeHook("TrafficSystem_Pathfinding", kTrafficSystemPathfindingRva);
|
||||||
|
DetachProbeHook("StopPathfindingA", kStopPathfindingA);
|
||||||
|
DetachProbeHook("StopPathfindingB", kStopPathfindingB);
|
||||||
|
DetachProbeHook("StartPathfindingA", kStartPathfindingA);
|
||||||
|
DetachProbeHook("StartPathfindingB", kStartPathfindingB);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user