From 768f2341f19d1e2e9b8fd05d1d667f46ab21dc71 Mon Sep 17 00:00:00 2001 From: IcePixelx <41352111+PixieCore@users.noreply.github.com> Date: Tue, 17 Aug 2021 23:02:14 +0200 Subject: [PATCH 01/14] Added separate function to resolve relative addresses in address.h --- shared/include/address.h | 48 +++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/shared/include/address.h b/shared/include/address.h index 9a9d88b6..a595bc55 100644 --- a/shared/include/address.h +++ b/shared/include/address.h @@ -276,26 +276,21 @@ public: MemoryAddress FollowNearCall(std::ptrdiff_t opcodeOffset = 0x1, std::ptrdiff_t nextInstructionOffset = 0x5) { - // Skip E9 opcode. - std::uintptr_t skipOpCode = ptr + opcodeOffset; - - // Get 4-byte long relative address. - std::int32_t relativeAddress = *reinterpret_cast(skipOpCode); - - // Get location of next instruction. - std::uintptr_t nextInstruction = ptr + nextInstructionOffset; - - // Get function location via adding relative address to next instruction. - return MemoryAddress(nextInstruction + relativeAddress); + return ResolveRelativeAddress(opcodeOffset, nextInstructionOffset); } MemoryAddress FollowNearCallSelf(std::ptrdiff_t opcodeOffset = 0x1, std::ptrdiff_t nextInstructionOffset = 0x5) { - // Skip E9 opcode. - std::uintptr_t skipOpCode = ptr + opcodeOffset; + return ResolveRelativeAddressSelf(opcodeOffset, nextInstructionOffset); + } + + MemoryAddress ResolveRelativeAddressSelf(std::ptrdiff_t registerOffset = 0x1, std::ptrdiff_t nextInstructionOffset = 0x4) + { + // Skip register. + std::uintptr_t skipRegister = ptr + registerOffset; // Get 4-byte long relative address. - std::int32_t relativeAddress = *reinterpret_cast(skipOpCode); + std::int32_t relativeAddress = *reinterpret_cast(skipRegister); // Get location of next instruction. std::uintptr_t nextInstruction = ptr + nextInstructionOffset; @@ -304,7 +299,22 @@ public: ptr = nextInstruction + relativeAddress; return *this; } - + + MemoryAddress ResolveRelativeAddress(std::ptrdiff_t registerOffset = 0x1, std::ptrdiff_t nextInstructionOffset = 0x4) + { + // Skip register. + std::uintptr_t skipRegister = ptr + registerOffset; + + // Get 4-byte long relative address. + std::int32_t relativeAddress = *reinterpret_cast(skipRegister); + + // Get location of next instruction. + std::uintptr_t nextInstruction = ptr + nextInstructionOffset; + + // Get function location via adding relative address to next instruction. + return MemoryAddress(nextInstruction + relativeAddress); + } + private: std::uintptr_t ptr = 0; }; @@ -339,14 +349,6 @@ public: return ModuleSections(); } - void PrintSections() - { - for (ModuleSections& currentSection : moduleSections) - { - printf(" [+Module: %s+]%s, %p\n", moduleName.c_str(), currentSection.sectionName.c_str(), reinterpret_cast(currentSection.sectionStartAddress)); - } - } - Module() = default; Module(std::string moduleName) : moduleName(moduleName) { From 7e7717ff68b5e177e58dd3e7989f35740cdc9236 Mon Sep 17 00:00:00 2001 From: IcePixelx <41352111+PixieCore@users.noreply.github.com> Date: Tue, 17 Aug 2021 23:03:21 +0200 Subject: [PATCH 02/14] Added new patterns to the print function. --- r5dev/include/patterns.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/r5dev/include/patterns.h b/r5dev/include/patterns.h index fe68f6a0..c7f78b70 100644 --- a/r5dev/include/patterns.h +++ b/r5dev/include/patterns.h @@ -23,8 +23,10 @@ namespace /*0x141057FD0*/ FUNC_AT_ADDRESS(addr_SQVM_Print, void*, r5_patterns.PatternSearch("83 F8 01 48 8D 3D ? ? ? ?").OffsetSelf(0x3).FollowNearCallSelf(0x3, 0x7).GetPtr()); + /*0x14105F950*/ FUNC_AT_ADDRESS(addr_SQVM_Warning, __int64(*)(__int64, int, int, const char*, std::size_t*), r5_patterns.PatternSearch("E8 ? ? ? ? 85 C0 0F 99 C3").FollowNearCallSelf().GetPtr()); + /*0x140B1E55*/ FUNC_AT_ADDRESS(addr_SQVM_Warning_ReturnAddr, void*, r5_patterns.PatternSearch("E8 ? ? ? ? 85 C0 0F 99 C3").OffsetSelf(0x5).GetPtr()); //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 @@ -62,6 +64,7 @@ namespace #pragma endregion #pragma region CBaseFileSystem + /*0x14038BE20*/ FUNC_AT_ADDRESS(addr_CBaseFileSystem_FileSystemWarning, void(*)(void*, FileWarningLevel_t, const char*, ...), r5_patterns.PatternSearch("E8 ? ? ? ? 33 C0 80 3B 2A").FollowNearCallSelf().GetPtr()); #pragma endregion @@ -82,6 +85,8 @@ namespace PRINT_ADDRESS("SQVM_Print", addr_SQVM_Print); PRINT_ADDRESS("SQVM_LoadScript", addr_SQVM_LoadScript); PRINT_ADDRESS("SQVM_LoadRson", addr_SQVM_LoadRson); + PRINT_ADDRESS("SQVM_Warning", addr_SQVM_Warning); + PRINT_ADDRESS("SQVM_Warning_ReturnAddr", addr_SQVM_Warning_ReturnAddr); PRINT_ADDRESS("NET_PrintFunc", addr_NET_PrintFunc); PRINT_ADDRESS("NET_ReceiveDatagram", addr_NET_ReceiveDatagram); PRINT_ADDRESS("NET_SendDatagram ", addr_NET_SendDatagram); From 54cdb2fb61b2c729e6b0e99e0cd5c1ede3cc5229 Mon Sep 17 00:00:00 2001 From: IcePixelx <41352111+PixieCore@users.noreply.github.com> Date: Tue, 17 Aug 2021 23:04:53 +0200 Subject: [PATCH 03/14] Updated IsFlagSet hooks. * Cleaned up code to properly mask off Dev and Cheat flags. * Added separate define from _DEBUG so you can define it in release builds for people without C++ Debug Restributeables. --- r5dev/src/hooks/iconvar.cpp | 52 ++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/r5dev/src/hooks/iconvar.cpp b/r5dev/src/hooks/iconvar.cpp index b57c180e..780a9d72 100644 --- a/r5dev/src/hooks/iconvar.cpp +++ b/r5dev/src/hooks/iconvar.cpp @@ -1,6 +1,10 @@ #include "pch.h" #include "hooks.h" +#ifdef _DEBUG +#define MaskOffCheats +#endif + namespace Hooks { ConVar_IsFlagSetFn originalConVar_IsFlagSet = nullptr; @@ -10,19 +14,19 @@ namespace Hooks bool Hooks::ConVar_IsFlagSet(ConVar* cvar, int flag) { -#ifdef _DEBUG +#ifdef MaskOffCheats if (g_bDebugConsole) { - printf("--------------------------------------------------\n"); - printf(" Flaged: %08X\n", cvar->m_ConCommandBase.m_nFlags); + std::cout << "--------------------------------------------------\n"; + std::cout << cvar->m_ConCommandBase.m_pszName << " Flags: " << std::hex << std::uppercase << cvar->m_ConCommandBase.m_nFlags << "\n"; } - // Mask off FCVAR_CHEATS and FCVAR_DEVELOPMENTONLY - cvar->m_ConCommandBase.m_nFlags &= 0xFFFFBFFD; + // Mask off FCVAR_DEVELOPMENTONLY and FCVAR_CHEAT. + cvar->m_ConCommandBase.m_nFlags &= ~(FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT); if (g_bDebugConsole) { - printf(" Masked: %08X\n", cvar->m_ConCommandBase.m_nFlags); - printf(" Verify: %08X\n", flag); - printf("--------------------------------------------------\n"); + std::cout << cvar->m_ConCommandBase.m_pszName << " Flags: " << std::hex << std::uppercase << cvar->m_ConCommandBase.m_nFlags << "\n"; + std::cout << cvar->m_ConCommandBase.m_pszName << " Verify: " << std::hex << std::uppercase << flag << "\n"; + std::cout << "--------------------------------------------------\n"; } if (flag & FCVAR_RELEASE) @@ -30,14 +34,12 @@ bool Hooks::ConVar_IsFlagSet(ConVar* cvar, int flag) return true; } - if (!g_bReturnAllFalse) - { - return (cvar->m_ConCommandBase.m_nFlags & flag) != 0; - } - else + if (g_bReturnAllFalse) { return false; } + + return (cvar->m_ConCommandBase.m_nFlags & flag) != 0; #else // Mask off FCVAR_DEVELOPMENTONLY if existing. cvar->m_ConCommandBase.m_nFlags &= ~FCVAR_DEVELOPMENTONLY; @@ -48,19 +50,19 @@ bool Hooks::ConVar_IsFlagSet(ConVar* cvar, int flag) bool Hooks::ConCommand_IsFlagSet(ConCommandBase* cmd, int flag) { -#ifdef _DEBUG +#ifdef MaskOffCheats if (g_bDebugConsole) { - printf("--------------------------------------------------\n"); - printf(" Flaged: %08X\n", cmd->m_nFlags); + std::cout << "--------------------------------------------------\n"; + std::cout << cmd->m_pszName << " Flags: " << std::hex << std::uppercase << cmd->m_nFlags << "\n"; } - // Mask off FCVAR_CHEATS and FCVAR_DEVELOPMENTONLY - cmd->m_nFlags &= 0xFFFFBFFD; + // Mask off FCVAR_DEVELOPMENTONLY and FCVAR_CHEAT. + cmd->m_nFlags &= ~(FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT); if (g_bDebugConsole) { - printf(" Masked: %08X\n", cmd->m_nFlags); - printf(" Verify: %08X\n", flag); - printf("--------------------------------------------------\n"); + std::cout << cmd->m_pszName << " Flags: " << std::hex << std::uppercase << cmd->m_nFlags << "\n"; + std::cout << cmd->m_pszName << " Verify: " << std::hex << std::uppercase << flag << "\n"; + std::cout << "--------------------------------------------------\n"; } if (flag & FCVAR_RELEASE) @@ -68,14 +70,12 @@ bool Hooks::ConCommand_IsFlagSet(ConCommandBase* cmd, int flag) return true; } - if (!g_bReturnAllFalse) - { - return (cmd->m_nFlags & flag) != 0; - } - else + if (g_bReturnAllFalse) { return false; } + + return (cmd->m_nFlags & flag) != 0; #else // Mask off FCVAR_DEVELOPMENTONLY if existing. cmd->m_nFlags &= ~FCVAR_DEVELOPMENTONLY; From 3558eb9c487d3297ab28451053347c0afae7f15f Mon Sep 17 00:00:00 2001 From: IcePixelx <41352111+PixieCore@users.noreply.github.com> Date: Tue, 17 Aug 2021 23:11:29 +0200 Subject: [PATCH 04/14] Removed un-used define in hooks.h --- r5dev/include/hooks.h | 1 - 1 file changed, 1 deletion(-) diff --git a/r5dev/include/hooks.h b/r5dev/include/hooks.h index b4bc2f0e..b880254f 100644 --- a/r5dev/include/hooks.h +++ b/r5dev/include/hooks.h @@ -64,7 +64,6 @@ namespace Hooks #pragma region ConVar bool ConVar_IsFlagSet(ConVar* cvar, int flag); bool ConCommand_IsFlagSet(ConCommandBase* cmd, int flag); - void Map_Callback(void* args); using ConVar_IsFlagSetFn = bool(*)(ConVar*, int); extern ConVar_IsFlagSetFn originalConVar_IsFlagSet; From bbd58bba7567f463e2581559df522d67f3d0b026 Mon Sep 17 00:00:00 2001 From: IcePixelx <41352111+PixieCore@users.noreply.github.com> Date: Tue, 17 Aug 2021 23:18:35 +0200 Subject: [PATCH 05/14] Fixed potential crashes in r5net and added debug prints. * Potential crashes were when in certain post functions the returned status wasn't 200. --- r5net/include/netpch.h | 2 + r5net/include/r5/r5net.h | 2 +- r5net/src/r5net.cpp | 148 +++++++++++++++++++++++++++------------ 3 files changed, 107 insertions(+), 45 deletions(-) diff --git a/r5net/include/netpch.h b/r5net/include/netpch.h index c41f119c..78f633cf 100644 --- a/r5net/include/netpch.h +++ b/r5net/include/netpch.h @@ -1,6 +1,8 @@ #pragma once #pragma message("Precompiling r5net headers.\n") +//#define DebugR5Net + #define WIN32_LEAN_AND_MEAN #include #include diff --git a/r5net/include/r5/r5net.h b/r5net/include/r5/r5net.h index dd77c6ad..1293c5f1 100644 --- a/r5net/include/r5/r5net.h +++ b/r5net/include/r5/r5net.h @@ -22,7 +22,7 @@ namespace R5Net std::vector GetServersList(std::string& outMessage); bool PostServerHost(std::string& outMessage, std::string& outToken, const ServerListing& serverListing); - bool GetServerByToken(ServerListing& outServer, std::string& outError, const std::string& token, const std::string& password = ""); + bool GetServerByToken(ServerListing& outServer, std::string& outMessage, const std::string token, const std::string password = ""); std::string GetVersionString(); }; } \ No newline at end of file diff --git a/r5net/src/r5net.cpp b/r5net/src/r5net.cpp index 852ca936..5a901949 100644 --- a/r5net/src/r5net.cpp +++ b/r5net/src/r5net.cpp @@ -16,11 +16,19 @@ std::vector R5Net::Client::GetServersList(std::string& outMessage nlohmann::json reqBody = nlohmann::json::object(); reqBody["version"] = GetVersionString(); - std::string reqBodyStr = reqBody.dump();; + std::string reqBodyStr = reqBody.dump(); + +#ifdef DebugR5Net + std::cout << " [+R5Net+] Sending GetServerList post now..\n"; +#endif httplib::Result res = m_HttpClient.Post("/servers", reqBody.dump().c_str(), reqBody.dump().length(), "application/json"); - if (res) +#ifdef DebugR5Net + std::cout << " [+R5Net+] GetServerList replied with " << res->status << "\n"; +#endif + + if (res && res->status == 200) // STATUS_OK { nlohmann::json resBody = nlohmann::json::parse(res->body); if (resBody["success"].is_boolean() && resBody["success"].get()) @@ -42,7 +50,10 @@ std::vector R5Net::Client::GetServersList(std::string& outMessage } else { - outMessage = "Failed to reach comp-server"; + if (res) + outMessage = std::string("Failed to reach comp-server ") + std::to_string(res->status); + else + outMessage = "Failed to reach comp-server unknown error code."; } return list; @@ -61,70 +72,119 @@ bool R5Net::Client::PostServerHost(std::string& outMessage, std::string& outToke std::string reqBodyStr = reqBody.dump(); - auto res = m_HttpClient.Post("/servers/add", reqBodyStr.c_str(), reqBodyStr.length(), "application/json"); +#ifdef DebugR5Net + std::cout << " [+R5Net+] Sending PostServerHost post now..\n"; +#endif - if (!res) + httplib::Result res = m_HttpClient.Post("/servers/add", reqBodyStr.c_str(), reqBodyStr.length(), "application/json"); + +#ifdef DebugR5Net + std::cout << " [+R5Net+] PostServerHost replied with " << res->status << "\n"; +#endif + + if (res && res->status == 200) // STATUS_OK { - outMessage = "Failed to reach comp-server"; - outToken = ""; - return false; - } - - nlohmann::json resBody = nlohmann::json::parse(res->body); - if (resBody["success"].is_boolean() && resBody["success"].get()) - { - if (resBody["token"].is_string()) - outToken = resBody["token"].get(); + nlohmann::json resBody = nlohmann::json::parse(res->body); + if (resBody["success"].is_boolean() && resBody["success"].get()) + { + if (resBody["token"].is_string()) + outToken = resBody["token"].get(); + else + outToken = ""; + + return true; + } else - outToken = ""; - return true; + { + if (resBody["err"].is_string()) + outMessage = resBody["err"].get(); + else + outMessage = "An unknown error occured!"; + + return false; + } } else { - if (resBody["err"].is_string()) - outMessage = resBody["err"].get(); - else - outMessage = "An unknown error occured!"; + if (res) + outMessage = std::string("Failed to reach comp-server ") + std::to_string(res->status); + else + outMessage = "Failed to reach comp-server unknown error code."; + + outToken = ""; return false; } + + return false; } -bool R5Net::Client::GetServerByToken(ServerListing& outServer, std::string& outError, const std::string& token, const std::string& password) +bool R5Net::Client::GetServerByToken(ServerListing& outServer, std::string& outMessage, const std::string token, const std::string password) { nlohmann::json reqBody = nlohmann::json::object(); reqBody["token"] = token; reqBody["password"] = password; +#ifdef DebugR5Net + std::cout << " [+R5Net+] Sending GetServerByToken post now...\n"; +#endif + httplib::Result res = m_HttpClient.Post("/server/byToken", reqBody.dump().c_str(), reqBody.dump().length(), "application/json"); - if (!res) +#ifdef DebugR5Net + std::cout << " [+R5Net+] GetServerByToken replied with " << res->status << "\n"; +#endif + + if (res && res->status == 200) // STATUS_OK { - outError = "Failed to reach comp-server"; - outServer = ServerListing{}; - return false; + if (!res->body.empty()) + { + nlohmann::json resBody = nlohmann::json::parse(res->body); + + if (res && resBody["success"].is_boolean() && resBody["success"]) + { + outServer = ServerListing{ + resBody["server"]["name"].get(), + resBody["server"]["map"].get(), + resBody["server"]["ip"].get(), + resBody["server"]["port"].get() + }; + return true; + } + else + { + if (resBody["err"].is_string()) + outMessage = resBody["err"].get(); + else + outMessage = ""; + + outServer = ServerListing{}; + return false; + } + } } - - nlohmann::json resBody = nlohmann::json::parse(res->body); - - if (res && resBody["success"].is_boolean() && resBody["success"]) + else { - outServer = ServerListing{ - resBody["server"]["name"].get(), - resBody["server"]["map"].get(), - resBody["server"]["ip"].get(), - resBody["server"]["port"].get() - }; - return true; - } - else - { - if (resBody["err"].is_string()) - outError = resBody["err"].get(); - else - outError = ""; + if (res) + { + if (!res->body.empty()) + { + nlohmann::json resBody = nlohmann::json::parse(res->body); + if (resBody["err"].is_string()) + outMessage = resBody["err"].get(); + else + outMessage = "Failed to reach comp-server unknown error code."; + + return false; + } + + outMessage = std::string("Failed to reach comp-server ") + std::to_string(res->status); + return false; + } + + outMessage = "failed to reach comp-server unknown error code."; outServer = ServerListing{}; return false; } From a3025e76de885558da4aef07077cbfee4551ed58 Mon Sep 17 00:00:00 2001 From: Marcii0 <58266292+Marcii0@users.noreply.github.com> Date: Thu, 19 Aug 2021 00:17:18 +0200 Subject: [PATCH 06/14] Changed map-select drop down menu, now it displays 'Map Name + Season' instead of file-name. (#41) * Host Server shows normal map names * Changed a few stuff... * redid some stuff that isn't crucial * Update CCompanion.cpp * Update CCompanion.cpp * Updated mapname displaying. * Moved "ServerMap" as a static object into CCompanion::HostServerSection(). Co-authored-by: IcePixelx <41352111+PixieCore@users.noreply.github.com> --- r5dev/src/CCompanion.cpp | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/r5dev/src/CCompanion.cpp b/r5dev/src/CCompanion.cpp index f9c1ed37..b020ba40 100644 --- a/r5dev/src/CCompanion.cpp +++ b/r5dev/src/CCompanion.cpp @@ -11,10 +11,20 @@ CCompanion* g_ServerBrowser = nullptr; +std::map mapArray = +{ + { "mp_rr_canyonlands_64k_x_64k", "King's Canyon Season 0" }, + { "mp_rr_desertlands_64k_x_64k", "World's Edge Season 3" }, + { "mp_rr_canyonlands_mu1", "King's Canyon Season 2" }, + { "mp_rr_canyonlands_mu1_night", "King's Canyon Season 2 After Dark" }, + { "mp_rr_desertlands_64k_x_64k_nx", "World's Edge Season 3 After Dark" }, + { "mp_lobby", "Lobby Season 3" }, + { "mp_rr_canyonlands_staging", "King's Canyon Firing Range" } +}; + /*----------------------------------------------------------------------------- * _ccompanion.cpp *-----------------------------------------------------------------------------*/ - CCompanion::CCompanion() : MatchmakingServerStringBuffer("r5a-comp-sv.herokuapp.com"), r5net(new R5Net::Client("r5a-comp-sv.herokuapp.com")) { memset(ServerConnStringBuffer, 0, sizeof(ServerConnStringBuffer)); @@ -26,7 +36,16 @@ CCompanion::CCompanion() : MatchmakingServerStringBuffer("r5a-comp-sv.herokuapp. int slashPos = filename.rfind("\\", std::string::npos); filename = filename.substr((INT8)slashPos + 1, std::string::npos); filename = filename.substr(0, filename.size() - 6); - MapsList.push_back(filename); + + auto it = mapArray.find(filename); // Find MapName in mapArray. + if (it != mapArray.end()) + { + MapsList.push_back(it->second); + } + else + { + MapsList.push_back(filename); + } } // copy assignment kjek @@ -358,6 +377,7 @@ void CCompanion::ServerBrowserSection() void CCompanion::HostServerSection() { static std::string ServerNameErr = ""; + static std::string ServerMap = std::string(); ImGui::InputTextWithHint("##ServerHost_ServerName", "Server Name (Required)", &MyServer.name); ImGui::InputTextWithHint("##ServerHost_ServerPassword", "Password (Optional)", &MyServer.password); @@ -369,13 +389,18 @@ void CCompanion::HostServerSection() if (ImGui::Selectable(item.c_str(), item == MyServer.map)) { MyServer.map = item; + for (auto it = mapArray.begin(); it != mapArray.end(); ++it) + { + if (it->second.compare(MyServer.map) == NULL) + ServerMap = it->first; + } } } ImGui::EndCombo(); } ImGui::Spacing(); - ImGui::Checkbox("Start as dedicated server (HACK)##ServerHost_DediCheckbox", &StartAsDedi); + ImGui::Checkbox("Start as Dedicated Server (HACK)##ServerHost_DediCheckbox", &StartAsDedi); ImGui::SameLine(); @@ -389,9 +414,8 @@ void CCompanion::HostServerSection() { ServerNameErr = std::string(); UpdateHostingStatus(); - std::stringstream cmd; - cmd << "map " << MyServer.map; + cmd << "map " << ServerMap; ProcessCommand(cmd.str().c_str()); if (StartAsDedi) @@ -407,7 +431,7 @@ void CCompanion::HostServerSection() if (ImGui::Button("Force Start##ServerHost_ForceStart", ImVec2(ImGui::GetWindowSize().x, 32))) { - strncpy_s(GameGlobals::HostState->m_levelName, MyServer.map.c_str(), 64); // Copy new map into hoststate levelname. 64 is size of m_levelname. + strncpy_s(GameGlobals::HostState->m_levelName, ServerMap.c_str(), 64); // Copy new map into hoststate levelname. 64 is size of m_levelname. GameGlobals::HostState->m_iNextState = HostStates_t::HS_NEW_GAME; // Force CHostState::FrameUpdate to start a server. } @@ -428,7 +452,7 @@ void CCompanion::HostServerSection() if (ImGui::Button("Change Level##ServerHost_ChangeLevel", ImVec2(ImGui::GetWindowSize().x, 32))) { - strncpy_s(GameGlobals::HostState->m_levelName, MyServer.map.c_str(), 64); // Copy new map into hoststate levelname. 64 is size of m_levelname. + strncpy_s(GameGlobals::HostState->m_levelName, ServerMap.c_str(), 64); // Copy new map into hoststate levelname. 64 is size of m_levelname. GameGlobals::HostState->m_iNextState = HostStates_t::HS_CHANGE_LEVEL_MP; // Force CHostState::FrameUpdate to change the level. } From 06127dee1d901d555b8a6b2b4592a12273454d64 Mon Sep 17 00:00:00 2001 From: BobTheBob <32057864+BobTheBob9@users.noreply.github.com> Date: Wed, 18 Aug 2021 23:17:51 +0100 Subject: [PATCH 07/14] prevent squirrel compiler errors from killing game process (#43) --- r5dev/include/opcptc.h | 5 +++++ r5dev/src/opcptc.cpp | 3 +++ 2 files changed, 8 insertions(+) diff --git a/r5dev/include/opcptc.h b/r5dev/include/opcptc.h index cb1188b0..ae207e25 100644 --- a/r5dev/include/opcptc.h +++ b/r5dev/include/opcptc.h @@ -36,6 +36,10 @@ namespace MemoryAddress FairFight_Init = r5_op.PatternSearch("40 53 48 83 EC 20 8B 81 B0 03 ? ? 48 8B D9 C6"); #pragma endregion +#pragma region Squirrel + MemoryAddress Squirrel_CompileError = r5_op.PatternSearch("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 81 EC ? ? ? ? 48 8B D9 4C 8B F2"); +#pragma endregion + void PrintOAddress() // Test the sigscan results { std::cout << "+--------------------------------------------------------+" << std::endl; @@ -46,6 +50,7 @@ namespace PRINT_ADDRESS("Host_NewGame", Host_NewGame.GetPtr()); PRINT_ADDRESS("CServer_Auth", CServer_Auth.GetPtr()); PRINT_ADDRESS("FairFight_Init", FairFight_Init.GetPtr()); + PRINT_ADDRESS("Squirrel_CompileError", Squirrel_CompileError.GetPtr()); std::cout << "+--------------------------------------------------------+" << std::endl; // TODO implement error handling when sigscan fails or result is 0 diff --git a/r5dev/src/opcptc.cpp b/r5dev/src/opcptc.cpp index c269b078..40f944aa 100644 --- a/r5dev/src/opcptc.cpp +++ b/r5dev/src/opcptc.cpp @@ -26,4 +26,7 @@ void InstallOpcodes() /* .TEXT */ //------------------------------------------------------------------------- // JA --> JMP | Prevent FairFight anti-cheat from initializing on the server FairFight_Init.Offset(0x61).Patch({ 0xE9, 0xED, 0x00, 0x00, 0x00, 0x00 }); + //------------------------------------------------------------------------- + // CALL --> NOP | Prevent squirrel compiler errors from calling Error + Squirrel_CompileError.Offset(0x12C).Patch({ 0x90, 0x90, 0x90, 0x90, 0x90 }); } From 70b4c02a9a7b0978d64a1ab7c1db3c76f695eda8 Mon Sep 17 00:00:00 2001 From: IcePixelx <41352111+PixieCore@users.noreply.github.com> Date: Thu, 19 Aug 2021 01:27:44 +0200 Subject: [PATCH 08/14] Read description for all changes. * Added ability to register custom ConVar. * Added 2 custom ConVars to open the CGameConsole and CCompanion Windows. * Changed ResolveRelativeAddress. * Added Config System for the Gui. * Added ImGui::Hotkey. * Added the ability to change 2 hotkeys for opening the window for CGameConsole and CCompanion. * Changed pattern for Squirrel_CompilerError to use a String. * Added IMemAlloc::AllocWrapper to patterns.h --- external/imgui/include/imgui.h | 1 + external/imgui/src/imgui_widgets.cpp | 361 +++++++++++++++++++++++++++ r5dev/include/gameclasses.h | 6 +- r5dev/include/gui_utility.h | 68 +++++ r5dev/include/opcptc.h | 3 +- r5dev/include/patterns.h | 6 +- r5dev/src/CGameConsole.cpp | 12 + r5dev/src/dllmain.cpp | 1 + r5dev/src/gameclasses.cpp | 74 ++++++ r5dev/src/gui_utility.cpp | 3 +- r5dev/src/id3dx.cpp | 9 +- shared/include/address.h | 4 +- shared/include/utility.h | 1 - 13 files changed, 535 insertions(+), 14 deletions(-) diff --git a/external/imgui/include/imgui.h b/external/imgui/include/imgui.h index 44b9922a..72c197e5 100644 --- a/external/imgui/include/imgui.h +++ b/external/imgui/include/imgui.h @@ -548,6 +548,7 @@ namespace ImGui IMGUI_API bool InputDouble(const char* label, double* v, double step = 0.0, double step_fast = 0.0, const char* format = "%.6f", ImGuiInputTextFlags flags = 0); IMGUI_API bool InputScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_step = NULL, const void* p_step_fast = NULL, const char* format = NULL, ImGuiInputTextFlags flags = 0); IMGUI_API bool InputScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_step = NULL, const void* p_step_fast = NULL, const char* format = NULL, ImGuiInputTextFlags flags = 0); + IMGUI_API bool Hotkey(const char* label, int* key, const ImVec2& size); // Widgets: Color Editor/Picker (tip: the ColorEdit* functions have a little color square that can be left-clicked to open a picker, and right-clicked to open an option menu.) // - Note that in C++ a 'float v[X]' function argument is the _same_ as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. diff --git a/external/imgui/src/imgui_widgets.cpp b/external/imgui/src/imgui_widgets.cpp index d4d39143..2f6b05a2 100644 --- a/external/imgui/src/imgui_widgets.cpp +++ b/external/imgui/src/imgui_widgets.cpp @@ -8048,4 +8048,365 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, } +const char* const KeyNames[] = +{ + "Null", + "Mouse1", + "Mouse2", + "Cancel", + "Mouse3", + "Mouse4", + "Mouse5", + "Undefined", + "Back", + "Tab", + "Reserved", + "Reserved", + "Clear", + "Return", + "Undefined", + "Undefined", + "Shift", + "Control", + "Menu", + "Pause", + "Capital", + "Kana", + "Ime On", + "Junja", + "Final", + "Kanji", + "Ime Off", + "Escape", + "Convert", + "Nonconvert", + "Accept", + "Modechange", + "Space", + "Prior", + "Next", + "End", + "Home", + "Left", + "Up", + "Right", + "Down", + "Select", + "Print", + "Execute", + "Snapshot", + "Insert", + "Delete", + "Help", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "Lwin", + "Rwin", + "Apps", + "Unknown", + "Sleep", + "Numpad0", + "Numpad1", + "Numpad2", + "Numpad3", + "Numpad4", + "Numpad5", + "Numpad6", + "Numpad7", + "Numpad8", + "Numpad9", + "Multiply", + "Add", + "Separator", + "Subtract", + "Decimal", + "Divide", + "F1", + "F2", + "F3", + "F4", + "F5", + "F6", + "F7", + "F8", + "F9", + "F10", + "F11", + "F12", + "F13", + "F14", + "F15", + "F16", + "F17", + "F18", + "F19", + "F20", + "F21", + "F22", + "F23", + "F24", + "Unassigned", + "Unassigned", + "Unassigned", + "Unassigned", + "Unassigned", + "Unassigned", + "Unassigned", + "Unassigned", + "Numlock", + "Scroll", + "Oem_nec_equal", + "Oem_fj_masshou", + "Oem_fj_touroku", + "Oem_fj_loya", + "Oem_fj_roya", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Lshift", + "Rshift", + "Lcontrol", + "Rcontrol", + "Lmenu", + "Rmenu", + "Browser Back", + "Browser Stop", + "Browser Refresh", + "Browser Search", + "Browser Favorite", + "Browser Home", + "Volume Mute", + "Volume Down", + "Volume Up", + "Next Track", + "Previous Track", + "Media Stop", + "Play/Pause", + "Mail", + "Media", + "App1", + "App2", + "Reserved", + "Reserved", + "Reserved", + ":;", + "+", + ",", + "-", + ".", + "?", + "~", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined", + "Undefined" +}; + +bool ImGui::Hotkey(const char* label, int* key, const ImVec2& ssize) +{ + ImGuiWindow* window = ImGui::GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + ImGuiIO& io = g.IO; + const ImGuiStyle& style = g.Style; + + float backupPaddingY = style.FramePadding.y; + g.Style.FramePadding.y = 0.0f; + + const ImGuiID id = window->GetID(label); + const ImVec2 labelSize = ImGui::CalcTextSize(label, NULL, true); + const ImVec2 size = ImGui::CalcItemSize(ssize, ImGui::CalcItemWidth(), labelSize.y + style.FramePadding.y * 2.0f); + + const ImRect frameBB(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, labelSize.y + style.FramePadding.y)); + const ImRect total_bb(frameBB.Min, frameBB.Max + ImVec2(labelSize.x > 0.0f ? style.ItemInnerSpacing.x + labelSize.x : 0.0f, 0.0f)); + + ImGui::ItemSize(total_bb, style.FramePadding.y); + if (!ImGui::ItemAdd(total_bb, id)) + { + g.Style.FramePadding.y = backupPaddingY; + return false; + } + + const bool requestedFocus = ImGui::FocusableItemRegister(window, id); + const bool isHovered = ImGui::ItemHoverable(frameBB, id); + + if (isHovered) { + ImGui::SetHoveredID(id); + g.MouseCursor = ImGuiMouseCursor_TextInput; + } + + const bool didClick = isHovered && io.MouseClicked[0]; + + if (requestedFocus || didClick) + { + if (g.ActiveId != id) + { + memset(io.MouseDown, 0, sizeof(io.MouseDown)); + memset(io.KeysDown, 0, sizeof(io.KeysDown)); + *key = 0; + } + ImGui::SetActiveID(id, window); + ImGui::FocusWindow(window); + } + else if (io.MouseClicked[0]) + { + if (g.ActiveId == id) + { + ImGui::ClearActiveID(); + } + } + + bool didValueChange = false; + int kkey = *key; + + if (g.ActiveId == id) + { + for (auto i = 0x1; i <= 0xA5; i++) + { + if (io.KeysDown[i]) + { + kkey = i; + didValueChange = true; + ImGui::ClearActiveID(); + } + } + + if (IsKeyPressedMap(ImGuiKey_Escape)) + { + *key = NULL; + ImGui::ClearActiveID(); + } + else + { + *key = kkey; + } + } + + char displayBuf[24] = "None"; + + if (*key != 0 && g.ActiveId != id) + { + strcpy_s(displayBuf, KeyNames[*key]); + } + else if (g.ActiveId == id) + { + strcpy_s(displayBuf, "Press key"); + } + + const ImRect clip_rect(frameBB.Min.x, frameBB.Min.y, frameBB.Min.x + size.x, frameBB.Min.y + size.y); + ImGui::RenderTextClipped(frameBB.Min + style.FramePadding, frameBB.Max - style.FramePadding, displayBuf, NULL, NULL, style.ButtonTextAlign, &clip_rect); + + g.Style.FramePadding.y = backupPaddingY; + + return didValueChange; +} + #endif // #ifndef IMGUI_DISABLE diff --git a/r5dev/include/gameclasses.h b/r5dev/include/gameclasses.h index 90f343fd..59d962ce 100644 --- a/r5dev/include/gameclasses.h +++ b/r5dev/include/gameclasses.h @@ -291,12 +291,13 @@ public: const char* m_pzsCurrentValue; //0x0058 __int64 m_iStringLength; //0x0060 float m_flValue; //0x0068 - __int64 m_iValue; //0x006C + int m_iValue; //0x006C bool m_bHasMin; //0x0070 float m_flMinValue; //0x0074 bool m_bHasMax; //0x0078 float m_flMaxValue; //0x007C -}; //Size: 0x0080 + char pad_0080[32]; //0x0080 +}; //Size: 0x00A0 class CCVarIteratorInternal // Fully reversed table, just look at the virtual function table and rename the function. { @@ -368,6 +369,7 @@ namespace GameGlobals extern CInputSystem* InputSystem; extern CCVar* Cvar; + ConVar* CreateCustomConVar(const char* name, const char* defaultValue, int flags, const char* helpString, bool bMin, float fMin, bool bMax, float fMax, void* callback, void* unk); void InitGameGlobals(); extern bool IsInitialized; } \ No newline at end of file diff --git a/r5dev/include/gui_utility.h b/r5dev/include/gui_utility.h index a6239c2c..052314ab 100644 --- a/r5dev/include/gui_utility.h +++ b/r5dev/include/gui_utility.h @@ -1,6 +1,74 @@ +#pragma once + ///////////////////////////////////////////////////////////////////////////// // Internals 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); + +class GuiConfig +{ +public: + struct + { + int bind1 = VK_OEM_3; + int bind2 = VK_INSERT; + } CGameConsoleConfig; + + struct + { + int bind1 = VK_HOME; + int bind2 = VK_F10; + } CCompanionConfig; + + void Load() + { + std::filesystem::path path = std::filesystem::current_path() /= "gui.config"; // Get current path + gui.config + + nlohmann::json in; + std::ifstream config_file(path, std::ios::in); // Parse config file. + + if (config_file.good() && config_file) // Check if it parsed. + { + config_file >> in; + config_file.close(); + + if (!in.is_null()) + { + if (!in["config"].is_null()) + { + // CGameConsole + CGameConsoleConfig.bind1 = in["config"]["CGameConsole"]["bind1"].get(); + CGameConsoleConfig.bind2 = in["config"]["CGameConsole"]["bind2"].get(); + + // CCompanion + CCompanionConfig.bind1 = in["config"]["CCompanion"]["bind1"].get(); + CCompanionConfig.bind2 = in["config"]["CCompanion"]["bind2"].get(); + } + } + } + } + + void Save() + { + nlohmann::json out; + + // CGameConsole + out["config"]["CGameConsole"]["bind1"] = CGameConsoleConfig.bind1; + out["config"]["CGameConsole"]["bind2"] = CGameConsoleConfig.bind2; + + // CCompanion + out["config"]["CCompanion"]["bind1"] = CCompanionConfig.bind1; + out["config"]["CCompanion"]["bind2"] = CCompanionConfig.bind2; + + std::filesystem::path path = std::filesystem::current_path() /= "gui.config"; // Get current path + gui.config + std::ofstream out_file(path, std::ios::out | std::ios::trunc); // Write config file.. + + out_file << out.dump(4); // Dump it into config file.. + + out_file.close(); // Close the file handle. + }; +}; + +extern GuiConfig g_GuiConfig; diff --git a/r5dev/include/opcptc.h b/r5dev/include/opcptc.h index ae207e25..e563def9 100644 --- a/r5dev/include/opcptc.h +++ b/r5dev/include/opcptc.h @@ -37,7 +37,8 @@ namespace #pragma endregion #pragma region Squirrel - MemoryAddress Squirrel_CompileError = r5_op.PatternSearch("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 81 EC ? ? ? ? 48 8B D9 4C 8B F2"); + /*0x14105CCA0*/ + MemoryAddress Squirrel_CompileError = r5_op.StringSearch("%s SCRIPT COMPILE ERROR: %s").FindPatternSelf("48 89 5C", MemoryAddress::Direction::UP); #pragma endregion void PrintOAddress() // Test the sigscan results diff --git a/r5dev/include/patterns.h b/r5dev/include/patterns.h index c7f78b70..301ed6e4 100644 --- a/r5dev/include/patterns.h +++ b/r5dev/include/patterns.h @@ -55,7 +55,7 @@ namespace #pragma region CHLClient /*0x1405C0740*/ - FUNC_AT_ADDRESS(addr_CHLClient_FrameStageNotify, void(*)(void* rcx, int curStage), r5_patterns.PatternSearch("48 83 EC 28 89 15 ?? ?? ?? ??").GetPtr()); + FUNC_AT_ADDRESS(addr_CHLClient_FrameStageNotify, void(*)(void*, int), r5_patterns.PatternSearch("48 83 EC 28 89 15 ?? ?? ?? ??").GetPtr()); #pragma endregion #pragma region CVEngineServer @@ -71,6 +71,9 @@ namespace #pragma region Utility /*0x140295600*/ FUNC_AT_ADDRESS(addr_MSG_EngineError, int(*)(char*, va_list), r5_patterns.StringSearch("Engine Error").FindPatternSelf("48 89 ? ? ? 48 89", MemoryAddress::Direction::UP, 500).GetPtr()); + + /*0x1401B31C0*/ + FUNC_AT_ADDRESS(addr_MemAlloc_Wrapper, void*(*)(__int64), r5_patterns.StringSearch("ConversionModeMenu").FindPatternSelf("E8 ? ? ? ? 48", MemoryAddress::Direction::UP).FollowNearCallSelf().GetPtr()); #pragma endregion // Un-used atm. // DWORD64 p_KeyValues_FindKey = /*1404744E0*/ reinterpret_cast(PatternScan("r5apex.exe", "40 56 57 41 57 48 81 EC ?? ?? ?? ?? 45")); @@ -95,6 +98,7 @@ namespace PRINT_ADDRESS("CVEngineServer::IsPersistenceDataAvailable", addr_CVEngineServer_IsPersistenceDataAvailable); PRINT_ADDRESS("CBaseFileSystem::FileSystemWarning", addr_CBaseFileSystem_FileSystemWarning); PRINT_ADDRESS("MSG_EngineError", addr_MSG_EngineError); + PRINT_ADDRESS("MemAlloc_Wrapper", addr_MemAlloc_Wrapper); std::cout << "+--------------------------------------------------------+" << std::endl; // TODO implement error handling when sigscan fails or result is 0 } diff --git a/r5dev/src/CGameConsole.cpp b/r5dev/src/CGameConsole.cpp index 0fe76f43..dc522f8b 100644 --- a/r5dev/src/CGameConsole.cpp +++ b/r5dev/src/CGameConsole.cpp @@ -75,6 +75,18 @@ void CGameConsole::Draw(const char* title) ClearLog(); } copy_to_clipboard = ImGui::SmallButton("Copy"); + ImGui::Text("CG Hotkey:"); + ImGui::SameLine(); + if (ImGui::Hotkey("##OpenCGameConsoleBind1", &g_GuiConfig.CGameConsoleConfig.bind1, ImVec2(80, 80))) + { + g_GuiConfig.Save(); + } + ImGui::Text("CC Hotkey:"); + ImGui::SameLine(); + if (ImGui::Hotkey("##OpenCCompanionBind1", &g_GuiConfig.CCompanionConfig.bind1, ImVec2(80, 80))) + { + g_GuiConfig.Save(); + } ImGui::EndPopup(); } if (ImGui::Button("Options")) diff --git a/r5dev/src/dllmain.cpp b/r5dev/src/dllmain.cpp index c996b69b..be313cef 100644 --- a/r5dev/src/dllmain.cpp +++ b/r5dev/src/dllmain.cpp @@ -15,6 +15,7 @@ void InitializeR5Dev() SetupConsole(); Hooks::InstallHooks(); InstallOpcodes(); + g_GuiConfig.Load(); // Load gui config. SetupDXSwapChain(); printf("+-----------------------------------------------------------------------------+\n"); printf("| R5 DEV -- INITIALIZED ------------------------------------------------- |\n"); diff --git a/r5dev/src/gameclasses.cpp b/r5dev/src/gameclasses.cpp index 84da7d83..d1dd6cb0 100644 --- a/r5dev/src/gameclasses.cpp +++ b/r5dev/src/gameclasses.cpp @@ -1,8 +1,60 @@ #include "pch.h" #include "gameclasses.h" +#include "id3dx.h" namespace GameGlobals { + namespace CustomConVar + { + void CGameConsole_Callback(void* cmd) + { + std::string szValue = *(const char**)((std::uintptr_t)cmd + 0x18); + try + { + int value = std::stoi(szValue); + switch (value) + { + case 0: + g_bShowConsole = false; + break; + case 1: + g_bShowConsole = true; + break; + default: + break; + } + } + catch (std::exception& e) + { + std::cout << " [+CGameConsole+] Please don't input a character that isn't a number into cgameconsole :(.\n"; + } + } + + void CCompanion_Callback(void* cmd) + { + std::string szValue = *(const char**)((std::uintptr_t)cmd + 0x18); + try + { + int value = std::stoi(szValue); + switch (value) + { + case 0: + g_bShowBrowser = false; + break; + case 1: + g_bShowBrowser = true; + break; + default: + break; + } + } + catch (std::exception& e) + { + std::cout << " [+CCompanion+] Please don't input a character that isn't a number into ccompanion :(.\n"; + }; + } + } + bool IsInitialized = false; CHostState* HostState = nullptr; CInputSystem* InputSystem = nullptr; @@ -49,7 +101,29 @@ namespace GameGlobals // { // printf("%s: %p\n", current->InterfaceName, current->InterfacePtr); // } + + ConVar* CGameConsoleConVar = CreateCustomConVar("cgameconsole", "0", 0, "Opens the R5 Reloaded Console", false, 0.f, false, 0.f, CustomConVar::CGameConsole_Callback, nullptr); + ConVar* CCompanionConVar = CreateCustomConVar("ccompanion", "0", 0, "Opens the R5 Reloaded Server Browser", false, 0.f, false, 0.f, CustomConVar::CCompanion_Callback, nullptr); EmptyHostNames(); IsInitialized = true; } + + ConVar* CreateCustomConVar(const char* name, const char* defaultValue, int flags, const char* helpString, bool bMin, float fMin, bool bMax, float fMax, void* callback, void* unk) + { + static MemoryAddress ConVarVtable = MemoryAddress(0x14046FB50).Offset(0x12).ResolveRelativeAddress(); // Get vtable ptr for ConVar table. + static MemoryAddress ICvarVtable = MemoryAddress(0x14046FB50).Offset(0x29).ResolveRelativeAddress(); // Get vtable ptr for ICvar table. + static MemoryAddress CreateConVar = MemoryAddress(0x140470540); // Get CreateConvar address. + + ConVar* allocatedConvar = reinterpret_cast(addr_MemAlloc_Wrapper(0xA0)); // Allocate new memory with StdMemAlloc else we crash. + memset(allocatedConvar, 0, 0xA0); // Set all to null. + std::uintptr_t cvarPtr = reinterpret_cast(allocatedConvar); // To ptr. + + *(void**)(cvarPtr + 0x40) = ICvarVtable.RCast(); // 0x40 to ICvar table. + *(void**)cvarPtr = ConVarVtable.RCast(); // 0x0 to ConVar table. + + CreateConVar.RCast() // Call to create ConVar. + (allocatedConvar, name, defaultValue, flags, helpString, bMin, fMin, bMax, fMax, callback, unk); + + return allocatedConvar; // Return allocated ConVar. + } } \ No newline at end of file diff --git a/r5dev/src/gui_utility.cpp b/r5dev/src/gui_utility.cpp index b1210854..e991c749 100644 --- a/r5dev/src/gui_utility.cpp +++ b/r5dev/src/gui_utility.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "gui_utility.h" +GuiConfig g_GuiConfig; /*----------------------------------------------------------------------------- * _gui_utility.cpp @@ -40,4 +41,4 @@ void Strtrim(char* s) while (str_end > s && str_end[-1] == ' ') str_end--; *str_end = 0; -} +} \ No newline at end of file diff --git a/r5dev/src/id3dx.cpp b/r5dev/src/id3dx.cpp index 31962ca3..827838f0 100644 --- a/r5dev/src/id3dx.cpp +++ b/r5dev/src/id3dx.cpp @@ -56,17 +56,14 @@ LRESULT CALLBACK DXGIMsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) LRESULT CALLBACK HwndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - if (uMsg == WM_KEYDOWN) + if (uMsg == WM_KEYUP || uMsg == WM_SYSKEYDOWN) { - if (wParam == VK_OEM_3 || wParam == VK_INSERT) // For everyone without a US keyboard layout. + if (wParam == g_GuiConfig.CGameConsoleConfig.bind1 || wParam == g_GuiConfig.CGameConsoleConfig.bind2) { g_bShowConsole = !g_bShowConsole; } - } - if (uMsg == WM_SYSKEYDOWN) - { - if (wParam == VK_F10) + if (wParam == g_GuiConfig.CCompanionConfig.bind1 || wParam == g_GuiConfig.CCompanionConfig.bind2) { g_bShowBrowser = !g_bShowBrowser; } diff --git a/shared/include/address.h b/shared/include/address.h index a595bc55..b3cc6c22 100644 --- a/shared/include/address.h +++ b/shared/include/address.h @@ -284,7 +284,7 @@ public: return ResolveRelativeAddressSelf(opcodeOffset, nextInstructionOffset); } - MemoryAddress ResolveRelativeAddressSelf(std::ptrdiff_t registerOffset = 0x1, std::ptrdiff_t nextInstructionOffset = 0x4) + MemoryAddress ResolveRelativeAddressSelf(std::ptrdiff_t registerOffset = 0x0, std::ptrdiff_t nextInstructionOffset = 0x4) { // Skip register. std::uintptr_t skipRegister = ptr + registerOffset; @@ -300,7 +300,7 @@ public: return *this; } - MemoryAddress ResolveRelativeAddress(std::ptrdiff_t registerOffset = 0x1, std::ptrdiff_t nextInstructionOffset = 0x4) + MemoryAddress ResolveRelativeAddress(std::ptrdiff_t registerOffset = 0x0, std::ptrdiff_t nextInstructionOffset = 0x4) { // Skip register. std::uintptr_t skipRegister = ptr + registerOffset; diff --git a/shared/include/utility.h b/shared/include/utility.h index cc27fa9e..c2075066 100644 --- a/shared/include/utility.h +++ b/shared/include/utility.h @@ -4,7 +4,6 @@ // Internals BOOL FileExists(LPCTSTR szPath); MODULEINFO GetModuleInfo(const char* szModule); -std::uint8_t* PatternScan(const char* module, const char* signature); ///////////////////////////////////////////////////////////////////////////// // Utility From 0e171fca6a4662225f1da32e1b12e5450b338c1a Mon Sep 17 00:00:00 2001 From: IcePixelx <41352111+PixieCore@users.noreply.github.com> Date: Thu, 19 Aug 2021 14:32:52 +0200 Subject: [PATCH 09/14] Changes in description. * Added icon to launcher.exe * Launcher.exe gets remnamed to Run R5 Reloaded.exe in launcher release compilation configuration. * Extended argument buffer for starting the game in launcher.exe. * Added exception printing if in the custom ConVars an invalid value gets passed. --- r5dev/r5dev.vcxproj | 2 +- r5dev/src/gameclasses.cpp | 4 +- r5launcher/R5 Reloaded.ico | Bin 0 -> 12674 bytes r5launcher/main.cpp | 64 ++++++++++++++++++----- r5launcher/main.h | 7 +-- r5launcher/r5launcher.rc | 71 ++++++++++++++++++++++++++ r5launcher/r5launcher.vcxproj | 11 +++- r5launcher/r5launcher.vcxproj.filters | 13 +++++ r5launcher/resource.h | 16 ++++++ 9 files changed, 166 insertions(+), 22 deletions(-) create mode 100644 r5launcher/R5 Reloaded.ico create mode 100644 r5launcher/r5launcher.rc create mode 100644 r5launcher/resource.h diff --git a/r5dev/r5dev.vcxproj b/r5dev/r5dev.vcxproj index 3b562f80..f41f62bf 100644 --- a/r5dev/r5dev.vcxproj +++ b/r5dev/r5dev.vcxproj @@ -151,7 +151,7 @@ Minhook.x64.lib;r5net.lib;%(AdditionalDependencies) - del $(SolutionDir)bin\$(Configuration)\r5dev.dll + del "$(SolutionDir)bin\$(Configuration)\r5dev.dll" rename "$(TargetPath)" "r5dev.dll" diff --git a/r5dev/src/gameclasses.cpp b/r5dev/src/gameclasses.cpp index d1dd6cb0..21f47c22 100644 --- a/r5dev/src/gameclasses.cpp +++ b/r5dev/src/gameclasses.cpp @@ -26,7 +26,7 @@ namespace GameGlobals } catch (std::exception& e) { - std::cout << " [+CGameConsole+] Please don't input a character that isn't a number into cgameconsole :(.\n"; + std::cout << " [+CGameConsole+] Please don't input a character that isn't a number into cgameconsole :(." << e.what() << std::endl; } } @@ -50,7 +50,7 @@ namespace GameGlobals } catch (std::exception& e) { - std::cout << " [+CCompanion+] Please don't input a character that isn't a number into ccompanion :(.\n"; + std::cout << " [+CCompanion+] Please don't input a character that isn't a number into ccompanion :(." << e.what() << std::endl; }; } } diff --git a/r5launcher/R5 Reloaded.ico b/r5launcher/R5 Reloaded.ico new file mode 100644 index 0000000000000000000000000000000000000000..f63d17a45def313b3c5b7ce636ed64a5ce778e61 GIT binary patch literal 12674 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 literal 0 HcmV?d00001 diff --git a/r5launcher/main.cpp b/r5launcher/main.cpp index cd0c0ae3..189d4128 100644 --- a/r5launcher/main.cpp +++ b/r5launcher/main.cpp @@ -1,6 +1,6 @@ #include #include - +#include #include #include @@ -40,7 +40,7 @@ bool LaunchR5Apex(LAUNCHMODE lMode, LAUNCHSTATE lState) BOOL result; FILE* sLaunchParams; - CHAR sArgumentBuffer[1024] = { 0 }; + CHAR sArgumentBuffer[2048] = { 0 }; CHAR sCommandDirectory[MAX_PATH]; LPSTR sCommandLine = sCommandDirectory; @@ -173,23 +173,59 @@ bool LaunchR5Apex(LAUNCHMODE lMode, LAUNCHSTATE lState) /////////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[], char* envp[]) { - for (int i = 1; i < argc; ++i) + std::cout << "If you choose Dev as start parameter do not host servers into the Server Browser\n\n" + << "Every command will be and people can execute any script on your server.\n\n" + << "Use release for normal playing.\n\n" + << "Dev should only be used for testing purposes.\n\n"; + + std::cout << "Enter 1 for Dev Build. Enter 2 for Release Build:\n"; + + std::string input = std::string(); + + if (std::cin >> input) { - std::string arg = argv[i]; - if ((arg == "-dedicated") || (arg == "-dedi")) + try { - LaunchR5Apex(LAUNCHMODE::LM_DEDI, LAUNCHSTATE::LS_CHEATS); - Sleep(2000); - return EXIT_SUCCESS; + LAUNCHMODE iinput = (LAUNCHMODE)std::stoi(input); + switch (iinput) + { + case LAUNCHMODE::LM_DEBUG: + { + LaunchR5Apex(LAUNCHMODE::LM_DEBUG, LAUNCHSTATE::LS_CHEATS); + Sleep(2000); + return EXIT_SUCCESS; + } + case LAUNCHMODE::LM_GAME: + { + LaunchR5Apex(LAUNCHMODE::LM_GAME, LAUNCHSTATE::LS_CHEATS); + Sleep(2000); + return EXIT_SUCCESS; + } + case LAUNCHMODE::LM_DEDI: + { + LaunchR5Apex(LAUNCHMODE::LM_DEDI, LAUNCHSTATE::LS_CHEATS); + Sleep(2000); + return EXIT_SUCCESS; + } + default: + { + std::cout << "R5 Reloaded asked for a number between 1 and 2 :(.\n"; + Sleep(2000); + return EXIT_FAILURE; + } + } } - if ((arg == "-debug") || (arg == "-dbg")) + catch (std::exception& e) { - LaunchR5Apex(LAUNCHMODE::LM_DEBUG, LAUNCHSTATE::LS_CHEATS); - Sleep(2000); - return EXIT_SUCCESS; + std::cout << "R5 Reloaded asked for a number and not a letter or anything of that sort :(." << e.what() << std::endl; + Sleep(5000); + return EXIT_FAILURE; } } - LaunchR5Apex(LAUNCHMODE::LM_GAME, LAUNCHSTATE::LS_CHEATS); - Sleep(2000); + + std::cout << "R5 Reloaded needs an input to launch :(.\n"; + + Sleep(5000); + return EXIT_SUCCESS; } \ No newline at end of file diff --git a/r5launcher/main.h b/r5launcher/main.h index cf6f177b..c65bbd46 100644 --- a/r5launcher/main.h +++ b/r5launcher/main.h @@ -5,9 +5,10 @@ //----------------------------------------------------------------------------- enum class LAUNCHMODE : int { - LM_GAME, // Dev DLL - LM_DEDI, // Dedi DLL - LM_DEBUG // Debug DLL + LM_NULL, + LM_DEBUG, // Debug DLL + LM_GAME, // Release DLL + LM_DEDI // Dedi DLL }; //----------------------------------------------------------------------------- diff --git a/r5launcher/r5launcher.rc b/r5launcher/r5launcher.rc new file mode 100644 index 00000000..5d31049c --- /dev/null +++ b/r5launcher/r5launcher.rc @@ -0,0 +1,71 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// German (Germany) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN +#pragma code_page(1252) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON "R5 Reloaded.ico" + +#endif // German (Germany) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/r5launcher/r5launcher.vcxproj b/r5launcher/r5launcher.vcxproj index 9e0a8685..b478581e 100644 --- a/r5launcher/r5launcher.vcxproj +++ b/r5launcher/r5launcher.vcxproj @@ -165,8 +165,8 @@ detours.lib;%(AdditionalDependencies) - - + del "$(SolutionDir)bin\$(Configuration)\Run R5 Reloaded.exe" +rename "$(TargetPath)" "Run R5 Reloaded.exe" @@ -174,6 +174,13 @@ + + + + + + + diff --git a/r5launcher/r5launcher.vcxproj.filters b/r5launcher/r5launcher.vcxproj.filters index 35284662..f00d890a 100644 --- a/r5launcher/r5launcher.vcxproj.filters +++ b/r5launcher/r5launcher.vcxproj.filters @@ -23,5 +23,18 @@ Header Files + + Header Files + + + + + Resource Files + + + + + Resource Files + \ No newline at end of file diff --git a/r5launcher/resource.h b/r5launcher/resource.h new file mode 100644 index 00000000..13375343 --- /dev/null +++ b/r5launcher/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by r5launcher.rc +// +#define IDI_ICON1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif From 962afa215e97c75e80cc6644fb8ad64d110dfb60 Mon Sep 17 00:00:00 2001 From: IcePixelx <41352111+PixieCore@users.noreply.github.com> Date: Thu, 19 Aug 2021 14:35:30 +0200 Subject: [PATCH 10/14] Wrong return. --- r5launcher/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/r5launcher/main.cpp b/r5launcher/main.cpp index 189d4128..e9449575 100644 --- a/r5launcher/main.cpp +++ b/r5launcher/main.cpp @@ -227,5 +227,5 @@ int main(int argc, char* argv[], char* envp[]) Sleep(5000); - return EXIT_SUCCESS; + return EXIT_FAILURE; } \ No newline at end of file From bb4b4d76366eccd7687bdfe970e50274320c6622 Mon Sep 17 00:00:00 2001 From: IcePixelx <41352111+PixieCore@users.noreply.github.com> Date: Thu, 19 Aug 2021 14:46:22 +0200 Subject: [PATCH 11/14] Added shortcut with launch params. --- r5launcher/main.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/r5launcher/main.cpp b/r5launcher/main.cpp index e9449575..d37d347d 100644 --- a/r5launcher/main.cpp +++ b/r5launcher/main.cpp @@ -173,6 +173,31 @@ bool LaunchR5Apex(LAUNCHMODE lMode, LAUNCHSTATE lState) /////////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[], char* envp[]) { + for (int i = 1; i < argc; ++i) + { + std::string arg = argv[i]; + if ((arg == "-dedicated") || (arg == "-dedi")) + { + LaunchR5Apex(LAUNCHMODE::LM_DEDI, LAUNCHSTATE::LS_CHEATS); + Sleep(2000); + return EXIT_SUCCESS; + } + + if ((arg == "-debug") || (arg == "-dbg")) + { + LaunchR5Apex(LAUNCHMODE::LM_DEBUG, LAUNCHSTATE::LS_CHEATS); + Sleep(2000); + return EXIT_SUCCESS; + } + + if ((arg == "-release") || (arg == "-rl")) + { + LaunchR5Apex(LAUNCHMODE::LM_GAME, LAUNCHSTATE::LS_CHEATS); + Sleep(2000); + return EXIT_SUCCESS; + } + } + std::cout << "If you choose Dev as start parameter do not host servers into the Server Browser\n\n" << "Every command will be and people can execute any script on your server.\n\n" << "Use release for normal playing.\n\n" From 64aa6e7f97ea9461ed5d5795901e427732fb62bd Mon Sep 17 00:00:00 2001 From: IcePixelx <41352111+PixieCore@users.noreply.github.com> Date: Thu, 19 Aug 2021 14:48:31 +0200 Subject: [PATCH 12/14] Fixed prints. --- r5dev/src/gameclasses.cpp | 4 ++-- r5launcher/main.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/r5dev/src/gameclasses.cpp b/r5dev/src/gameclasses.cpp index 21f47c22..72d1edf9 100644 --- a/r5dev/src/gameclasses.cpp +++ b/r5dev/src/gameclasses.cpp @@ -26,7 +26,7 @@ namespace GameGlobals } catch (std::exception& e) { - std::cout << " [+CGameConsole+] Please don't input a character that isn't a number into cgameconsole :(." << e.what() << std::endl; + std::cout << " [+CGameConsole+] Please don't input a character that isn't a number into cgameconsole :(. Error: " << e.what() << std::endl; } } @@ -50,7 +50,7 @@ namespace GameGlobals } catch (std::exception& e) { - std::cout << " [+CCompanion+] Please don't input a character that isn't a number into ccompanion :(." << e.what() << std::endl; + std::cout << " [+CCompanion+] Please don't input a character that isn't a number into ccompanion :(. Error: " << e.what() << std::endl; }; } } diff --git a/r5launcher/main.cpp b/r5launcher/main.cpp index d37d347d..e4230fd8 100644 --- a/r5launcher/main.cpp +++ b/r5launcher/main.cpp @@ -242,7 +242,7 @@ int main(int argc, char* argv[], char* envp[]) } catch (std::exception& e) { - std::cout << "R5 Reloaded asked for a number and not a letter or anything of that sort :(." << e.what() << std::endl; + std::cout << "R5 Reloaded asked for a number and not a letter or anything of that sort :(. Error: " << e.what() << std::endl; Sleep(5000); return EXIT_FAILURE; } From 4f463eb446f5ebf561d42db0f6cb2bed8a43e517 Mon Sep 17 00:00:00 2001 From: IcePixelx <41352111+PixieCore@users.noreply.github.com> Date: Fri, 20 Aug 2021 12:26:32 +0200 Subject: [PATCH 13/14] Fixed error message parsing in r5net. --- r5net/src/r5net.cpp | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/r5net/src/r5net.cpp b/r5net/src/r5net.cpp index 5a901949..cb2f5bb4 100644 --- a/r5net/src/r5net.cpp +++ b/r5net/src/r5net.cpp @@ -51,9 +51,25 @@ std::vector R5Net::Client::GetServersList(std::string& outMessage else { if (res) + { + if (!res->body.empty()) + { + nlohmann::json resBody = nlohmann::json::parse(res->body); + + if (resBody["err"].is_string()) + outMessage = resBody["err"].get(); + else + outMessage = std::string("Failed to reach comp-server ") + std::to_string(res->status); + + return list; + } + outMessage = std::string("Failed to reach comp-server ") + std::to_string(res->status); - else - outMessage = "Failed to reach comp-server unknown error code."; + return list; + } + + outMessage = "failed to reach comp-server unknown error code."; + return list; } return list; @@ -107,12 +123,24 @@ bool R5Net::Client::PostServerHost(std::string& outMessage, std::string& outToke else { if (res) + { + if (!res->body.empty()) + { + nlohmann::json resBody = nlohmann::json::parse(res->body); + + if (resBody["err"].is_string()) + outMessage = resBody["err"].get(); + else + outMessage = std::string("Failed to reach comp-server ") + std::to_string(res->status); + + return false; + } + outMessage = std::string("Failed to reach comp-server ") + std::to_string(res->status); - else - outMessage = "Failed to reach comp-server unknown error code."; - - outToken = ""; + return false; + } + outMessage = "failed to reach comp-server unknown error code."; return false; } @@ -175,7 +203,7 @@ bool R5Net::Client::GetServerByToken(ServerListing& outServer, std::string& outM if (resBody["err"].is_string()) outMessage = resBody["err"].get(); else - outMessage = "Failed to reach comp-server unknown error code."; + outMessage = std::string("Failed to reach comp-server ") + std::to_string(res->status); return false; } From 906dff5aa4289ddda61be508b6b20320f5cfb7bf Mon Sep 17 00:00:00 2001 From: IcePixelx <41352111+PixieCore@users.noreply.github.com> Date: Fri, 20 Aug 2021 12:37:09 +0200 Subject: [PATCH 14/14] Update r5net.cpp --- r5net/src/r5net.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/r5net/src/r5net.cpp b/r5net/src/r5net.cpp index cb2f5bb4..6afa0130 100644 --- a/r5net/src/r5net.cpp +++ b/r5net/src/r5net.cpp @@ -106,7 +106,7 @@ bool R5Net::Client::PostServerHost(std::string& outMessage, std::string& outToke if (resBody["token"].is_string()) outToken = resBody["token"].get(); else - outToken = ""; + outToken = std::string(); return true; } @@ -133,13 +133,16 @@ bool R5Net::Client::PostServerHost(std::string& outMessage, std::string& outToke else outMessage = std::string("Failed to reach comp-server ") + std::to_string(res->status); + outToken = std::string(); return false; } + outToken = std::string(); outMessage = std::string("Failed to reach comp-server ") + std::to_string(res->status); return false; } + outToken = std::string(); outMessage = "failed to reach comp-server unknown error code."; return false; }