diff --git a/red4ext/EdgeWeightGPS/src/Main.cpp b/red4ext/EdgeWeightGPS/src/Main.cpp index b4f3b67..8a92116 100644 --- a/red4ext/EdgeWeightGPS/src/Main.cpp +++ b/red4ext/EdgeWeightGPS/src/Main.cpp @@ -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((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(GetModuleHandleW(nullptr)); + const auto ret = reinterpret_cast(__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(frequency.QuadPart); + gLogStartTick = static_cast(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(&DetourTrafficSystemPathfinding), reinterpret_cast(&gOriginalTrafficSystemPathfinding)); + AttachProbeHook("StopPathfindingA", kStopPathfindingA, reinterpret_cast(&DetourStopPathfindingA), + reinterpret_cast(&gOriginalStopPathfindingA)); + AttachProbeHook("StopPathfindingB", kStopPathfindingB, reinterpret_cast(&DetourStopPathfindingB), + reinterpret_cast(&gOriginalStopPathfindingB)); + AttachProbeHook("StartPathfindingA", kStartPathfindingA, reinterpret_cast(&DetourStartPathfindingA), + reinterpret_cast(&gOriginalStartPathfindingA)); + AttachProbeHook("StartPathfindingB", kStartPathfindingB, reinterpret_cast(&DetourStartPathfindingB), + reinterpret_cast(&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;