diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp index 131a6182..ea906ecd 100644 --- a/src/Components/Loader.cpp +++ b/src/Components/Loader.cpp @@ -64,6 +64,7 @@ namespace Components Loader::Register(new Monitor()); Loader::Register(new Network()); Loader::Register(new Theatre()); + Loader::Register(new Clantags()); Loader::Register(new Download()); Loader::Register(new Playlist()); Loader::Register(new RawFiles()); @@ -81,6 +82,7 @@ namespace Components Loader::Register(new Gametypes()); Loader::Register(new Materials()); Loader::Register(new Threading()); + Loader::Register(new CardTitles()); Loader::Register(new FileSystem()); Loader::Register(new ModelSurfs()); Loader::Register(new PlayerName()); @@ -94,6 +96,7 @@ namespace Components Loader::Register(new AssetHandler()); Loader::Register(new Localization()); Loader::Register(new MusicalTalent()); + Loader::Register(new ServerCommands()); Loader::Register(new StructuredData()); Loader::Register(new ConnectProtocol()); Loader::Register(new StartupMessages()); @@ -111,7 +114,7 @@ namespace Components #ifdef DEBUG if(!Loader::PerformingUnitTests()) { - Logger::Print("Unregistering component: %s\n", component->getName()); + Logger::Print("Unregistering component: %s\n", component->getName().data()); } #endif delete component; @@ -164,7 +167,7 @@ namespace Components for (auto component : Loader::Components) { #if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - Logger::Print("Testing '%s'...\n", component->getName()); + Logger::Print("Testing '%s'...\n", component->getName().data()); #endif auto startTime = std::chrono::high_resolution_clock::now(); bool testRes = component->unitTest(); @@ -192,7 +195,7 @@ namespace Components #ifdef DEBUG if(!Loader::PerformingUnitTests()) { - Logger::Print("Component registered: %s\n", component->getName()); + Logger::Print("Component registered: %s\n", component->getName().data()); } #endif Loader::Components.push_back(component); diff --git a/src/Components/Loader.hpp b/src/Components/Loader.hpp index d41085d2..afb79c17 100644 --- a/src/Components/Loader.hpp +++ b/src/Components/Loader.hpp @@ -9,7 +9,12 @@ namespace Components virtual ~Component() {}; #if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - virtual const char* getName() { return "Unknown"; }; + virtual std::string getName() + { + std::string name = typeid(*this).name(); + Utils::String::Replace(name, "class Components::", ""); + return name; + }; #endif // It's illegal to spawn threads in DLLMain, and apparently it causes problems if they are destroyed there as well. @@ -34,6 +39,20 @@ namespace Components static bool IsPostgame(); static bool IsComInitialized(); + template + static T* GetInstance() + { + for (auto& component : Loader::Components) + { + if (typeid(*component) == typeid(T)) + { + return reinterpret_cast(component); + } + } + + return nullptr; + } + static Utils::Memory::Allocator* GetAlloctor(); private: @@ -75,6 +94,7 @@ namespace Components #include "Modules/Logger.hpp" #include "Modules/Friends.hpp" #include "Modules/IPCPipe.hpp" +#include "Modules/Clantags.hpp" #include "Modules/Download.hpp" #include "Modules/Playlist.hpp" #include "Modules/RawFiles.hpp" @@ -91,6 +111,7 @@ namespace Components #include "Modules/Materials.hpp" #include "Modules/Singleton.hpp" #include "Modules/Threading.hpp" +#include "Modules/CardTitles.hpp" #include "Modules/FileSystem.hpp" #include "Modules/ModelSurfs.hpp" #include "Modules/PlayerName.hpp" @@ -103,6 +124,7 @@ namespace Components #include "Modules/AssetHandler.hpp" #include "Modules/Localization.hpp" #include "Modules/MusicalTalent.hpp" +#include "Modules/ServerCommands.hpp" #include "Modules/StructuredData.hpp" #include "Modules/ConnectProtocol.hpp" #include "Modules/StartupMessages.hpp" diff --git a/src/Components/Modules/AntiCheat.hpp b/src/Components/Modules/AntiCheat.hpp index 39a15d8f..82149cc2 100644 --- a/src/Components/Modules/AntiCheat.hpp +++ b/src/Components/Modules/AntiCheat.hpp @@ -16,10 +16,6 @@ namespace Components AntiCheat(); ~AntiCheat(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "AntiCheat"; }; -#endif - static void CrashClient(); static void InitLoadLibHook(); diff --git a/src/Components/Modules/ArenaLength.hpp b/src/Components/Modules/ArenaLength.hpp index da9918e7..f495b5c7 100644 --- a/src/Components/Modules/ArenaLength.hpp +++ b/src/Components/Modules/ArenaLength.hpp @@ -7,10 +7,6 @@ namespace Components public: ArenaLength(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "ArenaLength"; }; -#endif - static Game::newMapArena_t NewArenas[128]; private: diff --git a/src/Components/Modules/AssetHandler.hpp b/src/Components/Modules/AssetHandler.hpp index 9b83bc34..c1f72315 100644 --- a/src/Components/Modules/AssetHandler.hpp +++ b/src/Components/Modules/AssetHandler.hpp @@ -22,10 +22,6 @@ namespace Components AssetHandler(); ~AssetHandler(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "AssetHandler"; }; -#endif - static void OnFind(Game::XAssetType type, Utils::Slot callback); static void OnLoad(Utils::Slot callback); diff --git a/src/Components/Modules/Auth.hpp b/src/Components/Modules/Auth.hpp index a6d266a4..56ab27de 100644 --- a/src/Components/Modules/Auth.hpp +++ b/src/Components/Modules/Auth.hpp @@ -8,10 +8,6 @@ namespace Components Auth(); ~Auth(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Auth"; }; -#endif - void preDestroy() override; bool unitTest() override; diff --git a/src/Components/Modules/Bans.hpp b/src/Components/Modules/Bans.hpp index a02f05fe..6482b896 100644 --- a/src/Components/Modules/Bans.hpp +++ b/src/Components/Modules/Bans.hpp @@ -10,10 +10,6 @@ namespace Components Bans(); ~Bans(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Bans"; }; -#endif - static void BanClientNum(int num, std::string reason); static bool IsBanned(Entry entry); diff --git a/src/Components/Modules/Bots.hpp b/src/Components/Modules/Bots.hpp index bdda8441..d79f51e2 100644 --- a/src/Components/Modules/Bots.hpp +++ b/src/Components/Modules/Bots.hpp @@ -8,10 +8,6 @@ namespace Components Bots(); ~Bots(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Bots"; }; -#endif - private: static std::vector BotNames; diff --git a/src/Components/Modules/CardTitles.cpp b/src/Components/Modules/CardTitles.cpp new file mode 100644 index 00000000..d00bcd7a --- /dev/null +++ b/src/Components/Modules/CardTitles.cpp @@ -0,0 +1,230 @@ +#include "STDInclude.hpp" + +namespace Components +{ + std::string CardTitles::CustomTitles[18]; + Dvar::Var CardTitles::CustomTitleDvar; + + CClient* CardTitles::GetClientByIndex(std::uint32_t index) + { + return &reinterpret_cast(0x8E77B0)[index]; + } + + std::int32_t CardTitles::GetPlayerCardClientInfo(std::int32_t lookupResult, playercarddata_s* data) + { + std::int32_t returnResult = lookupResult; + + std::string username = Dvar::Var("name").get(); + + if (data->name == username) + { + returnResult += 0xFE000000; + } + else + { + for (auto clientNum = 0; clientNum < 18; clientNum++) + { + CClient* c = GetClientByIndex(clientNum); + if (c != nullptr) + { + if (!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; + break; + } + } + } + } + + return returnResult; + } + + void __declspec(naked) CardTitles::GetPlayerCardClientInfoStub() + { + __asm + { + push eax + pushad + + push esi + push eax + call GetPlayerCardClientInfo + add esp, 8 + + mov [esp + 20h], eax + popad + pop eax + + pop esi + pop ebp + mov[ebx + 4], eax + pop ebx + + push 62EB2Ch + retn + } + } + + const char* CardTitles::TableLookupByRowHook(Game::Operand* operand, tablelookuprequest_s* request) + { + std::uint8_t prefix = (request->tableRow >> (8 * 3)) & 0xFF; + std::uint8_t data = (request->tableRow >> (8 * 2)) & 0xFF; + + if (request->tablename == "mp/cardTitleTable.csv"s) + { + if (prefix != 0x00) + { + // Column 1 = CardTitle + if (request->tableColumn == 1) + { + if (prefix == 0xFE) + { + if (!CustomTitleDvar.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", CustomTitleDvar.get()); + + // prepare return value + operand->internals.stringVal.string = title; + operand->dataType = Game::VAL_STRING; + + return title; + } + } + else if (prefix == 0xFF) + { + if (!CustomTitles[data].empty()) + { + const char* title = Utils::String::VA("\x15%s", CustomTitles[data].data()); + + // prepare return value + operand->internals.stringVal.string = title; + operand->dataType = Game::VAL_STRING; + + return title; + } + } + } + + // If the title was changed it already returned at this point so... + // Remove prefix and data to make being readable to the normal lookuprequest + request->tableRow = static_cast(*(reinterpret_cast(&request->tableRow))); + } + } + + return nullptr; + } + + __declspec(naked) void CardTitles::TableLookupByRowHookStub() + { + __asm + { + push eax + pushad + + push esi + push ebx + + call TableLookupByRowHook + add esp, 8 + + mov [esp + 20h], eax + popad + pop eax + + cmp eax, 0 + jz OriginalTitle + + pop ecx + mov ecx, DWORD ptr[esi + 4] + retn + + OriginalTitle: + + mov eax, [esi + 50h] + cmp eax, 3 + + push 62DCC7h + retn + } + } + + void CardTitles::SendCustomTitlesToClients() + { + std::string list; + + for (int i = 0; i < 18; i++) + { + char playerTitle[18]; + + if (Game::svs_clients[i].state >= 3) + { + strncpy_s(playerTitle, Game::Info_ValueForKey(Game::svs_clients[i].connectInfoString, "customTitle"), 17); + } + else + { + memset(playerTitle, 0, 18); + } + + list.append(Utils::String::VA("\\%s\\%s", std::to_string(i).c_str(), playerTitle)); + } + + std::string command = Utils::String::VA("%c customTitles \"%s\"", 21, list.data()); + Game::SV_GameSendServerCommand(-1, 0, command.data()); + } + + void CardTitles::ParseCustomTitles(const char* msg) + { + for (int i = 0; i < 18; ++i) + { + const char* playerTitle = Game::Info_ValueForKey(msg, std::to_string(i).c_str()); + + if (playerTitle) CardTitles::CustomTitles[i] = playerTitle; + else CardTitles::CustomTitles[i].clear(); + } + } + + CardTitles::CardTitles() + { + Dvar::OnInit([]() + { + CardTitles::CustomTitleDvar = Dvar::Register("customtitle", "", Game::dvar_flag::DVAR_FLAG_USERINFO | Game::dvar_flag::DVAR_FLAG_SAVED, "Custom card title"); + }); + + ServerCommands::OnCommand(21, [](Command::Params* params) + { + if (params->get(1) == "customTitles"s && !Dedicated::IsEnabled()) + { + if (params->length() == 3) + { + CardTitles::ParseCustomTitles(params->get(2)); + return true; + } + } + + return false; + + }); + + for(int i = 0; i < ARRAYSIZE(CardTitles::CustomTitles); ++i) + { + CardTitles::CustomTitles[i].clear(); + } + + Utils::Hook(0x62EB26, CardTitles::GetPlayerCardClientInfoStub).install()->quick(); + + // Table lookup stuff + Utils::Hook(0x62DCC1, CardTitles::TableLookupByRowHookStub).install()->quick(); + Utils::Hook::Nop(0x62DCC6, 1); + } + + CardTitles::~CardTitles() + { + for (int i = 0; i < ARRAYSIZE(CardTitles::CustomTitles); ++i) + { + CardTitles::CustomTitles[i].clear(); + } + } +} diff --git a/src/Components/Modules/CardTitles.hpp b/src/Components/Modules/CardTitles.hpp new file mode 100644 index 00000000..7f838ef8 --- /dev/null +++ b/src/Components/Modules/CardTitles.hpp @@ -0,0 +1,74 @@ +#pragma once + +namespace Components +{ + struct tablelookuprequest_s + { + std::uint8_t padding[4]; + char* tablename; + std::uint8_t padding2[4]; + std::int32_t tableRow; + std::uint8_t padding3[4]; + std::int32_t tableColumn; + }; + struct playercarddata_s + { + std::uint32_t padding; + std::uint32_t playercardNumber; + std::uint32_t unknown; + std::uint32_t unknown2; + std::uint32_t level; //Level is counted from 0 -> Value 69 is Level 70 + std::uint32_t prestige; + std::uint32_t padding2; + char name[40]; + }; + + 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::uint8_t _0x0038[968]; + std::uint32_t ViewAngles; // 0x0400 + std::uint8_t _0x040C[136]; + std::uint32_t IsShooting; // 0x0494 + std::uint8_t _0x0498[4]; + std::uint32_t IsZoomed; // 0x049C + std::uint8_t _0x04A0[68]; + std::uint32_t weaponID; // 0x04E4 + std::uint8_t _0x04E8[24]; + std::uint32_t weaponID2; // 0x0500 + std::uint8_t _0x0504[40]; + std::uint8_t _padding[8]; + }; + + class CardTitles : public Component + { + public: + static Dvar::Var CustomTitleDvar; + static std::string CustomTitles[18]; + + static void SendCustomTitlesToClients(); + static void ParseCustomTitles(const char * msg); + + CardTitles(); + ~CardTitles(); + + private: + static CClient * GetClientByIndex(std::uint32_t index); + static std::int32_t GetPlayerCardClientInfo(std::int32_t lookupResult, playercarddata_s * data); + static void GetPlayerCardClientInfoStub(); + static const char* TableLookupByRowHook(Game::Operand * operand, tablelookuprequest_s * request); + static void TableLookupByRowHookStub(); + + + }; +} diff --git a/src/Components/Modules/Changelog.hpp b/src/Components/Modules/Changelog.hpp index 5d42abab..dd74a8be 100644 --- a/src/Components/Modules/Changelog.hpp +++ b/src/Components/Modules/Changelog.hpp @@ -8,10 +8,6 @@ namespace Components Changelog(); ~Changelog(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Changelog"; }; -#endif - static void LoadChangelog(); private: diff --git a/src/Components/Modules/Clantags.cpp b/src/Components/Modules/Clantags.cpp new file mode 100644 index 00000000..84c009bb --- /dev/null +++ b/src/Components/Modules/Clantags.cpp @@ -0,0 +1,107 @@ +#include "STDInclude.hpp" + +namespace Components +{ + std::string Clantags::Tags[18]; + + void Clantags::ParseClantags(const char* infoString) + { + for (int i = 0; i < 18; i++) + { + const char* clantag = Game::Info_ValueForKey(infoString, std::to_string(i).data()); + + if (clantag) Clantags::Tags[i] = clantag; + else Clantags::Tags[i].clear(); + } + } + + void Clantags::SendClantagsToClients() + { + std::string list; + + for (int i = 0; i < 18; ++i) + { + char clantag[5] = { 0 }; + + if (Game::svs_clients[i].state >= 3) + { + strncpy_s(clantag, Game::Info_ValueForKey(Game::svs_clients[i].connectInfoString, "iw4x_clantag"), 4); + } + + list.append(Utils::String::VA("\\%s\\%s", std::to_string(i).data(), clantag)); + } + + std::string command = Utils::String::VA("%c clantags \"%s\"", 22, list.data()); + Game::SV_GameSendServerCommand(-1, 0, command.data()); + } + + const char* Clantags::GetUserClantag(std::uint32_t clientnum, const char* playername) + { + if (Clantags::Tags[clientnum].empty()) return playername; + return Utils::String::VA("[%s] %s", Clantags::Tags[clientnum].data(), playername); + } + + __declspec(naked) void Clantags::DrawPlayerNameOnScoreboard() + { + __asm + { + push eax + pushad + + push edi + push [ebp] + + call Clantags::GetUserClantag + add esp, 8 + + mov [esp + 20h], eax + + popad + pop edi + + push 591247h // Return address + push 5909E0h // Draw string func + retn + } + } + + Clantags::Clantags() + { + // Create clantag dvar + Dvar::OnInit([]() + { + Dvar::Register("iw4x_clantag", "", Game::dvar_flag::DVAR_FLAG_USERINFO | Game::dvar_flag::DVAR_FLAG_SAVED, "If set, your clantag will be shown on the scoreboard."); + }); + + // Servercommand hook + ServerCommands::OnCommand(22, [](Command::Params* params) + { + if (params->get(1) == "clantags"s && !Dedicated::IsEnabled()) + { + if (params->length() == 3) + { + Clantags::ParseClantags(params->get(2)); + return true; + } + } + + return false; + }); + + for (int i = 0; i < ARRAYSIZE(Clantags::Tags); ++i) + { + Clantags::Tags[i].clear(); + } + + // Draw clantag before playername + Utils::Hook(0x591242, Clantags::DrawPlayerNameOnScoreboard).install()->quick(); + } + + Clantags::~Clantags() + { + for (int i = 0; i < ARRAYSIZE(Clantags::Tags); ++i) + { + Clantags::Tags[i].clear(); + } + } +} diff --git a/src/Components/Modules/Clantags.hpp b/src/Components/Modules/Clantags.hpp new file mode 100644 index 00000000..f2a05d72 --- /dev/null +++ b/src/Components/Modules/Clantags.hpp @@ -0,0 +1,21 @@ +#pragma once + +namespace Components +{ + class Clantags : public Component + { + public: + static void ParseClantags(const char * infoString); + static void SendClantagsToClients(); + + Clantags(); + ~Clantags(); + + private: + static std::string Clantags::Tags[18]; + + static const char* GetUserClantag(std::uint32_t clientnum, const char * playername); + static void DrawPlayerNameOnScoreboard(); + + }; +} diff --git a/src/Components/Modules/Colors.hpp b/src/Components/Modules/Colors.hpp index 8bc95333..6d8d4f62 100644 --- a/src/Components/Modules/Colors.hpp +++ b/src/Components/Modules/Colors.hpp @@ -8,10 +8,6 @@ namespace Components Colors(); ~Colors(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Colors"; }; -#endif - static void Strip(const char* in, char* out, int max); static std::string Strip(std::string in); diff --git a/src/Components/Modules/Command.hpp b/src/Components/Modules/Command.hpp index e1cccecd..cd605082 100644 --- a/src/Components/Modules/Command.hpp +++ b/src/Components/Modules/Command.hpp @@ -50,10 +50,6 @@ namespace Components Command(); ~Command(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Command"; }; -#endif - static Game::cmd_function_t* Allocate(); static void Add(const char* name, Utils::Slot callback); diff --git a/src/Components/Modules/ConnectProtocol.hpp b/src/Components/Modules/ConnectProtocol.hpp index 454d1b34..d801df82 100644 --- a/src/Components/Modules/ConnectProtocol.hpp +++ b/src/Components/Modules/ConnectProtocol.hpp @@ -7,10 +7,6 @@ namespace Components public: ConnectProtocol(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "ConnectProtocol"; }; -#endif - static bool IsEvaluated(); static bool Used(); diff --git a/src/Components/Modules/Console.hpp b/src/Components/Modules/Console.hpp index 1b06c22a..0ef30bb5 100644 --- a/src/Components/Modules/Console.hpp +++ b/src/Components/Modules/Console.hpp @@ -11,10 +11,6 @@ namespace Components Console(); ~Console(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Console"; }; -#endif - static void SetSkipShutdown(); static void FreeNativeConsole(); diff --git a/src/Components/Modules/D3D9Ex.hpp b/src/Components/Modules/D3D9Ex.hpp index 0f7364e3..f3a232f6 100644 --- a/src/Components/Modules/D3D9Ex.hpp +++ b/src/Components/Modules/D3D9Ex.hpp @@ -7,10 +7,6 @@ namespace Components public: D3D9Ex(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "D3D9Ex"; }; -#endif - private: class D3D9Device : public IDirect3DDevice9 diff --git a/src/Components/Modules/Dedicated.cpp b/src/Components/Modules/Dedicated.cpp index ea99e51f..ba017b3f 100644 --- a/src/Components/Modules/Dedicated.cpp +++ b/src/Components/Modules/Dedicated.cpp @@ -185,56 +185,6 @@ namespace Components Game::Com_Error(code, message); } - __declspec(naked) void Dedicated::OnServerCommandStub() - { - __asm - { - push eax - pushad - - call Dedicated::OnServerCommand - - mov [esp + 20h], eax - popad - pop eax - - test al, al - jnz returnSafe - - push 5944AEh - retn - - returnSafe: - push 594536h - retn - } - } - - int Dedicated::OnServerCommand() - { - Command::ClientParams params; - - ZeroMemory(Dedicated::PlayerGuids, sizeof(Dedicated::PlayerGuids)); - - if (params.length() >= (18 * 2 + 1) && params.get(0)[0] == 20) - { - for (int client = 0; client < 18; client++) - { - Dedicated::PlayerGuids[client][0].bits = strtoull(params.get(2 * client + 1), nullptr, 16); - Dedicated::PlayerGuids[client][1].bits = strtoull(params.get(2 * client + 2), nullptr, 16); - - if(Steam::Proxy::SteamFriends && Dedicated::PlayerGuids[client][1].bits != 0) - { - Steam::Proxy::SteamFriends->SetPlayedWith(Dedicated::PlayerGuids[client][1]); - } - } - - return 1; - } - - return 0; - } - void Dedicated::MapRotate() { if (!Dedicated::IsEnabled() && Dvar::Var("sv_dontrotate").get()) @@ -452,6 +402,20 @@ namespace Components // Post initialization point Utils::Hook(0x60BFBF, Dedicated::PostInitializationStub, HOOK_JUMP).install()->quick(); + // Transmit custom data + Dedicated::OnFrame([]() + { + static std::uint64_t LastUpdate = 0; + + if ((GetTickCount64() - LastUpdate) > 10000) + { + CardTitles::SendCustomTitlesToClients(); + Clantags::SendClantagsToClients(); + + LastUpdate = GetTickCount64(); + } + }); + #ifdef USE_LEGACY_SERVER_LIST // Heartbeats @@ -565,7 +529,21 @@ namespace Components } // Intercept server commands - Utils::Hook(0x59449F, Dedicated::OnServerCommandStub, HOOK_JUMP).install()->quick(); + ServerCommands::OnCommand(20, [](Command::Params* params) + { + for (int client = 0; client < 18; client++) + { + Dedicated::PlayerGuids[client][0].bits = strtoull(params->get(2 * client + 1), nullptr, 16); + Dedicated::PlayerGuids[client][1].bits = strtoull(params->get(2 * client + 2), nullptr, 16); + + if (Steam::Proxy::SteamFriends && Dedicated::PlayerGuids[client][1].bits != 0) + { + Steam::Proxy::SteamFriends->SetPlayedWith(Dedicated::PlayerGuids[client][1]); + } + } + + return true; + }); } QuickPatch::OnFrame([]() diff --git a/src/Components/Modules/Dedicated.hpp b/src/Components/Modules/Dedicated.hpp index 9deeaed1..0a3cd54d 100644 --- a/src/Components/Modules/Dedicated.hpp +++ b/src/Components/Modules/Dedicated.hpp @@ -10,10 +10,6 @@ namespace Components Dedicated(); ~Dedicated(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Dedicated"; }; -#endif - static SteamID PlayerGuids[18][2]; static bool IsEnabled(); @@ -29,9 +25,6 @@ namespace Components static bool SendChat; - static void OnServerCommandStub(); - static int OnServerCommand(); - static void MapRotate(); static void FrameHandler(); static void FrameStub(); diff --git a/src/Components/Modules/Discovery.hpp b/src/Components/Modules/Discovery.hpp index a9dc4344..655122bf 100644 --- a/src/Components/Modules/Discovery.hpp +++ b/src/Components/Modules/Discovery.hpp @@ -8,10 +8,6 @@ namespace Components Discovery(); ~Discovery(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Discovery"; }; -#endif - void preDestroy() override; static void Perform(); diff --git a/src/Components/Modules/Download.hpp b/src/Components/Modules/Download.hpp index 8d807ef9..299da811 100644 --- a/src/Components/Modules/Download.hpp +++ b/src/Components/Modules/Download.hpp @@ -9,10 +9,6 @@ namespace Components Download(); ~Download(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Download"; }; -#endif - void preDestroy() override; static void InitiateClientDownload(std::string mod, bool map = false); diff --git a/src/Components/Modules/Dvar.hpp b/src/Components/Modules/Dvar.hpp index b12ed8c7..cbbb87ee 100644 --- a/src/Components/Modules/Dvar.hpp +++ b/src/Components/Modules/Dvar.hpp @@ -44,10 +44,6 @@ namespace Components Dvar(); ~Dvar(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Dvar"; }; -#endif - static void OnInit(Utils::Slot callback); // Only strings and bools use this type of declaration diff --git a/src/Components/Modules/Exception.hpp b/src/Components/Modules/Exception.hpp index eeaa57c7..2038842a 100644 --- a/src/Components/Modules/Exception.hpp +++ b/src/Components/Modules/Exception.hpp @@ -8,9 +8,6 @@ namespace Components Exception(); ~Exception(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Exception"; }; -#endif static LPTOP_LEVEL_EXCEPTION_FILTER Hook(); static void SetMiniDumpType(bool codeseg, bool dataseg); diff --git a/src/Components/Modules/FastFiles.hpp b/src/Components/Modules/FastFiles.hpp index 76175219..eb5569a1 100644 --- a/src/Components/Modules/FastFiles.hpp +++ b/src/Components/Modules/FastFiles.hpp @@ -8,10 +8,6 @@ namespace Components FastFiles(); ~FastFiles(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "FastFiles"; }; -#endif - static void AddZonePath(std::string path); static std::string Current(); static bool Ready(); diff --git a/src/Components/Modules/FileSystem.hpp b/src/Components/Modules/FileSystem.hpp index 09afa221..800701b9 100644 --- a/src/Components/Modules/FileSystem.hpp +++ b/src/Components/Modules/FileSystem.hpp @@ -88,10 +88,6 @@ namespace Components FileSystem(); ~FileSystem(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "FileSystem"; }; -#endif - static std::vector GetFileList(std::string path, std::string extension); static std::vector GetSysFileList(std::string path, std::string extension, bool folders = false); static void DeleteFile(std::string folder, std::string file); diff --git a/src/Components/Modules/Flags.hpp b/src/Components/Modules/Flags.hpp index e5cb7f67..2148622d 100644 --- a/src/Components/Modules/Flags.hpp +++ b/src/Components/Modules/Flags.hpp @@ -8,10 +8,6 @@ namespace Components Flags(); ~Flags(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Flags"; }; -#endif - static bool HasFlag(std::string flag); private: diff --git a/src/Components/Modules/FrameTime.hpp b/src/Components/Modules/FrameTime.hpp index 4da5bf94..4b10d129 100644 --- a/src/Components/Modules/FrameTime.hpp +++ b/src/Components/Modules/FrameTime.hpp @@ -7,10 +7,6 @@ namespace Components public: FrameTime(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "FrameTime"; }; -#endif - private: static void SVFrameWaitStub(); static void SVFrameWaitFunc(); diff --git a/src/Components/Modules/Friends.hpp b/src/Components/Modules/Friends.hpp index 21ab888f..5c4dfb4b 100644 --- a/src/Components/Modules/Friends.hpp +++ b/src/Components/Modules/Friends.hpp @@ -8,10 +8,6 @@ namespace Components Friends(); ~Friends(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Friends"; }; -#endif - static void UpdateFriends(); static void UpdateRank(); static void UpdateServer(Network::Address server, std::string hostname, std::string mapname); diff --git a/src/Components/Modules/Gametypes.hpp b/src/Components/Modules/Gametypes.hpp index 7914a3bf..5576512e 100644 --- a/src/Components/Modules/Gametypes.hpp +++ b/src/Components/Modules/Gametypes.hpp @@ -7,10 +7,6 @@ namespace Components public: Gametypes(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Gametypes"; }; -#endif - private: static unsigned int GetGametypeCount(); static const char* GetGametypeText(unsigned int index, int column); diff --git a/src/Components/Modules/IPCPipe.hpp b/src/Components/Modules/IPCPipe.hpp index 58bbc713..2e51e16c 100644 --- a/src/Components/Modules/IPCPipe.hpp +++ b/src/Components/Modules/IPCPipe.hpp @@ -65,10 +65,6 @@ namespace Components public: IPCPipe(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "IPCPipe"; }; -#endif - void preDestroy() override; static bool Write(std::string command, std::string data); diff --git a/src/Components/Modules/Lean.hpp b/src/Components/Modules/Lean.hpp index 7fce86d2..4ae28d51 100644 --- a/src/Components/Modules/Lean.hpp +++ b/src/Components/Modules/Lean.hpp @@ -10,10 +10,6 @@ namespace Components public: Lean(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Lean"; }; -#endif - private: static Game::kbutton_t in_leanleft; static Game::kbutton_t in_leanright; diff --git a/src/Components/Modules/Localization.hpp b/src/Components/Modules/Localization.hpp index 8aa31afb..a96af75e 100644 --- a/src/Components/Modules/Localization.hpp +++ b/src/Components/Modules/Localization.hpp @@ -8,10 +8,6 @@ namespace Components Localization(); ~Localization(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Localization"; }; -#endif - static void Set(std::string key, std::string value); static const char* Get(const char* key); diff --git a/src/Components/Modules/Logger.hpp b/src/Components/Modules/Logger.hpp index accafa62..6d683437 100644 --- a/src/Components/Modules/Logger.hpp +++ b/src/Components/Modules/Logger.hpp @@ -8,10 +8,6 @@ namespace Components Logger(); ~Logger(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Logger"; }; -#endif - static void MessagePrint(int channel, std::string message); static void Print(int channel, const char* message, ...); static void Print(const char* message, ...); diff --git a/src/Components/Modules/Maps.hpp b/src/Components/Modules/Maps.hpp index 1becaa63..46211308 100644 --- a/src/Components/Modules/Maps.hpp +++ b/src/Components/Modules/Maps.hpp @@ -49,10 +49,6 @@ namespace Components Maps(); ~Maps(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Maps"; }; -#endif - static void HandleAsSPMap(); static void AddDependency(std::string expression, std::string zone); diff --git a/src/Components/Modules/Materials.hpp b/src/Components/Modules/Materials.hpp index 55d479fa..fe9ccd6a 100644 --- a/src/Components/Modules/Materials.hpp +++ b/src/Components/Modules/Materials.hpp @@ -8,10 +8,6 @@ namespace Components Materials(); ~Materials(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Materials"; }; -#endif - static int FormatImagePath(char* buffer, size_t size, int, int, const char* image); private: diff --git a/src/Components/Modules/Menus.hpp b/src/Components/Modules/Menus.hpp index 4a099a2e..4a96f260 100644 --- a/src/Components/Modules/Menus.hpp +++ b/src/Components/Modules/Menus.hpp @@ -11,10 +11,6 @@ namespace Components Menus(); ~Menus(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Menus"; }; -#endif - static void FreeEverything(); static void Add(std::string menu); diff --git a/src/Components/Modules/ModList.hpp b/src/Components/Modules/ModList.hpp index 5022cfe1..8f2a0e97 100644 --- a/src/Components/Modules/ModList.hpp +++ b/src/Components/Modules/ModList.hpp @@ -8,10 +8,6 @@ namespace Components ModList(); ~ModList(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "ModList"; }; -#endif - static void RunMod(std::string mod); private: diff --git a/src/Components/Modules/ModelSurfs.hpp b/src/Components/Modules/ModelSurfs.hpp index 41093e1b..a2f9f205 100644 --- a/src/Components/Modules/ModelSurfs.hpp +++ b/src/Components/Modules/ModelSurfs.hpp @@ -8,10 +8,6 @@ namespace Components ModelSurfs(); ~ModelSurfs(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "ModelSurfs"; }; -#endif - private: static std::unordered_map BufferMap; static std::unordered_map AllocMap; diff --git a/src/Components/Modules/Monitor.hpp b/src/Components/Modules/Monitor.hpp index d95ca242..e26aa3bf 100644 --- a/src/Components/Modules/Monitor.hpp +++ b/src/Components/Modules/Monitor.hpp @@ -7,10 +7,6 @@ namespace Components public: Monitor(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Monitor"; }; -#endif - static bool IsEnabled(); private: diff --git a/src/Components/Modules/MusicalTalent.hpp b/src/Components/Modules/MusicalTalent.hpp index aee7aac9..b3c07747 100644 --- a/src/Components/Modules/MusicalTalent.hpp +++ b/src/Components/Modules/MusicalTalent.hpp @@ -8,10 +8,6 @@ namespace Components MusicalTalent(); ~MusicalTalent(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "MusicalTalent"; }; -#endif - static void Replace(std::string sound, const char* file); private: diff --git a/src/Components/Modules/Network.hpp b/src/Components/Modules/Network.hpp index 9293db70..a7a40441 100644 --- a/src/Components/Modules/Network.hpp +++ b/src/Components/Modules/Network.hpp @@ -58,10 +58,6 @@ namespace Components Network(); ~Network(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Network"; }; -#endif - static void Handle(std::string packet, Utils::Slot callback); static void OnStart(Utils::Slot callback); diff --git a/src/Components/Modules/News.hpp b/src/Components/Modules/News.hpp index 6aa93cef..4880da1f 100644 --- a/src/Components/Modules/News.hpp +++ b/src/Components/Modules/News.hpp @@ -8,10 +8,6 @@ namespace Components News(); ~News(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "News"; }; -#endif - void preDestroy() override; bool unitTest() override; diff --git a/src/Components/Modules/Node.hpp b/src/Components/Modules/Node.hpp index 01ab5e79..78cf175c 100644 --- a/src/Components/Modules/Node.hpp +++ b/src/Components/Modules/Node.hpp @@ -21,10 +21,6 @@ namespace Components Node(); ~Node(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Node"; }; -#endif - bool unitTest() override; static void SyncNodeList(); diff --git a/src/Components/Modules/Party.hpp b/src/Components/Modules/Party.hpp index 6ea399c0..8994ce0f 100644 --- a/src/Components/Modules/Party.hpp +++ b/src/Components/Modules/Party.hpp @@ -8,10 +8,6 @@ namespace Components Party(); ~Party(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Party"; }; -#endif - static Network::Address Target(); static void Connect(Network::Address target); static const char* GetLobbyInfo(SteamID lobby, std::string key); diff --git a/src/Components/Modules/PlayerName.hpp b/src/Components/Modules/PlayerName.hpp index e7b6efa4..68c3c74d 100644 --- a/src/Components/Modules/PlayerName.hpp +++ b/src/Components/Modules/PlayerName.hpp @@ -8,10 +8,6 @@ namespace Components PlayerName(); ~PlayerName(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "PlayerName"; }; -#endif - private: static std::string PlayerNames[18]; diff --git a/src/Components/Modules/Playlist.hpp b/src/Components/Modules/Playlist.hpp index 4d82fd85..ceeb99a8 100644 --- a/src/Components/Modules/Playlist.hpp +++ b/src/Components/Modules/Playlist.hpp @@ -10,10 +10,6 @@ namespace Components Playlist(); ~Playlist(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Playlist"; }; -#endif - static void LoadPlaylist(); static std::string ReceivedPlaylistBuffer; diff --git a/src/Components/Modules/QuickPatch.hpp b/src/Components/Modules/QuickPatch.hpp index 0f01474a..60c44584 100644 --- a/src/Components/Modules/QuickPatch.hpp +++ b/src/Components/Modules/QuickPatch.hpp @@ -10,10 +10,6 @@ namespace Components QuickPatch(); ~QuickPatch(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "QuickPatch"; }; -#endif - bool unitTest() override; static void UnlockStats(); diff --git a/src/Components/Modules/RCon.hpp b/src/Components/Modules/RCon.hpp index 996f7b65..1cc486e5 100644 --- a/src/Components/Modules/RCon.hpp +++ b/src/Components/Modules/RCon.hpp @@ -8,10 +8,6 @@ namespace Components RCon(); ~RCon(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "RCon"; }; -#endif - private: class Container { diff --git a/src/Components/Modules/RawFiles.hpp b/src/Components/Modules/RawFiles.hpp index a6bfe437..30e4458b 100644 --- a/src/Components/Modules/RawFiles.hpp +++ b/src/Components/Modules/RawFiles.hpp @@ -7,10 +7,6 @@ namespace Components public: RawFiles(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "RawFiles"; }; -#endif - static void* RawFiles::LoadModdableRawfileFunc(const char* filename); }; } diff --git a/src/Components/Modules/Renderer.hpp b/src/Components/Modules/Renderer.hpp index fcc28a56..23673599 100644 --- a/src/Components/Modules/Renderer.hpp +++ b/src/Components/Modules/Renderer.hpp @@ -11,10 +11,6 @@ namespace Components Renderer(); ~Renderer(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Renderer"; }; -#endif - static int Width(); static int Height(); diff --git a/src/Components/Modules/Script.hpp b/src/Components/Modules/Script.hpp index 9966877f..14bc5119 100644 --- a/src/Components/Modules/Script.hpp +++ b/src/Components/Modules/Script.hpp @@ -26,10 +26,6 @@ namespace Components Script(); ~Script(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Script"; }; -#endif - static int LoadScriptAndLabel(std::string script, std::string label); static void AddFunction(std::string name, Game::scr_function_t function, bool isDev = false); diff --git a/src/Components/Modules/ServerCommands.cpp b/src/Components/Modules/ServerCommands.cpp new file mode 100644 index 00000000..37b09567 --- /dev/null +++ b/src/Components/Modules/ServerCommands.cpp @@ -0,0 +1,106 @@ +#include "STDInclude.hpp" + +namespace Components +{ + std::unordered_map> ServerCommands::Commands; + std::uint32_t ServerCommands::LastServerCommand; + + void ServerCommands::OnCommand(std::int32_t cmd, std::function cb) + { + ServerCommands::Commands[cmd] = cb; + } + + bool ServerCommands::OnServerCommand() + { + Command::ClientParams params(*Game::cmd_id); + + for (auto &serverCommandCB : ServerCommands::Commands) + { + if (params.length() >= 1) + { + if (params.get(0)[0] == serverCommandCB.first) + { + return serverCommandCB.second(¶ms); + } + } + } + + return false; + } + + __declspec(naked) void ServerCommands::OnServerCommandStub() + { + __asm + { + push eax + pushad + call ServerCommands::OnServerCommand + mov [esp + 20h], eax + popad + pop eax + + test al, al + jnz jumpback + + push 5944AEh + retn + + jumpback: + push 594536h + retn + } + } + + __declspec(naked) void ServerCommands::OnServerCommandPreFailStub() + { + __asm + { + mov ServerCommands::LastServerCommand, ecx + cmp ecx, 79h + + jl above + + push 59449Fh + retn + + above: + push 593C28h + retn + } + } + + void ServerCommands::OnServerCommandFailPrint(int type, const char *, ...) + { + Command::ClientParams params(*Game::cmd_id); + Game::Com_Printf(type, "Unknown client game command: %i %s\n", LastServerCommand, params.join(1)); + } + + __declspec(naked) void ServerCommands::OnServerCommandFailPrintStub() + { + __asm + { + pushad + call ServerCommands::OnServerCommandFailPrint + popad + + push 5944C0h + retn + } + } + + ServerCommands::ServerCommands() + { + // Server command receive hook + Utils::Hook(0x59449F, ServerCommands::OnServerCommandStub).install()->quick(); + + // Server command fail hooks + Utils::Hook(0x593C1F, ServerCommands::OnServerCommandPreFailStub).install()->quick(); + Utils::Hook(0x5944BB, ServerCommands::OnServerCommandFailPrintStub).install()->quick(); + Utils::Hook::Set(0x5944D3, 0xEB); + } + + ServerCommands::~ServerCommands() + { + ServerCommands::Commands.clear(); + } +} diff --git a/src/Components/Modules/ServerCommands.hpp b/src/Components/Modules/ServerCommands.hpp new file mode 100644 index 00000000..fac41915 --- /dev/null +++ b/src/Components/Modules/ServerCommands.hpp @@ -0,0 +1,23 @@ +#pragma once + +namespace Components +{ + class ServerCommands : public Component + { + public: + ServerCommands(); + ~ServerCommands(); + + static void OnCommand(std::int32_t cmd, std::function cb); + + private: + static std::unordered_map> Commands; + static std::uint32_t LastServerCommand; + + static bool OnServerCommand(); + static void OnServerCommandStub(); + static void OnServerCommandPreFailStub(); + static void OnServerCommandFailPrint(int type, const char * trash, ...); + static void OnServerCommandFailPrintStub(); + }; +} diff --git a/src/Components/Modules/ServerInfo.hpp b/src/Components/Modules/ServerInfo.hpp index 18c92245..d7e0cf17 100644 --- a/src/Components/Modules/ServerInfo.hpp +++ b/src/Components/Modules/ServerInfo.hpp @@ -8,10 +8,6 @@ namespace Components ServerInfo(); ~ServerInfo(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "ServerInfo"; }; -#endif - static Utils::InfoString GetInfo(); private: diff --git a/src/Components/Modules/ServerList.hpp b/src/Components/Modules/ServerList.hpp index 8c17f8b3..7f160435 100644 --- a/src/Components/Modules/ServerList.hpp +++ b/src/Components/Modules/ServerList.hpp @@ -32,10 +32,6 @@ namespace Components ServerList(); ~ServerList(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "ServerList"; }; -#endif - static void Refresh(UIScript::Token); static void RefreshVisibleList(UIScript::Token); static void UpdateVisibleList(UIScript::Token); diff --git a/src/Components/Modules/Singleton.hpp b/src/Components/Modules/Singleton.hpp index c02b832b..db2a11c8 100644 --- a/src/Components/Modules/Singleton.hpp +++ b/src/Components/Modules/Singleton.hpp @@ -7,10 +7,6 @@ namespace Components public: Singleton(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Singleton"; }; -#endif - static bool IsFirstInstance(); private: diff --git a/src/Components/Modules/Slowmotion.hpp b/src/Components/Modules/Slowmotion.hpp index a8cc057b..7f9dcee4 100644 --- a/src/Components/Modules/Slowmotion.hpp +++ b/src/Components/Modules/Slowmotion.hpp @@ -10,10 +10,6 @@ namespace Components public: SlowMotion(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "SlowMotion"; }; -#endif - private: static int Delay; diff --git a/src/Components/Modules/StartupMessages.hpp b/src/Components/Modules/StartupMessages.hpp index 1d1d3e52..0c19a60b 100644 --- a/src/Components/Modules/StartupMessages.hpp +++ b/src/Components/Modules/StartupMessages.hpp @@ -7,10 +7,6 @@ namespace Components public: StartupMessages(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "StartupMessages"; }; -#endif - static void AddMessage(std::string message); private: diff --git a/src/Components/Modules/Stats.hpp b/src/Components/Modules/Stats.hpp index 52518565..72f90c38 100644 --- a/src/Components/Modules/Stats.hpp +++ b/src/Components/Modules/Stats.hpp @@ -8,10 +8,6 @@ namespace Components Stats(); ~Stats(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Stats"; }; -#endif - static bool IsMaxLevel(); private: diff --git a/src/Components/Modules/StringTable.hpp b/src/Components/Modules/StringTable.hpp index 48b65299..74a471bf 100644 --- a/src/Components/Modules/StringTable.hpp +++ b/src/Components/Modules/StringTable.hpp @@ -8,10 +8,6 @@ namespace Components StringTable(); ~StringTable(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "StringTable"; }; -#endif - private: static std::unordered_map StringTableMap; diff --git a/src/Components/Modules/StructuredData.hpp b/src/Components/Modules/StructuredData.hpp index 41bfd714..8c7a6431 100644 --- a/src/Components/Modules/StructuredData.hpp +++ b/src/Components/Modules/StructuredData.hpp @@ -26,10 +26,6 @@ namespace Components StructuredData(); ~StructuredData(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "StructuredData"; }; -#endif - private: static bool UpdateVersionOffsets(Game::StructuredDataDefSet *set, Game::StructuredDataBuffer *buffer, Game::StructuredDataDef *oldDef); diff --git a/src/Components/Modules/Theatre.hpp b/src/Components/Modules/Theatre.hpp index b64026df..2b8858d4 100644 --- a/src/Components/Modules/Theatre.hpp +++ b/src/Components/Modules/Theatre.hpp @@ -7,10 +7,6 @@ namespace Components public: Theatre(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Theatre"; }; -#endif - static void StopRecording(); private: diff --git a/src/Components/Modules/Threading.hpp b/src/Components/Modules/Threading.hpp index 9c66654f..2e4354d3 100644 --- a/src/Components/Modules/Threading.hpp +++ b/src/Components/Modules/Threading.hpp @@ -7,10 +7,6 @@ namespace Components public: Threading(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Threading"; }; -#endif - private: static void FrameEpilogueStub(); static void PacketEventStub(); diff --git a/src/Components/Modules/Toast.hpp b/src/Components/Modules/Toast.hpp index f3ed65a3..dc59ec0f 100644 --- a/src/Components/Modules/Toast.hpp +++ b/src/Components/Modules/Toast.hpp @@ -11,10 +11,6 @@ namespace Components typedef WinToastLib::WinToastTemplate Template; -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Toast"; }; -#endif - static void Show(std::string image, std::string title, std::string description, int length); static bool ShowNative(const WinToastLib::WinToastTemplate& toast); diff --git a/src/Components/Modules/UIFeeder.hpp b/src/Components/Modules/UIFeeder.hpp index ec3838eb..e8840514 100644 --- a/src/Components/Modules/UIFeeder.hpp +++ b/src/Components/Modules/UIFeeder.hpp @@ -19,10 +19,6 @@ namespace Components UIFeeder(); ~UIFeeder(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "UIFeeder"; }; -#endif - static void Add(float feeder, GetItemCount_t itemCountCb, GetItemText_t itemTextCb, Select_t selectCb); private: diff --git a/src/Components/Modules/UIScript.hpp b/src/Components/Modules/UIScript.hpp index e10b8dcb..143d6fb9 100644 --- a/src/Components/Modules/UIScript.hpp +++ b/src/Components/Modules/UIScript.hpp @@ -8,10 +8,6 @@ namespace Components UIScript(); ~UIScript(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "UIScript"; }; -#endif - class Token { public: diff --git a/src/Components/Modules/Weapon.cpp b/src/Components/Modules/Weapon.cpp index 4c2ef802..e80e95e6 100644 --- a/src/Components/Modules/Weapon.cpp +++ b/src/Components/Modules/Weapon.cpp @@ -420,6 +420,22 @@ namespace Components Utils::Hook::Set(0x4F7630, 0x12DC + (sizeof(bg_sharedAmmoCaps) - (1200 * 4))); } + void* Weapon::LoadNoneWeaponHook() + { + // load anim scripts now, rather than a bit later on + Utils::Hook::Call(0x4E46A0)(); + + return Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_WEAPON, "none").data; + } + + void __declspec(naked) Weapon::LoadNoneWeaponHookStub() + { + __asm + { + jmp LoadNoneWeaponHook + } + } + Weapon::Weapon() { Weapon::PatchLimit(); @@ -436,6 +452,10 @@ namespace Components // Skip double loading for fs_game Utils::Hook::Set(0x4081FD, 0xEB); + // Weapon swap fix + Utils::Hook::Nop(0x4B3670, 5); + Utils::Hook(0x57B4F0, LoadNoneWeaponHookStub).install()->quick(); + // Don't load bounce sounds for now, it causes crashes // TODO: Actually check the weaponfiles and/or reset the soundtable correctly! //Utils::Hook::Nop(0x57A360, 5); diff --git a/src/Components/Modules/Weapon.hpp b/src/Components/Modules/Weapon.hpp index 1f785b35..5176a261 100644 --- a/src/Components/Modules/Weapon.hpp +++ b/src/Components/Modules/Weapon.hpp @@ -12,13 +12,11 @@ namespace Components public: Weapon(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Weapon"; }; -#endif - private: static Game::XAssetHeader WeaponFileLoad(Game::XAssetType type, std::string filename); static void PatchLimit(); + static void* LoadNoneWeaponHook(); + static void LoadNoneWeaponHookStub(); static void PatchConfigStrings(); static const char* GetWeaponConfigString(int index); diff --git a/src/Components/Modules/Window.hpp b/src/Components/Modules/Window.hpp index 8a9872b3..cd39da7a 100644 --- a/src/Components/Modules/Window.hpp +++ b/src/Components/Modules/Window.hpp @@ -7,10 +7,6 @@ namespace Components public: Window(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Window"; }; -#endif - static int Width(); static int Height(); static int Width(HWND window); diff --git a/src/Components/Modules/ZoneBuilder.hpp b/src/Components/Modules/ZoneBuilder.hpp index b57fb112..29e9b5a8 100644 --- a/src/Components/Modules/ZoneBuilder.hpp +++ b/src/Components/Modules/ZoneBuilder.hpp @@ -95,7 +95,6 @@ namespace Components ~ZoneBuilder(); #if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "ZoneBuilder"; }; bool unitTest() override; #endif diff --git a/src/Components/Modules/Zones.hpp b/src/Components/Modules/Zones.hpp index 84a27511..faa2d17f 100644 --- a/src/Components/Modules/Zones.hpp +++ b/src/Components/Modules/Zones.hpp @@ -12,10 +12,6 @@ namespace Components Zones(); ~Zones(); -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "Zones"; }; -#endif - static void SetVersion(int version); static int Version() { return Zones::ZoneVersion; }; diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 01fc3783..2e205576 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -121,6 +121,8 @@ namespace Game Image_LoadFromFileWithReader_t Image_LoadFromFileWithReader = Image_LoadFromFileWithReader_t(0x53ABF0); Image_Release_t Image_Release = Image_Release_t(0x51F010); + Info_ValueForKey_t Info_ValueForKey = Info_ValueForKey_t(0x47C820); + Key_SetCatcher_t Key_SetCatcher = Key_SetCatcher_t(0x43BD00); LargeLocalInit_t LargeLocalInit = LargeLocalInit_t(0x4A62A0); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index e6f7769b..68471344 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -304,6 +304,9 @@ namespace Game typedef void(__cdecl * Image_Release_t)(GfxImage* image); extern Image_Release_t Image_Release; + typedef char*(__cdecl * Info_ValueForKey_t)(const char* infoString, const char* key); + extern Info_ValueForKey_t Info_ValueForKey; + typedef void(__cdecl * Key_SetCatcher_t)(int localClientNum, int catcher); extern Key_SetCatcher_t Key_SetCatcher;