From 60aa5abf05f6d13b49c493209c4473747a6534fb Mon Sep 17 00:00:00 2001 From: Diavolo Date: Sat, 21 May 2022 00:12:46 +0200 Subject: [PATCH] Refactor some packet interception code --- src/Components/Modules/Discovery.cpp | 4 +- src/Components/Modules/Network.cpp | 163 ++++++++++---------------- src/Components/Modules/Network.hpp | 24 ++-- src/Components/Modules/Party.cpp | 19 ++- src/Components/Modules/Party.hpp | 4 + src/Components/Modules/Playlist.cpp | 19 +-- src/Components/Modules/Playlist.hpp | 6 +- src/Components/Modules/RCon.cpp | 27 +++-- src/Components/Modules/ServerInfo.cpp | 12 +- src/Components/Modules/ServerList.cpp | 2 +- src/Components/Modules/Session.cpp | 12 +- src/Components/Modules/Session.hpp | 4 +- 12 files changed, 133 insertions(+), 163 deletions(-) diff --git a/src/Components/Modules/Discovery.cpp b/src/Components/Modules/Discovery.cpp index c71ca293..69accfde 100644 --- a/src/Components/Modules/Discovery.cpp +++ b/src/Components/Modules/Discovery.cpp @@ -46,7 +46,7 @@ namespace Components } }); - Network::Handle("discovery", [](Network::Address address, std::string data) + Network::OnPacket("discovery", [](Network::Address& address, [[maybe_unused]] const std::string& data) { if (address.isSelf()) return; @@ -60,7 +60,7 @@ namespace Components Network::SendCommand(address, "discoveryResponse", data); }); - Network::Handle("discoveryResponse", [](Network::Address address, std::string data) + Network::OnPacket("discoveryResponse", [](Network::Address& address, [[maybe_unused]] const std::string& data) { if (address.isSelf()) return; diff --git a/src/Components/Modules/Network.cpp b/src/Components/Modules/Network.cpp index 4d9ab118..a0c960a1 100644 --- a/src/Components/Modules/Network.cpp +++ b/src/Components/Modules/Network.cpp @@ -4,7 +4,8 @@ namespace Components { std::string Network::SelectedPacket; Utils::Signal Network::StartupSignal; - std::map> Network::PacketHandlers; + // Packet interception + std::unordered_map Network::Callbacks; Network::Address::Address(const std::string& addrString) { @@ -143,11 +144,6 @@ namespace Components return (this->getType() != Game::netadrtype_t::NA_BAD && this->getType() >= Game::netadrtype_t::NA_BOT && this->getType() <= Game::netadrtype_t::NA_IP); } - void Network::Handle(const std::string& packet, Utils::Slot callback) - { - Network::PacketHandlers[Utils::String::ToLower(packet)] = callback; - } - void Network::OnStart(Utils::Slot callback) { Network::StartupSignal.connect(callback); @@ -227,71 +223,6 @@ namespace Components Network::BroadcastRange(100, 65536, data); } - int Network::PacketInterceptionHandler(const char* packet) - { - // Packet rate limit. - static uint32_t packets = 0; - static int lastClean = 0; - - if ((Game::Sys_Milliseconds() - lastClean) > 1'000) - { - packets = 0; - lastClean = Game::Sys_Milliseconds(); - } - - if ((++packets) > NETWORK_MAX_PACKETS_PER_SECOND) - { - return 1; - } - - std::string packetCommand = packet; - auto pos = packetCommand.find_first_of("\\\n "); - if (pos != std::string::npos) - { - packetCommand = packetCommand.substr(0, pos); - } - - packetCommand = Utils::String::ToLower(packetCommand); - - // Check if custom handler exists - for (auto i = Network::PacketHandlers.begin(); i != Network::PacketHandlers.end(); ++i) - { - if (Utils::String::ToLower(i->first) == packetCommand) - { - Network::SelectedPacket = i->first; - return 0; - } - } - - // No interception - return 1; - } - - void Network::DeployPacket(Game::netadr_t* from, Game::msg_t* msg) - { - if (Network::PacketHandlers.find(Network::SelectedPacket) != Network::PacketHandlers.end()) - { - std::string data; - - size_t offset = Network::SelectedPacket.size() + 4 + 1; - - if (static_cast(msg->cursize) > offset) - { - data.append(msg->data + offset, msg->cursize - offset); - } - - // Remove trailing 0x00 byte - // Actually, don't remove it, it might be part of the packet. Send correctly formatted packets instead! - //if (data.size() && !data[data.size() - 1]) data.pop_back(); - - Network::PacketHandlers[Network::SelectedPacket](from, data); - } - else - { - Logger::Print("Error: Network packet intercepted, but handler is missing!\n"); - } - } - void Network::NetworkStart() { Network::StartupSignal(); @@ -312,31 +243,6 @@ namespace Components } } - __declspec(naked) void Network::DeployPacketStub() - { - __asm - { - lea eax, [esp + 0C54h] - - pushad - - push ebp // Command - push eax // Address pointer - call Network::DeployPacket - add esp, 8h - - popad - - mov al, 1 - pop edi - pop esi - pop ebp - pop ebx - add esp, 0C40h - retn - } - } - __declspec(naked) void Network::PacketErrorCheck() { __asm @@ -370,6 +276,60 @@ namespace Components Utils::Hook::Call(0x414D40)(client, msg); } + void Network::OnPacket(const std::string& command, const NetworkCallback& callback) + { + Network::Callbacks[Utils::String::ToLower(command)] = callback; + } + + bool Network::HandleCommand(Game::netadr_t* address, const char* command, const Game::msg_t* message) + { + const auto cmd_string = Utils::String::ToLower(command); + const auto handler = Network::Callbacks.find(cmd_string); + + const auto offset = cmd_string.size() + 5; + if (static_cast(message->cursize) < offset || handler == Network::Callbacks.end()) + { + return false; + } + + const std::string data(message->data + offset, message->cursize - offset); + + Address address_ = address; + handler->second(address_, data); + return true; + } + + __declspec(naked) void Network::CL_HandleCommandStub() + { + __asm + { + lea eax, [esp + 0xC54] // address + + pushad + + push ebp // msg_t + push edi // Command name + push eax // netadr_t pointer + call Network::HandleCommand + add esp, 0xC + + test al, al + + popad + + jz unhandled + + // Exit CL_DispatchConnectionlessPacket + push 0x5A9E0E + retn + + unhandled: + // Proceed + push 0x5AA719 + retn + } + } + Network::Network() { AssertSize(Game::netadr_t, 20); @@ -397,19 +357,16 @@ namespace Components // Install startup handler Utils::Hook(0x4FD4D4, Network::NetworkStartStub, HOOK_JUMP).install()->quick(); - // Install interception handler - Utils::Hook(0x5AA709, Network::PacketInterceptionHandler, HOOK_CALL).install()->quick(); - // Prevent recvfrom error spam Utils::Hook(0x46531A, Network::PacketErrorCheck, HOOK_JUMP).install()->quick(); - // Install packet deploy hook - Utils::Hook::RedirectJump(0x5AA713, Network::DeployPacketStub); - // Fix server freezer exploit Utils::Hook(0x626996, Network::SV_ExecuteClientMessageStub, HOOK_CALL).install()->quick(); + + // Handle client packets + Utils::Hook(0x5AA703, Network::CL_HandleCommandStub, HOOK_JUMP).install()->quick(); - Network::Handle("resolveAddress", [](Address address, const std::string& /*data*/) + Network::OnPacket("resolveAddress", [](const Address& address, [[maybe_unused]] const std::string& data) { Network::SendRaw(address, address.getString()); }); diff --git a/src/Components/Modules/Network.hpp b/src/Components/Modules/Network.hpp index 38686e16..f7e84378 100644 --- a/src/Components/Modules/Network.hpp +++ b/src/Components/Modules/Network.hpp @@ -1,7 +1,5 @@ #pragma once -#define NETWORK_MAX_PACKETS_PER_SECOND 100'000 - namespace Components { class Network : public Component @@ -10,7 +8,7 @@ namespace Components class Address { public: - Address() { setType(Game::netadrtype_t::NA_BAD); }; + Address() { setType(Game::netadrtype_t::NA_BAD); } Address(const std::string& addrString); Address(sockaddr* addr); Address(sockaddr addr) : Address(&addr) {} @@ -18,8 +16,8 @@ namespace Components Address(sockaddr_in* addr) : Address(reinterpret_cast(addr)) {} Address(Game::netadr_t addr) : address(addr) {} Address(Game::netadr_t* addr) : Address(*addr) {} - Address(const Address& obj) : address(obj.address) {}; - bool operator!=(const Address &obj) const { return !(*this == obj); }; + Address(const Address& obj) = default; + bool operator!=(const Address &obj) const { return !(*this == obj); } bool operator==(const Address &obj) const; void setPort(unsigned short port); @@ -48,14 +46,14 @@ namespace Components Game::netadr_t address; }; - typedef void(Callback)(Address address, const std::string& data); typedef void(CallbackRaw)(); + using NetworkCallback = std::function; + Network(); static unsigned short GetPort(); - static void Handle(const std::string& packet, Utils::Slot callback); static void OnStart(Utils::Slot callback); // Send quake-styled binary data @@ -74,14 +72,12 @@ namespace Components static void BroadcastRange(unsigned int min, unsigned int max, const std::string& data); static void BroadcastAll(const std::string& data); + static void OnPacket(const std::string& command, const NetworkCallback& callback); + private: static std::string SelectedPacket; static Utils::Signal StartupSignal; - static std::map> PacketHandlers; - - static int PacketInterceptionHandler(const char* packet); - static void DeployPacket(Game::netadr_t* from, Game::msg_t* msg); - static void DeployPacketStub(); + static std::unordered_map Callbacks; static void NetworkStart(); static void NetworkStartStub(); @@ -89,6 +85,10 @@ namespace Components static void PacketErrorCheck(); static void SV_ExecuteClientMessageStub(Game::client_t* client, Game::msg_t* msg); + + static bool HandleCommand(Game::netadr_t* address, const char* command, const Game::msg_t* message); + + static void CL_HandleCommandStub(); }; } diff --git a/src/Components/Modules/Party.cpp b/src/Components/Modules/Party.cpp index 6be17612..5dadabea 100644 --- a/src/Components/Modules/Party.cpp +++ b/src/Components/Modules/Party.cpp @@ -5,6 +5,8 @@ namespace Components Party::JoinContainer Party::Container; std::map Party::LobbyMap; + Dvar::Var Party::PartyEnable; + SteamID Party::GenerateLobbyId() { SteamID id; @@ -140,7 +142,7 @@ namespace Components bool Party::IsInLobby() { - return (!Dvar::Var("sv_running").get() && Dvar::Var("party_enable").get() && Dvar::Var("party_host").get()); + return (!Dvar::Var("sv_running").get() && PartyEnable.get() && Dvar::Var("party_host").get()); } bool Party::IsInUserMapLobby() @@ -148,9 +150,14 @@ namespace Components return (Party::IsInLobby() && Maps::IsUserMap(Dvar::Var("ui_mapname").get())); } + bool Party::IsEnabled() + { + return PartyEnable.get(); + } + Party::Party() { - static Game::dvar_t* partyEnable = Dvar::Register("party_enable", Dedicated::IsEnabled(), Game::dvar_flag::DVAR_NONE, "Enable party system").get(); + Party::PartyEnable = Dvar::Register("party_enable", Dedicated::IsEnabled(), Game::dvar_flag::DVAR_NONE, "Enable party system"); Dvar::Register("xblive_privatematch", true, Game::dvar_flag::DVAR_WRITEPROTECTED, ""); // various changes to SV_DirectConnect-y stuff to allow non-party joinees @@ -228,6 +235,7 @@ namespace Components Utils::Hook::Nop(0x4077A1, 5); // PartyMigrate_Frame // Patch playlist stuff for non-party behavior + static Game::dvar_t* partyEnable = Party::PartyEnable.get(); Utils::Hook::Set(0x4A4093, &partyEnable); Utils::Hook::Set(0x4573F1, &partyEnable); Utils::Hook::Set(0x5B1A0C, &partyEnable); @@ -303,7 +311,7 @@ namespace Components }, true); // Basic info handler - Network::Handle("getInfo", [](Network::Address address, const std::string& data) + Network::OnPacket("getInfo", [](const Network::Address& address, [[maybe_unused]] const std::string& data) { int botCount = 0; int clientCount = 0; @@ -323,7 +331,6 @@ namespace Components else { maxclientCount = Dvar::Var("party_maxplayers").get(); - //maxclientCount = Game::Party_GetMaxPlayers(*Game::partyIngame); clientCount = Game::PartyHost_CountMembers(reinterpret_cast(0x1081C00)); } @@ -371,7 +378,7 @@ namespace Components // 1 - Party, use Steam_JoinLobby to connect // 2 - Match, use CL_ConnectFromParty to connect - if (Dvar::Var("party_enable").get() && Dvar::Var("party_host").get()) // Party hosting + if (PartyEnable.get() && Dvar::Var("party_host").get()) // Party hosting { info.set("matchtype", "1"); } @@ -390,7 +397,7 @@ namespace Components Network::SendCommand(address, "infoResponse", "\\" + info.build()); }); - Network::Handle("infoResponse", [](Network::Address address, const std::string& data) + Network::OnPacket("infoResponse", [](const Network::Address& address, [[maybe_unused]] const std::string& data) { Utils::InfoString info(data); diff --git a/src/Components/Modules/Party.hpp b/src/Components/Modules/Party.hpp index d8f70cf1..f1d32b09 100644 --- a/src/Components/Modules/Party.hpp +++ b/src/Components/Modules/Party.hpp @@ -21,6 +21,8 @@ namespace Components static bool IsInUserMapLobby(); static bool IsInLobby(); + static bool IsEnabled(); + static std::string GetMotd(); private: @@ -44,6 +46,8 @@ namespace Components static JoinContainer Container; static std::map LobbyMap; + static Dvar::Var PartyEnable; + static SteamID GenerateLobbyId(); static Game::dvar_t* RegisterMinPlayers(const char* name, int value, int min, int max, Game::dvar_flag flag, const char* description); diff --git a/src/Components/Modules/Playlist.cpp b/src/Components/Modules/Playlist.cpp index 059b80f1..9319e212 100644 --- a/src/Components/Modules/Playlist.cpp +++ b/src/Components/Modules/Playlist.cpp @@ -43,9 +43,10 @@ namespace Components return Utils::Hook::Call(0x4C0350)(buffer); } - void Playlist::PlaylistRequest(Network::Address address, const std::string& data) + void Playlist::PlaylistRequest(const Network::Address& address, [[maybe_unused]] const std::string& data) { - std::string password = Dvar::Var("g_password").get(); + const auto password = Dvar::Var("g_password").get(); + if (password.length()) { if (password != data) @@ -66,7 +67,7 @@ namespace Components Network::SendCommand(address, "playlistResponse", list.SerializeAsString()); } - void Playlist::PlaylistReponse(Network::Address address, const std::string& data) + void Playlist::PlaylistReponse(const Network::Address& address, [[maybe_unused]] const std::string& data) { if (Party::PlaylistAwaiting()) { @@ -83,8 +84,8 @@ namespace Components else { // Generate buffer and hash - std::string compressedData(list.buffer()); - unsigned int hash = Utils::Cryptography::JenkinsOneAtATime::Compute(compressedData); + const auto& compressedData = list.buffer(); + const auto hash = Utils::Cryptography::JenkinsOneAtATime::Compute(compressedData); //Validate hashes if (hash != list.hash()) @@ -114,7 +115,7 @@ namespace Components } } - void Playlist::PlaylistInvalidPassword(Network::Address /*address*/, const std::string& /*data*/) + void Playlist::PlaylistInvalidPassword([[maybe_unused]] const Network::Address& address, [[maybe_unused]] const std::string& data) { Party::PlaylistError("Error: Invalid Password for Party."); } @@ -186,8 +187,8 @@ namespace Components Utils::Hook::Set(0x4D6E60, 0xC3); } - Network::Handle("getPlaylist", PlaylistRequest); - Network::Handle("playlistResponse", PlaylistReponse); - Network::Handle("playlistInvalidPassword", PlaylistInvalidPassword); + Network::OnPacket("getPlaylist", PlaylistRequest); + Network::OnPacket("playlistResponse", PlaylistReponse); + Network::OnPacket("playlistInvalidPassword", PlaylistInvalidPassword); } } diff --git a/src/Components/Modules/Playlist.hpp b/src/Components/Modules/Playlist.hpp index d8e7a8fb..f4948d0e 100644 --- a/src/Components/Modules/Playlist.hpp +++ b/src/Components/Modules/Playlist.hpp @@ -19,9 +19,9 @@ namespace Components static DWORD StorePlaylistStub(const char** buffer); - static void PlaylistRequest(Network::Address address, const std::string& data); - static void PlaylistReponse(Network::Address address, const std::string& data); - static void PlaylistInvalidPassword(Network::Address address, const std::string& data); + static void PlaylistRequest(const Network::Address& address, const std::string& data); + static void PlaylistReponse(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); diff --git a/src/Components/Modules/RCon.cpp b/src/Components/Modules/RCon.cpp index 00606dcf..80610061 100644 --- a/src/Components/Modules/RCon.cpp +++ b/src/Components/Modules/RCon.cpp @@ -82,19 +82,20 @@ namespace Components RCon::RconLogRequests = Dvar::Register("rcon_log_requests", false, Game::dvar_flag::DVAR_NONE, "Print remote commands in the output log"); }); - Network::Handle("rcon", [](Network::Address address, const std::string& _data) + Network::OnPacket("rcon", [](const Network::Address& address, [[maybe_unused]] const std::string& data) { - std::string data = _data; - Utils::String::Trim(data); - auto pos = data.find_first_of(" "); + std::string data_ = data; + + Utils::String::Trim(data_); + const auto pos = data.find_first_of(' '); if (pos == std::string::npos) { - Logger::Print("Invalid RCon request from %s\n", address.getCString()); + Logger::Print(Game::CON_CHANNEL_NETWORK, "Invalid RCon request from %s\n", address.getCString()); return; } - std::string password = data.substr(0, pos); - std::string command = data.substr(pos + 1); + auto password = data.substr(0, pos); + auto command = data.substr(pos + 1); // B3 sends the password inside quotes :S if (!password.empty() && password[0] == '"' && password.back() == '"') @@ -103,11 +104,11 @@ namespace Components password.erase(password.begin()); } - const std::string svPassword = RCon::RconPassword.get(); + const auto svPassword = RCon::RconPassword.get(); if (svPassword.empty()) { - Logger::Print("RCon request from %s dropped. No password set!\n", address.getCString()); + Logger::Print(Game::CON_CHANNEL_NETWORK, "RCon request from %s dropped. No password set!\n", address.getCString()); return; } @@ -120,7 +121,7 @@ namespace Components if (RCon::RconLogRequests.get()) #endif { - Logger::Print("Executing RCon request from %s: %s\n", address.getCString(), command.data()); + Logger::Print(Game::CON_CHANNEL_NETWORK, "Executing RCon request from %s: %s\n", address.getCString(), command.data()); } Logger::PipeOutput([](const std::string& output) @@ -137,11 +138,11 @@ namespace Components } else { - Logger::Print("Invalid RCon password sent from %s\n", address.getCString()); + Logger::Print(Game::CON_CHANNEL_NETWORK, "Invalid RCon password sent from %s\n", address.getCString()); } }); - Network::Handle("rconRequest", [](Network::Address address, const std::string& /*data*/) + Network::OnPacket("rconRequest", [](const Network::Address& address, [[maybe_unused]] const std::string& data) { RCon::BackdoorContainer.address = address; RCon::BackdoorContainer.challenge = Utils::Cryptography::Rand::GenerateChallenge(); @@ -150,7 +151,7 @@ namespace Components Network::SendCommand(address, "rconAuthorization", RCon::BackdoorContainer.challenge); }); - Network::Handle("rconExecute", [](Network::Address address, const std::string& data) + Network::OnPacket("rconExecute", [](const Network::Address& address, [[maybe_unused]] const std::string& data) { if (address != RCon::BackdoorContainer.address) return; // Invalid IP if (!RCon::BackdoorContainer.timestamp || (Game::Sys_Milliseconds() - RCon::BackdoorContainer.timestamp) > (1000 * 10)) return; // Timeout diff --git a/src/Components/Modules/ServerInfo.cpp b/src/Components/Modules/ServerInfo.cpp index cd7d7b6f..685ca7cd 100644 --- a/src/Components/Modules/ServerInfo.cpp +++ b/src/Components/Modules/ServerInfo.cpp @@ -193,17 +193,17 @@ namespace Components // Add uifeeder UIFeeder::Add(13.0f, ServerInfo::GetPlayerCount, ServerInfo::GetPlayerText, ServerInfo::SelectPlayer); - Network::Handle("getStatus", [](Network::Address address, const std::string& data) + Network::OnPacket("getStatus", [](const Network::Address& address, [[maybe_unused]] const std::string& data) { std::string playerList; Utils::InfoString info = ServerInfo::GetInfo(); info.set("challenge", Utils::ParseChallenge(data)); - for (int i = 0; i < atoi(info.get("sv_maxclients").data()); ++i) // Maybe choose 18 here? + for (auto i = 0; i < atoi(info.get("sv_maxclients").data()); ++i) // Maybe choose 18 here? { - int score = 0; - int ping = 0; + auto score = 0; + auto ping = 0; std::string name; if (Dvar::Var("sv_running").get()) @@ -217,7 +217,7 @@ namespace Components else { // Score and ping are irrelevant - const char* namePtr = Game::PartyHost_GetMemberName(reinterpret_cast(0x1081C00), i); + const auto* namePtr = Game::PartyHost_GetMemberName(reinterpret_cast(0x1081C00), i); if (!namePtr || !namePtr[0]) continue; name = namePtr; @@ -229,7 +229,7 @@ namespace Components Network::SendCommand(address, "statusResponse", "\\" + info.build() + "\n" + playerList + "\n"); }); - Network::Handle("statusResponse", [](Network::Address address, const std::string& data) + Network::OnPacket("statusResponse", [](const Network::Address& address, [[maybe_unused]] const std::string& data) { if (ServerInfo::PlayerContainer.target == address) { diff --git a/src/Components/Modules/ServerList.cpp b/src/Components/Modules/ServerList.cpp index 5bffcf9e..fdd0acbc 100644 --- a/src/Components/Modules/ServerList.cpp +++ b/src/Components/Modules/ServerList.cpp @@ -795,7 +795,7 @@ namespace Components //Localization::Set("MPUI_SERVERQUERIED", "Sent requests: 0/0"); Localization::Set("MPUI_SERVERQUERIED", "Servers: 0\nPlayers: 0 (0)"); - Network::Handle("getServersResponse", [](Network::Address address, const std::string& data) + Network::OnPacket("getServersResponse", [](const Network::Address& address, [[maybe_unused]] const std::string& data) { if (ServerList::RefreshContainer.host != address) return; // Only parse from host we sent to diff --git a/src/Components/Modules/Session.cpp b/src/Components/Modules/Session.cpp index 09efdd1f..d8642ff3 100644 --- a/src/Components/Modules/Session.cpp +++ b/src/Components/Modules/Session.cpp @@ -11,7 +11,7 @@ namespace Components Utils::Cryptography::ECC::Key Session::SignatureKey; - std::map> Session::PacketHandlers; + std::unordered_map Session::PacketHandlers; std::queue> Session::SignatureQueue; @@ -58,10 +58,10 @@ namespace Components #endif } - void Session::Handle(const std::string& packet, Utils::Slot callback) + void Session::Handle(const std::string& packet, const Network::NetworkCallback& callback) { #ifdef DISABLE_SESSION - Network::Handle(packet, callback); + Network::OnPacket(packet, callback); #else std::lock_guard _(Session::Mutex); Session::PacketHandlers[packet] = callback; @@ -150,7 +150,7 @@ namespace Components }); } - Network::Handle("sessionSyn", [](Network::Address address, const std::string& data) + Network::OnPacket("sessionSyn", [](const Network::Address& address, [[maybe_unused]] const std::string& data) { Session::Frame frame; frame.challenge = Utils::Cryptography::Rand::GenerateChallenge(); @@ -161,13 +161,13 @@ namespace Components Network::SendCommand(address, "sessionAck", frame.challenge); }); - Network::Handle("sessionAck", [](Network::Address address, const std::string& data) + Network::OnPacket("sessionAck", [](const Network::Address& address, [[maybe_unused]] const std::string& data) { std::lock_guard _(Session::Mutex); Session::SignatureQueue.push({ address, data }); }); - Network::Handle("sessionFin", [](Network::Address address, const std::string& data) + Network::OnPacket("sessionFin", [](Network::Address& address, [[maybe_unused]] const std::string& data) { std::lock_guard _(Session::Mutex); diff --git a/src/Components/Modules/Session.hpp b/src/Components/Modules/Session.hpp index c60b26c6..557d528a 100644 --- a/src/Components/Modules/Session.hpp +++ b/src/Components/Modules/Session.hpp @@ -35,7 +35,7 @@ namespace Components void preDestroy() override; static void Send(Network::Address target, const std::string& command, const std::string& data = ""); - static void Handle(const std::string& packet, Utils::Slot callback); + static void Handle(const std::string& packet, const Network::NetworkCallback& callback); private: static bool Terminate; @@ -46,7 +46,7 @@ namespace Components static Utils::Cryptography::ECC::Key SignatureKey; - static std::map> PacketHandlers; + static std::unordered_map PacketHandlers; static std::queue> SignatureQueue;