From f2b34543f9a5511214dfaa5389d737c1633a6577 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Sat, 22 Jun 2024 22:48:00 +0200 Subject: [PATCH] switch to compression with limit at 30 MB --- include/Zlib/Compressor.h | 8 +-- src/Compressor.cpp | 91 ++++++++++++++++++----------------- src/Network/GlobalHandler.cpp | 5 +- src/Network/VehicleData.cpp | 14 +++--- src/Network/VehicleEvent.cpp | 4 +- 5 files changed, 68 insertions(+), 54 deletions(-) diff --git a/include/Zlib/Compressor.h b/include/Zlib/Compressor.h index 0a1d815..a3c383f 100644 --- a/include/Zlib/Compressor.h +++ b/include/Zlib/Compressor.h @@ -6,6 +6,8 @@ /// Created by Anonymous275 on 7/24/2020 /// #pragma once -#include -std::string Comp(std::string Data); -std::string DeComp(std::string Compressed); +#include +#include + +std::vector Comp(std::span input); +std::vector DeComp(std::span input); diff --git a/src/Compressor.cpp b/src/Compressor.cpp index ea3320f..c8bcf2e 100644 --- a/src/Compressor.cpp +++ b/src/Compressor.cpp @@ -6,52 +6,57 @@ /// Created by Anonymous275 on 7/15/2020 /// -#include +#include "Logger.h" +#include +#include +#include #include #ifdef __linux__ #include #endif -#define Biggest 30000 -std::string Comp(std::string Data) { - char* C = new char[Biggest]; - memset(C, 0, Biggest); - z_stream defstream; - defstream.zalloc = Z_NULL; - defstream.zfree = Z_NULL; - defstream.opaque = Z_NULL; - defstream.avail_in = (uInt)Data.length(); - defstream.next_in = (Bytef*)&Data[0]; - defstream.avail_out = Biggest; - defstream.next_out = reinterpret_cast(C); - deflateInit(&defstream, Z_BEST_COMPRESSION); - deflate(&defstream, Z_SYNC_FLUSH); - deflate(&defstream, Z_FINISH); - deflateEnd(&defstream); - int TO = defstream.total_out; - std::string Ret(TO, 0); - memcpy(&Ret[0], C, TO); - delete[] C; - return Ret; +std::vector Comp(std::span input) { + auto max_size = compressBound(input.size()); + std::vector output(max_size); + uLongf output_size = output.size(); + int res = compress( + reinterpret_cast(output.data()), + &output_size, + reinterpret_cast(input.data()), + static_cast(input.size())); + if (res != Z_OK) { + error("zlib compress() failed: " + std::to_string(res)); + throw std::runtime_error("zlib compress() failed"); + } + debug("zlib compressed " + std::to_string(input.size()) + " B to " + std::to_string(output_size) + " B"); + output.resize(output_size); + return output; +} + +std::vector DeComp(std::span input) { + std::vector output_buffer(std::min(input.size() * 5, 15 * 1024 * 1024)); + + uLongf output_size = output_buffer.size(); + + while (true) { + int res = uncompress( + reinterpret_cast(output_buffer.data()), + &output_size, + reinterpret_cast(input.data()), + static_cast(input.size())); + if (res == Z_BUF_ERROR) { + if (output_buffer.size() > 30 * 1024 * 1024) { + throw std::runtime_error("decompressed packet size of 30 MB exceeded"); + } + debug("zlib uncompress() failed, trying with 2x buffer size of " + std::to_string(output_buffer.size() * 2)); + output_buffer.resize(output_buffer.size() * 2); + output_size = output_buffer.size(); + } else if (res != Z_OK) { + error("zlib uncompress() failed: " + std::to_string(res)); + throw std::runtime_error("zlib uncompress() failed"); + } else if (res == Z_OK) { + break; + } + } output_buffer.resize(output_size); + return output_buffer; } -std::string DeComp(std::string Compressed) { - char* C = new char[Biggest]; - memset(C, 0, Biggest); - z_stream infstream; - infstream.zalloc = Z_NULL; - infstream.zfree = Z_NULL; - infstream.opaque = Z_NULL; - infstream.avail_in = Biggest; - infstream.next_in = (Bytef*)(&Compressed[0]); - infstream.avail_out = Biggest; - infstream.next_out = (Bytef*)(C); - inflateInit(&infstream); - inflate(&infstream, Z_SYNC_FLUSH); - inflate(&infstream, Z_FINISH); - inflateEnd(&infstream); - int TO = infstream.total_out; - std::string Ret(TO, 0); - 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..7011f01 100644 --- a/src/Network/GlobalHandler.cpp +++ b/src/Network/GlobalHandler.cpp @@ -6,6 +6,7 @@ /// Created by Anonymous275 on 7/25/2020 /// #include "Network/network.hpp" +#include #if defined(_WIN32) #include #include @@ -93,6 +94,8 @@ void ServerSend(std::string Data, bool Rel) { Ack = true; if (C == 'N' || C == 'W' || C == 'Y' || C == 'V' || C == 'E' || C == 'C') Rel = true; + if (compressBound(Data.size()) > 1024) + Rel = true; if (Ack || Rel) { if (Ack || DLen > 1000) SendLarge(Data); @@ -296,4 +299,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..305e86a 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -31,8 +31,8 @@ void UDPSend(std::string Data) { if (ClientID == -1 || UDPSock == -1) return; if (Data.length() > 400) { - std::string CMP(Comp(Data)); - Data = "ABG:" + CMP; + auto res = Comp(std::span(Data.data(), Data.size())); + Data = "ABG:" + std::string(res.data(), res.size()); } std::string Packet = char(ClientID + 1) + std::string(":") + Data; int sendOk = sendto(UDPSock, Packet.c_str(), int(Packet.size()), 0, (sockaddr*)ToServer, sizeof(*ToServer)); @@ -42,15 +42,17 @@ void UDPSend(std::string Data) { void SendLarge(std::string Data) { if (Data.length() > 400) { - std::string CMP(Comp(Data)); - Data = "ABG:" + CMP; + auto res = Comp(std::span(Data.data(), Data.size())); + Data = "ABG:" + std::string(res.data(), res.size()); } TCPSend(Data, TCPSock); } void UDPParser(std::string Packet) { if (Packet.substr(0, 4) == "ABG:") { - Packet = DeComp(Packet.substr(4)); + auto substr = Packet.substr(4); + auto res = DeComp(std::span(substr.data(), substr.size())); + Packet = std::string(res.data(), res.size()); } ServerParser(Packet); } @@ -92,4 +94,4 @@ void UDPClientMain(const std::string& IP, int Port) { UDPRcv(); KillSocket(UDPSock); WSACleanup(); -} \ No newline at end of file +} diff --git a/src/Network/VehicleEvent.cpp b/src/Network/VehicleEvent.cpp index d60f669..c02a572 100644 --- a/src/Network/VehicleEvent.cpp +++ b/src/Network/VehicleEvent.cpp @@ -112,7 +112,9 @@ std::string TCPRcv(SOCKET Sock) { std::string Ret(Data.data(), Header); if (Ret.substr(0, 4) == "ABG:") { - Ret = DeComp(Ret.substr(4)); + auto substr = Ret.substr(4); + auto res = DeComp(std::span(substr.data(), substr.size())); + Ret = std::string(res.data(), res.size()); } #ifdef DEBUG