From c879fddffd81eaee9fd9e584f03667c61f61d1f0 Mon Sep 17 00:00:00 2001 From: Edo Date: Sat, 22 Apr 2023 22:35:31 +0200 Subject: [PATCH 01/16] [Branding]: Small update (#966) --- src/Components/Modules/Branding.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Modules/Branding.cpp b/src/Components/Modules/Branding.cpp index 0164b6d4..c0f1eaab 100644 --- a/src/Components/Modules/Branding.cpp +++ b/src/Components/Modules/Branding.cpp @@ -101,7 +101,7 @@ namespace Components RegisterBrandingDvars(); // UI version string - Utils::Hook::Set(0x43F73B, "IW4x - " REVISION_STR); + Utils::Hook::Set(0x43F73B, "IW4x " REVISION_STR); // Short version dvar Utils::Hook::Set(0x60BD91, REVISION_STR); From c961db16a72abfdab2c8be7f1eb5951463398b88 Mon Sep 17 00:00:00 2001 From: Edo Date: Sat, 22 Apr 2023 22:57:27 +0200 Subject: [PATCH 02/16] [General]: Create .editorconfig (#967) --- .editorconfig | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..2712949b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +[*.{cpp,hpp}] +end_of_line = crlf +insert_final_newline = true +indent_style = tab +indent_size = 4 +trim_trailing_whitespace = true +charset = utf-8 +brace_style = next_line +namespace_indentation = all +cpp_indent_namespace_contents = true From b33d5912a97bf3d5e8051669759fca5bf09938b1 Mon Sep 17 00:00:00 2001 From: Edo Date: Mon, 24 Apr 2023 16:55:10 +0200 Subject: [PATCH 03/16] [Console]: Fix format string (#968) --- src/Components/Modules/Console.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Modules/Console.cpp b/src/Components/Modules/Console.cpp index 8be532f7..08b53d69 100644 --- a/src/Components/Modules/Console.cpp +++ b/src/Components/Modules/Console.cpp @@ -97,9 +97,9 @@ namespace Components else if (IsWindow(GetWindow()) != FALSE) { #ifdef EXPERIMENTAL_BUILD - SetWindowTextA(GetWindow(), Utils::String::Format("IW4x " REVISION_STR "-develop : %s", hostname)); + SetWindowTextA(GetWindow(), Utils::String::Format("IW4x " REVISION_STR "-develop : {}", hostname)); #else - SetWindowTextA(GetWindow(), Utils::String::Format("IW4x " REVISION_STR " : %s", hostname)); + SetWindowTextA(GetWindow(), Utils::String::Format("IW4x " REVISION_STR " : {}", hostname)); #endif } } From f8acea54d84c252045e19b35378cf037adc2349d Mon Sep 17 00:00:00 2001 From: Edo Date: Mon, 24 Apr 2023 23:42:36 +0200 Subject: [PATCH 04/16] [Network]: Check who sent print OOB (#969) --- src/Components/Modules/Logger.cpp | 2 +- src/Components/Modules/Network.cpp | 21 ++++++++++++++++++++- src/Game/Common.cpp | 1 + src/Game/Common.hpp | 3 +++ src/Game/Functions.cpp | 1 + src/Game/Functions.hpp | 5 ++++- 6 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/Components/Modules/Logger.cpp b/src/Components/Modules/Logger.cpp index 69864abc..46754220 100644 --- a/src/Components/Modules/Logger.cpp +++ b/src/Components/Modules/Logger.cpp @@ -22,7 +22,7 @@ namespace Components void Logger::Print_Stub(const int channel, const char* message, ...) { - char buf[4096] = {0}; + char buf[4096]{}; va_list va; va_start(va, message); diff --git a/src/Components/Modules/Network.cpp b/src/Components/Modules/Network.cpp index 6e98e466..7efa61df 100644 --- a/src/Components/Modules/Network.cpp +++ b/src/Components/Modules/Network.cpp @@ -360,9 +360,13 @@ namespace Components Utils::Hook::Set(0x5AA5B6, 0xEB); // CL_SteamServerAuth Utils::Hook::Set(0x5AA69F, 0xEB); // echo Utils::Hook::Set(0x5AAA82, 0xEB); // SP + Utils::Hook::Set(0x5A9F77, 0xEB); // CL_WeNowCantHearSomeone Utils::Hook::Set(0x5A9F18, 0xEB); // CL_VoiceConnectionTestPacket Utils::Hook::Set(0x5A9FF3, 0xEB); // CL_HandleRelayPacket + // For security reasons check the sender of the 'print' OOB + Utils::Hook::Set(0x5AA729, 0xEB); + // Com_GetProtocol Utils::Hook::Set(0x4FB501, PROTOCOL); @@ -381,9 +385,24 @@ namespace Components Utils::Hook::Set(0x682170, 0xC3); // Telling LSP that we're playing a private match Utils::Hook::Nop(0x4FD448, 5); // Don't create lsp_socket - OnClientPacket("resolveAddress", [](const Address& address, [[maybe_unused]] const std::string& data) + OnClientPacket("resolveAddress", []([[maybe_unused]] const Address& address, [[maybe_unused]] const std::string& data) { SendRaw(address, address.getString()); }); + + OnClientPacket("print", []([[maybe_unused]] const Address& address, [[maybe_unused]] const std::string& data) + { + auto* clc = Game::CL_GetLocalClientConnection(0); + if (!Game::NET_CompareBaseAdr(clc->serverAddress, *address.get())) + { + return; + } + + char buffer[2048]{}; + + Game::I_strncpyz(clc->serverMessage, data.data(), sizeof(clc->serverMessage)); + Game::Com_sprintf(buffer, sizeof(buffer), "%s", data.data()); + Game::Com_PrintMessage(Game::CON_CHANNEL_CLIENT, data.data(), 0); + }); } } diff --git a/src/Game/Common.cpp b/src/Game/Common.cpp index 123fb859..0b86c1ea 100644 --- a/src/Game/Common.cpp +++ b/src/Game/Common.cpp @@ -12,6 +12,7 @@ namespace Game Com_PrintError_t Com_PrintError = Com_PrintError_t(0x4F8C70); Com_PrintWarning_t Com_PrintWarning = Com_PrintWarning_t(0x4E0200); Com_PrintMessage_t Com_PrintMessage = Com_PrintMessage_t(0x4AA830); + Com_sprintf_t Com_sprintf = Com_sprintf_t(0x413DE0); Com_EndParseSession_t Com_EndParseSession = Com_EndParseSession_t(0x4B80B0); Com_BeginParseSession_t Com_BeginParseSession = Com_BeginParseSession_t(0x4AAB80); Com_ParseOnLine_t Com_ParseOnLine = Com_ParseOnLine_t(0x4C0350); diff --git a/src/Game/Common.hpp b/src/Game/Common.hpp index 8698d685..f2d44ab2 100644 --- a/src/Game/Common.hpp +++ b/src/Game/Common.hpp @@ -29,6 +29,9 @@ namespace Game typedef void(*Com_PrintMessage_t)(int channel, const char* msg, int error); extern Com_PrintMessage_t Com_PrintMessage; + typedef int(*Com_sprintf_t)(char* dest, int size, const char* fmt, ...); + extern Com_sprintf_t Com_sprintf; + typedef void(*Com_EndParseSession_t)(); extern Com_EndParseSession_t Com_EndParseSession; diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 9dd91cea..1d5af994 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -109,6 +109,7 @@ namespace Game NET_AdrToString_t NET_AdrToString = NET_AdrToString_t(0x469880); NET_CompareAdr_t NET_CompareAdr = NET_CompareAdr_t(0x4D0AA0); + NET_CompareBaseAdr_t NET_CompareBaseAdr = NET_CompareBaseAdr_t(0x455510); NET_DeferPacketToClient_t NET_DeferPacketToClient = NET_DeferPacketToClient_t(0x4C8AA0); NET_ErrorString_t NET_ErrorString = NET_ErrorString_t(0x4E7720); NET_Init_t NET_Init = NET_Init_t(0x491860); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index c7c9635c..2618d37c 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -269,12 +269,15 @@ namespace Game typedef void(*NetadrToSockadr_t)(netadr_t *a, sockaddr *s); extern NetadrToSockadr_t NetadrToSockadr; - typedef const char* (*NET_AdrToString_t)(netadr_t adr); + typedef const char*(*NET_AdrToString_t)(netadr_t adr); extern NET_AdrToString_t NET_AdrToString; typedef bool(*NET_CompareAdr_t)(netadr_t a, netadr_t b); extern NET_CompareAdr_t NET_CompareAdr; + typedef int(*NET_CompareBaseAdr_t)(netadr_t a, netadr_t b); + extern NET_CompareBaseAdr_t NET_CompareBaseAdr; + typedef void(*NET_DeferPacketToClient_t)(netadr_t*, msg_t*); extern NET_DeferPacketToClient_t NET_DeferPacketToClient; From 2d196ea313088e112eaa9cca2e6111e7d5b9d19c Mon Sep 17 00:00:00 2001 From: Edo Date: Mon, 24 Apr 2023 23:51:04 +0200 Subject: [PATCH 05/16] [Network]: Fix this (#970) --- src/Components/Modules/Network.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Modules/Network.cpp b/src/Components/Modules/Network.cpp index 7efa61df..938173f9 100644 --- a/src/Components/Modules/Network.cpp +++ b/src/Components/Modules/Network.cpp @@ -402,7 +402,7 @@ namespace Components Game::I_strncpyz(clc->serverMessage, data.data(), sizeof(clc->serverMessage)); Game::Com_sprintf(buffer, sizeof(buffer), "%s", data.data()); - Game::Com_PrintMessage(Game::CON_CHANNEL_CLIENT, data.data(), 0); + Game::Com_PrintMessage(Game::CON_CHANNEL_CLIENT, buffer, 0); }); } } From 409b23d233a9ff0c10eb556c6d93c206c7519ac0 Mon Sep 17 00:00:00 2001 From: Edo Date: Tue, 25 Apr 2023 00:55:08 +0200 Subject: [PATCH 06/16] [String]: Reduce initial buffer size (#971) --- src/Utils/String.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/String.cpp b/src/Utils/String.cpp index 365b71ef..a0fed218 100644 --- a/src/Utils/String.cpp +++ b/src/Utils/String.cpp @@ -8,7 +8,7 @@ namespace Utils::String const char* VA(const char* fmt, ...) { static VAProvider<4, 256> globalProvider; - static thread_local VAProvider<8, 1024> provider; + static thread_local VAProvider<8, 256> provider; va_list ap; va_start(ap, fmt); From b5ed99a2f909c987e36cc0776886587edb01480b Mon Sep 17 00:00:00 2001 From: Edo Date: Tue, 25 Apr 2023 10:05:12 +0200 Subject: [PATCH 07/16] [Chat]: Go back to using SV_CMD_CAN_IGNORE (#972) --- src/Components/Modules/Chat.cpp | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/Components/Modules/Chat.cpp b/src/Components/Modules/Chat.cpp index d3aa5397..2e0c476f 100644 --- a/src/Components/Modules/Chat.cpp +++ b/src/Components/Modules/Chat.cpp @@ -56,13 +56,13 @@ namespace Components if (IsMuted(player)) { SendChat = false; - Game::SV_GameSendServerCommand(player - Game::g_entities, Game::SV_CMD_RELIABLE, Utils::String::VA("%c \"You are muted\"", 0x65)); + Game::SV_GameSendServerCommand(player - Game::g_entities, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"You are muted\"", 0x65)); } if (sv_disableChat.get()) { SendChat = false; - Game::SV_GameSendServerCommand(player - Game::g_entities, Game::SV_CMD_RELIABLE, Utils::String::VA("%c \"Chat is disabled\"", 0x65)); + Game::SV_GameSendServerCommand(player - Game::g_entities, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"Chat is disabled\"", 0x65)); } // Message might be empty after the special characters @@ -297,7 +297,7 @@ namespace Components }); Logger::Print("{} was muted\n", client->name); - Game::SV_GameSendServerCommand(client - Game::svs_clients, Game::SV_CMD_RELIABLE, Utils::String::VA("%c \"You were muted\"", 0x65)); + Game::SV_GameSendServerCommand(client - Game::svs_clients, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"You were muted\"", 0x65)); } void Chat::UnmuteClient(const Game::client_t* client) @@ -305,7 +305,7 @@ namespace Components UnmuteInternal(client->steamID); Logger::Print("{} was unmuted\n", client->name); - Game::SV_GameSendServerCommand(client - Game::svs_clients, Game::SV_CMD_RELIABLE, Utils::String::VA("%c \"You were unmuted\"", 0x65)); + Game::SV_GameSendServerCommand(client - Game::svs_clients, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"You were unmuted\"", 0x65)); } void Chat::UnmuteInternal(const std::uint64_t id, bool everyone) @@ -461,12 +461,12 @@ namespace Components if (!name.empty()) { - Game::SV_GameSendServerCommand(-1, Game::SV_CMD_RELIABLE, Utils::String::Format("{:c} \"{}: {}\"", 0x68, name, message)); + Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"{}: {}\"", 0x68, name, message)); Logger::Print(Game::CON_CHANNEL_SERVER, "{}: {}\n", name, message); } else { - Game::SV_GameSendServerCommand(-1, Game::SV_CMD_RELIABLE, Utils::String::Format("{:c} \"Console: {}\"", 0x68, message)); + Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"Console: {}\"", 0x68, message)); Logger::Print(Game::CON_CHANNEL_SERVER, "Console: {}\n", message); } }); @@ -489,12 +489,12 @@ namespace Components if (!name.empty()) { - Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_RELIABLE, Utils::String::Format("{:c} \"{}: {}\"", 0x68, name.data(), message)); + Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"{}: {}\"", 0x68, name.data(), message)); Logger::Print(Game::CON_CHANNEL_SERVER, "{} -> {}: {}\n", name, clientNum, message); } else { - Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_RELIABLE, Utils::String::Format("{:c} \"Console: {}\"", 0x68, message)); + Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"Console: {}\"", 0x68, message)); Logger::Print(Game::CON_CHANNEL_SERVER, "Console -> {}: {}\n", clientNum, message); } }); @@ -510,7 +510,7 @@ namespace Components if (params->size() < 2) return; const auto message = params->join(1); - Game::SV_GameSendServerCommand(-1, Game::SV_CMD_RELIABLE, Utils::String::Format("{:c} \"{}\"", 0x68, message)); + Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"{}\"", 0x68, message)); Logger::Print(Game::CON_CHANNEL_SERVER, "Raw: {}\n", message); }); @@ -528,7 +528,7 @@ namespace Components const auto clientNum = static_cast(std::min(parsedInput, Game::MAX_CLIENTS)); const auto message = params->join(2); - Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_RELIABLE, Utils::String::Format("{:c} \"{}\"", 0x68, message)); + Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"{}\"", 0x68, message)); Logger::Print(Game::CON_CHANNEL_SERVER, "Raw -> {}: {}\n", clientNum, message); }); @@ -619,9 +619,6 @@ namespace Components Utils::Hook(0x4D00D4, PostSayStub, HOOK_CALL).install()->quick(); Utils::Hook(0x4D0110, PostSayStub, HOOK_CALL).install()->quick(); - // Patch G_SayTo to use SV_CMD_RELIABLE - Utils::Hook::Set(0x5DF7E3, Game::SV_CMD_RELIABLE); - // Change logic that does word splitting with new lines for chat messages to support fonticons Utils::Hook(0x592E10, CG_AddToTeamChat_Stub, HOOK_JUMP).install()->quick(); From 4dd88de3a0dbf624a08ac1accc69986788402f10 Mon Sep 17 00:00:00 2001 From: Edo Date: Tue, 25 Apr 2023 13:08:29 +0200 Subject: [PATCH 08/16] [Voice]: Check who sent packet (#973) --- src/Components/Modules/Network.cpp | 24 +++++++++++++++++++++--- src/Components/Modules/Network.hpp | 5 ++++- src/Components/Modules/Voice.cpp | 17 +++++++++++++---- src/Components/Modules/Voice.hpp | 2 +- 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/Components/Modules/Network.cpp b/src/Components/Modules/Network.cpp index 938173f9..800b4ce0 100644 --- a/src/Components/Modules/Network.cpp +++ b/src/Components/Modules/Network.cpp @@ -5,6 +5,7 @@ namespace Components Utils::Signal Network::StartupSignal; // Packet interception std::unordered_map Network::CL_Callbacks; + std::unordered_map Network::CL_RawCallbacks; Network::Address::Address() { @@ -274,17 +275,34 @@ namespace Components CL_Callbacks[Utils::String::ToLower(command)] = callback; } - bool Network::CL_HandleCommand(Game::netadr_t* address, const char* command, const Game::msg_t* message) + void Network::OnClientPacketRaw(const std::string& command, const networkRawCallback& callback) + { + CL_RawCallbacks[Utils::String::ToLower(command)] = callback; + } + + bool Network::CL_HandleCommand(Game::netadr_t* address, const char* command, Game::msg_t* message) { const auto command_ = Utils::String::ToLower(command); - const auto handler = CL_Callbacks.find(command_); const auto offset = command_.size() + 5; - if (static_cast(message->cursize) < offset || handler == CL_Callbacks.end()) + if (static_cast(message->cursize) < offset) { return false; } + if (const auto rawHandler = CL_RawCallbacks.find(command_); rawHandler != CL_RawCallbacks.end()) + { + rawHandler->second(address, message); + return true; + } + + const auto handler = CL_Callbacks.find(command_); + if (handler == CL_Callbacks.end()) + { + // Normal handler was not found, return + return false; + } + const std::string data(reinterpret_cast(message->data) + offset, message->cursize - offset); auto target = Address{ address }; diff --git a/src/Components/Modules/Network.hpp b/src/Components/Modules/Network.hpp index fcd8262a..547628ed 100644 --- a/src/Components/Modules/Network.hpp +++ b/src/Components/Modules/Network.hpp @@ -49,6 +49,7 @@ namespace Components typedef void(CallbackRaw)(); using networkCallback = std::function; + using networkRawCallback = std::function; Network(); @@ -73,17 +74,19 @@ namespace Components static void BroadcastAll(const std::string& data); static void OnClientPacket(const std::string& command, const networkCallback& callback); + static void OnClientPacketRaw(const std::string& command, const networkRawCallback& callback); private: static Utils::Signal StartupSignal; static std::unordered_map CL_Callbacks; + static std::unordered_map CL_RawCallbacks; static void NetworkStart(); static void NetworkStartStub(); static void PacketErrorCheck(); - static bool CL_HandleCommand(Game::netadr_t* address, const char* command, const Game::msg_t* message); + static bool CL_HandleCommand(Game::netadr_t* address, const char* command, Game::msg_t* message); static void CL_HandleCommandStub(); }; diff --git a/src/Components/Modules/Voice.cpp b/src/Components/Modules/Voice.cpp index c14b0c34..ea28d5d7 100644 --- a/src/Components/Modules/Voice.cpp +++ b/src/Components/Modules/Voice.cpp @@ -241,7 +241,7 @@ namespace Components void Voice::CL_WriteVoicePacket_Hk(const int localClientNum) { const auto connstate = Game::CL_GetLocalClientConnectionState(localClientNum); - const auto clc = Game::CL_GetLocalClientConnection(localClientNum); + const auto* clc = Game::CL_GetLocalClientConnection(localClientNum); const auto* vc = Game::CL_GetLocalClientVoiceCommunication(localClientNum); if (clc->demoplaying || (connstate < Game::CA_LOADING)) { @@ -315,8 +315,14 @@ namespace Components } } - void Voice::CL_VoicePacket_Hk(const int localClientNum, Game::msg_t* msg) + void Voice::CL_VoicePacket(Game::netadr_t* address, Game::msg_t* msg) { + auto* clc = Game::CL_GetLocalClientConnection(0); + if (!Game::NET_CompareBaseAdr(clc->serverAddress, *address)) + { + return; + } + const auto numPackets = Game::MSG_ReadByte(msg); if (numPackets < 0 || numPackets > MAX_SERVER_QUEUED_VOICE_PACKETS) { @@ -342,7 +348,7 @@ namespace Components return; } - if (!CL_IsPlayerMuted_Hk(nullptr, localClientNum, voicePacket.talker)) + if (!CL_IsPlayerMuted_Hk(nullptr, 0, voicePacket.talker)) { if ((*Game::cl_voice)->current.enabled) { @@ -395,7 +401,10 @@ namespace Components // Write voice packets to the server instead of other clients Utils::Hook(0x487935, CL_WriteVoicePacket_Hk, HOOK_CALL).install()->quick(); Utils::Hook(0x5AD945, CL_WriteVoicePacket_Hk, HOOK_CALL).install()->quick(); - Utils::Hook(0x5A9E06, CL_VoicePacket_Hk, HOOK_CALL).install()->quick(); + + // Disable 'v' OOB handler and use our own + Utils::Hook::Set(0x5A9E02, 0xEB); + Network::OnClientPacketRaw("v", CL_VoicePacket); Utils::Hook(0x4AE740, CL_IsPlayerTalking_Hk, HOOK_JUMP).install()->quick(); Utils::Hook(0x4B6250, CL_IsPlayerMuted_Hk, HOOK_JUMP).install()->quick(); diff --git a/src/Components/Modules/Voice.hpp b/src/Components/Modules/Voice.hpp index 908bbe54..bc5a2bc5 100644 --- a/src/Components/Modules/Voice.hpp +++ b/src/Components/Modules/Voice.hpp @@ -46,7 +46,7 @@ namespace Components static void CL_TogglePlayerMute(int localClientNum, int muteClientIndex); static void CL_WriteVoicePacket_Hk(int localClientNum); - static void CL_VoicePacket_Hk(int localClientNum, Game::msg_t* msg); + static void CL_VoicePacket(Game::netadr_t* address, Game::msg_t* msg); static void UI_Mute_player(int clientNum, int localClientNum); static void UI_Mute_Player_Stub(); From 82662a2088f9fa3c22b1048d16450709bb5e7828 Mon Sep 17 00:00:00 2001 From: Edo Date: Wed, 26 Apr 2023 10:58:53 +0100 Subject: [PATCH 09/16] [RCon]: Improve (#974) --- src/Components/Modules/RCon.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Components/Modules/RCon.cpp b/src/Components/Modules/RCon.cpp index ddab0636..70b8e785 100644 --- a/src/Components/Modules/RCon.cpp +++ b/src/Components/Modules/RCon.cpp @@ -110,12 +110,6 @@ namespace Components bool RCon::RateLimitCheck(const Network::Address& address, const int time) { const auto ip = address.getIP(); - - if (!RateLimit.contains(ip.full)) - { - RateLimit[ip.full] = 0; - } - const auto lastTime = RateLimit[ip.full]; if (lastTime && (time - lastTime) < RconTimeout.get()) From 619cdf39e478c666a4ca7ccca594bda69cf7671c Mon Sep 17 00:00:00 2001 From: Edo Date: Wed, 26 Apr 2023 14:57:54 +0100 Subject: [PATCH 10/16] [Bots]: Format code properly (#975) --- src/Components/Modules/Bots.cpp | 6 +++--- src/Components/Modules/Bots.hpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Components/Modules/Bots.cpp b/src/Components/Modules/Bots.cpp index 70fc6efe..dcb26b50 100644 --- a/src/Components/Modules/Bots.cpp +++ b/src/Components/Modules/Bots.cpp @@ -16,7 +16,7 @@ namespace Components const Game::dvar_t* Bots::sv_randomBotNames; const Game::dvar_t* Bots::sv_replaceBots; - std::size_t Bots::botDataIndex; + std::size_t Bots::BotDataIndex; struct BotMovementInfo { @@ -121,8 +121,8 @@ namespace Components if (!botNames.empty()) { - botDataIndex %= botNames.size(); - const auto index = botDataIndex++; + BotDataIndex %= botNames.size(); + const auto index = BotDataIndex++; botName = botNames[index].first; clanName = botNames[index].second; } diff --git a/src/Components/Modules/Bots.hpp b/src/Components/Modules/Bots.hpp index b7cf2315..c97b2d26 100644 --- a/src/Components/Modules/Bots.hpp +++ b/src/Components/Modules/Bots.hpp @@ -15,7 +15,7 @@ namespace Components static const Game::dvar_t* sv_randomBotNames; static const Game::dvar_t* sv_replaceBots; - static std::size_t botDataIndex; + static std::size_t BotDataIndex; static std::vector LoadBotNames(); static int BuildConnectString(char* buffer, const char* connectString, int num, int, int protocol, int checksum, int statVer, int statStuff, int port); From 6c775ceb2029d97b04fcc2bc7ef3f6af57a02355 Mon Sep 17 00:00:00 2001 From: Edo Date: Wed, 26 Apr 2023 18:48:05 +0100 Subject: [PATCH 11/16] [MapRotation]: Update minor detail (#976) --- src/Components/Modules/MapRotation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Modules/MapRotation.cpp b/src/Components/Modules/MapRotation.cpp index a449c763..b8ca5dad 100644 --- a/src/Components/Modules/MapRotation.cpp +++ b/src/Components/Modules/MapRotation.cpp @@ -155,7 +155,7 @@ namespace Components // People may have sv_mapRotation empty because they only use 'addMap' or 'addGametype' if (!mapRotation.empty()) { - Logger::Debug("sv_mapRotation is not empty. Parsing..."); + Logger::Debug("{} is not empty. Parsing...", (*Game::sv_mapRotation)->name); LoadRotation(mapRotation); } } From 0a5a585f349c6a21eac520412a214a0c2f7af1b5 Mon Sep 17 00:00:00 2001 From: Edo Date: Wed, 26 Apr 2023 21:12:21 +0100 Subject: [PATCH 12/16] [MapRotation]: Fix bug (#977) --- src/Components/Modules/MapRotation.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/Components/Modules/MapRotation.cpp b/src/Components/Modules/MapRotation.cpp index b8ca5dad..d3d9961f 100644 --- a/src/Components/Modules/MapRotation.cpp +++ b/src/Components/Modules/MapRotation.cpp @@ -134,7 +134,7 @@ namespace Components } catch (const std::exception& ex) { - Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}: {} contains invalid data!\n", ex.what(), (*Game::sv_mapRotation)->name); + Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}. {} contains invalid data!\n", ex.what(), (*Game::sv_mapRotation)->name); } Logger::Debug("DedicatedRotation size after parsing is '{}'", DedicatedRotation.getEntriesSize()); @@ -286,9 +286,13 @@ namespace Components assert(!data.empty()); // Ook, ook, eek - Logger::Warning(Game::CON_CHANNEL_SERVER, "You are using deprecated {}", (*Game::sv_mapRotationCurrent)->name); + Logger::Warning(Game::CON_CHANNEL_SERVER, "You are using deprecated {}\n", (*Game::sv_mapRotationCurrent)->name); RotationData rotationCurrent; + rotationCurrent.setHandler("map", ApplyMap); + rotationCurrent.setHandler("gametype", ApplyGametype); + rotationCurrent.setHandler("exec", ApplyExec); + try { Logger::Debug("Parsing {}", (*Game::sv_mapRotationCurrent)->name); @@ -296,7 +300,7 @@ namespace Components } catch (const std::exception& ex) { - Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}: {} contains invalid data!\n", ex.what(), (*Game::sv_mapRotationCurrent)->name); + Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}. {} contains invalid data!\n", ex.what(), (*Game::sv_mapRotationCurrent)->name); } Game::Dvar_SetString(*Game::sv_mapRotationCurrent, ""); @@ -407,11 +411,16 @@ namespace Components { Logger::Debug("Testing map rotation parsing..."); - const auto* normal = "map mp_highrise map mp_terminal map mp_firingrange map mp_trailerpark gametype dm map mp_shipment_long"; + const auto* normal = "exec war.cfg map mp_highrise map mp_terminal map mp_firingrange map mp_trailerpark gametype dm map mp_shipment_long"; + + RotationData rotation; + rotation.setHandler("map", ApplyMap); + rotation.setHandler("gametype", ApplyGametype); + rotation.setHandler("exec", ApplyExec); try { - DedicatedRotation.parse(normal); + rotation.parse(normal); } catch (const std::exception& ex) { @@ -419,14 +428,14 @@ namespace Components return false; } - DedicatedRotation.clear(); + rotation.clear(); const auto* mistake = "spdevmap mp_dome"; auto success = false; try { - DedicatedRotation.parse(mistake); + rotation.parse(mistake); } catch (const std::exception& ex) { From b34407449c3ee5670b21c97b0532a561f9620e85 Mon Sep 17 00:00:00 2001 From: Edo Date: Wed, 26 Apr 2023 21:41:57 +0100 Subject: [PATCH 13/16] [MapRotation]: Clean unit test (#978) --- src/Components/Modules/MapRotation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Modules/MapRotation.cpp b/src/Components/Modules/MapRotation.cpp index d3d9961f..ad64585e 100644 --- a/src/Components/Modules/MapRotation.cpp +++ b/src/Components/Modules/MapRotation.cpp @@ -424,7 +424,7 @@ namespace Components } catch (const std::exception& ex) { - Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}: parsing of 'normal' failed\n", ex.what()); + Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}. parsing of 'normal' failed\n", ex.what()); return false; } @@ -439,7 +439,7 @@ namespace Components } catch (const std::exception& ex) { - Logger::Debug("{}: parsing of 'normal' failed as expected", ex.what()); + Logger::Debug("{}. parsing of 'normal' failed as expected", ex.what()); success = true; } From a60b06002bbdea433f138aa2e6c4a9ac518d677f Mon Sep 17 00:00:00 2001 From: Edo Date: Wed, 26 Apr 2023 22:14:30 +0100 Subject: [PATCH 14/16] [MapRotation]: Change command type to SV (#979) --- src/Components/Modules/MapRotation.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Components/Modules/MapRotation.cpp b/src/Components/Modules/MapRotation.cpp index ad64585e..ecbf1f96 100644 --- a/src/Components/Modules/MapRotation.cpp +++ b/src/Components/Modules/MapRotation.cpp @@ -162,7 +162,7 @@ namespace Components void MapRotation::AddMapRotationCommands() { - Command::Add("addMap", [](Command::Params* params) + Command::AddSV("addMap", [](Command::Params* params) { if (params->size() < 2) { @@ -173,7 +173,7 @@ namespace Components DedicatedRotation.addEntry("map", params->get(1)); }); - Command::Add("addGametype", [](Command::Params* params) + Command::AddSV("addGametype", [](Command::Params* params) { if (params->size() < 2) { @@ -397,7 +397,7 @@ namespace Components MapRotation::MapRotation() { - AddMapRotationCommands(); + Events::OnSVInit(AddMapRotationCommands); Utils::Hook::Set(0x4152E8, SV_MapRotate_f); DedicatedRotation.setHandler("map", ApplyMap); From 7f67cde8fde223c0e2d12347e152da02f9c470fd Mon Sep 17 00:00:00 2001 From: Edo Date: Wed, 26 Apr 2023 23:02:17 +0100 Subject: [PATCH 15/16] [MapRotation]: Last fix ever (#980) --- src/Components/Modules/MapRotation.cpp | 33 +++++++++++++------------- src/Components/Modules/MapRotation.hpp | 4 ++-- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/Components/Modules/MapRotation.cpp b/src/Components/Modules/MapRotation.cpp index ecbf1f96..f6daef67 100644 --- a/src/Components/Modules/MapRotation.cpp +++ b/src/Components/Modules/MapRotation.cpp @@ -126,7 +126,7 @@ namespace Components return mapRotationJson; } - void MapRotation::LoadRotation(const std::string& data) + void MapRotation::ParseRotation(const std::string& data) { try { @@ -140,6 +140,19 @@ namespace Components Logger::Debug("DedicatedRotation size after parsing is '{}'", DedicatedRotation.getEntriesSize()); } + void MapRotation::RandomizeMapRotation() + { + if (SVRandomMapRotation.get()) + { + Logger::Print(Game::CON_CHANNEL_SERVER, "Randomizing the map rotation\n"); + DedicatedRotation.randomize(); + } + else + { + Logger::Debug("Map rotation was not randomized"); + } + } + void MapRotation::LoadMapRotation() { static auto loaded = false; @@ -156,7 +169,8 @@ namespace Components if (!mapRotation.empty()) { Logger::Debug("{} is not empty. Parsing...", (*Game::sv_mapRotation)->name); - LoadRotation(mapRotation); + ParseRotation(mapRotation); + RandomizeMapRotation(); } } @@ -341,19 +355,6 @@ namespace Components SVNextMap.set(""); } - void MapRotation::RandomizeMapRotation() - { - if (SVRandomMapRotation.get()) - { - Logger::Print(Game::CON_CHANNEL_SERVER, "Randomizing the map rotation\n"); - DedicatedRotation.randomize(); - } - else - { - Logger::Debug("Map rotation was not randomized"); - } - } - void MapRotation::SV_MapRotate_f() { if (!ShouldRotate()) @@ -382,8 +383,6 @@ namespace Components return; } - RandomizeMapRotation(); - ApplyRotation(DedicatedRotation); SetNextMap(DedicatedRotation); } diff --git a/src/Components/Modules/MapRotation.hpp b/src/Components/Modules/MapRotation.hpp index 3acbd4f3..6ca2fb51 100644 --- a/src/Components/Modules/MapRotation.hpp +++ b/src/Components/Modules/MapRotation.hpp @@ -84,7 +84,8 @@ namespace Components // Holds the parsed data from sv_mapRotation static RotationData DedicatedRotation; - static void LoadRotation(const std::string& data); + static void RandomizeMapRotation(); + static void ParseRotation(const std::string& data); static void LoadMapRotation(); // Use these commands before SV_MapRotate_f is called @@ -103,7 +104,6 @@ namespace Components static void SetNextMap(RotationData& rotation); // Only call this after ApplyRotation static void SetNextMap(const char* value); static void ClearNextMap(); - static void RandomizeMapRotation(); static void SV_MapRotate_f(); }; From 59c132428d6a252f7ad073a73a08616e60e05366 Mon Sep 17 00:00:00 2001 From: Edo Date: Wed, 26 Apr 2023 23:20:37 +0100 Subject: [PATCH 16/16] Update CHANGELOG.md (#981) --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72cfcf32..5537e31c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.3.0/). +## r4226 - 2023-04-26 + +- Chat system will go back to using `SV_CMD_CAN_IGNORE` commands (#972) + +### Fixed + +- Fix bug with how `sv_mapRotationCurrent` is parsed (#977) + +### Known issues + +- Sound issue fix is experimental as the bug is not fully understood. + ## r4208 - 2023-04-22 ### Changed