From 5191a24d371719a2c715fb6c257a8a5c5f25bff0 Mon Sep 17 00:00:00 2001 From: IcePixelx <41352111+PixieCore@users.noreply.github.com> Date: Sun, 18 Jul 2021 17:34:15 +0200 Subject: [PATCH 1/2] Added GameGlobals, Re-factored overlay.cpp. --- r5dev/include/console.h | 1 + r5dev/include/gameclasses.h | 14 +- r5dev/include/hooks.h | 2 +- r5dev/include/overlay.h | 156 ++++- r5dev/include/patterns.h | 14 +- r5dev/include/serverlisting.h | 3 +- r5dev/r5dev.vcxproj | 1 + r5dev/r5dev.vcxproj.filters | 3 + r5dev/src/gameclasses.cpp | 16 + r5dev/src/hooks.cpp | 58 +- r5dev/src/id3dx.cpp | 13 +- r5dev/src/overlay.cpp | 1231 ++++++++++++++------------------- r5dev/src/serverlisting.cpp | 5 +- 13 files changed, 736 insertions(+), 781 deletions(-) create mode 100644 r5dev/src/gameclasses.cpp diff --git a/r5dev/include/console.h b/r5dev/include/console.h index 91fa9885..a7879bb3 100644 --- a/r5dev/include/console.h +++ b/r5dev/include/console.h @@ -4,6 +4,7 @@ // Initialization void SetupConsole(); void RemoveCMHooks(); +void ToggleDevCommands(); ///////////////////////////////////////////////////////////////////////////// // Hooks diff --git a/r5dev/include/gameclasses.h b/r5dev/include/gameclasses.h index 145cc9d3..eac74e2a 100644 --- a/r5dev/include/gameclasses.h +++ b/r5dev/include/gameclasses.h @@ -515,4 +515,16 @@ public: using OriginalFn = void(__thiscall*)(CHLClient*, ClientFrameStage_t); (*reinterpret_cast(this))[58](this, curStage); /* 48 83 EC 28 89 15 ? ? ? ? */ } -}; \ No newline at end of file +}; + +///////////////////////////////////////////////////////////////////////////// +// Initialize Game Globals + +namespace GameGlobals +{ + extern CHostState* HostState; + extern CInputSystem* InputSystem; + + void InitGameGlobals(); + extern bool IsInitialized; +} \ No newline at end of file diff --git a/r5dev/include/hooks.h b/r5dev/include/hooks.h index a2d9fa4e..025eb1e0 100644 --- a/r5dev/include/hooks.h +++ b/r5dev/include/hooks.h @@ -11,4 +11,4 @@ void ToggleNetHooks(); // Globals inline bool g_bDebugLoading = false; -///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/r5dev/include/overlay.h b/r5dev/include/overlay.h index 974a6171..3800def8 100644 --- a/r5dev/include/overlay.h +++ b/r5dev/include/overlay.h @@ -8,25 +8,133 @@ void PrintDXAddress(); void InstallDXHooks(); void RemoveDXHooks(); -void ShowGameConsole(bool* p_open); +void DrawMenu(); ///////////////////////////////////////////////////////////////////////////// // Internals -int Stricmp(const char* s1, const char* s2); -int Strnicmp(const char* s1, const char* s2, int n); +int Stricmp(const char* s1, const char* s2); +int Strnicmp(const char* s1, const char* s2, int n); char* Strdup(const char* s); void Strtrim(char* s); ///////////////////////////////////////////////////////////////////////////// // Globals -inline ImVector Items; - +inline ImVector Items; inline std::string OriginUID = "1010417302770"; -///////////////////////////////////////////////////////////////////////////// +class CGameConsole +{ +private: + /////////////////////////////////////////////////////////////////////////// + char InputBuf[256] = { 0 }; + ImVector Commands; + ImVector History; + int HistoryPos = -1; + ImGuiTextFilter Filter; + bool AutoScroll = true; + bool ScrollToBottom = false; + bool ThemeSet = false; -using json = nlohmann::json; -void RunConsoleCommand(std::string command); +public: + /////////////////////////////////////////////////////////////////////////// + + CGameConsole(); + ~CGameConsole(); + + void Draw(const char* title); + void ProcessCommand(const char* command_line); + void ExecCommand(const char* command_line); + int TextEditCallback(ImGuiInputTextCallbackData* data); + + /////////////////////////////////////////////////////////////////////////// + // History + static int TextEditCallbackStub(ImGuiInputTextCallbackData* data) + { + CGameConsole* console = (CGameConsole*)data->UserData; + return console->TextEditCallback(data); + } + + /////////////////////////////////////////////////////////////////////////// + // Utility + void ClearLog() + { + for (int i = 0; i < Items.Size; i++) { free(Items[i]); } + Items.clear(); + } + void AddLog(const char* fmt, ...) IM_FMTARGS(2) + { + char buf[1024]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args); + buf[IM_ARRAYSIZE(buf) - 1] = 0; + va_end(args); + Items.push_back(Strdup(buf)); + } + + /////////////////////////////////////////////////////////////////////// + // Style + void SetStyleVar() + { + ImGuiStyle& style = ImGui::GetStyle(); + ImVec4* colors = style.Colors; + + colors[ImGuiCol_Text] = ImVec4(0.81f, 0.81f, 0.81f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.56f, 0.56f, 0.56f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f); + colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); + colors[ImGuiCol_PopupBg] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f); + colors[ImGuiCol_Border] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.04f, 0.04f, 0.04f, 0.64f); + colors[ImGuiCol_FrameBg] = ImVec4(0.13f, 0.13f, 0.13f, 1.00f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 1.00f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.24f, 0.24f, 0.24f, 1.00f); + colors[ImGuiCol_TitleBg] = ImVec4(0.22f, 0.22f, 0.22f, 1.00f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); + colors[ImGuiCol_MenuBarBg] = ImVec4(0.22f, 0.22f, 0.22f, 1.00f); + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.10f, 0.10f, 0.10f, 1.00f); + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f); + colors[ImGuiCol_CheckMark] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); + colors[ImGuiCol_SliderGrab] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f); + colors[ImGuiCol_Button] = ImVec4(0.35f, 0.35f, 0.35f, 1.00f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.45f, 0.45f, 0.45f, 1.00f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.52f, 0.52f, 0.52f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.35f, 0.35f, 0.35f, 1.00f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.45f, 1.00f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f); + colors[ImGuiCol_Separator] = ImVec4(0.53f, 0.53f, 0.57f, 1.00f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.52f, 0.52f, 0.52f, 1.00f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f); + colors[ImGuiCol_Tab] = ImVec4(0.18f, 0.18f, 0.18f, 1.00f); + colors[ImGuiCol_TabHovered] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); + colors[ImGuiCol_TabActive] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); + + style.WindowBorderSize = 0.0f; + style.FrameBorderSize = 1.0f; + style.ChildBorderSize = 1.0f; + style.PopupBorderSize = 1.0f; + style.TabBorderSize = 1.0f; + + style.WindowRounding = 2.5f; + style.FrameRounding = 0.0f; + style.ChildRounding = 0.0f; + style.PopupRounding = 0.0f; + style.TabRounding = 1.0f; + style.ScrollbarRounding = 1.0f; + + style.ItemSpacing = ImVec2(4, 4); + style.WindowPadding = ImVec2(5, 5); + } +}; + +extern CGameConsole* g_GameConsole; ///////////////////////////////////////////////////////////////////////////// // ServerBrowser @@ -34,28 +142,31 @@ void RunConsoleCommand(std::string command); class CCompanion { public: + CCompanion(); + + //////////////////// + // Enums // + ////////////////// + enum class ESection { ServerBrowser, HostServer, Settings - } CurrentSection; + } CurrentSection = ESection::ServerBrowser; enum class EHostStatus { NotHosting, WaitingForStateChange, Hosting, ConnectedToSomeoneElse - }; + } HostingStatus = EHostStatus::NotHosting; - CCompanion(); //////////////////// // Server Browser // - //////////////////// - ImVector ServerList; + /////////////////// + ImVector ServerList; ServerListing* SelectedServer; - ImGuiTextFilter ServerBrowserFilter; - char ServerConnStringBuffer[256] = { 0 }; //////////////////// @@ -63,7 +174,6 @@ public: //////////////////// char MatchmakingServerStringBuffer[256] = { 0 }; - //////////////////// // Host Server // //////////////////// @@ -71,18 +181,18 @@ public: std::string* SelectedMap = nullptr; char ServerNameBuffer[64] = { 0 }; bool StartAsDedi; - EHostStatus HostingStatus = EHostStatus::NotHosting; + + void SetSection(ESection section) + { + CurrentSection = section; + } void RefreshServerList(); - - void SendHostingPostRequest(); - void SetSection(ESection section); + void SendHostingPostRequest(char* mapName); void CompMenu(); void ServerBrowserSection(); void SettingsSection(); void HostServerSection(); - void Draw(const char* title, bool* p_open); + void Draw(const char* title); void UpdateHostingStatus(); - - std::string GetGameStateLastMap(); }; \ No newline at end of file diff --git a/r5dev/include/patterns.h b/r5dev/include/patterns.h index e586520c..78e8079e 100644 --- a/r5dev/include/patterns.h +++ b/r5dev/include/patterns.h @@ -21,33 +21,33 @@ namespace //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* ==== SQUIRREL ======================================================================================================================================================== */ DWORD64 p_SQVM_Print = /*0x141057FD0*/ reinterpret_cast(PatternScan("r5apex.exe","48 8B C4 48 89 50 10 4C 89 40 18 4C 89 48 20 53 56 57 48 81 EC 30 08 00 00 48 8B DA 48 8D 70 18 48 8B F9 E8 ?? ?? ?? FF 48 89 74 24 28 48 8D 54 24 30 33")); - void* SQVM_Print = (void*)p_SQVM_Print; + void* org_SQVM_Print = (void*)p_SQVM_Print; //DWORD64 p_SQVM_LoadScript = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x5C\x24\x10\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x48\x89\x4C\x24\x08\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\x6C", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); // For S0 and S1 DWORD64 p_SQVM_LoadScript = /*0x141055630*/ reinterpret_cast(PatternScan("r5apex.exe", "48 8B C4 48 89 48 08 55 41 56 48 8D 68")); // For anything S2 and above (current S8) - bool (*SQVM_LoadScript)(void* sqvm, const char* script_path, const char* script_name, int flag) = (bool (*)(void*, const char*, const char*, int))p_SQVM_LoadScript; /*E8 ?? ?? ?? ?? 84 C0 74 1C 41 B9 ?? ?? ?? ??*/ + bool (*org_SQVM_LoadScript)(void* sqvm, const char* script_path, const char* script_name, int flag) = (bool (*)(void*, const char*, const char*, int))p_SQVM_LoadScript; /*E8 ?? ?? ?? ?? 84 C0 74 1C 41 B9 ?? ?? ?? ??*/ DWORD64 p_SQVM_LoadRson = /*0x140C957E0*/ reinterpret_cast(PatternScan("r5apex.exe", "4C 8B DC 49 89 5B 08 57 48 81 EC A0 00 00 00 33")); - int (*SQVM_LoadRson)(const char* rson_name) = (int (*)(const char*))p_SQVM_LoadRson; + int (*org_SQVM_LoadRson)(const char* rson_name) = (int (*)(const char*))p_SQVM_LoadRson; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* ==== NETCHAN ========================================================================================================================================================= */ DWORD64 p_NET_ReceiveDatagram = /*0x1402655F0*/ reinterpret_cast(PatternScan("r5apex.exe", "48 89 74 24 18 48 89 7C 24 20 55 41 54 41 55 41 56 41 57 48 8D AC 24 50 EB")); - bool (*NET_ReceiveDatagram)(int, void*, bool) = (bool (*)(int, void*, bool))p_NET_ReceiveDatagram; /*E8 ?? ?? ?? ?? 84 C0 75 35 48 8B D3*/ + bool (*org_NET_ReceiveDatagram)(int, void*, bool) = (bool (*)(int, void*, bool))p_NET_ReceiveDatagram; /*E8 ?? ?? ?? ?? 84 C0 75 35 48 8B D3*/ DWORD64 p_NET_SendDatagram = /*0x1402662D0*/ reinterpret_cast(PatternScan("r5apex.exe", "48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 56 41 57 48 81 EC ? 05 ? ?")); - int (*NET_SendDatagram)(SOCKET s, const char* buf, int len, int flags) = (int (*)(SOCKET, const char*, int, int))p_NET_SendDatagram; + int (*org_NET_SendDatagram)(SOCKET s, const char* buf, int len, int flags) = (int (*)(SOCKET, const char*, int, int))p_NET_SendDatagram; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* ==== CHLCLIENT ======================================================================================================================================================= */ DWORD64 p_CHLClient_FrameStageNotify = /*0x1405C0740*/ reinterpret_cast(PatternScan("r5apex.exe", "48 83 EC 28 89 15 ?? ?? ?? ??")); - void (*CHLClient_FrameStageNotify)(void* rcx, int curStage) = (void (*)(void*, int))p_CHLClient_FrameStageNotify; + void (*org_CHLClient_FrameStageNotify)(void* rcx, int curStage) = (void (*)(void*, int))p_CHLClient_FrameStageNotify; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* ==== UTILITY ========================================================================================================================================================= */ DWORD64 p_MSG_EngineError = /*0x140295600*/ reinterpret_cast(PatternScan("r5apex.exe", "48 89 5C 24 08 48 89 74 24 10 57 48 81 EC 30 08 00 00 48 8B DA 48 8B F9 E8 ?? ?? ?? FF 33 F6 48")); - int (*MSG_EngineError)(char* fmt, va_list args) = (int (*)(char*, va_list))p_MSG_EngineError; + int (*org_MSG_EngineError)(char* fmt, va_list args) = (int (*)(char*, va_list))p_MSG_EngineError; // Un-used atm. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/r5dev/include/serverlisting.h b/r5dev/include/serverlisting.h index 166d4b6e..6ee968c6 100644 --- a/r5dev/include/serverlisting.h +++ b/r5dev/include/serverlisting.h @@ -4,7 +4,6 @@ class ServerListing { - public: std::string name; @@ -14,6 +13,6 @@ public: int expiry; ServerListing(std::string name, std::string map, std::string ip, std::string version, int expiry); - bool Select(); + void Select(); }; diff --git a/r5dev/r5dev.vcxproj b/r5dev/r5dev.vcxproj index 614a672a..e58f67cb 100644 --- a/r5dev/r5dev.vcxproj +++ b/r5dev/r5dev.vcxproj @@ -313,6 +313,7 @@ + diff --git a/r5dev/r5dev.vcxproj.filters b/r5dev/r5dev.vcxproj.filters index 01003e5f..20faf4a8 100644 --- a/r5dev/r5dev.vcxproj.filters +++ b/r5dev/r5dev.vcxproj.filters @@ -102,6 +102,9 @@ Source Files + + Source Files + diff --git a/r5dev/src/gameclasses.cpp b/r5dev/src/gameclasses.cpp new file mode 100644 index 00000000..0b424df7 --- /dev/null +++ b/r5dev/src/gameclasses.cpp @@ -0,0 +1,16 @@ +#include "gameclasses.h" + +namespace GameGlobals +{ + bool IsInitialized = false; + CHostState* HostState = nullptr; + CInputSystem* InputSystem = nullptr; + + void InitGameGlobals() + { + HostState = reinterpret_cast(0x141736120); // Get CHostState from memory. + InputSystem = *reinterpret_cast(0x14D40B380); // Get IInputSystem from memory. + + IsInitialized = true; + } +} \ No newline at end of file diff --git a/r5dev/src/hooks.cpp b/r5dev/src/hooks.cpp index f6337026..f8420908 100644 --- a/r5dev/src/hooks.cpp +++ b/r5dev/src/hooks.cpp @@ -16,7 +16,7 @@ bool HNET_ReceiveDatagram(int sock, void* inpacket, bool raw) { - bool result = NET_ReceiveDatagram(sock, inpacket, raw); + bool result = org_NET_ReceiveDatagram(sock, inpacket, raw); if (result) { int i = NULL; @@ -32,7 +32,7 @@ bool HNET_ReceiveDatagram(int sock, void* inpacket, bool raw) unsigned int HNET_SendDatagram(SOCKET s, const char* buf, int len, int flags) { - unsigned int result = NET_SendDatagram(s, buf, len, flags); + unsigned int result = org_NET_SendDatagram(s, buf, len, flags); if (result) { /////////////////////////////////////////////////////////////////////////// @@ -49,16 +49,12 @@ unsigned int HNET_SendDatagram(SOCKET s, const char* buf, int len, int flags) void __fastcall HCHLClient__FrameStageNotify(CHLClient* rcx, ClientFrameStage_t curStage) /* __fastcall so we can make sure first argument will be RCX and second RDX. */ { - static CHostState* HostState = reinterpret_cast(0x141736120); - switch (curStage) { case FRAME_START: // FrameStageNotify gets called every frame by CEngine::Frame with the stage being FRAME_START. We can use this to check/set global variables. { - if (HostState->m_bWaitingForConnection) // Easy way to check if we are DEDI. - { - // printf("AWAITING CONNECTION\n"); - } + if (!GameGlobals::IsInitialized) + GameGlobals::InitGameGlobals(); break; } @@ -66,7 +62,7 @@ void __fastcall HCHLClient__FrameStageNotify(CHLClient* rcx, ClientFrameStage_t break; } - CHLClient_FrameStageNotify(rcx, curStage); + org_CHLClient_FrameStageNotify(rcx, curStage); } //################################################################################# @@ -103,14 +99,14 @@ __int64 HSQVM_LoadRson(const char* rson_name) /////////////////////////////////////////////////////////////////////////////// // Returns the new path if the rson exists on the disk - if (FileExists(filepath) && SQVM_LoadRson(rson_name)) + if (FileExists(filepath) && org_SQVM_LoadRson(rson_name)) { printf("\n"); printf("##################################################\n"); printf("] '%s'\n", filepath); printf("##################################################\n"); printf("\n"); - return SQVM_LoadRson(filepath); + return org_SQVM_LoadRson(filepath); } else { @@ -119,7 +115,7 @@ __int64 HSQVM_LoadRson(const char* rson_name) printf("] '%s'\n", rson_name); printf("##################################################\n"); printf("\n"); - return SQVM_LoadRson(rson_name); + return org_SQVM_LoadRson(rson_name); } } @@ -143,7 +139,7 @@ bool HSQVM_LoadScript(void* sqvm, const char* script_path, const char* script_na } /////////////////////////////////////////////////////////////////////////////// // Returns true if the script exists on the disk - if (FileExists(filepath) && SQVM_LoadScript(sqvm, filepath, script_name, flag)) + if (FileExists(filepath) && org_SQVM_LoadScript(sqvm, filepath, script_name, flag)) { return true; } @@ -151,7 +147,7 @@ bool HSQVM_LoadScript(void* sqvm, const char* script_path, const char* script_na { printf(" [!] FAILED. Try SP / VPK for '%s'\n", filepath); } - return SQVM_LoadScript(sqvm, script_path, script_name, flag); + return org_SQVM_LoadScript(sqvm, script_path, script_name, flag); } //################################################################################# @@ -166,7 +162,7 @@ int HMSG_EngineError(char* fmt, va_list args) vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args); buf[IM_ARRAYSIZE(buf) - 1] = 0; Items.push_back(Strdup(buf)); - return MSG_EngineError(fmt, args); + return org_MSG_EngineError(fmt, args); } //################################################################################# @@ -182,17 +178,17 @@ void InstallENHooks() /////////////////////////////////////////////////////////////////////////////// // Hook Squirrel functions - DetourAttach((LPVOID*)&SQVM_Print, &HSQVM_Print); - DetourAttach((LPVOID*)&SQVM_LoadRson, &HSQVM_LoadRson); - DetourAttach((LPVOID*)&SQVM_LoadScript, &HSQVM_LoadScript); + DetourAttach((LPVOID*)&org_SQVM_Print, &HSQVM_Print); + DetourAttach((LPVOID*)&org_SQVM_LoadRson, &HSQVM_LoadRson); + DetourAttach((LPVOID*)&org_SQVM_LoadScript, &HSQVM_LoadScript); /////////////////////////////////////////////////////////////////////////////// // Hook Game Functions - DetourAttach((LPVOID*)&CHLClient_FrameStageNotify, &HCHLClient__FrameStageNotify); + DetourAttach((LPVOID*)&org_CHLClient_FrameStageNotify, &HCHLClient__FrameStageNotify); /////////////////////////////////////////////////////////////////////////////// // Hook Utility functions - DetourAttach((LPVOID*)&MSG_EngineError, &HMSG_EngineError); + DetourAttach((LPVOID*)&org_MSG_EngineError, &HMSG_EngineError); /////////////////////////////////////////////////////////////////////////////// // Commit the transaction @@ -212,22 +208,22 @@ void RemoveENHooks() /////////////////////////////////////////////////////////////////////////////// // Unhook Squirrel functions - DetourDetach((LPVOID*)&SQVM_Print, &HSQVM_Print); - DetourDetach((LPVOID*)&SQVM_LoadRson, &HSQVM_LoadRson); - DetourDetach((LPVOID*)&SQVM_LoadScript, &HSQVM_LoadScript); + DetourDetach((LPVOID*)&org_SQVM_Print, &HSQVM_Print); + DetourDetach((LPVOID*)&org_SQVM_LoadRson, &HSQVM_LoadRson); + DetourDetach((LPVOID*)&org_SQVM_LoadScript, &HSQVM_LoadScript); /////////////////////////////////////////////////////////////////////////////// // Unhook Game Functions - DetourDetach((LPVOID*)&CHLClient_FrameStageNotify, &HCHLClient__FrameStageNotify); + DetourDetach((LPVOID*)&org_CHLClient_FrameStageNotify, &HCHLClient__FrameStageNotify); /////////////////////////////////////////////////////////////////////////////// // Unhook Netchan functions - DetourDetach((LPVOID*)&NET_SendDatagram, &HNET_SendDatagram); - DetourDetach((LPVOID*)&NET_ReceiveDatagram, &HNET_ReceiveDatagram); + DetourDetach((LPVOID*)&org_NET_SendDatagram, &HNET_SendDatagram); + DetourDetach((LPVOID*)&org_NET_ReceiveDatagram, &HNET_ReceiveDatagram); /////////////////////////////////////////////////////////////////////////////// // Unhook Utility functions - DetourDetach((LPVOID*)&MSG_EngineError, &HMSG_EngineError); + DetourDetach((LPVOID*)&org_MSG_EngineError, &HMSG_EngineError); /////////////////////////////////////////////////////////////////////////////// // Commit the transaction @@ -247,8 +243,8 @@ void ToggleNetHooks() if (!g_net) { - DetourAttach((LPVOID*)&NET_SendDatagram, &HNET_SendDatagram); - DetourAttach((LPVOID*)&NET_ReceiveDatagram, &HNET_ReceiveDatagram); + DetourAttach((LPVOID*)&org_NET_SendDatagram, &HNET_SendDatagram); + DetourAttach((LPVOID*)&org_NET_ReceiveDatagram, &HNET_ReceiveDatagram); printf("\n"); printf("+--------------------------------------------------------+\n"); printf("|>>>>>>>>>>>>>| NETCHANNEL TRACE ACTIVATED |<<<<<<<<<<<<<|\n"); @@ -257,8 +253,8 @@ void ToggleNetHooks() } else { - DetourDetach((LPVOID*)&NET_SendDatagram, &HNET_SendDatagram); - DetourDetach((LPVOID*)&NET_ReceiveDatagram, &HNET_ReceiveDatagram); + DetourDetach((LPVOID*)&org_NET_SendDatagram, &HNET_SendDatagram); + DetourDetach((LPVOID*)&org_NET_ReceiveDatagram, &HNET_ReceiveDatagram); printf("\n"); printf("+--------------------------------------------------------+\n"); printf("|>>>>>>>>>>>>| NETCHANNEL TRACE DEACTIVATED |<<<<<<<<<<<<|\n"); diff --git a/r5dev/src/id3dx.cpp b/r5dev/src/id3dx.cpp index 4c819294..d3199812 100644 --- a/r5dev/src/id3dx.cpp +++ b/r5dev/src/id3dx.cpp @@ -256,23 +256,22 @@ void SetupImGui() void DrawImGui() { - bool bShowMenu = false; + if (!GameGlobals::IsInitialized || !GameGlobals::InputSystem) // Check if GameGlobals initialized and if InputSystem is valid. + return; ImGui_ImplWin32_NewFrame(); ImGui_ImplDX11_NewFrame(); ImGui::NewFrame(); - static CInputSystem* InputSystem = *reinterpret_cast(0x14D40B380); - if (g_bShowMenu) { - InputSystem->EnableInput(false); // Disable input. - ShowGameConsole(&bShowMenu); + GameGlobals::InputSystem->EnableInput(false); // Disable input. + DrawMenu(); } - else if (!g_bShowMenu) + else { - InputSystem->EnableInput(true); // Enable input. + GameGlobals::InputSystem->EnableInput(true); // Enable input. } ImGui::EndFrame(); diff --git a/r5dev/src/overlay.cpp b/r5dev/src/overlay.cpp index 4324b0f0..8074485e 100644 --- a/r5dev/src/overlay.cpp +++ b/r5dev/src/overlay.cpp @@ -11,6 +11,7 @@ #include "id3dx.h" #include "console.h" #include "patterns.h" +#include "gameclasses.h" #include "imgui.h" #include "imgui_impl_dx11.h" @@ -22,449 +23,326 @@ #include #include +#define DebugOverlay + +CGameConsole* g_GameConsole = nullptr; + /*----------------------------------------------------------------------------- * _overlay.cpp *-----------------------------------------------------------------------------*/ -class CGameConsole +CGameConsole::CGameConsole() { -private: - /////////////////////////////////////////////////////////////////////////// - char InputBuf[256] = { 0 }; - ImVector Commands; - ImVector History; - int HistoryPos = -1; - ImGuiTextFilter Filter; - bool AutoScroll = true; - bool ScrollToBottom = false; - bool ThemeSet = false; + ClearLog(); + memset(InputBuf, 0, sizeof(InputBuf)); -public: - /////////////////////////////////////////////////////////////////////////// - CGameConsole() - { - ClearLog(); - memset(InputBuf, 0, sizeof(InputBuf)); + HistoryPos = -1; + AutoScroll = true; + ScrollToBottom = false; + ThemeSet = false; - HistoryPos = -1; - AutoScroll = true; - ScrollToBottom = false; - ThemeSet = false; - - Commands.push_back("HELP"); - Commands.push_back("HISTORY"); - Commands.push_back("CLEAR"); - Commands.push_back("CLASSIFY"); + Commands.push_back("HELP"); + Commands.push_back("HISTORY"); + Commands.push_back("CLEAR"); + Commands.push_back("CLASSIFY"); - AddLog("[DEBUG] THREAD ID: %ld\n", g_dThreadId); - } - ~CGameConsole() + AddLog("[DEBUG] THREAD ID: %ld\n", g_dThreadId); +} + +CGameConsole::~CGameConsole() +{ + ClearLog(); + for (int i = 0; i < History.Size; i++) { - ClearLog(); - for (int i = 0; i < History.Size; i++) { free(History[i]); } + free(History[i]); + } +} + +/////////////////////////////////////////////////////////////////////////// +// Draw + +void CGameConsole::Draw(const char* title) +{ + if (!ThemeSet) + { + SetStyleVar(); + ThemeSet = true; } - /////////////////////////////////////////////////////////////////////////// - // Internals - static int Stricmp(const char* s1, const char* s2) - { - int d; - while ((d = toupper(*s2) - toupper(*s1)) == 0 && *s1) - { - s1++; s2++; - } - return d; - } - static int Strnicmp(const char* s1, const char* s2, int n) - { - int d = 0; while (n > 0 && (d = toupper(*s2) - toupper(*s1)) == 0 && *s1) - { - s1++; s2++; n--; - } - return d; - } - static char* Strdup(const char* s) - { - IM_ASSERT(s); size_t len = strlen(s) + 1; void* buf = malloc(len); IM_ASSERT(buf); if (buf != NULL) - { - return (char*)memcpy(buf, (const void*)s, len); - } - return NULL; - } - static void Strtrim(char* s) - { - char* str_end = s + strlen(s); while (str_end > s && str_end[-1] == ' ') str_end--; *str_end = 0; - } + //ImGui::ShowStyleEditor(); - /////////////////////////////////////////////////////////////////////////// - // Utility - void ClearLog() + ImGui::SetNextWindowSize(ImVec2(840, 600), ImGuiCond_FirstUseEver); + ImGui::SetWindowPos(ImVec2(-1000, 50), ImGuiCond_FirstUseEver); + + if (!ImGui::Begin(title, NULL)) // Passing a bool only causes problems if you Begin a new window. I would not suggest to use it. { - for (int i = 0; i < Items.Size; i++) { free(Items[i]); } - Items.clear(); - } - void AddLog(const char* fmt, ...) IM_FMTARGS(2) - { - char buf[1024]; - va_list args; - va_start(args, fmt); - vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args); - buf[IM_ARRAYSIZE(buf) - 1] = 0; - va_end(args); - Items.push_back(Strdup(buf)); + ImGui::End(); return; } /////////////////////////////////////////////////////////////////////// - // Style - void SetStyleVar() + if (ImGui::SmallButton("Developer mode")) { - ImGuiStyle& style = ImGui::GetStyle(); - ImVec4* colors = style.Colors; + ToggleDevCommands(); + AddLog("+--------------------------------------------------------+\n"); + AddLog("|>>>>>>>>>>>>>>| DEVONLY COMMANDS TOGGLED |<<<<<<<<<<<<<<|\n"); + AddLog("+--------------------------------------------------------+\n"); + ProcessCommand("exec autoexec"); + } + ImGui::SameLine(); + if (ImGui::SmallButton("Netchannel Trace")) + { + ToggleNetHooks(); + AddLog("+--------------------------------------------------------+\n"); + AddLog("|>>>>>>>>>>>>>>| NETCHANNEL TRACE TOGGLED |<<<<<<<<<<<<<<|\n"); + AddLog("+--------------------------------------------------------+\n"); + ProcessCommand("exec netchan"); + } + /////////////////////////////////////////////////////////////////////// + ImGui::SameLine(); + if (ImGui::SmallButton("Clear")) + { + ClearLog(); + } + ImGui::SameLine(); + bool copy_to_clipboard = ImGui::SmallButton("Copy"); + ImGui::Separator(); + if (ImGui::BeginPopup("Options")) + { + ImGui::Checkbox("Auto-scroll", &AutoScroll); ImGui::EndPopup(); + } + if (ImGui::Button("Options")) + { + ImGui::OpenPopup("Options"); + } + ImGui::SameLine(); + Filter.Draw("Filter [\"-incl,-excl\"] [\"error\"]", 265); + ImGui::Separator(); - colors[ImGuiCol_Text] = ImVec4(0.81f, 0.81f, 0.81f, 1.00f); - colors[ImGuiCol_TextDisabled] = ImVec4(0.56f, 0.56f, 0.56f, 1.00f); - colors[ImGuiCol_WindowBg] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f); - colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); - colors[ImGuiCol_PopupBg] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f); - colors[ImGuiCol_Border] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); - colors[ImGuiCol_BorderShadow] = ImVec4(0.04f, 0.04f, 0.04f, 0.64f); - colors[ImGuiCol_FrameBg] = ImVec4(0.13f, 0.13f, 0.13f, 1.00f); - colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 1.00f); - colors[ImGuiCol_FrameBgActive] = ImVec4(0.24f, 0.24f, 0.24f, 1.00f); - colors[ImGuiCol_TitleBg] = ImVec4(0.22f, 0.22f, 0.22f, 1.00f); - colors[ImGuiCol_TitleBgActive] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f); - colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); - colors[ImGuiCol_MenuBarBg] = ImVec4(0.22f, 0.22f, 0.22f, 1.00f); - colors[ImGuiCol_ScrollbarBg] = ImVec4(0.10f, 0.10f, 0.10f, 1.00f); - colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); - colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f); - colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f); - colors[ImGuiCol_CheckMark] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); - colors[ImGuiCol_SliderGrab] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); - colors[ImGuiCol_SliderGrabActive] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f); - colors[ImGuiCol_Button] = ImVec4(0.35f, 0.35f, 0.35f, 1.00f); - colors[ImGuiCol_ButtonHovered] = ImVec4(0.45f, 0.45f, 0.45f, 1.00f); - colors[ImGuiCol_ButtonActive] = ImVec4(0.52f, 0.52f, 0.52f, 1.00f); - colors[ImGuiCol_Header] = ImVec4(0.35f, 0.35f, 0.35f, 1.00f); - colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.45f, 1.00f); - colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f); - colors[ImGuiCol_Separator] = ImVec4(0.53f, 0.53f, 0.57f, 1.00f); - colors[ImGuiCol_SeparatorHovered] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f); - colors[ImGuiCol_SeparatorActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f); - colors[ImGuiCol_ResizeGrip] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); - colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.52f, 0.52f, 0.52f, 1.00f); - colors[ImGuiCol_ResizeGripActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f); - colors[ImGuiCol_Tab] = ImVec4(0.18f, 0.18f, 0.18f, 1.00f); - colors[ImGuiCol_TabHovered] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); - colors[ImGuiCol_TabActive] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); + // Reserve enough left-over height for 1 separator + 1 input text + const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); - style.WindowBorderSize = 0.0f; - style.FrameBorderSize = 1.0f; - style.ChildBorderSize = 1.0f; - style.PopupBorderSize = 1.0f; - style.TabBorderSize = 1.0f; + /////////////////////////////////////////////////////////////////////// + ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), true, ImGuiWindowFlags_AlwaysVerticalScrollbar); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 4.f, 6.f }); + if (copy_to_clipboard) + { + ImGui::LogToClipboard(); + } + for (int i = 0; i < Items.Size; i++) + { + const char* item = Items[i]; + if (!Filter.PassFilter(item)) + { + continue; + } + /////////////////////////////////////////////////////////////////// + ImVec4 color; + bool has_color = false; - style.WindowRounding = 2.5f; - style.FrameRounding = 0.0f; - style.ChildRounding = 0.0f; - style.PopupRounding = 0.0f; - style.TabRounding = 1.0f; - style.ScrollbarRounding = 1.0f; + /////////////////////////////////////////////////////////////////// + // General + if (strstr(item, "[INFO]")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); has_color = true; } + if (strstr(item, "[ERROR]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } + if (strstr(item, "[DEBUG]")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; } + if (strstr(item, "[WARNING]")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; } + if (strncmp(item, "# ", 2) == 0) { color = ImVec4(1.00f, 0.80f, 0.60f, 1.00f); has_color = true; } - style.ItemSpacing = ImVec2(4, 4); - style.WindowPadding = ImVec2(5, 5); + /////////////////////////////////////////////////////////////////// + // Callbacks + if (strstr(item, "CodeCallback_")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; } + + /////////////////////////////////////////////////////////////////// + // Script errors + if (strstr(item, ".gnut")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); has_color = true; } + if (strstr(item, ".nut")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); has_color = true; } + if (strstr(item, "[CLIENT]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } + if (strstr(item, "[SERVER]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } + if (strstr(item, "[UI]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } + if (strstr(item, "SCRIPT ERROR")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } + if (strstr(item, "SCRIPT COMPILE")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } + if (strstr(item, ".gnut #")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } + if (strstr(item, ".nut #")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } + if (strstr(item, " -> ")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } + + /////////////////////////////////////////////////////////////////// + // Script debug + if (strstr(item, "CALLSTACK")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; } + if (strstr(item, "LOCALS")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; } + if (strstr(item, "*FUNCTION")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; } + if (strstr(item, "DIAGPRINTS")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; } + if (strstr(item, " File : ")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; } + if (strstr(item, "<><>GRX<><>")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; } + + /////////////////////////////////////////////////////////////////// + // Filters + if (strstr(item, ") -> ")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); has_color = true; } + /////////////////////////////////////////////////////////////////// + + if (has_color) { ImGui::PushStyleColor(ImGuiCol_Text, color); } + ImGui::TextWrapped(item); + if (has_color) { ImGui::PopStyleColor(); } + } + if (copy_to_clipboard) { ImGui::LogFinish(); } + + if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())) { ImGui::SetScrollHereY(1.0f); } + ScrollToBottom = false; + + /////////////////////////////////////////////////////////////////////// + ImGui::PopStyleVar(); + ImGui::EndChild(); + ImGui::Separator(); + + /////////////////////////////////////////////////////////////////////// + // Console + bool reclaim_focus = false; + ImGui::PushItemWidth(750); + if (ImGui::IsWindowAppearing()) { ImGui::SetKeyboardFocusHere(); } + ImGuiInputTextFlags input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory; + + if (ImGui::InputText("##input", InputBuf, IM_ARRAYSIZE(InputBuf), input_text_flags, &TextEditCallbackStub, (void*)this)) + { + char* s = InputBuf; + const char* replace = ""; + if (strstr(InputBuf, "`")) { strcpy_s(s, sizeof(replace), replace); } + Strtrim(s); + if (s[0]) { ProcessCommand(s); } + strcpy_s(s, sizeof(replace), replace); + reclaim_focus = true; + } + ImGui::SameLine(); + if (ImGui::Button("Submit")) + { + char* s = InputBuf; + const char* replace = ""; + if (s[0]) { ProcessCommand(s); } + strcpy_s(s, sizeof(replace), replace); + reclaim_focus = true; } - /////////////////////////////////////////////////////////////////////////// - // Draw - void Draw(const char* title, bool* p_open) - { - if (!ThemeSet) - { - SetStyleVar(); - ThemeSet = true; - } - - //ImGui::ShowStyleEditor(); - - ImGui::SetNextWindowSize(ImVec2(840, 600), ImGuiCond_FirstUseEver); - ImGui::SetWindowPos(ImVec2(-1000, 50), ImGuiCond_FirstUseEver); - - if (!ImGui::Begin(title, NULL)) // Passing a bool only causes problems if you Begin a new window. I would not suggest to use it. - { - ImGui::End(); return; - } - - /////////////////////////////////////////////////////////////////////// - if (ImGui::SmallButton("Developer mode")) - { - ToggleDevCommands(); - AddLog("+--------------------------------------------------------+\n"); - AddLog("|>>>>>>>>>>>>>>| DEVONLY COMMANDS TOGGLED |<<<<<<<<<<<<<<|\n"); - AddLog("+--------------------------------------------------------+\n"); - ProcessCommand("exec autoexec"); - } - ImGui::SameLine(); - if (ImGui::SmallButton("Netchannel Trace")) - { - ToggleNetHooks(); - AddLog("+--------------------------------------------------------+\n"); - AddLog("|>>>>>>>>>>>>>>| NETCHANNEL TRACE TOGGLED |<<<<<<<<<<<<<<|\n"); - AddLog("+--------------------------------------------------------+\n"); - ProcessCommand("exec netchan"); - } - /////////////////////////////////////////////////////////////////////// - ImGui::SameLine(); - if (ImGui::SmallButton("Clear")) - { - ClearLog(); - } - ImGui::SameLine(); - bool copy_to_clipboard = ImGui::SmallButton("Copy"); - ImGui::Separator(); - if (ImGui::BeginPopup("Options")) - { - ImGui::Checkbox("Auto-scroll", &AutoScroll); ImGui::EndPopup(); - } - if (ImGui::Button("Options")) - { - ImGui::OpenPopup("Options"); - } - ImGui::SameLine(); - Filter.Draw("Filter [\"-incl,-excl\"] [\"error\"]", 265); - ImGui::Separator(); - - // Reserve enough left-over height for 1 separator + 1 input text - const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); - - /////////////////////////////////////////////////////////////////////// - ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), true, ImGuiWindowFlags_AlwaysVerticalScrollbar); - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 4.f, 6.f }); - if (copy_to_clipboard) - { - ImGui::LogToClipboard(); - } - for (int i = 0; i < Items.Size; i++) - { - const char* item = Items[i]; - if (!Filter.PassFilter(item)) - { - continue; - } - /////////////////////////////////////////////////////////////////// - ImVec4 color; - bool has_color = false; - - /////////////////////////////////////////////////////////////////// - // General - if (strstr(item, "[INFO]")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); has_color = true; } - if (strstr(item, "[ERROR]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } - if (strstr(item, "[DEBUG]")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; } - if (strstr(item, "[WARNING]")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; } - if (strncmp(item, "# ", 2) == 0) { color = ImVec4(1.00f, 0.80f, 0.60f, 1.00f); has_color = true; } - - /////////////////////////////////////////////////////////////////// - // Callbacks - if (strstr(item, "CodeCallback_")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; } - - /////////////////////////////////////////////////////////////////// - // Script errors - if (strstr(item, ".gnut")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); has_color = true; } - if (strstr(item, ".nut")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); has_color = true; } - if (strstr(item, "[CLIENT]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } - if (strstr(item, "[SERVER]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } - if (strstr(item, "[UI]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } - if (strstr(item, "SCRIPT ERROR")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } - if (strstr(item, "SCRIPT COMPILE")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } - if (strstr(item, ".gnut #")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } - if (strstr(item, ".nut #")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } - if (strstr(item, " -> ")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } - - /////////////////////////////////////////////////////////////////// - // Script debug - if (strstr(item, "CALLSTACK")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; } - if (strstr(item, "LOCALS")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; } - if (strstr(item, "*FUNCTION")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; } - if (strstr(item, "DIAGPRINTS")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; } - if (strstr(item, " File : ")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; } - if (strstr(item, "<><>GRX<><>")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; } - - /////////////////////////////////////////////////////////////////// - // Filters - if (strstr(item, ") -> ")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); has_color = true; } - /////////////////////////////////////////////////////////////////// - - if (has_color) { ImGui::PushStyleColor(ImGuiCol_Text, color); } - ImGui::TextWrapped(item); - if (has_color) { ImGui::PopStyleColor(); } - } - if (copy_to_clipboard) { ImGui::LogFinish(); } - - if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())) { ImGui::SetScrollHereY(1.0f); } - ScrollToBottom = false; - - /////////////////////////////////////////////////////////////////////// - ImGui::PopStyleVar(); - ImGui::EndChild(); - ImGui::Separator(); - - /////////////////////////////////////////////////////////////////////// - // Console - bool reclaim_focus = false; - ImGui::PushItemWidth(750); - if (ImGui::IsWindowAppearing()) { ImGui::SetKeyboardFocusHere(); } - ImGuiInputTextFlags input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory; - - if (ImGui::InputText("##input", InputBuf, IM_ARRAYSIZE(InputBuf), input_text_flags, &TextEditCallbackStub, (void*)this)) - { - char* s = InputBuf; - const char* replace = ""; - if (strstr(InputBuf, "`")) { strcpy_s(s, sizeof(replace), replace); } - Strtrim(s); - if (s[0]) { ProcessCommand(s); } - strcpy_s(s, sizeof(replace), replace); - reclaim_focus = true; - } - ImGui::SameLine(); - if (ImGui::Button("Submit")) - { - char* s = InputBuf; - const char* replace = ""; - if (s[0]) { ProcessCommand(s); } - strcpy_s(s, sizeof(replace), replace); - reclaim_focus = true; - } - - // Auto-focus on window apparition - ImGui::SetItemDefaultFocus(); - if (reclaim_focus) - {// Auto focus previous widget - ImGui::SetKeyboardFocusHere(-1); - } - - ImGui::End(); + // Auto-focus on window apparition + ImGui::SetItemDefaultFocus(); + if (reclaim_focus) + {// Auto focus previous widget + ImGui::SetKeyboardFocusHere(-1); } - + ImGui::End(); +} +/////////////////////////////////////////////////////////////////////////// +// Exec +void CGameConsole::ProcessCommand(const char* command_line) +{ + std::thread t(&CGameConsole::ExecCommand, this, command_line); + t.detach(); - /////////////////////////////////////////////////////////////////////////// - // Exec - void ProcessCommand(const char* command_line) + // HACK: This is to avoid a race condition. + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + AddLog("# %s\n", command_line); + + HistoryPos = -1; + for (int i = History.Size - 1; i >= 0; i--) { - std::thread t(&CGameConsole::ExecCommand, this, command_line); - t.detach(); - - // HACK: This is to avoid a race condition. - Sleep(1); - AddLog("# %s\n", command_line); - - HistoryPos = -1; - for (int i = History.Size - 1; i >= 0; i--) + if (Stricmp(History[i], command_line) == 0) { - if (Stricmp(History[i], command_line) == 0) + free(History[i]); + History.erase(History.begin() + i); + break; + } + } + + History.push_back(Strdup(command_line)); + if (Stricmp(command_line, "CLEAR") == 0) + { + ClearLog(); + } + else if (Stricmp(command_line, "HELP") == 0) + { + AddLog("Commands:"); + for (int i = 0; i < Commands.Size; i++) + { + AddLog("- %s", Commands[i]); + } + } + else if (Stricmp(command_line, "HISTORY") == 0) + { + int first = History.Size - 10; + for (int i = first > 0 ? first : 0; i < History.Size; i++) + { + AddLog("%3d: %s\n", i, History[i]); + } + } + + ScrollToBottom = true; +} + +void CGameConsole::ExecCommand(const char* command_line) +{ + CommandExecute(NULL, command_line); +} + +/////////////////////////////////////////////////////////////////////////// +// Edit +int CGameConsole::TextEditCallback(ImGuiInputTextCallbackData* data) +{ + switch (data->EventFlag) + { + case ImGuiInputTextFlags_CallbackCompletion: + { + // Locate beginning of current word + const char* word_end = data->Buf + data->CursorPos; + const char* word_start = word_end; + while (word_start > data->Buf) + { + const char c = word_start[-1]; + if (c == ' ' || c == '\t' || c == ',' || c == ';') { - free(History[i]); - History.erase(History.begin() + i); break; } + word_start--; } - - History.push_back(Strdup(command_line)); - if (Stricmp(command_line, "CLEAR") == 0) - { - ClearLog(); - } - else if (Stricmp(command_line, "HELP") == 0) - { - AddLog("Commands:"); - for (int i = 0; i < Commands.Size; i++) { AddLog("- %s", Commands[i]); } - } - else if (Stricmp(command_line, "HISTORY") == 0) - { - int first = History.Size - 10; - for (int i = first > 0 ? first : 0; i < History.Size; i++) { AddLog("%3d: %s\n", i, History[i]); } - } - - ScrollToBottom = true; + break; } - void ExecCommand(const char* command_line) + case ImGuiInputTextFlags_CallbackHistory: { - CommandExecute(NULL, command_line); - } - - /////////////////////////////////////////////////////////////////////////// - // History - static int TextEditCallbackStub(ImGuiInputTextCallbackData* data) - { - CGameConsole* console = (CGameConsole*)data->UserData; - return console->TextEditCallback(data); - } - - /////////////////////////////////////////////////////////////////////////// - // Edit - int TextEditCallback(ImGuiInputTextCallbackData* data) - { - switch (data->EventFlag) + const int prev_history_pos = HistoryPos; + if (data->EventKey == ImGuiKey_UpArrow) { - case ImGuiInputTextFlags_CallbackCompletion: + if (HistoryPos == -1) { HistoryPos = History.Size - 1; } + else if (HistoryPos > 0) { HistoryPos--; } + } + else if (data->EventKey == ImGuiKey_DownArrow) + { + if (HistoryPos != -1) { - // Locate beginning of current word - const char* word_end = data->Buf + data->CursorPos; - const char* word_start = word_end; - while (word_start > data->Buf) + if (++HistoryPos >= History.Size) { - const char c = word_start[-1]; - if (c == ' ' || c == '\t' || c == ',' || c == ';') - { - break; - } - word_start--; - } - break; - } - case ImGuiInputTextFlags_CallbackHistory: - { - const int prev_history_pos = HistoryPos; - if (data->EventKey == ImGuiKey_UpArrow) - { - if (HistoryPos == -1) { HistoryPos = History.Size - 1; } - else if (HistoryPos > 0) { HistoryPos--; } - } - else if (data->EventKey == ImGuiKey_DownArrow) - { - if (HistoryPos != -1) - { - if (++HistoryPos >= History.Size) - { - HistoryPos = -1; - } - } - } - if (prev_history_pos != HistoryPos) - { - const char* history_str = (HistoryPos >= 0) ? History[HistoryPos] : ""; - data->DeleteChars(0, data->BufTextLen); - data->InsertChars(0, history_str); + HistoryPos = -1; } } } - return 0; + if (prev_history_pos != HistoryPos) + { + const char* history_str = (HistoryPos >= 0) ? History[HistoryPos] : ""; + data->DeleteChars(0, data->BufTextLen); + data->InsertChars(0, history_str); + } } -}; + } + return 0; +} +/////////////////////////////////////////////////////////////////////////// +// Companion CCompanion::CCompanion() { memset(MatchmakingServerStringBuffer, 0, sizeof(MatchmakingServerStringBuffer)); memset(ServerNameBuffer, 0, sizeof(ServerNameBuffer)); memset(ServerConnStringBuffer, 0, sizeof(ServerConnStringBuffer)); - - strcpy_s(MatchmakingServerStringBuffer, "r5a-comp-sv.herokuapp.com"); - std::string path = "stbsp"; for (const auto& entry : std::filesystem::directory_iterator(path)) { @@ -475,355 +353,296 @@ CCompanion::CCompanion() MapsList.push_back(filename); } - SelectedMap = &MapsList[0]; + SelectedMap = &MapsList[0]; - //RefreshServerList(); - - static std::thread HostingServerRequestThread([this]() + static std::thread HostingServerRequestThread([this]() + { + while (true) { - while(true) - { - UpdateHostingStatus(); - std::this_thread::sleep_for(std::chrono::milliseconds(5000)); - } - }); - HostingServerRequestThread.detach(); + UpdateHostingStatus(); + std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + } + }); + HostingServerRequestThread.detach(); } - void CCompanion::UpdateHostingStatus() - { - std::string lastMap = GetGameStateLastMap(); +void CCompanion::UpdateHostingStatus() +{ + if (!GameGlobals::HostState) // Is HostState valid? + return; - switch(HostingStatus) + GameGlobals::HostState->m_bActiveGame ? HostingStatus = EHostStatus::Hosting : HostingStatus = EHostStatus::NotHosting; // Are we hosting a server? + + switch (HostingStatus) + { + case EHostStatus::NotHosting: + { + break; + } + case EHostStatus::Hosting: + { + SendHostingPostRequest(GameGlobals::HostState->m_levelName); + break; + } + default: + break; + } +} + +void CCompanion::RefreshServerList() +{ + ServerList.clear(); + + static bool bThreadLocked = false; + + if (!bThreadLocked) + { + std::thread t([this]() { - case EHostStatus::NotHosting: - { - if(lastMap != "no_map" && lastMap != "") - HostingStatus = EHostStatus::ConnectedToSomeoneElse; - break; - } - case EHostStatus::WaitingForStateChange: +#ifdef DebugOverlay + std::cout << " [+CCompanion+] Refreshing server list with string" << MatchmakingServerStringBuffer << "\n"; +#endif + bThreadLocked = true; + httplib::Client client(MatchmakingServerStringBuffer); + client.set_connection_timeout(10); + auto res = client.Get("/servers"); + if (res) { - if(lastMap != "no_map" && lastMap != "") - HostingStatus = EHostStatus::Hosting; - break; - } - case EHostStatus::Hosting: - { - if (lastMap == "no_map" || lastMap == "") - HostingStatus = EHostStatus::NotHosting; - else SendHostingPostRequest(); - break; - } - case EHostStatus::ConnectedToSomeoneElse: - { - if(lastMap == "no_map" || lastMap == "") + nlohmann::json root = nlohmann::json::parse(res->body); + for (auto obj : root["servers"]) { - HostingStatus = EHostStatus::NotHosting; + ServerList.push_back( + new ServerListing(obj["name"], obj["map"], obj["ip"], obj["version"], obj["expire"]) + ); } - break; } - } + bThreadLocked = false; + }); + + t.detach(); } +} - std::string CCompanion::GetGameStateLastMap() +void CCompanion::SendHostingPostRequest(char* mapName) +{ + httplib::Client client(MatchmakingServerStringBuffer); + client.set_connection_timeout(10); + + // send a post request to "/servers/add" with a json body + nlohmann::json body = nlohmann::json::object(); + body["name"] = ServerNameBuffer; + body["map"] = mapName; + body["version"] = "1.0"; + + std::string body_str = body.dump(); + +#ifdef DebugOverlay + std::cout << " [+CCompanion+] Sending request now, Body:" << body_str << "\n"; +#endif + + httplib::Result result = client.Post("/servers/add", body_str.c_str(), body_str.length(), "application/json"); +#ifdef DebugOverlay + if (result) { + std::cout << " [+CCompanion+] Request Result: " << result->body << "\n"; + } +#endif +} - // I know you're gonna comment abt this function; but I dont think it's necessary to include a fully-fledged VDF parser for now +void CCompanion::CompMenu() +{ + ImGui::BeginTabBar("CompMenu"); + if (ImGui::TabItemButton("Server Browser")) + { + SetSection(ESection::ServerBrowser); + } + if (ImGui::TabItemButton("Host Server")) + { + SetSection(ESection::HostServer); + } + if (ImGui::TabItemButton("Settings")) + { + SetSection(ESection::Settings); + } + ImGui::EndTabBar(); +} - wchar_t* savedGamesPath = new wchar_t[256]; +void CCompanion::ServerBrowserSection() +{ + ImGui::BeginGroup(); + ServerBrowserFilter.Draw(); + ImGui::SameLine(); + if (ImGui::Button("Refresh List")) + { + RefreshServerList(); + } + ImGui::EndGroup(); + ImGui::Separator(); - SHGetKnownFolderPath(FOLDERID_SavedGames, KF_FLAG_CREATE, nullptr, &savedGamesPath); - - if (savedGamesPath == nullptr) return ""; - - std::wstringstream filePath; - - filePath << savedGamesPath; - filePath << "\\Respawn\\Apex\\local\\previousgamestate.txt"; - - CoTaskMemFree(static_cast(savedGamesPath)); - - std::ifstream f(filePath.str()); - std::string line; - - - for(int i = 0; i < 7; i++) + ImGui::BeginChild("ServerListChild", { 0, 780 }, false, ImGuiWindowFlags_HorizontalScrollbar); + { + ImGui::BeginTable("bumbumceau", 6); { - std::getline(f, line); - } - - // returns the substring of the line that contains only the map name - return line.substr(35, line.size() - 35 - 1); - + ImGui::TableSetupColumn("Name", 0, 35); + ImGui::TableSetupColumn("IP Address", 0, 20); + ImGui::TableSetupColumn("Map", 0, 25); + ImGui::TableSetupColumn("Version", 0, 10); + ImGui::TableSetupColumn("Expiry", 0, 10); + ImGui::TableSetupColumn("", 0, 8); + ImGui::TableHeadersRow(); - } + for (ServerListing* server : ServerList) + { + const char* name = server->name.c_str(); + const char* ip = server->ip.c_str(); + const char* map = server->map.c_str(); + const char* version = server->version.c_str(); + int expiry = server->expiry; - void CCompanion::RefreshServerList() - { - ServerList.clear(); - - static bool bThreadLocked = false; - - if (!bThreadLocked) { - std::thread t([this]() { - std::cout << "Refreshing server list with string" << MatchmakingServerStringBuffer << std::endl; - bThreadLocked = true; - httplib::Client client(MatchmakingServerStringBuffer); - client.set_connection_timeout(10); - auto res = client.Get("/servers"); - if (res) + if (ServerBrowserFilter.PassFilter(name) + || ServerBrowserFilter.PassFilter(ip) + || ServerBrowserFilter.PassFilter(map) + || ServerBrowserFilter.PassFilter(version)) { - json root = json::parse(res->body); - for (auto obj : root["servers"]) + ImGui::TableNextColumn(); + ImGui::Text(name); + ImGui::TableNextColumn(); + + ImGui::Text(ip); + ImGui::TableNextColumn(); + + ImGui::Text(map); + ImGui::TableNextColumn(); + + ImGui::Text(version); + ImGui::TableNextColumn(); + + std::stringstream expirySS; + expirySS << expiry << " seconds left"; + ImGui::Text(expirySS.str().c_str()); + ImGui::TableNextColumn(); + + std::string selectButtonText = "Connect##"; + selectButtonText += (server->name + server->ip + server->map); + + if (ImGui::Button(selectButtonText.c_str())) { - ServerList.push_back( - new ServerListing(obj["name"], obj["map"], obj["ip"], obj["version"], obj["expire"]) - ); + SelectedServer = server; + server->Select(); } } - bThreadLocked = false; - }); - t.detach(); - } - - - - - } - - void CCompanion::SendHostingPostRequest() - { - httplib::Client client(MatchmakingServerStringBuffer); - client.set_connection_timeout(10); - // send a post request to "/servers/add" with a json body - json body = json::object(); - body["name"] = ServerNameBuffer; - body["map"] = *SelectedMap; - body["version"] = "1.0"; - - std::string body_str = body.dump(); - - std::cout << body_str << "\n"; - - auto res = client.Post("/servers/add", body_str.c_str(), body_str.length(), "application/json"); - if (res) - { - std::cout << "Hosting Request Result: " << res->body << "\n"; - } - } - - - void CCompanion::SetSection(ESection section) - { - CurrentSection = section; - } - - - void CCompanion::CompMenu() - { - ImGui::BeginTabBar("CompMenu"); - if (ImGui::TabItemButton("Server Browser")) - { - SetSection(ESection::ServerBrowser); - } - if (ImGui::TabItemButton("Host Server")) - { - SetSection(ESection::HostServer); - } - if (ImGui::TabItemButton("Settings")) - { - SetSection(ESection::Settings); - } - ImGui::EndTabBar(); - } - - void CCompanion::ServerBrowserSection() - { - - ImGui::BeginGroup(); - ServerBrowserFilter.Draw(); - ImGui::SameLine(); - if (ImGui::Button("Refresh List")) - { - RefreshServerList(); - } - ImGui::EndGroup(); - ImGui::Separator(); - - ImGui::BeginChild("ServerListChild", { 0, 780 }, false, ImGuiWindowFlags_HorizontalScrollbar); - - ImGui::BeginTable("bumbumceau", 6); - - ImGui::TableSetupColumn("Name", 0, 35); - ImGui::TableSetupColumn("IP Address", 0, 20); - ImGui::TableSetupColumn("Map", 0, 25); - ImGui::TableSetupColumn("Version", 0, 10); - ImGui::TableSetupColumn("Expiry", 0, 10); - ImGui::TableSetupColumn("", 0, 8); - ImGui::TableHeadersRow(); - - for (ServerListing* server : ServerList) - { - const char* name = server->name.c_str(); - const char* ip = server->ip.c_str(); - const char* map = server->map.c_str(); - const char* version = server->version.c_str(); - int expiry = server->expiry; - - if (ServerBrowserFilter.PassFilter(name) - || ServerBrowserFilter.PassFilter(ip) - || ServerBrowserFilter.PassFilter(map) - || ServerBrowserFilter.PassFilter(version)) - { - ImGui::TableNextColumn(); - ImGui::Text(name); - ImGui::TableNextColumn(); - - ImGui::Text(ip); - ImGui::TableNextColumn(); - - ImGui::Text(map); - ImGui::TableNextColumn(); - - ImGui::Text(version); - ImGui::TableNextColumn(); - - std::stringstream expirySS; - expirySS << expiry << " seconds left"; - ImGui::Text(expirySS.str().c_str()); - ImGui::TableNextColumn(); - - std::string selectButtonText = "Connect##"; - selectButtonText += (server->name + server->ip + server->map); - - if (ImGui::Button(selectButtonText.c_str())) - { - SelectedServer = server; - server->Select(); - } } - } - ImGui::EndTable(); - ImGui::EndChild(); + } + ImGui::EndChild(); - ImGui::Separator(); - ImGui::InputTextWithHint("##ServerBrowser_ServerConnString", "Enter an ip address or \"localhost\"", ServerConnStringBuffer, IM_ARRAYSIZE(ServerConnStringBuffer)); - ImGui::SameLine(); - if (ImGui::Button("Connect to the server", ImVec2(ImGui::GetWindowSize().x * (1.f / 3.f), 19))) + ImGui::Separator(); + ImGui::InputTextWithHint("##ServerBrowser_ServerConnString", "Enter an ip address or \"localhost\"", ServerConnStringBuffer, IM_ARRAYSIZE(ServerConnStringBuffer)); + ImGui::SameLine(); + if (ImGui::Button("Connect to the server", ImVec2(ImGui::GetWindowSize().x * (1.f / 3.f), 19))) + { + std::stringstream cmd; + cmd << "connect " << ServerConnStringBuffer; + g_GameConsole->ProcessCommand(cmd.str().c_str()); + } +} + +void CCompanion::HostServerSection() +{ + ImGui::InputTextWithHint("Server Name##ServerHost_ServerName", "Required Field", ServerNameBuffer, IM_ARRAYSIZE(ServerNameBuffer)); + ImGui::Spacing(); + if (ImGui::BeginCombo("Map##ServerHost_MapListBox", SelectedMap->c_str())) + { + for (auto& item : MapsList) { + if (ImGui::Selectable(item.c_str(), &item == SelectedMap)) + { + SelectedMap = &item; + } + } + ImGui::EndCombo(); + } + ImGui::Spacing(); + + ImGui::Checkbox("Start as dedicated server (HACK)##ServerHost_DediCheckbox", &StartAsDedi); + + ImGui::Separator(); + + if (ImGui::Button("Start The Server##ServerHost_StartServerButton", ImVec2(ImGui::GetWindowSize().x, 32))) + { + if (strcmp(ServerNameBuffer, "") != 0) + { + UpdateHostingStatus(); + std::stringstream cmd; - cmd << "connect " << ServerConnStringBuffer; - RunConsoleCommand(cmd.str().c_str()); + cmd << "map " << SelectedMap->c_str(); + g_GameConsole->ProcessCommand(cmd.str().c_str()); + + if (StartAsDedi) + { + ToggleDevCommands(); + } } } - void CCompanion::HostServerSection() + if (strcmp(ServerNameBuffer, "") == 0) + ImGui::TextColored(ImVec4(1.00f, 0.00f, 0.00f, 1.00f), "ERROR: Please specify a name for the server!"); + + if (StartAsDedi) { - ImGui::InputTextWithHint("Server Name##ServerHost_ServerName", "Required Field", ServerNameBuffer, IM_ARRAYSIZE(ServerNameBuffer)); - ImGui::Spacing(); - if (ImGui::BeginCombo("Map##ServerHost_MapListBox", SelectedMap->c_str())) + if (ImGui::Button("Reload Scripts##ServerHost_ReloadServerButton", ImVec2(ImGui::GetWindowSize().x, 32))) { - for (auto& item : MapsList) - { - if (ImGui::Selectable(item.c_str(), &item == SelectedMap)) - { - SelectedMap = &item; - } - } - ImGui::EndCombo(); + g_GameConsole->ProcessCommand("reparse_weapons"); + g_GameConsole->ProcessCommand("reload"); } - ImGui::Spacing(); - - ImGui::Checkbox("Start as dedicated server (HACK)##ServerHost_DediCheckbox", &StartAsDedi); - - ImGui::Separator(); - - if (ImGui::Button("Start The Server##ServerHost_StartServerButton", ImVec2(ImGui::GetWindowSize().x, 32))) + if (ImGui::Button("Stop The Server##ServerHost_StopServerButton", ImVec2(ImGui::GetWindowSize().x, 32))) { - - if (strcmp(ServerNameBuffer, "") != 0) - { - UpdateHostingStatus(); - if(HostingStatus == EHostStatus::NotHosting) - HostingStatus = EHostStatus::WaitingForStateChange; - UpdateHostingStatus(); - - std::stringstream cmd; - cmd << "map " << SelectedMap->c_str(); - RunConsoleCommand(cmd.str()); - if (StartAsDedi) - { - ToggleDevCommands(); - } - - } + g_GameConsole->ProcessCommand("disconnect"); } - if (strcmp(ServerNameBuffer, "") == 0) ImGui::TextColored(ImVec4(1.00f, 0.00f, 0.00f, 1.00f), "ERROR: Please specify a name for the server!"); - if (StartAsDedi) - { - if (ImGui::Button("Reload Scripts##ServerHost_ReloadServerButton", ImVec2(ImGui::GetWindowSize().x, 32))) - { - RunConsoleCommand("reparse_weapons"); - RunConsoleCommand("reload"); - } - if (ImGui::Button("Stop The Server##ServerHost_StopServerButton", ImVec2(ImGui::GetWindowSize().x, 32))) - { - RunConsoleCommand("disconnect"); - } - } - - } +} - void CCompanion::SettingsSection() +void CCompanion::SettingsSection() +{ + ImGui::InputText("Matchmaking Server String", MatchmakingServerStringBuffer, IM_ARRAYSIZE(MatchmakingServerStringBuffer), 0); +} + +void CCompanion::Draw(const char* title) +{ + ImGui::SetNextWindowSize(ImVec2(800, 890), ImGuiCond_FirstUseEver); + ImGui::SetWindowPos(ImVec2(-500, 50), ImGuiCond_FirstUseEver); + + if (!ImGui::Begin(title, NULL)) { - ImGui::InputText("Matchmaking Server String", MatchmakingServerStringBuffer, IM_ARRAYSIZE(MatchmakingServerStringBuffer), 0); - } - - - void CCompanion::Draw(const char* title, bool* p_open) - { - ImGui::SetNextWindowSize(ImVec2(800, 890), ImGuiCond_FirstUseEver); - ImGui::SetWindowPos(ImVec2(-500, 50), ImGuiCond_FirstUseEver); - - if (!ImGui::Begin(title, NULL)) - { - ImGui::End(); return; - } - /////////////////////////////////////////////////////////////////////// - CompMenu(); - - switch (CurrentSection) - { - case ESection::ServerBrowser: - ServerBrowserSection(); - break; - - case ESection::HostServer: - HostServerSection(); - break; - - case ESection::Settings: - SettingsSection(); - break; - - - default: - break; - } - ImGui::End(); + return; + } + /////////////////////////////////////////////////////////////////////// + CompMenu(); + + switch (CurrentSection) + { + case ESection::ServerBrowser: + ServerBrowserSection(); + break; + case ESection::HostServer: + HostServerSection(); + break; + case ESection::Settings: + SettingsSection(); + break; + default: + break; } -//############################################################################# -// INTERNALS -//############################################################################# + ImGui::End(); +} +/////////////////////////////////////////////////////////////////////////// +// Internals int Stricmp(const char* s1, const char* s2) { int d; @@ -833,6 +652,7 @@ int Stricmp(const char* s1, const char* s2) } return d; } + int Strnicmp(const char* s1, const char* s2, int n) { int d = 0; while (n > 0 && (d = toupper(*s2) - toupper(*s1)) == 0 && *s1) @@ -841,6 +661,7 @@ int Strnicmp(const char* s1, const char* s2, int n) } return d; } + char* Strdup(const char* s) { IM_ASSERT(s); size_t len = strlen(s) + 1; void* buf = malloc(len); IM_ASSERT(buf); if (buf != NULL) @@ -849,9 +670,13 @@ char* Strdup(const char* s) } return NULL; } -void Strtrim(char* s) + +void Strtrim(char* s) { - char* str_end = s + strlen(s); while (str_end > s && str_end[-1] == ' ') str_end--; *str_end = 0; + char* str_end = s + strlen(s); + + while (str_end > s && str_end[-1] == ' ') + str_end--; *str_end = 0; } @@ -859,17 +684,11 @@ void Strtrim(char* s) // ENTRYPOINT //############################################################################# -void ShowGameConsole(bool* p_open) +void DrawMenu() { static CGameConsole console; + g_GameConsole = &console; static CCompanion browser; - console.Draw("Console", p_open); - browser.Draw("Companion", p_open); -} - - -void RunConsoleCommand(std::string command) -{ - static CGameConsole console; - console.ProcessCommand(command.c_str()); + console.Draw("Console"); + browser.Draw("Companion"); } \ No newline at end of file diff --git a/r5dev/src/serverlisting.cpp b/r5dev/src/serverlisting.cpp index 7313c560..3437a415 100644 --- a/r5dev/src/serverlisting.cpp +++ b/r5dev/src/serverlisting.cpp @@ -11,10 +11,9 @@ ServerListing::ServerListing(std::string name, std::string map, std::string ip, this->expiry = expiry; } -bool ServerListing::Select() +void ServerListing::Select() { std::stringstream cmd; cmd << "connect " << this->ip; - RunConsoleCommand(cmd.str().c_str()); - return true; + g_GameConsole->ProcessCommand(cmd.str().c_str()); } \ No newline at end of file From b98f1c94a323249c9795f6a2ba7cdb9d85a07a9e Mon Sep 17 00:00:00 2001 From: IcePixelx <41352111+PixieCore@users.noreply.github.com> Date: Sun, 18 Jul 2021 17:38:59 +0200 Subject: [PATCH 2/2] re-named console variables. --- r5dev/include/patterns.h | 6 +++--- r5dev/src/console.cpp | 16 ++++++++-------- r5dev/src/overlay.cpp | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/r5dev/include/patterns.h b/r5dev/include/patterns.h index 78e8079e..a130b08f 100644 --- a/r5dev/include/patterns.h +++ b/r5dev/include/patterns.h @@ -10,13 +10,13 @@ namespace //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* ==== CONSOLE ========================================================================================================================================================= */ DWORD64 p_CommandExecute = /*0x140202090*/ reinterpret_cast(PatternScan("r5apex.exe", "48 89 5C 24 ? 57 48 83 EC 20 48 8D 0D ? ? ? ? 41 8B D8")); - void (*CommandExecute)(void* self, const char* cmd) = (void (*)(void*, const char*))p_CommandExecute; + void (*org_CommandExecute)(void* self, const char* cmd) = (void (*)(void*, const char*))p_CommandExecute; DWORD64 p_ConVar_IsFlagSet = /*0x14046FE90*/ reinterpret_cast(PatternScan("r5apex.exe", "48 8B 41 48 85 50 38")); - bool (*ConVar_IsFlagSet)(int** cvar, int flag) = (bool (*)(int**, int))p_ConVar_IsFlagSet; + bool (*org_ConVar_IsFlagSet)(int** cvar, int flag) = (bool (*)(int**, int))p_ConVar_IsFlagSet; DWORD64 p_ConCommand_IsFlagSet = /*0x14046F490*/ reinterpret_cast(PatternScan("r5apex.exe", "85 51 38 0F 95 C0 C3")); - bool (*ConCommand_IsFlagSet)(int* cmd, int flag) = (bool (*)(int*, int))p_ConCommand_IsFlagSet; + bool (*org_ConCommand_IsFlagSet)(int* cmd, int flag) = (bool (*)(int*, int))p_ConCommand_IsFlagSet; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* ==== SQUIRREL ======================================================================================================================================================== */ diff --git a/r5dev/src/console.cpp b/r5dev/src/console.cpp index e322b91e..a12c6d51 100644 --- a/r5dev/src/console.cpp +++ b/r5dev/src/console.cpp @@ -136,12 +136,12 @@ DWORD __stdcall ProcessConsoleWorker(LPVOID) if (sCommand == "console test") { g_bDebugConsole = !g_bDebugConsole; continue; } /////////////////////////////////////////////////////////////////////// // Exec toggles - if (sCommand == "1") { ToggleDevCommands(); CommandExecute(NULL, "exec autoexec_dev"); } + if (sCommand == "1") { ToggleDevCommands(); org_CommandExecute(NULL, "exec autoexec_dev"); } if (sCommand == "2") { g_bDebugLoading = !g_bDebugLoading; continue; } /////////////////////////////////////////////////////////////////////// // Execute the command in the r5 SQVM - CommandExecute(NULL, sCommand.c_str()); + org_CommandExecute(NULL, sCommand.c_str()); sCommand.clear(); /////////////////////////////////////////////////////////////////////// @@ -165,8 +165,8 @@ void RemoveCMHooks() /////////////////////////////////////////////////////////////////////////// // Unhook Console functions - DetourDetach((LPVOID*)&ConVar_IsFlagSet, &HConVar_IsFlagSet); - DetourDetach((LPVOID*)&ConCommand_IsFlagSet, &HConCommand_IsFlagSet); + DetourDetach((LPVOID*)&org_ConVar_IsFlagSet, &HConVar_IsFlagSet); + DetourDetach((LPVOID*)&org_ConCommand_IsFlagSet, &HConCommand_IsFlagSet); /////////////////////////////////////////////////////////////////////////// // Commit the transaction @@ -186,8 +186,8 @@ void ToggleDevCommands() if (!g_dev) { - DetourAttach((LPVOID*)&ConVar_IsFlagSet, &HConVar_IsFlagSet); - DetourAttach((LPVOID*)&ConCommand_IsFlagSet, &HConCommand_IsFlagSet); + DetourAttach((LPVOID*)&org_ConVar_IsFlagSet, &HConVar_IsFlagSet); + DetourAttach((LPVOID*)&org_ConCommand_IsFlagSet, &HConCommand_IsFlagSet); printf("\n"); printf("+--------------------------------------------------------+\n"); printf("|>>>>>>>>>>>>>| DEVONLY COMMANDS ACTIVATED |<<<<<<<<<<<<<|\n"); @@ -197,8 +197,8 @@ void ToggleDevCommands() } else { - DetourDetach((LPVOID*)&ConVar_IsFlagSet, &HConVar_IsFlagSet); - DetourDetach((LPVOID*)&ConCommand_IsFlagSet, &HConCommand_IsFlagSet); + DetourDetach((LPVOID*)&org_ConVar_IsFlagSet, &HConVar_IsFlagSet); + DetourDetach((LPVOID*)&org_ConCommand_IsFlagSet, &HConCommand_IsFlagSet); printf("\n"); printf("+--------------------------------------------------------+\n"); printf("|>>>>>>>>>>>>| DEVONLY COMMANDS DEACTIVATED |<<<<<<<<<<<<|\n"); diff --git a/r5dev/src/overlay.cpp b/r5dev/src/overlay.cpp index 8074485e..44c9535d 100644 --- a/r5dev/src/overlay.cpp +++ b/r5dev/src/overlay.cpp @@ -279,7 +279,7 @@ void CGameConsole::ProcessCommand(const char* command_line) void CGameConsole::ExecCommand(const char* command_line) { - CommandExecute(NULL, command_line); + org_CommandExecute(NULL, command_line); } ///////////////////////////////////////////////////////////////////////////