From 7b733bf8eb639edb575a9e4b95c4757533863df4 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Thu, 27 Jun 2024 09:34:52 +0200 Subject: [PATCH 01/29] temporarily set dev to true always --- src/Startup.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Startup.cpp b/src/Startup.cpp index 7289d88e..835c2dc9 100644 --- a/src/Startup.cpp +++ b/src/Startup.cpp @@ -27,7 +27,7 @@ #include extern int TraceBack; -bool Dev = false; +bool Dev = true; int ProxyPort = 0; namespace fs = std::filesystem; @@ -81,10 +81,10 @@ std::string GetEN() { } std::string GetVer() { - return "2.0"; + return "2.1"; } std::string GetPatch() { - return ".99"; + return ".0"; } std::string GetEP(char* P) { From a6e765ad676ed10d8b9b7b676e2239a643d7465d Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 12 Aug 2024 23:25:10 +0200 Subject: [PATCH 02/29] update gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 01db102f..023421f6 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ Resources/ bin/ compile_commands.json key +out/ +.vs/ +cmake/ From fd0bef4e350e598649095e3c72456149fd4df7c6 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 12 Aug 2024 23:25:40 +0200 Subject: [PATCH 03/29] added vcpkg auto download --- .gitmodules | 3 +++ CMakeLists.txt | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/.gitmodules b/.gitmodules index b37131e0..00d6695d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "evpp"] path = evpp url = https://github.com/BeamMP/evpp.git +[submodule "vcpkg"] + path = vcpkg + url = https://github.com/microsoft/vcpkg.git diff --git a/CMakeLists.txt b/CMakeLists.txt index bffd6293..b611234c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,13 @@ cmake_minimum_required(VERSION 3.10) +include(cmake/Vcpkg.cmake) + project(Launcher) +include(cmake/StandardSettings.cmake) +include(cmake/StaticAnalyzers.cmake) +include(cmake/Git.cmake) + if (WIN32) message(STATUS "MSVC -> forcing use of statically-linked runtime.") STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) From e033251c5fed8bcabf38f596c6784f0963fe7e3b Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 12 Aug 2024 23:27:58 +0200 Subject: [PATCH 04/29] refractor DNS lookup This DNS lookup prefer IPv6, and return an IPv4 as fallback. If the client doesnt have IPv6 compatibility, then the DNS probe gonna return IPv4 only --- include/Network/network.hpp | 2 +- src/Network/DNS.cpp | 55 +++++++++++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/include/Network/network.hpp b/include/Network/network.hpp index 5c0b2b3d..6b200c9e 100644 --- a/include/Network/network.hpp +++ b/include/Network/network.hpp @@ -45,7 +45,7 @@ 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); +std::string resolveHost(const std::string& IP); void ServerParser(std::string_view Data); std::string Login(const std::string& fields); void TCPSend(const std::string& Data, uint64_t Sock); diff --git a/src/Network/DNS.cpp b/src/Network/DNS.cpp index d28b829f..83cc6ad1 100644 --- a/src/Network/DNS.cpp +++ b/src/Network/DNS.cpp @@ -10,6 +10,7 @@ #if defined(_WIN32) #include +#include #elif defined(__linux__) #include "linuxfixes.h" #include @@ -18,26 +19,58 @@ #include "Logger.h" -std::string GetAddr(const std::string& IP) { - if (IP.find_first_not_of("0123456789.") == -1) - return IP; - hostent* host; +/** + * Resolve IPs of host, prefered IPv6, and return IPv4 otherwise. + */ +std::string resolveHost(const std::string& hostStr) { + struct addrinfo* addresses = nullptr; + struct addrinfo hints {}; + memset(&hints, 0, sizeof(hints)); + + std::string resolved = ""; + #ifdef _WIN32 WSADATA wsaData; if (WSAStartup(514, &wsaData) != 0) { error("WSA Startup Failed!"); WSACleanup(); - return ""; + return resolved; } #endif + // UNSPEC to resolve both ip stack (IPv4 & IPv6) + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; - host = gethostbyname(IP.c_str()); - if (!host) { - error("DNS lookup failed! on " + IP); + int res = getaddrinfo(hostStr.c_str(), nullptr, &hints, &addresses); + if (res != 0) + { + std::cerr << "getaddrinfo failed: " << gai_strerror(res) << std::endl; +#ifdef _WIN32 WSACleanup(); - return "DNS"; +#endif + freeaddrinfo(addresses); + return resolved; } - std::string Ret = inet_ntoa(*((struct in_addr*)host->h_addr)); + + //Loop all add result, and return it by prefeence ipv6 + for (struct addrinfo* ptr = addresses; ptr != nullptr; ptr = ptr->ai_next) { + char ipstr[INET6_ADDRSTRLEN] = { 0 }; + + if (ptr->ai_family == AF_INET6) { + struct sockaddr_in6* ipv6 = (struct sockaddr_in6*)ptr->ai_addr; + inet_ntop(AF_INET6, &(ipv6->sin6_addr), ipstr, sizeof(ipstr)); + resolved = ipstr; + break; //Break if IPv6 finded + } + else if (ptr->ai_family == AF_INET) { + struct sockaddr_in* ipv4 = (struct sockaddr_in*)ptr->ai_addr; + inet_ntop(AF_INET, &(ipv4->sin_addr), ipstr, sizeof(ipstr)); + resolved = ipstr; + } + } + + freeaddrinfo(addresses); WSACleanup(); - return Ret; + return resolved; } \ No newline at end of file From 41ed06108c7e8be3bf26dac48f6b9c3b60e5ae83 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 12 Aug 2024 23:37:41 +0200 Subject: [PATCH 05/29] comments --- src/Network/DNS.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Network/DNS.cpp b/src/Network/DNS.cpp index 83cc6ad1..db3481a9 100644 --- a/src/Network/DNS.cpp +++ b/src/Network/DNS.cpp @@ -53,7 +53,7 @@ std::string resolveHost(const std::string& hostStr) { return resolved; } - //Loop all add result, and return it by prefeence ipv6 + //Loop all and return it by prefeence ipv6 for (struct addrinfo* ptr = addresses; ptr != nullptr; ptr = ptr->ai_next) { char ipstr[INET6_ADDRSTRLEN] = { 0 }; From 6d0afdbad3b05f393a677ccf3ad8b724523867a7 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 12 Aug 2024 23:51:19 +0200 Subject: [PATCH 06/29] Added mecanism resolve if needed --- src/Network/Core.cpp | 50 +++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index 0c51f88e..9f51a72e 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -45,25 +45,36 @@ bool ModLoaded; int ping = -1; void StartSync(const std::string& Data) { - std::string IP = GetAddr(Data.substr(1, Data.find(':') - 1)); - if (IP.find('.') == -1) { - if (IP == "DNS") - UlStatus = "UlConnection Failed! (DNS Lookup Failed)"; - else - UlStatus = "UlConnection Failed! (WSA failed to start)"; - ListOfMods = "-"; - Terminate = true; - return; + + const std::regex ipv4v6Pattern(R"(((^\h*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\h*(|/([0-9]|[1-2][0-9]|3[0-2]))$)|(^\h*((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\h*(|/([0-9]|[0-9][0-9]|1[0-1][0-9]|12[0-8]))$)))"); + + std::string host = Data.substr(1, Data.rfind(':') - 1); + uint16_t port = std::stoi(Data.substr(Data.rfind(':') + 1)); + + std::string IP; + + if (std::regex_match(host, ipv4v6Pattern)) + IP = host; + else { + + IP = resolveHost(host); + if (IP.length() == 0) { + UlStatus = "UlConnection Failed! (DNS Lookup Failed)"; + ListOfMods = "-"; + Terminate = true; + return; + } } + CheckLocalKey(); UlStatus = "UlLoading..."; TCPTerminate = false; Terminate = false; ConfList->clear(); ping = -1; - std::thread GS(TCPGameServer, IP, std::stoi(Data.substr(Data.find(':') + 1))); - GS.detach(); info("Connecting to server"); + std::thread GS(TCPGameServer, IP, port); + GS.detach(); } bool IsAllowedLink(const std::string& Link) { @@ -87,6 +98,7 @@ void Parse(std::string Data, SOCKET CSocket) { Data = Code + HTTP::Get("https://backend.beammp.com/servers-info"); break; case 'C': + //TODO StartSync Here ListOfMods.clear(); StartSync(Data); while (ListOfMods.empty() && !Terminate) { @@ -170,6 +182,7 @@ void Parse(std::string Data, SOCKET CSocket) { Data = "Z" + GetVer(); break; case 'N': + if (SubCode == 'c') { nlohmann::json Auth = { { "Auth", LoginAuth ? 1 : 0 }, @@ -198,6 +211,7 @@ void Parse(std::string Data, SOCKET CSocket) { } void GameHandler(SOCKET Client) { + int32_t Size, Temp, Rcv; char Header[10] = { 0 }; do { @@ -265,49 +279,51 @@ void CoreMain() { ZeroMemory(&hints, sizeof(hints)); + //IPv4 socket waiting handling LUA communications hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; - hints.ai_flags = AI_PASSIVE; + + //Fill for loopback ipv4 iRes = getaddrinfo(nullptr, std::to_string(DEFAULT_PORT).c_str(), &hints, &res); if (iRes) { debug("(Core) addr info failed with error: " + std::to_string(iRes)); WSACleanup(); return; } + //Create socket LSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (LSocket == -1) { debug("(Core) socket failed with error: " + std::to_string(WSAGetLastError())); - freeaddrinfo(res); WSACleanup(); return; } iRes = bind(LSocket, res->ai_addr, int(res->ai_addrlen)); if (iRes == SOCKET_ERROR) { error("(Core) bind failed with error: " + std::to_string(WSAGetLastError())); - freeaddrinfo(res); KillSocket(LSocket); WSACleanup(); return; } + freeaddrinfo(res); iRes = listen(LSocket, SOMAXCONN); if (iRes == SOCKET_ERROR) { debug("(Core) listen failed with error: " + std::to_string(WSAGetLastError())); - freeaddrinfo(res); KillSocket(LSocket); WSACleanup(); return; } do { + //Waiting LUA Connexion CSocket = accept(LSocket, nullptr, nullptr); if (CSocket == -1) { error("(Core) accept failed with error: " + std::to_string(WSAGetLastError())); continue; } localRes(); - info("Game Connected!"); + info("Game Connected to LUA interface!"); GameHandler(CSocket); - warn("Game Reconnecting..."); + warn("Game reconnecting to LUA interface..."); } while (CSocket); KillSocket(LSocket); WSACleanup(); From 3c0e56dc0bfc32d2810512440bf6e47fc083f8b7 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 12 Aug 2024 23:52:41 +0200 Subject: [PATCH 07/29] Added TCP client IPv6 --- src/Network/VehicleEvent.cpp | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/Network/VehicleEvent.cpp b/src/Network/VehicleEvent.cpp index c02a5726..065c714e 100644 --- a/src/Network/VehicleEvent.cpp +++ b/src/Network/VehicleEvent.cpp @@ -128,13 +128,15 @@ std::string TCPRcv(SOCKET Sock) { void TCPClientMain(const std::string& IP, int Port) { LastIP = IP; LastPort = Port; - SOCKADDR_IN ServerAddr; + + int AF = (IP.find(':') != std::string::npos) ? AF_INET6 : AF_INET; int RetCode; #ifdef _WIN32 WSADATA wsaData; WSAStartup(514, &wsaData); // 2.2 #endif - TCPSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + //Create the socket for distant server + TCPSock = socket(AF, SOCK_STREAM, IPPROTO_TCP); if (TCPSock == -1) { printf("Client: socket failed! Error code: %d\n", WSAGetLastError()); @@ -142,10 +144,26 @@ void TCPClientMain(const std::string& IP, int Port) { return; } - ServerAddr.sin_family = AF_INET; - ServerAddr.sin_port = htons(Port); - inet_pton(AF_INET, IP.c_str(), &ServerAddr.sin_addr); - RetCode = connect(TCPSock, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr)); + if (AF == AF_INET) { + // IPv4 + struct sockaddr_in ServerAddr; + memset(&ServerAddr, 0, sizeof(ServerAddr)); + ServerAddr.sin_family = AF_INET; + ServerAddr.sin_port = htons(Port); + inet_pton(AF_INET, IP.c_str(), &ServerAddr.sin_addr); + + RetCode = connect(TCPSock, (struct sockaddr*)&ServerAddr, sizeof(ServerAddr)); + } else { + // IPv6 + struct sockaddr_in6 ServerAddr; + memset(&ServerAddr, 0, sizeof(ServerAddr)); + ServerAddr.sin6_family = AF_INET6; + ServerAddr.sin6_port = htons(Port); + inet_pton(AF_INET6, IP.c_str(), &ServerAddr.sin6_addr); + + RetCode = connect(TCPSock, (struct sockaddr*)&ServerAddr, sizeof(ServerAddr)); + } + if (RetCode != 0) { UlStatus = "UlConnection Failed!"; error("Client: connect failed! Error code: " + std::to_string(WSAGetLastError())); From 1f5978bc3240a9f4dc4933580bea4c2af2e9d6ce Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 12 Aug 2024 23:52:59 +0200 Subject: [PATCH 08/29] Added UDP Client support --- src/Network/VehicleData.cpp | 60 ++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index 23314646..ce598f91 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -24,17 +24,18 @@ #include SOCKET UDPSock = -1; -sockaddr_in* ToServer = nullptr; +sockaddr_storage* ToServer = nullptr; +socklen_t addrLen = 0; void UDPSend(std::string Data) { - if (ClientID == -1 || UDPSock == -1) + if (ClientID == -1 || UDPSock == -1 ||ToServer == nullptr) return; if (Data.length() > 400) { 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)); + int sendOk = sendto(UDPSock, Packet.c_str(), int(Packet.size()), 0, (sockaddr*)ToServer, addrLen); if (sendOk == SOCKET_ERROR) error("Error Code : " + std::to_string(WSAGetLastError())); } @@ -57,24 +58,22 @@ void UDPParser(std::string_view Packet) { ServerParser(Packet); } } + void UDPRcv() { - sockaddr_in FromServer {}; -#if defined(_WIN32) - int clientLength = sizeof(FromServer); -#elif defined(__linux__) - socklen_t clientLength = sizeof(FromServer); -#endif - ZeroMemory(&FromServer, clientLength); + sockaddr_storage FromServer {}; static thread_local std::array Ret {}; if (UDPSock == -1) return; - int32_t Rcv = recvfrom(UDPSock, Ret.data(), Ret.size() - 1, 0, (sockaddr*)&FromServer, &clientLength); + int32_t Rcv = recvfrom(UDPSock, Ret.data(), Ret.size() - 1, 0, (sockaddr*)&FromServer, &addrLen); if (Rcv == SOCKET_ERROR) return; Ret[Rcv] = 0; UDPParser(std::string_view(Ret.data(), Rcv)); } -void UDPClientMain(const std::string& IP, int Port) { + +void UDPClientMain(const std::string& IP, int Port) +{ + #ifdef _WIN32 WSADATA data; if (WSAStartup(514, &data)) { @@ -82,16 +81,41 @@ void UDPClientMain(const std::string& IP, int Port) { return; } #endif + //IPv6 or IPv4 ? + int AF = (IP.find(':') != std::string::npos) ? AF_INET6 : AF_INET; + + ToServer = new sockaddr_storage; + memset(ToServer, 0, sizeof(sockaddr_storage)); + + if (AF == AF_INET) { + // IPv4 + struct sockaddr_in serverAddrV4; + memset(&serverAddrV4, 0, sizeof(sockaddr_in)); + serverAddrV4.sin_family = AF_INET; + serverAddrV4.sin_port = htons(Port); + inet_pton(AF_INET, IP.c_str(), &serverAddrV4.sin_addr); + memcpy(ToServer, &serverAddrV4, sizeof(sockaddr_in)); + addrLen = sizeof(sockaddr_in); + } else { + // IPv6 + struct sockaddr_in6 serverAddrV6; + memset(&serverAddrV6, 0, sizeof(sockaddr_in6)); + serverAddrV6.sin6_family = AF_INET6; + serverAddrV6.sin6_port = htons(Port); + inet_pton(AF_INET6, IP.c_str(), &serverAddrV6.sin6_addr); + memcpy(ToServer, &serverAddrV6, sizeof(sockaddr_in6)); + addrLen = sizeof(sockaddr_in6); + } + + + //Open socket + UDPSock = socket(AF, SOCK_DGRAM, 0); - delete ToServer; - ToServer = new sockaddr_in; - ToServer->sin_family = AF_INET; - ToServer->sin_port = htons(Port); - inet_pton(AF_INET, IP.c_str(), &ToServer->sin_addr); - UDPSock = socket(AF_INET, SOCK_DGRAM, 0); + //Send to the game client GameSend("P" + std::to_string(ClientID)); TCPSend("H", TCPSock); UDPSend("p"); + //Main loop while (!Terminate) UDPRcv(); KillSocket(UDPSock); From 16458bb37b73714f67dd3f61bbbf659b73df6dfd Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 12 Aug 2024 23:53:35 +0200 Subject: [PATCH 09/29] lisibility --- src/Network/GlobalHandler.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Network/GlobalHandler.cpp b/src/Network/GlobalHandler.cpp index dc4b5801..c2035ed2 100644 --- a/src/Network/GlobalHandler.cpp +++ b/src/Network/GlobalHandler.cpp @@ -31,6 +31,7 @@ bool GConnected = false; bool CServer = true; SOCKET CSocket = -1; SOCKET GSocket = -1; +int ClientID = -1; int KillSocket(uint64_t Dead) { if (Dead == (SOCKET)-1) { @@ -154,7 +155,6 @@ SOCKET SetupListener() { return -1; } #endif - ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; @@ -190,6 +190,7 @@ SOCKET SetupListener() { } return GSocket; } + void AutoPing() { while (!Terminate) { ServerSend("p", false); @@ -197,8 +198,9 @@ void AutoPing() { std::this_thread::sleep_for(std::chrono::seconds(1)); } } -int ClientID = -1; + void ParserAsync(std::string_view Data) { + if (Data.empty()) return; char Code = Data.at(0), SubCode = 0; @@ -221,9 +223,11 @@ void ParserAsync(std::string_view Data) { } GameSend(Data); } + void ServerParser(std::string_view Data) { ParserAsync(Data); } + void NetMain(const std::string& IP, int Port) { std::thread Ping(AutoPing); Ping.detach(); @@ -232,8 +236,10 @@ void NetMain(const std::string& IP, int Port) { Terminate = true; info("Connection Terminated!"); } + void TCPGameServer(const std::string& IP, int Port) { GSocket = SetupListener(); + while (!TCPTerminate && GSocket != -1) { debug("MAIN LOOP OF GAME SERVER"); GConnected = false; From 739ef66ed45441b694e70a34f6b591d7f63bc2c9 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 12 Aug 2024 23:58:19 +0200 Subject: [PATCH 10/29] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 023421f6..643f52a5 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ key out/ .vs/ cmake/ +CMakeSettings.json \ No newline at end of file From f819586d396897fe05fa08120039ad6f1826fa29 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Tue, 13 Aug 2024 16:19:02 +0200 Subject: [PATCH 11/29] added vcpkg again --- .gitignore | 1 - cmake/CompilerWarnings.cmake | 115 +++++++++++++++++++++++++++++++++++ cmake/Git.cmake | 21 +++++++ cmake/StandardSettings.cmake | 44 ++++++++++++++ cmake/StaticAnalyzers.cmake | 20 ++++++ cmake/Vcpkg.cmake | 17 ++++++ 6 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 cmake/CompilerWarnings.cmake create mode 100644 cmake/Git.cmake create mode 100644 cmake/StandardSettings.cmake create mode 100644 cmake/StaticAnalyzers.cmake create mode 100644 cmake/Vcpkg.cmake diff --git a/.gitignore b/.gitignore index 643f52a5..9ddccb24 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,4 @@ compile_commands.json key out/ .vs/ -cmake/ CMakeSettings.json \ No newline at end of file diff --git a/cmake/CompilerWarnings.cmake b/cmake/CompilerWarnings.cmake new file mode 100644 index 00000000..c42cb17d --- /dev/null +++ b/cmake/CompilerWarnings.cmake @@ -0,0 +1,115 @@ +# from here: +# +# https://github.com/lefticus/cppbestpractices/blob/master/02-Use_the_Tools_Available.md +# Courtesy of Jason Turner +# License here: https://github.com/cpp-best-practices/cppbestpractices/blob/master/LICENSE +# +# This version has been modified by the owners of the current respository. +# Modifications have mostly been marked with "modified" or similar, though this is not +# strictly required. + +function(set_project_warnings project_name) + set(MSVC_WARNINGS + /W4 # Baseline reasonable warnings + /w14242 # 'identifier': conversion from 'type1' to 'type1', possible loss + # of data + /w14254 # 'operator': conversion from 'type1:field_bits' to + # 'type2:field_bits', possible loss of data + /w14263 # 'function': member function does not override any base class + # virtual member function + /w14265 # 'classname': class has virtual functions, but destructor is not + # virtual instances of this class may not be destructed correctly + /w14287 # 'operator': unsigned/negative constant mismatch + /we4289 # nonstandard extension used: 'variable': loop control variable + # declared in the for-loop is used outside the for-loop scope + /w14296 # 'operator': expression is always 'boolean_value' + /w14311 # 'variable': pointer truncation from 'type1' to 'type2' + /w14545 # expression before comma evaluates to a function which is missing + # an argument list + /w14546 # function call before comma missing argument list + /w14547 # 'operator': operator before comma has no effect; expected + # operator with side-effect + /w14549 # 'operator': operator before comma has no effect; did you intend + # 'operator'? + /w14555 # expression has no effect; expected expression with side- effect + /w14619 # pragma warning: there is no warning number 'number' + /w14640 # Enable warning on thread un-safe static member initialization + /w14826 # Conversion from 'type1' to 'type_2' is sign-extended. This may + # cause unexpected runtime behavior. + /w14905 # wide string literal cast to 'LPSTR' + /w14906 # string literal cast to 'LPWSTR' + /w14928 # illegal copy-initialization; more than one user-defined + # conversion has been implicitly applied + /permissive- # standards conformance mode for MSVC compiler. + ) + + set(CLANG_WARNINGS + -Wall + -Wextra # reasonable and standard + -Wshadow # warn the user if a variable declaration shadows one from a + # parent context + -Wnon-virtual-dtor # warn the user if a class with virtual functions has a + # non-virtual destructor. This helps catch hard to + # track down memory errors + -Wold-style-cast # warn for c-style casts + -Wcast-align # warn for potential performance problem casts + -Wunused # warn on anything being unused + -Woverloaded-virtual # warn if you overload (not override) a virtual + # function + -Wpedantic # warn if non-standard C++ is used + -Wconversion # warn on type conversions that may lose data + -Wsign-conversion # warn on sign conversions + -Wnull-dereference # warn if a null dereference is detected + -Wdouble-promotion # warn if float is implicit promoted to double + -Wformat=2 # warn on security issues around functions that format output + # (ie printf) + # modified; added more errors / warnings + # some have been set to be errors, but the option _WARNINGS_AS_ERRORS + # (see below) should still be used in strict pipelines. + -Werror=uninitialized + -Werror=float-equal + -Werror=write-strings + -Werror=strict-aliasing -fstrict-aliasing + -Werror=missing-declarations + -Werror=missing-field-initializers + -Werror=ctor-dtor-privacy + -Werror=switch-enum + -Wswitch-default + -Werror=unused-result + -Werror=implicit-fallthrough + -Werror=return-type + -Wmissing-include-dirs + ) + + if (${PROJECT_NAME}_WARNINGS_AS_ERRORS) + set(CLANG_WARNINGS ${CLANG_WARNINGS} -Werror) + set(MSVC_WARNINGS ${MSVC_WARNINGS} /WX) + endif() + + set(GCC_WARNINGS + ${CLANG_WARNINGS} + -Wmisleading-indentation # warn if indentation implies blocks where blocks + # do not exist + -Wduplicated-cond # warn if if / else chain has duplicated conditions + -Wduplicated-branches # warn if if / else branches have duplicated code + -Wlogical-op # warn about logical operations being used where bitwise were + # probably wanted + # -Wuseless-cast # warn if you perform a cast to the same type (modified: removed) + ) + + if(MSVC) + set(PRJ_WARNINGS ${MSVC_WARNINGS}) + elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + set(PRJ_WARNINGS ${CLANG_WARNINGS}) + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(PRJ_WARNINGS ${GCC_WARNINGS}) + else() + message(AUTHOR_WARNING "No compiler warnings set for '${CMAKE_CXX_COMPILER_ID}' compiler.") + endif() + + target_compile_options(${project_name} PUBLIC ${PRJ_WARNINGS}) + + if(NOT TARGET ${project_name}) + message(AUTHOR_WARNING "${project_name} is not a target, thus no compiler warning were added.") + endif() +endfunction() diff --git a/cmake/Git.cmake b/cmake/Git.cmake new file mode 100644 index 00000000..abeffc6c --- /dev/null +++ b/cmake/Git.cmake @@ -0,0 +1,21 @@ +find_package(Git) +if(${PROJECT_NAME}_CHECKOUT_GIT_SUBMODULES) + if(Git_FOUND) + message(STATUS "Git found, submodule update and init") + execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + RESULT_VARIABLE GIT_SUBMOD_RESULT) + if(NOT GIT_SUBMOD_RESULT EQUAL "0") + message(SEND_ERROR "git submodule update --init --recursive failed with ${GIT_SUBMOD_RESULT}, please checkout submodules. This may result in missing dependencies.") + endif() + else() + message(SEND_ERROR "git required for checking out submodules, but not found. Submodules will not be checked out - this may result in missing dependencies.") + endif() +endif() + +if(Git_FOUND) + +else() + message(STATUS "Git not found - the version will not include a git hash.") + set(PRJ_GIT_HASH "unknown") +endif() diff --git a/cmake/StandardSettings.cmake b/cmake/StandardSettings.cmake new file mode 100644 index 00000000..0d8808ce --- /dev/null +++ b/cmake/StandardSettings.cmake @@ -0,0 +1,44 @@ +# Modified, original version from https://github.com/filipdutescu/modern-cpp-template (Unlicense) + +option(${PROJECT_NAME}_WARNINGS_AS_ERRORS "Treat compiler warnings as errors." OFF) +option(${PROJECT_NAME}_CHECKOUT_GIT_SUBMODULES "If git is found, initialize all submodules." ON) +option(${PROJECT_NAME}_ENABLE_UNIT_TESTING "Enable unit tests for the projects (from the `test` subfolder)." ON) +option(${PROJECT_NAME}_ENABLE_CLANG_TIDY "Enable static analysis with Clang-Tidy." OFF) +option(${PROJECT_NAME}_ENABLE_CPPCHECK "Enable static analysis with Cppcheck." OFF) +# TODO Implement code coverage +# option(${PROJECT_NAME}_ENABLE_CODE_COVERAGE "Enable code coverage through GCC." OFF) +option(${PROJECT_NAME}_ENABLE_DOXYGEN "Enable Doxygen documentation builds of source." OFF) + +# Generate compile_commands.json for clang based tools +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Export all symbols when building a shared library +if(BUILD_SHARED_LIBS) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS OFF) + set(CMAKE_CXX_VISIBILITY_PRESET hidden) + set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) +endif() + +option(${PROJECT_NAME}_ENABLE_LTO "Enable Interprocedural Optimization, aka Link Time Optimization (LTO)." OFF) +if(${PROJECT_NAME}_ENABLE_LTO) + include(CheckIPOSupported) + check_ipo_supported(RESULT result OUTPUT output) + if(result) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + else() + message(SEND_ERROR "IPO is not supported: ${output}.") + endif() +endif() + +option(${PROJECT_NAME}_ENABLE_CCACHE "Enable the usage of Ccache, in order to speed up rebuild times." ON) +find_program(CCACHE_FOUND ccache) +if(CCACHE_FOUND) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) +endif() + +option(${PROJECT_NAME}_ENABLE_SANITIZER "Enable sanitizer to detect memory errors, undefined behavior, etc. (slows down the executable)." OFF) +if(${PROJECT_NAME}_ENABLE_SANITIZER) + add_compile_options(-fsanitize=address,undefined) + add_link_options(-fsanitize=address,undefined) +endif() diff --git a/cmake/StaticAnalyzers.cmake b/cmake/StaticAnalyzers.cmake new file mode 100644 index 00000000..ed149f80 --- /dev/null +++ b/cmake/StaticAnalyzers.cmake @@ -0,0 +1,20 @@ +if(${PROJECT_NAME}_ENABLE_CLANG_TIDY) + find_program(CLANGTIDY clang-tidy) + if(CLANGTIDY) + set(CMAKE_CXX_CLANG_TIDY ${CLANGTIDY} -extra-arg=-Wno-unknown-warning-option) + message("Clang-Tidy finished setting up.") + else() + message(SEND_ERROR "Clang-Tidy requested but executable not found.") + endif() +endif() + +if(${PROJECT_NAME}_ENABLE_CPPCHECK) + find_program(CPPCHECK cppcheck) + if(CPPCHECK) + set(CMAKE_CXX_CPPCHECK ${CPPCHECK} --suppress=missingInclude --enable=all + --inline-suppr --inconclusive) + message("Cppcheck finished setting up.") + else() + message(SEND_ERROR "Cppcheck requested but executable not found.") + endif() +endif() diff --git a/cmake/Vcpkg.cmake b/cmake/Vcpkg.cmake new file mode 100644 index 00000000..9d8ecbac --- /dev/null +++ b/cmake/Vcpkg.cmake @@ -0,0 +1,17 @@ +if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) + if(NOT EXISTS ${CMAKE_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake) + find_package(Git) + if(Git_FOUND) + execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive vcpkg + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + RESULT_VARIABLE GIT_SUBMOD_RESULT) + if(NOT GIT_SUBMOD_RESULT EQUAL "0") + message(SEND_ERROR "Checking out vcpkg in source tree failed with ${GIT_SUBMOD_RESULT}.") + endif() + else() + message(FATAL_ERROR "Could not find git or vcpkg.cmake. Please either, install git and re-run cmake (or run `git submodule update --init --recursive`), or install vcpkg and add `-DCMAKE_TOOLCHAIN_FILE=/scripts/buildsystems/vcpkg.cmake` to your cmake invocation. Please try again after making those changes.") + endif() + endif() + set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake) +endif() + From d563bfe2387a01fb05f23cb490dbd4c743043938 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Tue, 13 Aug 2024 17:08:59 +0200 Subject: [PATCH 12/29] added download IPv4/IPv6 --- src/Network/Resources.cpp | 40 +++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/Network/Resources.cpp b/src/Network/Resources.cpp index f32c2633..6559c459 100644 --- a/src/Network/Resources.cpp +++ b/src/Network/Resources.cpp @@ -34,6 +34,7 @@ namespace fs = std::filesystem; std::string ListOfMods; + std::vector Split(const std::string& String, const std::string& delimiter) { std::vector Val; size_t pos; @@ -72,6 +73,9 @@ void Abord() { info("Terminated!"); } +/** + * Auth the client, and return a list of mods needed as string, or empty string otherwise + */ std::string Auth(SOCKET Sock) { TCPSend("VC" + GetVer(), Sock); @@ -116,7 +120,7 @@ std::string Auth(SOCKET Sock) { ListOfMods = "-"; TCPSend("Done", Sock); info("Done!"); - return ""; + return ""; //return empty } return Res; } @@ -168,22 +172,42 @@ void MultiKill(SOCKET Sock, SOCKET Sock1) { KillSocket(Sock); Terminate = true; } +/** + * Init the download socket. + */ SOCKET InitDSock() { - SOCKET DSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - SOCKADDR_IN ServerAddr; + int AF = (LastIP.find(':') != std::string::npos) ? AF_INET6 : AF_INET; + + SOCKET DSock = socket(AF, SOCK_STREAM, IPPROTO_TCP); + if (DSock < 1) { KillSocket(DSock); Terminate = true; return 0; } - ServerAddr.sin_family = AF_INET; - ServerAddr.sin_port = htons(LastPort); - inet_pton(AF_INET, LastIP.c_str(), &ServerAddr.sin_addr); - if (connect(DSock, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr)) != 0) { + + sockaddr_storage serverAddr; + memset(&serverAddr, 0, sizeof(sockaddr_storage)); + + if (AF == AF_INET) { + sockaddr_in* addr4 = (sockaddr_in*)&serverAddr; + addr4->sin_family = AF_INET; + addr4->sin_port = htons(LastPort); + inet_pton(AF_INET, LastIP.c_str(), &addr4->sin_addr); + } else if (AF == AF_INET6) { + sockaddr_in6* addr6 = (sockaddr_in6*)&serverAddr; + addr6->sin6_family = AF_INET6; + addr6->sin6_port = htons(LastPort); + inet_pton(AF_INET6, LastIP.c_str(), &addr6->sin6_addr); + } + + //Connect to the server + if (connect(DSock, (SOCKADDR*)&serverAddr, sizeof(sockaddr_storage)) != 0) { KillSocket(DSock); Terminate = true; return 0; } + char Code[2] = { 'D', char(ClientID) }; if (send(DSock, Code, 2, 0) != 2) { KillSocket(DSock); @@ -239,7 +263,7 @@ void InvalidResource(const std::string& File) { Terminate = true; } -void SyncResources(SOCKET Sock) { +void SyncResources(uint64_t Sock) { std::string Ret = Auth(Sock); if (Ret.empty()) return; From f732cace626b3118ab8b435d0dce0163aa14654a Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Tue, 13 Aug 2024 19:54:16 +0200 Subject: [PATCH 13/29] Update .gitmodules --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 00d6695d..b37131e0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "evpp"] path = evpp url = https://github.com/BeamMP/evpp.git -[submodule "vcpkg"] - path = vcpkg - url = https://github.com/microsoft/vcpkg.git From d0bbf873e6d02e997d5e5481f095350f5c6ccecd Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Tue, 13 Aug 2024 19:55:42 +0200 Subject: [PATCH 14/29] added submodule vcpkg --- .gitmodules | 3 +++ vcpkg | 1 + 2 files changed, 4 insertions(+) create mode 160000 vcpkg diff --git a/.gitmodules b/.gitmodules index b37131e0..00d6695d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "evpp"] path = evpp url = https://github.com/BeamMP/evpp.git +[submodule "vcpkg"] + path = vcpkg + url = https://github.com/microsoft/vcpkg.git diff --git a/vcpkg b/vcpkg new file mode 160000 index 00000000..3f142d2f --- /dev/null +++ b/vcpkg @@ -0,0 +1 @@ +Subproject commit 3f142d2fc6f6cf10360e89248405057fe771a9ed From 376dc9abcfa5fcc2f220c05651b7587b9e3c5b91 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Tue, 13 Aug 2024 21:14:59 +0200 Subject: [PATCH 15/29] header linux --- src/Network/DNS.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Network/DNS.cpp b/src/Network/DNS.cpp index db3481a9..0034d4a7 100644 --- a/src/Network/DNS.cpp +++ b/src/Network/DNS.cpp @@ -15,6 +15,7 @@ #include "linuxfixes.h" #include #include +#include #endif #include "Logger.h" From 6f75f9fc3c0014177574c42da46fce7ebe95f643 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Sat, 17 Aug 2024 23:07:19 +0200 Subject: [PATCH 16/29] Let resolveHost check IP format and resolving if needed I'have tested the behavior waited --- src/Network/Core.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index 9f51a72e..db9600b0 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -46,24 +46,20 @@ int ping = -1; void StartSync(const std::string& Data) { - const std::regex ipv4v6Pattern(R"(((^\h*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\h*(|/([0-9]|[1-2][0-9]|3[0-2]))$)|(^\h*((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\h*(|/([0-9]|[0-9][0-9]|1[0-1][0-9]|12[0-8]))$)))"); + //const std::regex ipv4v6Pattern(R"(((^\h*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\h*(|/([0-9]|[1-2][0-9]|3[0-2]))$)|(^\h*((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\h*(|/([0-9]|[0-9][0-9]|1[0-1][0-9]|12[0-8]))$)))"); std::string host = Data.substr(1, Data.rfind(':') - 1); uint16_t port = std::stoi(Data.substr(Data.rfind(':') + 1)); - std::string IP; + std::string IP; - if (std::regex_match(host, ipv4v6Pattern)) - IP = host; - else { + IP = resolveHost(host); - IP = resolveHost(host); - if (IP.length() == 0) { - UlStatus = "UlConnection Failed! (DNS Lookup Failed)"; - ListOfMods = "-"; - Terminate = true; - return; - } + if (IP.length() == 0) { + UlStatus = "UlConnection Failed! (DNS Lookup Failed)"; + ListOfMods = "-"; + Terminate = true; + return; } CheckLocalKey(); From 1965046fd86a3c46453d02615ffca016d4e9cc04 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Sat, 17 Aug 2024 23:07:55 +0200 Subject: [PATCH 17/29] remove forgotten TODO --- src/Network/Core.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index db9600b0..9f2ad053 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -94,7 +94,6 @@ void Parse(std::string Data, SOCKET CSocket) { Data = Code + HTTP::Get("https://backend.beammp.com/servers-info"); break; case 'C': - //TODO StartSync Here ListOfMods.clear(); StartSync(Data); while (ListOfMods.empty() && !Terminate) { From 8f27dbaee2d9771fc0416f39d9b420ca1cbd89f5 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Sat, 17 Aug 2024 23:27:13 +0200 Subject: [PATCH 18/29] Correct freeaddrinfo --- src/Network/Core.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index 9f2ad053..02f9c7bf 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -290,17 +290,18 @@ void CoreMain() { LSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (LSocket == -1) { debug("(Core) socket failed with error: " + std::to_string(WSAGetLastError())); + freeaddrinfo(res); WSACleanup(); return; } iRes = bind(LSocket, res->ai_addr, int(res->ai_addrlen)); + freeaddrinfo(res); if (iRes == SOCKET_ERROR) { error("(Core) bind failed with error: " + std::to_string(WSAGetLastError())); KillSocket(LSocket); WSACleanup(); return; } - freeaddrinfo(res); iRes = listen(LSocket, SOMAXCONN); if (iRes == SOCKET_ERROR) { debug("(Core) listen failed with error: " + std::to_string(WSAGetLastError())); From 926e4e0afdf53826ba4fb4d9e9e9fa0f68c1ddbf Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 19 Aug 2024 13:10:18 +0200 Subject: [PATCH 19/29] Create function to create socket and fill sockaddrinfo struct --- include/Network/network.hpp | 19 +++++++- src/Network/GlobalHandler.cpp | 4 +- src/Network/VehicleData.cpp | 42 +++++----------- src/Network/VehicleEvent.cpp | 92 +++++++++++++++++++---------------- 4 files changed, 82 insertions(+), 75 deletions(-) diff --git a/include/Network/network.hpp b/include/Network/network.hpp index 6b200c9e..55cf4ec4 100644 --- a/include/Network/network.hpp +++ b/include/Network/network.hpp @@ -8,8 +8,17 @@ #pragma once #include +#include -#ifdef __linux__ +#if defined(_WIN32) +#include +#elif defined(__linux__) +#include +#include +#include +#include +#include +#include #include "linuxfixes.h" #include #include @@ -52,3 +61,11 @@ void TCPSend(const std::string& Data, uint64_t Sock); void TCPClientMain(const std::string& IP, int Port); void UDPClientMain(const std::string& IP, int Port); void TCPGameServer(const std::string& IP, int Port); +/** + * Init a socket on the IP and port provided, and fill an sockaddr_storage. + * @param ip : IP of the distant host + * @param port : Port of the distant host + * @param sockType : Type of the socket asked: SOCK_DGRAM or SOCK_STREAM + * @param pStoreAddrInfo : A **valid** pointer to handle sockaddr informations used by the socket + */ +std::pair initSocket(std::string ip, int port, int sockType, sockaddr_storage* pStoreAddrInfo); diff --git a/src/Network/GlobalHandler.cpp b/src/Network/GlobalHandler.cpp index c2035ed2..8059fe8a 100644 --- a/src/Network/GlobalHandler.cpp +++ b/src/Network/GlobalHandler.cpp @@ -34,8 +34,8 @@ SOCKET GSocket = -1; int ClientID = -1; int KillSocket(uint64_t Dead) { - if (Dead == (SOCKET)-1) { - debug("Kill socket got -1 returning..."); + if (Dead == INVALID_SOCKET) { + debug("Kill invalid socket got, returning..."); return 0; } shutdown(Dead, SD_BOTH); diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index ce598f91..ec2fa0be 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -24,18 +24,17 @@ #include SOCKET UDPSock = -1; -sockaddr_storage* ToServer = nullptr; -socklen_t addrLen = 0; +sockaddr_storage ToServer {}; void UDPSend(std::string Data) { - if (ClientID == -1 || UDPSock == -1 ||ToServer == nullptr) + if (ClientID == -1 || UDPSock == -1) return; if (Data.length() > 400) { 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, addrLen); + int sendOk = sendto(UDPSock, Packet.c_str(), int(Packet.size()), 0, (sockaddr*)&ToServer, sizeof(sockaddr_storage)); if (sendOk == SOCKET_ERROR) error("Error Code : " + std::to_string(WSAGetLastError())); } @@ -61,6 +60,7 @@ void UDPParser(std::string_view Packet) { void UDPRcv() { sockaddr_storage FromServer {}; + socklen_t addrLen = sizeof(FromServer); static thread_local std::array Ret {}; if (UDPSock == -1) return; @@ -81,35 +81,19 @@ void UDPClientMain(const std::string& IP, int Port) return; } #endif - //IPv6 or IPv4 ? - int AF = (IP.find(':') != std::string::npos) ? AF_INET6 : AF_INET; - ToServer = new sockaddr_storage; - memset(ToServer, 0, sizeof(sockaddr_storage)); + auto result = initSocket(IP, Port, SOCK_DGRAM, &ToServer); - if (AF == AF_INET) { - // IPv4 - struct sockaddr_in serverAddrV4; - memset(&serverAddrV4, 0, sizeof(sockaddr_in)); - serverAddrV4.sin_family = AF_INET; - serverAddrV4.sin_port = htons(Port); - inet_pton(AF_INET, IP.c_str(), &serverAddrV4.sin_addr); - memcpy(ToServer, &serverAddrV4, sizeof(sockaddr_in)); - addrLen = sizeof(sockaddr_in); - } else { - // IPv6 - struct sockaddr_in6 serverAddrV6; - memset(&serverAddrV6, 0, sizeof(sockaddr_in6)); - serverAddrV6.sin6_family = AF_INET6; - serverAddrV6.sin6_port = htons(Port); - inet_pton(AF_INET6, IP.c_str(), &serverAddrV6.sin6_addr); - memcpy(ToServer, &serverAddrV6, sizeof(sockaddr_in6)); - addrLen = sizeof(sockaddr_in6); + if (result.second != 0) { + UlStatus = "UlConnection Failed!"; + error("Client: connect failed! Error code: " + std::to_string(WSAGetLastError())); + KillSocket(TCPSock); + WSACleanup(); + Terminate = true; + return; } - - //Open socket - UDPSock = socket(AF, SOCK_DGRAM, 0); + UDPSock = result.first; //Send to the game client GameSend("P" + std::to_string(ClientID)); diff --git a/src/Network/VehicleEvent.cpp b/src/Network/VehicleEvent.cpp index 065c714e..75a739e8 100644 --- a/src/Network/VehicleEvent.cpp +++ b/src/Network/VehicleEvent.cpp @@ -12,17 +12,6 @@ #include #include -#if defined(_WIN32) -#include -#elif defined(__linux__) -#include -#include -#include -#include -#include -#include -#endif - #include "Network/network.hpp" int LastPort; @@ -129,42 +118,22 @@ void TCPClientMain(const std::string& IP, int Port) { LastIP = IP; LastPort = Port; - int AF = (IP.find(':') != std::string::npos) ? AF_INET6 : AF_INET; - int RetCode; -#ifdef _WIN32 - WSADATA wsaData; - WSAStartup(514, &wsaData); // 2.2 -#endif - //Create the socket for distant server - TCPSock = socket(AF, SOCK_STREAM, IPPROTO_TCP); + sockaddr_storage server {}; - if (TCPSock == -1) { - printf("Client: socket failed! Error code: %d\n", WSAGetLastError()); + auto result = initSocket(IP, Port, SOCK_STREAM, &server); + + if (result.second != 0) { + UlStatus = "UlConnection Failed!"; + error("Client: connect failed! Error code: " + std::to_string(WSAGetLastError())); + KillSocket(TCPSock); WSACleanup(); + Terminate = true; return; } - - if (AF == AF_INET) { - // IPv4 - struct sockaddr_in ServerAddr; - memset(&ServerAddr, 0, sizeof(ServerAddr)); - ServerAddr.sin_family = AF_INET; - ServerAddr.sin_port = htons(Port); - inet_pton(AF_INET, IP.c_str(), &ServerAddr.sin_addr); - - RetCode = connect(TCPSock, (struct sockaddr*)&ServerAddr, sizeof(ServerAddr)); - } else { - // IPv6 - struct sockaddr_in6 ServerAddr; - memset(&ServerAddr, 0, sizeof(ServerAddr)); - ServerAddr.sin6_family = AF_INET6; - ServerAddr.sin6_port = htons(Port); - inet_pton(AF_INET6, IP.c_str(), &ServerAddr.sin6_addr); - - RetCode = connect(TCPSock, (struct sockaddr*)&ServerAddr, sizeof(ServerAddr)); - } - - if (RetCode != 0) { + TCPSock = result.first; + //Try to connect to the distant server, using the socket created + if (connect(TCPSock, (struct sockaddr*)&server, sizeof(sockaddr_storage))) + { UlStatus = "UlConnection Failed!"; error("Client: connect failed! Error code: " + std::to_string(WSAGetLastError())); KillSocket(TCPSock); @@ -190,3 +159,40 @@ void TCPClientMain(const std::string& IP, int Port) { debug("(TCP) Client: WSACleanup() failed!..."); #endif } + +std::pair initSocket(std::string ip, int port, int sockType, sockaddr_storage* storeAddrInfo) { + int AF = (ip.find(':') != std::string::npos) ? AF_INET6 : AF_INET; + int code = 0; +#ifdef _WIN32 + WSADATA wsaData; + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { + std::cerr << "Can't start Winsock!" << std::endl; + return std::make_pair(INVALID_SOCKET, -1); + } +#endif + // Create the socket + SOCKET sock = socket(AF, sockType, (sockType == SOCK_STREAM) ? IPPROTO_TCP : IPPROTO_UDP); + + if (sock == -1) { + std::cerr << "Client: socket failed! Error code: %d\n" << WSAGetLastError() << std::endl; + WSACleanup(); + return std::make_pair(INVALID_SOCKET, -1); + } + + if (AF == AF_INET) { + // IPv4 + struct sockaddr_in* saddr = (sockaddr_in*) storeAddrInfo; + saddr->sin_family = AF_INET; + saddr->sin_port = htons(port); + inet_pton(AF_INET, ip.c_str(), &(saddr->sin_addr)); + + } else { + // IPv6 + struct sockaddr_in6 *saddr = (sockaddr_in6*) storeAddrInfo; + saddr->sin6_family = AF_INET6; + saddr->sin6_port = htons(port); + inet_pton(AF_INET6, ip.c_str(), &(saddr->sin6_addr)); + } + + return std::make_pair( sock, code); +} From 4534e44238c4fe57a5a2a161e622710a5dffd6ff Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 19 Aug 2024 13:18:28 +0200 Subject: [PATCH 20/29] Added INVALID_SOCKET macro for linux --- include/Network/network.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/Network/network.hpp b/include/Network/network.hpp index 55cf4ec4..a2e3e24c 100644 --- a/include/Network/network.hpp +++ b/include/Network/network.hpp @@ -23,6 +23,8 @@ #include #include #include + +#define INVALID_SOCKET -1 #endif void NetReset(); From 79069532bf230bcfc3f82474eb6f6c13bef03855 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 19 Aug 2024 15:07:04 +0200 Subject: [PATCH 21/29] Update Core to use initSocket --- src/Network/Core.cpp | 44 +++++++++++++++++--------------------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index b4879a1c..6ea3accb 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -265,41 +265,29 @@ void localRes() { } void CoreMain() { debug("Core Network on start!"); - SOCKET LSocket, CSocket; - struct addrinfo* res = nullptr; - struct addrinfo hints { }; - int iRes; #ifdef _WIN32 WSADATA wsaData; - iRes = WSAStartup(514, &wsaData); // 2.2 - if (iRes) - debug("WSAStartup failed with error: " + std::to_string(iRes)); + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { + error("Can't start Winsock!"); + return; + } #endif + SOCKET LSocket, CSocket; - ZeroMemory(&hints, sizeof(hints)); + struct sockaddr_storage loopBackLUA { }; - //IPv4 socket waiting handling LUA communications - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; + auto localSocketRes = initSocket("127.0.0.1", DEFAULT_PORT, SOCK_STREAM, &loopBackLUA); - //Fill for loopback ipv4 - iRes = getaddrinfo(nullptr, std::to_string(DEFAULT_PORT).c_str(), &hints, &res); - if (iRes) { - debug("(Core) addr info failed with error: " + std::to_string(iRes)); - WSACleanup(); - return; - } - //Create socket - LSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (LSocket == -1) { - debug("(Core) socket failed with error: " + std::to_string(WSAGetLastError())); - freeaddrinfo(res); - WSACleanup(); + if (localSocketRes.second != 0 || localSocketRes.first == INVALID_SOCKET) { + error("Client: LUA Loopback socket creation failed! Error code: " + std::to_string(WSAGetLastError())), + WSACleanup(); return; } - iRes = bind(LSocket, res->ai_addr, int(res->ai_addrlen)); - freeaddrinfo(res); + + LSocket = localSocketRes.first; + + int iRes = bind(LSocket, (sockaddr*)&loopBackLUA, sizeof(sockaddr_storage)); + if (iRes == SOCKET_ERROR) { error("(Core) bind failed with error: " + std::to_string(WSAGetLastError())); KillSocket(LSocket); @@ -313,6 +301,7 @@ void CoreMain() { WSACleanup(); return; } + //MAIN LOOP do { //Waiting LUA Connexion CSocket = accept(LSocket, nullptr, nullptr); @@ -325,6 +314,7 @@ void CoreMain() { GameHandler(CSocket); warn("Game reconnecting to LUA interface..."); } while (CSocket); + KillSocket(LSocket); WSACleanup(); } From 56d1d86a61124be160f6b3f78da5518ae1a53d70 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 19 Aug 2024 15:18:14 +0200 Subject: [PATCH 22/29] make Ressoucre use initSocket --- src/Network/Resources.cpp | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/src/Network/Resources.cpp b/src/Network/Resources.cpp index 6559c459..976562f5 100644 --- a/src/Network/Resources.cpp +++ b/src/Network/Resources.cpp @@ -176,36 +176,29 @@ void MultiKill(SOCKET Sock, SOCKET Sock1) { * Init the download socket. */ SOCKET InitDSock() { - int AF = (LastIP.find(':') != std::string::npos) ? AF_INET6 : AF_INET; - SOCKET DSock = socket(AF, SOCK_STREAM, IPPROTO_TCP); + struct sockaddr_storage serverDownload { }; - if (DSock < 1) { + auto result = initSocket(LastIP, LastPort, SOCK_STREAM, &serverDownload); + + SOCKET DSock = result.first; + + if (result.second != 0) { + UlStatus = "UlConnection Failed!"; + error("Client: download mods failed! Error code: " + std::to_string(WSAGetLastError())); KillSocket(DSock); + WSACleanup(); Terminate = true; - return 0; + return INVALID_SOCKET; } - - sockaddr_storage serverAddr; - memset(&serverAddr, 0, sizeof(sockaddr_storage)); - - if (AF == AF_INET) { - sockaddr_in* addr4 = (sockaddr_in*)&serverAddr; - addr4->sin_family = AF_INET; - addr4->sin_port = htons(LastPort); - inet_pton(AF_INET, LastIP.c_str(), &addr4->sin_addr); - } else if (AF == AF_INET6) { - sockaddr_in6* addr6 = (sockaddr_in6*)&serverAddr; - addr6->sin6_family = AF_INET6; - addr6->sin6_port = htons(LastPort); - inet_pton(AF_INET6, LastIP.c_str(), &addr6->sin6_addr); - } - - //Connect to the server - if (connect(DSock, (SOCKADDR*)&serverAddr, sizeof(sockaddr_storage)) != 0) { + // Try to connect to the distant server, using the socket created + if (connect(DSock, (struct sockaddr*)&serverDownload, sizeof(sockaddr_storage))) { + UlStatus = "UlConnection Failed!"; + error("Client: download mods failed! Error code: " + std::to_string(WSAGetLastError())); KillSocket(DSock); + WSACleanup(); Terminate = true; - return 0; + return INVALID_SOCKET; } char Code[2] = { 'D', char(ClientID) }; From 9d984e975aafbf856499e51337dd5f9040da4a96 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 19 Aug 2024 15:18:45 +0200 Subject: [PATCH 23/29] Added platform specific network error --- include/Logger.h | 2 ++ src/Logger.cpp | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/include/Logger.h b/include/Logger.h index c588789c..06a445cc 100644 --- a/include/Logger.h +++ b/include/Logger.h @@ -8,6 +8,7 @@ #pragma once #include #include + void InitLog(); void except(const std::string& toPrint); void fatal(const std::string& toPrint); @@ -15,4 +16,5 @@ void debug(const std::string& toPrint); void error(const std::string& toPrint); void info(const std::string& toPrint); void warn(const std::string& toPrint); +void neterror(const std::string& toPrint); std::string getDate(); diff --git a/src/Logger.cpp b/src/Logger.cpp index 557cec00..9585a6fc 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -13,6 +13,11 @@ #include #include +#ifdef WIN32 +#include +#endif // WIN32 + + std::string getDate() { time_t tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); tm local_tm = *localtime(&tt); @@ -82,3 +87,16 @@ void except(const std::string& toPrint) { std::cout << Print; addToLog(Print); } + +void neterror(const std::string& toPrint) { + std::string Print = getDate() + "[NET_ERROR] " + toPrint; +#ifdef WIN32 + int errorCode = WSAGetLastError(); + Print += " WSA error: " + std::to_string(WSAGetLastError()) + "\n"; +#else + int errorCode = errno; + Print += " System Error Code: " + std::to_string(errorCode) + " - " + std::strerror(errorCode) + "\n"; +#endif + std::cout << Print; + addToLog(Print); +} From c87a6cdd95427858c7400c6d41d1f5faa411cab5 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 19 Aug 2024 16:59:13 +0200 Subject: [PATCH 24/29] Simplify initSocket --- include/Network/network.hpp | 2 +- src/Network/VehicleEvent.cpp | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/include/Network/network.hpp b/include/Network/network.hpp index a2e3e24c..c00b682d 100644 --- a/include/Network/network.hpp +++ b/include/Network/network.hpp @@ -70,4 +70,4 @@ void TCPGameServer(const std::string& IP, int Port); * @param sockType : Type of the socket asked: SOCK_DGRAM or SOCK_STREAM * @param pStoreAddrInfo : A **valid** pointer to handle sockaddr informations used by the socket */ -std::pair initSocket(std::string ip, int port, int sockType, sockaddr_storage* pStoreAddrInfo); +SOCKET initSocket(std::string ip, int port, int sockType, sockaddr_storage* pStoreAddrInfo); diff --git a/src/Network/VehicleEvent.cpp b/src/Network/VehicleEvent.cpp index 75a739e8..ed744718 100644 --- a/src/Network/VehicleEvent.cpp +++ b/src/Network/VehicleEvent.cpp @@ -160,23 +160,15 @@ void TCPClientMain(const std::string& IP, int Port) { #endif } -std::pair initSocket(std::string ip, int port, int sockType, sockaddr_storage* storeAddrInfo) { +SOCKET initSocket(std::string ip, int port, int sockType, sockaddr_storage* storeAddrInfo) { int AF = (ip.find(':') != std::string::npos) ? AF_INET6 : AF_INET; - int code = 0; -#ifdef _WIN32 - WSADATA wsaData; - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { - std::cerr << "Can't start Winsock!" << std::endl; - return std::make_pair(INVALID_SOCKET, -1); - } -#endif + // Create the socket SOCKET sock = socket(AF, sockType, (sockType == SOCK_STREAM) ? IPPROTO_TCP : IPPROTO_UDP); if (sock == -1) { - std::cerr << "Client: socket failed! Error code: %d\n" << WSAGetLastError() << std::endl; - WSACleanup(); - return std::make_pair(INVALID_SOCKET, -1); + neterror("Client: socket creation failed!"); + return INVALID_SOCKET; } if (AF == AF_INET) { @@ -184,15 +176,23 @@ std::pair initSocket(std::string ip, int port, int sockType, sockad struct sockaddr_in* saddr = (sockaddr_in*) storeAddrInfo; saddr->sin_family = AF_INET; saddr->sin_port = htons(port); - inet_pton(AF_INET, ip.c_str(), &(saddr->sin_addr)); + if (inet_pton(AF_INET, ip.c_str(), &(saddr->sin_addr)) != 1) { + neterror("Client: inet_pton failed!"); + KillSocket(sock); + return INVALID_SOCKET; + } } else { // IPv6 struct sockaddr_in6 *saddr = (sockaddr_in6*) storeAddrInfo; saddr->sin6_family = AF_INET6; saddr->sin6_port = htons(port); - inet_pton(AF_INET6, ip.c_str(), &(saddr->sin6_addr)); + if(inet_pton(AF_INET6, ip.c_str(), &(saddr->sin6_addr)) != 1) { + neterror("Client: inet_pton failed!"); + KillSocket(sock); + return INVALID_SOCKET; + } } - return std::make_pair( sock, code); + return sock; } From 13c14cc1e0efe23df7c78339fb9a036dc7b1f1be Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 19 Aug 2024 17:01:53 +0200 Subject: [PATCH 25/29] Adapt new initSocket --- src/Network/Core.cpp | 4 ++-- src/Network/Resources.cpp | 11 ++++------- src/Network/VehicleData.cpp | 10 +++------- src/Network/VehicleEvent.cpp | 8 ++++---- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index 6ea3accb..f39e50f8 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -276,9 +276,9 @@ void CoreMain() { struct sockaddr_storage loopBackLUA { }; - auto localSocketRes = initSocket("127.0.0.1", DEFAULT_PORT, SOCK_STREAM, &loopBackLUA); + LSocket = initSocket("0.0.0.0", DEFAULT_PORT, SOCK_STREAM, &loopBackLUA); - if (localSocketRes.second != 0 || localSocketRes.first == INVALID_SOCKET) { + if (LSocket == INVALID_SOCKET) { error("Client: LUA Loopback socket creation failed! Error code: " + std::to_string(WSAGetLastError())), WSACleanup(); return; diff --git a/src/Network/Resources.cpp b/src/Network/Resources.cpp index 976562f5..3d244e5a 100644 --- a/src/Network/Resources.cpp +++ b/src/Network/Resources.cpp @@ -179,22 +179,19 @@ SOCKET InitDSock() { struct sockaddr_storage serverDownload { }; - auto result = initSocket(LastIP, LastPort, SOCK_STREAM, &serverDownload); + SOCKET DSock = initSocket(LastIP, LastPort, SOCK_STREAM, &serverDownload); - SOCKET DSock = result.first; - - if (result.second != 0) { + if (DSock == INVALID_SOCKET) { UlStatus = "UlConnection Failed!"; - error("Client: download mods failed! Error code: " + std::to_string(WSAGetLastError())); - KillSocket(DSock); WSACleanup(); + neterror("Client: Download socket creation failed."); Terminate = true; return INVALID_SOCKET; } // Try to connect to the distant server, using the socket created if (connect(DSock, (struct sockaddr*)&serverDownload, sizeof(sockaddr_storage))) { UlStatus = "UlConnection Failed!"; - error("Client: download mods failed! Error code: " + std::to_string(WSAGetLastError())); + neterror("Client: Connection to download mods failed!."); KillSocket(DSock); WSACleanup(); Terminate = true; diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index ec2fa0be..be075daf 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -81,20 +81,16 @@ void UDPClientMain(const std::string& IP, int Port) return; } #endif + UDPSock = initSocket(IP, Port, SOCK_DGRAM, &ToServer); - auto result = initSocket(IP, Port, SOCK_DGRAM, &ToServer); - - if (result.second != 0) { + if (UDPSock == INVALID_SOCKET) { UlStatus = "UlConnection Failed!"; - error("Client: connect failed! Error code: " + std::to_string(WSAGetLastError())); - KillSocket(TCPSock); WSACleanup(); + neterror("Client: Failed to create UDP socket."); Terminate = true; return; } - UDPSock = result.first; - //Send to the game client GameSend("P" + std::to_string(ClientID)); TCPSend("H", TCPSock); diff --git a/src/Network/VehicleEvent.cpp b/src/Network/VehicleEvent.cpp index ed744718..8f34048b 100644 --- a/src/Network/VehicleEvent.cpp +++ b/src/Network/VehicleEvent.cpp @@ -120,9 +120,9 @@ void TCPClientMain(const std::string& IP, int Port) { sockaddr_storage server {}; - auto result = initSocket(IP, Port, SOCK_STREAM, &server); - - if (result.second != 0) { + TCPSock = initSocket(IP, Port, SOCK_STREAM, &server); + + if (TCPSock == INVALID_SOCKET) { UlStatus = "UlConnection Failed!"; error("Client: connect failed! Error code: " + std::to_string(WSAGetLastError())); KillSocket(TCPSock); @@ -130,7 +130,7 @@ void TCPClientMain(const std::string& IP, int Port) { Terminate = true; return; } - TCPSock = result.first; + //Try to connect to the distant server, using the socket created if (connect(TCPSock, (struct sockaddr*)&server, sizeof(sockaddr_storage))) { From b91298f3107f7b5ec7ec92827be509e89295b322 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 19 Aug 2024 17:02:54 +0200 Subject: [PATCH 26/29] Use initSocket --- src/Network/GlobalHandler.cpp | 76 +++++++++++------------------------ 1 file changed, 24 insertions(+), 52 deletions(-) diff --git a/src/Network/GlobalHandler.cpp b/src/Network/GlobalHandler.cpp index 8059fe8a..48683b74 100644 --- a/src/Network/GlobalHandler.cpp +++ b/src/Network/GlobalHandler.cpp @@ -141,56 +141,6 @@ void NetReset() { GSocket = -1; } -SOCKET SetupListener() { - if (GSocket != -1) - return GSocket; - struct addrinfo* result = nullptr; - struct addrinfo hints { }; - int iRes; -#ifdef _WIN32 - WSADATA wsaData; - iRes = WSAStartup(514, &wsaData); // 2.2 - if (iRes != 0) { - error("(Proxy) WSAStartup failed with error: " + std::to_string(iRes)); - return -1; - } -#endif - ZeroMemory(&hints, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_flags = AI_PASSIVE; - iRes = getaddrinfo(nullptr, std::to_string(DEFAULT_PORT + 1).c_str(), &hints, &result); - if (iRes != 0) { - error("(Proxy) info failed with error: " + std::to_string(iRes)); - WSACleanup(); - } - GSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); - if (GSocket == -1) { - error("(Proxy) socket failed with error: " + std::to_string(WSAGetLastError())); - freeaddrinfo(result); - WSACleanup(); - return -1; - } - iRes = bind(GSocket, result->ai_addr, (int)result->ai_addrlen); - if (iRes == SOCKET_ERROR) { - error("(Proxy) bind failed with error: " + std::to_string(WSAGetLastError())); - freeaddrinfo(result); - KillSocket(GSocket); - WSACleanup(); - return -1; - } - freeaddrinfo(result); - iRes = listen(GSocket, SOMAXCONN); - if (iRes == SOCKET_ERROR) { - error("(Proxy) listen failed with error: " + std::to_string(WSAGetLastError())); - KillSocket(GSocket); - WSACleanup(); - return -1; - } - return GSocket; -} - void AutoPing() { while (!Terminate) { ServerSend("p", false); @@ -238,9 +188,30 @@ void NetMain(const std::string& IP, int Port) { } void TCPGameServer(const std::string& IP, int Port) { - GSocket = SetupListener(); - while (!TCPTerminate && GSocket != -1) { + struct sockaddr_storage loopBackTcp { }; + + GSocket = initSocket("127.0.0.1", DEFAULT_PORT + 1, SOCK_STREAM, &loopBackTcp); + + if (GSocket == INVALID_SOCKET) { + return; + } + + int iRes = bind(GSocket, (sockaddr*)&loopBackTcp, sizeof(sockaddr_storage)); + if (iRes == SOCKET_ERROR) { + neterror("(Proxy) LoopBack TCP bind failed!"); + KillSocket(GSocket); + return; + } + + iRes = listen(GSocket, SOMAXCONN); + if (iRes == SOCKET_ERROR) { + neterror("(Proxy) LoopBack TCP listen failed!"); + KillSocket(GSocket); + return; + } + + while (!TCPTerminate && GSocket != INVALID_SOCKET) { debug("MAIN LOOP OF GAME SERVER"); GConnected = false; if (!CServer) { @@ -254,6 +225,7 @@ void TCPGameServer(const std::string& IP, int Port) { std::thread Client(TCPClientMain, IP, Port); Client.detach(); } + CSocket = accept(GSocket, nullptr, nullptr); if (CSocket == -1) { debug("(Proxy) accept failed with error: " + std::to_string(WSAGetLastError())); From 981e213d8649d7ca0d0420bfa1aca004e2857a91 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 19 Aug 2024 17:03:26 +0200 Subject: [PATCH 27/29] use INVALID_SOCKET macro for coherence --- src/Network/GlobalHandler.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Network/GlobalHandler.cpp b/src/Network/GlobalHandler.cpp index 48683b74..693242c1 100644 --- a/src/Network/GlobalHandler.cpp +++ b/src/Network/GlobalHandler.cpp @@ -119,22 +119,24 @@ void ServerSend(std::string Data, bool Rel) { } void NetReset() { + debug("Network reset called"); TCPTerminate = false; GConnected = false; Terminate = false; UlStatus = "Ulstart"; MStatus = " "; - if (UDPSock != (SOCKET)(-1)) { + + if (UDPSock != INVALID_SOCKET) { debug("Terminating UDP Socket : " + std::to_string(TCPSock)); KillSocket(UDPSock); } UDPSock = -1; - if (TCPSock != (SOCKET)(-1)) { + if (TCPSock != INVALID_SOCKET) { debug("Terminating TCP Socket : " + std::to_string(TCPSock)); KillSocket(TCPSock); } TCPSock = -1; - if (GSocket != (SOCKET)(-1)) { + if (GSocket != INVALID_SOCKET) { debug("Terminating GTCP Socket : " + std::to_string(GSocket)); KillSocket(GSocket); } From bb9e14c865283929a6f37b4e459e522cceb7d19f Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 19 Aug 2024 18:28:13 +0200 Subject: [PATCH 28/29] Cleaned all WSACleanup and startup Based on Windows's documentation, the entire app need at least one WSAStarup call, other gonna juste increment a counter, for wich the app need the same number of WSACleanup. https://learn.microsoft.com/fr-fr/windows/win32/api/winsock/nf-winsock-wsastartup To simplify, and to increase a lot the visibility, the app will call one WSAStartup, and one WSACleanup at all. This is done on CoreNetwork function. --- include/Network/network.hpp | 2 + src/GameStart.cpp | 16 +++++--- src/Network/Core.cpp | 71 +++++++++++++++++------------------ src/Network/DNS.cpp | 18 +-------- src/Network/GlobalHandler.cpp | 6 +-- src/Network/Resources.cpp | 2 - src/Network/VehicleData.cpp | 10 +---- src/Network/VehicleEvent.cpp | 14 ++----- 8 files changed, 56 insertions(+), 83 deletions(-) diff --git a/include/Network/network.hpp b/include/Network/network.hpp index c00b682d..2c91da1b 100644 --- a/include/Network/network.hpp +++ b/include/Network/network.hpp @@ -32,6 +32,8 @@ extern bool Dev; extern int ping; [[noreturn]] void CoreNetwork(); +extern SOCKET LSocket; +extern bool shuttingdown; extern int ProxyPort; extern int ClientID; extern int LastPort; diff --git a/src/GameStart.cpp b/src/GameStart.cpp index 6e49db92..22b456f5 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -6,6 +6,8 @@ /// Created by Anonymous275 on 7/19/2020 /// +#include "Network/network.hpp" + #if defined(_WIN32) #include #elif defined(__linux__) @@ -83,12 +85,14 @@ void StartGame(std::string Dir) { info("Game Launched!"); GamePID = pi.dwProcessId; WaitForSingleObject(pi.hProcess, INFINITE); - error("Game Closed! launcher closing soon"); + warn("Game Closed! launcher closing soon"); } else { error("Failed to Launch the game! launcher closing soon"); } - std::this_thread::sleep_for(std::chrono::seconds(5)); - exit(2); + + shuttingdown = true; + if (LSocket != INVALID_SOCKET) + KillSocket(LSocket); } #elif defined(__linux__) void StartGame(std::string Dir) { @@ -105,9 +109,9 @@ void StartGame(std::string Dir) { waitpid(pid, &status, 0); error("Game Closed! launcher closing soon"); } - - std::this_thread::sleep_for(std::chrono::seconds(5)); - exit(2); + shuttingdown = true; + if (LSocket != INVALID_SOCKET) + KillSocket(LSocket); } #endif diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index f39e50f8..138d36e6 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -5,8 +5,9 @@ /// /// Created by Anonymous275 on 7/20/2020 /// -#include "Http.h" + #include "Network/network.hpp" +#include "Http.h" #include "Security/Init.h" #include #include @@ -44,11 +45,11 @@ std::string UlStatus; std::string MStatus; bool ModLoaded; int ping = -1; +bool shuttingdown = false; +SOCKET LSocket = INVALID_SOCKET; void StartSync(const std::string& Data) { - //const std::regex ipv4v6Pattern(R"(((^\h*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\h*(|/([0-9]|[1-2][0-9]|3[0-2]))$)|(^\h*((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\h*(|/([0-9]|[0-9][0-9]|1[0-1][0-9]|12[0-8]))$)))"); - std::string host = Data.substr(1, Data.rfind(':') - 1); uint16_t port = std::stoi(Data.substr(Data.rfind(':') + 1)); @@ -192,7 +193,7 @@ void Parse(std::string Data, SOCKET CSocket) { if (UserID != -1) { Auth["id"] = UserID; } - Data = "N" + Auth.dump(); + Data = "N" + Auth.dump(); } else { Data = "N" + Login(Data.substr(Data.find(':') + 1)); } @@ -265,40 +266,31 @@ void localRes() { } void CoreMain() { debug("Core Network on start!"); -#ifdef _WIN32 - WSADATA wsaData; - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { - error("Can't start Winsock!"); - return; - } -#endif - SOCKET LSocket, CSocket; + + SOCKET CSocket; struct sockaddr_storage loopBackLUA { }; LSocket = initSocket("0.0.0.0", DEFAULT_PORT, SOCK_STREAM, &loopBackLUA); if (LSocket == INVALID_SOCKET) { - error("Client: LUA Loopback socket creation failed! Error code: " + std::to_string(WSAGetLastError())), - WSACleanup(); + neterror("(Core) Client LUA Loopback socket creation failed!"); return; } - LSocket = localSocketRes.first; - int iRes = bind(LSocket, (sockaddr*)&loopBackLUA, sizeof(sockaddr_storage)); if (iRes == SOCKET_ERROR) { - error("(Core) bind failed with error: " + std::to_string(WSAGetLastError())); + neterror("(Core) Client LUA Loopback socket binding failed!"); KillSocket(LSocket); - WSACleanup(); + shuttingdown = true; + warn("Maybe your game is already launched!"); return; } iRes = listen(LSocket, SOMAXCONN); if (iRes == SOCKET_ERROR) { - debug("(Core) listen failed with error: " + std::to_string(WSAGetLastError())); + debug("(Core) Client LUA Loopback socket listen failed!"); KillSocket(LSocket); - WSACleanup(); return; } //MAIN LOOP @@ -306,17 +298,18 @@ void CoreMain() { //Waiting LUA Connexion CSocket = accept(LSocket, nullptr, nullptr); if (CSocket == -1) { - error("(Core) accept failed with error: " + std::to_string(WSAGetLastError())); + if (shuttingdown) + break; + neterror("(Core) Client LUA Loopback socket accept failed!"); continue; } localRes(); info("Game Connected to LUA interface!"); GameHandler(CSocket); warn("Game reconnecting to LUA interface..."); - } while (CSocket); + } while (LSocket != INVALID_SOCKET); KillSocket(LSocket); - WSACleanup(); } #if defined(_WIN32) @@ -330,22 +323,28 @@ int Handle(EXCEPTION_POINTERS* ep) { #endif [[noreturn]] void CoreNetwork() { - while (true) { -#if not defined(__MINGW32__) - __try { -#endif - - CoreMain(); -#if not defined(__MINGW32__) and not defined(__linux__) - } __except (Handle(GetExceptionInformation())) { } -#elif not defined(__MINGW32__) and defined(__linux__) - } - catch (...) { - except("(Core) Code : " + std::string(strerror(errno))); +#ifdef WIN32 + WSADATA wsaData; + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { + fatal("(CoreNetwork) Can't start Winsock!"); } #endif - std::this_thread::sleep_for(std::chrono::seconds(1)); + while (!shuttingdown) { + try { + CoreMain(); + } catch (const std::exception& e) { + except("(Core) Fatal Execption: " + std::string(e.what())); +#ifdef WIN32 + WSACleanup(); +#endif + } catch (...) { + except("(Core) Code : " + std::string(strerror(errno))); + } } + +#ifdef _WIN32 + WSACleanup(); +#endif } diff --git a/src/Network/DNS.cpp b/src/Network/DNS.cpp index 0034d4a7..06d2f6ae 100644 --- a/src/Network/DNS.cpp +++ b/src/Network/DNS.cpp @@ -30,27 +30,14 @@ std::string resolveHost(const std::string& hostStr) { std::string resolved = ""; -#ifdef _WIN32 - WSADATA wsaData; - if (WSAStartup(514, &wsaData) != 0) { - error("WSA Startup Failed!"); - WSACleanup(); - return resolved; - } -#endif // UNSPEC to resolve both ip stack (IPv4 & IPv6) hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; - int res = getaddrinfo(hostStr.c_str(), nullptr, &hints, &addresses); - if (res != 0) + if (getaddrinfo(hostStr.c_str(), nullptr, &hints, &addresses) != 0) { - std::cerr << "getaddrinfo failed: " << gai_strerror(res) << std::endl; -#ifdef _WIN32 - WSACleanup(); -#endif - freeaddrinfo(addresses); + neterror("(DNS) getaddrinfo failed."); return resolved; } @@ -72,6 +59,5 @@ std::string resolveHost(const std::string& hostStr) { } freeaddrinfo(addresses); - WSACleanup(); return resolved; } \ No newline at end of file diff --git a/src/Network/GlobalHandler.cpp b/src/Network/GlobalHandler.cpp index 693242c1..2e07365c 100644 --- a/src/Network/GlobalHandler.cpp +++ b/src/Network/GlobalHandler.cpp @@ -29,8 +29,8 @@ std::chrono::time_point PingStart, PingEnd; bool GConnected = false; bool CServer = true; -SOCKET CSocket = -1; -SOCKET GSocket = -1; +SOCKET CSocket = INVALID_SOCKET; +SOCKET GSocket = INVALID_SOCKET; int ClientID = -1; int KillSocket(uint64_t Dead) { @@ -40,7 +40,7 @@ int KillSocket(uint64_t Dead) { } shutdown(Dead, SD_BOTH); int a = closesocket(Dead); - if (a != 0) { + if (a != 0 && !shuttingdown) { warn("Failed to close socket!"); } return a; diff --git a/src/Network/Resources.cpp b/src/Network/Resources.cpp index 3d244e5a..5d4ce85b 100644 --- a/src/Network/Resources.cpp +++ b/src/Network/Resources.cpp @@ -183,7 +183,6 @@ SOCKET InitDSock() { if (DSock == INVALID_SOCKET) { UlStatus = "UlConnection Failed!"; - WSACleanup(); neterror("Client: Download socket creation failed."); Terminate = true; return INVALID_SOCKET; @@ -193,7 +192,6 @@ SOCKET InitDSock() { UlStatus = "UlConnection Failed!"; neterror("Client: Connection to download mods failed!."); KillSocket(DSock); - WSACleanup(); Terminate = true; return INVALID_SOCKET; } diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index be075daf..a483b6ef 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -74,18 +74,10 @@ void UDPRcv() { void UDPClientMain(const std::string& IP, int Port) { -#ifdef _WIN32 - WSADATA data; - if (WSAStartup(514, &data)) { - error("Can't start Winsock!"); - return; - } -#endif UDPSock = initSocket(IP, Port, SOCK_DGRAM, &ToServer); if (UDPSock == INVALID_SOCKET) { UlStatus = "UlConnection Failed!"; - WSACleanup(); neterror("Client: Failed to create UDP socket."); Terminate = true; return; @@ -98,6 +90,6 @@ void UDPClientMain(const std::string& IP, int Port) //Main loop while (!Terminate) UDPRcv(); + KillSocket(UDPSock); - WSACleanup(); } diff --git a/src/Network/VehicleEvent.cpp b/src/Network/VehicleEvent.cpp index 8f34048b..8db75b13 100644 --- a/src/Network/VehicleEvent.cpp +++ b/src/Network/VehicleEvent.cpp @@ -31,6 +31,7 @@ bool CheckBytes(int32_t Bytes) { } return true; } + void UUl(const std::string& R) { UlStatus = "UlDisconnected: " + R; } @@ -124,9 +125,6 @@ void TCPClientMain(const std::string& IP, int Port) { if (TCPSock == INVALID_SOCKET) { UlStatus = "UlConnection Failed!"; - error("Client: connect failed! Error code: " + std::to_string(WSAGetLastError())); - KillSocket(TCPSock); - WSACleanup(); Terminate = true; return; } @@ -135,9 +133,8 @@ void TCPClientMain(const std::string& IP, int Port) { if (connect(TCPSock, (struct sockaddr*)&server, sizeof(sockaddr_storage))) { UlStatus = "UlConnection Failed!"; - error("Client: connect failed! Error code: " + std::to_string(WSAGetLastError())); + neterror("Client: connect to server failed!"); KillSocket(TCPSock); - WSACleanup(); Terminate = true; return; } @@ -152,12 +149,7 @@ void TCPClientMain(const std::string& IP, int Port) { GameSend("T"); ////Game Send Terminate if (KillSocket(TCPSock) != 0) - debug("(TCP) Cannot close socket. Error code: " + std::to_string(WSAGetLastError())); - -#ifdef _WIN32 - if (WSACleanup() != 0) - debug("(TCP) Client: WSACleanup() failed!..."); -#endif + neterror("(TCP) Cannot close socket."); } SOCKET initSocket(std::string ip, int port, int sockType, sockaddr_storage* storeAddrInfo) { From 625116d5534928b2aee59e231a72d0d2a4ee9886 Mon Sep 17 00:00:00 2001 From: "Nathan J." Date: Mon, 19 Aug 2024 18:33:12 +0200 Subject: [PATCH 29/29] Linux small ajustement --- src/Logger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Logger.cpp b/src/Logger.cpp index 9585a6fc..de910569 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -95,7 +95,7 @@ void neterror(const std::string& toPrint) { Print += " WSA error: " + std::to_string(WSAGetLastError()) + "\n"; #else int errorCode = errno; - Print += " System Error Code: " + std::to_string(errorCode) + " - " + std::strerror(errorCode) + "\n"; + Print += " System Error Code: " + std::to_string(errorCode) + "\n"; #endif std::cout << Print; addToLog(Print);