From fc454cd11e26b9eb8ad9f63c05f1ecfef8f90a17 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Wed, 19 Jun 2024 15:53:49 +0200 Subject: [PATCH 1/4] avoid creating a thread every packet --- src/Network/Core.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index c65f257..0c51f88 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -230,8 +230,7 @@ void GameHandler(SOCKET Client) { if (Temp < 1) break; - std::thread Respond(Parse, Ret, Client); - Respond.detach(); + Parse(Ret, Client); } while (Temp > 0); if (Temp == 0) { debug("(Core) Connection closing"); From 17e887442cfea82544539e22d180748c4e920bd6 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Wed, 19 Jun 2024 16:18:11 +0200 Subject: [PATCH 2/4] avoid a substr() which costs us ~20% of runtime performance --- include/Network/network.hpp | 4 ++-- include/Zlib/Compressor.h | 2 +- src/Compressor.cpp | 4 ++-- src/Network/GlobalHandler.cpp | 14 +++++++++----- src/Network/VehicleData.cpp | 12 +++++++----- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/include/Network/network.hpp b/include/Network/network.hpp index 6743966..5c0b2b3 100644 --- a/include/Network/network.hpp +++ b/include/Network/network.hpp @@ -41,12 +41,12 @@ int KillSocket(uint64_t Dead); void UUl(const std::string& R); void UDPSend(std::string Data); bool CheckBytes(int32_t Bytes); -void GameSend(std::string Data); +void GameSend(std::string_view Data); void SendLarge(std::string Data); std::string TCPRcv(uint64_t Sock); void SyncResources(uint64_t TCPSock); std::string GetAddr(const std::string& IP); -void ServerParser(const std::string& Data); +void ServerParser(std::string_view Data); std::string Login(const std::string& fields); void TCPSend(const std::string& Data, uint64_t Sock); void TCPClientMain(const std::string& IP, int Port); diff --git a/include/Zlib/Compressor.h b/include/Zlib/Compressor.h index 0a1d815..17222ad 100644 --- a/include/Zlib/Compressor.h +++ b/include/Zlib/Compressor.h @@ -8,4 +8,4 @@ #pragma once #include std::string Comp(std::string Data); -std::string DeComp(std::string Compressed); +std::string DeComp(std::string_view Compressed); diff --git a/src/Compressor.cpp b/src/Compressor.cpp index ea3320f..cf5b149 100644 --- a/src/Compressor.cpp +++ b/src/Compressor.cpp @@ -34,7 +34,7 @@ std::string Comp(std::string Data) { delete[] C; return Ret; } -std::string DeComp(std::string Compressed) { +std::string DeComp(std::string_view Compressed) { char* C = new char[Biggest]; memset(C, 0, Biggest); z_stream infstream; @@ -54,4 +54,4 @@ std::string DeComp(std::string Compressed) { memcpy(&Ret[0], C, TO); delete[] C; return Ret; -} \ No newline at end of file +} diff --git a/src/Network/GlobalHandler.cpp b/src/Network/GlobalHandler.cpp index 2b53584..46f6576 100644 --- a/src/Network/GlobalHandler.cpp +++ b/src/Network/GlobalHandler.cpp @@ -55,13 +55,12 @@ bool CheckBytes(uint32_t Bytes) { return true; } -void GameSend(std::string Data) { +void GameSend(std::string_view Data) { static std::mutex Lock; std::scoped_lock Guard(Lock); if (TCPTerminate || !GConnected || CSocket == -1) return; int32_t Size, Temp, Sent; - Data += '\n'; Size = int32_t(Data.size()); Sent = 0; #ifdef DEBUG @@ -77,6 +76,11 @@ void GameSend(std::string Data) { return; Sent += Temp; } while (Sent < Size); + // send separately to avoid an allocation for += "\n" + Temp = send(CSocket, "\n", 1, 0); + if (!CheckBytes(Temp)) { + return; + } } void ServerSend(std::string Data, bool Rel) { if (Terminate || Data.empty()) @@ -191,7 +195,7 @@ void AutoPing() { } } int ClientID = -1; -void ParserAsync(const std::string& Data) { +void ParserAsync(std::string_view Data) { if (Data.empty()) return; char Code = Data.at(0), SubCode = 0; @@ -214,7 +218,7 @@ void ParserAsync(const std::string& Data) { } GameSend(Data); } -void ServerParser(const std::string& Data) { +void ServerParser(std::string_view Data) { ParserAsync(Data); } void NetMain(const std::string& IP, int Port) { @@ -296,4 +300,4 @@ void TCPGameServer(const std::string& IP, int Port) { if (CSocket != SOCKET_ERROR) KillSocket(CSocket); debug("END OF GAME SERVER"); -} \ No newline at end of file +} diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index 4f1269f..baf9ba5 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -21,6 +21,7 @@ #endif #include "Logger.h" +#include #include #include @@ -48,7 +49,7 @@ void SendLarge(std::string Data) { TCPSend(Data, TCPSock); } -void UDPParser(std::string Packet) { +void UDPParser(std::string_view Packet) { if (Packet.substr(0, 4) == "ABG:") { Packet = DeComp(Packet.substr(4)); } @@ -62,13 +63,14 @@ void UDPRcv() { socklen_t clientLength = sizeof(FromServer); #endif ZeroMemory(&FromServer, clientLength); - std::string Ret(10240, 0); + std::array Ret {}; + Ret.fill(0); if (UDPSock == -1) return; - int32_t Rcv = recvfrom(UDPSock, &Ret[0], 10240, 0, (sockaddr*)&FromServer, &clientLength); + int32_t Rcv = recvfrom(UDPSock, Ret.data(), Ret.size(), 0, (sockaddr*)&FromServer, &clientLength); if (Rcv == SOCKET_ERROR) return; - UDPParser(Ret.substr(0, Rcv)); + UDPParser(std::string_view(Ret.data(), Rcv)); } void UDPClientMain(const std::string& IP, int Port) { #ifdef _WIN32 @@ -92,4 +94,4 @@ void UDPClientMain(const std::string& IP, int Port) { UDPRcv(); KillSocket(UDPSock); WSACleanup(); -} \ No newline at end of file +} From 8b0f4f99f6d4e1b20d0dedab7bc3a64d61e17b3a Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Wed, 19 Jun 2024 16:53:17 +0200 Subject: [PATCH 3/4] use thread_local static buffer to receive into, null term manually --- src/Network/VehicleData.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index baf9ba5..4d3a9ef 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -63,13 +63,13 @@ void UDPRcv() { socklen_t clientLength = sizeof(FromServer); #endif ZeroMemory(&FromServer, clientLength); - std::array Ret {}; - Ret.fill(0); + static thread_local std::array Ret {}; if (UDPSock == -1) return; - int32_t Rcv = recvfrom(UDPSock, Ret.data(), Ret.size(), 0, (sockaddr*)&FromServer, &clientLength); + int32_t Rcv = recvfrom(UDPSock, Ret.data(), Ret.size() - 1, 0, (sockaddr*)&FromServer, &clientLength); if (Rcv == SOCKET_ERROR) return; + Ret[Rcv] = 0; UDPParser(std::string_view(Ret.data(), Rcv)); } void UDPClientMain(const std::string& IP, int Port) { From d32da036bc501a21e87053fdf87950c09f3cd019 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Fri, 21 Jun 2024 17:30:47 +0200 Subject: [PATCH 4/4] fix mod name bug --- src/Network/Resources.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Network/Resources.cpp b/src/Network/Resources.cpp index e3d8049..f32c263 100644 --- a/src/Network/Resources.cpp +++ b/src/Network/Resources.cpp @@ -296,13 +296,14 @@ void SyncResources(SOCKET Sock) { if (!fs::exists(GetGamePath() + "mods/multiplayer")) { fs::create_directories(GetGamePath() + "mods/multiplayer"); } - auto name = GetGamePath() + "mods/multiplayer" + a.substr(a.find_last_of('/')); + auto modname = a.substr(a.find_last_of('/')); #if defined(__linux__) // Linux version of the game doesnt support uppercase letters in mod names - for (char& c : name) { + for (char& c : modname) { c = ::tolower(c); } #endif + auto name = GetGamePath() + "mods/multiplayer" + modname; auto tmp_name = name + ".tmp"; fs::copy_file(a, tmp_name, fs::copy_options::overwrite_existing); fs::rename(tmp_name, name);