Huge engine/host commit.

* Rebuild CModGroupApp::Main, did not include the dedicated routine with the empty class global.
* Using a template function now for virtual function calls
* Implemented most of the CEngine class and grabbing its global var now.
* Using local CEngine now in FrameUpdate
* Implemented EngineParms_t fully and grabbing its global var.
* Added macro for adding class member variables at offsets.

A lot of comments added regarding what needs to be done for this commit.

* Check other season compability, wasn't able to do that due to not having access to said binaries at the moment.
* Fix sdklauncher to use widestrings to fix the bug with other languages in path
This commit is contained in:
IcePixelx 2022-01-23 18:26:48 +01:00
parent a1f96797c0
commit f43c5da8ae
21 changed files with 380 additions and 93 deletions

View File

@ -25,17 +25,16 @@ enum class ClientFrameStage_t : int
class CHLClient
{
public:
/* Might wanna implement my callvfunc wrapper I sent the other day here? - Pix*/
void FrameStageNotify(ClientFrameStage_t curStage) // @0x1405C0740 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
{
using OriginalFn = void(__thiscall*)(CHLClient*, ClientFrameStage_t);
(*reinterpret_cast<OriginalFn**>(this))[58](this, curStage); /*48 83 EC 28 89 15 ?? ?? ?? ??*/
static int index = 58;
CallVFunc<void>(index, this, curStage); /*48 83 EC 28 89 15 ?? ?? ?? ??*/
}
void* /* CUserCmd* */ GetUserCmd(int sequenceNumber) // @0x1405BB020 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
{
using OriginalFn = void(__thiscall*)(CHLClient*, int);
(*reinterpret_cast<OriginalFn**>(this))[28](this, sequenceNumber); /*48 83 EC 28 48 8B 05 ? ? ? ? 48 8D 0D ? ? ? ? 44 8B C2*/
static int index = 28;
return CallVFunc<void*>(index, this, sequenceNumber); /*48 83 EC 28 48 8B 05 ? ? ? ? 48 8D 0D ? ? ? ? 44 8B C2*/
}
};

View File

