switch to compression with limit at 30 MB

This commit is contained in:
Lion Kortlepel 2024-06-22 22:48:00 +02:00
parent e0e2607632
commit f2b34543f9
No known key found for this signature in database
GPG Key ID: 4322FF2B4C71259B
5 changed files with 68 additions and 54 deletions

View File

@ -6,6 +6,8 @@
/// Created by Anonymous275 on 7/24/2020 /// Created by Anonymous275 on 7/24/2020
/// ///
#pragma once #pragma once
#include <string> #include <span>
std::string Comp(std::string Data); #include <vector>
std::string DeComp(std::string Compressed);
std::vector<char> Comp(std::span<char> input);
std::vector<char> DeComp(std::span<char> input);

View File

@ -6,52 +6,57 @@
/// Created by Anonymous275 on 7/15/2020 /// Created by Anonymous275 on 7/15/2020
/// ///
#include <iostream> #include "Logger.h"
#include <span>
#include <vector>
#include <zconf.h>
#include <zlib.h> #include <zlib.h>
#ifdef __linux__ #ifdef __linux__
#include <cstring> #include <cstring>
#endif #endif
#define Biggest 30000 std::vector<char> Comp(std::span<char> input) {
std::string Comp(std::string Data) { auto max_size = compressBound(input.size());
char* C = new char[Biggest]; std::vector<char> output(max_size);
memset(C, 0, Biggest); uLongf output_size = output.size();
z_stream defstream; int res = compress(
defstream.zalloc = Z_NULL; reinterpret_cast<Bytef*>(output.data()),
defstream.zfree = Z_NULL; &output_size,
defstream.opaque = Z_NULL; reinterpret_cast<Bytef*>(input.data()),
defstream.avail_in = (uInt)Data.length(); static_cast<uLongf>(input.size()));
defstream.next_in = (Bytef*)&Data[0]; if (res != Z_OK) {
defstream.avail_out = Biggest; error("zlib compress() failed: " + std::to_string(res));
defstream.next_out = reinterpret_cast<Bytef*>(C); throw std::runtime_error("zlib compress() failed");
deflateInit(&defstream, Z_BEST_COMPRESSION); }
deflate(&defstream, Z_SYNC_FLUSH); debug("zlib compressed " + std::to_string(input.size()) + " B to " + std::to_string(output_size) + " B");
deflate(&defstream, Z_FINISH); output.resize(output_size);
deflateEnd(&defstream); return output;
int TO = defstream.total_out; }
std::string Ret(TO, 0);
memcpy(&Ret[0], C, TO); std::vector<char> DeComp(std::span<char> input) {
delete[] C; std::vector<char> output_buffer(std::min<size_t>(input.size() * 5, 15 * 1024 * 1024));
return Ret;
uLongf output_size = output_buffer.size();
while (true) {
int res = uncompress(
reinterpret_cast<Bytef*>(output_buffer.data()),
&output_size,
reinterpret_cast<const Bytef*>(input.data()),
static_cast<uLongf>(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;
}

View File

@ -6,6 +6,7 @@
/// Created by Anonymous275 on 7/25/2020 /// Created by Anonymous275 on 7/25/2020
/// ///
#include "Network/network.hpp" #include "Network/network.hpp"
#include <zlib.h>
#if defined(_WIN32) #if defined(_WIN32)
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
@ -93,6 +94,8 @@ void ServerSend(std::string Data, bool Rel) {
Ack = true; Ack = true;
if (C == 'N' || C == 'W' || C == 'Y' || C == 'V' || C == 'E' || C == 'C') if (C == 'N' || C == 'W' || C == 'Y' || C == 'V' || C == 'E' || C == 'C')
Rel = true; Rel = true;
if (compressBound(Data.size()) > 1024)
Rel = true;
if (Ack || Rel) { if (Ack || Rel) {
if (Ack || DLen > 1000) if (Ack || DLen > 1000)
SendLarge(Data); SendLarge(Data);
@ -296,4 +299,4 @@ void TCPGameServer(const std::string& IP, int Port) {
if (CSocket != SOCKET_ERROR) if (CSocket != SOCKET_ERROR)
KillSocket(CSocket); KillSocket(CSocket);
debug("END OF GAME SERVER"); debug("END OF GAME SERVER");
} }

View File

@ -31,8 +31,8 @@ void UDPSend(std::string Data) {
if (ClientID == -1 || UDPSock == -1) if (ClientID == -1 || UDPSock == -1)
return; return;
if (Data.length() > 400) { if (Data.length() > 400) {
std::string CMP(Comp(Data)); auto res = Comp(std::span<char>(Data.data(), Data.size()));
Data = "ABG:" + CMP; Data = "ABG:" + std::string(res.data(), res.size());
} }
std::string Packet = char(ClientID + 1) + std::string(":") + Data; std::string Packet = char(ClientID + 1) + std::string(":") + Data;
int sendOk = sendto(UDPSock, Packet.c_str(), int(Packet.size()), 0, (sockaddr*)ToServer, sizeof(*ToServer)); 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) { void SendLarge(std::string Data) {
if (Data.length() > 400) { if (Data.length() > 400) {
std::string CMP(Comp(Data)); auto res = Comp(std::span<char>(Data.data(), Data.size()));
Data = "ABG:" + CMP; Data = "ABG:" + std::string(res.data(), res.size());
} }
TCPSend(Data, TCPSock); TCPSend(Data, TCPSock);
} }
void UDPParser(std::string Packet) { void UDPParser(std::string Packet) {
if (Packet.substr(0, 4) == "ABG:") { if (Packet.substr(0, 4) == "ABG:") {
Packet = DeComp(Packet.substr(4)); auto substr = Packet.substr(4);
auto res = DeComp(std::span<char>(substr.data(), substr.size()));
Packet = std::string(res.data(), res.size());
} }
ServerParser(Packet); ServerParser(Packet);
} }
@ -92,4 +94,4 @@ void UDPClientMain(const std::string& IP, int Port) {
UDPRcv(); UDPRcv();
KillSocket(UDPSock); KillSocket(UDPSock);
WSACleanup(); WSACleanup();
} }

View File

@ -112,7 +112,9 @@ std::string TCPRcv(SOCKET Sock) {
std::string Ret(Data.data(), Header); std::string Ret(Data.data(), Header);
if (Ret.substr(0, 4) == "ABG:") { if (Ret.substr(0, 4) == "ABG:") {
Ret = DeComp(Ret.substr(4)); auto substr = Ret.substr(4);
auto res = DeComp(std::span<char>(substr.data(), substr.size()));
Ret = std::string(res.data(), res.size());
} }
#ifdef DEBUG #ifdef DEBUG