From 8ac33260a408ba99970d3338df280892b92e1754 Mon Sep 17 00:00:00 2001 From: Diavolo Date: Tue, 2 Aug 2022 23:04:02 +0200 Subject: [PATCH] [Utils] Fix function --- src/Components/Modules/Debug.cpp | 56 ++++++++++++++++++++++++++++++-- src/Components/Modules/Debug.hpp | 4 ++- src/Game/Functions.cpp | 8 +++++ src/Game/Functions.hpp | 20 ++++++++++++ src/Game/Structs.hpp | 46 ++++++++++++++++++++++++++ src/STDInclude.hpp | 9 +++++ src/Utils/Json.cpp | 6 +++- 7 files changed, 145 insertions(+), 4 deletions(-) diff --git a/src/Components/Modules/Debug.cpp b/src/Components/Modules/Debug.cpp index 9a2fc119..e7a36de9 100644 --- a/src/Components/Modules/Debug.cpp +++ b/src/Components/Modules/Debug.cpp @@ -2,7 +2,8 @@ namespace Components { - Dvar::Var Debug::DebugOverlay; + const Game::dvar_t* Debug::DebugOverlay; + const Game::dvar_t* Debug::BugName; Game::dvar_t** Debug::PlayerDebugHealth = reinterpret_cast(0x7A9F7C); @@ -198,7 +199,7 @@ namespace Components void Debug::CG_DrawDebugOverlays_Hk(const int localClientNum) { - switch (DebugOverlay.get()) + switch (DebugOverlay->current.integer) { case 2: CG_Debug_DrawPSFlags(localClientNum); @@ -218,6 +219,51 @@ namespace Components assert(("a", false)); } + void Debug::Com_Bug_f(Command::Params* params) + { + char newFileName[0x105]{}; + char to_ospath[MAX_PATH]{}; + char from_ospath[MAX_PATH]{}; + const char* bug; + + if (!*Game::logfile) + { + Logger::PrintError(Game::CON_CHANNEL_ERROR, "CopyFile failed: logfile wasn't opened\n"); + } + + if (params->size() == 2) + { + bug = params->get(1); + } + else + { + assert(BugName); + bug = BugName->current.string; + } + + sprintf_s(newFileName, "%s_%s.log", bug, Game::Live_GetLocalClientName(0)); + + Game::Sys_EnterCriticalSection(Game::CRITSECT_CONSOLE); + + if (*Game::logfile) + { + Game::FS_FCloseFile(reinterpret_cast(*Game::logfile)); + *Game::logfile = nullptr; + } + + Game::FS_BuildOSPath(Game::Sys_DefaultInstallPath(), "", "logs/console_mp.log", from_ospath); + Game::FS_BuildOSPath(Game::Sys_DefaultInstallPath(), "", newFileName, to_ospath); + const auto result = CopyFileA(from_ospath, to_ospath, 0); + Game::Com_OpenLogFile(); + + Game::Sys_LeaveCriticalSection(Game::CRITSECT_CONSOLE); + + if (!result) + { + Logger::PrintError(1, "CopyFile failed({}) {} {}\n", GetLastError(), "console_mp.log", newFileName); + } + } + void Debug::CL_InitDebugDvars() { static const char* debugOverlayNames_0[] = @@ -233,6 +279,8 @@ namespace Components DebugOverlay = Game::Dvar_RegisterEnum("debugOverlay", debugOverlayNames_0, 0, Game::DVAR_NONE, "Toggles the display of various debug info."); + BugName = Game::Dvar_RegisterString("bug_name", "bug0", + Game::DVAR_CHEAT | Game::DVAR_CODINFO, "Name appended to the copied console log"); } Debug::Debug() @@ -243,5 +291,9 @@ namespace Components Utils::Hook(0x49CB0A, CG_DrawDebugOverlays_Hk, HOOK_JUMP).install()->quick(); Utils::Hook::Set(0x60BCEA, Com_Assert_f); + +#ifdef _DEBUG + Command::Add("bug", Com_Bug_f); +#endif } } diff --git a/src/Components/Modules/Debug.hpp b/src/Components/Modules/Debug.hpp index a3d9dfcf..ba9b6b2a 100644 --- a/src/Components/Modules/Debug.hpp +++ b/src/Components/Modules/Debug.hpp @@ -8,7 +8,8 @@ namespace Components Debug(); private: - static Dvar::Var DebugOverlay; + static const Game::dvar_t* DebugOverlay; + static const Game::dvar_t* BugName; // Game dvars static Game::dvar_t** PlayerDebugHealth; @@ -32,6 +33,7 @@ namespace Components static void CG_DrawDebugOverlays_Hk(int localClientNum); static void Com_Assert_f(); + static void Com_Bug_f(Command::Params* params); static void CL_InitDebugDvars(); }; diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 7f3d08c5..32a43142 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -88,6 +88,7 @@ namespace Game Com_MatchToken_t Com_MatchToken = Com_MatchToken_t(0x447130); Com_SetSlowMotion_t Com_SetSlowMotion = Com_SetSlowMotion_t(0x446E20); Com_Quitf_t Com_Quit_f = Com_Quitf_t(0x4D4000); + Com_OpenLogFile_t Com_OpenLogFile = Com_OpenLogFile_t(0x60A8D0); Con_DrawMiniConsole_t Con_DrawMiniConsole = Con_DrawMiniConsole_t(0x464F30); Con_DrawSolidConsole_t Con_DrawSolidConsole = Con_DrawSolidConsole_t(0x5A5040); @@ -168,6 +169,7 @@ namespace Game FS_BuildPathToFile_t FS_BuildPathToFile = FS_BuildPathToFile_t(0x4702C0); FS_IsShippedIWD_t FS_IsShippedIWD = FS_IsShippedIWD_t(0x642440); FS_Delete_t FS_Delete = FS_Delete_t(0x48A5B0); + FS_BuildOSPath_t FS_BuildOSPath = FS_BuildOSPath_t(0x4702C0); G_LogPrintf_t G_LogPrintf = G_LogPrintf_t(0x4B0150); G_GetWeaponIndexForName_t G_GetWeaponIndexForName = G_GetWeaponIndexForName_t(0x49E540); @@ -256,6 +258,7 @@ namespace Game Live_GetMapIndex_t Live_GetMapIndex = Live_GetMapIndex_t(0x4F6440); Live_GetPrestige_t Live_GetPrestige = Live_GetPrestige_t(0x430F90); Live_GetXp_t Live_GetXp = Live_GetXp_t(0x404C60); + Live_GetLocalClientName_t Live_GetLocalClientName = Live_GetLocalClientName_t(0x441FC0); LiveStorage_GetStat_t LiveStorage_GetStat = LiveStorage_GetStat_t(0x471F60); @@ -400,6 +403,9 @@ namespace Game Sys_LockWrite_t Sys_LockWrite = Sys_LockWrite_t(0x435880); Sys_TempPriorityAtLeastNormalBegin_t Sys_TempPriorityAtLeastNormalBegin = Sys_TempPriorityAtLeastNormalBegin_t(0x478680); Sys_TempPriorityEnd_t Sys_TempPriorityEnd = Sys_TempPriorityEnd_t(0x4DCF00); + Sys_EnterCriticalSection_t Sys_EnterCriticalSection = Sys_EnterCriticalSection_t(0x4FC200); + Sys_LeaveCriticalSection_t Sys_LeaveCriticalSection = Sys_LeaveCriticalSection_t(0x41B8C0); + Sys_DefaultInstallPath_t Sys_DefaultInstallPath = Sys_DefaultInstallPath_t(0x4326E0); TeleportPlayer_t TeleportPlayer = TeleportPlayer_t(0x496850); @@ -633,6 +639,8 @@ namespace Game char (*sys_exitCmdLine)[1024] = reinterpret_cast(0x649FB68); + void** logfile = reinterpret_cast(0x1AD8F28); + GamerSettingState* gamerSettings = reinterpret_cast(0x107D3E8); void Sys_LockRead(FastCriticalSection* critSect) diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 55c839d8..658fe3af 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -199,6 +199,9 @@ namespace Game typedef void(__cdecl * Com_Quitf_t)(); extern Com_Quitf_t Com_Quit_f; + typedef void(__cdecl * Com_OpenLogFile_t)(); + extern Com_OpenLogFile_t Com_OpenLogFile; + typedef char* (__cdecl * Con_DrawMiniConsole_t)(int localClientNum, int xPos, int yPos, float alpha); extern Con_DrawMiniConsole_t Con_DrawMiniConsole; @@ -428,6 +431,9 @@ namespace Game typedef int(__cdecl* FS_Delete_t)(const char* fileName); extern FS_Delete_t FS_Delete; + typedef void(__cdecl * FS_BuildOSPath_t)(const char* base, const char* game, const char* qpath, char* ospath); + extern FS_BuildOSPath_t FS_BuildOSPath; + typedef void(__cdecl * G_LogPrintf_t)(const char* fmt, ...); extern G_LogPrintf_t G_LogPrintf; @@ -663,6 +669,9 @@ namespace Game typedef int(__cdecl * Live_GetXp_t)(int controllerIndex); extern Live_GetXp_t Live_GetXp; + typedef const char*(__cdecl * Live_GetLocalClientName_t)(int controllerIndex); + extern Live_GetLocalClientName_t Live_GetLocalClientName; + typedef int(__cdecl * LiveStorage_GetStat_t)(int controllerIndex, int index); extern LiveStorage_GetStat_t LiveStorage_GetStat; @@ -981,6 +990,15 @@ namespace Game typedef void(__cdecl * Sys_TempPriorityEnd_t)(TempPriority*); extern Sys_TempPriorityEnd_t Sys_TempPriorityEnd; + typedef void(__cdecl * Sys_EnterCriticalSection_t)(CriticalSection critSect); + extern Sys_EnterCriticalSection_t Sys_EnterCriticalSection; + + typedef void(__cdecl * Sys_LeaveCriticalSection_t)(CriticalSection critSect); + extern Sys_LeaveCriticalSection_t Sys_LeaveCriticalSection; + + typedef char*(__cdecl * Sys_DefaultInstallPath_t)(); + extern Sys_DefaultInstallPath_t Sys_DefaultInstallPath; + typedef void(__cdecl * TeleportPlayer_t)(gentity_t* entity, float* pos, float* orientation); extern TeleportPlayer_t TeleportPlayer; @@ -1305,6 +1323,8 @@ namespace Game extern char (*sys_exitCmdLine)[1024]; + extern void** logfile; + extern GamerSettingState* gamerSettings; void Sys_LockRead(FastCriticalSection* critSect); diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 971ecbd7..ac24a1e0 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -8793,6 +8793,52 @@ namespace Game GfxImage* image[8192]; }; + enum CriticalSection + { + CRITSECT_CONSOLE, + CRITSECT_DEBUG_SOCKET, + CRITSECT_COM_ERROR, + CRITSECT_STATMON, + CRITSECT_ALLOC_MARK, + CRITSECT_GENERATE_MARK, + CRITSECT_STREAMED_SOUND, + CRITSECT_FAKELAG, + CRITSECT_CLIENT_MESSAGE, + CRITSECT_CLIENT_CMD, + CRITSECT_DOBJ_ALLOC, + CRITSECT_START_SERVER, + CRITSECT_XANIM_ALLOC, + CRITSECT_KEY_BINDINGS, + CRITSECT_FX_VIS, + CRITSECT_SERVER_MESSAGE, + CRITSECT_SCRIPT_STRING, + CRITSECT_RD_BUFFER, + CRITSECT_SYS_EVENT_QUEUE, + CRITSECT_GPU_FENCE, + CRITSECT_FATAL_ERROR, + CRITSECT_MISSING_ASSET, + CRITSECT_PHYSICS, + CRITSECT_LIVE, + CRITSECT_AUDIO_PHYSICS, + CRITSECT_LSP, + CRITSECT_CINEMATIC_UPDATE, + CRITSECT_CINEMATIC_TARGET_CHANGE_COMMAND, + CRITSECT_CINEMATIC_TARGET_CHANGE_BACKEND, + CRITSECT_CINEMATIC_STATUS, + CRITSECT_CINEMATIC_SERVER, + CRITSECT_FX_ALLOC, + CRITSECT_NETTHREAD_OVERRIDE, + CRITSECT_CBUF, + CRITSECT_STATS_WRITE, + CRITSECT_CG_GLASS, + CRITSECT_SERVER_DEMO_COMPRESS, + CRITSECT_COM_SET_ERROR_MSG, + CRITSECT_SOUND_UPDATE, + CRITSECT_RESET_MODEL_LIGHTING, + + CRITSECT_COUNT, + }; // May be incorrect + #pragma endregion #ifndef IDA diff --git a/src/STDInclude.hpp b/src/STDInclude.hpp index becd7189..057bd2f5 100644 --- a/src/STDInclude.hpp +++ b/src/STDInclude.hpp @@ -107,6 +107,15 @@ using namespace std::literals; static_assert(offsetof(x, y) == (offset), \ #x "::" #y " is not at the right offset. Must be at " #offset) +// Helps the optimizer know code such as default label in a switch statement is unreachable. +// It may generate less assembly (speed increase) if used properly +#define ASSUME(e) ( (assert(0)), __assume(e) ) +#ifdef NDEBUG + #define AssertUnreachable __assume(0) +#else + #define AssertUnreachable ASSUME(0) +#endif + // Protobuf #include "proto/session.pb.h" #include "proto/party.pb.h" diff --git a/src/Utils/Json.cpp b/src/Utils/Json.cpp index 06f46499..2a0c19f0 100644 --- a/src/Utils/Json.cpp +++ b/src/Utils/Json.cpp @@ -22,8 +22,12 @@ namespace Utils::Json return "array"; case nlohmann::json::value_t::object: return "object"; + case nlohmann::json::value_t::binary: + return "binary"; + case nlohmann::json::value_t::discarded: + return "discarded"; default: - return "null"; + AssertUnreachable; } } }