#pragma once //----------------------------------------------------------------------------- // Forward declarations //----------------------------------------------------------------------------- class CEngine; /////////////////////////////////////////////////////////////////////////////// extern CEngine* g_pEngine; enum class EngineState_t : int { DLL_INACTIVE = 0x0, DLL_ACTIVE = 0x1, DLL_CLOSE = 0x2, DLL_RESTART = 0x3, DLL_PAUSED = 0x4, }; enum class EngineDllQuitting_t : int { QUIT_NOTQUITTING = 0x0, QUIT_TODESKTOP = 0x1, QUIT_RESTART = 0x2, }; // TODO: Check if all indexes match up between seasons. If not patternscan them. class CEngine { public: bool Load(bool dedicated, const char* rootDir); void Unload(); void SetNextState(EngineState_t iNextState); EngineState_t GetState(); void Frame(); float GetFrameTime(); float GetPreviousTime(); void SetQuitting(EngineDllQuitting_t quitDllState); // __m128 __fastcall GetCurTime() // Last functions in class table. // sub_1401FE2A0 // sub_1401FE2B0 // sub_1401FE3B0 #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) MEMBER_AT_OFFSET(EngineState_t, m_nDLLState, 0x8); MEMBER_AT_OFFSET(EngineState_t, m_nNextDLLState, 0xC); MEMBER_AT_OFFSET(std::int64_t, m_flCurrentTime, 0x10); MEMBER_AT_OFFSET(std::int64_t, m_flPreviousTime, 0x18); MEMBER_AT_OFFSET(int, m_flFrameTime, 0x20); #elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) // TODO: Verify offsets for other seasons. Should probably be the same as Season 2. MEMBER_AT_OFFSET(EngineState_t, m_nDLLState, 0x8); MEMBER_AT_OFFSET(EngineState_t, m_nNextDLLState, 0xC); MEMBER_AT_OFFSET(std::int64_t, m_flCurrentTime, 0x10); // They are 8 bytes for some reason but floats? Kinda confusing. MEMBER_AT_OFFSET(std::int64_t, m_flPreviousTime, 0x18); MEMBER_AT_OFFSET(float, m_flFrameTime, 0x20); #endif }; namespace { /* ==== CENGINE ======================================================================================================================================================= */ #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) // Verify for s0 and s1 static ADDRESS g_pEngineBuffer = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x8D\x0D\x00\x00\x00\x00\x74\x2A\x4C\x8B\x05\x00\x00\x00\x00", "xxx????xxxxx????").ResolveRelativeAddressSelf(0x3, 0x7); #elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) // Verify for s2 static ADDRESS g_pEngineBuffer = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x8D\x0D\x00\x00\x00\x00\x74\x2A\x4C\x8B\x05\x00\x00\x00\x00", "xxx????xxxxx????").ResolveRelativeAddressSelf(0x3, 0x7); #endif } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// class HEngine : public IDetour { virtual void debugp() { std::cout << "| VAR: g_pEngine : 0x" << std::hex << std::uppercase << g_pEngineBuffer.GetPtr() << std::setw(npad) << " |" << std::endl; } }; /////////////////////////////////////////////////////////////////////////////// REGISTER(HEngine);