diff --git a/r5dev/core/dllmain.cpp b/r5dev/core/dllmain.cpp index d5a5e455..b380b754 100644 --- a/r5dev/core/dllmain.cpp +++ b/r5dev/core/dllmain.cpp @@ -76,6 +76,11 @@ void Tier0_Init() g_pCmdLine->CreateCmdLine(GetCommandLineA()); g_CrashHandler->SetCrashCallback(&Crash_Callback); + + // This prevents the game from recreating it, + // see 'CCommandLine::StaticCreateCmdLine' for + // more information. + g_bCommandLineCreated = true; } void SDK_Init() diff --git a/r5dev/tier0/commandline.cpp b/r5dev/tier0/commandline.cpp index 1c7091a0..3fd09577 100644 --- a/r5dev/tier0/commandline.cpp +++ b/r5dev/tier0/commandline.cpp @@ -5,6 +5,25 @@ //=============================================================================// #include "tier0/commandline.h" +bool g_bCommandLineCreated = false; + +//----------------------------------------------------------------------------- +// Purpose: Create a command line from the passed in string +// Note that if you pass in a @filename, then the routine will read settings +// from a file instead of the command line +//----------------------------------------------------------------------------- +void CCommandLine::StaticCreateCmdLine(CCommandLine* thisptr, const char* pszCommandLine) +{ + // The SDK creates the cmdline instead, when loaded. We hook this + // function, and skip the actual creation of subsequent calls. + // This is required as otherwise our own appended parameters will + // get lost when the game recreates it in 'LauncherMain'. + if (!g_bCommandLineCreated) + { + v_CCommandLine__CreateCmdLine(thisptr, pszCommandLine); + } +} + //----------------------------------------------------------------------------- // Purpose: parses a text file and appends its parameters/values //----------------------------------------------------------------------------- @@ -60,7 +79,7 @@ void CCommandLine::AppendParametersFromFile(const char* const pszConfig) pArgValue = pArg; } - CommandLine()->AppendParm(szTextBuf, pArgValue); + AppendParm(szTextBuf, pArgValue); } fclose(pFile); @@ -68,3 +87,14 @@ void CCommandLine::AppendParametersFromFile(const char* const pszConfig) /////////////////////////////////////////////////////////////////////////////// CCommandLine* g_pCmdLine = nullptr; + + +void VCommandLine::Attach() const +{ + DetourAttach(&v_CCommandLine__CreateCmdLine, &CCommandLine::StaticCreateCmdLine); +} + +void VCommandLine::Detach() const +{ + DetourDetach(&v_CCommandLine__CreateCmdLine, &CCommandLine::StaticCreateCmdLine); +} \ No newline at end of file diff --git a/r5dev/tier0/commandline.h b/r5dev/tier0/commandline.h index e7061c76..ff905d52 100644 --- a/r5dev/tier0/commandline.h +++ b/r5dev/tier0/commandline.h @@ -4,6 +4,7 @@ class CCommandLine : public ICommandLine // VTABLE @0x141369C78 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM { public: + static void StaticCreateCmdLine(CCommandLine* thisptr, const char* pszCommandLine); void AppendParametersFromFile(const char* const pszConfig); private: @@ -19,6 +20,7 @@ private: char* m_ppParms[MAX_PARAMETERS]; }; +extern bool g_bCommandLineCreated; extern CCommandLine* g_pCmdLine; //----------------------------------------------------------------------------- // Instance singleton and expose interface to rest of code @@ -28,21 +30,24 @@ inline CCommandLine* CommandLine(void) return g_pCmdLine; } +inline CMemory p_CCommandLine__CreateCmdLine; +inline auto v_CCommandLine__CreateCmdLine = p_CCommandLine__CreateCmdLine.RCast(); + /////////////////////////////////////////////////////////////////////////////// class VCommandLine : public IDetour { virtual void GetAdr(void) const { - LogVarAdr("g_pCmdLine", reinterpret_cast(g_pCmdLine)); + LogFunAdr("CCommandLine::CreateCmdLine", p_CCommandLine__CreateCmdLine.GetPtr()); } - virtual void GetFun(void) const { } - virtual void GetVar(void) const + virtual void GetFun(void) const { - g_pCmdLine = g_GameDll.FindPatternSIMD("40 55 48 83 EC 20 48 8D 6C 24 ?? 48 89 5D 10 49 C7 C0 ?? ?? ?? ??") - .FindPatternSelf("48 8D 0D", CMemory::Direction::DOWN, 250).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + p_CCommandLine__CreateCmdLine = g_GameDll.FindPatternSIMD("48 89 54 24 ?? 48 89 4C 24 ?? 53 41 55 B8 ?? ?? ?? ??"); + v_CCommandLine__CreateCmdLine = p_CCommandLine__CreateCmdLine.RCast(); } + virtual void GetVar(void) const { } virtual void GetCon(void) const { } - virtual void Attach(void) const { } - virtual void Detach(void) const { } + virtual void Attach(void) const; + virtual void Detach(void) const; }; ///////////////////////////////////////////////////////////////////////////////