From a82b9fb36f48071a8069edf5fe361a590b44c159 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Mon, 17 Jun 2024 22:01:15 +0200 Subject: [PATCH] reformat --- include/Http.h | 7 +- include/Logger.h | 2 +- include/Network/network.hpp | 14 +- include/Security/Init.h | 2 +- include/Startup.h | 4 +- include/linuxfixes.h | 2 +- src/Compressor.cpp | 28 +-- src/Config.cpp | 47 ++--- src/GameStart.cpp | 75 +++----- src/Logger.cpp | 34 ++-- src/Network/Core.cpp | 314 ++++++++++++++++---------------- src/Network/DNS.cpp | 21 +-- src/Network/GlobalHandler.cpp | 223 ++++++++++++----------- src/Network/Http.cpp | 267 ++++++++++++++------------- src/Network/Resources.cpp | 243 +++++++++++++------------ src/Network/VehicleData.cpp | 72 ++++---- src/Network/VehicleEvent.cpp | 132 +++++++------- src/Security/BeamNG.cpp | 327 ++++++++++++++++++---------------- src/Security/Login.cpp | 62 +++---- src/Startup.cpp | 214 ++++++++++++---------- src/main.cpp | 12 +- 21 files changed, 1085 insertions(+), 1017 deletions(-) diff --git a/include/Http.h b/include/Http.h index 69ab403..55a32a8 100644 --- a/include/Http.h +++ b/include/Http.h @@ -6,14 +6,15 @@ /// Created by Anonymous275 on 7/18/2020 /// #pragma once -#include #include "Logger.h" +#include class HTTP { public: - static bool Download(const std::string &IP, const std::string &Path); + static bool Download(const std::string& IP, const std::string& Path); static std::string Post(const std::string& IP, const std::string& Fields); - static std::string Get(const std::string &IP); + static std::string Get(const std::string& IP); static bool ProgressBar(size_t c, size_t t); + public: static bool isDownload; }; \ No newline at end of file diff --git a/include/Logger.h b/include/Logger.h index aa948e3..c588789 100644 --- a/include/Logger.h +++ b/include/Logger.h @@ -6,8 +6,8 @@ /// Created by Anonymous275 on 4/2/2020. /// #pragma once -#include #include +#include void InitLog(); void except(const std::string& toPrint); void fatal(const std::string& toPrint); diff --git a/include/Network/network.hpp b/include/Network/network.hpp index df19206..6743966 100644 --- a/include/Network/network.hpp +++ b/include/Network/network.hpp @@ -6,19 +6,16 @@ /// Created by Anonymous275 on 7/18/2020 /// - #pragma once #include #ifdef __linux__ -#include #include "linuxfixes.h" #include +#include #include #endif - - void NetReset(); extern bool Dev; extern int ping; @@ -48,11 +45,10 @@ void GameSend(std::string 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 GetAddr(const std::string& IP); void ServerParser(const std::string& Data); std::string Login(const std::string& fields); -void TCPSend(const std::string&Data,uint64_t Sock); -void TCPClientMain(const std::string& IP,int Port); -void UDPClientMain(const std::string& IP,int Port); +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); - diff --git a/include/Security/Init.h b/include/Security/Init.h index c6f3db7..06dbf36 100644 --- a/include/Security/Init.h +++ b/include/Security/Init.h @@ -8,7 +8,7 @@ #pragma once #include void PreGame(const std::string& GamePath); -std::string CheckVer(const std::string &path); +std::string CheckVer(const std::string& path); void InitGame(const std::string& Dir); std::string GetGameDir(); void LegitimacyCheck(); diff --git a/include/Startup.h b/include/Startup.h index 7487146..6f91963 100644 --- a/include/Startup.h +++ b/include/Startup.h @@ -6,12 +6,12 @@ /// Created by Anonymous275 on 7/18/2020 /// #pragma once -#include #include +#include #include void InitLauncher(int argc, char* argv[]); -std::string GetEP(char*P = nullptr); +std::string GetEP(char* P = nullptr); std::string GetGamePath(); std::string GetVer(); std::string GetEN(); diff --git a/include/linuxfixes.h b/include/linuxfixes.h index c3fc21d..730e880 100644 --- a/include/linuxfixes.h +++ b/include/linuxfixes.h @@ -11,7 +11,7 @@ #define closesocket close #define SD_BOTH SHUT_RDWR // We dont need wsacleanup -#define WSACleanup() +#define WSACleanup() #define SOCKET_ERROR -1 #define ZeroMemory(mem, len) memset(mem, 0, len) diff --git a/src/Compressor.cpp b/src/Compressor.cpp index 436dccc..ea3320f 100644 --- a/src/Compressor.cpp +++ b/src/Compressor.cpp @@ -13,45 +13,45 @@ #endif #define Biggest 30000 -std::string Comp(std::string Data){ - char*C = new char[Biggest]; +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.next_in = (Bytef*)&Data[0]; defstream.avail_out = Biggest; - defstream.next_out = reinterpret_cast(C); + 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; + std::string Ret(TO, 0); + memcpy(&Ret[0], C, TO); + delete[] C; return Ret; } -std::string DeComp(std::string Compressed){ - char*C = new char[Biggest]; +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.next_in = (Bytef*)(&Compressed[0]); infstream.avail_out = Biggest; - infstream.next_out = (Bytef *)(C); + 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; + std::string Ret(TO, 0); + memcpy(&Ret[0], C, TO); + delete[] C; return Ret; } \ No newline at end of file diff --git a/src/Config.cpp b/src/Config.cpp index a92ddb0..b2125cf 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -2,57 +2,58 @@ /// Created by Anonymous275 on 2/23/2021 /// -#include -#include "Network/network.hpp" -#include #include "Logger.h" -#include +#include "Network/network.hpp" #include +#include +#include +#include namespace fs = std::filesystem; std::string Branch; -void ParseConfig(const nlohmann::json& d){ - if(d["Port"].is_number()){ +void ParseConfig(const nlohmann::json& d) { + if (d["Port"].is_number()) { DEFAULT_PORT = d["Port"].get(); } - //Default -1 - //Release 1 - //EA 2 - //Dev 3 - //Custom 3 + // Default -1 + // Release 1 + // EA 2 + // Dev 3 + // Custom 3 - if(d["Build"].is_string()){ + if (d["Build"].is_string()) { Branch = d["Build"].get(); - for(char& c : Branch)c = char(tolower(c)); + for (char& c : Branch) + c = char(tolower(c)); } } -void ConfigInit(){ - if(fs::exists("Launcher.cfg")){ +void ConfigInit() { + if (fs::exists("Launcher.cfg")) { std::ifstream cfg("Launcher.cfg"); - if(cfg.is_open()){ + if (cfg.is_open()) { auto Size = fs::file_size("Launcher.cfg"); std::string Buffer(Size, 0); cfg.read(&Buffer[0], Size); cfg.close(); nlohmann::json d = nlohmann::json::parse(Buffer, nullptr, false); - if(d.is_discarded()){ + if (d.is_discarded()) { fatal("Config failed to parse make sure it's valid JSON!"); } ParseConfig(d); - }else fatal("Failed to open Launcher.cfg!"); - }else{ + } else + fatal("Failed to open Launcher.cfg!"); + } else { std::ofstream cfg("Launcher.cfg"); - if(cfg.is_open()){ + if (cfg.is_open()) { cfg << - R"({ + R"({ "Port": 4444, "Build": "Default" })"; cfg.close(); - }else{ + } else { fatal("Failed to write config on disk!"); } } } - diff --git a/src/GameStart.cpp b/src/GameStart.cpp index a86fd6f..ac99d63 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -6,83 +6,83 @@ /// Created by Anonymous275 on 7/19/2020 /// - #if defined(_WIN32) #include #elif defined(__linux__) #include "vdf_parser.hpp" #include -#include -#include -#include #include +#include +#include +#include #endif +#include "Logger.h" +#include "Startup.h" #include #include -#include "Startup.h" -#include "Logger.h" #include unsigned long GamePID = 0; #if defined(_WIN32) -std::string QueryKey(HKEY hKey,int ID); -std::string GetGamePath(){ +std::string QueryKey(HKEY hKey, int ID); +std::string GetGamePath() { static std::string Path; - if(!Path.empty())return Path; + if (!Path.empty()) + return Path; HKEY hKey; LPCTSTR sk = "Software\\BeamNG\\BeamNG.drive"; LONG openRes = RegOpenKeyEx(HKEY_CURRENT_USER, sk, 0, KEY_ALL_ACCESS, &hKey); - if (openRes != ERROR_SUCCESS){ + if (openRes != ERROR_SUCCESS) { fatal("Please launch the game at least once!"); } - Path = QueryKey(hKey,4); + Path = QueryKey(hKey, 4); - if(Path.empty()){ + if (Path.empty()) { sk = R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders)"; openRes = RegOpenKeyEx(HKEY_CURRENT_USER, sk, 0, KEY_ALL_ACCESS, &hKey); - if (openRes != ERROR_SUCCESS){ - fatal("Cannot get Local Appdata directory!"); + if (openRes != ERROR_SUCCESS) { + fatal("Cannot get Local Appdata directory!"); } - Path = QueryKey(hKey,5); + Path = QueryKey(hKey, 5); Path += "\\BeamNG.drive\\"; } std::string Ver = CheckVer(GetGameDir()); - Ver = Ver.substr(0,Ver.find('.',Ver.find('.')+1)); + Ver = Ver.substr(0, Ver.find('.', Ver.find('.') + 1)); Path += Ver + "\\"; return Path; } #elif defined(__linux__) -std::string GetGamePath(){ +std::string GetGamePath() { // Right now only steam is supported - struct passwd *pw = getpwuid(getuid()); + struct passwd* pw = getpwuid(getuid()); std::string homeDir = pw->pw_dir; - + std::string Path = homeDir + "/.local/share/BeamNG.drive/"; std::string Ver = CheckVer(GetGameDir()); - Ver = Ver.substr(0,Ver.find('.',Ver.find('.')+1)); + Ver = Ver.substr(0, Ver.find('.', Ver.find('.') + 1)); Path += Ver + "/"; return Path; } #endif #if defined(_WIN32) -void StartGame(std::string Dir){ +void StartGame(std::string Dir) { BOOL bSuccess = FALSE; PROCESS_INFORMATION pi; - STARTUPINFO si = {0}; + STARTUPINFO si = { 0 }; si.cb = sizeof(si); std::string BaseDir = Dir; //+"\\Bin64"; - //Dir += R"(\Bin64\BeamNG.drive.x64.exe)"; + // Dir += R"(\Bin64\BeamNG.drive.x64.exe)"; Dir += "\\BeamNG.drive.exe"; bSuccess = CreateProcessA(Dir.c_str(), nullptr, nullptr, nullptr, TRUE, 0, nullptr, BaseDir.c_str(), &si, &pi); - if (bSuccess){ + if (bSuccess) { info("Game Launched!"); GamePID = pi.dwProcessId; WaitForSingleObject(pi.hProcess, INFINITE); error("Game Closed! launcher closing soon"); - }else{ + } else { error("Failed to Launch the game! launcher closing soon"); } std::this_thread::sleep_for(std::chrono::seconds(5)); @@ -92,26 +92,7 @@ void StartGame(std::string Dir){ void StartGame(std::string Dir) { int status; std::string filename = (Dir + "/BinLinux/BeamNG.drive.x64"); - char *argv[] = {filename.data(), NULL}; - pid_t pid; - int result = posix_spawn(&pid, filename.c_str(), NULL, NULL, argv, environ); - - if (result != 0) { - error("Failed to Launch the game! launcher closing soon"); - return; - } else { - waitpid(pid, &status, 0); - error("Game Closed! launcher closing soon"); - } - - std::this_thread::sleep_for(std::chrono::seconds(5)); - exit(2); -} -#endif -void StartGame(std::string Dir) { - int status; - std::string filename = (Dir + "/BinLinux/BeamNG.drive.x64"); - char *argv[] = {filename.data(), NULL}; + char* argv[] = { filename.data(), NULL }; pid_t pid; int result = posix_spawn(&pid, filename.c_str(), NULL, NULL, argv, environ); @@ -128,8 +109,8 @@ void StartGame(std::string Dir) { } #endif -void InitGame(const std::string& Dir){ - if(!Dev){ +void InitGame(const std::string& Dir) { + if (!Dev) { std::thread Game(StartGame, Dir); Game.detach(); } diff --git a/src/Logger.cpp b/src/Logger.cpp index e23bf9a..557cec0 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -6,11 +6,11 @@ /// Created by Anonymous275 on 7/17/2020 /// -#include "Startup.h" #include "Logger.h" +#include "Startup.h" +#include #include #include -#include #include std::string getDate() { @@ -24,24 +24,25 @@ std::string getDate() { std::string Min = (M > 9 ? std::to_string(M) : "0" + std::to_string(M)); std::string Hour = (H > 9 ? std::to_string(H) : "0" + std::to_string(H)); date - << "[" - << local_tm.tm_mday << "/" - << local_tm.tm_mon + 1 << "/" - << local_tm.tm_year + 1900 << " " - << Hour << ":" - << Min << ":" - << Secs - << "] "; + << "[" + << local_tm.tm_mday << "/" + << local_tm.tm_mon + 1 << "/" + << local_tm.tm_year + 1900 << " " + << Hour << ":" + << Min << ":" + << Secs + << "] "; return date.str(); } -void InitLog(){ +void InitLog() { std::ofstream LFS; LFS.open(GetEP() + "Launcher.log"); - if(!LFS.is_open()){ + if (!LFS.is_open()) { error("logger file init failed!"); - }else LFS.close(); + } else + LFS.close(); } -void addToLog(const std::string& Line){ +void addToLog(const std::string& Line) { std::ofstream LFS; LFS.open(GetEP() + "Launcher.log", std::ios_base::app); LFS << Line.c_str(); @@ -53,12 +54,13 @@ void info(const std::string& toPrint) { addToLog(Print); } void debug(const std::string& toPrint) { - if(!Dev)return; + if (!Dev) + return; std::string Print = getDate() + "[DEBUG] " + toPrint + "\n"; std::cout << Print; addToLog(Print); } -void warn(const std::string& toPrint){ +void warn(const std::string& toPrint) { std::string Print = getDate() + "[WARN] " + toPrint + "\n"; std::cout << Print; addToLog(Print); diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index 430097f..46d4a1f 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -5,28 +5,28 @@ /// /// Created by Anonymous275 on 7/20/2020 /// +#include "Http.h" #include "Network/network.hpp" #include "Security/Init.h" #include -#include "Http.h" #if defined(_WIN32) #include #include #elif defined(__linux__) -#include -#include -#include #include #include +#include +#include +#include #endif -#include "Startup.h" #include "Logger.h" -#include +#include "Startup.h" #include -#include +#include #include +#include extern int TraceBack; std::set* ConfList = nullptr; @@ -41,11 +41,13 @@ std::string MStatus; 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)"; +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; @@ -56,7 +58,7 @@ void StartSync(const std::string &Data){ Terminate = false; ConfList->clear(); ping = -1; - std::thread GS(TCPGameServer,IP,std::stoi(Data.substr(Data.find(':')+1))); + std::thread GS(TCPGameServer, IP, std::stoi(Data.substr(Data.find(':') + 1))); GS.detach(); info("Connecting to server"); } @@ -64,138 +66,150 @@ void StartSync(const std::string &Data){ bool IsAllowedLink(const std::string& Link) { std::regex link_pattern(R"(https:\/\/(?:\w+)?(?:\.)?(?:beammp\.com|discord\.gg))"); std::smatch link_match; - return std::regex_search(Link,link_match, link_pattern) && link_match.position() == 0; + return std::regex_search(Link, link_match, link_pattern) && link_match.position() == 0; } -void Parse(std::string Data,SOCKET CSocket){ +void Parse(std::string Data, SOCKET CSocket) { char Code = Data.at(0), SubCode = 0; - if(Data.length() > 1)SubCode = Data.at(1); - switch (Code){ - case 'A': - Data = Data.substr(0,1); - break; - case 'B': + if (Data.length() > 1) + SubCode = Data.at(1); + switch (Code) { + case 'A': + Data = Data.substr(0, 1); + break; + case 'B': + NetReset(); + Terminate = true; + TCPTerminate = true; + Data = Code + HTTP::Get("https://backend.beammp.com/servers-info"); + break; + case 'C': + ListOfMods.clear(); + StartSync(Data); + while (ListOfMods.empty() && !Terminate) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + if (ListOfMods == "-") + Data = "L"; + else + Data = "L" + ListOfMods; + break; + case 'O': // open default browser with URL + if (IsAllowedLink(Data.substr(1))) { + ShellExecuteA(nullptr, "open", Data.substr(1).c_str(), nullptr, nullptr, SW_SHOW); /// TODO: Look at when working on linux port + info("Opening Link \"" + Data.substr(1) + "\""); + } + Data.clear(); + break; + case 'P': + Data = Code + std::to_string(ProxyPort); + break; + case 'U': + if (SubCode == 'l') + Data = UlStatus; + if (SubCode == 'p') { + if (ping > 800) { + Data = "Up-2"; + } else + Data = "Up" + std::to_string(ping); + } + if (!SubCode) { + std::string Ping; + if (ping > 800) + Ping = "-2"; + else + Ping = std::to_string(ping); + Data = std::string(UlStatus) + "\n" + "Up" + Ping; + } + break; + case 'M': + Data = MStatus; + break; + case 'Q': + if (SubCode == 'S') { NetReset(); Terminate = true; TCPTerminate = true; - Data = Code + HTTP::Get("https://backend.beammp.com/servers-info"); - break; - case 'C': - ListOfMods.clear(); - StartSync(Data); - while(ListOfMods.empty() && !Terminate){ - std::this_thread::sleep_for(std::chrono::seconds(1)); + ping = -1; + } + if (SubCode == 'G') + exit(2); + Data.clear(); + break; + case 'R': // will send mod name + if (ConfList->find(Data) == ConfList->end()) { + ConfList->insert(Data); + ModLoaded = true; + } + Data.clear(); + break; + case 'Z': + Data = "Z" + GetVer(); + break; + case 'N': + if (SubCode == 'c') { + nlohmann::json Auth = { + { "Auth", LoginAuth ? 1 : 0 }, + }; + if (!Username.empty()) { + Auth["username"] = Username; } - if(ListOfMods == "-")Data = "L"; - else Data = "L"+ListOfMods; - break; - case 'O': //open default browser with URL - if(IsAllowedLink(Data.substr(1))) { - ShellExecuteA(nullptr, "open", Data.substr(1).c_str(), nullptr, nullptr,SW_SHOW); ///TODO: Look at when working on linux port - info("Opening Link \"" + Data.substr(1) + "\""); + if (!UserRole.empty()) { + Auth["role"] = UserRole; } - Data.clear(); - break; - case 'P': - Data = Code + std::to_string(ProxyPort); - break; - case 'U': - if(SubCode == 'l')Data = UlStatus; - if(SubCode == 'p'){ - if(ping > 800){ - Data = "Up-2"; - }else Data = "Up" + std::to_string(ping); - } - if(!SubCode){ - std::string Ping; - if(ping > 800)Ping = "-2"; - else Ping = std::to_string(ping); - Data = std::string(UlStatus) + "\n" + "Up" + Ping; - } - break; - case 'M': - Data = MStatus; - break; - case 'Q': - if(SubCode == 'S'){ - NetReset(); - Terminate = true; - TCPTerminate = true; - ping = -1; - } - if(SubCode == 'G')exit(2); - Data.clear(); - break; - case 'R': //will send mod name - if(ConfList->find(Data) == ConfList->end()){ - ConfList->insert(Data); - ModLoaded = true; - } - Data.clear(); - break; - case 'Z': - Data = "Z" + GetVer(); - break; - case 'N': - if (SubCode == 'c'){ - nlohmann::json Auth = { - {"Auth", LoginAuth ? 1 : 0 }, - }; - if (!Username.empty()) { - Auth["username"] = Username; - } - if (!UserRole.empty()) { - Auth["role"] = UserRole; - } - Data = Auth.dump(); - }else{ - Data = "N" + Login(Data.substr(Data.find(':') + 1)); - } - break; - default: - Data.clear(); - break; + Data = Auth.dump(); + } else { + Data = "N" + Login(Data.substr(Data.find(':') + 1)); + } + break; + default: + Data.clear(); + break; } - if(!Data.empty() && CSocket != -1){ - int res = send(CSocket, (Data+"\n").c_str(), int(Data.size())+1, 0); - if(res < 0){ + if (!Data.empty() && CSocket != -1) { + int res = send(CSocket, (Data + "\n").c_str(), int(Data.size()) + 1, 0); + if (res < 0) { debug("(Core) send failed with error: " + std::to_string(WSAGetLastError())); } } } -void GameHandler(SOCKET Client){ +void GameHandler(SOCKET Client) { - int32_t Size,Temp,Rcv; - char Header[10] = {0}; - do{ + int32_t Size, Temp, Rcv; + char Header[10] = { 0 }; + do { Rcv = 0; - do{ - Temp = recv(Client,&Header[Rcv],1,0); - if(Temp < 1)break; - if(!isdigit(Header[Rcv]) && Header[Rcv] != '>') { + do { + Temp = recv(Client, &Header[Rcv], 1, 0); + if (Temp < 1) + break; + if (!isdigit(Header[Rcv]) && Header[Rcv] != '>') { error("(Core) Invalid lua communication"); KillSocket(Client); return; } - }while(Header[Rcv++] != '>'); - if(Temp < 1)break; - if(std::from_chars(Header,&Header[Rcv],Size).ptr[0] != '>'){ - debug("(Core) Invalid lua Header -> " + std::string(Header,Rcv)); + } while (Header[Rcv++] != '>'); + if (Temp < 1) + break; + if (std::from_chars(Header, &Header[Rcv], Size).ptr[0] != '>') { + debug("(Core) Invalid lua Header -> " + std::string(Header, Rcv)); break; } - std::string Ret(Size,0); + std::string Ret(Size, 0); Rcv = 0; - do{ - Temp = recv(Client,&Ret[Rcv],Size-Rcv,0); - if(Temp < 1)break; + do { + Temp = recv(Client, &Ret[Rcv], Size - Rcv, 0); + if (Temp < 1) + break; Rcv += Temp; - }while(Rcv < Size); - if(Temp < 1)break; + } while (Rcv < Size); + if (Temp < 1) + break; std::thread Respond(Parse, Ret, Client); Respond.detach(); - }while(Temp > 0); + } while (Temp > 0); if (Temp == 0) { debug("(Core) Connection closing"); } else { @@ -204,10 +218,10 @@ void GameHandler(SOCKET Client){ NetReset(); KillSocket(Client); } -void localRes(){ +void localRes() { MStatus = " "; UlStatus = "Ulstart"; - if(ConfList != nullptr){ + if (ConfList != nullptr) { ConfList->clear(); delete ConfList; ConfList = nullptr; @@ -216,16 +230,17 @@ void localRes(){ } void CoreMain() { debug("Core Network on start!"); - SOCKET LSocket,CSocket; - struct addrinfo *res = nullptr; - struct addrinfo hints{}; + SOCKET LSocket, CSocket; + struct addrinfo* res = nullptr; + struct addrinfo hints { }; int iRes; - #ifdef _WIN32 +#ifdef _WIN32 WSADATA wsaData; - iRes = WSAStartup(514, &wsaData); //2.2 - if (iRes)debug("WSAStartup failed with error: " + std::to_string(iRes)); - #endif - + iRes = WSAStartup(514, &wsaData); // 2.2 + if (iRes) + debug("WSAStartup failed with error: " + std::to_string(iRes)); +#endif + ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; @@ -233,13 +248,13 @@ void CoreMain() { hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; iRes = getaddrinfo(nullptr, std::to_string(DEFAULT_PORT).c_str(), &hints, &res); - if (iRes){ + if (iRes) { debug("(Core) addr info failed with error: " + std::to_string(iRes)); WSACleanup(); return; } LSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (LSocket == -1){ + if (LSocket == -1) { debug("(Core) socket failed with error: " + std::to_string(WSAGetLastError())); freeaddrinfo(res); WSACleanup(); @@ -261,7 +276,7 @@ void CoreMain() { WSACleanup(); return; } - do{ + do { CSocket = accept(LSocket, nullptr, nullptr); if (CSocket == -1) { error("(Core) accept failed with error: " + std::to_string(WSAGetLastError())); @@ -271,36 +286,37 @@ void CoreMain() { info("Game Connected!"); GameHandler(CSocket); warn("Game Reconnecting..."); - }while(CSocket); + } while (CSocket); KillSocket(LSocket); WSACleanup(); } #if defined(_WIN32) -int Handle(EXCEPTION_POINTERS *ep){ +int Handle(EXCEPTION_POINTERS* ep) { char* hex = new char[100]; - sprintf_s(hex,100, "%lX", ep->ExceptionRecord->ExceptionCode); + sprintf_s(hex, 100, "%lX", ep->ExceptionRecord->ExceptionCode); except("(Core) Code : " + std::string(hex)); - delete [] hex; + delete[] hex; return 1; } #endif -[[noreturn]] void CoreNetwork(){ - while(true) { - #if not defined(__MINGW32__) - __try{ - #endif - - CoreMain(); +[[noreturn]] void CoreNetwork() { + while (true) { +#if not defined(__MINGW32__) + __try { +#endif - #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))); - } - #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))); + } +#endif std::this_thread::sleep_for(std::chrono::seconds(1)); } diff --git a/src/Network/DNS.cpp b/src/Network/DNS.cpp index bac5a00..d28b829 100644 --- a/src/Network/DNS.cpp +++ b/src/Network/DNS.cpp @@ -12,31 +12,32 @@ #include #elif defined(__linux__) #include "linuxfixes.h" -#include #include +#include #endif #include "Logger.h" -std::string GetAddr(const std::string&IP){ - if(IP.find_first_not_of("0123456789.") == -1)return IP; - hostent *host; - #ifdef _WIN32 +std::string GetAddr(const std::string& IP) { + if (IP.find_first_not_of("0123456789.") == -1) + return IP; + hostent* host; +#ifdef _WIN32 WSADATA wsaData; - if(WSAStartup(514, &wsaData) != 0){ + if (WSAStartup(514, &wsaData) != 0) { error("WSA Startup Failed!"); WSACleanup(); return ""; } - #endif - +#endif + host = gethostbyname(IP.c_str()); - if(!host){ + if (!host) { error("DNS lookup failed! on " + IP); WSACleanup(); return "DNS"; } - std::string Ret = inet_ntoa(*((struct in_addr *)host->h_addr)); + std::string Ret = inet_ntoa(*((struct in_addr*)host->h_addr)); WSACleanup(); return Ret; } \ No newline at end of file diff --git a/src/Network/GlobalHandler.cpp b/src/Network/GlobalHandler.cpp index 9d551d4..2b53584 100644 --- a/src/Network/GlobalHandler.cpp +++ b/src/Network/GlobalHandler.cpp @@ -11,139 +11,149 @@ #include #elif defined(__linux__) #include "linuxfixes.h" +#include +#include +#include #include #include #include -#include -#include -#include #endif #include "Logger.h" #include +#include #include #include -#include -std::chrono::time_point PingStart,PingEnd; +std::chrono::time_point PingStart, PingEnd; bool GConnected = false; bool CServer = true; SOCKET CSocket = -1; SOCKET GSocket = -1; -int KillSocket(uint64_t Dead){ - if(Dead == (SOCKET)-1){ +int KillSocket(uint64_t Dead) { + if (Dead == (SOCKET)-1) { debug("Kill socket got -1 returning..."); return 0; } - shutdown(Dead,SD_BOTH); + shutdown(Dead, SD_BOTH); int a = closesocket(Dead); - if(a != 0){ + if (a != 0) { warn("Failed to close socket!"); } return a; } -bool CheckBytes(uint32_t Bytes){ - if(Bytes == 0){ +bool CheckBytes(uint32_t Bytes) { + if (Bytes == 0) { debug("(Proxy) Connection closing"); return false; - }else if(Bytes < 0){ + } else if (Bytes < 0) { debug("(Proxy) send failed with error: " + std::to_string(WSAGetLastError())); return false; } return true; } -void GameSend(std::string Data){ +void GameSend(std::string Data) { static std::mutex Lock; std::scoped_lock Guard(Lock); - if(TCPTerminate || !GConnected || CSocket == -1)return; - int32_t Size,Temp,Sent; + if (TCPTerminate || !GConnected || CSocket == -1) + return; + int32_t Size, Temp, Sent; Data += '\n'; Size = int32_t(Data.size()); Sent = 0; - #ifdef DEBUG - if(Size > 1000){ - debug("Launcher -> game (" +std::to_string(Size)+")"); - } - #endif - do{ - if(Sent > -1){ +#ifdef DEBUG + if (Size > 1000) { + debug("Launcher -> game (" + std::to_string(Size) + ")"); + } +#endif + do { + if (Sent > -1) { Temp = send(CSocket, &Data[Sent], Size - Sent, 0); - } - if(!CheckBytes(Temp))return; + } + if (!CheckBytes(Temp)) + return; Sent += Temp; - }while(Sent < Size); + } while (Sent < Size); } -void ServerSend(std::string Data, bool Rel){ - if(Terminate || Data.empty())return; - if(Data.find("Zp") != std::string::npos && Data.size() > 500){ +void ServerSend(std::string Data, bool Rel) { + if (Terminate || Data.empty()) + return; + if (Data.find("Zp") != std::string::npos && Data.size() > 500) { abort(); } char C = 0; bool Ack = false; int DLen = int(Data.length()); - if(DLen > 3)C = Data.at(0); - if (C == 'O' || C == 'T')Ack = true; - if(C == 'N' || C == 'W' || C == 'Y' || C == 'V' || C == 'E' || C == 'C')Rel = true; - if(Ack || Rel){ - if(Ack || DLen > 1000)SendLarge(Data); - else TCPSend(Data,TCPSock); - }else UDPSend(Data); + if (DLen > 3) + C = Data.at(0); + if (C == 'O' || C == 'T') + Ack = true; + if (C == 'N' || C == 'W' || C == 'Y' || C == 'V' || C == 'E' || C == 'C') + Rel = true; + if (Ack || Rel) { + if (Ack || DLen > 1000) + SendLarge(Data); + else + TCPSend(Data, TCPSock); + } else + UDPSend(Data); if (DLen > 1000) { debug("(Launcher->Server) Bytes sent: " + std::to_string(Data.length()) + " : " - + Data.substr(0, 10) - + Data.substr(Data.length() - 10)); - }else if(C == 'Z'){ - //debug("(Game->Launcher) : " + Data); + + Data.substr(0, 10) + + Data.substr(Data.length() - 10)); + } else if (C == 'Z') { + // debug("(Game->Launcher) : " + Data); } } -void NetReset(){ +void NetReset() { TCPTerminate = false; GConnected = false; Terminate = false; UlStatus = "Ulstart"; MStatus = " "; - if(UDPSock != (SOCKET)(-1)){ + if (UDPSock != (SOCKET)(-1)) { debug("Terminating UDP Socket : " + std::to_string(TCPSock)); KillSocket(UDPSock); } UDPSock = -1; - if(TCPSock != (SOCKET)(-1)){ + if (TCPSock != (SOCKET)(-1)) { debug("Terminating TCP Socket : " + std::to_string(TCPSock)); KillSocket(TCPSock); } TCPSock = -1; - if(GSocket != (SOCKET)(-1)){ + if (GSocket != (SOCKET)(-1)) { debug("Terminating GTCP Socket : " + std::to_string(GSocket)); KillSocket(GSocket); } GSocket = -1; } -SOCKET SetupListener(){ - if(GSocket != -1)return GSocket; - struct addrinfo *result = nullptr; - struct addrinfo hints{}; +SOCKET SetupListener() { + if (GSocket != -1) + return GSocket; + struct addrinfo* result = nullptr; + struct addrinfo hints { }; int iRes; - #ifdef _WIN32 +#ifdef _WIN32 WSADATA wsaData; - iRes = WSAStartup(514, &wsaData); //2.2 + iRes = WSAStartup(514, &wsaData); // 2.2 if (iRes != 0) { error("(Proxy) WSAStartup failed with error: " + std::to_string(iRes)); return -1; } - #endif +#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); + 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(); @@ -155,7 +165,7 @@ SOCKET SetupListener(){ WSACleanup(); return -1; } - iRes = bind(GSocket, result->ai_addr, (int) result->ai_addrlen); + 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); @@ -173,57 +183,61 @@ SOCKET SetupListener(){ } return GSocket; } -void AutoPing(){ - while(!Terminate){ - ServerSend("p",false); +void AutoPing() { + while (!Terminate) { + ServerSend("p", false); PingStart = std::chrono::high_resolution_clock::now(); - std::this_thread::sleep_for(std::chrono::seconds (1)); + std::this_thread::sleep_for(std::chrono::seconds(1)); } } int ClientID = -1; -void ParserAsync(const std::string& Data){ - if(Data.empty())return; - char Code = Data.at(0),SubCode = 0; - if(Data.length() > 1)SubCode = Data.at(1); +void ParserAsync(const std::string& Data) { + if (Data.empty()) + return; + char Code = Data.at(0), SubCode = 0; + if (Data.length() > 1) + SubCode = Data.at(1); switch (Code) { - case 'p': - PingEnd = std::chrono::high_resolution_clock::now(); - if(PingStart > PingEnd)ping = 0; - else ping = int(std::chrono::duration_cast(PingEnd-PingStart).count()); - return; - case 'M': - MStatus = Data; - UlStatus = "Uldone"; - return; - default: - break; + case 'p': + PingEnd = std::chrono::high_resolution_clock::now(); + if (PingStart > PingEnd) + ping = 0; + else + ping = int(std::chrono::duration_cast(PingEnd - PingStart).count()); + return; + case 'M': + MStatus = Data; + UlStatus = "Uldone"; + return; + default: + break; } GameSend(Data); } -void ServerParser(const std::string& Data){ +void ServerParser(const std::string& Data) { ParserAsync(Data); } -void NetMain(const std::string& IP, int Port){ +void NetMain(const std::string& IP, int Port) { std::thread Ping(AutoPing); Ping.detach(); - UDPClientMain(IP,Port); + UDPClientMain(IP, Port); CServer = true; Terminate = true; info("Connection Terminated!"); } -void TCPGameServer(const std::string& IP, int Port){ +void TCPGameServer(const std::string& IP, int Port) { GSocket = SetupListener(); - while (!TCPTerminate && GSocket != -1){ + while (!TCPTerminate && GSocket != -1) { debug("MAIN LOOP OF GAME SERVER"); GConnected = false; - if(!CServer){ + if (!CServer) { warn("Connection still alive terminating"); NetReset(); TCPTerminate = true; Terminate = true; break; } - if(CServer) { + if (CServer) { std::thread Client(TCPClientMain, IP, Port); Client.detach(); } @@ -234,45 +248,52 @@ void TCPGameServer(const std::string& IP, int Port){ } debug("(Proxy) Game Connected!"); GConnected = true; - if(CServer){ + if (CServer) { std::thread t1(NetMain, IP, Port); t1.detach(); CServer = false; } - int32_t Size,Temp,Rcv; - char Header[10] = {0}; + int32_t Size, Temp, Rcv; + char Header[10] = { 0 }; - //Read byte by byte until '>' is rcved then get the size and read based on it - do{ + // Read byte by byte until '>' is rcved then get the size and read based on it + do { Rcv = 0; - do{ - Temp = recv(CSocket,&Header[Rcv],1,0); - if(Temp < 1 || TCPTerminate)break; - }while(Header[Rcv++] != '>'); - if(Temp < 1 || TCPTerminate)break; - if(std::from_chars(Header,&Header[Rcv],Size).ptr[0] != '>'){ - debug("(Game) Invalid lua Header -> " + std::string(Header,Rcv)); + do { + Temp = recv(CSocket, &Header[Rcv], 1, 0); + if (Temp < 1 || TCPTerminate) + break; + } while (Header[Rcv++] != '>'); + if (Temp < 1 || TCPTerminate) + break; + if (std::from_chars(Header, &Header[Rcv], Size).ptr[0] != '>') { + debug("(Game) Invalid lua Header -> " + std::string(Header, Rcv)); break; } - std::string Ret(Size,0); + std::string Ret(Size, 0); Rcv = 0; - do{ - Temp = recv(CSocket,&Ret[Rcv],Size-Rcv,0); - if(Temp < 1)break; + do { + Temp = recv(CSocket, &Ret[Rcv], Size - Rcv, 0); + if (Temp < 1) + break; Rcv += Temp; - }while(Rcv < Size && !TCPTerminate); - if(Temp < 1 || TCPTerminate)break; + } while (Rcv < Size && !TCPTerminate); + if (Temp < 1 || TCPTerminate) + break; - ServerSend(Ret,false); + ServerSend(Ret, false); - }while(Temp > 0 && !TCPTerminate); - if(Temp == 0)debug("(Proxy) Connection closing"); - else debug("(Proxy) recv failed error : " + std::to_string(WSAGetLastError())); + } while (Temp > 0 && !TCPTerminate); + if (Temp == 0) + debug("(Proxy) Connection closing"); + else + debug("(Proxy) recv failed error : " + std::to_string(WSAGetLastError())); } TCPTerminate = true; GConnected = false; Terminate = true; - if(CSocket != SOCKET_ERROR)KillSocket(CSocket); + if (CSocket != SOCKET_ERROR) + KillSocket(CSocket); debug("END OF GAME SERVER"); } \ No newline at end of file diff --git a/src/Network/Http.cpp b/src/Network/Http.cpp index 503eb80..64a7382 100644 --- a/src/Network/Http.cpp +++ b/src/Network/Http.cpp @@ -7,175 +7,168 @@ /// #define CPPHTTPLIB_OPENSSL_SUPPORT -#include -#include -#include #include "Http.h" -#include +#include #include #include +#include #include +#include +#include #include void WriteHttpDebug(const httplib::Client& client, const std::string& method, const std::string& target, const httplib::Result& result) try { - const std::filesystem::path folder = ".https_debug"; - std::filesystem::create_directories(folder); - if (!std::filesystem::exists(folder / "WHAT IS THIS FOLDER.txt")) { - std::ofstream ignore { folder / "WHAT IS THIS FOLDER.txt" }; - ignore << "This folder exists to help debug current issues with the backend. Do not share this folder with anyone but BeamMP staff. It contains detailed logs of any failed http requests." << std::endl; - } - const auto file = folder / (method + ".json"); - // 1 MB limit - if (std::filesystem::exists(file) && std::filesystem::file_size(file) > 1'000'000) { - std::filesystem::rename(file, file.generic_string() + ".bak"); - } + const std::filesystem::path folder = ".https_debug"; + std::filesystem::create_directories(folder); + if (!std::filesystem::exists(folder / "WHAT IS THIS FOLDER.txt")) { + std::ofstream ignore { folder / "WHAT IS THIS FOLDER.txt" }; + ignore << "This folder exists to help debug current issues with the backend. Do not share this folder with anyone but BeamMP staff. It contains detailed logs of any failed http requests." << std::endl; + } + const auto file = folder / (method + ".json"); + // 1 MB limit + if (std::filesystem::exists(file) && std::filesystem::file_size(file) > 1'000'000) { + std::filesystem::rename(file, file.generic_string() + ".bak"); + } - std::ofstream of { file, std::ios::app }; - nlohmann::json js { - { "utc", std::chrono::system_clock::now().time_since_epoch().count() }, - { "target", target }, - { "client_info", { - { "openssl_verify_result", client.get_openssl_verify_result() }, - { "host", client.host()}, - { "port", client.port()}, - { "socket_open", client.is_socket_open()}, - {"valid", client.is_valid()}, - } - }, - }; - if (result) { - auto value = result.value(); - js["result"] = {}; - js["result"]["body"] = value.body; - js["result"]["status"] = value.status; - js["result"]["headers"] = value.headers; - js["result"]["version"] = value.version; - js["result"]["location"] = value.location; - js["result"]["reason"] = value.reason; - } - of << js.dump(); -} -catch (const std::exception& e) { - error(e.what()); + std::ofstream of { file, std::ios::app }; + nlohmann::json js { + { "utc", std::chrono::system_clock::now().time_since_epoch().count() }, + { "target", target }, + { "client_info", { + { "openssl_verify_result", client.get_openssl_verify_result() }, + { "host", client.host() }, + { "port", client.port() }, + { "socket_open", client.is_socket_open() }, + { "valid", client.is_valid() }, + } }, + }; + if (result) { + auto value = result.value(); + js["result"] = {}; + js["result"]["body"] = value.body; + js["result"]["status"] = value.status; + js["result"]["headers"] = value.headers; + js["result"]["version"] = value.version; + js["result"]["location"] = value.location; + js["result"]["reason"] = value.reason; + } + of << js.dump(); +} catch (const std::exception& e) { + error(e.what()); } bool HTTP::isDownload = false; std::string HTTP::Get(const std::string& IP) { - static std::mutex Lock; - std::scoped_lock Guard(Lock); + static std::mutex Lock; + std::scoped_lock Guard(Lock); - auto pos = IP.find('/', 10); + auto pos = IP.find('/', 10); - httplib::Client cli(IP.substr(0, pos).c_str()); - cli.set_connection_timeout(std::chrono::seconds(10)); - cli.set_follow_location(true); - auto res = cli.Get(IP.substr(pos).c_str(), ProgressBar); - std::string Ret; + httplib::Client cli(IP.substr(0, pos).c_str()); + cli.set_connection_timeout(std::chrono::seconds(10)); + cli.set_follow_location(true); + auto res = cli.Get(IP.substr(pos).c_str(), ProgressBar); + std::string Ret; - if (res) { - if (res->status == 200) { - Ret = res->body; - } - else { - WriteHttpDebug(cli, "GET", IP, res); - error("Failed to GET '" + IP + "': " + res->reason + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result())); - - } - } - else { - if (isDownload) { - std::cout << "\n"; - } - WriteHttpDebug(cli, "GET", IP, res); - error("HTTP Get failed on " + to_string(res.error()) + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result())); - - } + if (res) { + if (res->status == 200) { + Ret = res->body; + } else { + WriteHttpDebug(cli, "GET", IP, res); + error("Failed to GET '" + IP + "': " + res->reason + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result())); + } + } else { + if (isDownload) { + std::cout << "\n"; + } + WriteHttpDebug(cli, "GET", IP, res); + error("HTTP Get failed on " + to_string(res.error()) + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result())); + } - return Ret; + return Ret; } std::string HTTP::Post(const std::string& IP, const std::string& Fields) { - static std::mutex Lock; - std::scoped_lock Guard(Lock); + static std::mutex Lock; + std::scoped_lock Guard(Lock); - auto pos = IP.find('/', 10); + auto pos = IP.find('/', 10); - httplib::Client cli(IP.substr(0, pos).c_str()); - cli.set_connection_timeout(std::chrono::seconds(10)); - std::string Ret; + httplib::Client cli(IP.substr(0, pos).c_str()); + cli.set_connection_timeout(std::chrono::seconds(10)); + std::string Ret; - if (!Fields.empty()) { - httplib::Result res = cli.Post(IP.substr(pos).c_str(), Fields, "application/json"); + if (!Fields.empty()) { + httplib::Result res = cli.Post(IP.substr(pos).c_str(), Fields, "application/json"); - if (res) { - if (res->status != 200) { - error(res->reason); - } - Ret = res->body; - } - else { - WriteHttpDebug(cli, "POST", IP, res); - error("HTTP Post failed on " + to_string(res.error()) + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result())); - - } - } - else { - httplib::Result res = cli.Post(IP.substr(pos).c_str()); - if (res) { - if (res->status != 200) { - error(res->reason); - } - Ret = res->body; - } - else { - WriteHttpDebug(cli, "POST", IP, res); - error("HTTP Post failed on " + to_string(res.error()) + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result())); - - } - } + if (res) { + if (res->status != 200) { + error(res->reason); + } + Ret = res->body; + } else { + WriteHttpDebug(cli, "POST", IP, res); + error("HTTP Post failed on " + to_string(res.error()) + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result())); + } + } else { + httplib::Result res = cli.Post(IP.substr(pos).c_str()); + if (res) { + if (res->status != 200) { + error(res->reason); + } + Ret = res->body; + } else { + WriteHttpDebug(cli, "POST", IP, res); + error("HTTP Post failed on " + to_string(res.error()) + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result())); + } + } - if (Ret.empty())return "-1"; - else return Ret; + if (Ret.empty()) + return "-1"; + else + return Ret; } bool HTTP::ProgressBar(size_t c, size_t t) { - if (isDownload) { - static double last_progress, progress_bar_adv; - progress_bar_adv = round(c / double(t) * 25); - std::cout << "\r"; - std::cout << "Progress : [ "; - std::cout << round(c / double(t) * 100); - std::cout << "% ] ["; - int i; - for (i = 0; i <= progress_bar_adv; i++)std::cout << "#"; - for (i = 0; i < 25 - progress_bar_adv; i++)std::cout << "."; - std::cout << "]"; - last_progress = round(c / double(t) * 100); - } - return true; + if (isDownload) { + static double last_progress, progress_bar_adv; + progress_bar_adv = round(c / double(t) * 25); + std::cout << "\r"; + std::cout << "Progress : [ "; + std::cout << round(c / double(t) * 100); + std::cout << "% ] ["; + int i; + for (i = 0; i <= progress_bar_adv; i++) + std::cout << "#"; + for (i = 0; i < 25 - progress_bar_adv; i++) + std::cout << "."; + std::cout << "]"; + last_progress = round(c / double(t) * 100); + } + return true; } bool HTTP::Download(const std::string& IP, const std::string& Path) { - static std::mutex Lock; - std::scoped_lock Guard(Lock); + static std::mutex Lock; + std::scoped_lock Guard(Lock); - isDownload = true; - std::string Ret = Get(IP); - isDownload = false; + isDownload = true; + std::string Ret = Get(IP); + isDownload = false; - if (Ret.empty())return false; + if (Ret.empty()) + return false; - std::ofstream File(Path, std::ios::binary); - if (File.is_open()) { - File << Ret; - File.close(); - std::cout << "\n"; - info("Download Complete!"); - } - else { - error("Failed to open file directory: " + Path); - return false; - } + std::ofstream File(Path, std::ios::binary); + if (File.is_open()) { + File << Ret; + File.close(); + std::cout << "\n"; + info("Download Complete!"); + } else { + error("Failed to open file directory: " + Path); + return false; + } - return true; + return true; } diff --git a/src/Network/Resources.cpp b/src/Network/Resources.cpp index 6272fa1..e3d8049 100644 --- a/src/Network/Resources.cpp +++ b/src/Network/Resources.cpp @@ -11,140 +11,146 @@ #if defined(_WIN32) #include #elif defined(__linux__) -#include -#include +#include #include #include #include -#include +#include +#include #endif -#include -#include "Startup.h" #include "Logger.h" -#include +#include "Startup.h" +#include +#include #include +#include #include +#include +#include #include #include -#include #include -#include -#include namespace fs = std::filesystem; std::string ListOfMods; -std::vector Split(const std::string& String,const std::string& delimiter){ +std::vector Split(const std::string& String, const std::string& delimiter) { std::vector Val; size_t pos; - std::string token,s = String; + std::string token, s = String; while ((pos = s.find(delimiter)) != std::string::npos) { token = s.substr(0, pos); - if(!token.empty())Val.push_back(token); + if (!token.empty()) + Val.push_back(token); s.erase(0, pos + delimiter.length()); } - if(!s.empty())Val.push_back(s); + if (!s.empty()) + Val.push_back(s); return Val; } -void CheckForDir(){ - if(!fs::exists("Resources")){ - // Could we just use fs::create_directory instead? - #if defined(_WIN32) +void CheckForDir() { + if (!fs::exists("Resources")) { +// Could we just use fs::create_directory instead? +#if defined(_WIN32) _wmkdir(L"Resources"); - #elif defined(__linux__) +#elif defined(__linux__) fs::create_directory(L"Resources"); - #endif +#endif } } -void WaitForConfirm(){ - while(!Terminate && !ModLoaded){ +void WaitForConfirm() { + while (!Terminate && !ModLoaded) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); } ModLoaded = false; } - -void Abord(){ +void Abord() { Terminate = true; TCPTerminate = true; info("Terminated!"); } -std::string Auth(SOCKET Sock){ - TCPSend("VC" + GetVer(),Sock); +std::string Auth(SOCKET Sock) { + TCPSend("VC" + GetVer(), Sock); auto Res = TCPRcv(Sock); - if(Res.empty() || Res[0] == 'E' || Res[0] == 'K'){ + if (Res.empty() || Res[0] == 'E' || Res[0] == 'K') { Abord(); return ""; } - TCPSend(PublicKey,Sock); - if(Terminate)return ""; + TCPSend(PublicKey, Sock); + if (Terminate) + return ""; Res = TCPRcv(Sock); - if(Res.empty() || Res[0] != 'P'){ + if (Res.empty() || Res[0] != 'P') { Abord(); return ""; } Res = Res.substr(1); - if(Res.find_first_not_of("0123456789") == std::string::npos){ + if (Res.find_first_not_of("0123456789") == std::string::npos) { ClientID = std::stoi(Res); - }else{ + } else { Abord(); UUl("Authentication failed!"); return ""; } - TCPSend("SR",Sock); - if(Terminate)return ""; + TCPSend("SR", Sock); + if (Terminate) + return ""; Res = TCPRcv(Sock); - if(Res[0] == 'E' || Res[0] == 'K'){ + if (Res[0] == 'E' || Res[0] == 'K') { Abord(); return ""; } - if(Res.empty() || Res == "-"){ + if (Res.empty() || Res == "-") { info("Didn't Receive any mods..."); ListOfMods = "-"; - TCPSend("Done",Sock); + TCPSend("Done", Sock); info("Done!"); return ""; } return Res; } -void UpdateUl(bool D,const std::string& msg){ - if(D)UlStatus = "UlDownloading Resource " + msg; - else UlStatus = "UlLoading Resource " + msg; +void UpdateUl(bool D, const std::string& msg) { + if (D) + UlStatus = "UlDownloading Resource " + msg; + else + UlStatus = "UlLoading Resource " + msg; } -void AsyncUpdate(uint64_t& Rcv,uint64_t Size,const std::string& Name){ +void AsyncUpdate(uint64_t& Rcv, uint64_t Size, const std::string& Name) { do { double pr = double(Rcv) / double(Size) * 100; std::string Per = std::to_string(trunc(pr * 10) / 10); UpdateUl(true, Name + " (" + Per.substr(0, Per.find('.') + 2) + "%)"); std::this_thread::sleep_for(std::chrono::milliseconds(100)); - }while(!Terminate && Rcv < Size); + } while (!Terminate && Rcv < Size); } -char* TCPRcvRaw(SOCKET Sock,uint64_t& GRcv, uint64_t Size){ - if(Sock == -1){ +char* TCPRcvRaw(SOCKET Sock, uint64_t& GRcv, uint64_t Size) { + if (Sock == -1) { Terminate = true; UUl("Invalid Socket"); return nullptr; } char* File = new char[Size]; uint64_t Rcv = 0; - do{ - int Len = int(Size-Rcv); - if(Len > 1000000)Len = 1000000; + do { + int Len = int(Size - Rcv); + if (Len > 1000000) + Len = 1000000; int32_t Temp = recv(Sock, &File[Rcv], Len, MSG_WAITALL); - if(Temp < 1){ + if (Temp < 1) { info(std::to_string(Temp)); UUl("Socket Closed Code 1"); KillSocket(Sock); @@ -154,18 +160,18 @@ char* TCPRcvRaw(SOCKET Sock,uint64_t& GRcv, uint64_t Size){ } Rcv += Temp; GRcv += Temp; - }while(Rcv < Size && !Terminate); + } while (Rcv < Size && !Terminate); return File; } -void MultiKill(SOCKET Sock,SOCKET Sock1){ +void MultiKill(SOCKET Sock, SOCKET Sock1) { KillSocket(Sock1); KillSocket(Sock); Terminate = true; } -SOCKET InitDSock(){ +SOCKET InitDSock() { SOCKET DSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); SOCKADDR_IN ServerAddr; - if(DSock < 1){ + if (DSock < 1) { KillSocket(DSock); Terminate = true; return 0; @@ -173,13 +179,13 @@ SOCKET InitDSock(){ 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){ + if (connect(DSock, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr)) != 0) { KillSocket(DSock); Terminate = true; return 0; } - char Code[2] = {'D',char(ClientID)}; - if(send(DSock,Code,2,0) != 2){ + char Code[2] = { 'D', char(ClientID) }; + if (send(DSock, Code, 2, 0) != 2) { KillSocket(DSock); Terminate = true; return 0; @@ -187,55 +193,56 @@ SOCKET InitDSock(){ return DSock; } -std::string MultiDownload(SOCKET MSock,SOCKET DSock, uint64_t Size, const std::string& Name){ +std::string MultiDownload(SOCKET MSock, SOCKET DSock, uint64_t Size, const std::string& Name) { - uint64_t GRcv = 0, MSize = Size/2, DSize = Size - MSize; + uint64_t GRcv = 0, MSize = Size / 2, DSize = Size - MSize; - std::thread Au(AsyncUpdate,std::ref(GRcv), Size, Name); + std::thread Au(AsyncUpdate, std::ref(GRcv), Size, Name); - std::packaged_task task([&] { return TCPRcvRaw(MSock,GRcv,MSize); }); + std::packaged_task task([&] { return TCPRcvRaw(MSock, GRcv, MSize); }); std::future f1 = task.get_future(); std::thread Dt(std::move(task)); Dt.detach(); - char* DData = TCPRcvRaw(DSock,GRcv,DSize); + char* DData = TCPRcvRaw(DSock, GRcv, DSize); - if(!DData){ - MultiKill(MSock,DSock); + if (!DData) { + MultiKill(MSock, DSock); return ""; } f1.wait(); char* MData = f1.get(); - if(!MData){ - MultiKill(MSock,DSock); + if (!MData) { + MultiKill(MSock, DSock); return ""; } - if(Au.joinable())Au.join(); + if (Au.joinable()) + Au.join(); + /// omg yes very ugly my god but i was in a rush will revisit + std::string Ret(Size, 0); + memcpy(&Ret[0], MData, MSize); + delete[] MData; - ///omg yes very ugly my god but i was in a rush will revisit - std::string Ret(Size,0); - memcpy(&Ret[0],MData,MSize); - delete[]MData; - - memcpy(&Ret[MSize],DData,DSize); - delete[]DData; + memcpy(&Ret[MSize], DData, DSize); + delete[] DData; return Ret; } -void InvalidResource(const std::string& File){ +void InvalidResource(const std::string& File) { UUl("Invalid mod \"" + File + "\""); warn("The server tried to sync \"" + File + "\" that is not a .zip file!"); Terminate = true; } -void SyncResources(SOCKET Sock){ +void SyncResources(SOCKET Sock) { std::string Ret = Auth(Sock); - if(Ret.empty())return; + if (Ret.empty()) + return; info("Checking Resources..."); CheckForDir(); @@ -246,59 +253,59 @@ void SyncResources(SOCKET Sock){ list.clear(); Ret.clear(); - int Amount = 0,Pos = 0; - std::string a,t; - for(const std::string&name : FNames){ - if(!name.empty()){ + int Amount = 0, Pos = 0; + std::string a, t; + for (const std::string& name : FNames) { + if (!name.empty()) { t += name.substr(name.find_last_of('/') + 1) + ";"; } } - if(t.empty())ListOfMods = "-"; - else ListOfMods = t; + if (t.empty()) + ListOfMods = "-"; + else + ListOfMods = t; t.clear(); - for(auto FN = FNames.begin(),FS = FSizes.begin(); FN != FNames.end() && !Terminate; ++FN,++FS) { + for (auto FN = FNames.begin(), FS = FSizes.begin(); FN != FNames.end() && !Terminate; ++FN, ++FS) { auto pos = FN->find_last_of('/'); auto ZIP = FN->find(".zip"); if (ZIP == std::string::npos || FN->length() - ZIP != 4) { InvalidResource(*FN); return; } - if (pos == std::string::npos)continue; + if (pos == std::string::npos) + continue; Amount++; } - if(!FNames.empty())info("Syncing..."); + if (!FNames.empty()) + info("Syncing..."); SOCKET DSock = InitDSock(); - for(auto FN = FNames.begin(),FS = FSizes.begin(); FN != FNames.end() && !Terminate; ++FN,++FS) { + for (auto FN = FNames.begin(), FS = FSizes.begin(); FN != FNames.end() && !Terminate; ++FN, ++FS) { auto pos = FN->find_last_of('/'); if (pos != std::string::npos) { a = "Resources" + FN->substr(pos); - } else continue; + } else + continue; Pos++; if (fs::exists(a)) { - if (FS->find_first_not_of("0123456789") != std::string::npos)continue; - if (fs::file_size(a) == std::stoull(*FS)){ - UpdateUl(false,std::to_string(Pos) + "/" + std::to_string(Amount) + ": " + a.substr(a.find_last_of('/'))); + if (FS->find_first_not_of("0123456789") != std::string::npos) + continue; + if (fs::file_size(a) == std::stoull(*FS)) { + UpdateUl(false, std::to_string(Pos) + "/" + std::to_string(Amount) + ": " + a.substr(a.find_last_of('/'))); std::this_thread::sleep_for(std::chrono::milliseconds(50)); try { - if(!fs::exists(GetGamePath() + "mods/multiplayer")){ + if (!fs::exists(GetGamePath() + "mods/multiplayer")) { fs::create_directories(GetGamePath() + "mods/multiplayer"); } auto name = GetGamePath() + "mods/multiplayer" + a.substr(a.find_last_of('/')); - #if defined(__linux__) +#if defined(__linux__) // Linux version of the game doesnt support uppercase letters in mod names - for(char &c : name){ + for (char& c : name) { c = ::tolower(c); } - #endif +#endif auto tmp_name = name + ".tmp"; - fs::copy_file(a,tmp_name,fs::copy_options::overwrite_existing); + fs::copy_file(a, tmp_name, fs::copy_options::overwrite_existing); fs::rename(tmp_name, name); - for(char &c : FName){ - c = ::tolower(c); - } - #endif - - fs::copy_file(a, GetGamePath() + "mods/multiplayer" + FName, } catch (std::exception& e) { error("Failed copy to the mods folder! " + std::string(e.what())); Terminate = true; @@ -306,15 +313,16 @@ void SyncResources(SOCKET Sock){ } WaitForConfirm(); continue; - }else remove(a.c_str()); + } else + remove(a.c_str()); } CheckForDir(); std::string FName = a.substr(a.find_last_of('/')); do { - TCPSend("f" + *FN,Sock); + TCPSend("f" + *FN, Sock); std::string Data = TCPRcv(Sock); - if (Data == "CO" || Terminate){ + if (Data == "CO" || Terminate) { Terminate = true; UUl("Server cannot find " + FName); break; @@ -322,10 +330,11 @@ void SyncResources(SOCKET Sock){ std::string Name = std::to_string(Pos) + "/" + std::to_string(Amount) + ": " + FName; - Data = MultiDownload(Sock,DSock,std::stoull(*FS), Name); + Data = MultiDownload(Sock, DSock, std::stoull(*FS), Name); - if(Terminate)break; - UpdateUl(false,std::to_string(Pos)+"/"+std::to_string(Amount)+": "+FName); + if (Terminate) + break; + UpdateUl(false, std::to_string(Pos) + "/" + std::to_string(Amount) + ": " + FName); std::ofstream LFS; LFS.open(a.c_str(), std::ios_base::app | std::ios::binary); if (LFS.is_open()) { @@ -333,29 +342,29 @@ void SyncResources(SOCKET Sock){ LFS.close(); } - }while(fs::file_size(a) != std::stoull(*FS) && !Terminate); - if(!Terminate){ - if(!fs::exists(GetGamePath() + "mods/multiplayer")){ + } while (fs::file_size(a) != std::stoull(*FS) && !Terminate); + if (!Terminate) { + if (!fs::exists(GetGamePath() + "mods/multiplayer")) { fs::create_directories(GetGamePath() + "mods/multiplayer"); } - // Linux version of the game doesnt support uppercase letters in mod names - #if defined(__linux__) - for(char &c : FName){ +// Linux version of the game doesnt support uppercase letters in mod names +#if defined(__linux__) + for (char& c : FName) { c = ::tolower(c); } - #endif +#endif - fs::copy_file(a,GetGamePath() + "mods/multiplayer" + FName, fs::copy_options::overwrite_existing); + fs::copy_file(a, GetGamePath() + "mods/multiplayer" + FName, fs::copy_options::overwrite_existing); } WaitForConfirm(); } KillSocket(DSock); - if(!Terminate){ - TCPSend("Done",Sock); + if (!Terminate) { + TCPSend("Done", Sock); info("Done!"); - }else{ + } else { UlStatus = "Ulstart"; info("Connection Terminated!"); } -} \ No newline at end of file +} diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index 888e985..4f1269f 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -5,87 +5,91 @@ /// /// Created by Anonymous275 on 5/8/2020 /// -#include "Zlib/Compressor.h" #include "Network/network.hpp" +#include "Zlib/Compressor.h" #if defined(_WIN32) #include #elif defined(__linux__) -#include -#include +#include "linuxfixes.h" +#include #include #include #include -#include -#include "linuxfixes.h" +#include +#include #endif #include "Logger.h" -#include #include +#include SOCKET UDPSock = -1; sockaddr_in* ToServer = nullptr; -void UDPSend(std::string Data){ - if(ClientID == -1 || UDPSock == -1)return; - if(Data.length() > 400){ +void UDPSend(std::string Data) { + if (ClientID == -1 || UDPSock == -1) + return; + if (Data.length() > 400) { std::string CMP(Comp(Data)); Data = "ABG:" + CMP; } - 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)); - if (sendOk == SOCKET_ERROR)error("Error Code : " + std::to_string(WSAGetLastError())); + if (sendOk == SOCKET_ERROR) + error("Error Code : " + std::to_string(WSAGetLastError())); } - -void SendLarge(std::string Data){ - if(Data.length() > 400){ +void SendLarge(std::string Data) { + if (Data.length() > 400) { std::string CMP(Comp(Data)); Data = "ABG:" + CMP; } - TCPSend(Data,TCPSock); + TCPSend(Data, TCPSock); } -void UDPParser(std::string Packet){ - if(Packet.substr(0,4) == "ABG:"){ +void UDPParser(std::string Packet) { + if (Packet.substr(0, 4) == "ABG:") { Packet = DeComp(Packet.substr(4)); } ServerParser(Packet); } -void UDPRcv(){ - sockaddr_in FromServer{}; - #if defined(_WIN32) +void UDPRcv() { + sockaddr_in FromServer {}; +#if defined(_WIN32) int clientLength = sizeof(FromServer); - #elif defined(__linux__) +#elif defined(__linux__) socklen_t clientLength = sizeof(FromServer); - #endif +#endif ZeroMemory(&FromServer, clientLength); - std::string Ret(10240,0); - if(UDPSock == -1)return; + std::string Ret(10240, 0); + if (UDPSock == -1) + return; int32_t Rcv = recvfrom(UDPSock, &Ret[0], 10240, 0, (sockaddr*)&FromServer, &clientLength); - if (Rcv == SOCKET_ERROR)return; - UDPParser(Ret.substr(0,Rcv)); + if (Rcv == SOCKET_ERROR) + return; + UDPParser(Ret.substr(0, Rcv)); } -void UDPClientMain(const std::string& IP,int Port){ - #ifdef _WIN32 +void UDPClientMain(const std::string& IP, int Port) { +#ifdef _WIN32 WSADATA data; - if (WSAStartup(514, &data)){ + if (WSAStartup(514, &data)) { error("Can't start Winsock!"); return; } - #endif - +#endif + 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); - GameSend("P"+std::to_string(ClientID)); - TCPSend("H",TCPSock); + GameSend("P" + std::to_string(ClientID)); + TCPSend("H", TCPSock); UDPSend("p"); - while(!Terminate)UDPRcv(); + while (!Terminate) + UDPRcv(); KillSocket(UDPSock); WSACleanup(); } \ No newline at end of file diff --git a/src/Network/VehicleEvent.cpp b/src/Network/VehicleEvent.cpp index 258158e..d60f669 100644 --- a/src/Network/VehicleEvent.cpp +++ b/src/Network/VehicleEvent.cpp @@ -6,21 +6,21 @@ /// Created by Anonymous275 on 5/8/2020 /// -#include -#include #include "Logger.h" -#include #include +#include +#include +#include #if defined(_WIN32) #include #elif defined(__linux__) -#include -#include +#include #include #include #include -#include +#include +#include #endif #include "Network/network.hpp" @@ -29,12 +29,12 @@ int LastPort; std::string LastIP; SOCKET TCPSock = -1; -bool CheckBytes(int32_t Bytes){ - if (Bytes == 0){ +bool CheckBytes(int32_t Bytes) { + if (Bytes == 0) { debug("(TCP) Connection closing... CheckBytes(16)"); Terminate = true; return false; - }else if (Bytes < 0) { + } else if (Bytes < 0) { debug("(TCP CB) recv failed with error: " + std::to_string(WSAGetLastError())); KillSocket(TCPSock); Terminate = true; @@ -42,98 +42,99 @@ bool CheckBytes(int32_t Bytes){ } return true; } -void UUl(const std::string& R){ +void UUl(const std::string& R) { UlStatus = "UlDisconnected: " + R; } -void TCPSend(const std::string&Data,uint64_t Sock){ - if(Sock == -1){ - Terminate = true; - UUl("Invalid Socket"); - return; - } +void TCPSend(const std::string& Data, uint64_t Sock) { + if (Sock == -1) { + Terminate = true; + UUl("Invalid Socket"); + return; + } - int32_t Size,Sent,Temp; - std::string Send(4,0); - Size = int32_t(Data.size()); - memcpy(&Send[0],&Size,sizeof(Size)); - Send += Data; - // Do not use Size before this point for anything but the header - Sent = 0; - Size += 4; - do{ - if (size_t(Sent) >= Send.size()) { - error("string OOB in " + std::string(__func__)); - UUl("TCP Send OOB"); - return; - } - Temp = send(Sock, &Send[Sent], Size - Sent, 0); - if(!CheckBytes(Temp)){ - UUl("Socket Closed Code 2"); - return; - } - Sent += Temp; - }while(Sent < Size); + int32_t Size, Sent, Temp; + std::string Send(4, 0); + Size = int32_t(Data.size()); + memcpy(&Send[0], &Size, sizeof(Size)); + Send += Data; + // Do not use Size before this point for anything but the header + Sent = 0; + Size += 4; + do { + if (size_t(Sent) >= Send.size()) { + error("string OOB in " + std::string(__func__)); + UUl("TCP Send OOB"); + return; + } + Temp = send(Sock, &Send[Sent], Size - Sent, 0); + if (!CheckBytes(Temp)) { + UUl("Socket Closed Code 2"); + return; + } + Sent += Temp; + } while (Sent < Size); } -std::string TCPRcv(SOCKET Sock){ - if(Sock == -1){ +std::string TCPRcv(SOCKET Sock) { + if (Sock == -1) { Terminate = true; UUl("Invalid Socket"); return ""; } - int32_t Header,BytesRcv = 0,Temp; + int32_t Header, BytesRcv = 0, Temp; std::vector Data(sizeof(Header)); - do{ - Temp = recv(Sock,&Data[BytesRcv],4-BytesRcv,0); - if(!CheckBytes(Temp)){ + do { + Temp = recv(Sock, &Data[BytesRcv], 4 - BytesRcv, 0); + if (!CheckBytes(Temp)) { UUl("Socket Closed Code 3"); return ""; } BytesRcv += Temp; - }while(BytesRcv < 4); - memcpy(&Header,&Data[0],sizeof(Header)); + } while (BytesRcv < 4); + memcpy(&Header, &Data[0], sizeof(Header)); - if(!CheckBytes(BytesRcv)){ + if (!CheckBytes(BytesRcv)) { UUl("Socket Closed Code 4"); return ""; } Data.resize(Header); BytesRcv = 0; - do{ - Temp = recv(Sock,&Data[BytesRcv],Header-BytesRcv,0); - if(!CheckBytes(Temp)){ + do { + Temp = recv(Sock, &Data[BytesRcv], Header - BytesRcv, 0); + if (!CheckBytes(Temp)) { UUl("Socket Closed Code 5"); return ""; } BytesRcv += Temp; - }while(BytesRcv < Header); + } while (BytesRcv < Header); - std::string Ret(Data.data(),Header); + std::string Ret(Data.data(), Header); if (Ret.substr(0, 4) == "ABG:") { Ret = DeComp(Ret.substr(4)); } #ifdef DEBUG - //debug("Parsing from server -> " + std::to_string(Ret.size())); + // debug("Parsing from server -> " + std::to_string(Ret.size())); #endif - if(Ret[0] == 'E' || Ret[0] == 'K')UUl(Ret.substr(1)); + if (Ret[0] == 'E' || Ret[0] == 'K') + UUl(Ret.substr(1)); return Ret; } -void TCPClientMain(const std::string& IP,int Port){ +void TCPClientMain(const std::string& IP, int Port) { LastIP = IP; LastPort = Port; SOCKADDR_IN ServerAddr; int RetCode; - #ifdef _WIN32 +#ifdef _WIN32 WSADATA wsaData; - WSAStartup(514, &wsaData); //2.2 - #endif + WSAStartup(514, &wsaData); // 2.2 +#endif TCPSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if(TCPSock == -1){ + if (TCPSock == -1) { printf("Client: socket failed! Error code: %d\n", WSAGetLastError()); WSACleanup(); return; @@ -142,8 +143,8 @@ void TCPClientMain(const std::string& IP,int Port){ 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(RetCode != 0){ + RetCode = connect(TCPSock, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr)); + if (RetCode != 0) { UlStatus = "UlConnection Failed!"; error("Client: connect failed! Error code: " + std::to_string(WSAGetLastError())); KillSocket(TCPSock); @@ -156,17 +157,16 @@ void TCPClientMain(const std::string& IP,int Port){ char Code = 'C'; send(TCPSock, &Code, 1, 0); SyncResources(TCPSock); - while(!Terminate){ + while (!Terminate) { ServerParser(TCPRcv(TCPSock)); } GameSend("T"); ////Game Send Terminate - if(KillSocket(TCPSock) != 0) + if (KillSocket(TCPSock) != 0) debug("(TCP) Cannot close socket. Error code: " + std::to_string(WSAGetLastError())); - #ifdef _WIN32 - if(WSACleanup() != 0) +#ifdef _WIN32 + if (WSACleanup() != 0) debug("(TCP) Client: WSACleanup() failed!..."); - #endif - +#endif } diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index d927d18..0ec69d9 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -11,9 +11,9 @@ #include #elif defined(__linux__) #include "vdf_parser.hpp" -#include #include #include +#include #endif #include "Logger.h" #include @@ -27,11 +27,10 @@ int TraceBack = 0; std::string GameDir; -void lowExit(int code){ +void lowExit(int code) { TraceBack = 0; - std::string msg = - "Failed to find the game please launch it. Report this if the issue persists code "; - error(msg+std::to_string(code)); + std::string msg = "Failed to find the game please launch it. Report this if the issue persists code "; + error(msg + std::to_string(code)); std::this_thread::sleep_for(std::chrono::seconds(10)); exit(2); } @@ -51,124 +50,136 @@ void SteamExit(int code){ std::this_thread::sleep_for(std::chrono::seconds(10)); exit(4); }*/ -std::string GetGameDir(){ - //if(TraceBack != 4)Exit(0); - #if defined(_WIN32) - return GameDir.substr(0,GameDir.find_last_of('\\')); - #elif defined(__linux__) - return GameDir.substr(0,GameDir.find_last_of('/')); - #endif +std::string GetGameDir() { +// if(TraceBack != 4)Exit(0); +#if defined(_WIN32) + return GameDir.substr(0, GameDir.find_last_of('\\')); +#elif defined(__linux__) + return GameDir.substr(0, GameDir.find_last_of('/')); +#endif } #ifdef _WIN32 -LONG OpenKey(HKEY root,const char* path,PHKEY hKey){ +LONG OpenKey(HKEY root, const char* path, PHKEY hKey) { return RegOpenKeyEx(root, reinterpret_cast(path), 0, KEY_READ, hKey); } -std::string QueryKey(HKEY hKey,int ID){ - TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name - DWORD cbName; // size of name string - TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name - DWORD cchClassName = MAX_PATH; // size of class string - DWORD cSubKeys=0; // number of subkeys - DWORD cbMaxSubKey; // longest subkey size - DWORD cchMaxClass; // longest class string - DWORD cValues; // number of values for key - DWORD cchMaxValue; // longest value name - DWORD cbMaxValueData; // longest value data - DWORD cbSecurityDescriptor; // size of security descriptor - FILETIME ftLastWriteTime; // last write time +std::string QueryKey(HKEY hKey, int ID) { + TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name + DWORD cbName; // size of name string + TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name + DWORD cchClassName = MAX_PATH; // size of class string + DWORD cSubKeys = 0; // number of subkeys + DWORD cbMaxSubKey; // longest subkey size + DWORD cchMaxClass; // longest class string + DWORD cValues; // number of values for key + DWORD cchMaxValue; // longest value name + DWORD cbMaxValueData; // longest value data + DWORD cbSecurityDescriptor; // size of security descriptor + FILETIME ftLastWriteTime; // last write time DWORD i, retCode; - TCHAR achValue[MAX_VALUE_NAME]; + TCHAR achValue[MAX_VALUE_NAME]; DWORD cchValue = MAX_VALUE_NAME; retCode = RegQueryInfoKey( - hKey, // key handle - achClass, // buffer for class name - &cchClassName, // size of class string - nullptr, // reserved - &cSubKeys, // number of subkeys - &cbMaxSubKey, // longest subkey size - &cchMaxClass, // longest class string - &cValues, // number of values for this key - &cchMaxValue, // longest value name - &cbMaxValueData, // longest value data - &cbSecurityDescriptor, // security descriptor - &ftLastWriteTime); // last write time + hKey, // key handle + achClass, // buffer for class name + &cchClassName, // size of class string + nullptr, // reserved + &cSubKeys, // number of subkeys + &cbMaxSubKey, // longest subkey size + &cchMaxClass, // longest class string + &cValues, // number of values for this key + &cchMaxValue, // longest value name + &cbMaxValueData, // longest value data + &cbSecurityDescriptor, // security descriptor + &ftLastWriteTime); // last write time BYTE* buffer = new BYTE[cbMaxValueData]; ZeroMemory(buffer, cbMaxValueData); - if (cSubKeys){ - for (i=0; i&a,const std::string& Path){ - for (const auto &entry : fs::directory_iterator(Path)) { +void FileList(std::vector& a, const std::string& Path) { + for (const auto& entry : fs::directory_iterator(Path)) { const auto& DPath = entry.path(); if (!entry.is_directory()) { a.emplace_back(DPath.string()); - }else if(NameValid(DPath.filename().string())){ + } else if (NameValid(DPath.filename().string())) { FileList(a, DPath.string()); } } } -bool Find(const std::string& FName,const std::string& Path){ +bool Find(const std::string& FName, const std::string& Path) { std::vector FS; - FileList(FS,Path+"\\userdata"); - for(std::string&a : FS){ - if(a.find(FName) != std::string::npos){ + FileList(FS, Path + "\\userdata"); + for (std::string& a : FS) { + if (a.find(FName) != std::string::npos) { FS.clear(); return true; } @@ -176,22 +187,24 @@ bool Find(const std::string& FName,const std::string& Path){ FS.clear(); return false; } -bool FindHack(const std::string& Path){ +bool FindHack(const std::string& Path) { bool s = true; - for (const auto &entry : fs::directory_iterator(Path)) { + for (const auto& entry : fs::directory_iterator(Path)) { std::string Name = entry.path().filename().string(); - for(char&c : Name)c = char(tolower(c)); - if(Name == "steam.exe")s = false; - if(Name.find("greenluma") != -1){ - error("Found malicious file/folder \"" + Name+"\""); + for (char& c : Name) + c = char(tolower(c)); + if (Name == "steam.exe") + s = false; + if (Name.find("greenluma") != -1) { + error("Found malicious file/folder \"" + Name + "\""); return true; } Name.clear(); } return s; } -std::vector GetID(const std::string& log){ - std::string vec,t,r; +std::vector GetID(const std::string& log) { + std::string vec, t, r; std::vector Ret; std::ifstream f(log.c_str(), std::ios::binary); f.seekg(0, std::ios_base::end); @@ -203,10 +216,12 @@ std::vector GetID(const std::string& log){ std::stringstream ss(vec); bool S = false; while (std::getline(ss, t, '{')) { - if(!S)S = true; - else{ - for(char& c : t){ - if(isdigit(c))r += c; + if (!S) + S = true; + else { + for (char& c : t) { + if (isdigit(c)) + r += c; } break; } @@ -216,15 +231,16 @@ std::vector GetID(const std::string& log){ S = false; bool L = true; while (std::getline(ss, t, '}')) { - if(L){ + if (L) { L = false; continue; } - for(char& c : t){ - if(c == '"'){ - if(!S)S = true; - else{ - if(r.length() > 10) { + for (char& c : t) { + if (c == '"') { + if (!S) + S = true; + else { + if (r.length() > 10) { Ret.emplace_back(r); } r.clear(); @@ -232,13 +248,14 @@ std::vector GetID(const std::string& log){ continue; } } - if(isdigit(c))r += c; + if (isdigit(c)) + r += c; } } vec.clear(); return Ret; } -std::string GetManifest(const std::string& Man){ +std::string GetManifest(const std::string& Man) { std::string vec; std::ifstream f(Man.c_str(), std::ios::binary); f.seekg(0, std::ios_base::end); @@ -249,103 +266,109 @@ std::string GetManifest(const std::string& Man){ f.close(); std::string ToFind = "\"LastOwner\"\t\t\""; int pos = int(vec.find(ToFind)); - if(pos != -1){ + if (pos != -1) { pos += int(ToFind.length()); vec = vec.substr(pos); - return vec.substr(0,vec.find('\"')); - }else return ""; + return vec.substr(0, vec.find('\"')); + } else + return ""; } -bool IDCheck(std::string Man, std::string steam){ - bool a = false,b = true; +bool IDCheck(std::string Man, std::string steam) { + bool a = false, b = true; int pos = int(Man.rfind("steamapps")); - // if(pos == -1)Exit(5); - Man = Man.substr(0,pos+9) + "\\appmanifest_284160.acf"; + // if(pos == -1)Exit(5); + Man = Man.substr(0, pos + 9) + "\\appmanifest_284160.acf"; steam += "\\config\\loginusers.vdf"; - if(fs::exists(Man) && fs::exists(steam)){ - for(const std::string&ID : GetID(steam)){ - if(ID == GetManifest(Man))b = false; + if (fs::exists(Man) && fs::exists(steam)) { + for (const std::string& ID : GetID(steam)) { + if (ID == GetManifest(Man)) + b = false; } - //if(b)Exit(6); - }else a = true; + // if(b)Exit(6); + } else + a = true; return a; } -void LegitimacyCheck(){ +void LegitimacyCheck() { - //std::string K1 = R"(Software\Valve\Steam)"; - //std::string K2 = R"(Software\Valve\Steam\Apps\284160)"; +// std::string K1 = R"(Software\Valve\Steam)"; +// std::string K2 = R"(Software\Valve\Steam\Apps\284160)"; - /*LONG dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K1.c_str(), &hKey); +/*LONG dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K1.c_str(), &hKey); - if(dwRegOPenKey == ERROR_SUCCESS) { - Result = QueryKey(hKey, 1); - if(Result.empty())Exit(1); +if(dwRegOPenKey == ERROR_SUCCESS) { + Result = QueryKey(hKey, 1); + if(Result.empty())Exit(1); - if(fs::exists(Result)){ - if(!Find("284160.json",Result))Exit(2); - if(FindHack(Result))SteamExit(1); - }else Exit(3); + if(fs::exists(Result)){ + if(!Find("284160.json",Result))Exit(2); + if(FindHack(Result))SteamExit(1); + }else Exit(3); - T = Result; - Result.clear(); - TraceBack++; - }else Exit(4); + T = Result; + Result.clear(); + TraceBack++; +}else Exit(4); - K1.clear(); - RegCloseKey(hKey); - dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K2.c_str(), &hKey); - if(dwRegOPenKey == ERROR_SUCCESS) { - Result = QueryKey(hKey, 2); - if(Result.empty())lowExit(1); - TraceBack++; - }else lowExit(2); - K2.clear(); - RegCloseKey(hKey);*/ - #if defined(_WIN32) +K1.clear(); +RegCloseKey(hKey); +dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K2.c_str(), &hKey); +if(dwRegOPenKey == ERROR_SUCCESS) { + Result = QueryKey(hKey, 2); + if(Result.empty())lowExit(1); + TraceBack++; +}else lowExit(2); +K2.clear(); +RegCloseKey(hKey);*/ +#if defined(_WIN32) std::string Result; std::string K3 = R"(Software\BeamNG\BeamNG.drive)"; HKEY hKey; LONG dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K3.c_str(), &hKey); - if(dwRegOPenKey == ERROR_SUCCESS) { + if (dwRegOPenKey == ERROR_SUCCESS) { Result = QueryKey(hKey, 3); - if(Result.empty())lowExit(3); - //if(IDCheck(Result,T))lowExit(5); + if (Result.empty()) + lowExit(3); + // if(IDCheck(Result,T))lowExit(5); GameDir = Result; - //TraceBack++; - }else lowExit(4); + // TraceBack++; + } else + lowExit(4); K3.clear(); Result.clear(); RegCloseKey(hKey); - //if(TraceBack < 3)exit(-1); - #elif defined(__linux__) - struct passwd *pw = getpwuid(getuid()); +// if(TraceBack < 3)exit(-1); +#elif defined(__linux__) + struct passwd* pw = getpwuid(getuid()); std::string homeDir = pw->pw_dir; // Right now only steam is supported std::ifstream libraryFolders(homeDir + "/.steam/root/steamapps/libraryfolders.vdf"); auto root = tyti::vdf::read(libraryFolders); - for (auto folderInfo: root.childs){ - if (std::filesystem::exists(folderInfo.second->attribs["path"] + "/steamapps/common/BeamNG.drive/")){ + for (auto folderInfo : root.childs) { + if (std::filesystem::exists(folderInfo.second->attribs["path"] + "/steamapps/common/BeamNG.drive/")) { GameDir = folderInfo.second->attribs["path"] + "/steamapps/common/BeamNG.drive/"; break; } } - #endif +#endif } -std::string CheckVer(const std::string &dir){ - #if defined(_WIN32) - std::string temp,Path = dir + "\\integrity.json"; - #elif defined(__linux__) - std::string temp,Path = dir + "/integrity.json"; - #endif +std::string CheckVer(const std::string& dir) { +#if defined(_WIN32) + std::string temp, Path = dir + "\\integrity.json"; +#elif defined(__linux__) + std::string temp, Path = dir + "/integrity.json"; +#endif std::ifstream f(Path.c_str(), std::ios::binary); int Size = int(std::filesystem::file_size(Path)); - std::string vec(Size,0); + std::string vec(Size, 0); f.read(&vec[0], Size); f.close(); - vec = vec.substr(vec.find_last_of("version"),vec.find_last_of('"')); - for(const char &a : vec){ - if(isdigit(a) || a == '.')temp+=a; + vec = vec.substr(vec.find_last_of("version"), vec.find_last_of('"')); + for (const char& a : vec) { + if (isdigit(a) || a == '.') + temp += a; } return temp; } diff --git a/src/Security/Login.cpp b/src/Security/Login.cpp index 0f8727c..8fbf15a 100644 --- a/src/Security/Login.cpp +++ b/src/Security/Login.cpp @@ -6,12 +6,11 @@ /// Created by Anonymous275 on 11/26/2020 /// -#include #include "Http.h" -#include #include "Logger.h" +#include #include - +#include namespace fs = std::filesystem; std::string PublicKey; @@ -20,15 +19,16 @@ extern bool LoginAuth; extern std::string Username; extern std::string UserRole; -void UpdateKey(const char* newKey){ - if(newKey && std::isalnum(newKey[0])){ +void UpdateKey(const char* newKey) { + if (newKey && std::isalnum(newKey[0])) { PrivateKey = newKey; std::ofstream Key("key"); - if(Key.is_open()){ + if (Key.is_open()) { Key << newKey; Key.close(); - }else fatal("Cannot write to disk!"); - }else if(fs::exists("key")){ + } else + fatal("Cannot write to disk!"); + } else if (fs::exists("key")) { remove("key"); } } @@ -37,15 +37,15 @@ void UpdateKey(const char* newKey){ /// "Guest":"Name" /// "pk":"private_key" -std::string GetFail(const std::string& R){ +std::string GetFail(const std::string& R) { std::string DRet = R"({"success":false,"message":)"; - DRet += "\""+R+"\"}"; + DRet += "\"" + R + "\"}"; error(R); return DRet; } -std::string Login(const std::string& fields){ - if(fields == "LO"){ +std::string Login(const std::string& fields) { + if (fields == "LO") { Username = ""; UserRole = ""; LoginAuth = false; @@ -56,7 +56,7 @@ std::string Login(const std::string& fields){ try { std::string Buffer = HTTP::Post("https://auth.beammp.com/userlogin", fields); - if(Buffer == "-1"){ + if (Buffer == "-1") { return GetFail("Failed to communicate with the auth system!"); } @@ -66,7 +66,7 @@ std::string Login(const std::string& fields){ error(Buffer); return GetFail("Invalid answer from authentication servers, please try again later!"); } - if(d.contains("success") && d["success"].get()){ + if (d.contains("success") && d["success"].get()) { LoginAuth = true; if (d.contains("username")) { Username = d["username"].get(); @@ -74,15 +74,16 @@ std::string Login(const std::string& fields){ if (d.contains("role")) { UserRole = d["role"].get(); } - if(d.contains("private_key")) { + if (d.contains("private_key")) { UpdateKey(d["private_key"].get().c_str()); } - if(d.contains("public_key")){ + if (d.contains("public_key")) { PublicKey = d["public_key"].get(); } info("Authentication successful!"); - }else info("Authentication failed!"); - if(d.contains("message")){ + } else + info("Authentication failed!"); + if (d.contains("message")) { d.erase("private_key"); d.erase("public_key"); return d.dump(); @@ -93,20 +94,20 @@ std::string Login(const std::string& fields){ } } -void CheckLocalKey(){ - if(fs::exists("key") && fs::file_size("key") < 100){ +void CheckLocalKey() { + if (fs::exists("key") && fs::file_size("key") < 100) { std::ifstream Key("key"); - if(Key.is_open()) { + if (Key.is_open()) { auto Size = fs::file_size("key"); std::string Buffer(Size, 0); Key.read(&Buffer[0], Size); Key.close(); for (char& c : Buffer) { - if (!std::isalnum(c) && c != '-') { - UpdateKey(nullptr); - return; - } + if (!std::isalnum(c) && c != '-') { + UpdateKey(nullptr); + return; + } } Buffer = HTTP::Post("https://auth.beammp.com/userlogin", R"({"pk":")" + Buffer + "\"}"); @@ -118,7 +119,7 @@ void CheckLocalKey(){ info("Invalid answer from authentication servers."); UpdateKey(nullptr); } - if(d["success"].get()){ + if (d["success"].get()) { LoginAuth = true; UpdateKey(d["private_key"].get().c_str()); PublicKey = d["public_key"].get(); @@ -128,14 +129,15 @@ void CheckLocalKey(){ if (d.contains("role")) { UserRole = d["role"].get(); } - //info(Role); - }else{ + // info(Role); + } else { info("Auto-Authentication unsuccessful please re-login!"); UpdateKey(nullptr); } - }else{ + } else { warn("Could not open saved key!"); UpdateKey(nullptr); } - }else UpdateKey(nullptr); + } else + UpdateKey(nullptr); } diff --git a/src/Startup.cpp b/src/Startup.cpp index f20e961..1fb23f9 100644 --- a/src/Startup.cpp +++ b/src/Startup.cpp @@ -6,25 +6,24 @@ /// Created by Anonymous275 on 7/16/2020 /// -#include -#include #include "zip_file.h" +#include +#include #include #if defined(_WIN32) #include #elif defined(__linux__) #include #endif +#include "Http.h" +#include "Logger.h" #include "Network/network.hpp" #include "Security/Init.h" -#include #include "Startup.h" #include "hashpp.h" -#include "Logger.h" +#include #include #include -#include "Http.h" - extern int TraceBack; bool Dev = false; @@ -42,23 +41,29 @@ VersionParser::VersionParser(const std::string& from_string) { } std::strong_ordering VersionParser::operator<=>( - const VersionParser& rhs) const noexcept { + const VersionParser& rhs) const noexcept { size_t const fields = std::min(data.size(), rhs.data.size()); for (size_t i = 0; i != fields; ++i) { - if (data[i] == rhs.data[i]) continue; - else if (data[i] < rhs.data[i]) return std::strong_ordering::less; - else return std::strong_ordering::greater; + if (data[i] == rhs.data[i]) + continue; + else if (data[i] < rhs.data[i]) + return std::strong_ordering::less; + else + return std::strong_ordering::greater; } - if (data.size() == rhs.data.size()) return std::strong_ordering::equal; - else if (data.size() > rhs.data.size()) return std::strong_ordering::greater; - else return std::strong_ordering::less; + if (data.size() == rhs.data.size()) + return std::strong_ordering::equal; + else if (data.size() > rhs.data.size()) + return std::strong_ordering::greater; + else + return std::strong_ordering::less; } bool VersionParser::operator==(const VersionParser& rhs) const noexcept { return std::is_eq(*this <=> rhs); } -std::string GetEN(){ +std::string GetEN() { #if defined(_WIN32) return "BeamMP-Launcher.exe"; #elif defined(__linux__) @@ -66,61 +71,61 @@ std::string GetEN(){ #endif } -std::string GetVer(){ +std::string GetVer() { return "2.0"; } -std::string GetPatch(){ +std::string GetPatch() { return ".85"; } -std::string GetEP(char*P){ - static std::string Ret = [&](){ +std::string GetEP(char* P) { + static std::string Ret = [&]() { std::string path(P); return path.substr(0, path.find_last_of("\\/") + 1); - } (); + }(); return Ret; } #if defined(_WIN32) -void ReLaunch(int argc,char*args[]){ +void ReLaunch(int argc, char* args[]) { std::string Arg; - for(int c = 2; c <= argc; c++){ + for (int c = 2; c <= argc; c++) { Arg += " "; - Arg += args[c-1]; + Arg += args[c - 1]; } system("cls"); - ShellExecute(nullptr,"runas",(GetEP() + GetEN()).c_str(),Arg.c_str(),nullptr,SW_SHOWNORMAL); - ShowWindow(GetConsoleWindow(),0); + ShellExecute(nullptr, "runas", (GetEP() + GetEN()).c_str(), Arg.c_str(), nullptr, SW_SHOWNORMAL); + ShowWindow(GetConsoleWindow(), 0); std::this_thread::sleep_for(std::chrono::seconds(1)); exit(1); } -void URelaunch(int argc,char* args[]){ +void URelaunch(int argc, char* args[]) { std::string Arg; - for(int c = 2; c <= argc; c++){ + for (int c = 2; c <= argc; c++) { Arg += " "; - Arg += args[c-1]; + Arg += args[c - 1]; } - ShellExecute(nullptr,"open",(GetEP() + GetEN()).c_str(),Arg.c_str(),nullptr,SW_SHOWNORMAL); - ShowWindow(GetConsoleWindow(),0); + ShellExecute(nullptr, "open", (GetEP() + GetEN()).c_str(), Arg.c_str(), nullptr, SW_SHOWNORMAL); + ShowWindow(GetConsoleWindow(), 0); std::this_thread::sleep_for(std::chrono::seconds(1)); exit(1); } #elif defined(__linux__) -void ReLaunch(int argc,char*args[]){ +void ReLaunch(int argc, char* args[]) { std::string Arg; - for(int c = 2; c <= argc; c++){ + for (int c = 2; c <= argc; c++) { Arg += " "; - Arg += args[c-1]; + Arg += args[c - 1]; } system("clear"); execl((GetEP() + GetEN()).c_str(), Arg.c_str(), NULL); std::this_thread::sleep_for(std::chrono::seconds(1)); exit(1); } -void URelaunch(int argc,char* args[]){ +void URelaunch(int argc, char* args[]) { std::string Arg; - for(int c = 2; c <= argc; c++){ + for (int c = 2; c <= argc; c++) { Arg += " "; - Arg += args[c-1]; + Arg += args[c - 1]; } execl((GetEP() + GetEN()).c_str(), Arg.c_str(), NULL); std::this_thread::sleep_for(std::chrono::seconds(1)); @@ -128,81 +133,86 @@ void URelaunch(int argc,char* args[]){ } #endif -void CheckName(int argc,char* args[]){ - #if defined(_WIN32) - std::string DN = GetEN(),CDir = args[0],FN = CDir.substr(CDir.find_last_of('\\')+1); - #elif defined(__linux__) - std::string DN = GetEN(),CDir = args[0],FN = CDir.substr(CDir.find_last_of('/')+1); - #endif - if(FN != DN){ - if(fs::exists(DN))remove(DN.c_str()); - if(fs::exists(DN))ReLaunch(argc,args); +void CheckName(int argc, char* args[]) { +#if defined(_WIN32) + std::string DN = GetEN(), CDir = args[0], FN = CDir.substr(CDir.find_last_of('\\') + 1); +#elif defined(__linux__) + std::string DN = GetEN(), CDir = args[0], FN = CDir.substr(CDir.find_last_of('/') + 1); +#endif + if (FN != DN) { + if (fs::exists(DN)) + remove(DN.c_str()); + if (fs::exists(DN)) + ReLaunch(argc, args); std::rename(FN.c_str(), DN.c_str()); - URelaunch(argc,args); + URelaunch(argc, args); } } void CheckForUpdates(int argc, char* args[], const std::string& CV) { std::string LatestHash = HTTP::Get("https://backend.beammp.com/sha/launcher?branch=" + Branch + "&pk=" + PublicKey); std::string LatestVersion = HTTP::Get( - "https://backend.beammp.com/version/launcher?branch=" + Branch + "&pk=" + PublicKey); + "https://backend.beammp.com/version/launcher?branch=" + Branch + "&pk=" + PublicKey); transform(LatestHash.begin(), LatestHash.end(), LatestHash.begin(), ::tolower); std::string EP(GetEP() + GetEN()), Back(GetEP() + "BeamMP-Launcher.back"); std::string FileHash = hashpp::get::getFileHash(hashpp::ALGORITHMS::SHA2_256, EP); - #if defined(_WIN32) - #elif defined(__linux__) - system("clear"); - #endif +#if defined(_WIN32) +#elif defined(__linux__) + system("clear"); +#endif - if (FileHash != LatestHash && VersionParser(LatestVersion) > VersionParser(GetVer()+GetPatch())) { + if (FileHash != LatestHash && VersionParser(LatestVersion) > VersionParser(GetVer() + GetPatch())) { info("Launcher update found!"); fs::remove(Back); fs::rename(EP, Back); info("Downloading Launcher update " + LatestHash); HTTP::Download( - "https://backend.beammp.com/builds/launcher?download=true" - "&pk=" + - PublicKey + "&branch=" + Branch, - EP); + "https://backend.beammp.com/builds/launcher?download=true" + "&pk=" + + PublicKey + "&branch=" + Branch, + EP); URelaunch(argc, args); - } else info("Launcher version is up to date"); + } else + info("Launcher version is up to date"); TraceBack++; } -void CustomPort(int argc, char* argv[]){ - if(argc > 1){ +void CustomPort(int argc, char* argv[]) { + if (argc > 1) { std::string Port = argv[1]; - if(Port.find_first_not_of("0123456789") == std::string::npos){ - if(std::stoi(Port) > 1000){ + if (Port.find_first_not_of("0123456789") == std::string::npos) { + if (std::stoi(Port) > 1000) { DEFAULT_PORT = std::stoi(Port); warn("Running on custom port : " + std::to_string(DEFAULT_PORT)); } } - if(argc > 2)Dev = true; + if (argc > 2) + Dev = true; } } #ifdef _WIN32 -void LinuxPatch(){ +void LinuxPatch() { HKEY hKey = nullptr; LONG result = RegOpenKeyEx(HKEY_CURRENT_USER, R"(Software\Wine)", 0, KEY_READ, &hKey); - if (result != ERROR_SUCCESS || getenv("USER") == nullptr)return; + if (result != ERROR_SUCCESS || getenv("USER") == nullptr) + return; RegCloseKey(hKey); info("Wine/Proton Detected! If you are on windows delete HKEY_CURRENT_USER\\Software\\Wine in regedit"); info("Applying patches..."); result = RegCreateKey(HKEY_CURRENT_USER, R"(Software\Valve\Steam\Apps\284160)", &hKey); - if (result != ERROR_SUCCESS){ + if (result != ERROR_SUCCESS) { fatal(R"(failed to create HKEY_CURRENT_USER\Software\Valve\Steam\Apps\284160)"); return; } result = RegSetValueEx(hKey, "Name", 0, REG_SZ, (BYTE*)"BeamNG.drive", 12); - if (result != ERROR_SUCCESS){ + if (result != ERROR_SUCCESS) { fatal(R"(failed to create the value "Name" under HKEY_CURRENT_USER\Software\Valve\Steam\Apps\284160)"); return; } @@ -236,93 +246,100 @@ void InitLauncher(int argc, char* argv[]) { } #endif -size_t DirCount(const std::filesystem::path& path){ - return (size_t)std::distance(std::filesystem::directory_iterator{path}, std::filesystem::directory_iterator{}); +size_t DirCount(const std::filesystem::path& path) { + return (size_t)std::distance(std::filesystem::directory_iterator { path }, std::filesystem::directory_iterator {}); } void CheckMP(const std::string& Path) { - if (!fs::exists(Path))return; + if (!fs::exists(Path)) + return; size_t c = DirCount(fs::path(Path)); try { - for (auto& p : fs::directory_iterator(Path)){ - if(p.exists() && !p.is_directory()){ + for (auto& p : fs::directory_iterator(Path)) { + if (p.exists() && !p.is_directory()) { std::string Name = p.path().filename().string(); - for(char&Ch : Name)Ch = char(tolower(Ch)); - if(Name != "beammp.zip")fs::remove(p.path()); + for (char& Ch : Name) + Ch = char(tolower(Ch)); + if (Name != "beammp.zip") + fs::remove(p.path()); } } } catch (...) { fatal("We were unable to clean the multiplayer mods folder! Is the game still running or do you have something open in that folder?"); } - } -void EnableMP(){ +void EnableMP() { std::string File(GetGamePath() + "mods/db.json"); - if(!fs::exists(File))return; + if (!fs::exists(File)) + return; auto Size = fs::file_size(File); - if(Size < 2)return; + if (Size < 2) + return; std::ifstream db(File); - if(db.is_open()) { + if (db.is_open()) { std::string Data(Size, 0); db.read(&Data[0], Size); db.close(); nlohmann::json d = nlohmann::json::parse(Data, nullptr, false); - if(Data.at(0) != '{' || d.is_discarded()) { - //error("Failed to parse " + File); //TODO illegal formatting + if (Data.at(0) != '{' || d.is_discarded()) { + // error("Failed to parse " + File); //TODO illegal formatting return; } - if(d.contains("mods") && d["mods"].contains("multiplayerbeammp")){ + if (d.contains("mods") && d["mods"].contains("multiplayerbeammp")) { d["mods"]["multiplayerbeammp"]["active"] = true; std::ofstream ofs(File); - if(ofs.is_open()){ + if (ofs.is_open()) { ofs << d.dump(); ofs.close(); - }else{ + } else { error("Failed to write " + File); } } } } -void PreGame(const std::string& GamePath){ +void PreGame(const std::string& GamePath) { std::string GameVer = CheckVer(GamePath); info("Game Version : " + GameVer); - + CheckMP(GetGamePath() + "mods/multiplayer"); - if(!Dev) { + if (!Dev) { std::string LatestHash = HTTP::Get("https://backend.beammp.com/sha/mod?branch=" + Branch + "&pk=" + PublicKey); transform(LatestHash.begin(), LatestHash.end(), LatestHash.begin(), ::tolower); LatestHash.erase(std::remove_if(LatestHash.begin(), LatestHash.end(), - [](auto const& c ) -> bool { return !std::isalnum(c); } ), LatestHash.end()); + [](auto const& c) -> bool { return !std::isalnum(c); }), + LatestHash.end()); try { if (!fs::exists(GetGamePath() + "mods/multiplayer")) { fs::create_directories(GetGamePath() + "mods/multiplayer"); } EnableMP(); - }catch(std::exception&e){ + } catch (std::exception& e) { fatal(e.what()); } - #if defined(_WIN32) +#if defined(_WIN32) std::string ZipPath(GetGamePath() + R"(mods\multiplayer\BeamMP.zip)"); - #elif defined(__linux__) +#elif defined(__linux__) // Linux version of the game cant handle mods with uppercase names std::string ZipPath(GetGamePath() + R"(mods/multiplayer/beammp.zip)"); - #endif +#endif std::string FileHash = hashpp::get::getFileHash(hashpp::ALGORITHMS::SHA2_256, ZipPath); if (FileHash != LatestHash) { info("Downloading BeamMP Update " + LatestHash); HTTP::Download("https://backend.beammp.com/builds/client?download=true" - "&pk=" + PublicKey + "&branch=" + Branch, ZipPath); + "&pk=" + + PublicKey + "&branch=" + Branch, + ZipPath); } std::string Target(GetGamePath() + "mods/unpacked/beammp"); - if(fs::is_directory(Target)) { + if (fs::is_directory(Target)) { fs::remove_all(Target); } } @@ -335,15 +352,15 @@ void set_headers(httplib::Response& res) { } void StartProxy() { - std::thread proxy([&](){ + std::thread proxy([&]() { httplib::Server HTTPProxy; httplib::Headers headers = { - {"User-Agent", "BeamMP-Launcher/" + GetVer() + GetPatch()}, - {"Accept", "*/*"} + { "User-Agent", "BeamMP-Launcher/" + GetVer() + GetPatch() }, + { "Accept", "*/*" } }; std::string pattern = "/:any1"; for (int i = 2; i <= 4; i++) { - HTTPProxy.Get(pattern, [&](const httplib::Request &req, httplib::Response &res) { + HTTPProxy.Get(pattern, [&](const httplib::Request& req, httplib::Response& res) { httplib::Client cli("https://backend.beammp.com"); set_headers(res); if (req.has_header("X-BMP-Authentication")) { @@ -359,7 +376,7 @@ void StartProxy() { } }); - HTTPProxy.Post(pattern, [&](const httplib::Request &req, httplib::Response &res) { + HTTPProxy.Post(pattern, [&](const httplib::Request& req, httplib::Response& res) { httplib::Client cli("https://backend.beammp.com"); set_headers(res); if (req.has_header("X-BMP-Authentication")) { @@ -369,7 +386,8 @@ void StartProxy() { headers.emplace("X-API-Version", req.get_header_value("X-API-Version")); } if (auto cli_res = cli.Post(req.path, headers, req.body, - req.get_header_value("Content-Type")); cli_res) { + req.get_header_value("Content-Type")); + cli_res) { res.set_content(cli_res->body, cli_res->get_header_value("Content-Type")); } else { res.set_content(to_string(cli_res.error()), "text/plain"); diff --git a/src/main.cpp b/src/main.cpp index 45b7965..0859282 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,16 +5,16 @@ /// /// Created by Anonymous275 on 7/16/2020 /// +#include "Http.h" +#include "Logger.h" #include "Network/network.hpp" #include "Security/Init.h" #include "Startup.h" #include -#include "Logger.h" #include -#include "Http.h" -[[noreturn]] void flush(){ - while(true){ +[[noreturn]] void flush() { + while (true) { std::cout.flush(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -32,7 +32,7 @@ int main(int argc, char* argv[]) { try { LegitimacyCheck(); - } catch (std::exception &e) { + } catch (std::exception& e) { fatal("Main 1 : " + std::string(e.what())); } @@ -41,5 +41,5 @@ int main(int argc, char* argv[]) { InitGame(GetGameDir()); CoreNetwork(); - ///TODO: make sure to use argv[0] for everything that should be in the same dir (mod down ect...) + /// TODO: make sure to use argv[0] for everything that should be in the same dir (mod down ect...) }