Little Itsy Bitsy TCP fixes (#118)

This commit is contained in:
Lion 2024-09-23 21:46:11 +02:00 committed by GitHub
commit 4bedfc8e96
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 53 additions and 34 deletions

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 <memory>
#include <zlib.h> #include <zlib.h>
#if defined(_WIN32) #if defined(_WIN32)
#include <winsock2.h> #include <winsock2.h>
@ -124,17 +125,17 @@ void NetReset() {
UlStatus = "Ulstart"; UlStatus = "Ulstart";
MStatus = " "; MStatus = " ";
if (UDPSock != (SOCKET)(-1)) { if (UDPSock != (SOCKET)(-1)) {
debug("Terminating UDP Socket : " + std::to_string(TCPSock)); debug("Terminating UDP Socket: " + std::to_string(TCPSock));
KillSocket(UDPSock); KillSocket(UDPSock);
} }
UDPSock = -1; UDPSock = -1;
if (TCPSock != (SOCKET)(-1)) { if (TCPSock != (SOCKET)(-1)) {
debug("Terminating TCP Socket : " + std::to_string(TCPSock)); debug("Terminating TCP Socket: " + std::to_string(TCPSock));
KillSocket(TCPSock); KillSocket(TCPSock);
} }
TCPSock = -1; TCPSock = -1;
if (GSocket != (SOCKET)(-1)) { if (GSocket != (SOCKET)(-1)) {
debug("Terminating GTCP Socket : " + std::to_string(GSocket)); debug("Terminating GTCP Socket: " + std::to_string(GSocket));
KillSocket(GSocket); KillSocket(GSocket);
} }
GSocket = -1; GSocket = -1;
@ -234,6 +235,8 @@ void NetMain(const std::string& IP, int Port) {
} }
void TCPGameServer(const std::string& IP, int Port) { void TCPGameServer(const std::string& IP, int Port) {
GSocket = SetupListener(); GSocket = SetupListener();
std::unique_ptr<std::thread> ClientThread {};
std::unique_ptr<std::thread> NetMainThread {};
while (!TCPTerminate && GSocket != -1) { while (!TCPTerminate && GSocket != -1) {
debug("MAIN LOOP OF GAME SERVER"); debug("MAIN LOOP OF GAME SERVER");
GConnected = false; GConnected = false;
@ -245,8 +248,7 @@ void TCPGameServer(const std::string& IP, int Port) {
break; break;
} }
if (CServer) { if (CServer) {
std::thread Client(TCPClientMain, IP, Port); ClientThread = std::make_unique<std::thread>(TCPClientMain, IP, Port);
Client.detach();
} }
CSocket = accept(GSocket, nullptr, nullptr); CSocket = accept(GSocket, nullptr, nullptr);
if (CSocket == -1) { if (CSocket == -1) {
@ -256,8 +258,7 @@ void TCPGameServer(const std::string& IP, int Port) {
debug("(Proxy) Game Connected!"); debug("(Proxy) Game Connected!");
GConnected = true; GConnected = true;
if (CServer) { if (CServer) {
std::thread t1(NetMain, IP, Port); NetMainThread = std::make_unique<std::thread>(NetMain, IP, Port);
t1.detach();
CServer = false; CServer = false;
} }
int32_t Size, Temp, Rcv; int32_t Size, Temp, Rcv;
@ -300,6 +301,16 @@ void TCPGameServer(const std::string& IP, int Port) {
TCPTerminate = true; TCPTerminate = true;
GConnected = false; GConnected = false;
Terminate = true; Terminate = true;
if (ClientThread) {
debug("Waiting for client thread");
ClientThread->join();
debug("Client thread done");
}
if (NetMainThread) {
debug("Waiting for net main thread");
NetMainThread->join();
debug("Net main thread done");
}
if (CSocket != SOCKET_ERROR) if (CSocket != SOCKET_ERROR)
KillSocket(CSocket); KillSocket(CSocket);
debug("END OF GAME SERVER"); debug("END OF GAME SERVER");

View File

@ -7,6 +7,7 @@
/// ///
#include "Network/network.hpp" #include "Network/network.hpp"
#include "Zlib/Compressor.h" #include "Zlib/Compressor.h"
#include <stdexcept>
#if defined(_WIN32) #if defined(_WIN32)
#include <ws2tcpip.h> #include <ws2tcpip.h>
@ -50,9 +51,13 @@ void SendLarge(std::string Data) {
void UDPParser(std::string_view Packet) { void UDPParser(std::string_view Packet) {
if (Packet.substr(0, 4) == "ABG:") { if (Packet.substr(0, 4) == "ABG:") {
auto substr = Packet.substr(4); auto substr = Packet.substr(4);
auto res = DeComp(std::span<const char>(substr.data(), substr.size())); try {
std::string DeCompPacket = std::string(res.data(), res.size()); auto res = DeComp(std::span<const char>(substr.data(), substr.size()));
ServerParser(DeCompPacket); std::string DeCompPacket = std::string(res.data(), res.size());
ServerParser(DeCompPacket);
} catch (const std::runtime_error& err) {
error("Error in decompression of UDP, ignoring");
}
} else { } else {
ServerParser(Packet); ServerParser(Packet);
} }
@ -92,8 +97,11 @@ void UDPClientMain(const std::string& IP, int Port) {
GameSend("P" + std::to_string(ClientID)); GameSend("P" + std::to_string(ClientID));
TCPSend("H", TCPSock); TCPSend("H", TCPSock);
UDPSend("p"); UDPSend("p");
while (!Terminate) debug("Starting UDP receive loop");
while (!Terminate) {
UDPRcv(); UDPRcv();
}
debug("UDP receive loop done");
KillSocket(UDPSock); KillSocket(UDPSock);
WSACleanup(); WSACleanup();
} }

View File

@ -82,39 +82,39 @@ std::string TCPRcv(SOCKET Sock) {
UUl("Invalid Socket"); UUl("Invalid Socket");
return ""; return "";
} }
int32_t Header, BytesRcv = 0, Temp; int32_t Header, Temp;
std::vector<char> Data(sizeof(Header)); std::vector<char> Data(sizeof(Header));
do { Temp = recv(Sock, Data.data(), sizeof(Header), MSG_WAITALL);
Temp = recv(Sock, &Data[BytesRcv], 4 - BytesRcv, 0); if (!CheckBytes(Temp)) {
if (!CheckBytes(Temp)) { UUl("Socket Closed Code 3");
UUl("Socket Closed Code 3"); return "";
return ""; }
} memcpy(&Header, Data.data(), sizeof(Header));
BytesRcv += Temp;
} while (BytesRcv < 4);
memcpy(&Header, &Data[0], sizeof(Header));
if (!CheckBytes(BytesRcv)) { if (!CheckBytes(Temp)) {
UUl("Socket Closed Code 4"); UUl("Socket Closed Code 4");
return ""; return "";
} }
Data.resize(Header);
BytesRcv = 0; Data.resize(Header, 0);
do { Temp = recv(Sock, Data.data(), Header, MSG_WAITALL);
Temp = recv(Sock, &Data[BytesRcv], Header - BytesRcv, 0); if (!CheckBytes(Temp)) {
if (!CheckBytes(Temp)) { UUl("Socket Closed Code 5");
UUl("Socket Closed Code 5"); return "";
return ""; }
}
BytesRcv += Temp;
} while (BytesRcv < Header);
std::string Ret(Data.data(), Header); std::string Ret(Data.data(), Header);
if (Ret.substr(0, 4) == "ABG:") { if (Ret.substr(0, 4) == "ABG:") {
auto substr = Ret.substr(4); auto substr = Ret.substr(4);
auto res = DeComp(std::span<char>(substr.data(), substr.size())); try {
Ret = std::string(res.data(), res.size()); auto res = DeComp(std::span<char>(substr.data(), substr.size()));
Ret = std::string(res.data(), res.size());
} catch (const std::runtime_error& err) {
// this happens e.g. when we're out of memory, or when we get incomplete data
error("Decompression failed");
return "";
}
} }
#ifdef DEBUG #ifdef DEBUG