diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp index 1ae357c9..d1fbff2e 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()); diff --git a/src/Components/Loader.hpp b/src/Components/Loader.hpp index 2c514ea4..e4988170 100644 --- a/src/Components/Loader.hpp +++ b/src/Components/Loader.hpp @@ -75,6 +75,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" diff --git a/src/Components/Modules/Clantags.cpp b/src/Components/Modules/Clantags.cpp new file mode 100644 index 00000000..f475eec1 --- /dev/null +++ b/src/Components/Modules/Clantags.cpp @@ -0,0 +1,120 @@ +#include "STDInclude.hpp" + +namespace Components +{ + std::vector < std::string > Clantags::Tags; + const char* CurrentName; + + void Clantags::ParseClantags(const char* infoString) + { + const char* clantag; + for (int i = 0; i < 18; i++) + { + clantag = Game::Info_ValueForKey(infoString, std::to_string(i).c_str()); + + if (clantag != nullptr) + { + Tags[i] = _strdup(clantag); + } + else + { + Tags[i] = ""; + } + } + } + + void Clantags::SendClantagsToClients() + { + const char* list = ""; + + for (int i = 0; i < 18; i++) + { + char clantag[5]; + + if (Game::svs_clients[i].state >= 3) + { + strncpy_s(clantag, Game::Info_ValueForKey(Game::svs_clients[i].connectInfoString, "iw4x_clantag"), 4); + } + else + { + memset(clantag, 0, 5); + } + + list = Utils::String::VA("%s\\%s\\%s", list, std::to_string(i).c_str(), clantag); + } + + list = Utils::String::VA("%c clantags \"%s\"", 22, list); + Game::SV_GameSendServerCommand(-1, 0, list); + } + + void Clantags::GetUserClantag(std::uint32_t clientnum, const char* playername) + { + if (Tags[clientnum].empty()) + { + CurrentName = playername; + return; + } + + CurrentName = Utils::String::VA("[%s] %s", Tags[clientnum].data(), playername); + } + + void __declspec(naked) Clantags::DrawPlayerNameOnScoreboard() + { + static DWORD drawstringfunc = 0x5909E0; + + __asm + { + pushad; + + push edi; + push [ebp]; + + call GetUserClantag; + add esp, 8; + + popad; + + mov edi, CurrentName; + + call drawstringfunc; + + push 591247h; + retn; + } + } + + Clantags::Clantags() + { + // Create clantag dvar + Dvar::OnInit([]() { + CardTitles::CustomTitleDvar = Game::Dvar_RegisterString("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 && !Flags::HasFlag("dedicated")) + { + if (params->length() == 3) + { + Clantags::ParseClantags(params->get(2)); + return true; + } + } + + return false; + + }); + + // Resize clantags array + Tags.resize(18); + + // Draw clantag before playername + Utils::Hook(0x591242, DrawPlayerNameOnScoreboard).install()->quick(); + } + + Clantags::~Clantags() + { + Tags.clear(); + } +} diff --git a/src/Components/Modules/Clantags.hpp b/src/Components/Modules/Clantags.hpp new file mode 100644 index 00000000..1f1d4e56 --- /dev/null +++ b/src/Components/Modules/Clantags.hpp @@ -0,0 +1,20 @@ +#pragma once + +namespace Components +{ + class Clantags : public Component + { + public: + static std::vector < std::string > Clantags::Tags; + static void ParseClantags(const char * infoString); + static void SendClantagsToClients(); + + Clantags(); + ~Clantags(); + + private: + static void GetUserClantag(std::uint32_t clientnum, const char * playername); + static void DrawPlayerNameOnScoreboard(); + + }; +} diff --git a/src/Components/Modules/Dedicated.cpp b/src/Components/Modules/Dedicated.cpp index bca732bc..7758c264 100644 --- a/src/Components/Modules/Dedicated.cpp +++ b/src/Components/Modules/Dedicated.cpp @@ -402,7 +402,7 @@ namespace Components // Post initialization point Utils::Hook(0x60BFBF, Dedicated::PostInitializationStub, HOOK_JUMP).install()->quick(); - // Custom cardtitles + // Transmit custom data Dedicated::OnFrame([]() { static std::uint64_t LastUpdate = 0; @@ -410,6 +410,8 @@ namespace Components if ((GetTickCount64() - LastUpdate) > 10000) { CardTitles::SendCustomTitlesToClients(); + Clantags::SendClantagsToClients(); + LastUpdate = GetTickCount64(); } });