From 4fb1ba6912bc21d0de251ef6cc546bebf87d594d Mon Sep 17 00:00:00 2001 From: Jacob Babor Date: Fri, 19 Jun 2026 21:56:58 -0500 Subject: [PATCH] Log RED4ext lifecycle callbacks --- red4ext/EdgeWeightGPS/src/Main.cpp | 125 ++++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 1 deletion(-) diff --git a/red4ext/EdgeWeightGPS/src/Main.cpp b/red4ext/EdgeWeightGPS/src/Main.cpp index bfddd7f..cf123ca 100644 --- a/red4ext/EdgeWeightGPS/src/Main.cpp +++ b/red4ext/EdgeWeightGPS/src/Main.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -18,13 +19,74 @@ namespace RED4ext::v1 { +struct Logger +{ + void (*Trace)(PluginHandle aHandle, const char* aMessage); + void (*TraceF)(PluginHandle aHandle, const char* aFormat, ...); + void (*TraceW)(PluginHandle aHandle, const wchar_t* aMessage); + void (*TraceWF)(PluginHandle aHandle, const wchar_t* aFormat, ...); + void (*Debug)(PluginHandle aHandle, const char* aMessage); + void (*DebugF)(PluginHandle aHandle, const char* aFormat, ...); + void (*DebugW)(PluginHandle aHandle, const wchar_t* aMessage); + void (*DebugWF)(PluginHandle aHandle, const wchar_t* aFormat, ...); + void (*Info)(PluginHandle aHandle, const char* aMessage); + void (*InfoF)(PluginHandle aHandle, const char* aFormat, ...); + void (*InfoW)(PluginHandle aHandle, const wchar_t* aMessage); + void (*InfoWF)(PluginHandle aHandle, const wchar_t* aFormat, ...); + void (*Warn)(PluginHandle aHandle, const char* aMessage); + void (*WarnF)(PluginHandle aHandle, const char* aFormat, ...); + void (*WarnW)(PluginHandle aHandle, const wchar_t* aMessage); + void (*WarnWF)(PluginHandle aHandle, const wchar_t* aFormat, ...); + void (*Error)(PluginHandle aHandle, const char* aMessage); + void (*ErrorF)(PluginHandle aHandle, const char* aFormat, ...); + void (*ErrorW)(PluginHandle aHandle, const wchar_t* aMessage); + void (*ErrorWF)(PluginHandle aHandle, const wchar_t* aFormat, ...); + void (*Critical)(PluginHandle aHandle, const char* aMessage); + void (*CriticalF)(PluginHandle aHandle, const char* aFormat, ...); + void (*CriticalW)(PluginHandle aHandle, const wchar_t* aMessage); + void (*CriticalWF)(PluginHandle aHandle, const wchar_t* aFormat, ...); +}; + +struct GameState +{ + bool (*OnEnter)(void* aApp); + bool (*OnUpdate)(void* aApp); + bool (*OnExit)(void* aApp); +}; + +struct GameStates +{ + bool (*Add)(PluginHandle aHandle, uint32_t aType, GameState* aState); +}; + +struct Scripts +{ + bool (*Add)(PluginHandle aHandle, const wchar_t* aPath); + bool (*RegisterNeverRefType)(const char* aType); + bool (*RegisterMixedRefType)(const char* aType); +}; + struct Sdk; + +struct Sdk +{ + SemVer* runtime; + Logger* logger; + void* hooking; + GameStates* gameStates; + Scripts* scripts; +}; } namespace { +constexpr uint32_t kGameStateRunning = 2; + HMODULE gModule = nullptr; std::mutex gLogMutex; +RED4ext::v1::PluginHandle gHandle = nullptr; +const RED4ext::v1::Sdk* gSdk = nullptr; +uint32_t gUpdateLogCount = 0; std::filesystem::path GetLogPath() { @@ -56,6 +118,17 @@ void Log(std::string_view aMessage) out << std::put_time(&localTime, "%Y-%m-%d %H:%M:%S") << " " << aMessage << "\n"; } +void LogRed4ext(std::string_view aMessage) +{ + Log(aMessage); + + if (gSdk && gSdk->logger && gSdk->logger->Info && gHandle) + { + std::string text(aMessage); + gSdk->logger->Info(gHandle, text.c_str()); + } +} + const char* ReasonToString(RED4ext::v1::EMainReason aReason) { switch (aReason) @@ -68,6 +141,41 @@ const char* ReasonToString(RED4ext::v1::EMainReason aReason) return "Unknown"; } + +bool OnRunningEnter(void* aApp) +{ + std::ostringstream line; + line << "GameState Running OnEnter app=" << aApp; + LogRed4ext(line.str()); + return true; +} + +bool OnRunningUpdate(void* aApp) +{ + if (gUpdateLogCount < 5) + { + std::ostringstream line; + line << "GameState Running OnUpdate app=" << aApp << " count=" << gUpdateLogCount; + LogRed4ext(line.str()); + ++gUpdateLogCount; + } + + return false; +} + +bool OnRunningExit(void* aApp) +{ + std::ostringstream line; + line << "GameState Running OnExit app=" << aApp; + LogRed4ext(line.str()); + return true; +} + +RED4ext::v1::GameState gRunningState{ + .OnEnter = OnRunningEnter, + .OnUpdate = OnRunningUpdate, + .OnExit = OnRunningExit, +}; } BOOL APIENTRY DllMain(HMODULE aModule, DWORD aReason, LPVOID) @@ -82,9 +190,24 @@ BOOL APIENTRY DllMain(HMODULE aModule, DWORD aReason, LPVOID) RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4ext::v1::EMainReason aReason, const RED4ext::v1::Sdk* aSdk) { + gHandle = aHandle; + gSdk = aSdk; + std::ostringstream line; line << "EdgeWeightGPS Main reason=" << ReasonToString(aReason) << " handle=" << aHandle << " sdk=" << aSdk; - Log(line.str()); + if (aSdk && aSdk->runtime) + { + line << " runtime=" << static_cast(aSdk->runtime->major) << "." << aSdk->runtime->minor << "." + << aSdk->runtime->patch; + } + LogRed4ext(line.str()); + + if (aReason == RED4ext::v1::EMainReason::Load && aSdk && aSdk->gameStates && aSdk->gameStates->Add) + { + const auto added = aSdk->gameStates->Add(aHandle, kGameStateRunning, &gRunningState); + LogRed4ext(added ? "registered Running game-state callbacks" : "failed to register Running game-state callbacks"); + } + return true; }