@ -73,3 +73,17 @@ namespace
MODULE g_mRadAudioSystemDll = MODULE("mileswin64.dll");
}
#endif // !SDKLAUNCHER
// Since we wanna be able to use it anywhere I thought this might be the best location for it. Since it gets inlined anyway.
#define MEMBER_AT_OFFSET(varType, varName, offset) \
varType& varName() \
{ \
static int _##varName = offset; \
return *(varType*)((std::uintptr_t)this + _##varName); \
}
template <typename ReturnType, typename ...Args>
ReturnType CallVFunc(int index, void* thisPtr, Args... args)
{
return (*reinterpret_cast<ReturnType(__fastcall***)(void*, Args...)>(thisPtr))[index](thisPtr, args...);
}

View File

@ -186,8 +186,10 @@
<ClInclude Include="engine\host_cmd.h" />
<ClInclude Include="engine\host_state.h" />
<ClInclude Include="engine\net_chan.h" />
<ClInclude Include="engine\sv_main.h" />
<ClInclude Include="engine\sys_dll.h" />
<ClInclude Include="engine\sys_dll2.h" />
<ClInclude Include="engine\sys_engine.h" />
<ClInclude Include="engine\sys_utils.h" />
<ClInclude Include="launcher\IApplication.h" />
<ClInclude Include="mathlib\adler32.h" />
@ -375,8 +377,10 @@
<ClCompile Include="engine\host_cmd.cpp" />
<ClCompile Include="engine\host_state.cpp" />
<ClCompile Include="engine\net_chan.cpp" />
<ClCompile Include="engine\sv_main.cpp" />
<ClCompile Include="engine\sys_dll.cpp" />
<ClCompile Include="engine\sys_dll2.cpp" />
<ClCompile Include="engine\sys_engine.cpp" />
<ClCompile Include="engine\sys_utils.cpp" />
<ClCompile Include="launcher\IApplication.cpp" />
<ClCompile Include="mathlib\adler32.cpp" />

View File

@ -672,6 +672,12 @@
<ClInclude Include="core\termutil.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="engine\sys_engine.h">
<Filter>sdk\engine</Filter>
</ClInclude>
<ClInclude Include="engine\sv_main.h">
<Filter>sdk\engine</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="client\IVEngineClient.cpp">
@ -887,6 +893,12 @@
<ClCompile Include="vpc\interfaces.cpp">
<Filter>sdk\vpc</Filter>
</ClCompile>
<ClCompile Include="engine\sys_engine.cpp">
<Filter>sdk\engine</Filter>
</ClCompile>
<ClCompile Include="engine\sv_main.cpp">
<Filter>sdk\engine</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="r5dev.def" />

View File

@ -1,4 +1,7 @@
#include "core/stdafx.h"
#include "engine/host_cmd.h"
///////////////////////////////////////////////////////////////////////////////
EngineParms_t* g_pEngineParms = reinterpret_cast<EngineParms_t*>(g_pEngineParmsBuffer.GetPtr());
// TODO: this file is for when dedicated is stable, to move hardcoded patches in Host_Init for a more dynamic solution.

View File

@ -1,5 +1,15 @@
#pragma once
struct EngineParms_t
{
char* baseDirectory;
char* modName;
char* rootGameName;
unsigned int memSizeAvailable;
};
extern EngineParms_t* g_pEngineParms;
namespace
{
/* ==== HOST ============================================================================================================================================================ */
@ -12,6 +22,9 @@ namespace
#endif
ADDRESS p_malloc_internal = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\xE9\x00\x00\x00\x00\xCC\xCC\xCC\x40\x53\x48\x83\xEC\x20\x48\x8D\x05\x00\x00\x00\x00", "x????xxxxxxxxxxxx????");
void* (*malloc_internal)(void* pPool, int64_t size) = (void* (*)(void*, int64_t))p_malloc_internal.GetPtr(); /*E9 ? ? ? ? CC CC CC 40 53 48 83 EC 20 48 8D 05 ? ? ? ?*/
// TODO: Verify for other seasons beside 3.
static ADDRESS g_pEngineParmsBuffer = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x4C\x8B\x05\x00\x00\x00\x00\xB2\x01", "xxx????xx").ResolveRelativeAddressSelf(0x3, 0x7);
}
namespace
@ -30,6 +43,7 @@ class HHostCmd : public IDetour
{
std::cout << "| FUN: Host_Init : 0x" << std::hex << std::uppercase << p_Host_Init.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| FUN: malloc_internal : 0x" << std::hex << std::uppercase << p_malloc_internal.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| VAR: g_pEngineParms : 0x" << std::hex << std::uppercase << g_pEngineParmsBuffer.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| VAR: g_pMallocPool : 0x" << std::hex << std::uppercase << g_pMallocPool.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "+----------------------------------------------------------------+" << std::endl;
}

View File

@ -8,6 +8,7 @@
#include "networksystem/r5net.h"
#include "squirrel/sqinit.h"
#include "public/include/bansystem.h"
#include "engine/sys_engine.h"
//-----------------------------------------------------------------------------
// Purpose: Send keep alive request to Pylon Master Server.
@ -125,7 +126,6 @@ void HCHostState_FrameUpdate(void* rcx, void* rdx, float time)
static auto Host_ChangelevelFn = ADDRESS(0x1402387B0).RCast<void(*)(bool, const char*, const char*)>();
static auto CL_EndMovieFn = ADDRESS(0x1402C03D0).RCast<void(*)()>();
static auto SendOfflineRequestToStryderFn = ADDRESS(0x14033D380).RCast<void(*)()>();
static auto CEngine = ADDRESS(0X141741BA0).RCast<void*>();
static bool bInitialized = false;
if (!bInitialized)
@ -331,7 +331,7 @@ void HCHostState_FrameUpdate(void* rcx, void* rdx, float time)
DevMsg(eDLL_T::ENGINE, "CHostState::FrameUpdate | CASE:HS_RESTART | Restarting client\n");
CL_EndMovieFn();
SendOfflineRequestToStryderFn(); // We have hostnames nulled anyway.
*(std::int32_t*)((std::uintptr_t)CEngine + 0xC) = 3; //g_CEngine.vtable->SetNextState(&g_CEngine, DLL_RESTART);
g_pEngine->SetNextState(EngineState_t::DLL_RESTART);
break;
}
case HostStates_t::HS_SHUTDOWN:
@ -339,7 +339,7 @@ void HCHostState_FrameUpdate(void* rcx, void* rdx, float time)
DevMsg(eDLL_T::ENGINE, "CHostState::FrameUpdate | CASE:HS_SHUTDOWN | Shutdown client\n");
CL_EndMovieFn();
SendOfflineRequestToStryderFn(); // We have hostnames nulled anyway.
*(std::int32_t*)((std::uintptr_t)CEngine + 0xC) = 2; //g_CEngine.vtable->SetNextState(&g_CEngine, DLL_CLOSE);
g_pEngine->SetNextState(EngineState_t::DLL_CLOSE);
break;
}
default:

