From 01a629d02bb570f0e3803ec71514bdc74c442198 Mon Sep 17 00:00:00 2001 From: Edo Date: Sun, 25 Dec 2022 18:23:53 +0100 Subject: [PATCH] [General]: Fix some things (#667) --- README.md | 1 - premake5.lua | 8 - src/Components/Loader.cpp | 220 +++++++++++++------------- src/Components/Loader.hpp | 128 +++++++-------- src/Components/Modules/CardTitles.cpp | 64 ++++---- src/Components/Modules/CardTitles.hpp | 43 ++--- src/Components/Modules/Dvar.cpp | 16 +- src/Components/Modules/Dvar.hpp | 13 +- src/Components/Modules/Exception.cpp | 84 ++++------ src/Components/Modules/Exception.hpp | 4 +- src/Components/Modules/Party.cpp | 4 +- src/Components/Modules/Playlist.cpp | 141 ++++++++--------- src/Components/Modules/Playlist.hpp | 8 +- src/Components/Modules/ServerInfo.cpp | 4 +- src/Components/Modules/Singleton.cpp | 4 +- src/DllMain.cpp | 2 +- src/Game/Common.cpp | 2 + src/Game/Common.hpp | 4 +- src/Game/Dvars.cpp | 1 + src/Game/Dvars.hpp | 1 + src/Game/Functions.cpp | 4 + src/Game/Functions.hpp | 5 + 22 files changed, 368 insertions(+), 393 deletions(-) diff --git a/README.md b/README.md index 448d11c9..fa6f3612 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,6 @@ | `--copy-to=PATH` | Optional, copy the DLL to a custom folder after build, define the path here if wanted. | | `--copy-pdb` | Copy debug information for binaries as well to the path given via --copy-to. | | `--force-unit-tests` | Always compile unit tests. | -| `--force-exception-handler` | Install custom unhandled exception handler even for Debug builds. | | `--disable-binary-check` | Do not perform integrity checks on the exe. | ## Command line arguments diff --git a/premake5.lua b/premake5.lua index 3f36f4bd..a311c929 100644 --- a/premake5.lua +++ b/premake5.lua @@ -76,11 +76,6 @@ newoption { description = "Always compile unit tests." } -newoption { - trigger = "force-exception-handler", - description = "Install custom unhandled exception handler even for Debug builds." -} - newoption { trigger = "disable-binary-check", description = "Do not perform integrity checks on the exe." @@ -257,9 +252,6 @@ workspace "iw4x" if _OPTIONS["force-unit-tests"] then defines {"FORCE_UNIT_TESTS"} end - if _OPTIONS["force-exception-handler"] then - defines {"FORCE_EXCEPTION_HANDLER"} - end if _OPTIONS["disable-binary-check"] then defines {"DISABLE_BINARY_CHECK"} end diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp index 74caf387..ef452178 100644 --- a/src/Components/Loader.cpp +++ b/src/Components/Loader.cpp @@ -9,128 +9,128 @@ namespace Components bool Loader::IsPregame() { - return Loader::Pregame; + return Pregame; } bool Loader::IsPostgame() { - return Loader::Postgame; + return Postgame; } bool Loader::IsUninitializing() { - return Loader::Uninitializing; + return Uninitializing; } void Loader::Initialize() { - Loader::Pregame = true; - Loader::Postgame = false; - Loader::Uninitializing = false; + Pregame = true; + Postgame = false; + Uninitializing = false; Utils::Memory::GetAllocator()->clear(); - Loader::Register(new Flags()); - Loader::Register(new Singleton()); - // Install our exception handler as early as posssible to get better debug dumps from startup crashes - Loader::Register(new Exception()); - Loader::Register(new Auth()); - Loader::Register(new Bans()); - Loader::Register(new Dvar()); - Loader::Register(new Bots()); - Loader::Register(new Lean()); - Loader::Register(new Maps()); - Loader::Register(new News()); - Loader::Register(new Node()); - Loader::Register(new RCon()); - Loader::Register(new Stats()); - Loader::Register(new Menus()); - Loader::Register(new Toast()); - Loader::Register(new Party()); - Loader::Register(new Zones()); - Loader::Register(new D3D9Ex()); - Loader::Register(new Logger()); - Loader::Register(new Weapon()); - Loader::Register(new Window()); - Loader::Register(new Command()); - Loader::Register(new Console()); - Loader::Register(new Friends()); - Loader::Register(new IPCPipe()); - Loader::Register(new MapDump()); - Loader::Register(new ModList()); - Loader::Register(new Network()); - Loader::Register(new NetworkDebug()); - Loader::Register(new Session()); - Loader::Register(new Theatre()); - Loader::Register(new ClanTags()); - Loader::Register(new Download()); - Loader::Register(new Playlist()); - Loader::Register(new RawFiles()); - Loader::Register(new Renderer()); - Loader::Register(new UIFeeder()); - Loader::Register(new UIScript()); - Loader::Register(new Changelog()); - Loader::Register(new Dedicated()); - Loader::Register(new Discovery()); - Loader::Register(new FastFiles()); - Loader::Register(new Gametypes()); - Loader::Register(new Materials()); - Loader::Register(new Scheduler()); - Loader::Register(new Threading()); - Loader::Register(new CardTitles()); - Loader::Register(new FileSystem()); - Loader::Register(new ModelSurfs()); - Loader::Register(new PlayerName()); - Loader::Register(new QuickPatch()); - Loader::Register(new Security()); - Loader::Register(new ServerInfo()); - Loader::Register(new ServerList()); - Loader::Register(new SlowMotion()); - Loader::Register(new ArenaLength()); - Loader::Register(new StringTable()); - Loader::Register(new ZoneBuilder()); - Loader::Register(new AssetHandler()); - Loader::Register(new Localization()); - Loader::Register(new ServerCommands()); - Loader::Register(new StructuredData()); - Loader::Register(new ConnectProtocol()); - Loader::Register(new StartupMessages()); - Loader::Register(new SoundMutexFix()); - Loader::Register(new Gamepad()); - Loader::Register(new Chat()); - Loader::Register(new TextRenderer()); - Loader::Register(new PlayerMovement()); - Loader::Register(new Elevators()); - Loader::Register(new ClientCommand()); - Loader::Register(new VisionFile()); - Loader::Register(new Branding()); - Loader::Register(new Debug()); - Loader::Register(new RawMouse()); - Loader::Register(new Bullet()); - Loader::Register(new MapRotation()); - Loader::Register(new Ceg()); - Loader::Register(new UserInfo()); - Loader::Register(new Events()); - Loader::Register(new Voice()); - Loader::Register(new Vote()); + Register(new Auth()); + Register(new Command()); + Register(new Dvar()); + Register(new Exception()); // Install our exception handler as early as posssible to get better debug dumps from startup crashes + Register(new Flags()); + Register(new Network()); + Register(new Logger()); + Register(new Singleton()); + Register(new UIScript()); + Register(new ZoneBuilder()); + + Register(new ArenaLength()); + Register(new AssetHandler()); + Register(new Bans()); + Register(new Bots()); + Register(new Branding()); + Register(new Bullet()); + Register(new CardTitles()); + Register(new Ceg()); + Register(new Changelog()); + Register(new Chat()); + Register(new ClanTags()); + Register(new ClientCommand()); + Register(new ConnectProtocol()); + Register(new Console()); + Register(new D3D9Ex()); + Register(new Debug()); + Register(new Dedicated()); + Register(new Discovery()); + Register(new Download()); + Register(new Elevators()); + Register(new Events()); + Register(new FastFiles()); + Register(new FileSystem()); + Register(new Friends()); + Register(new Gamepad()); + Register(new Gametypes()); + Register(new IPCPipe()); + Register(new Lean()); + Register(new Localization()); + Register(new MapDump()); + Register(new MapRotation()); + Register(new Maps()); + Register(new Materials()); + Register(new Menus()); + Register(new ModList()); + Register(new ModelSurfs()); + Register(new NetworkDebug()); + Register(new News()); + Register(new Node()); + Register(new Party()); + Register(new PlayerMovement()); + Register(new PlayerName()); + Register(new Playlist()); + Register(new QuickPatch()); + Register(new RCon()); + Register(new RawFiles()); + Register(new RawMouse()); + Register(new Renderer()); + Register(new Scheduler()); + Register(new Security()); + Register(new ServerCommands()); + Register(new ServerInfo()); + Register(new ServerList()); + Register(new Session()); + Register(new SlowMotion()); + Register(new SoundMutexFix()); + Register(new StartupMessages()); + Register(new Stats()); + Register(new StringTable()); + Register(new StructuredData()); + Register(new TextRenderer()); + Register(new Theatre()); + Register(new Threading()); + Register(new Toast()); + Register(new UIFeeder()); + Register(new UserInfo()); + Register(new VisionFile()); + Register(new Voice()); + Register(new Vote()); + Register(new Weapon()); + Register(new Window()); + Register(new Zones()); - Loader::Register(new GSC()); + Register(new GSC()); - Loader::Pregame = false; + Pregame = false; // Make sure preDestroy is called when the game shuts down - Scheduler::OnGameShutdown(Loader::PreDestroy); + Scheduler::OnGameShutdown(PreDestroy); } void Loader::Uninitialize() { - Loader::Uninitializing = true; - Loader::PreDestroyNoPostGame(); + Uninitializing = true; + PreDestroyNoPostGame(); - std::reverse(Loader::Components.begin(), Loader::Components.end()); - for (auto component : Loader::Components) + std::reverse(Components.begin(), Components.end()); + for (auto& component : Components) { #ifdef DEBUG - if (!Loader::IsPerformingUnitTests()) + if (!IsPerformingUnitTests()) { Logger::Print("Unregister component: {}\n", component->getName()); } @@ -138,21 +138,21 @@ namespace Components delete component; } - Loader::Components.clear(); + Components.clear(); Utils::Memory::GetAllocator()->clear(); - Loader::Uninitializing = false; + Uninitializing = false; } void Loader::PreDestroy() { - if (!Loader::Postgame) + if (!Postgame) { - Loader::Postgame = true; + Postgame = true; - auto components = Loader::Components; + auto components = Components; std::reverse(components.begin(), components.end()); - for (auto component : components) + for (auto& component : components) { component->preDestroy(); } @@ -161,17 +161,17 @@ namespace Components void Loader::PreDestroyNoPostGame() { - if (!Loader::Postgame) + if (!Postgame) { - auto components = Loader::Components; + auto components = Components; std::reverse(components.begin(), components.end()); - for (auto component : components) + for (auto& component : components) { component->preDestroy(); } - Loader::Postgame = true; + Postgame = true; } } @@ -181,7 +181,7 @@ namespace Components Logger::Print("Performing unit tests for components:\n"); - for (const auto component : Loader::Components) + for (const auto& component : Components) { #if defined(FORCE_UNIT_TESTS) Logger::Debug("Testing '{}'...\n", component->getName()); @@ -210,12 +210,12 @@ namespace Components if (component) { #if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - if (!Loader::IsPerformingUnitTests()) + if (!IsPerformingUnitTests()) { Logger::Print("Component registered: {}\n", component->getName()); } #endif - Loader::Components.push_back(component); + Components.push_back(component); } } } diff --git a/src/Components/Loader.hpp b/src/Components/Loader.hpp index b45931db..33e84015 100644 --- a/src/Components/Loader.hpp +++ b/src/Components/Loader.hpp @@ -42,7 +42,7 @@ namespace Components template static T* GetInstance() { - for (auto& component : Loader::Components) + for (auto& component : Components) { if (typeid(*component) == typeid(T)) { @@ -61,87 +61,89 @@ namespace Components }; } -#include "Modules/Scheduler.hpp" +// Priority #include "Modules/Auth.hpp" -#include "Modules/Bans.hpp" -#include "Modules/Dvar.hpp" -#include "Modules/Bots.hpp" -#include "Modules/Lean.hpp" -#include "Modules/Maps.hpp" -#include "Modules/News.hpp" -#include "Modules/Flags.hpp" -#include "Modules/Menus.hpp" -#include "Modules/Toast.hpp" -#include "Modules/Zones.hpp" -#include "Modules/D3D9Ex.hpp" -#include "Modules/Weapon.hpp" -#include "Modules/Window.hpp" #include "Modules/Command.hpp" -#include "Modules/Console.hpp" -#include "Modules/UIScript.hpp" -#include "Modules/ModList.hpp" +#include "Modules/Dvar.hpp" +#include "Modules/Exception.hpp" +#include "Modules/Flags.hpp" #include "Modules/Network.hpp" -#include "Modules/NetworkDebug.hpp" -#include "Modules/Theatre.hpp" -#include "Modules/QuickPatch.hpp" -#include "Modules/Security.hpp" -#include "Modules/Node.hpp" -#include "Modules/RCon.hpp" -#include "Modules/Party.hpp" // Destroys the order, but requires network classes :D #include "Modules/Logger.hpp" -#include "Modules/Friends.hpp" -#include "Modules/IPCPipe.hpp" -#include "Modules/MapDump.hpp" -#include "Modules/Session.hpp" -#include "Modules/ClanTags.hpp" -#include "Modules/Download.hpp" -#include "Modules/Playlist.hpp" -#include "Modules/RawFiles.hpp" -#include "Modules/Renderer.hpp" -#include "Modules/UIFeeder.hpp" +#include "Modules/Singleton.hpp" +#include "Modules/UIScript.hpp" +#include "Modules/ZoneBuilder.hpp" + +#include "Modules/ArenaLength.hpp" +#include "Modules/AssetHandler.hpp" +#include "Modules/Bans.hpp" +#include "Modules/Bots.hpp" +#include "Modules/Branding.hpp" +#include "Modules/Bullet.hpp" +#include "Modules/CardTitles.hpp" +#include "Modules/Ceg.hpp" #include "Modules/Changelog.hpp" +#include "Modules/Chat.hpp" +#include "Modules/ClanTags.hpp" +#include "Modules/ClientCommand.hpp" +#include "Modules/ConnectProtocol.hpp" +#include "Modules/Console.hpp" +#include "Modules/D3D9Ex.hpp" +#include "Modules/Debug.hpp" #include "Modules/Dedicated.hpp" #include "Modules/Discovery.hpp" -#include "Modules/Exception.hpp" +#include "Modules/Download.hpp" +#include "Modules/Elevators.hpp" +#include "Modules/Events.hpp" #include "Modules/FastFiles.hpp" -#include "Modules/Gametypes.hpp" -#include "Modules/Materials.hpp" -#include "Modules/Singleton.hpp" -#include "Modules/Threading.hpp" -#include "Modules/CardTitles.hpp" #include "Modules/FileSystem.hpp" +#include "Modules/Friends.hpp" +#include "Modules/Gamepad.hpp" +#include "Modules/Gametypes.hpp" +#include "Modules/IPCPipe.hpp" +#include "Modules/Lean.hpp" +#include "Modules/Localization.hpp" +#include "Modules/MapDump.hpp" +#include "Modules/MapRotation.hpp" +#include "Modules/Maps.hpp" +#include "Modules/Materials.hpp" +#include "Modules/Menus.hpp" +#include "Modules/ModList.hpp" #include "Modules/ModelSurfs.hpp" +#include "Modules/NetworkDebug.hpp" +#include "Modules/News.hpp" +#include "Modules/Node.hpp" +#include "Modules/Party.hpp" +#include "Modules/PlayerMovement.hpp" #include "Modules/PlayerName.hpp" +#include "Modules/Playlist.hpp" +#include "Modules/QuickPatch.hpp" +#include "Modules/RCon.hpp" +#include "Modules/RawFiles.hpp" +#include "Modules/RawMouse.hpp" +#include "Modules/Renderer.hpp" +#include "Modules/Scheduler.hpp" +#include "Modules/Security.hpp" +#include "Modules/ServerCommands.hpp" #include "Modules/ServerInfo.hpp" #include "Modules/ServerList.hpp" +#include "Modules/Session.hpp" #include "Modules/SlowMotion.hpp" -#include "Modules/ArenaLength.hpp" -#include "Modules/StringTable.hpp" -#include "Modules/ZoneBuilder.hpp" -#include "Modules/AssetHandler.hpp" -#include "Modules/Localization.hpp" -#include "Modules/ServerCommands.hpp" -#include "Modules/StructuredData.hpp" -#include "Modules/ConnectProtocol.hpp" +#include "Modules/SoundMutexFix.hpp" #include "Modules/StartupMessages.hpp" #include "Modules/Stats.hpp" -#include "Modules/SoundMutexFix.hpp" -#include "Modules/Chat.hpp" +#include "Modules/StringTable.hpp" +#include "Modules/StructuredData.hpp" #include "Modules/TextRenderer.hpp" -#include "Modules/PlayerMovement.hpp" -#include "Modules/Elevators.hpp" -#include "Modules/ClientCommand.hpp" -#include "Modules/VisionFile.hpp" -#include "Modules/Gamepad.hpp" -#include "Modules/Branding.hpp" -#include "Modules/Debug.hpp" -#include "Modules/RawMouse.hpp" -#include "Modules/Bullet.hpp" -#include "Modules/MapRotation.hpp" -#include "Modules/Ceg.hpp" +#include "Modules/Theatre.hpp" +#include "Modules/Threading.hpp" +#include "Modules/Toast.hpp" +#include "Modules/UIFeeder.hpp" #include "Modules/UserInfo.hpp" -#include "Modules/Events.hpp" +#include "Modules/VisionFile.hpp" #include "Modules/Voice.hpp" #include "Modules/Vote.hpp" +#include "Modules/Weapon.hpp" +#include "Modules/Window.hpp" +#include "Modules/Zones.hpp" #include "Modules/GSC/GSC.hpp" diff --git a/src/Components/Modules/CardTitles.cpp b/src/Components/Modules/CardTitles.cpp index d4dcb8b0..5e00a4e4 100644 --- a/src/Components/Modules/CardTitles.cpp +++ b/src/Components/Modules/CardTitles.cpp @@ -2,7 +2,7 @@ namespace Components { - std::string CardTitles::CustomTitles[18]; + char CardTitles::CustomTitles[Game::MAX_CLIENTS][18]; Dvar::Var CardTitles::CustomTitle; CClient* CardTitles::GetClientByIndex(std::uint32_t index) @@ -10,35 +10,34 @@ namespace Components return &reinterpret_cast(0x8E77B0)[index]; } - std::int32_t CardTitles::GetPlayerCardClientInfo(std::int32_t lookupResult, Game::PlayerCardData* data) + int CardTitles::GetPlayerCardClientInfo(int lookupResult, Game::PlayerCardData* data) { - std::int32_t returnResult = lookupResult; + auto result = lookupResult; - std::string username = Dvar::Var("name").get(); - - if (data->name == username) + const auto* username = Dvar::Var("name").get(); + if (std::strcmp(data->name, username) == 0) { - returnResult += 0xFE000000; + result += 0xFE000000; } else { - for (std::size_t clientNum = 0; clientNum < Game::MAX_CLIENTS; ++clientNum) + for (std::size_t i = 0; i < Game::MAX_CLIENTS; ++i) { - CClient* c = GetClientByIndex(clientNum); + CClient* c = GetClientByIndex(i); if (c != nullptr) { if (!std::strcmp(data->name, c->Name)) { // Since a 4 byte integer is overkill for a row num: We can use it to store the customprefix + clientNum and use a 2 byte integer for the row number - returnResult += 0xFF000000; - returnResult += clientNum * 0x10000; + result += 0xFF000000; + result += i * 0x10000; break; } } } } - return returnResult; + return result; } void __declspec(naked) CardTitles::GetPlayerCardClientInfoStub() @@ -71,7 +70,7 @@ namespace Components std::uint8_t prefix = (request->tableRow >> (8 * 3)) & 0xFF; std::uint8_t data = (request->tableRow >> (8 * 2)) & 0xFF; - if (data >= ARRAYSIZE(CardTitles::CustomTitles)) return nullptr; + if (data >= Game::MAX_CLIENTS) return nullptr; if (request->tablename == "mp/cardTitleTable.csv"s) { @@ -82,10 +81,10 @@ namespace Components { if (prefix == 0xFE) { - if (!CardTitles::CustomTitle.get().empty()) + if (!CustomTitle.get().empty()) { // 0xFF in front of the title to skip localization. Or else it will wait for a couple of seconds for the asset of type localize - const char* title = Utils::String::VA("\x15%s", CardTitles::CustomTitle.get()); + const auto* title = Utils::String::VA("\x15%s", CustomTitle.get()); // prepare return value operand->internals.stringVal.string = title; @@ -96,9 +95,9 @@ namespace Components } else if (prefix == 0xFF) { - if (!CardTitles::CustomTitles[data].empty()) + if (CustomTitles[data][0] != '\0') { - const char* title = Utils::String::VA("\x15%s", CardTitles::CustomTitles[data].data()); + const auto* title = Utils::String::VA("\x15%s", CustomTitles[data]); // prepare return value operand->internals.stringVal.string = title; @@ -156,11 +155,11 @@ namespace Components { std::string list; - for (std::size_t i = 0; i < Game::MAX_CLIENTS; i++) + for (std::size_t i = 0; i < Game::MAX_CLIENTS; ++i) { - char playerTitle[18]; + char playerTitle[18]{}; - if (Game::svs_clients[i].header.state >= Game::CS_CONNECTED) + if (Game::svs_clients[i].userinfo[0] != '\0') { strncpy_s(playerTitle, Game::Info_ValueForKey(Game::svs_clients[i].userinfo, "customTitle"), _TRUNCATE); } @@ -180,10 +179,17 @@ namespace Components { for (std::size_t i = 0; i < Game::MAX_CLIENTS; ++i) { - const char* playerTitle = Game::Info_ValueForKey(msg, std::to_string(i).c_str()); + const auto index = std::to_string(i); + const auto* playerTitle = Game::Info_ValueForKey(msg, index.data()); - if (playerTitle) CardTitles::CustomTitles[i] = playerTitle; - else CardTitles::CustomTitles[i].clear(); + if (playerTitle[0] == '\0') + { + CustomTitles[i][0] = '\0'; + } + else + { + Game::I_strncpyz(CustomTitles[i], playerTitle, sizeof(CustomTitles[0]) / sizeof(char)); + } } } @@ -191,16 +197,18 @@ namespace Components { Scheduler::Once([] { - CardTitles::CustomTitle = Dvar::Register("customTitle", "", Game::DVAR_USERINFO | Game::DVAR_ARCHIVE, "Custom card title"); + CustomTitle = Dvar::Register("customTitle", "", Game::DVAR_USERINFO | Game::DVAR_ARCHIVE, "Custom card title"); }, Scheduler::Pipeline::MAIN); + std::memset(&CustomTitles, 0, sizeof(char[Game::MAX_CLIENTS][18])); + ServerCommands::OnCommand(21, [](Command::Params* params) { - if (params->get(1) == "customTitles"s && !Dedicated::IsEnabled()) + if (std::strcmp(params->get(1), "customTitles") == 0) { if (params->size() == 3) { - CardTitles::ParseCustomTitles(params->get(2)); + ParseCustomTitles(params->get(2)); return true; } } @@ -209,10 +217,10 @@ namespace Components }); - Utils::Hook(0x62EB26, CardTitles::GetPlayerCardClientInfoStub).install()->quick(); + Utils::Hook(0x62EB26, GetPlayerCardClientInfoStub).install()->quick(); // Table lookup stuff - Utils::Hook(0x62DCC1, CardTitles::TableLookupByRowHookStub).install()->quick(); + Utils::Hook(0x62DCC1, TableLookupByRowHookStub).install()->quick(); Utils::Hook::Nop(0x62DCC6, 1); } } diff --git a/src/Components/Modules/CardTitles.hpp b/src/Components/Modules/CardTitles.hpp index 7dcf5ce8..67b64495 100644 --- a/src/Components/Modules/CardTitles.hpp +++ b/src/Components/Modules/CardTitles.hpp @@ -14,27 +14,27 @@ namespace Components struct CClient { - std::uint32_t IsValid; // 0x0000 - std::uint32_t IsValid2; // 0x0004 - std::uint32_t ClientNumber; // 0x0008 - char Name[16]; // 0x000C - std::uint32_t Team; // 0x001C - std::uint32_t Team2; // 0x0020 - std::uint32_t Rank; // 0x0024 (rank - 1) - std::uint32_t Prestige; // 0x0028 - std::uint32_t Perks; // 0x002C - std::uint32_t Kills; // 0x0030 - std::uint32_t Score; // 0x0034 + std::uint32_t IsValid; // 0x0000 + std::uint32_t IsValid2; // 0x0004 + std::uint32_t ClientNumber; // 0x0008 + char Name[16]; // 0x000C + std::uint32_t Team; // 0x001C + std::uint32_t Team2; // 0x0020 + std::uint32_t Rank; // 0x0024 (rank - 1) + std::uint32_t Prestige; // 0x0028 + std::uint32_t Perks; // 0x002C + std::uint32_t Kills; // 0x0030 + std::uint32_t Score; // 0x0034 std::uint8_t _0x0038[968]; - std::uint32_t ViewAngles; // 0x0400 + std::uint32_t ViewAngles; // 0x0400 std::uint8_t _0x040C[136]; - std::uint32_t IsShooting; // 0x0494 + std::uint32_t IsShooting; // 0x0494 std::uint8_t _0x0498[4]; - std::uint32_t IsZoomed; // 0x049C + std::uint32_t IsZoomed; // 0x049C std::uint8_t _0x04A0[68]; - std::uint32_t weaponID; // 0x04E4 + std::uint32_t weaponID; // 0x04E4 std::uint8_t _0x04E8[24]; - std::uint32_t weaponID2; // 0x0500 + std::uint32_t weaponID2; // 0x0500 std::uint8_t _0x0504[40]; std::uint8_t _padding[8]; }; @@ -44,19 +44,20 @@ namespace Components public: AssertOffset(Game::PlayerCardData, Game::PlayerCardData::name, 0x1C); - static Dvar::Var CustomTitle; - static std::string CustomTitles[18]; - static void SendCustomTitlesToClients(); - static void ParseCustomTitles(const char* msg); CardTitles(); private: + static Dvar::Var CustomTitle; + static char CustomTitles[Game::MAX_CLIENTS][18]; + static CClient* GetClientByIndex(std::uint32_t index); - static std::int32_t GetPlayerCardClientInfo(std::int32_t lookupResult, Game::PlayerCardData* data); + static int GetPlayerCardClientInfo(int lookupResult, Game::PlayerCardData* data); static void GetPlayerCardClientInfoStub(); static const char* TableLookupByRowHook(Game::Operand* operand, tablelookuprequest_s* request); static void TableLookupByRowHookStub(); + + static void ParseCustomTitles(const char* msg); }; } diff --git a/src/Components/Modules/Dvar.cpp b/src/Components/Modules/Dvar.cpp index dd96d737..857d0976 100644 --- a/src/Components/Modules/Dvar.cpp +++ b/src/Components/Modules/Dvar.cpp @@ -186,24 +186,24 @@ namespace Components } } - template<> Dvar::Var Dvar::Register(const char* dvarName, bool value, Flag flag, const char* description) + template<> Dvar::Var Dvar::Register(const char* dvarName, bool value, std::uint16_t flag, const char* description) { - return Game::Dvar_RegisterBool(dvarName, value, flag.val, description); + return Game::Dvar_RegisterBool(dvarName, value, flag, description); } - template<> Dvar::Var Dvar::Register(const char* dvarName, const char* value, Flag flag, const char* description) + template<> Dvar::Var Dvar::Register(const char* dvarName, const char* value, std::uint16_t flag, const char* description) { - return Game::Dvar_RegisterString(dvarName, value, flag.val, description); + return Game::Dvar_RegisterString(dvarName, value, flag, description); } - template<> Dvar::Var Dvar::Register(const char* dvarName, int value, int min, int max, Flag flag, const char* description) + template<> Dvar::Var Dvar::Register(const char* dvarName, int value, int min, int max, std::uint16_t flag, const char* description) { - return Game::Dvar_RegisterInt(dvarName, value, min, max, flag.val, description); + return Game::Dvar_RegisterInt(dvarName, value, min, max, flag, description); } - template<> Dvar::Var Dvar::Register(const char* dvarName, float value, float min, float max, Flag flag, const char* description) + template<> Dvar::Var Dvar::Register(const char* dvarName, float value, float min, float max, std::uint16_t flag, const char* description) { - return Game::Dvar_RegisterFloat(dvarName, value, min, max, flag.val, description); + return Game::Dvar_RegisterFloat(dvarName, value, min, max, flag, description); } void Dvar::ResetDvarsValue() diff --git a/src/Components/Modules/Dvar.hpp b/src/Components/Modules/Dvar.hpp index 7f97a842..a34154c6 100644 --- a/src/Components/Modules/Dvar.hpp +++ b/src/Components/Modules/Dvar.hpp @@ -5,15 +5,6 @@ namespace Components class Dvar : public Component { public: - class Flag - { - public: - Flag(Game::DvarFlags flag) : val(flag) {} - Flag(std::uint16_t flag) : Flag(static_cast(flag)) {} - - Game::DvarFlags val; - }; - class Var { public: @@ -44,8 +35,8 @@ namespace Components ~Dvar(); // Only strings and bools use this type of declaration - template static Var Register(const char* dvarName, T value, Flag flag, const char* description); - template static Var Register(const char* dvarName, T value, T min, T max, Flag flag, const char* description); + template static Var Register(const char* dvarName, T value, std::uint16_t flag, const char* description); + template static Var Register(const char* dvarName, T value, T min, T max, std::uint16_t flag, const char* description); static void ResetDvarsValue(); diff --git a/src/Components/Modules/Exception.cpp b/src/Components/Modules/Exception.cpp index f1d84b3d..c831f46f 100644 --- a/src/Components/Modules/Exception.cpp +++ b/src/Components/Modules/Exception.cpp @@ -7,20 +7,10 @@ namespace Components Utils::Hook Exception::SetFilterHook; int Exception::MiniDumpType; - __declspec(noreturn) void Exception::ErrorLongJmp(jmp_buf _Buf, int _Value) - { - if (!*reinterpret_cast(0x1AD7EB4)) - { - TerminateProcess(GetCurrentProcess(), 1337); - } - - longjmp(_Buf, _Value); - } - - __declspec(noreturn) void Exception::LongJmp(jmp_buf _Buf, int _Value) + __declspec(noreturn) void Exception::LongJmp_Internal_Stub(jmp_buf env, int status) { AssetHandler::ResetBypassState(); - longjmp(_Buf, _Value); + Game::longjmp_internal(env, status); } void Exception::SuspendProcess() @@ -76,7 +66,7 @@ namespace Components return; } - auto lock = GlobalLock(hMem); + auto* lock = GlobalLock(hMem); if (lock != nullptr) { std::memcpy(lock, error.data(), error.size() + 1); @@ -107,17 +97,15 @@ namespace Components errorStr = Utils::String::VA("Fatal error (0x%08X) at 0x%08X.\nCopy exception address to clipboard?", ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress); } - //Exception::SuspendProcess(); - // Message should be copied to the keyboard if no button is pressed if (MessageBoxA(nullptr, errorStr.data(), nullptr, MB_YESNO | MB_ICONERROR) == IDYES) { - Exception::CopyMessageToClipboard(Utils::String::VA("0x%08X", ExceptionInfo->ExceptionRecord->ExceptionAddress)); + CopyMessageToClipboard(Utils::String::VA("0x%08X", ExceptionInfo->ExceptionRecord->ExceptionAddress)); } if (Flags::HasFlag("bigminidumps")) { - Exception::SetMiniDumpType(true, false); + SetMiniDumpType(true, false); } // Current executable name @@ -134,23 +122,22 @@ namespace Components _localtime64_s(<ime, &time); strftime(filenameFriendlyTime, sizeof(filenameFriendlyTime) - 1, "%Y%m%d%H%M%S", <ime); - // Combine with queuedMinidumpsFolder - char filename[MAX_PATH] = { 0 }; - Utils::IO::CreateDir("minidumps"); + // Combine with queued MinidumpsFolder + char filename[MAX_PATH]{}; + CreateDirectoryA("minidumps", nullptr); PathCombineA(filename, "minidumps\\", Utils::String::VA("%s-" VERSION "-%s.dmp", exeFileName, filenameFriendlyTime)); - DWORD fileShare = FILE_SHARE_READ | FILE_SHARE_WRITE; + constexpr auto fileShare = FILE_SHARE_READ | FILE_SHARE_WRITE; HANDLE hFile = CreateFileA(filename, GENERIC_WRITE | GENERIC_READ, fileShare, nullptr, (fileShare & FILE_SHARE_WRITE) > 0 ? OPEN_ALWAYS : OPEN_EXISTING, NULL, nullptr); MINIDUMP_EXCEPTION_INFORMATION ex = { GetCurrentThreadId(), ExceptionInfo, FALSE }; - if (!MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, static_cast(Exception::MiniDumpType), &ex, nullptr, nullptr)) + if (!MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, static_cast(MiniDumpType), &ex, nullptr, nullptr)) { - MessageBoxA(nullptr, Utils::String::VA("There was an error creating the minidump (%s)! Hit OK to close the program.", Utils::GetLastWindowsError().data()), "Minidump Error", MB_OK | MB_ICONERROR); + MessageBoxA(nullptr, Utils::String::Format("There was an error creating the minidump ({})! Hit OK to close the program.", Utils::GetLastWindowsError()), "ERROR", MB_OK | MB_ICONERROR); OutputDebugStringA("Failed to create new minidump!"); Utils::OutputDebugLastError(); TerminateProcess(GetCurrentProcess(), ExceptionInfo->ExceptionRecord->ExceptionCode); } - //if (ExceptionInfo->ExceptionRecord->ExceptionFlags == EXCEPTION_NONCONTINUABLE) { TerminateProcess(GetCurrentProcess(), ExceptionInfo->ExceptionRecord->ExceptionCode); } @@ -158,54 +145,39 @@ namespace Components return EXCEPTION_CONTINUE_SEARCH; } - LPTOP_LEVEL_EXCEPTION_FILTER WINAPI Exception::SetUnhandledExceptionFilterStub(LPTOP_LEVEL_EXCEPTION_FILTER) - { - Exception::SetFilterHook.uninstall(); - LPTOP_LEVEL_EXCEPTION_FILTER retval = SetUnhandledExceptionFilter(&Exception::ExceptionFilter); - Exception::SetFilterHook.install(); - return retval; - } - - LPTOP_LEVEL_EXCEPTION_FILTER Exception::Hook() - { - return SetUnhandledExceptionFilter(&Exception::ExceptionFilter); - } - void Exception::SetMiniDumpType(bool codeseg, bool dataseg) { - Exception::MiniDumpType = MiniDumpIgnoreInaccessibleMemory; - Exception::MiniDumpType |= MiniDumpWithHandleData; - Exception::MiniDumpType |= MiniDumpScanMemory; - Exception::MiniDumpType |= MiniDumpWithProcessThreadData; - Exception::MiniDumpType |= MiniDumpWithFullMemoryInfo; - Exception::MiniDumpType |= MiniDumpWithThreadInfo; - //Exception::MiniDumpType |= MiniDumpWithModuleHeaders; + MiniDumpType = MiniDumpIgnoreInaccessibleMemory; + MiniDumpType |= MiniDumpWithHandleData; + MiniDumpType |= MiniDumpScanMemory; + MiniDumpType |= MiniDumpWithProcessThreadData; + MiniDumpType |= MiniDumpWithFullMemoryInfo; + MiniDumpType |= MiniDumpWithThreadInfo; if (codeseg) { - Exception::MiniDumpType |= MiniDumpWithCodeSegs; + MiniDumpType |= MiniDumpWithCodeSegs; } + if (dataseg) { - Exception::MiniDumpType |= MiniDumpWithDataSegs; + MiniDumpType |= MiniDumpWithDataSegs; } } Exception::Exception() { - Exception::SetMiniDumpType(Flags::HasFlag("bigminidumps"), Flags::HasFlag("reallybigminidumps")); - -#if !defined(DEBUG) || defined(FORCE_EXCEPTION_HANDLER) - Exception::SetFilterHook.initialize(SetUnhandledExceptionFilter, Exception::SetUnhandledExceptionFilterStub, HOOK_JUMP); - Exception::SetFilterHook.install(); + SetMiniDumpType(Flags::HasFlag("bigminidumps"), Flags::HasFlag("reallybigminidumps")); SetUnhandledExceptionFilter(&Exception::ExceptionFilter); -#endif - //Utils::Hook(0x4B241F, Exception::ErrorLongJmp, HOOK_CALL).install()->quick(); - Utils::Hook(0x6B8898, Exception::LongJmp, HOOK_JUMP).install()->quick(); + Utils::Hook(0x4B241F, LongJmp_Internal_Stub, HOOK_CALL).install()->quick(); + Utils::Hook(0x61DB44, LongJmp_Internal_Stub, HOOK_CALL).install()->quick(); + Utils::Hook(0x61F17D, LongJmp_Internal_Stub, HOOK_CALL).install()->quick(); + Utils::Hook(0x61F248, LongJmp_Internal_Stub, HOOK_CALL).install()->quick(); + Utils::Hook(0x61F5E7, LongJmp_Internal_Stub, HOOK_CALL).install()->quick(); -#ifdef _DEBUG +#ifdef MAP_TEST Command::Add("mapTest", [](Command::Params* params) { Game::UI_UpdateArenas(); @@ -227,6 +199,6 @@ namespace Components Exception::~Exception() { - Exception::SetFilterHook.uninstall(); + SetFilterHook.uninstall(); } } diff --git a/src/Components/Modules/Exception.hpp b/src/Components/Modules/Exception.hpp index 55a04c1f..20a5d0b7 100644 --- a/src/Components/Modules/Exception.hpp +++ b/src/Components/Modules/Exception.hpp @@ -15,9 +15,7 @@ namespace Components private: static void SuspendProcess(); static LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS ExceptionInfo); - static LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilterStub(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter); - static __declspec(noreturn) void ErrorLongJmp(jmp_buf _Buf, int _Value); - static __declspec(noreturn) void LongJmp(jmp_buf _Buf, int _Value); + static __declspec(noreturn) void LongJmp_Internal_Stub(jmp_buf env, int status); static void CopyMessageToClipboard(const std::string& error); diff --git a/src/Components/Modules/Party.cpp b/src/Components/Modules/Party.cpp index 34128c5d..62c31846 100644 --- a/src/Components/Modules/Party.cpp +++ b/src/Components/Modules/Party.cpp @@ -319,7 +319,7 @@ namespace Components auto clientCount = 0; auto maxClientCount = *Game::svs_clientCount; const auto securityLevel = Dvar::Var("sv_securityLevel").get(); - const auto password = Dvar::Var("g_password").get(); + const auto* password = (*Game::g_password)->current.string; if (maxClientCount) { @@ -352,7 +352,7 @@ namespace Components info.set("shortversion", SHORTVERSION); info.set("checksum", std::to_string(Game::Sys_Milliseconds())); info.set("mapname", Dvar::Var("mapname").get()); - info.set("isPrivate", password.empty() ? "0" : "1"); + info.set("isPrivate", *password ? "1" : "0"); info.set("hc", (Dvar::Var("g_hardcore").get() ? "1" : "0")); info.set("securityLevel", std::to_string(securityLevel)); info.set("sv_running", (Dedicated::IsRunning() ? "1" : "0")); diff --git a/src/Components/Modules/Playlist.cpp b/src/Components/Modules/Playlist.cpp index 8e25475f..915042e2 100644 --- a/src/Components/Modules/Playlist.cpp +++ b/src/Components/Modules/Playlist.cpp @@ -9,26 +9,26 @@ namespace Components void Playlist::LoadPlaylist() { // Check if playlist already loaded - if (Utils::Hook::Get(0x1AD3680)) return; + if (*Game::s_havePlaylists) return; // Don't load playlists when dedi and no party if (Dedicated::IsEnabled() && !Dvar::Var("party_enable").get()) { - Utils::Hook::Set(0x1AD3680, true); // Set received to true + *Game::s_havePlaylists = true; Dvar::Var("xblive_privateserver").set(true); return; } Dvar::Var("xblive_privateserver").set(false); - auto playlistFilename = Dvar::Var("playlistFilename").get(); + const auto playlistFilename = Dvar::Var("playlistFilename").get(); FileSystem::File playlist(playlistFilename); if (playlist.exists()) { Logger::Print("Parsing playlist '{}'...\n", playlist.getName()); Game::Playlist_ParsePlaylists(playlist.getBuffer().data()); - Utils::Hook::Set(0x1AD3680, true); // Playlist loaded + *Game::s_havePlaylists = true; } else { @@ -36,18 +36,18 @@ namespace Components } } - DWORD Playlist::StorePlaylistStub(const char** buffer) + char* Playlist::Com_ParseOnLine_Hk(const char** data_p) { - Playlist::MapRelocation.clear(); - Playlist::CurrentPlaylistBuffer = Utils::Compression::ZLib::Compress(*buffer); - return Utils::Hook::Call(0x4C0350)(buffer); + MapRelocation.clear(); + CurrentPlaylistBuffer = Utils::Compression::ZLib::Compress(*data_p); + return Game::Com_ParseOnLine(data_p); } void Playlist::PlaylistRequest(const Network::Address& address, [[maybe_unused]] const std::string& data) { - const auto password = Dvar::Var("g_password").get(); + const auto* password = (*Game::g_password)->current.string; - if (password.length()) + if (*password) { if (password != data) { @@ -58,7 +58,7 @@ namespace Components Logger::Print("Received playlist request, sending currently stored buffer.\n"); - std::string compressedList = Playlist::CurrentPlaylistBuffer; + std::string compressedList = CurrentPlaylistBuffer; Proto::Party::Playlist list; list.set_hash(Utils::Cryptography::JenkinsOneAtATime::Compute(compressedList)); @@ -67,51 +67,48 @@ namespace Components Network::SendCommand(address, "playlistResponse", list.SerializeAsString()); } - void Playlist::PlaylistReponse(const Network::Address& address, [[maybe_unused]] const std::string& data) + void Playlist::PlaylistResponse(const Network::Address& address, [[maybe_unused]] const std::string& data) { - if (Party::PlaylistAwaiting()) + if (!Party::PlaylistAwaiting()) { - if (address == Party::Target()) - { - Proto::Party::Playlist list; + Logger::Print("Received stray playlist response, ignoring it.\n"); + return; + } + + if (address != Party::Target()) + { + Logger::Print("Received playlist from someone else than our target host, ignoring it.\n"); + return; + } + + Proto::Party::Playlist list; - if (!list.ParseFromString(data)) - { - Party::PlaylistError(Utils::String::VA("Received playlist response from %s, but it is invalid.", address.getCString())); - Playlist::ReceivedPlaylistBuffer.clear(); - return; - } - else - { - // Generate buffer and hash - const auto& compressedData = list.buffer(); - const auto hash = Utils::Cryptography::JenkinsOneAtATime::Compute(compressedData); - - //Validate hashes - if (hash != list.hash()) - { - Party::PlaylistError(Utils::String::VA("Received playlist response from %s, but the checksum did not match (%X != %X).", address.getCString(), list.hash(), hash)); - Playlist::ReceivedPlaylistBuffer.clear(); - return; - } - - // Decompress buffer - Playlist::ReceivedPlaylistBuffer = Utils::Compression::ZLib::Decompress(compressedData); - - // Load and continue connection - Logger::Print("Received playlist, loading and continuing connection...\n"); - Game::Playlist_ParsePlaylists(Playlist::ReceivedPlaylistBuffer.data()); - Party::PlaylistContinue(); - } - } - else - { - Logger::Print("Received playlist from someone else than our target host, ignoring it.\n"); - } + if (!list.ParseFromString(data)) + { + Party::PlaylistError(std::format("Received playlist response from {}, but it is invalid.", address.getString())); + ReceivedPlaylistBuffer.clear(); } else { - Logger::Print("Received stray playlist response, ignoring it.\n"); + // Generate buffer and hash + const auto& compressedData = list.buffer(); + const auto hash = Utils::Cryptography::JenkinsOneAtATime::Compute(compressedData); + + // Validate hashes + if (hash != list.hash()) + { + Party::PlaylistError(std::format("Received playlist response from {}, but the checksum did not match ({} != {}).", address.getString(), list.hash(), hash)); + ReceivedPlaylistBuffer.clear(); + return; + } + + // Decompress buffer + ReceivedPlaylistBuffer = Utils::Compression::ZLib::Decompress(compressedData); + + // Load and continue connection + Logger::Print("Received playlist, loading and continuing connection...\n"); + Game::Playlist_ParsePlaylists(ReceivedPlaylistBuffer.data()); + Party::PlaylistContinue(); } } @@ -120,27 +117,27 @@ namespace Components Party::PlaylistError("Error: Invalid Password for Party."); } - void Playlist::MapNameCopy(char *dest, const char *src, int destsize) + void Playlist::MapNameCopy(char* dest, const char* src, int destsize) { Utils::Hook::Call(0x4D6F80)(dest, src, destsize); - Playlist::MapRelocation[dest] = src; + MapRelocation[dest] = src; } - void Playlist::SetMapName(const char* cvar, const char* value) + void Playlist::SetMapName(const char* dvarName, const char* value) { - auto i = Playlist::MapRelocation.find(value); - if (i != Playlist::MapRelocation.end()) + auto i = MapRelocation.find(value); + if (i != MapRelocation.end()) { value = i->second.data(); } - Game::Dvar_SetStringByName(cvar, value); + Game::Dvar_SetStringByName(dvarName, value); } int Playlist::GetMapIndex(const char* mapname) { - auto i = Playlist::MapRelocation.find(mapname); - if (i != Playlist::MapRelocation.end()) + auto i = MapRelocation.find(mapname); + if (i != MapRelocation.end()) { mapname = i->second.data(); } @@ -153,7 +150,7 @@ namespace Components // Default playlists Utils::Hook::Set(0x60B06E, "playlists_default.info"); - // disable playlist download function + // Disable playlist download function Utils::Hook::Set(0x4D4790, 0xC3); // Load playlist, but don't delete it @@ -161,34 +158,34 @@ namespace Components Utils::Hook::Nop(0x4D6E67, 5); Utils::Hook::Nop(0x4D6E71, 2); - // playlist dvar 'validity check' + // Disable Playlist_ValidatePlaylistNum Utils::Hook::Set(0x4B1170, 0xC3); - // disable playlist checking - Utils::Hook::Set(0x5B69E9, 0xEB); // too new - Utils::Hook::Set(0x5B696E, 0xEB); // too old + // Disable playlist checking + Utils::Hook::Set(0x5B69E9, 0xEB); // Too new + Utils::Hook::Set(0x5B696E, 0xEB); // Too old - //Got playlists is true + // Got playlists is true //Utils::Hook::Set(0x1AD3680, true); - Utils::Hook(0x497DB5, Playlist::GetMapIndex, HOOK_CALL).install()->quick(); - Utils::Hook(0x42A19D, Playlist::MapNameCopy, HOOK_CALL).install()->quick(); - Utils::Hook(0x4A6FEE, Playlist::SetMapName, HOOK_CALL).install()->quick(); + Utils::Hook(0x497DB5, GetMapIndex, HOOK_CALL).install()->quick(); + Utils::Hook(0x42A19D, MapNameCopy, HOOK_CALL).install()->quick(); + Utils::Hook(0x4A6FEE, SetMapName, HOOK_CALL).install()->quick(); // Store playlist buffer on load - Utils::Hook(0x42961C, Playlist::StorePlaylistStub, HOOK_CALL).install()->quick(); + Utils::Hook(0x42961C, Com_ParseOnLine_Hk, HOOK_CALL).install()->quick(); // Playlist_ParsePlaylists //if (Dedicated::IsDedicated()) { // Custom playlist loading - Utils::Hook(0x420B5A, Playlist::LoadPlaylist, HOOK_JUMP).install()->quick(); + Utils::Hook(0x420B5A, LoadPlaylist, HOOK_JUMP).install()->quick(); - // disable playlist.ff loading function - Utils::Hook::Set(0x4D6E60, 0xC3); + // disable playlist.ff loading function (Win_LoadPlaylistFastfile) + Utils::Hook::Set(0x4D6E60, 0xC3); } Network::OnClientPacket("getPlaylist", PlaylistRequest); - Network::OnClientPacket("playlistResponse", PlaylistReponse); + Network::OnClientPacket("playlistResponse", PlaylistResponse); Network::OnClientPacket("playlistInvalidPassword", PlaylistInvalidPassword); } } diff --git a/src/Components/Modules/Playlist.hpp b/src/Components/Modules/Playlist.hpp index f4948d0e..397fd807 100644 --- a/src/Components/Modules/Playlist.hpp +++ b/src/Components/Modules/Playlist.hpp @@ -17,14 +17,14 @@ namespace Components static std::string CurrentPlaylistBuffer; static std::unordered_map MapRelocation; - static DWORD StorePlaylistStub(const char** buffer); + static char* Com_ParseOnLine_Hk(const char** data_p); static void PlaylistRequest(const Network::Address& address, const std::string& data); - static void PlaylistReponse(const Network::Address& address, const std::string& data); + static void PlaylistResponse(const Network::Address& address, const std::string& data); static void PlaylistInvalidPassword(const Network::Address& address, const std::string& data); - static void MapNameCopy(char *dest, const char *src, int destsize); - static void SetMapName(const char* cvar, const char* value); + static void MapNameCopy(char* dest, const char* src, int destsize); + static void SetMapName(const char* dvarName, const char* value); static int GetMapIndex(const char* mapname); }; } diff --git a/src/Components/Modules/ServerInfo.cpp b/src/Components/Modules/ServerInfo.cpp index e161ab5c..59593d18 100644 --- a/src/Components/Modules/ServerInfo.cpp +++ b/src/Components/Modules/ServerInfo.cpp @@ -131,7 +131,7 @@ namespace Components Utils::InfoString ServerInfo::GetInfo() { auto maxClientCount = *Game::svs_clientCount; - const auto password = Dvar::Var("g_password").get(); + const auto* password = (*Game::g_password)->current.string; if (!maxClientCount) { @@ -145,7 +145,7 @@ namespace Components info.set("shortversion", SHORTVERSION); info.set("version", (*Game::version)->current.string); info.set("mapname", (*Game::sv_mapname)->current.string); - info.set("isPrivate", password.empty() ? "0" : "1"); + info.set("isPrivate", *password ? "1" : "0"); info.set("checksum", Utils::String::VA("%X", Utils::Cryptography::JenkinsOneAtATime::Compute(Utils::String::VA("%u", Game::Sys_Milliseconds())))); info.set("aimAssist", (Gamepad::sv_allowAimAssist.get() ? "1" : "0")); info.set("voiceChat", (Voice::SV_VoiceEnabled() ? "1" : "0")); diff --git a/src/Components/Modules/Singleton.cpp b/src/Components/Modules/Singleton.cpp index d0b0cefd..aa362c5d 100644 --- a/src/Components/Modules/Singleton.cpp +++ b/src/Components/Modules/Singleton.cpp @@ -17,7 +17,7 @@ namespace Components { printf("%s", "IW4x " VERSION " (built " __DATE__ " " __TIME__ ")\n"); printf("%d\n", REVISION); - ExitProcess(0); + std::exit(0); } Console::FreeNativeConsole(); @@ -28,7 +28,7 @@ namespace Components if (!FirstInstance && !ConnectProtocol::Used() && MessageBoxA(nullptr, "Do you want to start another instance?\nNot all features will be available!", "Game already running", MB_ICONEXCLAMATION | MB_YESNO) == IDNO) { - ExitProcess(0); + std::exit(0); } } } diff --git a/src/DllMain.cpp b/src/DllMain.cpp index 16c2f485..eadda265 100644 --- a/src/DllMain.cpp +++ b/src/DllMain.cpp @@ -49,7 +49,6 @@ BOOL APIENTRY DllMain(HINSTANCE /*hinstDLL*/, DWORD fdwReason, LPVOID /*lpvReser if (fdwReason == DLL_PROCESS_ATTACH) { SetProcessDEPPolicy(PROCESS_DEP_ENABLE); - Steam::Proxy::RunMod(); std::srand(std::uint32_t(std::time(nullptr)) ^ ~(GetTickCount() * GetCurrentProcessId())); @@ -72,6 +71,7 @@ BOOL APIENTRY DllMain(HINSTANCE /*hinstDLL*/, DWORD fdwReason, LPVOID /*lpvReser } #endif + Steam::Proxy::RunMod(); // Install entry point hook Utils::Hook(0x6BAC0F, Main::EntryPoint, HOOK_JUMP).install()->quick(); } diff --git a/src/Game/Common.cpp b/src/Game/Common.cpp index b9b626c2..123fb859 100644 --- a/src/Game/Common.cpp +++ b/src/Game/Common.cpp @@ -31,6 +31,8 @@ namespace Game int* com_errorPrintsCount = reinterpret_cast(0x1AD7910); + int* errorcode = reinterpret_cast(0x1AD7EB4); + char* Com_GetParseThreadInfo() { if (Sys_IsMainThread()) diff --git a/src/Game/Common.hpp b/src/Game/Common.hpp index 012e5f07..8698d685 100644 --- a/src/Game/Common.hpp +++ b/src/Game/Common.hpp @@ -35,7 +35,7 @@ namespace Game typedef void(*Com_BeginParseSession_t)(const char* filename); extern Com_BeginParseSession_t Com_BeginParseSession; - typedef char* (*Com_ParseOnLine_t)(const char** data_p); + typedef char*(*Com_ParseOnLine_t)(const char** data_p); extern Com_ParseOnLine_t Com_ParseOnLine; typedef void(*Com_SkipRestOfLine_t)(const char** data); @@ -71,6 +71,8 @@ namespace Game extern int* com_errorPrintsCount; + extern int* errorcode; + extern char* Com_GetParseThreadInfo(); extern void Com_SetParseNegativeNumbers(int parse); diff --git a/src/Game/Dvars.cpp b/src/Game/Dvars.cpp index 8f63be0f..038308e0 100644 --- a/src/Game/Dvars.cpp +++ b/src/Game/Dvars.cpp @@ -52,6 +52,7 @@ namespace Game const dvar_t** g_allowVote = reinterpret_cast(0x19BD644); const dvar_t** g_oldVoting = reinterpret_cast(0x1A45DEC); const dvar_t** g_gametype = reinterpret_cast(0x1A45DC8); + const dvar_t** g_password = reinterpret_cast(0x18835C0); const dvar_t** version = reinterpret_cast(0x1AD7930); diff --git a/src/Game/Dvars.hpp b/src/Game/Dvars.hpp index e8532b86..b3397ebd 100644 --- a/src/Game/Dvars.hpp +++ b/src/Game/Dvars.hpp @@ -108,6 +108,7 @@ namespace Game extern const dvar_t** g_allowVote; extern const dvar_t** g_oldVoting; extern const dvar_t** g_gametype; + extern const dvar_t** g_password; extern const dvar_t** version; diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 75b6cdd7..a87789a6 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -268,6 +268,8 @@ namespace Game LargeLocalBeginRight_t LargeLocalBeginRight = LargeLocalBeginRight_t(0x644140); LargeLocalReset_t LargeLocalReset = LargeLocalReset_t(0x430630); + longjmp_internal_t longjmp_internal = longjmp_internal_t(0x6B8898); + CmdArgs* cmd_args = reinterpret_cast(0x1AAC5D0); CmdArgs* sv_cmd_args = reinterpret_cast(0x1ACF8A0); @@ -405,6 +407,8 @@ namespace Game punctuation_s* default_punctuations = reinterpret_cast(0x797F80); + bool* s_havePlaylists = reinterpret_cast(0x1AD3680); + const char* TableLookup(StringTable* stringtable, int row, int column) { if (!stringtable || !stringtable->values || row >= stringtable->rowCount || column >= stringtable->columnCount) return ""; diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index ae9d6323..6f84f841 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -593,6 +593,9 @@ namespace Game typedef void(*LargeLocalReset_t)(); extern LargeLocalReset_t LargeLocalReset; + typedef void(*longjmp_internal_t)(jmp_buf env, int status); + extern longjmp_internal_t longjmp_internal; + constexpr std::size_t STATIC_MAX_LOCAL_CLIENTS = 1; constexpr std::size_t MAX_LOCAL_CLIENTS = 1; constexpr std::size_t MAX_CLIENTS = 18; @@ -739,6 +742,8 @@ namespace Game extern punctuation_s* default_punctuations; + extern bool* s_havePlaylists; + constexpr auto MAX_MSGLEN = 0x20000; ScreenPlacement* ScrPlace_GetFullPlacement();