r5sdk/r5dev/core/init.cpp
Kawe Mazidjatari 6fbf78a4eb Add logging hook for Miles Sound System debug output
Miles Sound System sets a pointer to a logger function in the exported function "MilesStartup", which can be set by passing a pointer to your logging function in the first parameter. Since this call is inline, we just hook the function that Respawn used for the audio logger instead, which has the actual print within the function stripped.
2022-11-27 15:02:22 +01:00

500 lines
16 KiB
C++

//=============================================================================//
//
// Purpose: Main systems initialization file
//
//=============================================================================//
#include "core/stdafx.h"
#include "core/logdef.h"
#include "core/init.h"
#include "tier0/jobthread.h"
#include "tier0/threadtools.h"
#include "tier0/tslist.h"
#include "tier0/memstd.h"
#include "tier0/fasttimer.h"
#include "tier0/cpu.h"
#include "tier0/commandline.h"
#include "tier0/platform_internal.h"
#include "tier1/cmd.h"
#include "tier1/IConVar.h"
#include "tier1/cvar.h"
#include "vpc/IAppSystem.h"
#include "vpc/keyvalues.h"
#include "vpc/interfaces.h"
#include "vstdlib/callback.h"
#include "vstdlib/completion.h"
#include "vstdlib/keyvaluessystem.h"
#include "common/opcodes.h"
#include "common/netmessages.h"
#include "launcher/prx.h"
#include "launcher/launcher.h"
#include "launcher/IApplication.h"
#include "filesystem/basefilesystem.h"
#include "filesystem/filesystem.h"
#include "datacache/mdlcache.h"
#include "ebisusdk/EbisuSDK.h"
#ifndef DEDICATED
#include "milessdk/shared/core.h"
#include "milessdk/win64_rrthreads.h"
#endif // !DEDICATED
#include "vphysics/QHull.h"
#include "bsplib/bsplib.h"
#include "materialsystem/cmaterialsystem.h"
#ifndef DEDICATED
#include "materialsystem/cmaterialglue.h"
#include "vgui/vgui_baseui_interface.h"
#include "vgui/vgui_debugpanel.h"
#include "vgui/vgui_fpspanel.h"
#include "vguimatsurface/MatSystemSurface.h"
#include "client/vengineclient_impl.h"
#endif // !DEDICATED
#include "client/cdll_engine_int.h"
#ifndef CLIENT_DLL
#include "engine/server/server.h"
#include "server/persistence.h"
#include "server/vengineserver_impl.h"
#endif // !CLIENT_DLL
#include "squirrel/sqinit.h"
#include "squirrel/sqapi.h"
#include "squirrel/sqvm.h"
#include "squirrel/sqscript.h"
#include "squirrel/sqstdaux.h"
#include "studiorender/studiorendercontext.h"
#include "rtech/rtech_game.h"
#include "rtech/rtech_utils.h"
#include "rtech/stryder/stryder.h"
#include "rtech/rui/rui.h"
#ifndef DEDICATED
#include "engine/client/cl_ents_parse.h"
#endif // !DEDICATED
#include "engine/client/cl_main.h"
#include "engine/client/client.h"
#include "engine/client/clientstate.h"
#include "engine/traceinit.h"
#include "engine/common.h"
#include "engine/cmodel_bsp.h"
#include "engine/host.h"
#include "engine/host_cmd.h"
#include "engine/host_state.h"
#include "engine/modelloader.h"
#include "engine/net.h"
#include "engine/net_chan.h"
#ifndef CLIENT_DLL
#include "engine/server/sv_main.h"
#endif // !CLIENT_DLL
#include "engine/sdk_dll.h"
#include "engine/sys_dll.h"
#include "engine/sys_dll2.h"
#include "engine/sys_engine.h"
#include "engine/sys_utils.h"
#include "engine/sys_getmodes.h"
#ifndef DEDICATED
#include "engine/sys_mainwind.h"
#endif // !DEDICATED
#include "engine/gl_matsysiface.h"
#include "engine/gl_screen.h"
#ifndef DEDICATED
#include "engine/gl_rsurf.h"
#include "engine/debugoverlay.h"
#endif // !DEDICATED
#include "game/shared/animation.h"
#ifndef CLIENT_DLL
#include "game/server/ai_node.h"
#include "game/server/ai_network.h"
#include "game/server/ai_networkmanager.h"
#include "game/server/ai_utility.h"
#include "game/server/detour_impl.h"
#include "game/server/fairfight_impl.h"
#include "game/server/gameinterface.h"
#endif // !CLIENT_DLL
#ifndef DEDICATED
#include "game/client/viewrender.h"
#endif // !DEDICATED
#include "public/edict.h"
#ifndef DEDICATED
#include "public/idebugoverlay.h"
#include "inputsystem/inputsystem.h"
#include "windows/id3dx.h"
#endif // !DEDICATED
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// ██╗███╗ ██╗██╗████████╗██╗ █████╗ ██╗ ██╗███████╗ █████╗ ████████╗██╗ ██████╗ ███╗ ██╗
// ██║████╗ ██║██║╚══██╔══╝██║██╔══██╗██║ ██║╚══███╔╝██╔══██╗╚══██╔══╝██║██╔═══██╗████╗ ██║
// ██║██╔██╗ ██║██║ ██║ ██║███████║██║ ██║ ███╔╝ ███████║ ██║ ██║██║ ██║██╔██╗ ██║
// ██║██║╚██╗██║██║ ██║ ██║██╔══██║██║ ██║ ███╔╝ ██╔══██║ ██║ ██║██║ ██║██║╚██╗██║
// ██║██║ ╚████║██║ ██║ ██║██║ ██║███████╗██║███████╗██║ ██║ ██║ ██║╚██████╔╝██║ ╚████║
// ╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝
//
/////////////////////////////////////////////////////////////////////////////////////////////////
void Systems_Init()
{
spdlog::info("+-------------------------------------------------------------+\n");
QuerySystemInfo();
CFastTimer initTimer;
initTimer.Start();
DetourInit();
initTimer.End();
spdlog::info("+-------------------------------------------------------------+\n");
spdlog::info("Detour->Init() '{:10.6f}' seconds ('{:12d}' clocks)\n", initTimer.GetDuration().GetSeconds(), initTimer.GetDuration().GetCycles());
initTimer.Start();
// Begin the detour transaction to hook the process
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
// Hook functions
//TSList_Attach();
Launcher_Attach();
IApplication_Attach();
#ifdef DEDICATED
//PRX_Attach();
#endif // DEDICATED
#ifndef DEDICATED
CL_Ents_Parse_Attach();
#endif // !DEDICATED
CBaseClient_Attach();
CBaseFileSystem_Attach();
MDLCache_Attach();
#ifndef DEDICATED
MilesCore_Attach();
CMaterialSystem_Attach();
#endif // !DEDICATED
QHull_Attach();
BspLib_Attach();
#ifndef DEDICATED
CEngineVGui_Attach();
//CFPSPanel_Attach();
CHLClient_Attach();
#endif // !DEDICATED
#if !defined(CLIENT_DLL) && defined (GAMEDLL_S3)
CServer_Attach(); // S1 and S2 CServer functions require work.
#endif // !CLIENT_DLL && GAMEDLL_S3
Host_Attach();
HostCmd_Attach();
CHostState_Attach();
CModelBsp_Attach();
CModelLoader_Attach();
#if !defined(DEDICATED) && defined (GAMEDLL_S3)
CNetMessages_Attach(); // S1 and S2 require certification.
#endif // !DEDICATED && GAMEDLL_S3
NET_Attach();
NetChan_Attach();
ConCommand_Attach();
IConVar_Attach();
CKeyValueSystem_Attach();
#ifndef CLIENT_DLL
Persistence_Attach();
IVEngineServer_Attach();
CServerGameDLL_Attach();
#endif // !CLIENT_DLL
SQAPI_Attach();
SQVM_Attach();
SQScript_Attach();
SQAUX_Attach();
RTech_Game_Attach();
RTech_Utils_Attach();
#ifndef DEDICATED
Rui_Attach();
#endif // !DEDICATED
SysDll_Attach();
SysDll2_Attach();
SysUtils_Attach();
#ifndef DEDICATED
SysGame_Attach();
#endif // !DEDICATED
#ifndef DEDICATED
HCVideoMode_Common_Attach();
DebugOverlays_Attach();
RSurf_Attach();
#endif // !DEDICATED
Animation_Attach();
#ifndef CLIENT_DLL
CAI_Utility_Attach();
CAI_Network_Attach();
CAI_NetworkManager_Attach();
#endif // !#ifndef CLIENT_DLL
// Patch instructions
RuntimePtc_Init();
// Commit the transaction
HRESULT hr = DetourTransactionCommit();
if (hr != NO_ERROR)
{
// Failed to hook into the process, terminate
Error(eDLL_T::COMMON, 0xBAD0C0DE, "Failed to detour process: error code = %08x\n", hr);
}
initTimer.End();
spdlog::info("Detour->Attach() '{:10.6f}' seconds ('{:12d}' clocks)\n", initTimer.GetDuration().GetSeconds(), initTimer.GetDuration().GetCycles());
spdlog::info("+-------------------------------------------------------------+\n");
ConVar::Init();
#ifdef DEDICATED
Dedicated_Init();
#endif // DEDICATED
SpdLog_PostInit();
std::thread fixed(&CEngineSDK::FixedFrame, g_EngineSDK);
fixed.detach();
}
//////////////////////////////////////////////////////////////////////////
//
// ███████╗██╗ ██╗██╗ ██╗████████╗██████╗ ██████╗ ██╗ ██╗███╗ ██╗
// ██╔════╝██║ ██║██║ ██║╚══██╔══╝██╔══██╗██╔═══██╗██║ ██║████╗ ██║
// ███████╗███████║██║ ██║ ██║ ██║ ██║██║ ██║██║ █╗ ██║██╔██╗ ██║
// ╚════██║██╔══██║██║ ██║ ██║ ██║ ██║██║ ██║██║███╗██║██║╚██╗██║
// ███████║██║ ██║╚██████╔╝ ██║ ██████╔╝╚██████╔╝╚███╔███╔╝██║ ╚████║
// ╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══╝╚══╝ ╚═╝ ╚═══╝
//
//////////////////////////////////////////////////////////////////////////
void Systems_Shutdown()
{
CFastTimer shutdownTimer;
shutdownTimer.Start();
// Begin the detour transaction to unhook the process
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
// Unhook functions
//TSList_Detach();
Launcher_Detach();
IApplication_Detach();
#ifdef DEDICATED
//PRX_Detach();
#endif // DEDICATED
#ifndef DEDICATED
CL_Ents_Parse_Detach();
#endif // !DEDICATED
CBaseClient_Detach();
CBaseFileSystem_Detach();
MDLCache_Detach();
#ifndef DEDICATED
MilesCore_Detach();
CMaterialSystem_Detach();
#endif // !DEDICATED
QHull_Detach();
BspLib_Detach();
#ifndef DEDICATED
CEngineVGui_Detach();
//CFPSPanel_Detach();
CHLClient_Detach();
#endif // !DEDICATED
#if !defined(CLIENT_DLL) && defined (GAMEDLL_S3)
CServer_Detach(); // S1 and S2 CServer functions require work.
#endif // !CLIENT_DLL && GAMEDLL_S3
Host_Detach();
HostCmd_Detach();
CHostState_Detach();
CModelBsp_Detach();
CModelLoader_Detach();
#if !defined(DEDICATED) && defined (GAMEDLL_S3)
CNetMessages_Detach(); // S1 and S2 require certification.
#endif // !DEDICATED && GAMEDLL_S3
NET_Detach();
NetChan_Detach();
ConCommand_Detach();
IConVar_Detach();
CKeyValueSystem_Detach();
#ifndef CLIENT_DLL
Persistence_Detach();
IVEngineServer_Detach();
CServerGameDLL_Detach();
#endif // !CLIENT_DLL
SQAPI_Detach();
SQVM_Detach();
SQScript_Detach();
SQAUX_Detach();
RTech_Game_Detach();
RTech_Utils_Detach();
#ifndef DEDICATED
Rui_Detach();
#endif // !DEDICATED
SysDll_Detach();
SysDll2_Detach();
SysUtils_Detach();
#ifndef DEDICATED
SysGame_Detach();
#endif // DEDICATED
#ifndef DEDICATED
HCVideoMode_Common_Detach();
DebugOverlays_Detach();
RSurf_Detach();
#endif // !DEDICATED
Animation_Detach();
#ifndef CLIENT_DLL
CAI_Utility_Detach();
CAI_Network_Detach();
CAI_NetworkManager_Detach();
#endif // !CLIENT_DLL
// Commit the transaction
DetourTransactionCommit();
shutdownTimer.End();
spdlog::info("Detour->Detach() '{:10.6f}' seconds ('{:12d}' clocks)\n", shutdownTimer.GetDuration().GetSeconds(), shutdownTimer.GetDuration().GetCycles());
spdlog::info("+-------------------------------------------------------------+\n");
}
/////////////////////////////////////////////////////
//
// ██╗ ██╗████████╗██╗██╗ ██╗████████╗██╗ ██╗
// ██║ ██║╚══██╔══╝██║██║ ██║╚══██╔══╝╚██╗ ██╔╝
// ██║ ██║ ██║ ██║██║ ██║ ██║ ╚████╔╝
// ██║ ██║ ██║ ██║██║ ██║ ██║ ╚██╔╝
// ╚██████╔╝ ██║ ██║███████╗██║ ██║ ██║
// ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝
//
/////////////////////////////////////////////////////
void WinSock_Init()
{
WSAData wsaData{};
int nError = ::WSAStartup(MAKEWORD(2, 2), &wsaData);
if (nError != 0)
{
std::cerr << "Failed to start Winsock via WSAStartup: (" << NET_ErrorString(WSAGetLastError()) << ")" << std::endl;
}
}
void WinSock_Shutdown()
{
int nError = ::WSACleanup();
if (nError != 0)
{
std::cerr << "Failed to stop Winsock via WSACleanup: (" << NET_ErrorString(WSAGetLastError()) << ")" << std::endl;
}
}
void QuerySystemInfo()
{
const CPUInformation& pi = GetCPUInformation();
spdlog::info("CPU model identifier : '{:s}'\n", pi.m_szProcessorBrand);
spdlog::info("CPU vendor identifier : '{:s}'\n", pi.m_szProcessorID);
spdlog::info("CPU core count : '{:12d}' ({:s})\n", pi.m_nPhysicalProcessors, "Physical");
spdlog::info("CPU core count : '{:12d}' ({:s})\n", pi.m_nLogicalProcessors, "Logical");
spdlog::info("L1 cache (KiB): '{:12d}'\n", pi.m_nL1CacheSizeKb);
spdlog::info("L1 cache (Dsc): '{:#12x}'\n" , pi.m_nL1CacheDesc);
spdlog::info("L2 cache (KiB): '{:12d}'\n", pi.m_nL2CacheSizeKb);
spdlog::info("L2 cache (Dsc): '{:#12x}'\n" , pi.m_nL2CacheDesc);
spdlog::info("L3 cache (KiB): '{:12d}'\n", pi.m_nL3CacheSizeKb);
spdlog::info("L3 cache (Dsc): '{:#12x}'\n" , pi.m_nL3CacheDesc);
spdlog::info("Clock speed (CPS): '{:12d}'\n", pi.m_Speed);
MEMORYSTATUSEX statex{};
statex.dwLength = sizeof(statex);
if (GlobalMemoryStatusEx(&statex))
{
spdlog::info("Total system memory (MiB): '{:12d}' ({:s})\n", (statex.ullTotalPhys / 1024) / 1024, "Physical");
spdlog::info("Avail system memory (MiB): '{:12d}' ({:s})\n", (statex.ullAvailPhys / 1024) / 1024, "Physical");
spdlog::info("Total system memory (MiB): '{:12d}' ({:s})\n", (statex.ullTotalVirtual / 1024) / 1024, "Virtual");
spdlog::info("Avail system memory (MiB): '{:12d}' ({:s})\n", (statex.ullAvailVirtual / 1024) / 1024, "Virtual");
}
else
{
spdlog::error("Unable to retrieve system memory information: {:s}\n",
std::system_category().message(static_cast<int>(::GetLastError())));
}
}
void CheckCPU() // Respawn's engine and our SDK utilize POPCNT, SSE3 and SSSE3 (Supplemental SSE 3 Instructions).
{
const CPUInformation& pi = GetCPUInformation();
static char szBuf[1024];
if (!pi.m_bSSE3)
{
V_snprintf(szBuf, sizeof(szBuf), "CPU does not have %s!\n", "SSE 3");
MessageBoxA(NULL, szBuf, "Unsupported CPU", MB_ICONERROR | MB_OK);
ExitProcess(-1);
}
if (!pi.m_bSSSE3)
{
V_snprintf(szBuf, sizeof(szBuf), "CPU does not have %s!\n", "SSSE 3 (Supplemental SSE 3 Instructions)");
MessageBoxA(NULL, szBuf, "Unsupported CPU", MB_ICONERROR | MB_OK);
ExitProcess(-1);
}
if (!pi.m_bPOPCNT)
{
V_snprintf(szBuf, sizeof(szBuf), "CPU does not have %s!\n", "POPCNT");
MessageBoxA(NULL, szBuf, "Unsupported CPU", MB_ICONERROR | MB_OK);
ExitProcess(-1);
}
}
void DetourInit() // Run the sigscan
{
bool bLogAdr = (strstr(GetCommandLineA(), "-sig_toconsole") != nullptr);
bool bInitDivider = false;
for (const IDetour* pDetour : vDetour)
{
pDetour->GetCon(); // Constants.
pDetour->GetFun(); // Functions.
pDetour->GetVar(); // Variables.
if (bLogAdr)
{
if (!bInitDivider)
{
bInitDivider = true;
spdlog::debug("+----------------------------------------------------------------+\n");
}
pDetour->GetAdr();
}
}
}
void DetourAddress() // Test the sigscan results
{
spdlog::debug("+----------------------------------------------------------------+\n");
for (const IDetour* pDetour : vDetour)
{
pDetour->GetAdr();
}
}