4
r5dev/engine/sv_main.cpp Normal file
View File

@ -0,0 +1,4 @@
#include "core/stdafx.h"
#include "engine/sv_main.h"
///////////////////////////////////////////////////////////////////////////////

26
r5dev/engine/sv_main.h Normal file
View File

@ -0,0 +1,26 @@
#pragma once
///////////////////////////////////////////////////////////////////////////////
namespace
{
/* ==== SV_MAIN ======================================================================================================================================================= */
ADDRESS p_SV_ShutdownGameDLL = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x28\x80\x3D\x00\x00\x00\x00\x00\x0F\x84\x00\x00\x00\x00\x48\x8B\x0D\x00\x00\x00\x00\x48\x89\x5C\x24\x00", "xxxxxx?????xx????xxx????xxxx?");
void (*SV_ShutdownGameDLL)() = (void(*)())p_SV_ShutdownGameDLL.GetPtr(); /*48 83 EC 28 80 3D ? ? ? ? ? 0F 84 ? ? ? ? 48 8B 0D ? ? ? ? 48 89 5C 24 ?*/
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
class HSV_MAIN : public IDetour
{
virtual void debugp()
{
std::cout << "| FUN: SV_ShutdownGameDLL : 0x" << std::hex << std::uppercase << p_SV_ShutdownGameDLL.GetPtr() << std::setw(npad) << " |" << std::endl;
}
};
///////////////////////////////////////////////////////////////////////////////
REGISTER(HSV_MAIN);

View File

@ -3,6 +3,7 @@
class CEngineAPI
{
public:
// TODO [ AMOS ]:
};
@ -10,6 +11,10 @@ namespace
{
ADDRESS p_CEngineAPI_Connect = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x28\x48\x8B\x05\x00\x00\x00\x00\x48\x8D\x0D\x00\x00\x00\x00\x48\x85\xC0\x48\x89\x15", "xxxxxxx????xxx????xxxxxx");
bool (*CEngineAPI_Connect)(CEngineAPI* thisptr, CreateInterfaceFn factory) = (bool (*)(CEngineAPI*, CreateInterfaceFn))p_CEngineAPI_Connect.GetPtr(); /*48 83 EC 28 48 8B 05 ? ? ? ? 48 8D 0D ? ? ? ? 48 85 C0 48 89 15 ? ? ? ?*/
// TODO: Verify for other seasons beside 3.
ADDRESS p_CEngineAPI_MainLoop = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\xE8\x00\x00\x00\x00\x48\x8B\x15\x00\x00\x00\x00\x84\xC0\xB9\x00\x00\x00\x00", "x????xxx????xxx????").FollowNearCallSelf();
bool (*CEngineAPI_MainLoop)() = (bool(*)())p_CEngineAPI_MainLoop.GetPtr(); /*E8 ? ? ? ? 48 8B 15 ? ? ? ? 84 C0 B9 ? ? ? ?*/
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
ADDRESS p_PakFile_Init = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x44\x88\x44\x24\x00\x56\x57\x41\x54\x41\x56\x41\x57\x48\x83\xEC\x20", "xxxx?xxxx?xxxx?xxxxxxxxxxxx");
int (*PakFile_Init)(char* buffer, char* source, char vpk_file) = (int (*)(char*, char*, char))p_PakFile_Init.GetPtr(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 44 88 44 24 ?? 56 57 41 54 41 56 41 57 48 83 EC 20*/
@ -29,6 +34,7 @@ class HSys_Dll2 : public IDetour
virtual void debugp()
{
std::cout << "| FUN: CEngineAPI::Connect : 0x" << std::hex << std::uppercase << p_CEngineAPI_Connect.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| FUN: CEngineAPI::MainLoop : 0x" << std::hex << std::uppercase << p_CEngineAPI_MainLoop.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| FUN: PakFile_Init : 0x" << std::hex << std::uppercase << p_PakFile_Init.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| VAR: g_pMapVPKCache : 0x" << std::hex << std::uppercase << g_pMapVPKCache.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "+----------------------------------------------------------------+" << std::endl;

View File

@ -0,0 +1,5 @@
#include "core/stdafx.h"
#include "sys_engine.h"
///////////////////////////////////////////////////////////////////////////////
CEngine* g_pEngine = reinterpret_cast<CEngine*>(g_pEngineBuffer.GetPtr());

154
r5dev/engine/sys_engine.h Normal file
View File

@ -0,0 +1,154 @@
#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:
//-----------------------------------------------------------------------------
// Purpose: Start initializing the engine.
//-----------------------------------------------------------------------------
bool Load(bool dedicated, const char* rootDir)
{
static int index = 1;
return CallVFunc<bool>(index, this, dedicated, rootDir);
}
//-----------------------------------------------------------------------------
// Purpose: Start to shutdown the engine.
//-----------------------------------------------------------------------------
void Unload()
{
static int index = 2;
CallVFunc<void>(index, this);
}
//-----------------------------------------------------------------------------
// Purpose: Set the next dll engine state.
//-----------------------------------------------------------------------------
void SetNextState(EngineState_t iNextState)
{
// Rebuild function, vfunc index is 3 in season 3.
m_nNextDLLState() = iNextState;
}
//-----------------------------------------------------------------------------
// Purpose: Get the dll engine state.
//-----------------------------------------------------------------------------
EngineState_t GetState()
{
// Rebuild function, vfunc index is 4 in season 3.
return m_nDLLState();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Frame()
{
static int index = 5;
CallVFunc<void>(index, this);
}
//-----------------------------------------------------------------------------
// Purpose: Get engine frame time.
//-----------------------------------------------------------------------------
float GetFrameTime()
{
// Rebuild function, vfunc index is 6 in season 3.
return m_flFrameTime();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
float GetPreviousTime() // I'm not sure if this is right, should double check.
{
static int index = 7;
return CallVFunc<float>(index, this);
}
// Yes that is the function, I have no clue how to implement it at this moment so its gonna reside here for now. It's vfunc index 8.
//__m128 __fastcall CEngine::GetCurTime(CEngine *thisPtr)
//{
// return _mm_cvtpd_ps((__m128d)(unsigned __int64)thisPtr->m_flCurrentTime);
//}
//-----------------------------------------------------------------------------
// Purpose: Set dll state.
//-----------------------------------------------------------------------------
void SetQuitting(EngineDllQuitting_t quitDllState)
{
static int index = 9;
CallVFunc<void>(index, this, quitDllState);
}
// 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);

View File

@ -7,20 +7,20 @@ class CInputSystem
public:
void EnableInput(bool bEnabled)// @0x14039F100 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
{
using OriginalFn = void(__thiscall*)(CInputSystem*, bool);
(*reinterpret_cast<OriginalFn**>(this))[10](this, bEnabled);
static int index = 10;
CallVFunc<void>(index, this, bEnabled);
}
void EnableMessagePump(bool bEnabled) // @0x14039F110 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
{
using OriginalFn = void(__thiscall*)(CInputSystem*, bool);
(*reinterpret_cast<OriginalFn**>(this))[11](this, bEnabled);
static int index = 11;
CallVFunc<void>(index, this, bEnabled);
}
bool IsButtonDown(ButtonCode_t Button) // @0x1403A0140 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
{
using OriginalFn = bool(__thiscall*)(CInputSystem*, ButtonCode_t);
return (*reinterpret_cast<OriginalFn**>(this))[13](this, Button);
static int index = 13;
return CallVFunc<bool>(index, this, Button);
}
private:

View File

@ -2,14 +2,43 @@
#include "tier0/cvar.h"
#include "launcher/IApplication.h"
#include "ebisusdk/EbisuSDK.h"
#include "engine/sys_engine.h"
#include "engine/sys_dll2.h"
#include "engine/sv_main.h"
#include "engine/host_cmd.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void* HIApplication_Main(void* a1, void* a2)
int HIApplication_Main(CModAppSystemGroup* modAppSystemGroup)
{
HEbisuSDK_Init();
return IAppSystem_Main(a1, a2);
int nRunResult = 3; // RUN_OK
HEbisuSDK_Init(); // Not here in retail. We init EbisuSDK here though.
if (modAppSystemGroup->m_bIsServerOnly()) // This will never be true anyway but we implement it for the sake of it.
{
if (g_pEngine->Load(true, g_pEngineParms->baseDirectory))
{
// Below is vfunc call that is supposed to be used for real dedicated servers. The class instance is sadly stripped to some degree.
//(*(void(__fastcall**)(__int64))(*(_QWORD*)qword_14C119C10 + 72i64))(qword_14C119C10);// dedicated->RunServer
SV_ShutdownGameDLL();
}
}
else
{
g_pEngine->SetQuitting(EngineDllQuitting_t::QUIT_NOTQUITTING);
if (g_pEngine->Load(false, g_pEngineParms->baseDirectory))
{
if (CEngineAPI_MainLoop())
{
nRunResult = 4; // RUN_RESTART
}
g_pEngine->Unload();
SV_ShutdownGameDLL();
}
}
return nRunResult;
}
//-----------------------------------------------------------------------------

View File

@ -1,5 +1,15 @@
#pragma once
class CModAppSystemGroup
{
public:
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
MEMBER_AT_OFFSET(bool, m_bIsServerOnly, 0xA8);
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) // TODO: Verify offset in CModAppSystemGroup::Main for other seasons. Should probably be the same as Season 2.
MEMBER_AT_OFFSET(bool, m_bIsServerOnly, 0xA8);
#endif
};
namespace
{
/* ==== CAPPSYSTEMGROUP ================================================================================================================================================= */
@ -11,7 +21,7 @@ namespace
bool (*IAppSystem_Create)(void* a1) = (bool(*)(void*))p_IAppSystem_Create.GetPtr(); /*48 8B C4 57 41 54 41 55 41 56 41 57 48 83 EC 60 48 C7 40 ?? ?? ?? ?? ?? 48 89 58 08*/
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
ADDRESS p_IAppSystem_Main = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x48\x83\xEC\x20\x80\xB9\x00\x00\x00\x00\x00\xBB\x00\x00\x00\x00", "xxxxxxxx?????x????");
void* (*IAppSystem_Main)(void* a1, void* a2) = (void* (*)(void*, void*))p_IAppSystem_Main.GetPtr(); /*40 53 48 83 EC 20 80 B9 ?? ?? ?? ?? ?? BB ?? ?? ?? ??*/
int (*IAppSystem_Main)(void* modAppSystemGroup) = (int(*)(void*))p_IAppSystem_Main.GetPtr(); /*40 53 48 83 EC 20 80 B9 ?? ?? ?? ?? ?? BB ?? ?? ?? ??*/
ADDRESS p_IAppSystem_Create = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x8B\xC4\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8B\xEC\x48\x83\xEC\x60", "xxxxxxxxxxxxxxxxxxx");
bool (*IAppSystem_Create)(void* a1) = (bool(*)(void*))p_IAppSystem_Create.GetPtr(); /*48 8B C4 55 41 54 41 55 41 56 41 57 48 8B EC 48 83 EC 60*/
@ -19,7 +29,7 @@ namespace
}
///////////////////////////////////////////////////////////////////////////////
void* HIApplication_Main(void* a1, void* a2);
int HIApplication_Main(CModAppSystemGroup* modAppSystemGroup);
bool HIApplication_Create(void* a1);
void IApplication_Attach();

View File

@ -38,8 +38,10 @@
<ClCompile Include="engine\host_cmd.cpp" />
<ClCompile Include="engine\host_state.cpp" />
<ClCompile Include="engine\net_chan.cpp" />
<ClCompile Include="engine\sv_main.cpp" />
<ClCompile Include="engine\sys_dll.cpp" />
<ClCompile Include="engine\sys_dll2.cpp" />
<ClCompile Include="engine\sys_engine.cpp" />
<ClCompile Include="engine\sys_utils.cpp" />
<ClCompile Include="gameui\IConsole.cpp" />
<ClCompile Include="gameui\IBrowser.cpp" />
@ -233,8 +235,10 @@
<ClInclude Include="engine\host_cmd.h" />
<ClInclude Include="engine\host_state.h" />
<ClInclude Include="engine\net_chan.h" />
<ClInclude Include="engine\sv_main.h" />
<ClInclude Include="engine\sys_dll.h" />
<ClInclude Include="engine\sys_dll2.h" />
<ClInclude Include="engine\sys_engine.h" />
<ClInclude Include="engine\sys_utils.h" />
<ClInclude Include="gameui\IConsole.h" />
<ClInclude Include="gameui\IBrowser.h" />

View File

@ -411,6 +411,12 @@
<ClCompile Include="vpc\interfaces.cpp">
<Filter>sdk\vpc</Filter>
</ClCompile>
<ClCompile Include="engine\sv_main.cpp">
<Filter>sdk\engine</Filter>
</ClCompile>
<ClCompile Include="engine\sys_engine.cpp">
<Filter>sdk\engine</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="client\cdll_engine_int.h">
@ -1055,6 +1061,12 @@
<ClInclude Include="core\termutil.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="engine\sv_main.h">
<Filter>sdk\engine</Filter>
</ClInclude>
<ClInclude Include="engine\sys_engine.h">
<Filter>sdk\engine</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="r5dev.def" />

View File

@ -15,26 +15,26 @@
//-----------------------------------------------------------------------------
void CCommandLine::CreateCmdLine(const char* pszCommandline)
{
using OriginalFn = void(__thiscall*)(CCommandLine*, const char*);
(*reinterpret_cast<OriginalFn**>(this))[0](this, pszCommandline);
static int index = 0;
CallVFunc<void>(index, this, pszCommandline);
}
//-----------------------------------------------------------------------------
// purpose: creates a command line from the arguments passed in
// Purpose: creates a command line from the arguments passed in
//-----------------------------------------------------------------------------
void CCommandLine::CreateCmdLine(int argc, char** argv)
{
using OriginalFn = void(__thiscall*)(CCommandLine*, int, char**);
return (*reinterpret_cast<OriginalFn**>(this))[1](this, argc, argv);
static int index = 1;
CallVFunc<void>(index, this, argc, argv);
}
//-----------------------------------------------------------------------------
// purpose: allocates a pool for the command line [seems unused]
// Purpose: allocates a pool for the command line [seems unused]
//-----------------------------------------------------------------------------
void CCommandLine::CreatePool(void* pMem)
{
using OriginalFn = void(__thiscall*)(CCommandLine*, void*);
(*reinterpret_cast<OriginalFn**>(this))[2](this, pMem);
static int index = 2;
CallVFunc<void>(index, this, pMem);
}
//-----------------------------------------------------------------------------
@ -43,8 +43,8 @@ void CCommandLine::CreatePool(void* pMem)
//-----------------------------------------------------------------------------
const char* CCommandLine::GetCmdLine(void)
{
using OriginalFn = const char* (__thiscall*)(CCommandLine*);
return (*reinterpret_cast<OriginalFn**>(this))[3](this);
static int index = 3;
return CallVFunc<const char*>(index, this);
}
//-----------------------------------------------------------------------------
@ -55,18 +55,18 @@ const char* CCommandLine::GetCmdLine(void)
//-----------------------------------------------------------------------------
const char* CCommandLine::CheckParm(const char* psz, const char** ppszValue)
{
using OriginalFn = const char* (__thiscall*)(CCommandLine*, const char*, const char**);
return (*reinterpret_cast<OriginalFn**>(this))[4](this, psz, ppszValue);
static int index = 4;
return CallVFunc<const char*>(index, this, psz, ppszValue);
}
//-----------------------------------------------------------------------------
// Purpose: Remove specified string ( and any args attached to it ) from command line
// Input : *pszParm -
//-----------------------------------------------------------------------------
void CCommandLine::RemoveParm(void)
void CCommandLine::RemoveParm(const char* pszParm)
{
using OriginalFn = void(__thiscall*)(CCommandLine*);
return (*reinterpret_cast<OriginalFn**>(this))[5](this);
static int index = 5;
CallVFunc<void>(index, this, pszParm);
}
//-----------------------------------------------------------------------------
@ -76,8 +76,8 @@ void CCommandLine::RemoveParm(void)
//-----------------------------------------------------------------------------
void CCommandLine::AppendParm(const char* pszParm, const char* pszValues)
{
using OriginalFn = void(__thiscall*)(CCommandLine*, const char*, const char*);
return (*reinterpret_cast<OriginalFn**>(this))[6](this, pszParm, pszParm);
static int index = 6;
CallVFunc<void>(index, this, pszParm, pszValues);
}
//-----------------------------------------------------------------------------
@ -85,47 +85,47 @@ void CCommandLine::AppendParm(const char* pszParm, const char* pszValues)
//-----------------------------------------------------------------------------
const char* CCommandLine::ParmValue(const char* psz, const char* pDefaultVal)
{
using OriginalFn = const char* (__thiscall*)(CCommandLine*, const char*, const char*);
return (*reinterpret_cast<OriginalFn**>(this))[7](this, psz, pDefaultVal);
static int index = 7;
return CallVFunc<const char*>(index, this, psz, pDefaultVal);
}
int CCommandLine::ParmValue(const char* psz, int nDefaultVal)
{
using OriginalFn = int(__thiscall*)(CCommandLine*, const char*, int);
return (*reinterpret_cast<OriginalFn**>(this))[8](this, psz, nDefaultVal);
static int index = 8;
return CallVFunc<int>(index, this, psz, nDefaultVal);
}
float CCommandLine::ParmValue(const char* psz, float flDefaultVal)
{
using OriginalFn = float(__thiscall*)(CCommandLine*, const char*, float);
return (*reinterpret_cast<OriginalFn**>(this))[9](this, psz, flDefaultVal);
static int index = 9;
return CallVFunc<float>(index, this, psz, flDefaultVal);
}
//-----------------------------------------------------------------------------
// purpose: returns individual command line arguments
// Purpose: returns individual command line arguments
//-----------------------------------------------------------------------------
int CCommandLine::ParmCount(void)
{
using OriginalFn = int(__thiscall*)(CCommandLine*);
return (*reinterpret_cast<OriginalFn**>(this))[10](this);
static int index = 10;
return CallVFunc<int>(index, this);
}
int CCommandLine::FindParm(const char* psz)
{
using OriginalFn = int(__thiscall*)(CCommandLine*, const char*);
return (*reinterpret_cast<OriginalFn**>(this))[11](this, psz);
static int index = 11;
return CallVFunc<int>(index, this, psz);
}
const char* CCommandLine::GetParm(int nIndex)
{
using OriginalFn = const char* (__thiscall*)(CCommandLine*, int);
return (*reinterpret_cast<OriginalFn**>(this))[12](this, nIndex);
static int index = 12;
return CallVFunc<const char*>(index, this, nIndex);
}
void CCommandLine::SetParm(int nIndex, char const* pParm)
{
using OriginalFn = void(__thiscall*)(CCommandLine*, int, const char*);
return (*reinterpret_cast<OriginalFn**>(this))[13](this, nIndex, pParm);
static int index = 13;
CallVFunc<void>(index, this, nIndex, pParm);
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -8,7 +8,7 @@ public:
void CreatePool(void* pMem);
const char* GetCmdLine(void);
const char* CheckParm(const char* psz, const char** ppszValue = NULL);
void RemoveParm(void);
void RemoveParm(const char* pszParm);
void AppendParm(const char* pszParm, const char* pszValues);
const char* ParmValue(const char* psz, const char* pDefaultVal = NULL);
int ParmValue(const char* psz, int nDefaultVal);

View File

@ -61,8 +61,8 @@ ConVar* r5net_show_debug = new ConVar();
//-----------------------------------------------------------------------------
ConCommandBase* CCVar::FindCommandBase(const char* pszCommandName)
{
using OriginalFn = ConCommandBase * (__thiscall*)(CCVar*, const char*);
return (*reinterpret_cast<OriginalFn**>(this))[14](this, pszCommandName);
static int index = 14;
return CallVFunc<ConCommandBase*>(index, this, pszCommandName);
}
//-----------------------------------------------------------------------------
@ -71,8 +71,8 @@ ConCommandBase* CCVar::FindCommandBase(const char* pszCommandName)
//-----------------------------------------------------------------------------
ConVar* CCVar::FindVar(const char* pszVarName)
{
using OriginalFn = ConVar * (__thiscall*)(CCVar*, const char*);
return (*reinterpret_cast<OriginalFn**>(this))[16](this, pszVarName);
static int index = 16;
return CallVFunc<ConVar*>(index, this, pszVarName);
}
//-----------------------------------------------------------------------------
@ -81,8 +81,8 @@ ConVar* CCVar::FindVar(const char* pszVarName)
//-----------------------------------------------------------------------------
ConCommand* CCVar::FindCommand(const char* pszCommandName)
{
using OriginalFn = ConCommand* (__thiscall*)(CCVar*, const char*);
return (*reinterpret_cast<OriginalFn**>(this))[18](this, pszCommandName);
static int index = 18;
return CallVFunc<ConCommand*>(index, this, pszCommandName);
}
//-----------------------------------------------------------------------------
@ -90,8 +90,8 @@ ConCommand* CCVar::FindCommand(const char* pszCommandName)
//-----------------------------------------------------------------------------
CCVarIteratorInternal* CCVar::FactoryInternalIterator()
{
using OriginalFn = CCVarIteratorInternal * (__thiscall*)(CCVar*);
return (*reinterpret_cast<OriginalFn**>(this))[41](this);
static int index = 41;
return CallVFunc<CCVarIteratorInternal*>(index, this);
}
//-----------------------------------------------------------------------------

View File

@ -51,32 +51,32 @@ public:
void RegisterSizeofKeyValues(std::int64_t size) //@0x1413AA1F0 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
{
using OriginalFn = void(__thiscall*)(CKeyValuesSystem*, std::int64_t);
(*reinterpret_cast<OriginalFn**>(this))[0](this, size);
static int index = 0;
CallVFunc<void>(index, this, size);
}
void* AllocKeyValuesMemory(std::int64_t size) // @0x1413AA1F8 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
{
using OriginalFn = void* (__thiscall*)(CKeyValuesSystem*, std::int64_t);
return (*reinterpret_cast<OriginalFn**>(this))[1](this, size);
static int index = 1;
return CallVFunc<void*>(index, this, size);
}
void FreeKeyValuesMemory(void* pMem) // @0x1413AA200 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
{
using OriginalFn = void(__thiscall*)(CKeyValuesSystem*, void*);
(*reinterpret_cast<OriginalFn**>(this))[2](this, pMem);
static int index = 2;
CallVFunc<void>(index, this, pMem);
}
HKeySymbol GetSymbolForString(const char* name, bool bCreate) // @0x1413AA208 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
{
using OriginalFn = HKeySymbol(__thiscall*)(CKeyValuesSystem*, const char*, bool);
return (*reinterpret_cast<OriginalFn**>(this))[3](this, name, bCreate);
static int index = 3;
return CallVFunc<HKeySymbol>(index, this, name, bCreate);
}
const char* GetStringForSymbol(HKeySymbol symbol) // @0x1413AA210 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
{
using OriginalFn = const char* (__thiscall*)(CKeyValuesSystem*, HKeySymbol);
return (*reinterpret_cast<OriginalFn**>(this))[4](this, symbol);
static int index = 4;
return CallVFunc<const char*>(index, this, symbol);
}
// void __fastcall CKeyValuesSystem::FreeKeyValuesMemory(CKeyValuesSystem* this_arg, void* ptr_mem_arg)
@ -111,20 +111,20 @@ public:
void SetKeyValuesExpressionSymbol(const char* name, bool bValue) // @0x1413AA230 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
{
using OriginalFn = void(__thiscall*)(CKeyValuesSystem*, const char*, bool);
(*reinterpret_cast<OriginalFn**>(this))[8](this, name, bValue);
static int index = 8;
CallVFunc<void>(index, this, name, bValue);
}
bool GetKeyValuesExpressionSymbol(const char* name) // @0x1413AA238 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
{
using OriginalFn = bool(__thiscall*)(CKeyValuesSystem*, const char*);
return (*reinterpret_cast<OriginalFn**>(this))[9](this, name);
static int index = 9;
return CallVFunc<bool>(index, this, name);
}
HKeySymbol GetSymbolForStringCaseSensitive(HKeySymbol& hCaseInsensitiveSymbol, const char* name, bool bCreate) // @0x1413AA240 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
{
using OriginalFn = HKeySymbol(__thiscall*)(CKeyValuesSystem*, HKeySymbol&, const char*, bool);
return (*reinterpret_cast<OriginalFn**>(this))[10](this, hCaseInsensitiveSymbol, name, bCreate);
static int index = 10;
return CallVFunc<HKeySymbol>(index, this, hCaseInsensitiveSymbol, name, bCreate);
}
// Datatypes aren't accurate. But full fill the actual byte distance.
@ -202,17 +202,8 @@ public:
}
// Compiler makes it so m_Value shares the offset spot with m_flValue that why we cast it like this.
float& m_flValue()
{
static std::int32_t offset = 0x18;
return *(float*)((std::uintptr_t)this + offset);
}
int& m_iValue()
{
static std::int32_t offset = 0x18;
return *(int*)((std::uintptr_t)this + offset);
}
MEMBER_AT_OFFSET(float, m_flValue, 0x18);
MEMBER_AT_OFFSET(int, m_iValue, 0x18);
public:
uint32_t m_iKeyName : 24; // 0x0000