From 8bc35fb82e3568cc40dd700b28921d7f5d4448a3 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Sun, 1 Nov 2020 02:00:27 +0100 Subject: [PATCH 01/30] Refactor to work on Linux / Unix, fix some compiler errors. CMakeLists was also modified to make this work, but its scuffed and i will hold on to that for a while longer --- include/Client.hpp | 7 +++- include/Lua/LuaSystem.hpp | 6 ++-- include/Security/Enc.h | 4 +++ include/Security/Xor.h | 13 ++++---- include/UnixCompat.h | 30 +++++++++++++++++ src/Compressor.cpp | 25 +++++++------- src/Console.cpp | 12 +++++-- src/Enc.cpp | 8 +++-- src/Init/Resources.cpp | 6 ++-- src/Init/Startup.cpp | 3 +- src/Lua/LuaMain.cpp | 5 +++ src/Lua/LuaSystem.cpp | 14 ++++++-- src/Network/Auth.cpp | 54 +++++++++++++++++++++++++++++- src/Network/GParser.cpp | 16 +++++++-- src/Network/Sync.cpp | 8 ++++- src/Network/TCPHandler.cpp | 15 ++++++++- src/Network/VehicleData.cpp | 65 ++++++++++++++++++++++++++++++++++--- src/logger.cpp | 4 +++ 18 files changed, 254 insertions(+), 41 deletions(-) create mode 100644 include/UnixCompat.h diff --git a/include/Client.hpp b/include/Client.hpp index 310c320..11f5c1f 100644 --- a/include/Client.hpp +++ b/include/Client.hpp @@ -3,7 +3,12 @@ /// #pragma once +#ifdef __WIN32 #include +#else +#include +#define SOCKET int +#endif #include "Buffer.h" #include #include @@ -67,4 +72,4 @@ struct ClientInterface{ } }; -extern ClientInterface* CI; \ No newline at end of file +extern ClientInterface* CI; diff --git a/include/Lua/LuaSystem.hpp b/include/Lua/LuaSystem.hpp index e7f1461..1bf5a43 100644 --- a/include/Lua/LuaSystem.hpp +++ b/include/Lua/LuaSystem.hpp @@ -11,7 +11,9 @@ #include #include #include -namespace fs = std::experimental::filesystem; + +namespace fs = std::filesystem; + struct LuaArg{ std::vector args; void PushArgs(lua_State *State){ @@ -64,4 +66,4 @@ public: }; int CallFunction(Lua*lua,const std::string& FuncName,LuaArg* args); int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller,LuaArg* arg,bool Wait); -extern std::set PluginEngine; \ No newline at end of file +extern std::set PluginEngine; diff --git a/include/Security/Enc.h b/include/Security/Enc.h index e418232..02bd72a 100644 --- a/include/Security/Enc.h +++ b/include/Security/Enc.h @@ -2,7 +2,11 @@ /// Created by Anonymous275 on 7/28/2020 /// #pragma once +#ifdef __linux +#define EXCEPTION_POINTERS void +#else #include +#endif #include #include "Xor.h" struct RSA{ diff --git a/include/Security/Xor.h b/include/Security/Xor.h index a7b2874..d4f0d91 100644 --- a/include/Security/Xor.h +++ b/include/Security/Xor.h @@ -5,6 +5,7 @@ #include #include #include +#include #define BEGIN_NAMESPACE(x) namespace x { #define END_NAMESPACE } @@ -68,10 +69,10 @@ BEGIN_NAMESPACE(XorCompileTime) public: template - constexpr __forceinline XorString(const Char* str, std::index_sequence< Is... >) : _key(RandomChar< K >::value), _encrypted{ enc(str[Is])... } + constexpr inline XorString(const Char* str, std::index_sequence< Is... >) : _key(RandomChar< K >::value), _encrypted{ enc(str[Is])... } {} - __forceinline decltype(auto) decrypt(){ + inline decltype(auto) decrypt(){ for (size_t i = 0; i < N; ++i) { _encrypted[i] = dec(_encrypted[i]); } @@ -83,14 +84,14 @@ BEGIN_NAMESPACE(XorCompileTime) static auto w_printf = [](const char* fmt, ...) { va_list args; va_start(args, fmt); - vprintf_s(fmt, args); + vprintf(fmt, args); va_end(args); }; static auto w_printf_s = [](const char* fmt, ...) { va_list args; va_start(args, fmt); - vprintf_s(fmt, args); + vprintf(fmt, args); va_end(args); }; @@ -113,7 +114,7 @@ BEGIN_NAMESPACE(XorCompileTime) static auto w_sprintf_s = [](char* buf, size_t buf_size, const char* fmt, ...) { va_list args; va_start(args, fmt); - vsprintf_s(buf, buf_size, fmt, args); + vsnprintf(buf, buf_size, fmt, args); va_end(args); }; @@ -121,7 +122,7 @@ BEGIN_NAMESPACE(XorCompileTime) int ret; va_list args; va_start(args, fmt); - ret = vsprintf_s(buf, buf_size, fmt, args); + ret = vsnprintf(buf, buf_size, fmt, args); va_end(args); return ret; }; diff --git a/include/UnixCompat.h b/include/UnixCompat.h new file mode 100644 index 0000000..a5d23e1 --- /dev/null +++ b/include/UnixCompat.h @@ -0,0 +1,30 @@ +// Author: lionkor + +#pragma once + +// This header defines unix equivalents of common win32 functions. + +#ifndef __WIN32 + +#include +#include +#include + +// ZeroMemory is just a {0} or a memset(addr, 0, len), and it's a macro on MSVC +inline void ZeroMemory(void* dst, size_t len) { + assert(std::memset(dst, 0, len) != nullptr); +} +// provides unix equivalent of closesocket call in win32 +inline void closesocket(int socket) { + close(socket); +} + +#ifndef __try +#define __try +#endif + +#ifndef __except +#define __except(x) /**/ +#endif + +#endif // __WIN32 diff --git a/src/Compressor.cpp b/src/Compressor.cpp index 9733650..65e7630 100644 --- a/src/Compressor.cpp +++ b/src/Compressor.cpp @@ -3,11 +3,15 @@ /// #include "Zlib/zlib.h" #include +#include +#include +#include #define Biggest 30000 std::string Comp(std::string Data){ - char*C = new char[Biggest]; - memset(C, 0, Biggest); + std::array C; + // obsolete + C.fill(0); z_stream defstream; defstream.zalloc = Z_NULL; defstream.zfree = Z_NULL; @@ -15,20 +19,20 @@ std::string Comp(std::string Data){ defstream.avail_in = (uInt)Data.length(); defstream.next_in = (Bytef *)&Data[0]; defstream.avail_out = Biggest; - defstream.next_out = reinterpret_cast(C); + defstream.next_out = reinterpret_cast(C.data()); 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_s(&Ret[0],TO,C,TO); - delete [] C; + std::copy_n(C.begin(), TO, Ret.begin()); return Ret; } std::string DeComp(std::string Compressed){ - char*C = new char[Biggest]; - memset(C, 0, Biggest); + std::array C; + // not needed + C.fill(0); z_stream infstream; infstream.zalloc = Z_NULL; infstream.zfree = Z_NULL; @@ -36,14 +40,13 @@ std::string DeComp(std::string Compressed){ infstream.avail_in = Biggest; infstream.next_in = (Bytef *)(&Compressed[0]); infstream.avail_out = Biggest; - infstream.next_out = (Bytef *)(C); + infstream.next_out = (Bytef *)(C.data()); inflateInit(&infstream); inflate(&infstream, Z_SYNC_FLUSH); inflate(&infstream, Z_FINISH); inflateEnd(&infstream); int TO = infstream.total_out; std::string Ret(TO,0); - memcpy_s(&Ret[0],TO,C,TO); - delete [] C; + std::copy_n(C.begin(), TO, Ret.begin()); return Ret; -} \ No newline at end of file +} diff --git a/src/Console.cpp b/src/Console.cpp index 1d01193..b78ba6c 100644 --- a/src/Console.cpp +++ b/src/Console.cpp @@ -3,10 +3,14 @@ /// #include "Lua/LuaSystem.hpp" +#ifdef __WIN32 #include +#include +#else // *nix +typedef unsigned long DWORD, *PDWORD, *LPDWORD; +#endif // __WIN32 #include "Logger.h" #include -#include #include #include #include @@ -47,6 +51,7 @@ void ConsoleOut(const std::string& msg){ } } void SetupConsole(){ +#ifdef __WIN32 DWORD outMode = 0; HANDLE stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); if (stdoutHandle == INVALID_HANDLE_VALUE){ @@ -66,10 +71,11 @@ void SetupConsole(){ std::this_thread::sleep_for(std::chrono::seconds(3)); exit(GetLastError()); } +#endif // __WIN32 } [[noreturn]] void ReadCin(){ while (true){ - int In = _getch(); + int In = getchar(); if (In == 13) { if(!CInputBuff.empty()) { HandleInput(CInputBuff); @@ -90,4 +96,4 @@ void ConsoleInit(){ In.detach(); std::thread Out(OutputRefresh); Out.detach(); -} \ No newline at end of file +} diff --git a/src/Enc.cpp b/src/Enc.cpp index e2ec495..4c7d12f 100644 --- a/src/Enc.cpp +++ b/src/Enc.cpp @@ -3,11 +3,12 @@ /// #include "Security/Enc.h" #include "Settings.h" -#include +//#include #include "Logger.h" #include #include #include +#include int Rand(){ std::random_device r; @@ -85,9 +86,10 @@ int Dec(int value,int d,int n){ } int Handle(EXCEPTION_POINTERS *ep,char* Origin){ + assert(false); std::stringstream R; R << Sec("Code : ") << std::hex - << ep->ExceptionRecord->ExceptionCode + //<< ep->ExceptionRecord->ExceptionCode << std::dec << Sec(" Origin : ") << Origin; except(R.str()); return 1; @@ -116,4 +118,4 @@ std::string RSA_D(const std::string& Data, RSA*k){ ret += char(Dec(c,k->d,k->n)); } return ret; -} \ No newline at end of file +} diff --git a/src/Init/Resources.cpp b/src/Init/Resources.cpp index 233f192..06f7500 100644 --- a/src/Init/Resources.cpp +++ b/src/Init/Resources.cpp @@ -6,7 +6,9 @@ #include "Settings.h" #include #include "Logger.h" -namespace fs = std::experimental::filesystem; + +namespace fs = std::filesystem; + uint64_t MaxModSize = 0; std::string FileSizes; std::string FileList; @@ -30,4 +32,4 @@ void InitRes(){ if(ModsLoaded){ info(Sec("Loaded ")+std::to_string(ModsLoaded)+Sec(" Mods")); } -} \ No newline at end of file +} diff --git a/src/Init/Startup.cpp b/src/Init/Startup.cpp index 7e7a7ee..cf4f70e 100644 --- a/src/Init/Startup.cpp +++ b/src/Init/Startup.cpp @@ -5,6 +5,7 @@ #include "Client.hpp" #include "Logger.h" #include +#include std::string CustomIP; std::string GetSVer(){ @@ -31,4 +32,4 @@ void InitServer(int argc, char* argv[]){ InitLog(); Args(argc,argv); CI = new ClientInterface; -} \ No newline at end of file +} diff --git a/src/Lua/LuaMain.cpp b/src/Lua/LuaMain.cpp index f788c91..d155725 100644 --- a/src/Lua/LuaMain.cpp +++ b/src/Lua/LuaMain.cpp @@ -8,6 +8,11 @@ #include "Logger.h" #include +#ifdef __linux +// we need this for `struct stat` +#include +#endif // __linux + std::set PluginEngine; bool NewFile(const std::string&Path){ for(Lua*Script : PluginEngine){ diff --git a/src/Lua/LuaSystem.cpp b/src/Lua/LuaSystem.cpp index 1d7e44c..bae4c78 100644 --- a/src/Lua/LuaSystem.cpp +++ b/src/Lua/LuaSystem.cpp @@ -8,6 +8,7 @@ #include "Settings.h" #include "Network.h" #include "Logger.h" +#include "UnixCompat.h" #include #include #include @@ -134,7 +135,7 @@ char* ThreadOrigin(Lua*lua){ std::string T = "Thread in " + lua->GetFileName().substr(lua->GetFileName().find('\\')); char* Data = new char[T.size()+1]; ZeroMemory(Data,T.size()+1); - memcpy_s(Data,T.size(),T.c_str(),T.size()); + memcpy(Data, T.c_str(),T.size()); return Data; } void SafeExecution(Lua* lua,const std::string& FuncName){ @@ -142,10 +143,15 @@ void SafeExecution(Lua* lua,const std::string& FuncName){ lua_getglobal(luaState, FuncName.c_str()); if(lua_isfunction(luaState, -1)) { char* Origin = ThreadOrigin(lua); +#ifdef __WIN32 __try{ int R = lua_pcall(luaState, 0, 0, 0); CheckLua(luaState, R); }__except(Handle(GetExceptionInformation(),Origin)){} +#else // unix + int R = lua_pcall(luaState, 0, 0, 0); + CheckLua(luaState, R); +#endif // __WIN32 delete [] Origin; } ClearStack(luaState); @@ -492,7 +498,7 @@ char* Lua::GetOrigin(){ std::string T = GetFileName().substr(GetFileName().find('\\')); char* Data = new char[T.size()]; ZeroMemory(Data,T.size()); - memcpy_s(Data,T.size(),T.c_str(),T.size()); + memcpy(Data,T.c_str(),T.size()); return Data; } int CallFunction(Lua*lua,const std::string& FuncName,LuaArg* Arg){ @@ -508,14 +514,18 @@ int CallFunction(Lua*lua,const std::string& FuncName,LuaArg* Arg){ } int R = 0; char* Origin = lua->GetOrigin(); +#ifdef __WIN32 __try{ +#endif // __WIN32 R = lua_pcall(luaState, Size, 1, 0); if (CheckLua(luaState, R)){ if (lua_isnumber(luaState, -1)) { return int(lua_tointeger(luaState, -1)); } } +#ifdef __WIN32 }__except(Handle(GetExceptionInformation(),Origin)){} +#endif // __WIN32 delete [] Origin; } ClearStack(luaState); diff --git a/src/Network/Auth.cpp b/src/Network/Auth.cpp index ed3f7bc..4bc7ddb 100644 --- a/src/Network/Auth.cpp +++ b/src/Network/Auth.cpp @@ -8,6 +8,10 @@ #include "Logger.h" #include #include +#include +#include "UnixCompat.h" + + struct Hold{ SOCKET TCPSock{}; bool Done = false; @@ -148,17 +152,31 @@ void Identification(SOCKET TCPSock,Hold*S,RSA*Skey){ void Identify(SOCKET TCPSock){ auto* S = new Hold; RSA*Skey = GenKey(); + // this disgusting ifdef stuff is needed because for some + // reason MSVC defines __try and __except and libg++ defines + // __try and __catch so its all a big mess if we leave this in or undefine + // the macros +#ifdef __WIN32 __try{ +#endif // __WIN32 Identification(TCPSock,S,Skey); +#ifdef __WIN32 }__except(1){ +#endif // __WIN32 + if(TCPSock != -1){ closesocket(TCPSock); } +#ifdef __WIN32 } +#endif // __WIN32 + delete Skey; delete S; } + void TCPServerMain(){ +#ifdef __WIN32 WSADATA wsaData; if (WSAStartup(514, &wsaData)){ error(Sec("Can't start Winsock!")); @@ -195,4 +213,38 @@ void TCPServerMain(){ closesocket(client); WSACleanup(); -} \ No newline at end of file +#else // unix + // wondering why we need slightly different implementations of this? + // ask ms. + SOCKET client, Listener = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); + sockaddr_in addr{}; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_family = AF_INET; + addr.sin_port = htons(Port); + if (bind(Listener, (sockaddr*)&addr, sizeof(addr)) != 0){ + error(Sec("Can't bind socket! ") + std::string(strerror(errno))); + std::this_thread::sleep_for(std::chrono::seconds(5)); + exit(-1); + } + if(Listener == -1){ + error(Sec("Invalid listening socket")); + return; + } + if(listen(Listener,SOMAXCONN)){ + error(Sec("listener failed ")+ std::string(strerror(errno))); + return; + } + info(Sec("Vehicle event network online")); + do{ + client = accept(Listener, nullptr, nullptr); + if(client == -1){ + warn(Sec("Got an invalid client socket on connect! Skipping...")); + continue; + } + std::thread ID(Identify,client); + ID.detach(); + }while(client); + + closesocket(client); +#endif // __WIN32 +} diff --git a/src/Network/GParser.cpp b/src/Network/GParser.cpp index 60f40ad..a22f483 100644 --- a/src/Network/GParser.cpp +++ b/src/Network/GParser.cpp @@ -7,8 +7,10 @@ #include "Settings.h" #include "Network.h" #include "Logger.h" +#include "UnixCompat.h" #include + int FC(const std::string& s,const std::string& p,int n) { auto i = s.find(p); int j; @@ -116,10 +118,14 @@ void SyncClient(Client*c){ } info(c->GetName() + Sec(" is now synced!")); } -void ParseVeh(Client*c, const std::string&Packet){ +void ParseVeh(Client*c, const std::string& Packet){ +#ifdef __WIN32 __try{ VehicleParser(c,Packet); }__except(Handle(GetExceptionInformation(),Sec("Vehicle Handler"))){} +#else // unix + VehicleParser(c,Packet); +#endif // __WIN32 } void HandleEvent(Client*c ,const std::string&Data){ @@ -189,8 +195,12 @@ void GlobalParser(Client*c, const std::string& Pack){ } } -void GParser(Client*c, const std::string&Packet){ +void GParser(Client*c, const std::string& Packet){ +#ifdef __WIN32 __try{ GlobalParser(c, Packet); }__except(Handle(GetExceptionInformation(),Sec("Global Handler"))){} -} \ No newline at end of file +#else + GlobalParser(c, Packet); +#endif // __WIN32 +} diff --git a/src/Network/Sync.cpp b/src/Network/Sync.cpp index 0431d78..137a6cd 100644 --- a/src/Network/Sync.cpp +++ b/src/Network/Sync.cpp @@ -5,8 +5,14 @@ #include "Client.hpp" #include "Settings.h" #include "Logger.h" +#include "UnixCompat.h" #include +#ifdef __linux +// we need this for `struct stat` +#include +#endif // __linux + void STCPSend(Client*c,std::string Data){ if(c == nullptr)return; int BytesSent; @@ -100,4 +106,4 @@ void SyncResources(Client*c){ except(Sec("Exception! : ") + std::string(e.what())); c->SetStatus(-1); } -} \ No newline at end of file +} diff --git a/src/Network/TCPHandler.cpp b/src/Network/TCPHandler.cpp index 630c180..fcc8f3a 100644 --- a/src/Network/TCPHandler.cpp +++ b/src/Network/TCPHandler.cpp @@ -4,6 +4,7 @@ #include "Security/Enc.h" #include "Network.h" #include "Logger.h" +#include "UnixCompat.h" #include void TCPSend(Client*c,const std::string&Data){ @@ -18,11 +19,15 @@ void TCPSend(Client*c,const std::string&Data){ } } void TCPHandle(Client*c,const std::string& data){ +#ifdef __WIN32 __try{ +#endif // __WIN32 c->Handler.Handle(c,data); +#ifdef __WIN32 }__except(1){ c->Handler.clear(); } +#endif // __WIN32 } void TCPRcv(Client*c){ if(c == nullptr || c->GetStatus() < 0)return; @@ -35,7 +40,11 @@ void TCPRcv(Client*c){ if(c->GetStatus() > -1)c->SetStatus(-1); return; }else if (BytesRcv < 0) { +#ifdef __WIN32 debug(Sec("(TCP) recv failed with error: ") + std::to_string(WSAGetLastError())); +#else // unix + debug(Sec("(TCP) recv failed with error: ") + std::string(strerror(errno))); +#endif // __WIN32 if(c->GetStatus() > -1)c->SetStatus(-1); closesocket(c->GetTCPSock()); return; @@ -50,11 +59,15 @@ void TCPClient(Client*c){ } OnConnect(c); while (c->GetStatus() > -1)TCPRcv(c); +#ifdef __WIN32 __try{ +#endif // __WIN32 OnDisconnect(c, c->GetStatus() == -2); +#ifdef __WIN32 }__except(Handle(GetExceptionInformation(),Sec("OnDisconnect"))){} +#endif // __WIN32 } void InitClient(Client*c){ std::thread NewClient(TCPClient,c); NewClient.detach(); -} \ No newline at end of file +} diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index 4680642..64a8743 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -8,14 +8,17 @@ #include "Settings.h" #include "Network.h" #include "Logger.h" +#include "UnixCompat.h" #include #include #include #include +#include +#include int FC(const std::string& s,const std::string& p,int n); struct PacketData{ int ID; - Client* Client; + ::Client* Client; std::string Data; int Tries; }; @@ -38,10 +41,17 @@ void UDPSend(Client*c,std::string Data){ Data = "ABG:" + CMP; } int sendOk = sendto(UDPSock, Data.c_str(), int(Data.size()), 0, (sockaddr *) &Addr, AddrSize); - if (sendOk == SOCKET_ERROR) { +#ifdef __WIN32 + if (sendOk != 0) { debug(Sec("(UDP) Send Failed Code : ") + std::to_string(WSAGetLastError())); if(c->GetStatus() > -1)c->SetStatus(-1); } +#else // unix + if (sendOk != 0) { + debug(Sec("(UDP) Send Failed Code : ") + std::string(strerror(errno))); + if(c->GetStatus() > -1)c->SetStatus(-1); + } +#endif // __WIN32 } void AckID(int ID){ @@ -144,9 +154,13 @@ std::string UDPRcvFromClient(sockaddr_in& client){ int clientLength = sizeof(client); ZeroMemory(&client, clientLength); std::string Ret(10240,0); - int Rcv = recvfrom(UDPSock, &Ret[0], 10240, 0, (sockaddr*)&client, &clientLength); + int Rcv = recvfrom(UDPSock, &Ret[0], 10240, 0, (sockaddr*)&client, (socklen_t*)&clientLength); if (Rcv == -1){ +#ifdef __WIN32 error(Sec("(UDP) Error receiving from Client! Code : ") + std::to_string(WSAGetLastError())); +#else // unix + error(Sec("(UDP) Error receiving from Client! Code : ") + std::string(strerror(errno))); +#endif // __WIN32 return ""; } return Ret; @@ -240,6 +254,7 @@ void LOOP(){ } } [[noreturn]] void UDPServerMain(){ +#ifdef __WIN32 WSADATA data; if (WSAStartup(514, &data)){ error(Sec("Can't start Winsock!")); @@ -286,4 +301,46 @@ void LOOP(){ /*closesocket(UDPSock); WSACleanup(); return;*/ -} \ No newline at end of file +#else // unix + UDPSock = socket(AF_INET, SOCK_DGRAM, 0); + // Create a server hint structure for the server + sockaddr_in serverAddr{}; + serverAddr.sin_addr.s_addr = INADDR_ANY; //Any Local + serverAddr.sin_family = AF_INET; // Address format is IPv4 + serverAddr.sin_port = htons(Port); // Convert from little to big endian + + // Try and bind the socket to the IP and port + if (bind(UDPSock, (sockaddr*)&serverAddr, sizeof(serverAddr)) != 0){ + error(Sec("Can't bind socket!") + std::string(strerror(errno))); + std::this_thread::sleep_for(std::chrono::seconds(5)); + exit(-1); + //return; + } + + DataAcks.clear(); + std::thread Ack(LOOP); + Ack.detach(); + + info(Sec("Vehicle data network online on port ")+std::to_string(Port)+Sec(" with a Max of ")+std::to_string(MaxPlayers)+Sec(" Clients")); + while (true){ + sockaddr_in client{}; + std::string Data = UDPRcvFromClient(client); //Receives any data from Socket + auto Pos = Data.find(':'); + if(Data.empty() || Pos < 0 || Pos > 2)continue; + /*char clientIp[256]; + ZeroMemory(clientIp, 256); ///Code to get IP we don't need that yet + inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);*/ + uint8_t ID = Data.at(0)-1; + for(Client*c : CI->Clients){ + if(c != nullptr && c->GetID() == ID){ + c->SetUDPAddr(client); + c->isConnected = true; + UDPParser(c,Data.substr(2)); + } + } + } + /*closesocket(UDPSock); // TODO: Why not this? We did this in TCPServerMain? + return; + */ +#endif // __WIN32 +} diff --git a/src/logger.cpp b/src/logger.cpp index 222e038..72020df 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -19,7 +19,11 @@ std::string getDate() { auto s = std::chrono::duration_cast(tp);tp -= s; time_t tt = std::chrono::system_clock::to_time_t(now); tm local_tm{}; +#ifdef __WIN32 localtime_s(&local_tm,&tt); +#else // unix + localtime_r(&tt, &local_tm); +#endif // __WIN32 std::stringstream date; int S = local_tm.tm_sec; int M = local_tm.tm_min; From 953131289dbc1da141012f69fa60907a8709eaa8 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Sun, 1 Nov 2020 12:19:19 +0100 Subject: [PATCH 02/30] Fix compiler warnings, explicitly cast by default --- include/Buffer.h | 4 ++-- include/Lua/LuaSystem.hpp | 9 ++++----- src/Compressor.cpp | 4 ++-- src/Enc.cpp | 7 ++++++- src/Init/Config.cpp | 8 ++++---- src/Lua/LuaSystem.cpp | 2 +- src/Network/Auth.cpp | 12 ++++++------ src/Network/GParser.cpp | 4 ++-- src/Network/Sync.cpp | 27 ++++++++++++++------------- src/Network/TCPHandler.cpp | 8 ++++---- src/Network/VehicleData.cpp | 30 +++++++++++++++--------------- 11 files changed, 60 insertions(+), 55 deletions(-) diff --git a/include/Buffer.h b/include/Buffer.h index ac1a1c8..d9587e0 100644 --- a/include/Buffer.h +++ b/include/Buffer.h @@ -22,7 +22,7 @@ private: std::string::size_type p; if (Buf.at(0) == '\n'){ p = Buf.find('\n',1); - if(p != -1){ + if(p != std::string::npos){ std::string R = Buf.substr(1,p-1); std::string_view B(R.c_str(),R.find(char(0))); GParser(c, B.data()); @@ -31,7 +31,7 @@ private: } }else{ p = Buf.find('\n'); - if(p == -1)Buf.clear(); + if(p == std::string::npos)Buf.clear(); else{ Buf = Buf.substr(p); Manage(c); diff --git a/include/Lua/LuaSystem.hpp b/include/Lua/LuaSystem.hpp index 1bf5a43..22e7e75 100644 --- a/include/Lua/LuaSystem.hpp +++ b/include/Lua/LuaSystem.hpp @@ -20,17 +20,16 @@ struct LuaArg{ for(std::any arg : args){ if(!arg.has_value())return; std::string Type = arg.type().name(); - if(Type.find("bool") != -1){ + if(Type.find("bool") != std::string::npos){ lua_pushboolean(State,std::any_cast(arg)); } - if(Type.find("basic_string") != -1 || Type.find("char") != -1){ + if(Type.find("basic_string") != std::string::npos || Type.find("char") != std::string::npos){ lua_pushstring(State,std::any_cast(arg).c_str()); } - if(Type.find("int") != -1){ + if(Type.find("int") != std::string::npos){ lua_pushinteger(State,std::any_cast(arg)); } - if(Type.find("float") != -1){ - lua_pushnumber(State,std::any_cast(arg)); + if(Type.find("float") != std::string::npos){ lua_pushnumber(State,std::any_cast(arg)); } } } diff --git a/src/Compressor.cpp b/src/Compressor.cpp index 65e7630..e47f93e 100644 --- a/src/Compressor.cpp +++ b/src/Compressor.cpp @@ -24,7 +24,7 @@ std::string Comp(std::string Data){ deflate(&defstream, Z_SYNC_FLUSH); deflate(&defstream, Z_FINISH); deflateEnd(&defstream); - int TO = defstream.total_out; + size_t TO = defstream.total_out; std::string Ret(TO,0); std::copy_n(C.begin(), TO, Ret.begin()); return Ret; @@ -45,7 +45,7 @@ std::string DeComp(std::string Compressed){ inflate(&infstream, Z_SYNC_FLUSH); inflate(&infstream, Z_FINISH); inflateEnd(&infstream); - int TO = infstream.total_out; + size_t TO = infstream.total_out; std::string Ret(TO,0); std::copy_n(C.begin(), TO, Ret.begin()); return Ret; diff --git a/src/Enc.cpp b/src/Enc.cpp index 4c7d12f..6522a90 100644 --- a/src/Enc.cpp +++ b/src/Enc.cpp @@ -85,15 +85,20 @@ int Dec(int value,int d,int n){ return log_power(value, d, n); } +#ifdef __WIN32 int Handle(EXCEPTION_POINTERS *ep,char* Origin){ assert(false); std::stringstream R; R << Sec("Code : ") << std::hex - //<< ep->ExceptionRecord->ExceptionCode + << ep->ExceptionRecord->ExceptionCode << std::dec << Sec(" Origin : ") << Origin; except(R.str()); return 1; } +#else +// stub +int Handle(EXCEPTION_POINTERS *, char*) { return 1; } +#endif // __WIN32 std::string RSA_E(const std::string& Data, RSA*k){ std::stringstream stream; diff --git a/src/Init/Config.cpp b/src/Init/Config.cpp index 9789121..e24a744 100644 --- a/src/Init/Config.cpp +++ b/src/Init/Config.cpp @@ -33,13 +33,13 @@ void SetValues(const std::string& Line, int Index) { } Data = Data.substr(1); std::string::size_type sz; - bool Boolean = std::string(Data).find("true") != -1;//searches for "true" + bool FoundTrue = std::string(Data).find("true") != std::string::npos;//searches for "true" switch (Index) { case 1 : - Debug = Boolean;//checks and sets the Debug Value + Debug = FoundTrue;//checks and sets the Debug Value break; case 2 : - Private = Boolean;//checks and sets the Private Value + Private = FoundTrue;//checks and sets the Private Value break; case 3 : Port = std::stoi(Data, &sz);//sets the Port @@ -146,4 +146,4 @@ void InitConfig(){ exit(0); } if(Debug)DebugData(); -} \ No newline at end of file +} diff --git a/src/Lua/LuaSystem.cpp b/src/Lua/LuaSystem.cpp index bae4c78..47b2f9f 100644 --- a/src/Lua/LuaSystem.cpp +++ b/src/Lua/LuaSystem.cpp @@ -375,7 +375,7 @@ int lua_RemoteEvent(lua_State *L){ } return 0; } -int lua_ServerExit(lua_State *L){ +int lua_ServerExit(lua_State *){ exit(0); } int lua_Set(lua_State *L){ diff --git a/src/Network/Auth.cpp b/src/Network/Auth.cpp index 4bc7ddb..2da1f9f 100644 --- a/src/Network/Auth.cpp +++ b/src/Network/Auth.cpp @@ -17,17 +17,17 @@ struct Hold{ bool Done = false; }; bool Send(SOCKET TCPSock,std::string Data){ - int BytesSent; - BytesSent = send(TCPSock, Data.c_str(), int(Data.size()), 0); + ssize_t BytesSent; + BytesSent = send(TCPSock, Data.c_str(), size_t(Data.size()), 0); Data.clear(); if (BytesSent <= 0)return false; return true; } std::string Rcv(SOCKET TCPSock){ char buf[6768]; - int len = 6768; + size_t len = 6768; ZeroMemory(buf, len); - int BytesRcv = recv(TCPSock, buf, len,0); + ssize_t BytesRcv = recv(TCPSock, buf, len,0); if (BytesRcv <= 0)return ""; return std::string(buf); } @@ -131,7 +131,7 @@ void Identification(SOCKET TCPSock,Hold*S,RSA*Skey){ Name = Res.substr(2,Res.find(':')-2); DID = Res.substr(Res.find(':')+1); Role = GetRole(DID); - if(Role.empty() || Role.find(Sec("Error")) != -1){ + if(Role.empty() || Role.find(Sec("Error")) != std::string::npos){ closesocket(TCPSock); return; } @@ -220,7 +220,7 @@ void TCPServerMain(){ sockaddr_in addr{}; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_family = AF_INET; - addr.sin_port = htons(Port); + addr.sin_port = htons(uint16_t(Port)); if (bind(Listener, (sockaddr*)&addr, sizeof(addr)) != 0){ error(Sec("Can't bind socket! ") + std::string(strerror(errno))); std::this_thread::sleep_for(std::chrono::seconds(5)); diff --git a/src/Network/GParser.cpp b/src/Network/GParser.cpp index a22f483..5d5e8e8 100644 --- a/src/Network/GParser.cpp +++ b/src/Network/GParser.cpp @@ -149,7 +149,7 @@ void HandleEvent(Client*c ,const std::string&Data){ } void GlobalParser(Client*c, const std::string& Pack){ - static int lastRecv = 0; + [[maybe_unused]] static int lastRecv = 0; if(Pack.empty() || c == nullptr)return; std::string Packet = Pack.substr(0,Pack.find(char(0))); std::string pct; @@ -181,7 +181,7 @@ void GlobalParser(Client*c, const std::string& Pack){ SendToAll(c,Packet,false,true); return; case 'C': - if(Packet.length() < 4 || Packet.find(':', 3) == -1)break; + if(Packet.length() < 4 || Packet.find(':', 3) == std::string::npos)break; if (TriggerLuaEvent(Sec("onChatMessage"), false, nullptr,new LuaArg{ {c->GetID(), c->GetName(), Packet.substr(Packet.find(':', 3) + 1)} },true))break; diff --git a/src/Network/Sync.cpp b/src/Network/Sync.cpp index 137a6cd..0ec589c 100644 --- a/src/Network/Sync.cpp +++ b/src/Network/Sync.cpp @@ -15,8 +15,7 @@ void STCPSend(Client*c,std::string Data){ if(c == nullptr)return; - int BytesSent; - BytesSent = send(c->GetTCPSock(), Data.c_str(), int(Data.size()), 0); + ssize_t BytesSent = send(c->GetTCPSock(), Data.c_str(), size_t(Data.size()), 0); Data.clear(); if (BytesSent == 0){ if(c->GetStatus() > -1)c->SetStatus(-1); @@ -35,20 +34,22 @@ void SendFile(Client*c,const std::string&Name){ std::ifstream f(Name.c_str(), std::ios::binary); f.seekg(0, std::ios_base::end); std::streampos fileSize = f.tellg(); - size_t Size = fileSize,Sent = 0,Diff; - int Split = 64000; + size_t Size = size_t(fileSize); + size_t Sent = 0; + size_t Diff; + ssize_t Split = 64000; while(c->GetStatus() > -1 && Sent < Size){ Diff = Size - Sent; - if(Diff > Split){ - std::string Data(Split,0); - f.seekg(Sent, std::ios_base::beg); + if(Diff > size_t(Split)){ + std::string Data(size_t(Split),0); + f.seekg(ssize_t(Sent), std::ios_base::beg); f.read(&Data[0], Split); STCPSend(c,Data); - Sent += Split; + Sent += size_t(Split); }else{ std::string Data(Diff,0); - f.seekg(Sent, std::ios_base::beg); - f.read(&Data[0], Diff); + f.seekg(ssize_t(Sent), std::ios_base::beg); + f.read(&Data[0], ssize_t(Diff)); STCPSend(c,Data); Sent += Diff; } @@ -79,9 +80,9 @@ void Parse(Client*c,const std::string&Packet){ bool STCPRecv(Client*c){ if(c == nullptr)return false; char buf[200]; - int len = 200; + size_t len = 200; ZeroMemory(buf, len); - int BytesRcv = recv(c->GetTCPSock(), buf, len,0); + ssize_t BytesRcv = recv(c->GetTCPSock(), buf, len,0); if (BytesRcv == 0){ if(c->GetStatus() > -1)c->SetStatus(-1); closesocket(c->GetTCPSock()); @@ -92,7 +93,7 @@ bool STCPRecv(Client*c){ return false; } if(strcmp(buf,"Done") == 0)return false; - std::string Ret(buf,BytesRcv); + std::string Ret(buf, size_t(BytesRcv)); Parse(c,Ret); return true; } diff --git a/src/Network/TCPHandler.cpp b/src/Network/TCPHandler.cpp index fcc8f3a..1765fba 100644 --- a/src/Network/TCPHandler.cpp +++ b/src/Network/TCPHandler.cpp @@ -10,7 +10,7 @@ void TCPSend(Client*c,const std::string&Data){ if(c == nullptr)return; std::string Send = "\n" + Data.substr(0,Data.find(char(0))) + "\n"; - size_t Sent = send(c->GetTCPSock(), Send.c_str(), int(Send.size()), 0); + ssize_t Sent = send(c->GetTCPSock(), Send.c_str(), size_t(Send.size()), 0); if (Sent == 0){ if(c->GetStatus() > -1)c->SetStatus(-1); }else if (Sent < 0) { @@ -32,9 +32,9 @@ void TCPHandle(Client*c,const std::string& data){ void TCPRcv(Client*c){ if(c == nullptr || c->GetStatus() < 0)return; char buf[4096]; - int len = 4096; + size_t len = 4096; ZeroMemory(buf, len); - int BytesRcv = recv(c->GetTCPSock(), buf, len,0); + ssize_t BytesRcv = recv(c->GetTCPSock(), buf, len,0); if (BytesRcv == 0){ debug(Sec("(TCP) Connection closing...")); if(c->GetStatus() > -1)c->SetStatus(-1); @@ -49,7 +49,7 @@ void TCPRcv(Client*c){ closesocket(c->GetTCPSock()); return; } - std::string Buf(buf,BytesRcv); + std::string Buf(buf,(size_t(BytesRcv))); TCPHandle(c,Buf); } void TCPClient(Client*c){ diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index 64a8743..13d60db 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -34,13 +34,13 @@ std::set SplitPackets; void UDPSend(Client*c,std::string Data){ if(c == nullptr || !c->isConnected || c->GetStatus() < 0)return; sockaddr_in Addr = c->GetUDPAddr(); - int AddrSize = sizeof(c->GetUDPAddr()); + socklen_t AddrSize = sizeof(c->GetUDPAddr()); Data = Data.substr(0,Data.find(char(0))); if(Data.length() > 400){ std::string CMP(Comp(Data)); Data = "ABG:" + CMP; } - int sendOk = sendto(UDPSock, Data.c_str(), int(Data.size()), 0, (sockaddr *) &Addr, AddrSize); + ssize_t sendOk = sendto(UDPSock, Data.c_str(), Data.size(), 0, (sockaddr *) &Addr, AddrSize); #ifdef __WIN32 if (sendOk != 0) { debug(Sec("(UDP) Send Failed Code : ") + std::to_string(WSAGetLastError())); @@ -102,13 +102,13 @@ void SendLarge(Client*c,std::string Data){ } } struct HandledC{ - int Pos = 0; + size_t Pos = 0; Client *c = nullptr; std::array HandledIDs = {-1}; }; std::set HandledIDs; void ResetIDs(HandledC*H){ - for(int C = 0;C < 100;C++){ + for(size_t C = 0;C < 100;C++){ H->HandledIDs.at(C) = -1; } } @@ -151,10 +151,10 @@ bool Handled(Client*c,int ID){ return false; } std::string UDPRcvFromClient(sockaddr_in& client){ - int clientLength = sizeof(client); + size_t clientLength = sizeof(client); ZeroMemory(&client, clientLength); std::string Ret(10240,0); - int Rcv = recvfrom(UDPSock, &Ret[0], 10240, 0, (sockaddr*)&client, (socklen_t*)&clientLength); + ssize_t Rcv = recvfrom(UDPSock, &Ret[0], 10240, 0, (sockaddr*)&client, (socklen_t*)&clientLength); if (Rcv == -1){ #ifdef __WIN32 error(Sec("(UDP) Error receiving from Client! Code : ") + std::to_string(WSAGetLastError())); @@ -177,13 +177,13 @@ SplitData*GetSplit(int SplitID){ void HandleChunk(Client*c,const std::string&Data){ int pos = FC(Data,"|",5); if(pos == -1)return; - std::stringstream ss(Data.substr(0,pos++)); + std::stringstream ss(Data.substr(0,size_t(pos++))); std::string t; int I = -1; //Current Max ID SID std::vector Num(4,0); while (std::getline(ss, t, '|')) { - if(I != -1)Num.at(I) = std::stoi(t); + if(I >= 0)Num.at(size_t(I)) = std::stoi(t); I++; } std::string ack = "TRG:" + std::to_string(Num.at(2)); @@ -191,12 +191,12 @@ void HandleChunk(Client*c,const std::string&Data){ if(Handled(c,Num.at(2))){ return; } - std::string Packet = Data.substr(pos); + std::string Packet = Data.substr(size_t(pos)); SplitData* SData = GetSplit(Num.at(3)); SData->Total = Num.at(1); SData->ID = Num.at(3); SData->Fragments.insert(std::make_pair(Num.at(0),Packet)); - if(SData->Fragments.size() == SData->Total){ + if(SData->Fragments.size() == size_t(SData->Total)) { std::string ToHandle; for(const std::pair& a : SData->Fragments){ ToHandle += a.second; @@ -213,7 +213,7 @@ void UDPParser(Client*c,std::string Packet){ } if(Packet.substr(0,4) == "TRG:"){ std::string pkt = Packet.substr(4); - if(Packet.find_first_not_of("0123456789") == -1){ + if(Packet.find_first_not_of("0123456789") == std::string::npos){ AckID(stoi(Packet)); } return; @@ -307,7 +307,7 @@ void LOOP(){ sockaddr_in serverAddr{}; serverAddr.sin_addr.s_addr = INADDR_ANY; //Any Local serverAddr.sin_family = AF_INET; // Address format is IPv4 - serverAddr.sin_port = htons(Port); // Convert from little to big endian + serverAddr.sin_port = htons(uint16_t(Port)); // Convert from little to big endian // Try and bind the socket to the IP and port if (bind(UDPSock, (sockaddr*)&serverAddr, sizeof(serverAddr)) != 0){ @@ -325,12 +325,12 @@ void LOOP(){ while (true){ sockaddr_in client{}; std::string Data = UDPRcvFromClient(client); //Receives any data from Socket - auto Pos = Data.find(':'); - if(Data.empty() || Pos < 0 || Pos > 2)continue; + size_t Pos = Data.find(':'); + if(Data.empty() || Pos > 2)continue; /*char clientIp[256]; ZeroMemory(clientIp, 256); ///Code to get IP we don't need that yet inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);*/ - uint8_t ID = Data.at(0)-1; + uint8_t ID = uint8_t(Data.at(0)) - 1; for(Client*c : CI->Clients){ if(c != nullptr && c->GetID() == ID){ c->SetUDPAddr(client); From 4d259c9d25a85a16d652b70f2648ebdfc1fa87a5 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Sun, 1 Nov 2020 12:46:16 +0100 Subject: [PATCH 03/30] add cmake lists for debian --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a436374..35fecfe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,10 @@ cmake_minimum_required(VERSION 3.10) project(Server) set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -fmax-errors=1 -Wconversion") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") file(GLOB source_files "src/*.cpp" "src/*/*.cpp" "include/*.h" "include/*/*.h" "include/*.hpp" "include/*/*.hpp") add_executable(${PROJECT_NAME} ${source_files}) target_include_directories(${PROJECT_NAME} PUBLIC $) set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "BeamMP-Server") -target_link_libraries(${PROJECT_NAME} libcurl_a urlmon ws2_32 lua53 zlibstatic) \ No newline at end of file +target_link_libraries(${PROJECT_NAME} curl lua5.3 z pthread) From 13e79e407ceacf2b763e2e041e3ec31c7ef70a41 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 1 Nov 2020 06:48:31 -0500 Subject: [PATCH 04/30] add support for std::filesystem on older compilers --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 35fecfe..858b422 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,4 +7,4 @@ file(GLOB source_files "src/*.cpp" "src/*/*.cpp" "include/*.h" "include/*/*.h" " add_executable(${PROJECT_NAME} ${source_files}) target_include_directories(${PROJECT_NAME} PUBLIC $) set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "BeamMP-Server") -target_link_libraries(${PROJECT_NAME} curl lua5.3 z pthread) +target_link_libraries(${PROJECT_NAME} curl lua5.3 z pthread stdc++fs) From eead954bf94c591b61d89d368a001628f810a921 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Tue, 3 Nov 2020 09:00:42 +0100 Subject: [PATCH 05/30] Fix Console on Unix, adapt console behavior to that of a traditional console, add Assert.h, add clang-format file with modified WebKit style --- .clang-format | 5 + include/Assert.h | 59 +++++++++ include/Buffer.h | 4 +- src/Console.cpp | 47 ++++++- src/Network/GParser.cpp | 2 +- src/Network/Sync.cpp | 116 +++++++++-------- src/Network/VehicleData.cpp | 251 +++++++++++++++++++----------------- 7 files changed, 306 insertions(+), 178 deletions(-) create mode 100644 .clang-format create mode 100644 include/Assert.h diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..ee5a01f --- /dev/null +++ b/.clang-format @@ -0,0 +1,5 @@ +--- +BasedOnStyle: WebKit +BreakBeforeBraces: Attach + +... diff --git a/include/Assert.h b/include/Assert.h new file mode 100644 index 0000000..f3bcc55 --- /dev/null +++ b/include/Assert.h @@ -0,0 +1,59 @@ +// Author: lionkor + +#pragma once + +#include +#include + +#include "Logger.h" + +static const char* const ANSI_RESET = "\u001b[0m"; + +static const char* const ANSI_BLACK = "\u001b[30m"; +static const char* const ANSI_RED = "\u001b[31m"; +static const char* const ANSI_GREEN = "\u001b[32m"; +static const char* const ANSI_YELLOW = "\u001b[33m"; +static const char* const ANSI_BLUE = "\u001b[34m"; +static const char* const ANSI_MAGENTA = "\u001b[35m"; +static const char* const ANSI_CYAN = "\u001b[36m"; +static const char* const ANSI_WHITE = "\u001b[37m"; + +static const char* const ANSI_BLACK_BOLD = "\u001b[30;1m"; +static const char* const ANSI_RED_BOLD = "\u001b[31;1m"; +static const char* const ANSI_GREEN_BOLD = "\u001b[32;1m"; +static const char* const ANSI_YELLOW_BOLD = "\u001b[33;1m"; +static const char* const ANSI_BLUE_BOLD = "\u001b[34;1m"; +static const char* const ANSI_MAGENTA_BOLD = "\u001b[35;1m"; +static const char* const ANSI_CYAN_BOLD = "\u001b[36;1m"; +static const char* const ANSI_WHITE_BOLD = "\u001b[37;1m"; + +static const char* const ANSI_BOLD = "\u001b[1m"; +static const char* const ANSI_UNDERLINE = "\u001b[4m"; + +inline void _assert(const char* file, const char* function, unsigned line, + const char* condition_string, bool result) { + if (!result) { +#if DEBUG + fprintf(stderr, + "%sASSERTION FAILED%s at %s%s:%u%s \n\t-> in %s%s%s, Line %u: \n\t\t-> " + "Failed Condition: %s%s%s\n", + ANSI_RED_BOLD, ANSI_RESET, ANSI_UNDERLINE, file, line, ANSI_RESET, + ANSI_BOLD, function, ANSI_RESET, line, ANSI_RED, condition_string, + ANSI_RESET); + fprintf(stderr, "%s... terminating with SIGABRT ...%s\n", ANSI_BOLD, ANSI_RESET); + abort(); +#else + char buf[2048]; + sprintf(buf, + "%s=> ASSERTION `%s` FAILED IN RELEASE BUILD%s%s -> IGNORING FAILED ASSERTION " + "& HOPING IT WON'T CRASH%s\n", + ANSI_RED_BOLD, condition_string, ANSI_RESET, ANSI_RED, ANSI_RESET); + error(buf); +#endif + } +} + +#ifndef ASSERT +#define Assert(cond) _assert(__FILE__, __func__, __LINE__, #cond, (cond)) +#endif // ASSERT +#define AssertNotReachable() _assert(__FILE__, __func__, __LINE__, "reached unreachable code", false) diff --git a/include/Buffer.h b/include/Buffer.h index d9587e0..83d5205 100644 --- a/include/Buffer.h +++ b/include/Buffer.h @@ -3,12 +3,13 @@ /// #pragma once #include +#include "Assert.h" class Client; void GParser(Client*c, const std::string&Packet); class Buffer{ public: void Handle(Client*c,const std::string& Data){ - if(c == nullptr)return; + Assert(c); Buf += Data; Manage(c); } @@ -18,6 +19,7 @@ public: private: std::string Buf; void Manage(Client*c){ + Assert(c); if(!Buf.empty()){ std::string::size_type p; if (Buf.at(0) == '\n'){ diff --git a/src/Console.cpp b/src/Console.cpp index b78ba6c..54c2cc5 100644 --- a/src/Console.cpp +++ b/src/Console.cpp @@ -8,6 +8,8 @@ #include #else // *nix typedef unsigned long DWORD, *PDWORD, *LPDWORD; +#include +#include #endif // __WIN32 #include "Logger.h" #include @@ -20,6 +22,7 @@ std::string CInputBuff; std::mutex MLock; Lua* LuaConsole; void HandleInput(const std::string& cmd){ + std::cout << std::endl; if (cmd == "exit") { exit(0); }else LuaConsole->Execute(cmd); @@ -28,13 +31,12 @@ void HandleInput(const std::string& cmd){ void ProcessOut(){ static size_t len = 2; if(QConsoleOut.empty() && len == CInputBuff.length())return; - printf("%c[2K\r", 27); for(const std::string& msg : QConsoleOut) if(!msg.empty())std::cout << msg; MLock.lock(); QConsoleOut.clear(); MLock.unlock(); - std::cout << "> " << CInputBuff; + std::cout << "> " << CInputBuff << std::flush; len = CInputBuff.length(); } @@ -50,6 +52,32 @@ void ConsoleOut(const std::string& msg){ ProcessOut(); } } + +#ifndef __WIN32 +static int _getch() +{ + char buf = 0; + struct termios old; + fflush(stdout); + if(tcgetattr(0, &old) < 0) + perror("tcsetattr()"); + old.c_lflag &= ~unsigned(ICANON); + old.c_lflag &= ~unsigned(ECHO); + old.c_cc[VMIN] = 1; + old.c_cc[VTIME] = 0; + if(tcsetattr(0, TCSANOW, &old) < 0) + perror("tcsetattr ICANON"); + if(read(0, &buf, 1) < 0) + perror("read()"); + old.c_lflag |= ICANON; + old.c_lflag |= ECHO; + if(tcsetattr(0, TCSADRAIN, &old) < 0) + perror("tcsetattr ~ICANON"); + // no echo printf("%c\n", buf); + return buf; +} +#endif // __WIN32 + void SetupConsole(){ #ifdef __WIN32 DWORD outMode = 0; @@ -71,19 +99,28 @@ void SetupConsole(){ std::this_thread::sleep_for(std::chrono::seconds(3)); exit(GetLastError()); } +#else #endif // __WIN32 } + [[noreturn]] void ReadCin(){ while (true){ - int In = getchar(); - if (In == 13) { + int In = _getch(); + if (In == 13 || In == '\n') { if(!CInputBuff.empty()) { HandleInput(CInputBuff); CInputBuff.clear(); } }else if(In == 8){ if(!CInputBuff.empty())CInputBuff.pop_back(); - }else CInputBuff += char(In); + } else if (In == 4) { + CInputBuff = "exit"; + HandleInput(CInputBuff); + CInputBuff.clear(); + }else { + printf("%c[2K\r", 27); + CInputBuff += char(In); + } } } void ConsoleInit(){ diff --git a/src/Network/GParser.cpp b/src/Network/GParser.cpp index 5d5e8e8..86b7e82 100644 --- a/src/Network/GParser.cpp +++ b/src/Network/GParser.cpp @@ -163,7 +163,7 @@ void GlobalParser(Client*c, const std::string& Pack){ } switch (Code) { - case 'P': + case 'P': // initial connection Respond(c, Sec("P") + std::to_string(c->GetID()),true); SyncClient(c); return; diff --git a/src/Network/Sync.cpp b/src/Network/Sync.cpp index 0ec589c..e76cca1 100644 --- a/src/Network/Sync.cpp +++ b/src/Network/Sync.cpp @@ -1,10 +1,10 @@ /// /// Created by Anonymous275 on 8/1/2020 /// -#include "Security/Enc.h" #include "Client.hpp" -#include "Settings.h" #include "Logger.h" +#include "Security/Enc.h" +#include "Settings.h" #include "UnixCompat.h" #include @@ -13,22 +13,25 @@ #include #endif // __linux -void STCPSend(Client*c,std::string Data){ - if(c == nullptr)return; +void STCPSend(Client* c, std::string Data) { + if (c == nullptr) + return; ssize_t BytesSent = send(c->GetTCPSock(), Data.c_str(), size_t(Data.size()), 0); Data.clear(); - if (BytesSent == 0){ - if(c->GetStatus() > -1)c->SetStatus(-1); - }else if (BytesSent < 0) { - if(c->GetStatus() > -1)c->SetStatus(-1); + if (BytesSent == 0) { + if (c->GetStatus() > -1) + c->SetStatus(-1); + } else if (BytesSent < 0) { + if (c->GetStatus() > -1) + c->SetStatus(-1); closesocket(c->GetTCPSock()); } } -void SendFile(Client*c,const std::string&Name){ - info(c->GetName()+Sec(" requesting : ")+Name.substr(Name.find_last_of('/'))); - struct stat Info{}; - if(stat(Name.c_str(), &Info) != 0){ - STCPSend(c,Sec("Cannot Open")); +void SendFile(Client* c, const std::string& Name) { + info(c->GetName() + Sec(" requesting : ") + Name.substr(Name.find_last_of('/'))); + struct stat Info {}; + if (stat(Name.c_str(), &Info) != 0) { + STCPSend(c, Sec("Cannot Open")); return; } std::ifstream f(Name.c_str(), std::ios::binary); @@ -38,72 +41,81 @@ void SendFile(Client*c,const std::string&Name){ size_t Sent = 0; size_t Diff; ssize_t Split = 64000; - while(c->GetStatus() > -1 && Sent < Size){ + while (c->GetStatus() > -1 && Sent < Size) { Diff = Size - Sent; - if(Diff > size_t(Split)){ - std::string Data(size_t(Split),0); + if (Diff > size_t(Split)) { + std::string Data(size_t(Split), 0); f.seekg(ssize_t(Sent), std::ios_base::beg); f.read(&Data[0], Split); - STCPSend(c,Data); + STCPSend(c, Data); Sent += size_t(Split); - }else{ - std::string Data(Diff,0); + } else { + std::string Data(Diff, 0); f.seekg(ssize_t(Sent), std::ios_base::beg); f.read(&Data[0], ssize_t(Diff)); - STCPSend(c,Data); + STCPSend(c, Data); Sent += Diff; } } f.close(); } -void Parse(Client*c,const std::string&Packet){ - if(c == nullptr || Packet.empty())return; - char Code = Packet.at(0),SubCode = 0; - if(Packet.length() > 1)SubCode = Packet.at(1); +void Parse(Client* c, const std::string& Packet) { + if (c == nullptr || Packet.empty()) + return; + char Code = Packet.at(0), SubCode = 0; + if (Packet.length() > 1) + SubCode = Packet.at(1); switch (Code) { - case 'f': - SendFile(c,Packet.substr(1)); - return; - case 'S': - if(SubCode == 'R'){ - debug(Sec("Sending Mod Info")); - std::string ToSend = FileList+FileSizes; - if(ToSend.empty())ToSend = "-"; - STCPSend(c,ToSend); - } - return; - default: - return; + case 'f': + SendFile(c, Packet.substr(1)); + return; + case 'S': + if (SubCode == 'R') { + debug(Sec("Sending Mod Info")); + std::string ToSend = FileList + FileSizes; + if (ToSend.empty()) + ToSend = "-"; + STCPSend(c, ToSend); + } + return; + default: + return; } } -bool STCPRecv(Client*c){ - if(c == nullptr)return false; +bool STCPRecv(Client* c) { + if (c == nullptr) + return false; char buf[200]; size_t len = 200; ZeroMemory(buf, len); - ssize_t BytesRcv = recv(c->GetTCPSock(), buf, len,0); - if (BytesRcv == 0){ - if(c->GetStatus() > -1)c->SetStatus(-1); + ssize_t BytesRcv = recv(c->GetTCPSock(), buf, len, 0); + if (BytesRcv == 0) { + if (c->GetStatus() > -1) + c->SetStatus(-1); closesocket(c->GetTCPSock()); return false; - }else if (BytesRcv < 0) { - if(c->GetStatus() > -1)c->SetStatus(-1); + } else if (BytesRcv < 0) { + if (c->GetStatus() > -1) + c->SetStatus(-1); closesocket(c->GetTCPSock()); return false; } - if(strcmp(buf,"Done") == 0)return false; + if (strcmp(buf, "Done") == 0) + return false; std::string Ret(buf, size_t(BytesRcv)); - Parse(c,Ret); + Parse(c, Ret); return true; } -void SyncResources(Client*c){ - if(c == nullptr)return; - try{ - STCPSend(c,Sec("WS")); - while(c->GetStatus() > -1 && STCPRecv(c)); - }catch (std::exception& e){ +void SyncResources(Client* c) { + if (c == nullptr) + return; + try { + STCPSend(c, Sec("WS")); + while (c->GetStatus() > -1 && STCPRecv(c)) + ; + } catch (std::exception& e) { except(Sec("Exception! : ") + std::string(e.what())); c->SetStatus(-1); } diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index 13d60db..d5b2827 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -2,147 +2,155 @@ /// Created by Anonymous275 on 5/8/2020 /// ///UDP -#include "Security/Enc.h" -#include "Compressor.h" #include "Client.hpp" -#include "Settings.h" -#include "Network.h" +#include "Compressor.h" #include "Logger.h" +#include "Network.h" +#include "Security/Enc.h" +#include "Settings.h" #include "UnixCompat.h" -#include -#include -#include #include #include #include -int FC(const std::string& s,const std::string& p,int n); -struct PacketData{ +#include +#include +#include +int FC(const std::string& s, const std::string& p, int n); +struct PacketData { int ID; ::Client* Client; std::string Data; int Tries; }; -struct SplitData{ - int Total{}; - int ID{}; - std::set> Fragments; +struct SplitData { + int Total {}; + int ID {}; + std::set> Fragments; }; SOCKET UDPSock; std::set DataAcks; std::set SplitPackets; -void UDPSend(Client*c,std::string Data){ - if(c == nullptr || !c->isConnected || c->GetStatus() < 0)return; +void UDPSend(Client* c, std::string Data) { + if (c == nullptr || !c->isConnected || c->GetStatus() < 0) + return; sockaddr_in Addr = c->GetUDPAddr(); socklen_t AddrSize = sizeof(c->GetUDPAddr()); - Data = Data.substr(0,Data.find(char(0))); - if(Data.length() > 400){ + Data = Data.substr(0, Data.find(char(0))); + if (Data.length() > 400) { std::string CMP(Comp(Data)); Data = "ABG:" + CMP; } - ssize_t sendOk = sendto(UDPSock, Data.c_str(), Data.size(), 0, (sockaddr *) &Addr, AddrSize); + ssize_t sendOk = sendto(UDPSock, Data.c_str(), Data.size(), 0, (sockaddr*)&Addr, AddrSize); #ifdef __WIN32 if (sendOk != 0) { debug(Sec("(UDP) Send Failed Code : ") + std::to_string(WSAGetLastError())); - if(c->GetStatus() > -1)c->SetStatus(-1); + if (c->GetStatus() > -1) + c->SetStatus(-1); } #else // unix if (sendOk != 0) { debug(Sec("(UDP) Send Failed Code : ") + std::string(strerror(errno))); - if(c->GetStatus() > -1)c->SetStatus(-1); + if (c->GetStatus() > -1) + c->SetStatus(-1); } #endif // __WIN32 } -void AckID(int ID){ - for(PacketData* p : DataAcks){ - if(p != nullptr && p->ID == ID){ +void AckID(int ID) { + for (PacketData* p : DataAcks) { + if (p != nullptr && p->ID == ID) { DataAcks.erase(p); break; } } } -int PacktID(){ +int PacktID() { static int ID = -1; - if(ID > 999999)ID = 0; - else ID++; + if (ID > 999999) + ID = 0; + else + ID++; return ID; } -int SplitID(){ +int SplitID() { static int SID = -1; - if(SID > 999999)SID = 0; - else SID++; + if (SID > 999999) + SID = 0; + else + SID++; return SID; } -void SendLarge(Client*c,std::string Data){ - Data = Data.substr(0,Data.find(char(0))); +void SendLarge(Client* c, std::string Data) { + Data = Data.substr(0, Data.find(char(0))); int ID = PacktID(); std::string Packet; - if(Data.length() > 1000){ + if (Data.length() > 1000) { std::string pckt = Data; - int S = 1,Split = int(ceil(float(pckt.length()) / 1000)); + int S = 1, Split = int(ceil(float(pckt.length()) / 1000)); int SID = SplitID(); - while(pckt.length() > 1000){ - Packet = "SC|"+std::to_string(S)+"|"+std::to_string(Split)+"|"+std::to_string(ID)+"|"+ - std::to_string(SID)+"|"+pckt.substr(0,1000); - DataAcks.insert(new PacketData{ID,c,Packet,1}); - UDPSend(c,Packet); + while (pckt.length() > 1000) { + Packet = "SC|" + std::to_string(S) + "|" + std::to_string(Split) + "|" + std::to_string(ID) + "|" + std::to_string(SID) + "|" + pckt.substr(0, 1000); + DataAcks.insert(new PacketData { ID, c, Packet, 1 }); + UDPSend(c, Packet); pckt = pckt.substr(1000); S++; ID = PacktID(); } - Packet = "SC|"+std::to_string(S)+"|"+std::to_string(Split)+"|"+ - std::to_string(ID)+"|"+std::to_string(SID)+"|"+pckt; - DataAcks.insert(new PacketData{ID,c,Packet,1}); - UDPSend(c,Packet); - }else{ + Packet = "SC|" + std::to_string(S) + "|" + std::to_string(Split) + "|" + std::to_string(ID) + "|" + std::to_string(SID) + "|" + pckt; + DataAcks.insert(new PacketData { ID, c, Packet, 1 }); + UDPSend(c, Packet); + } else { Packet = "BD:" + std::to_string(ID) + ":" + Data; - DataAcks.insert(new PacketData{ID,c,Packet,1}); - UDPSend(c,Packet); + DataAcks.insert(new PacketData { ID, c, Packet, 1 }); + UDPSend(c, Packet); } } -struct HandledC{ +struct HandledC { size_t Pos = 0; - Client *c = nullptr; - std::array HandledIDs = {-1}; + Client* c = nullptr; + std::array HandledIDs = { -1 }; }; std::set HandledIDs; -void ResetIDs(HandledC*H){ - for(size_t C = 0;C < 100;C++){ +void ResetIDs(HandledC* H) { + for (size_t C = 0; C < 100; C++) { H->HandledIDs.at(C) = -1; } } -HandledC*GetHandled(Client*c){ - for(HandledC*h : HandledIDs){ - if(h->c == c){ +HandledC* GetHandled(Client* c) { + for (HandledC* h : HandledIDs) { + if (h->c == c) { return h; } } return new HandledC(); } -bool Handled(Client*c,int ID){ +bool Handled(Client* c, int ID) { bool handle = false; - for(HandledC*h : HandledIDs){ - if(h->c == c){ - for(int id : h->HandledIDs){ - if(id == ID)return true; + for (HandledC* h : HandledIDs) { + if (h->c == c) { + for (int id : h->HandledIDs) { + if (id == ID) + return true; } - if(h->Pos > 99)h->Pos = 0; + if (h->Pos > 99) + h->Pos = 0; h->HandledIDs.at(h->Pos) = ID; h->Pos++; handle = true; } } - for(HandledC*h : HandledIDs){ - if(h->c == nullptr || !h->c->isConnected){ + for (HandledC* h : HandledIDs) { + if (h->c == nullptr || !h->c->isConnected) { HandledIDs.erase(h); break; } } - if(!handle){ - HandledC *h = GetHandled(c); + if (!handle) { + HandledC* h = GetHandled(c); ResetIDs(h); - if (h->Pos > 99)h->Pos = 0; + if (h->Pos > 99) + h->Pos = 0; h->HandledIDs.at(h->Pos) = ID; h->Pos++; h->c = c; @@ -150,12 +158,12 @@ bool Handled(Client*c,int ID){ } return false; } -std::string UDPRcvFromClient(sockaddr_in& client){ +std::string UDPRcvFromClient(sockaddr_in& client) { size_t clientLength = sizeof(client); ZeroMemory(&client, clientLength); - std::string Ret(10240,0); + std::string Ret(10240, 0); ssize_t Rcv = recvfrom(UDPSock, &Ret[0], 10240, 0, (sockaddr*)&client, (socklen_t*)&clientLength); - if (Rcv == -1){ + if (Rcv == -1) { #ifdef __WIN32 error(Sec("(UDP) Error receiving from Client! Code : ") + std::to_string(WSAGetLastError())); #else // unix @@ -166,77 +174,80 @@ std::string UDPRcvFromClient(sockaddr_in& client){ return Ret; } -SplitData*GetSplit(int SplitID){ - for(SplitData* a : SplitPackets){ - if(a->ID == SplitID)return a; +SplitData* GetSplit(int SplitID) { + for (SplitData* a : SplitPackets) { + if (a->ID == SplitID) + return a; } auto* SP = new SplitData(); SplitPackets.insert(SP); return SP; } -void HandleChunk(Client*c,const std::string&Data){ - int pos = FC(Data,"|",5); - if(pos == -1)return; - std::stringstream ss(Data.substr(0,size_t(pos++))); +void HandleChunk(Client* c, const std::string& Data) { + int pos = FC(Data, "|", 5); + if (pos == -1) + return; + std::stringstream ss(Data.substr(0, size_t(pos++))); std::string t; int I = -1; //Current Max ID SID - std::vector Num(4,0); + std::vector Num(4, 0); while (std::getline(ss, t, '|')) { - if(I >= 0)Num.at(size_t(I)) = std::stoi(t); + if (I >= 0) + Num.at(size_t(I)) = std::stoi(t); I++; } std::string ack = "TRG:" + std::to_string(Num.at(2)); - UDPSend(c,ack); - if(Handled(c,Num.at(2))){ + UDPSend(c, ack); + if (Handled(c, Num.at(2))) { return; } std::string Packet = Data.substr(size_t(pos)); SplitData* SData = GetSplit(Num.at(3)); SData->Total = Num.at(1); SData->ID = Num.at(3); - SData->Fragments.insert(std::make_pair(Num.at(0),Packet)); - if(SData->Fragments.size() == size_t(SData->Total)) { + SData->Fragments.insert(std::make_pair(Num.at(0), Packet)); + if (SData->Fragments.size() == size_t(SData->Total)) { std::string ToHandle; - for(const std::pair& a : SData->Fragments){ + for (const std::pair& a : SData->Fragments) { ToHandle += a.second; } - GParser(c,ToHandle); + GParser(c, ToHandle); SplitPackets.erase(SData); delete SData; SData = nullptr; } } -void UDPParser(Client*c,std::string Packet){ - if(Packet.substr(0,4) == "ABG:"){ +void UDPParser(Client* c, std::string Packet) { + if (Packet.substr(0, 4) == "ABG:") { Packet = DeComp(Packet.substr(4)); } - if(Packet.substr(0,4) == "TRG:"){ + if (Packet.substr(0, 4) == "TRG:") { std::string pkt = Packet.substr(4); - if(Packet.find_first_not_of("0123456789") == std::string::npos){ + if (Packet.find_first_not_of("0123456789") == std::string::npos) { AckID(stoi(Packet)); } return; - }else if(Packet.substr(0,3) == "BD:"){ - auto pos = Packet.find(':',4); - int ID = stoi(Packet.substr(3,pos-3)); + } else if (Packet.substr(0, 3) == "BD:") { + auto pos = Packet.find(':', 4); + int ID = stoi(Packet.substr(3, pos - 3)); std::string pkt = "TRG:" + std::to_string(ID); - UDPSend(c,pkt); - if(!Handled(c,ID)) { + UDPSend(c, pkt); + if (!Handled(c, ID)) { pkt = Packet.substr(pos + 1); GParser(c, pkt); } return; - }else if(Packet.substr(0,2) == "SC"){ - HandleChunk(c,Packet); + } else if (Packet.substr(0, 2) == "SC") { + HandleChunk(c, Packet); return; } - GParser(c,Packet); + GParser(c, Packet); } -void LOOP(){ - while(UDPSock != -1) { - for (PacketData* p : DataAcks){ - if(p != nullptr) { +void LOOP() { + while (UDPSock != -1) { + for (PacketData* p : DataAcks) { + if (p != nullptr) { if (p->Client == nullptr || p->Client->GetTCPSock() == -1) { DataAcks.erase(p); break; @@ -253,23 +264,23 @@ void LOOP(){ std::this_thread::sleep_for(std::chrono::milliseconds(300)); } } -[[noreturn]] void UDPServerMain(){ +[[noreturn]] void UDPServerMain() { #ifdef __WIN32 WSADATA data; - if (WSAStartup(514, &data)){ + if (WSAStartup(514, &data)) { error(Sec("Can't start Winsock!")); //return; } UDPSock = socket(AF_INET, SOCK_DGRAM, 0); // Create a server hint structure for the server - sockaddr_in serverAddr{}; + sockaddr_in serverAddr {}; serverAddr.sin_addr.S_un.S_addr = ADDR_ANY; //Any Local serverAddr.sin_family = AF_INET; // Address format is IPv4 serverAddr.sin_port = htons(Port); // Convert from little to big endian // Try and bind the socket to the IP and port - if (bind(UDPSock, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR){ + if (bind(UDPSock, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) { error(Sec("Can't bind socket!") + std::to_string(WSAGetLastError())); std::this_thread::sleep_for(std::chrono::seconds(5)); exit(-1); @@ -280,21 +291,22 @@ void LOOP(){ std::thread Ack(LOOP); Ack.detach(); - info(Sec("Vehicle data network online on port ")+std::to_string(Port)+Sec(" with a Max of ")+std::to_string(MaxPlayers)+Sec(" Clients")); - while (true){ - sockaddr_in client{}; + info(Sec("Vehicle data network online on port ") + std::to_string(Port) + Sec(" with a Max of ") + std::to_string(MaxPlayers) + Sec(" Clients")); + while (true) { + sockaddr_in client {}; std::string Data = UDPRcvFromClient(client); //Receives any data from Socket auto Pos = Data.find(':'); - if(Data.empty() || Pos < 0 || Pos > 2)continue; + if (Data.empty() || Pos < 0 || Pos > 2) + continue; /*char clientIp[256]; ZeroMemory(clientIp, 256); ///Code to get IP we don't need that yet inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);*/ - uint8_t ID = Data.at(0)-1; - for(Client*c : CI->Clients){ - if(c != nullptr && c->GetID() == ID){ + uint8_t ID = Data.at(0) - 1; + for (Client* c : CI->Clients) { + if (c != nullptr && c->GetID() == ID) { c->SetUDPAddr(client); c->isConnected = true; - UDPParser(c,Data.substr(2)); + UDPParser(c, Data.substr(2)); } } } @@ -304,13 +316,13 @@ void LOOP(){ #else // unix UDPSock = socket(AF_INET, SOCK_DGRAM, 0); // Create a server hint structure for the server - sockaddr_in serverAddr{}; + sockaddr_in serverAddr {}; serverAddr.sin_addr.s_addr = INADDR_ANY; //Any Local serverAddr.sin_family = AF_INET; // Address format is IPv4 serverAddr.sin_port = htons(uint16_t(Port)); // Convert from little to big endian // Try and bind the socket to the IP and port - if (bind(UDPSock, (sockaddr*)&serverAddr, sizeof(serverAddr)) != 0){ + if (bind(UDPSock, (sockaddr*)&serverAddr, sizeof(serverAddr)) != 0) { error(Sec("Can't bind socket!") + std::string(strerror(errno))); std::this_thread::sleep_for(std::chrono::seconds(5)); exit(-1); @@ -321,21 +333,22 @@ void LOOP(){ std::thread Ack(LOOP); Ack.detach(); - info(Sec("Vehicle data network online on port ")+std::to_string(Port)+Sec(" with a Max of ")+std::to_string(MaxPlayers)+Sec(" Clients")); - while (true){ - sockaddr_in client{}; + info(Sec("Vehicle data network online on port ") + std::to_string(Port) + Sec(" with a Max of ") + std::to_string(MaxPlayers) + Sec(" Clients")); + while (true) { + sockaddr_in client {}; std::string Data = UDPRcvFromClient(client); //Receives any data from Socket size_t Pos = Data.find(':'); - if(Data.empty() || Pos > 2)continue; + if (Data.empty() || Pos > 2) + continue; /*char clientIp[256]; ZeroMemory(clientIp, 256); ///Code to get IP we don't need that yet inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);*/ uint8_t ID = uint8_t(Data.at(0)) - 1; - for(Client*c : CI->Clients){ - if(c != nullptr && c->GetID() == ID){ + for (Client* c : CI->Clients) { + if (c != nullptr && c->GetID() == ID) { c->SetUDPAddr(client); c->isConnected = true; - UDPParser(c,Data.substr(2)); + UDPParser(c, Data.substr(2)); } } } From 289bb1c1f38a6273c9c8ad3105def28b8e9034a9 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Tue, 3 Nov 2020 09:03:01 +0100 Subject: [PATCH 06/30] add *Server.cfg* rule to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a6c96aa..0d9e091 100644 --- a/.gitignore +++ b/.gitignore @@ -459,3 +459,4 @@ out/build/x86-Debug/.cmake/api/v1/reply/target-cmake-main-Debug-540e487569703b71 out/build/x86-Debug/.cmake/api/v1/reply/index-2020-01-28T17-35-38-0764.json out/build/x86-Debug/.cmake/api/v1/reply/codemodel-v2-6a61e390ef8eaf17e9f8.json out/build/x86-Debug/Server.cfg +*Server.cfg* From 69f20bdf41726fad5ad7013acd74b82f165036f2 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Tue, 3 Nov 2020 09:36:00 +0100 Subject: [PATCH 07/30] Add TID debug printing --- include/Logger.h | 2 ++ src/logger.cpp | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/include/Logger.h b/include/Logger.h index cf26ba5..f3a4ea7 100644 --- a/include/Logger.h +++ b/include/Logger.h @@ -5,6 +5,8 @@ #include #include void InitLog(); +#define DebugPrintTID(what) DebugPrintTIDInternal(what, __func__) +void DebugPrintTIDInternal(const std::string& what, const std::string& func); // prints the current thread id in debug mode, to make tracing of crashes and asserts easier void ConsoleOut(const std::string& msg); void except(const std::string& toPrint); void debug(const std::string& toPrint); diff --git a/src/logger.cpp b/src/logger.cpp index 72020df..2e3f3fd 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -8,6 +8,13 @@ #include #include #include +#include + +void DebugPrintTIDInternal(const std::string& what, const std::string& func) { + std::stringstream ss; + ss << "Thread '" << std::this_thread::get_id() << "' in " << func << " is " << what; + debug(ss.str()); +} std::string getDate() { typedef std::chrono::duration>::type> days; From 2ec65d5b8453cc78a02051d8541b0b765f40da32 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Tue, 3 Nov 2020 10:13:52 +0100 Subject: [PATCH 08/30] Implement Assertion properly, TID printing in debug builds --- include/Assert.h | 26 +++++++++++++++++++------- include/Client.hpp | 2 ++ include/Logger.h | 1 + src/Init/Config.cpp | 2 ++ src/Network/Auth.cpp | 2 ++ src/Network/GParser.cpp | 8 ++++++++ src/Network/Http.cpp | 5 ++++- src/Network/InitClient.cpp | 6 +++++- src/Network/Sync.cpp | 5 +++++ src/Network/TCPHandler.cpp | 4 ++++ src/logger.cpp | 8 +++++--- src/main.cpp | 5 +++++ 12 files changed, 62 insertions(+), 12 deletions(-) diff --git a/include/Assert.h b/include/Assert.h index f3bcc55..f0f8bde 100644 --- a/include/Assert.h +++ b/include/Assert.h @@ -1,9 +1,19 @@ // Author: lionkor +/* + * Asserts are to be used anywhere where assumptions about state are made + * implicitly. AssertNotReachable is used where code should never go, like in + * default switch cases which shouldn't trigger. They make it explicit + * that a place cannot normally be reached and make it an error if they do. + */ + #pragma once #include #include +#include +#include +#include #include "Logger.h" @@ -30,23 +40,25 @@ static const char* const ANSI_WHITE_BOLD = "\u001b[37;1m"; static const char* const ANSI_BOLD = "\u001b[1m"; static const char* const ANSI_UNDERLINE = "\u001b[4m"; -inline void _assert(const char* file, const char* function, unsigned line, - const char* condition_string, bool result) { +inline void _assert([[maybe_unused]] const char* file, [[maybe_unused]] const char* function, [[maybe_unused]] unsigned line, + [[maybe_unused]] const char* condition_string, [[maybe_unused]] bool result) { if (!result) { #if DEBUG - fprintf(stderr, - "%sASSERTION FAILED%s at %s%s:%u%s \n\t-> in %s%s%s, Line %u: \n\t\t-> " + std::stringstream ss; + ss << std::this_thread::get_id(); + fprintf(stdout, + "(debug build) TID %s: %sASSERTION FAILED%s at %s%s:%u%s in \n\t-> in %s%s%s, Line %u: \n\t\t-> " "Failed Condition: %s%s%s\n", - ANSI_RED_BOLD, ANSI_RESET, ANSI_UNDERLINE, file, line, ANSI_RESET, + ss.str().c_str(), ANSI_RED_BOLD, ANSI_RESET, ANSI_UNDERLINE, file, line, ANSI_RESET, ANSI_BOLD, function, ANSI_RESET, line, ANSI_RED, condition_string, ANSI_RESET); - fprintf(stderr, "%s... terminating with SIGABRT ...%s\n", ANSI_BOLD, ANSI_RESET); + fprintf(stdout, "%s... terminating with SIGABRT ...%s\n", ANSI_BOLD, ANSI_RESET); abort(); #else char buf[2048]; sprintf(buf, "%s=> ASSERTION `%s` FAILED IN RELEASE BUILD%s%s -> IGNORING FAILED ASSERTION " - "& HOPING IT WON'T CRASH%s\n", + "& HOPING IT WON'T CRASH%s", ANSI_RED_BOLD, condition_string, ANSI_RESET, ANSI_RED, ANSI_RESET); error(buf); #endif diff --git a/include/Client.hpp b/include/Client.hpp index 11f5c1f..9c6bfa6 100644 --- a/include/Client.hpp +++ b/include/Client.hpp @@ -10,6 +10,7 @@ #define SOCKET int #endif #include "Buffer.h" +#include "Assert.h" #include #include #include @@ -65,6 +66,7 @@ struct ClientInterface{ c = nullptr; } void AddClient(Client *c){ + Assert(c); Clients.insert(c); } int Size(){ diff --git a/include/Logger.h b/include/Logger.h index f3a4ea7..a8a3add 100644 --- a/include/Logger.h +++ b/include/Logger.h @@ -8,6 +8,7 @@ void InitLog(); #define DebugPrintTID(what) DebugPrintTIDInternal(what, __func__) void DebugPrintTIDInternal(const std::string& what, const std::string& func); // prints the current thread id in debug mode, to make tracing of crashes and asserts easier void ConsoleOut(const std::string& msg); +void QueueAbort(); void except(const std::string& toPrint); void debug(const std::string& toPrint); void error(const std::string& toPrint); diff --git a/src/Init/Config.cpp b/src/Init/Config.cpp index e24a744..3d91176 100644 --- a/src/Init/Config.cpp +++ b/src/Init/Config.cpp @@ -3,6 +3,7 @@ /// #include "Security/Enc.h" #include "Logger.h" +#include "Assert.h" #include #include #include @@ -77,6 +78,7 @@ std::string RemoveComments(const std::string& Line){ return Return; } void LoadConfig(std::ifstream& IFS){ + Assert(IFS.is_open()); std::string line; int index = 1; while (getline(IFS, line)) { diff --git a/src/Network/Auth.cpp b/src/Network/Auth.cpp index 2da1f9f..b2f3e9a 100644 --- a/src/Network/Auth.cpp +++ b/src/Network/Auth.cpp @@ -90,6 +90,8 @@ std::string GenerateM(RSA*key){ } void Identification(SOCKET TCPSock,Hold*S,RSA*Skey){ + Assert(S); + Assert(Skey); S->TCPSock = TCPSock; std::thread Timeout(Check,S); Timeout.detach(); diff --git a/src/Network/GParser.cpp b/src/Network/GParser.cpp index 86b7e82..9492bac 100644 --- a/src/Network/GParser.cpp +++ b/src/Network/GParser.cpp @@ -21,6 +21,7 @@ int FC(const std::string& s,const std::string& p,int n) { else return -1; } void Apply(Client*c,int VID,const std::string& pckt){ + Assert(c); std::string Packet = pckt; std::string VD = c->GetCarData(VID); Packet = Packet.substr(FC(Packet, ",", 2) + 1); @@ -31,6 +32,7 @@ void Apply(Client*c,int VID,const std::string& pckt){ } void VehicleParser(Client*c,const std::string& Pckt){ + Assert(c); if(c == nullptr || Pckt.length() < 4)return; std::string Packet = Pckt; char Code = Packet.at(1); @@ -94,10 +96,12 @@ void VehicleParser(Client*c,const std::string& Pckt){ SendToAll(c,Packet,false,true); return; default: + AssertNotReachable(); return; } } void SyncClient(Client*c){ + Assert(c); if(c->isSynced)return; c->isSynced = true; std::this_thread::sleep_for(std::chrono::seconds(1)); @@ -119,6 +123,7 @@ void SyncClient(Client*c){ info(c->GetName() + Sec(" is now synced!")); } void ParseVeh(Client*c, const std::string& Packet){ + Assert(c); #ifdef __WIN32 __try{ VehicleParser(c,Packet); @@ -129,6 +134,7 @@ void ParseVeh(Client*c, const std::string& Packet){ } void HandleEvent(Client*c ,const std::string&Data){ + Assert(c); std::stringstream ss(Data); std::string t,Name; int a = 0; @@ -149,6 +155,7 @@ void HandleEvent(Client*c ,const std::string&Data){ } void GlobalParser(Client*c, const std::string& Pack){ + Assert(c); [[maybe_unused]] static int lastRecv = 0; if(Pack.empty() || c == nullptr)return; std::string Packet = Pack.substr(0,Pack.find(char(0))); @@ -196,6 +203,7 @@ void GlobalParser(Client*c, const std::string& Pack){ } void GParser(Client*c, const std::string& Packet){ + Assert(c); #ifdef __WIN32 __try{ GlobalParser(c, Packet); diff --git a/src/Network/Http.cpp b/src/Network/Http.cpp index e95e5c7..b46e5c2 100644 --- a/src/Network/Http.cpp +++ b/src/Network/Http.cpp @@ -3,6 +3,7 @@ /// #define CURL_STATICLIB #include "Curl/curl.h" +#include "Assert.h" #include static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp){ ((std::string*)userp)->append((char*)contents, size * nmemb); @@ -13,6 +14,7 @@ std::string HttpRequest(const std::string& IP,int port){ CURLcode res; std::string readBuffer; curl = curl_easy_init(); + Assert(curl); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, IP.c_str()); curl_easy_setopt(curl, CURLOPT_PORT, port); @@ -30,6 +32,7 @@ std::string PostHTTP(const std::string& IP,const std::string& Fields){ CURLcode res; std::string readBuffer; curl = curl_easy_init(); + Assert(curl); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, IP.c_str()); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, Fields.size()); @@ -42,4 +45,4 @@ std::string PostHTTP(const std::string& IP,const std::string& Fields){ if(res != CURLE_OK)return "-1"; } return readBuffer; -} \ No newline at end of file +} diff --git a/src/Network/InitClient.cpp b/src/Network/InitClient.cpp index e194e15..a31c0f1 100644 --- a/src/Network/InitClient.cpp +++ b/src/Network/InitClient.cpp @@ -24,6 +24,7 @@ int OpenID(){ return ID; } void Respond(Client*c, const std::string& MSG, bool Rel){ + Assert(c); char C = MSG.at(0); if(Rel || C == 'W' || C == 'Y' || C == 'V' || C == 'E'){ if(C == 'O' || C == 'T' || MSG.length() > 1000)SendLarge(c,MSG); @@ -31,6 +32,7 @@ void Respond(Client*c, const std::string& MSG, bool Rel){ }else UDPSend(c,MSG); } void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel){ + Assert(c); char C = Data.at(0); for(Client*client : CI->Clients){ if(client != nullptr) { @@ -55,6 +57,7 @@ void UpdatePlayers(){ SendToAll(nullptr, Packet,true,true); } void OnDisconnect(Client*c,bool kicked){ + Assert(c); info(c->GetName() + Sec(" Connection Terminated")); if(c == nullptr)return; std::string Packet; @@ -73,6 +76,7 @@ void OnDisconnect(Client*c,bool kicked){ CI->RemoveClient(c); ///Removes the Client from existence } void OnConnect(Client*c){ + Assert(c); info(Sec("Client connected")); c->SetID(OpenID()); info(Sec("Assigned ID ") + std::to_string(c->GetID()) + Sec(" to ") + c->GetName()); @@ -82,4 +86,4 @@ void OnConnect(Client*c){ Respond(c,"M"+MapName,true); //Send the Map on connect info(c->GetName() + Sec(" : Connected")); TriggerLuaEvent(Sec("onPlayerJoining"),false,nullptr,new LuaArg{{c->GetID()}},false); -} \ No newline at end of file +} diff --git a/src/Network/Sync.cpp b/src/Network/Sync.cpp index e76cca1..75d5018 100644 --- a/src/Network/Sync.cpp +++ b/src/Network/Sync.cpp @@ -14,6 +14,7 @@ #endif // __linux void STCPSend(Client* c, std::string Data) { + Assert(c); if (c == nullptr) return; ssize_t BytesSent = send(c->GetTCPSock(), Data.c_str(), size_t(Data.size()), 0); @@ -28,6 +29,7 @@ void STCPSend(Client* c, std::string Data) { } } void SendFile(Client* c, const std::string& Name) { + Assert(c); info(c->GetName() + Sec(" requesting : ") + Name.substr(Name.find_last_of('/'))); struct stat Info {}; if (stat(Name.c_str(), &Info) != 0) { @@ -61,6 +63,7 @@ void SendFile(Client* c, const std::string& Name) { } void Parse(Client* c, const std::string& Packet) { + Assert(c); if (c == nullptr || Packet.empty()) return; char Code = Packet.at(0), SubCode = 0; @@ -84,6 +87,7 @@ void Parse(Client* c, const std::string& Packet) { } } bool STCPRecv(Client* c) { + Assert(c); if (c == nullptr) return false; char buf[200]; @@ -109,6 +113,7 @@ bool STCPRecv(Client* c) { } void SyncResources(Client* c) { + Assert(c); if (c == nullptr) return; try { diff --git a/src/Network/TCPHandler.cpp b/src/Network/TCPHandler.cpp index 1765fba..50364b8 100644 --- a/src/Network/TCPHandler.cpp +++ b/src/Network/TCPHandler.cpp @@ -8,6 +8,7 @@ #include void TCPSend(Client*c,const std::string&Data){ + Assert(c); if(c == nullptr)return; std::string Send = "\n" + Data.substr(0,Data.find(char(0))) + "\n"; ssize_t Sent = send(c->GetTCPSock(), Send.c_str(), size_t(Send.size()), 0); @@ -19,6 +20,7 @@ void TCPSend(Client*c,const std::string&Data){ } } void TCPHandle(Client*c,const std::string& data){ + Assert(c); #ifdef __WIN32 __try{ #endif // __WIN32 @@ -30,6 +32,7 @@ void TCPHandle(Client*c,const std::string& data){ #endif // __WIN32 } void TCPRcv(Client*c){ + Assert(c); if(c == nullptr || c->GetStatus() < 0)return; char buf[4096]; size_t len = 4096; @@ -53,6 +56,7 @@ void TCPRcv(Client*c){ TCPHandle(c,Buf); } void TCPClient(Client*c){ + Assert(c); if(c->GetTCPSock() == -1){ CI->RemoveClient(c); return; diff --git a/src/logger.cpp b/src/logger.cpp index 2e3f3fd..2fa24e2 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -11,9 +11,11 @@ #include void DebugPrintTIDInternal(const std::string& what, const std::string& func) { - std::stringstream ss; - ss << "Thread '" << std::this_thread::get_id() << "' in " << func << " is " << what; - debug(ss.str()); + // we need to print to cout here as we might crash before all console output is handled, + // due to segfaults or asserts. +#ifdef DEBUG + std::cout << "(debug build) Thread '" << std::this_thread::get_id() << "' in " << func << " is " << what << std::endl; +#endif // DEBUG } std::string getDate() { diff --git a/src/main.cpp b/src/main.cpp index ec81acd..5b7fd09 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,17 +1,22 @@ #include "Startup.h" +#include "Assert.h" #include #include [[noreturn]] void loop(){ + DebugPrintTID("test loop"); while(true){ std::cout.flush(); + Assert(false); std::this_thread::sleep_for(std::chrono::milliseconds(600)); } } int main(int argc, char* argv[]) { + DebugPrintTID("main"); #ifdef DEBUG std::thread t1(loop); t1.detach(); #endif + Assert(false); ConsoleInit(); InitServer(argc,argv); InitConfig(); From b2166402a2f7752503342ebd6134739abc61363a Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Tue, 3 Nov 2020 10:22:49 +0100 Subject: [PATCH 09/30] Print TIDs in every new thread --- include/Logger.h | 4 ++-- src/Console.cpp | 2 ++ src/Init/Heartbeat.cpp | 3 ++- src/Lua/LuaMain.cpp | 1 + src/Lua/LuaSystem.cpp | 1 + src/Network/Auth.cpp | 1 + src/Network/StatMonitor.cpp | 1 + src/Network/TCPHandler.cpp | 1 + src/Network/VehicleData.cpp | 1 + src/logger.cpp | 4 ++-- src/main.cpp | 6 ++---- 11 files changed, 16 insertions(+), 9 deletions(-) diff --git a/include/Logger.h b/include/Logger.h index a8a3add..fa05349 100644 --- a/include/Logger.h +++ b/include/Logger.h @@ -5,8 +5,8 @@ #include #include void InitLog(); -#define DebugPrintTID(what) DebugPrintTIDInternal(what, __func__) -void DebugPrintTIDInternal(const std::string& what, const std::string& func); // prints the current thread id in debug mode, to make tracing of crashes and asserts easier +#define DebugPrintTID() DebugPrintTIDInternal(__func__) +void DebugPrintTIDInternal(const std::string& func); // prints the current thread id in debug mode, to make tracing of crashes and asserts easier void ConsoleOut(const std::string& msg); void QueueAbort(); void except(const std::string& toPrint); diff --git a/src/Console.cpp b/src/Console.cpp index 54c2cc5..a7926ac 100644 --- a/src/Console.cpp +++ b/src/Console.cpp @@ -47,6 +47,7 @@ void ConsoleOut(const std::string& msg){ } [[noreturn]] void OutputRefresh(){ + DebugPrintTID(); while(true){ std::this_thread::sleep_for(std::chrono::milliseconds(10)); ProcessOut(); @@ -104,6 +105,7 @@ void SetupConsole(){ } [[noreturn]] void ReadCin(){ + DebugPrintTID(); while (true){ int In = _getch(); if (In == 13 || In == '\n') { diff --git a/src/Init/Heartbeat.cpp b/src/Init/Heartbeat.cpp index bf10e16..a1bb1ab 100644 --- a/src/Init/Heartbeat.cpp +++ b/src/Init/Heartbeat.cpp @@ -29,6 +29,7 @@ std::string GenerateCall(){ return ret; } void Heartbeat(){ + DebugPrintTID(); std::string R,T; while(true){ R = GenerateCall(); @@ -56,4 +57,4 @@ void Heartbeat(){ void HBInit(){ std::thread HB(Heartbeat); HB.detach(); -} \ No newline at end of file +} diff --git a/src/Lua/LuaMain.cpp b/src/Lua/LuaMain.cpp index d155725..0ec5687 100644 --- a/src/Lua/LuaMain.cpp +++ b/src/Lua/LuaMain.cpp @@ -48,6 +48,7 @@ void FolderList(const std::string& Path,bool HotSwap){ } } [[noreturn]]void HotSwaps(const std::string& path){ + DebugPrintTID(); while(true){ for(Lua*Script : PluginEngine){ struct stat Info{}; diff --git a/src/Lua/LuaSystem.cpp b/src/Lua/LuaSystem.cpp index 47b2f9f..d97ab9a 100644 --- a/src/Lua/LuaSystem.cpp +++ b/src/Lua/LuaSystem.cpp @@ -162,6 +162,7 @@ void ExecuteAsync(Lua* lua,const std::string& FuncName){ SafeExecution(lua,FuncName); } void CallAsync(Lua* lua,const std::string& Func,int U){ + DebugPrintTID(); lua->StopThread = false; int D = 1000 / U; while(!lua->StopThread){ diff --git a/src/Network/Auth.cpp b/src/Network/Auth.cpp index b2f3e9a..3da2573 100644 --- a/src/Network/Auth.cpp +++ b/src/Network/Auth.cpp @@ -178,6 +178,7 @@ void Identify(SOCKET TCPSock){ } void TCPServerMain(){ + DebugPrintTID(); #ifdef __WIN32 WSADATA wsaData; if (WSAStartup(514, &wsaData)){ diff --git a/src/Network/StatMonitor.cpp b/src/Network/StatMonitor.cpp index b555547..9a2db80 100644 --- a/src/Network/StatMonitor.cpp +++ b/src/Network/StatMonitor.cpp @@ -30,6 +30,7 @@ void Monitor() { } [[noreturn]]void Stat(){ + DebugPrintTID(); while(true){ Monitor(); std::this_thread::sleep_for(std::chrono::seconds(1)); diff --git a/src/Network/TCPHandler.cpp b/src/Network/TCPHandler.cpp index 50364b8..c2c3408 100644 --- a/src/Network/TCPHandler.cpp +++ b/src/Network/TCPHandler.cpp @@ -56,6 +56,7 @@ void TCPRcv(Client*c){ TCPHandle(c,Buf); } void TCPClient(Client*c){ + DebugPrintTID(); Assert(c); if(c->GetTCPSock() == -1){ CI->RemoveClient(c); diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index d5b2827..4f91b34 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -245,6 +245,7 @@ void UDPParser(Client* c, std::string Packet) { GParser(c, Packet); } void LOOP() { + DebugPrintTID(); while (UDPSock != -1) { for (PacketData* p : DataAcks) { if (p != nullptr) { diff --git a/src/logger.cpp b/src/logger.cpp index 2fa24e2..daded17 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -10,11 +10,11 @@ #include #include -void DebugPrintTIDInternal(const std::string& what, const std::string& func) { +void DebugPrintTIDInternal(const std::string& func) { // we need to print to cout here as we might crash before all console output is handled, // due to segfaults or asserts. #ifdef DEBUG - std::cout << "(debug build) Thread '" << std::this_thread::get_id() << "' in " << func << " is " << what << std::endl; + std::cout << "(debug build) Thread '" << std::this_thread::get_id() << "' is " << func << std::endl; #endif // DEBUG } diff --git a/src/main.cpp b/src/main.cpp index 5b7fd09..1b74071 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,20 +3,18 @@ #include #include [[noreturn]] void loop(){ - DebugPrintTID("test loop"); + DebugPrintTID(); while(true){ std::cout.flush(); - Assert(false); std::this_thread::sleep_for(std::chrono::milliseconds(600)); } } int main(int argc, char* argv[]) { - DebugPrintTID("main"); + DebugPrintTID(); #ifdef DEBUG std::thread t1(loop); t1.detach(); #endif - Assert(false); ConsoleInit(); InitServer(argc,argv); InitConfig(); From aa73a9d16ae3f1f67e7a26a5119a36ec6a701394 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Tue, 3 Nov 2020 10:38:44 +0100 Subject: [PATCH 10/30] Assert nullptrs in VehicleData we'll nuke this file anyways, but for now lets be safe about ptrs. --- src/Network/VehicleData.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index 4f91b34..17c68b8 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -32,6 +32,7 @@ SOCKET UDPSock; std::set DataAcks; std::set SplitPackets; void UDPSend(Client* c, std::string Data) { + Assert(c); if (c == nullptr || !c->isConnected || c->GetStatus() < 0) return; sockaddr_in Addr = c->GetUDPAddr(); @@ -82,6 +83,7 @@ int SplitID() { return SID; } void SendLarge(Client* c, std::string Data) { + Assert(c); Data = Data.substr(0, Data.find(char(0))); int ID = PacktID(); std::string Packet; @@ -118,6 +120,7 @@ void ResetIDs(HandledC* H) { } } HandledC* GetHandled(Client* c) { + Assert(c); for (HandledC* h : HandledIDs) { if (h->c == c) { return h; @@ -126,6 +129,7 @@ HandledC* GetHandled(Client* c) { return new HandledC(); } bool Handled(Client* c, int ID) { + Assert(c); bool handle = false; for (HandledC* h : HandledIDs) { if (h->c == c) { @@ -184,6 +188,7 @@ SplitData* GetSplit(int SplitID) { return SP; } void HandleChunk(Client* c, const std::string& Data) { + Assert(c); int pos = FC(Data, "|", 5); if (pos == -1) return; @@ -219,6 +224,7 @@ void HandleChunk(Client* c, const std::string& Data) { } } void UDPParser(Client* c, std::string Packet) { + Assert(c); if (Packet.substr(0, 4) == "ABG:") { Packet = DeComp(Packet.substr(4)); } From e9432ac1ca1af977005f5e0db880452c448fecbb Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Tue, 3 Nov 2020 11:48:42 +0100 Subject: [PATCH 11/30] add WIN32 and UNIX specific cmake instructions --- CMakeLists.txt | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 858b422..040bfca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,25 @@ cmake_minimum_required(VERSION 3.10) project(Server) set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -fmax-errors=1 -Wconversion") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") + +if (UNIX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og -g") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -s") +elseif (WIN32) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /permissive-") +endif () + +find_package(Boost 1.71.0 REQUIRED COMPONENTS system thread) file(GLOB source_files "src/*.cpp" "src/*/*.cpp" "include/*.h" "include/*/*.h" "include/*.hpp" "include/*/*.hpp") -add_executable(${PROJECT_NAME} ${source_files}) -target_include_directories(${PROJECT_NAME} PUBLIC $) -set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "BeamMP-Server") -target_link_libraries(${PROJECT_NAME} curl lua5.3 z pthread stdc++fs) +add_executable(BeamMP-Server ${source_files}) + +target_include_directories(BeamMP-Server PUBLIC $ ${Boost_INCLUDE_DIRS}) + +if (UNIX) + target_link_libraries(BeamMP-Server curl lua5.3 krb5 z pthread stdc++fs ${Boost_LINK_DIRS}) +elseif (WIN32) + target_link_libraries(BeamMP-Server libcurl_a urlmon ws2_32 lua53 zlibstatic ${Boost_LINK_DIRS}) +endif () From e986df0579ac0c00cb0703d435581f9470f7f8dc Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Tue, 3 Nov 2020 12:01:31 +0100 Subject: [PATCH 12/30] change __WIN32 to WIN32 (oops) --- CMakeLists.txt | 3 +++ include/Client.hpp | 2 +- include/Curl/curl.h | 2 +- include/UnixCompat.h | 4 ++-- include/Zlib/zconf.h | 2 +- include/Zlib/zutil.h | 2 +- src/Console.cpp | 12 ++++++------ src/Enc.cpp | 4 ++-- src/Lua/LuaSystem.cpp | 12 ++++++------ src/Network/Auth.cpp | 16 ++++++++-------- src/Network/GParser.cpp | 8 ++++---- src/Network/TCPHandler.cpp | 20 ++++++++++---------- src/Network/VehicleData.cpp | 12 ++++++------ src/logger.cpp | 4 ++-- 14 files changed, 53 insertions(+), 50 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 040bfca..d777da4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,9 @@ if (UNIX) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og -g") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -s") elseif (WIN32) + # This might cause issues with old windows headers, but it's worth the trouble to keep the code + # completely cross platform. For fixes to common issues arising from /permissive- visit: + # https://docs.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /permissive-") endif () diff --git a/include/Client.hpp b/include/Client.hpp index 9c6bfa6..9f2cf9e 100644 --- a/include/Client.hpp +++ b/include/Client.hpp @@ -3,7 +3,7 @@ /// #pragma once -#ifdef __WIN32 +#ifdef WIN32 #include #else #include diff --git a/include/Curl/curl.h b/include/Curl/curl.h index 162b606..3fa143c 100644 --- a/include/Curl/curl.h +++ b/include/Curl/curl.h @@ -38,7 +38,7 @@ * Define WIN32 when build target is Win32 API */ -#if (defined(_WIN32) || defined(__WIN32__)) && \ +#if (defined(_WIN32) || defined(WIN32__)) && \ !defined(WIN32) && !defined(__SYMBIAN32__) #define WIN32 #endif diff --git a/include/UnixCompat.h b/include/UnixCompat.h index a5d23e1..bfaf81f 100644 --- a/include/UnixCompat.h +++ b/include/UnixCompat.h @@ -4,7 +4,7 @@ // This header defines unix equivalents of common win32 functions. -#ifndef __WIN32 +#ifndef WIN32 #include #include @@ -27,4 +27,4 @@ inline void closesocket(int socket) { #define __except(x) /**/ #endif -#endif // __WIN32 +#endif // WIN32 diff --git a/include/Zlib/zconf.h b/include/Zlib/zconf.h index 352f552..545e5b1 100644 --- a/include/Zlib/zconf.h +++ b/include/Zlib/zconf.h @@ -176,7 +176,7 @@ #if defined(_WINDOWS) && !defined(WINDOWS) # define WINDOWS #endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(WIN32__) # ifndef WIN32 # define WIN32 # endif diff --git a/include/Zlib/zutil.h b/include/Zlib/zutil.h index b079ea6..370f7b9 100644 --- a/include/Zlib/zutil.h +++ b/include/Zlib/zutil.h @@ -133,7 +133,7 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #if defined(MACOS) || defined(TARGET_OS_MAC) # define OS_CODE 7 # ifndef Z_SOLO -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != WIN32_os # include /* for fdopen */ # else # ifndef fdopen diff --git a/src/Console.cpp b/src/Console.cpp index a7926ac..5dd99db 100644 --- a/src/Console.cpp +++ b/src/Console.cpp @@ -3,14 +3,14 @@ /// #include "Lua/LuaSystem.hpp" -#ifdef __WIN32 +#ifdef WIN32 #include #include #else // *nix typedef unsigned long DWORD, *PDWORD, *LPDWORD; #include #include -#endif // __WIN32 +#endif // WIN32 #include "Logger.h" #include #include @@ -54,7 +54,7 @@ void ConsoleOut(const std::string& msg){ } } -#ifndef __WIN32 +#ifndef WIN32 static int _getch() { char buf = 0; @@ -77,10 +77,10 @@ static int _getch() // no echo printf("%c\n", buf); return buf; } -#endif // __WIN32 +#endif // WIN32 void SetupConsole(){ -#ifdef __WIN32 +#ifdef WIN32 DWORD outMode = 0; HANDLE stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); if (stdoutHandle == INVALID_HANDLE_VALUE){ @@ -101,7 +101,7 @@ void SetupConsole(){ exit(GetLastError()); } #else -#endif // __WIN32 +#endif // WIN32 } [[noreturn]] void ReadCin(){ diff --git a/src/Enc.cpp b/src/Enc.cpp index 6522a90..90b9939 100644 --- a/src/Enc.cpp +++ b/src/Enc.cpp @@ -85,7 +85,7 @@ int Dec(int value,int d,int n){ return log_power(value, d, n); } -#ifdef __WIN32 +#ifdef WIN32 int Handle(EXCEPTION_POINTERS *ep,char* Origin){ assert(false); std::stringstream R; @@ -98,7 +98,7 @@ int Handle(EXCEPTION_POINTERS *ep,char* Origin){ #else // stub int Handle(EXCEPTION_POINTERS *, char*) { return 1; } -#endif // __WIN32 +#endif // WIN32 std::string RSA_E(const std::string& Data, RSA*k){ std::stringstream stream; diff --git a/src/Lua/LuaSystem.cpp b/src/Lua/LuaSystem.cpp index d97ab9a..6fc500b 100644 --- a/src/Lua/LuaSystem.cpp +++ b/src/Lua/LuaSystem.cpp @@ -143,7 +143,7 @@ void SafeExecution(Lua* lua,const std::string& FuncName){ lua_getglobal(luaState, FuncName.c_str()); if(lua_isfunction(luaState, -1)) { char* Origin = ThreadOrigin(lua); -#ifdef __WIN32 +#ifdef WIN32 __try{ int R = lua_pcall(luaState, 0, 0, 0); CheckLua(luaState, R); @@ -151,7 +151,7 @@ void SafeExecution(Lua* lua,const std::string& FuncName){ #else // unix int R = lua_pcall(luaState, 0, 0, 0); CheckLua(luaState, R); -#endif // __WIN32 +#endif // WIN32 delete [] Origin; } ClearStack(luaState); @@ -515,18 +515,18 @@ int CallFunction(Lua*lua,const std::string& FuncName,LuaArg* Arg){ } int R = 0; char* Origin = lua->GetOrigin(); -#ifdef __WIN32 +#ifdef WIN32 __try{ -#endif // __WIN32 +#endif // WIN32 R = lua_pcall(luaState, Size, 1, 0); if (CheckLua(luaState, R)){ if (lua_isnumber(luaState, -1)) { return int(lua_tointeger(luaState, -1)); } } -#ifdef __WIN32 +#ifdef WIN32 }__except(Handle(GetExceptionInformation(),Origin)){} -#endif // __WIN32 +#endif // WIN32 delete [] Origin; } ClearStack(luaState); diff --git a/src/Network/Auth.cpp b/src/Network/Auth.cpp index 3da2573..6bf96e9 100644 --- a/src/Network/Auth.cpp +++ b/src/Network/Auth.cpp @@ -158,20 +158,20 @@ void Identify(SOCKET TCPSock){ // reason MSVC defines __try and __except and libg++ defines // __try and __catch so its all a big mess if we leave this in or undefine // the macros -#ifdef __WIN32 +#ifdef WIN32 __try{ -#endif // __WIN32 +#endif // WIN32 Identification(TCPSock,S,Skey); -#ifdef __WIN32 +#ifdef WIN32 }__except(1){ -#endif // __WIN32 +#endif // WIN32 if(TCPSock != -1){ closesocket(TCPSock); } -#ifdef __WIN32 +#ifdef WIN32 } -#endif // __WIN32 +#endif // WIN32 delete Skey; delete S; @@ -179,7 +179,7 @@ void Identify(SOCKET TCPSock){ void TCPServerMain(){ DebugPrintTID(); -#ifdef __WIN32 +#ifdef WIN32 WSADATA wsaData; if (WSAStartup(514, &wsaData)){ error(Sec("Can't start Winsock!")); @@ -249,5 +249,5 @@ void TCPServerMain(){ }while(client); closesocket(client); -#endif // __WIN32 +#endif // WIN32 } diff --git a/src/Network/GParser.cpp b/src/Network/GParser.cpp index 9492bac..f337f20 100644 --- a/src/Network/GParser.cpp +++ b/src/Network/GParser.cpp @@ -124,13 +124,13 @@ void SyncClient(Client*c){ } void ParseVeh(Client*c, const std::string& Packet){ Assert(c); -#ifdef __WIN32 +#ifdef WIN32 __try{ VehicleParser(c,Packet); }__except(Handle(GetExceptionInformation(),Sec("Vehicle Handler"))){} #else // unix VehicleParser(c,Packet); -#endif // __WIN32 +#endif // WIN32 } void HandleEvent(Client*c ,const std::string&Data){ @@ -204,11 +204,11 @@ void GlobalParser(Client*c, const std::string& Pack){ void GParser(Client*c, const std::string& Packet){ Assert(c); -#ifdef __WIN32 +#ifdef WIN32 __try{ GlobalParser(c, Packet); }__except(Handle(GetExceptionInformation(),Sec("Global Handler"))){} #else GlobalParser(c, Packet); -#endif // __WIN32 +#endif // WIN32 } diff --git a/src/Network/TCPHandler.cpp b/src/Network/TCPHandler.cpp index c2c3408..5b80a07 100644 --- a/src/Network/TCPHandler.cpp +++ b/src/Network/TCPHandler.cpp @@ -21,15 +21,15 @@ void TCPSend(Client*c,const std::string&Data){ } void TCPHandle(Client*c,const std::string& data){ Assert(c); -#ifdef __WIN32 +#ifdef WIN32 __try{ -#endif // __WIN32 +#endif // WIN32 c->Handler.Handle(c,data); -#ifdef __WIN32 +#ifdef WIN32 }__except(1){ c->Handler.clear(); } -#endif // __WIN32 +#endif // WIN32 } void TCPRcv(Client*c){ Assert(c); @@ -43,11 +43,11 @@ void TCPRcv(Client*c){ if(c->GetStatus() > -1)c->SetStatus(-1); return; }else if (BytesRcv < 0) { -#ifdef __WIN32 +#ifdef WIN32 debug(Sec("(TCP) recv failed with error: ") + std::to_string(WSAGetLastError())); #else // unix debug(Sec("(TCP) recv failed with error: ") + std::string(strerror(errno))); -#endif // __WIN32 +#endif // WIN32 if(c->GetStatus() > -1)c->SetStatus(-1); closesocket(c->GetTCPSock()); return; @@ -64,13 +64,13 @@ void TCPClient(Client*c){ } OnConnect(c); while (c->GetStatus() > -1)TCPRcv(c); -#ifdef __WIN32 +#ifdef WIN32 __try{ -#endif // __WIN32 +#endif // WIN32 OnDisconnect(c, c->GetStatus() == -2); -#ifdef __WIN32 +#ifdef WIN32 }__except(Handle(GetExceptionInformation(),Sec("OnDisconnect"))){} -#endif // __WIN32 +#endif // WIN32 } void InitClient(Client*c){ std::thread NewClient(TCPClient,c); diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index 17c68b8..14bd246 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -43,7 +43,7 @@ void UDPSend(Client* c, std::string Data) { Data = "ABG:" + CMP; } ssize_t sendOk = sendto(UDPSock, Data.c_str(), Data.size(), 0, (sockaddr*)&Addr, AddrSize); -#ifdef __WIN32 +#ifdef WIN32 if (sendOk != 0) { debug(Sec("(UDP) Send Failed Code : ") + std::to_string(WSAGetLastError())); if (c->GetStatus() > -1) @@ -55,7 +55,7 @@ void UDPSend(Client* c, std::string Data) { if (c->GetStatus() > -1) c->SetStatus(-1); } -#endif // __WIN32 +#endif // WIN32 } void AckID(int ID) { @@ -168,11 +168,11 @@ std::string UDPRcvFromClient(sockaddr_in& client) { std::string Ret(10240, 0); ssize_t Rcv = recvfrom(UDPSock, &Ret[0], 10240, 0, (sockaddr*)&client, (socklen_t*)&clientLength); if (Rcv == -1) { -#ifdef __WIN32 +#ifdef WIN32 error(Sec("(UDP) Error receiving from Client! Code : ") + std::to_string(WSAGetLastError())); #else // unix error(Sec("(UDP) Error receiving from Client! Code : ") + std::string(strerror(errno))); -#endif // __WIN32 +#endif // WIN32 return ""; } return Ret; @@ -272,7 +272,7 @@ void LOOP() { } } [[noreturn]] void UDPServerMain() { -#ifdef __WIN32 +#ifdef WIN32 WSADATA data; if (WSAStartup(514, &data)) { error(Sec("Can't start Winsock!")); @@ -362,5 +362,5 @@ void LOOP() { /*closesocket(UDPSock); // TODO: Why not this? We did this in TCPServerMain? return; */ -#endif // __WIN32 +#endif // WIN32 } diff --git a/src/logger.cpp b/src/logger.cpp index daded17..357ebf4 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -28,11 +28,11 @@ std::string getDate() { auto s = std::chrono::duration_cast(tp);tp -= s; time_t tt = std::chrono::system_clock::to_time_t(now); tm local_tm{}; -#ifdef __WIN32 +#ifdef WIN32 localtime_s(&local_tm,&tt); #else // unix localtime_r(&tt, &local_tm); -#endif // __WIN32 +#endif // WIN32 std::stringstream date; int S = local_tm.tm_sec; int M = local_tm.tm_min; From 801ea3f777ac3c61faa1b8737ac3ee979b3a7ce8 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Tue, 3 Nov 2020 12:10:08 +0100 Subject: [PATCH 13/30] Fix windows naming issue with assert --- include/Buffer.h | 2 +- include/Client.hpp | 2 +- include/{Assert.h => CustomAssert.h} | 0 include/Lua/luaconf.h | 2 +- include/UnixCompat.h | 4 ++-- src/Enc.cpp | 4 ++-- src/Init/Config.cpp | 2 +- src/Network/Http.cpp | 2 +- src/main.cpp | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) rename include/{Assert.h => CustomAssert.h} (100%) diff --git a/include/Buffer.h b/include/Buffer.h index 83d5205..204e299 100644 --- a/include/Buffer.h +++ b/include/Buffer.h @@ -3,7 +3,7 @@ /// #pragma once #include -#include "Assert.h" +#include "CustomAssert.h" class Client; void GParser(Client*c, const std::string&Packet); class Buffer{ diff --git a/include/Client.hpp b/include/Client.hpp index 9f2cf9e..5344f46 100644 --- a/include/Client.hpp +++ b/include/Client.hpp @@ -10,7 +10,7 @@ #define SOCKET int #endif #include "Buffer.h" -#include "Assert.h" +#include "CustomAssert.h" #include #include #include diff --git a/include/Assert.h b/include/CustomAssert.h similarity index 100% rename from include/Assert.h rename to include/CustomAssert.h diff --git a/include/Lua/luaconf.h b/include/Lua/luaconf.h index f955556..78f40e7 100644 --- a/include/Lua/luaconf.h +++ b/include/Lua/luaconf.h @@ -706,7 +706,7 @@ ** Define it as a help when debugging C code. */ #if defined(LUA_USE_APICHECK) -#include +#include #define luai_apicheck(l,e) assert(e) #endif diff --git a/include/UnixCompat.h b/include/UnixCompat.h index bfaf81f..a2042cc 100644 --- a/include/UnixCompat.h +++ b/include/UnixCompat.h @@ -6,13 +6,13 @@ #ifndef WIN32 -#include +#include "CustomAssert.h" #include #include // ZeroMemory is just a {0} or a memset(addr, 0, len), and it's a macro on MSVC inline void ZeroMemory(void* dst, size_t len) { - assert(std::memset(dst, 0, len) != nullptr); + Assert(std::memset(dst, 0, len) != nullptr); } // provides unix equivalent of closesocket call in win32 inline void closesocket(int socket) { diff --git a/src/Enc.cpp b/src/Enc.cpp index 90b9939..a7affa0 100644 --- a/src/Enc.cpp +++ b/src/Enc.cpp @@ -3,12 +3,12 @@ /// #include "Security/Enc.h" #include "Settings.h" +#include "CustomAssert.h" //#include #include "Logger.h" #include #include #include -#include int Rand(){ std::random_device r; @@ -87,7 +87,7 @@ int Dec(int value,int d,int n){ #ifdef WIN32 int Handle(EXCEPTION_POINTERS *ep,char* Origin){ - assert(false); + Assert\(false); std::stringstream R; R << Sec("Code : ") << std::hex << ep->ExceptionRecord->ExceptionCode diff --git a/src/Init/Config.cpp b/src/Init/Config.cpp index 3d91176..0c2d294 100644 --- a/src/Init/Config.cpp +++ b/src/Init/Config.cpp @@ -3,7 +3,7 @@ /// #include "Security/Enc.h" #include "Logger.h" -#include "Assert.h" +#include "CustomAssert.h" #include #include #include diff --git a/src/Network/Http.cpp b/src/Network/Http.cpp index b46e5c2..d2fd184 100644 --- a/src/Network/Http.cpp +++ b/src/Network/Http.cpp @@ -3,7 +3,7 @@ /// #define CURL_STATICLIB #include "Curl/curl.h" -#include "Assert.h" +#include "CustomAssert.h" #include static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp){ ((std::string*)userp)->append((char*)contents, size * nmemb); diff --git a/src/main.cpp b/src/main.cpp index 1b74071..d6067a2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,5 @@ #include "Startup.h" -#include "Assert.h" +#include "CustomAssert.h" #include #include [[noreturn]] void loop(){ From ddd9c55822731b4449a012a32247686de9ed7f3b Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Tue, 3 Nov 2020 12:12:27 +0100 Subject: [PATCH 14/30] Disable _s warnings on msvc --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d777da4..28295fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,8 @@ elseif (WIN32) # completely cross platform. For fixes to common issues arising from /permissive- visit: # https://docs.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /permissive-") + # disables warnings about _s variants of stdc functions + add_definitions(_CRT_SECURE_NO_DEPRECATE _CRT_NONSTDC_NO_DEPRECATE) endif () find_package(Boost 1.71.0 REQUIRED COMPONENTS system thread) From f144d451c7add38ed6505a163f63e33dd07c1cbf Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Tue, 3 Nov 2020 12:14:19 +0100 Subject: [PATCH 15/30] Fixup --- src/Enc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Enc.cpp b/src/Enc.cpp index a7affa0..de73730 100644 --- a/src/Enc.cpp +++ b/src/Enc.cpp @@ -87,7 +87,7 @@ int Dec(int value,int d,int n){ #ifdef WIN32 int Handle(EXCEPTION_POINTERS *ep,char* Origin){ - Assert\(false); + Assert(false); std::stringstream R; R << Sec("Code : ") << std::hex << ep->ExceptionRecord->ExceptionCode From c5c21c43ad8a6ac68f8c37a03c61bc12bb5264f7 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Tue, 3 Nov 2020 12:50:05 +0100 Subject: [PATCH 16/30] Implement various WIN32 fixes --- include/CustomAssert.h | 22 +++++++--------------- src/Network/Auth.cpp | 12 +++++++++--- src/Network/Sync.cpp | 19 +++++++++++++------ src/Network/TCPHandler.cpp | 11 +++++++++-- src/Network/VehicleData.cpp | 12 ++++++++++-- 5 files changed, 48 insertions(+), 28 deletions(-) diff --git a/include/CustomAssert.h b/include/CustomAssert.h index f0f8bde..008e00d 100644 --- a/include/CustomAssert.h +++ b/include/CustomAssert.h @@ -44,23 +44,15 @@ inline void _assert([[maybe_unused]] const char* file, [[maybe_unused]] const ch [[maybe_unused]] const char* condition_string, [[maybe_unused]] bool result) { if (!result) { #if DEBUG - std::stringstream ss; - ss << std::this_thread::get_id(); - fprintf(stdout, - "(debug build) TID %s: %sASSERTION FAILED%s at %s%s:%u%s in \n\t-> in %s%s%s, Line %u: \n\t\t-> " - "Failed Condition: %s%s%s\n", - ss.str().c_str(), ANSI_RED_BOLD, ANSI_RESET, ANSI_UNDERLINE, file, line, ANSI_RESET, - ANSI_BOLD, function, ANSI_RESET, line, ANSI_RED, condition_string, - ANSI_RESET); - fprintf(stdout, "%s... terminating with SIGABRT ...%s\n", ANSI_BOLD, ANSI_RESET); + std::cout << std::flush << "(debug build) TID " + << std::this_thread::get_id() << ": ASSERTION FAILED: at " + << file << ":" << line << " \n\t-> in " + << function << ", Line " << line << ": \n\t\t-> " + << "Failed Condition: " << condition_string << std::endl; + std::cout << "... terminating ..." << std::endl; abort(); #else - char buf[2048]; - sprintf(buf, - "%s=> ASSERTION `%s` FAILED IN RELEASE BUILD%s%s -> IGNORING FAILED ASSERTION " - "& HOPING IT WON'T CRASH%s", - ANSI_RED_BOLD, condition_string, ANSI_RESET, ANSI_RED, ANSI_RESET); - error(buf); + std::cout << "Assertion '" << condition_string << "' failed, ignoring in release build" << std::endl; #endif } } diff --git a/src/Network/Auth.cpp b/src/Network/Auth.cpp index 6bf96e9..601ac59 100644 --- a/src/Network/Auth.cpp +++ b/src/Network/Auth.cpp @@ -17,8 +17,14 @@ struct Hold{ bool Done = false; }; bool Send(SOCKET TCPSock,std::string Data){ - ssize_t BytesSent; - BytesSent = send(TCPSock, Data.c_str(), size_t(Data.size()), 0); +#ifdef WIN32 + int BytesSent; + int len = static_cast(Data.size()); +#else + int64_t BytesSent; + size_t len = Data.size(); +#endif // WIN32 + BytesSent = send(TCPSock, Data.c_str(), len, 0); Data.clear(); if (BytesSent <= 0)return false; return true; @@ -27,7 +33,7 @@ std::string Rcv(SOCKET TCPSock){ char buf[6768]; size_t len = 6768; ZeroMemory(buf, len); - ssize_t BytesRcv = recv(TCPSock, buf, len,0); + int64_t BytesRcv = recv(TCPSock, buf, len,0); if (BytesRcv <= 0)return ""; return std::string(buf); } diff --git a/src/Network/Sync.cpp b/src/Network/Sync.cpp index 75d5018..17da7d1 100644 --- a/src/Network/Sync.cpp +++ b/src/Network/Sync.cpp @@ -17,7 +17,14 @@ void STCPSend(Client* c, std::string Data) { Assert(c); if (c == nullptr) return; - ssize_t BytesSent = send(c->GetTCPSock(), Data.c_str(), size_t(Data.size()), 0); +#ifdef WIN32 + int BytesSent; + int len = static_cast(Data.size()); +#else + int64_t BytesSent; + size_t len = Data.size(); +#endif // WIN32 + BytesSent = send(c->GetTCPSock(), Data.c_str(), len, 0); Data.clear(); if (BytesSent == 0) { if (c->GetStatus() > -1) @@ -42,19 +49,19 @@ void SendFile(Client* c, const std::string& Name) { size_t Size = size_t(fileSize); size_t Sent = 0; size_t Diff; - ssize_t Split = 64000; + int64_t Split = 64000; while (c->GetStatus() > -1 && Sent < Size) { Diff = Size - Sent; if (Diff > size_t(Split)) { std::string Data(size_t(Split), 0); - f.seekg(ssize_t(Sent), std::ios_base::beg); + f.seekg(int64_t(Sent), std::ios_base::beg); f.read(&Data[0], Split); STCPSend(c, Data); Sent += size_t(Split); } else { std::string Data(Diff, 0); - f.seekg(ssize_t(Sent), std::ios_base::beg); - f.read(&Data[0], ssize_t(Diff)); + f.seekg(int64_t(Sent), std::ios_base::beg); + f.read(&Data[0], int64_t(Diff)); STCPSend(c, Data); Sent += Diff; } @@ -93,7 +100,7 @@ bool STCPRecv(Client* c) { char buf[200]; size_t len = 200; ZeroMemory(buf, len); - ssize_t BytesRcv = recv(c->GetTCPSock(), buf, len, 0); + int64_t BytesRcv = recv(c->GetTCPSock(), buf, len, 0); if (BytesRcv == 0) { if (c->GetStatus() > -1) c->SetStatus(-1); diff --git a/src/Network/TCPHandler.cpp b/src/Network/TCPHandler.cpp index 5b80a07..2c8914e 100644 --- a/src/Network/TCPHandler.cpp +++ b/src/Network/TCPHandler.cpp @@ -11,7 +11,14 @@ void TCPSend(Client*c,const std::string&Data){ Assert(c); if(c == nullptr)return; std::string Send = "\n" + Data.substr(0,Data.find(char(0))) + "\n"; - ssize_t Sent = send(c->GetTCPSock(), Send.c_str(), size_t(Send.size()), 0); +#ifdef WIN32 + int Sent; + int len = static_cast(Send.size()); +#else + int64_t Sent; + size_t len = Send.size(); +#endif // WIN32 + Sent = send(c->GetTCPSock(), Send.c_str(), len, 0); if (Sent == 0){ if(c->GetStatus() > -1)c->SetStatus(-1); }else if (Sent < 0) { @@ -37,7 +44,7 @@ void TCPRcv(Client*c){ char buf[4096]; size_t len = 4096; ZeroMemory(buf, len); - ssize_t BytesRcv = recv(c->GetTCPSock(), buf, len,0); + int64_t BytesRcv = recv(c->GetTCPSock(), buf, len,0); if (BytesRcv == 0){ debug(Sec("(TCP) Connection closing...")); if(c->GetStatus() > -1)c->SetStatus(-1); diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index 14bd246..29aa3ef 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -42,7 +42,15 @@ void UDPSend(Client* c, std::string Data) { std::string CMP(Comp(Data)); Data = "ABG:" + CMP; } - ssize_t sendOk = sendto(UDPSock, Data.c_str(), Data.size(), 0, (sockaddr*)&Addr, AddrSize); +#ifdef WIN32 + int sendOk; + int len = static_cast(Data.size()); +#else + int64_t sendOk; + size_t len = Data.size(); +#endif // WIN32 + + sendOk = sendto(UDPSock, Data.c_str(), len, 0, (sockaddr*)&Addr, AddrSize); #ifdef WIN32 if (sendOk != 0) { debug(Sec("(UDP) Send Failed Code : ") + std::to_string(WSAGetLastError())); @@ -166,7 +174,7 @@ std::string UDPRcvFromClient(sockaddr_in& client) { size_t clientLength = sizeof(client); ZeroMemory(&client, clientLength); std::string Ret(10240, 0); - ssize_t Rcv = recvfrom(UDPSock, &Ret[0], 10240, 0, (sockaddr*)&client, (socklen_t*)&clientLength); + int64_t Rcv = recvfrom(UDPSock, &Ret[0], 10240, 0, (sockaddr*)&client, (socklen_t*)&clientLength); if (Rcv == -1) { #ifdef WIN32 error(Sec("(UDP) Error receiving from Client! Code : ") + std::to_string(WSAGetLastError())); From 9bae1554398aa9ae27fa6c7ea66c5c08aa6323c6 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Tue, 3 Nov 2020 12:53:19 +0100 Subject: [PATCH 17/30] dont assert at all in release mode --- include/CustomAssert.h | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/include/CustomAssert.h b/include/CustomAssert.h index 008e00d..7144ddd 100644 --- a/include/CustomAssert.h +++ b/include/CustomAssert.h @@ -40,10 +40,10 @@ static const char* const ANSI_WHITE_BOLD = "\u001b[37;1m"; static const char* const ANSI_BOLD = "\u001b[1m"; static const char* const ANSI_UNDERLINE = "\u001b[4m"; +#if DEBUG inline void _assert([[maybe_unused]] const char* file, [[maybe_unused]] const char* function, [[maybe_unused]] unsigned line, [[maybe_unused]] const char* condition_string, [[maybe_unused]] bool result) { if (!result) { -#if DEBUG std::cout << std::flush << "(debug build) TID " << std::this_thread::get_id() << ": ASSERTION FAILED: at " << file << ":" << line << " \n\t-> in " @@ -51,13 +51,17 @@ inline void _assert([[maybe_unused]] const char* file, [[maybe_unused]] const ch << "Failed Condition: " << condition_string << std::endl; std::cout << "... terminating ..." << std::endl; abort(); -#else - std::cout << "Assertion '" << condition_string << "' failed, ignoring in release build" << std::endl; -#endif } } -#ifndef ASSERT #define Assert(cond) _assert(__FILE__, __func__, __LINE__, #cond, (cond)) -#endif // ASSERT #define AssertNotReachable() _assert(__FILE__, __func__, __LINE__, "reached unreachable code", false) +#else +// In release build, these macros turn into NOPs. The compiler will optimize these out. +#define Assert(x) \ + do { \ + } while (false) +#define AssertNotReachable() \ + do { \ + } while (false) +#endif // DEBUG From 2beff2495f8c63fdaf2e4a05071ef71ad241a13e Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Tue, 3 Nov 2020 13:41:23 +0100 Subject: [PATCH 18/30] Fix backspace behavior, random printing of > --- src/Console.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Console.cpp b/src/Console.cpp index 5dd99db..3103da4 100644 --- a/src/Console.cpp +++ b/src/Console.cpp @@ -31,6 +31,7 @@ void HandleInput(const std::string& cmd){ void ProcessOut(){ static size_t len = 2; if(QConsoleOut.empty() && len == CInputBuff.length())return; + printf("%c[2K\r", 27); for(const std::string& msg : QConsoleOut) if(!msg.empty())std::cout << msg; MLock.lock(); @@ -120,7 +121,6 @@ void SetupConsole(){ HandleInput(CInputBuff); CInputBuff.clear(); }else { - printf("%c[2K\r", 27); CInputBuff += char(In); } } From 5452aeb5586bfeaa8a35719d51eeaa09d5e3d779 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Wed, 4 Nov 2020 11:58:09 +0100 Subject: [PATCH 19/30] Fix race condition in debug build printing --- include/Logger.h | 4 +++- src/Console.cpp | 57 +++++++++++++++++++++++--------------------- src/logger.cpp | 62 ++++++++++++++++++++++++++++-------------------- 3 files changed, 69 insertions(+), 54 deletions(-) diff --git a/include/Logger.h b/include/Logger.h index fa05349..93d4e48 100644 --- a/include/Logger.h +++ b/include/Logger.h @@ -2,8 +2,10 @@ /// Created by Anonymous275 on 4/2/2020. /// #pragma once -#include #include +#include +#include +extern std::mutex MLock; void InitLog(); #define DebugPrintTID() DebugPrintTIDInternal(__func__) void DebugPrintTIDInternal(const std::string& func); // prints the current thread id in debug mode, to make tracing of crashes and asserts easier diff --git a/src/Console.cpp b/src/Console.cpp index 3103da4..4d9ec44 100644 --- a/src/Console.cpp +++ b/src/Console.cpp @@ -4,8 +4,8 @@ #include "Lua/LuaSystem.hpp" #ifdef WIN32 -#include #include +#include #else // *nix typedef unsigned long DWORD, *PDWORD, *LPDWORD; #include @@ -13,27 +13,30 @@ typedef unsigned long DWORD, *PDWORD, *LPDWORD; #endif // WIN32 #include "Logger.h" #include +#include #include #include -#include std::vector QConsoleOut; std::string CInputBuff; std::mutex MLock; Lua* LuaConsole; -void HandleInput(const std::string& cmd){ +void HandleInput(const std::string& cmd) { std::cout << std::endl; if (cmd == "exit") { exit(0); - }else LuaConsole->Execute(cmd); + } else + LuaConsole->Execute(cmd); } -void ProcessOut(){ +void ProcessOut() { static size_t len = 2; - if(QConsoleOut.empty() && len == CInputBuff.length())return; + if (QConsoleOut.empty() && len == CInputBuff.length()) + return; printf("%c[2K\r", 27); - for(const std::string& msg : QConsoleOut) - if(!msg.empty())std::cout << msg; + for (const std::string& msg : QConsoleOut) + if (!msg.empty()) + std::cout << msg; MLock.lock(); QConsoleOut.clear(); MLock.unlock(); @@ -41,55 +44,54 @@ void ProcessOut(){ len = CInputBuff.length(); } -void ConsoleOut(const std::string& msg){ +void ConsoleOut(const std::string& msg) { MLock.lock(); QConsoleOut.emplace_back(msg); MLock.unlock(); } -[[noreturn]] void OutputRefresh(){ +[[noreturn]] void OutputRefresh() { DebugPrintTID(); - while(true){ + while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); ProcessOut(); } } #ifndef WIN32 -static int _getch() -{ +static int _getch() { char buf = 0; struct termios old; fflush(stdout); - if(tcgetattr(0, &old) < 0) + if (tcgetattr(0, &old) < 0) perror("tcsetattr()"); old.c_lflag &= ~unsigned(ICANON); old.c_lflag &= ~unsigned(ECHO); old.c_cc[VMIN] = 1; old.c_cc[VTIME] = 0; - if(tcsetattr(0, TCSANOW, &old) < 0) + if (tcsetattr(0, TCSANOW, &old) < 0) perror("tcsetattr ICANON"); - if(read(0, &buf, 1) < 0) + if (read(0, &buf, 1) < 0) perror("read()"); old.c_lflag |= ICANON; old.c_lflag |= ECHO; - if(tcsetattr(0, TCSADRAIN, &old) < 0) + if (tcsetattr(0, TCSADRAIN, &old) < 0) perror("tcsetattr ~ICANON"); // no echo printf("%c\n", buf); return buf; } #endif // WIN32 -void SetupConsole(){ +void SetupConsole() { #ifdef WIN32 DWORD outMode = 0; HANDLE stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); - if (stdoutHandle == INVALID_HANDLE_VALUE){ + if (stdoutHandle == INVALID_HANDLE_VALUE) { error("Invalid handle"); std::this_thread::sleep_for(std::chrono::seconds(3)); exit(GetLastError()); } - if (!GetConsoleMode(stdoutHandle, &outMode)){ + if (!GetConsoleMode(stdoutHandle, &outMode)) { error("Invalid console mode"); std::this_thread::sleep_for(std::chrono::seconds(3)); exit(GetLastError()); @@ -105,27 +107,28 @@ void SetupConsole(){ #endif // WIN32 } -[[noreturn]] void ReadCin(){ +[[noreturn]] void ReadCin() { DebugPrintTID(); - while (true){ + while (true) { int In = _getch(); if (In == 13 || In == '\n') { - if(!CInputBuff.empty()) { + if (!CInputBuff.empty()) { HandleInput(CInputBuff); CInputBuff.clear(); } - }else if(In == 8){ - if(!CInputBuff.empty())CInputBuff.pop_back(); + } else if (In == 8) { + if (!CInputBuff.empty()) + CInputBuff.pop_back(); } else if (In == 4) { CInputBuff = "exit"; HandleInput(CInputBuff); CInputBuff.clear(); - }else { + } else { CInputBuff += char(In); } } } -void ConsoleInit(){ +void ConsoleInit() { SetupConsole(); LuaConsole = new Lua(); LuaConsole->Console = true; diff --git a/src/logger.cpp b/src/logger.cpp index 357ebf4..5b9e99a 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -1,20 +1,23 @@ /// /// Created by Anonymous275 on 7/17/2020 /// +#include "Logger.h" #include "Security/Enc.h" #include "Settings.h" -#include "Logger.h" -#include -#include #include +#include #include +#include #include void DebugPrintTIDInternal(const std::string& func) { // we need to print to cout here as we might crash before all console output is handled, // due to segfaults or asserts. #ifdef DEBUG + MLock.lock(); + printf("%c[2K\r", 27); std::cout << "(debug build) Thread '" << std::this_thread::get_id() << "' is " << func << std::endl; + MLock.unlock(); #endif // DEBUG } @@ -22,14 +25,18 @@ std::string getDate() { typedef std::chrono::duration>::type> days; std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); std::chrono::system_clock::duration tp = now.time_since_epoch(); - days d = std::chrono::duration_cast(tp);tp -= d; - auto h = std::chrono::duration_cast(tp);tp -= h; - auto m = std::chrono::duration_cast(tp);tp -= m; - auto s = std::chrono::duration_cast(tp);tp -= s; + days d = std::chrono::duration_cast(tp); + tp -= d; + auto h = std::chrono::duration_cast(tp); + tp -= h; + auto m = std::chrono::duration_cast(tp); + tp -= m; + auto s = std::chrono::duration_cast(tp); + tp -= s; time_t tt = std::chrono::system_clock::to_time_t(now); - tm local_tm{}; + tm local_tm {}; #ifdef WIN32 - localtime_s(&local_tm,&tt); + localtime_s(&local_tm, &tt); #else // unix localtime_r(&tt, &local_tm); #endif // WIN32 @@ -41,27 +48,28 @@ 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 (Sec("Server.log")); - if(!LFS.is_open()){ + LFS.open(Sec("Server.log")); + if (!LFS.is_open()) { error(Sec("logger file init failed!")); - }else LFS.close(); + } else + LFS.close(); } std::mutex LogLock; -void addToLog(const std::string& Line){ +void addToLog(const std::string& Line) { std::ofstream LFS; - LFS.open (Sec("Server.log"), std::ios_base::app); + LFS.open(Sec("Server.log"), std::ios_base::app); LFS << Line.c_str(); LFS.close(); } @@ -73,14 +81,15 @@ void info(const std::string& toPrint) { LogLock.unlock(); } void debug(const std::string& toPrint) { - if(!Debug)return; + if (!Debug) + return; LogLock.lock(); std::string Print = getDate() + Sec("[DEBUG] ") + toPrint + "\n"; ConsoleOut(Print); addToLog(Print); LogLock.unlock(); } -void warn(const std::string& toPrint){ +void warn(const std::string& toPrint) { LogLock.lock(); std::string Print = getDate() + Sec("[WARN] ") + toPrint + "\n"; ConsoleOut(Print); @@ -93,7 +102,8 @@ void error(const std::string& toPrint) { std::string Print = getDate() + Sec("[ERROR] ") + toPrint + "\n"; ConsoleOut(Print); addToLog(Print); - if(ECounter > 10)exit(7); + if (ECounter > 10) + exit(7); ECounter++; LogLock.unlock(); } From f2d87078ae650e40d607b2cbc7514cd041b92172 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Wed, 4 Nov 2020 13:10:45 +0100 Subject: [PATCH 20/30] Fix various memory leaks with RAII --- include/Lua/LuaSystem.hpp | 80 ++-- src/Console.cpp | 4 +- src/Lua/LuaMain.cpp | 76 ++-- src/Lua/LuaSystem.cpp | 760 +++++++++++++++++++++----------------- 4 files changed, 512 insertions(+), 408 deletions(-) diff --git a/include/Lua/LuaSystem.hpp b/include/Lua/LuaSystem.hpp index 22e7e75..2d2bea9 100644 --- a/include/Lua/LuaSystem.hpp +++ b/include/Lua/LuaSystem.hpp @@ -3,66 +3,76 @@ /// #pragma once +#include "lua.hpp" +#include #include #include -#include "lua.hpp" -#include -#include #include +#include #include -#include +#include +#include namespace fs = std::filesystem; -struct LuaArg{ +struct LuaArg { std::vector args; - void PushArgs(lua_State *State){ - for(std::any arg : args){ - if(!arg.has_value())return; + void PushArgs(lua_State* State) { + for (std::any arg : args) { + if (!arg.has_value()) + return; std::string Type = arg.type().name(); - if(Type.find("bool") != std::string::npos){ - lua_pushboolean(State,std::any_cast(arg)); + if (Type.find("bool") != std::string::npos) { + lua_pushboolean(State, std::any_cast(arg)); } - if(Type.find("basic_string") != std::string::npos || Type.find("char") != std::string::npos){ - lua_pushstring(State,std::any_cast(arg).c_str()); + if (Type.find("basic_string") != std::string::npos || Type.find("char") != std::string::npos) { + lua_pushstring(State, std::any_cast(arg).c_str()); } - if(Type.find("int") != std::string::npos){ - lua_pushinteger(State,std::any_cast(arg)); + if (Type.find("int") != std::string::npos) { + lua_pushinteger(State, std::any_cast(arg)); } - if(Type.find("float") != std::string::npos){ lua_pushnumber(State,std::any_cast(arg)); + if (Type.find("float") != std::string::npos) { + lua_pushnumber(State, std::any_cast(arg)); } - } + } } }; class Lua { private: - std::set> RegisteredEvents; - lua_State *luaState = luaL_newstate(); - fs::file_time_type LastWrote; - std::string PluginName; - std::string FileName; + std::set> _RegisteredEvents; + lua_State* luaState { nullptr }; + fs::file_time_type _LastWrote; + std::string _PluginName; + std::string _FileName; + bool _StopThread = false; + bool _Console = false; + // this is called by the ctor to ensure RAII + void Init(); public: - void RegisterEvent(const std::string&Event,const std::string&FunctionName); - std::string GetRegistered(const std::string&Event); - void UnRegisterEvent(const std::string&Event); + void RegisterEvent(const std::string& Event, const std::string& FunctionName); + std::string GetRegistered(const std::string& Event) const; + void UnRegisterEvent(const std::string& Event); void SetLastWrite(fs::file_time_type time); - bool IsRegistered(const std::string&Event); - void SetPluginName(const std::string&Name); + bool IsRegistered(const std::string& Event); + void SetPluginName(const std::string& Name); void Execute(const std::string& Command); - void SetFileName(const std::string&Name); + void SetFileName(const std::string& Name); fs::file_time_type GetLastWrite(); - std::string GetPluginName(); - std::string GetFileName(); - bool StopThread = false; - bool Console = false; + std::string GetPluginName() const; + std::string GetFileName() const; lua_State* GetState(); + const lua_State* GetState() const; char* GetOrigin(); std::mutex Lock; void Reload(); - void Init(); + Lua(const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote, bool Console = false); + Lua(bool Console = false); + ~Lua(); + void SetStopThread(bool StopThread) { _StopThread = StopThread; } + bool GetStopThread() const { return _StopThread; } }; -int CallFunction(Lua*lua,const std::string& FuncName,LuaArg* args); -int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller,LuaArg* arg,bool Wait); -extern std::set PluginEngine; +int CallFunction(Lua* lua, const std::string& FuncName, LuaArg* args); +int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, LuaArg* arg, bool Wait); +extern std::set> PluginEngine; diff --git a/src/Console.cpp b/src/Console.cpp index 4d9ec44..91c27f9 100644 --- a/src/Console.cpp +++ b/src/Console.cpp @@ -130,9 +130,7 @@ void SetupConsole() { } void ConsoleInit() { SetupConsole(); - LuaConsole = new Lua(); - LuaConsole->Console = true; - LuaConsole->Init(); + LuaConsole = new Lua(true); printf("> "); std::thread In(ReadCin); In.detach(); diff --git a/src/Lua/LuaMain.cpp b/src/Lua/LuaMain.cpp index 0ec5687..5d9f706 100644 --- a/src/Lua/LuaMain.cpp +++ b/src/Lua/LuaMain.cpp @@ -2,10 +2,10 @@ /// Created by Anonymous275 on 5/20/2020 /// +#include "Logger.h" #include "Lua/LuaSystem.hpp" #include "Security/Enc.h" #include "Settings.h" -#include "Logger.h" #include #ifdef __linux @@ -13,75 +13,73 @@ #include #endif // __linux -std::set PluginEngine; -bool NewFile(const std::string&Path){ - for(Lua*Script : PluginEngine){ - if(Path == Script->GetFileName())return false; +std::set> PluginEngine; +bool NewFile(const std::string& Path) { + for (auto& Script : PluginEngine) { + if (Path == Script->GetFileName()) + return false; } return true; } -void RegisterFiles(const std::string& Path,bool HotSwap){ - std::string Name = Path.substr(Path.find_last_of('\\')+1); - if(!HotSwap)info(Sec("Loading plugin : ") + Name); - for (const auto &entry : fs::directory_iterator(Path)){ +void RegisterFiles(const std::string& Path, bool HotSwap) { + std::string Name = Path.substr(Path.find_last_of('\\') + 1); + if (!HotSwap) + info(Sec("Loading plugin : ") + Name); + for (const auto& entry : fs::directory_iterator(Path)) { auto pos = entry.path().string().find(Sec(".lua")); if (pos != std::string::npos && entry.path().string().length() - pos == 4) { - if(!HotSwap || NewFile(entry.path().string())){ - Lua *Script = new Lua(); - PluginEngine.insert(Script); - Script->SetFileName(entry.path().string()); - Script->SetPluginName(Name); - Script->SetLastWrite(fs::last_write_time(Script->GetFileName())); - Script->Init(); - if(HotSwap)info(Sec("[HOTSWAP] Added : ") + - Script->GetFileName().substr(Script->GetFileName().find('\\'))); + if (!HotSwap || NewFile(entry.path().string())) { + auto FileName = entry.path().string(); + std::unique_ptr ScriptToInsert(new Lua(Name, FileName, fs::last_write_time(FileName))); + auto& Script = *ScriptToInsert; + PluginEngine.insert(std::move(ScriptToInsert)); + if (HotSwap) + info(Sec("[HOTSWAP] Added : ") + Script.GetFileName().substr(Script.GetFileName().find('\\'))); } } } } -void FolderList(const std::string& Path,bool HotSwap){ - for (const auto &entry : fs::directory_iterator(Path)) { +void FolderList(const std::string& Path, bool HotSwap) { + for (const auto& entry : fs::directory_iterator(Path)) { auto pos = entry.path().filename().string().find('.'); if (pos == std::string::npos) { - RegisterFiles(entry.path().string(),HotSwap); + RegisterFiles(entry.path().string(), HotSwap); } } } -[[noreturn]]void HotSwaps(const std::string& path){ +[[noreturn]] void HotSwaps(const std::string& path) { DebugPrintTID(); - while(true){ - for(Lua*Script : PluginEngine){ - struct stat Info{}; - if(stat(Script->GetFileName().c_str(), &Info) != 0){ - Script->StopThread = true; + while (true) { + for (auto& Script : PluginEngine) { + struct stat Info {}; + if (stat(Script->GetFileName().c_str(), &Info) != 0) { + Script->SetStopThread(true); PluginEngine.erase(Script); - info(Sec("[HOTSWAP] Removed : ")+ - Script->GetFileName().substr(Script->GetFileName().find('\\'))); + info(Sec("[HOTSWAP] Removed : ") + Script->GetFileName().substr(Script->GetFileName().find('\\'))); break; } - if(Script->GetLastWrite() != fs::last_write_time(Script->GetFileName())){ - Script->StopThread = true; - info(Sec("[HOTSWAP] Updated : ")+ - Script->GetFileName().substr(Script->GetFileName().find('\\'))); + if (Script->GetLastWrite() != fs::last_write_time(Script->GetFileName())) { + Script->SetStopThread(true); + info(Sec("[HOTSWAP] Updated : ") + Script->GetFileName().substr(Script->GetFileName().find('\\'))); Script->SetLastWrite(fs::last_write_time(Script->GetFileName())); Script->Reload(); } } - FolderList(path,true); + FolderList(path, true); std::this_thread::sleep_for(std::chrono::seconds(2)); } } -void InitLua(){ - if(!fs::exists(Resource)){ +void InitLua() { + if (!fs::exists(Resource)) { fs::create_directory(Resource); } std::string Path = Resource + Sec("/Server"); - if(!fs::exists(Path)){ + if (!fs::exists(Path)) { fs::create_directory(Path); } - FolderList(Path,false); - std::thread t1(HotSwaps,Path); + FolderList(Path, false); + std::thread t1(HotSwaps, Path); t1.detach(); info(Sec("Lua system online")); } diff --git a/src/Lua/LuaSystem.cpp b/src/Lua/LuaSystem.cpp index 6fc500b..4e36506 100644 --- a/src/Lua/LuaSystem.cpp +++ b/src/Lua/LuaSystem.cpp @@ -3,511 +3,570 @@ /// #include "Lua/LuaSystem.hpp" -#include "Security/Enc.h" #include "Client.hpp" -#include "Settings.h" -#include "Network.h" #include "Logger.h" +#include "Network.h" +#include "Security/Enc.h" +#include "Settings.h" #include "UnixCompat.h" -#include #include +#include #include -LuaArg* CreateArg(lua_State *L,int T,int S){ - if(S > T)return nullptr; +LuaArg* CreateArg(lua_State* L, int T, int S) { + if (S > T) + return nullptr; auto* temp = new LuaArg; - for(int C = S;C <= T;C++){ - if(lua_isstring(L,C)){ - temp->args.emplace_back(std::string(lua_tostring(L,C))); - }else if(lua_isinteger(L,C)){ - temp->args.emplace_back(int(lua_tointeger(L,C))); - }else if(lua_isboolean(L,C)){ - temp->args.emplace_back(bool(lua_toboolean(L,C))); - }else if(lua_isnumber(L,C)) { + for (int C = S; C <= T; C++) { + if (lua_isstring(L, C)) { + temp->args.emplace_back(std::string(lua_tostring(L, C))); + } else if (lua_isinteger(L, C)) { + temp->args.emplace_back(int(lua_tointeger(L, C))); + } else if (lua_isboolean(L, C)) { + temp->args.emplace_back(bool(lua_toboolean(L, C))); + } else if (lua_isnumber(L, C)) { temp->args.emplace_back(float(lua_tonumber(L, C))); } } return temp; } -void ClearStack(lua_State *L){ - lua_settop(L,0); +void ClearStack(lua_State* L) { + lua_settop(L, 0); } -Lua* GetScript(lua_State *L){ - for(Lua*Script : PluginEngine){ - if (Script->GetState() == L)return Script; +std::optional> GetScript(lua_State* L) { + for (auto& Script : PluginEngine) { + if (Script->GetState() == L) + return *Script; } - return nullptr; + return std::nullopt; } -void SendError(lua_State *L,const std::string&msg){ - Lua* S = GetScript(L); +void SendError(lua_State* L, const std::string& msg) { + Assert(L); + auto MaybeS = GetScript(L); std::string a; - if(S == nullptr)a = Sec("Console"); - else a = S->GetFileName().substr(S->GetFileName().find('\\')); + if (!MaybeS.has_value()) { + a = Sec("_Console"); + } else { + Lua& S = MaybeS.value(); + a = S.GetFileName().substr(S.GetFileName().find('\\')); + } warn(a + Sec(" | Incorrect Call of ") + msg); } -int Trigger(Lua*lua,const std::string& R, LuaArg*arg){ +int Trigger(Lua* lua, const std::string& R, LuaArg* arg) { std::lock_guard lockGuard(lua->Lock); - std::packaged_task task([lua,R,arg]{return CallFunction(lua,R,arg);}); + std::packaged_task task([lua, R, arg] { return CallFunction(lua, R, arg); }); std::future f1 = task.get_future(); std::thread t(std::move(task)); t.detach(); auto status = f1.wait_for(std::chrono::seconds(5)); - if(status != std::future_status::timeout)return f1.get(); - SendError(lua->GetState(),R + " took too long to respond"); + if (status != std::future_status::timeout) + return f1.get(); + SendError(lua->GetState(), R + " took too long to respond"); return 0; } -int FutureWait(Lua*lua,const std::string& R, LuaArg*arg,bool Wait){ - std::packaged_task task([lua,R,arg]{return Trigger(lua,R,arg);}); +int FutureWait(Lua* lua, const std::string& R, LuaArg* arg, bool Wait) { + Assert(lua); + std::packaged_task task([lua, R, arg] { return Trigger(lua, R, arg); }); std::future f1 = task.get_future(); std::thread t(std::move(task)); t.detach(); int T = 0; - if(Wait)T = 6; + if (Wait) + T = 6; auto status = f1.wait_for(std::chrono::seconds(T)); - if(status != std::future_status::timeout)return f1.get(); + if (status != std::future_status::timeout) + return f1.get(); return 0; } -int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller,LuaArg* arg,bool Wait){ +int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, LuaArg* arg, bool Wait) { int R = 0; - for(Lua*Script : PluginEngine){ - if(Script->IsRegistered(Event)){ - if(local){ - if (Script->GetPluginName() == Caller->GetPluginName()){ - R += FutureWait(Script,Script->GetRegistered(Event),arg,Wait); + for (auto& Script : PluginEngine) { + if (Script->IsRegistered(Event)) { + if (local) { + if (Script->GetPluginName() == Caller->GetPluginName()) { + R += FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait); } - }else R += FutureWait(Script,Script->GetRegistered(Event), arg,Wait); + } else + R += FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait); } } return R; } -bool ConsoleCheck(lua_State *L, int r){ - if (r != LUA_OK){ +bool ConsoleCheck(lua_State* L, int r) { + if (r != LUA_OK) { std::string msg = lua_tostring(L, -1); - warn(Sec("Console | ") + msg); + warn(Sec("_Console | ") + msg); return false; } return true; } -bool CheckLua(lua_State *L, int r){ - if (r != LUA_OK){ +bool CheckLua(lua_State* L, int r) { + if (r != LUA_OK) { std::string msg = lua_tostring(L, -1); - Lua * S = GetScript(L); - std::string a = S->GetFileName().substr(S->GetFileName().find('\\')); - warn(a + " | " + msg); - return false; + auto MaybeS = GetScript(L); + if (MaybeS.has_value()) { + Lua& S = MaybeS.value(); + std::string a = S.GetFileName().substr(S.GetFileName().find('\\')); + warn(a + " | " + msg); + return false; + } + // What the fuck, what do we do?! + AssertNotReachable(); } return true; } -int lua_RegisterEvent(lua_State *L){ +int lua_RegisterEvent(lua_State* L) { int Args = lua_gettop(L); - Lua* Script = GetScript(L); - if(Args == 2 && lua_isstring(L,1) && lua_isstring(L,2)){ - Script->RegisterEvent(lua_tostring(L,1),lua_tostring(L,2)); - }else SendError(L,Sec("RegisterEvent invalid argument count expected 2 got ") + std::to_string(Args)); + auto MaybeScript = GetScript(L); + Assert(MaybeScript.has_value()); + Lua& Script = MaybeScript.value(); + if (Args == 2 && lua_isstring(L, 1) && lua_isstring(L, 2)) { + Script.RegisterEvent(lua_tostring(L, 1), lua_tostring(L, 2)); + } else + SendError(L, Sec("RegisterEvent invalid argument count expected 2 got ") + std::to_string(Args)); return 0; } -int lua_TriggerEventL(lua_State *L){ +int lua_TriggerEventL(lua_State* L) { int Args = lua_gettop(L); - Lua* Script = GetScript(L); - if(Args > 0){ - if(lua_isstring(L,1)){ - TriggerLuaEvent(lua_tostring(L, 1), true, Script, CreateArg(L,Args,2),false); - }else SendError(L,Sec("TriggerLocalEvent wrong argument [1] need string")); - }else{ - SendError(L,Sec("TriggerLocalEvent not enough arguments expected 1 got 0")); + auto MaybeScript = GetScript(L); + Assert(MaybeScript.has_value()); + Lua& Script = MaybeScript.value(); + if (Args > 0) { + if (lua_isstring(L, 1)) { + TriggerLuaEvent(lua_tostring(L, 1), true, &Script, CreateArg(L, Args, 2), false); + } else + SendError(L, Sec("TriggerLocalEvent wrong argument [1] need string")); + } else { + SendError(L, Sec("TriggerLocalEvent not enough arguments expected 1 got 0")); } return 0; } -int lua_TriggerEventG(lua_State *L){ +int lua_TriggerEventG(lua_State* L) { int Args = lua_gettop(L); - Lua* Script = GetScript(L); - if(Args > 0){ - if(lua_isstring(L,1)) { - TriggerLuaEvent(lua_tostring(L, 1), false, Script, CreateArg(L,Args,2),false); - }else SendError(L,Sec("TriggerGlobalEvent wrong argument [1] need string")); - }else SendError(L,Sec("TriggerGlobalEvent not enough arguments")); + auto MaybeScript = GetScript(L); + Assert(MaybeScript.has_value()); + Lua& Script = MaybeScript.value(); + if (Args > 0) { + if (lua_isstring(L, 1)) { + TriggerLuaEvent(lua_tostring(L, 1), false, &Script, CreateArg(L, Args, 2), false); + } else + SendError(L, Sec("TriggerGlobalEvent wrong argument [1] need string")); + } else + SendError(L, Sec("TriggerGlobalEvent not enough arguments")); return 0; } -char* ThreadOrigin(Lua*lua){ +char* ThreadOrigin(Lua* lua) { std::string T = "Thread in " + lua->GetFileName().substr(lua->GetFileName().find('\\')); - char* Data = new char[T.size()+1]; - ZeroMemory(Data,T.size()+1); - memcpy(Data, T.c_str(),T.size()); + char* Data = new char[T.size() + 1]; + ZeroMemory(Data, T.size() + 1); + memcpy(Data, T.c_str(), T.size()); return Data; } -void SafeExecution(Lua* lua,const std::string& FuncName){ +void SafeExecution(Lua* lua, const std::string& FuncName) { lua_State* luaState = lua->GetState(); lua_getglobal(luaState, FuncName.c_str()); - if(lua_isfunction(luaState, -1)) { + if (lua_isfunction(luaState, -1)) { char* Origin = ThreadOrigin(lua); #ifdef WIN32 - __try{ - int R = lua_pcall(luaState, 0, 0, 0); - CheckLua(luaState, R); - }__except(Handle(GetExceptionInformation(),Origin)){} + __try { + int R = lua_pcall(luaState, 0, 0, 0); + CheckLua(luaState, R); + } __except (Handle(GetExceptionInformation(), Origin)) { + } #else // unix int R = lua_pcall(luaState, 0, 0, 0); CheckLua(luaState, R); #endif // WIN32 - delete [] Origin; + delete[] Origin; } ClearStack(luaState); } -void ExecuteAsync(Lua* lua,const std::string& FuncName){ +void ExecuteAsync(Lua* lua, const std::string& FuncName) { std::lock_guard lockGuard(lua->Lock); - SafeExecution(lua,FuncName); + SafeExecution(lua, FuncName); } -void CallAsync(Lua* lua,const std::string& Func,int U){ +void CallAsync(Lua* lua, const std::string& Func, int U) { DebugPrintTID(); - lua->StopThread = false; + lua->SetStopThread(false); int D = 1000 / U; - while(!lua->StopThread){ - ExecuteAsync(lua,Func); + while (!lua->GetStopThread()) { + ExecuteAsync(lua, Func); std::this_thread::sleep_for(std::chrono::milliseconds(D)); } } -int lua_StopThread(lua_State *L){ - GetScript(L)->StopThread = true; +int lua_StopThread(lua_State* L) { + auto MaybeScript = GetScript(L); + Assert(MaybeScript.has_value()); + // ugly, but whatever, this is safe as fuck + MaybeScript.value().get().SetStopThread(true); return 0; } -int lua_CreateThread(lua_State *L){ +int lua_CreateThread(lua_State* L) { int Args = lua_gettop(L); - if(Args > 1){ - if(lua_isstring(L,1)) { - std::string STR = lua_tostring(L,1); - if(lua_isinteger(L,2) || lua_isnumber(L,2)){ - int U = int(lua_tointeger(L,2)); - if(U > 0 && U < 501){ - std::thread t1(CallAsync,GetScript(L),STR,U); + if (Args > 1) { + if (lua_isstring(L, 1)) { + std::string STR = lua_tostring(L, 1); + if (lua_isinteger(L, 2) || lua_isnumber(L, 2)) { + int U = int(lua_tointeger(L, 2)); + if (U > 0 && U < 501) { + auto MaybeScript = GetScript(L); + Assert(MaybeScript.has_value()); + Lua& Script = MaybeScript.value(); + std::thread t1(CallAsync, &Script, STR, U); t1.detach(); - }else SendError(L,Sec("CreateThread wrong argument [2] number must be between 1 and 500")); - }else SendError(L,Sec("CreateThread wrong argument [2] need number")); - }else SendError(L,Sec("CreateThread wrong argument [1] need string")); - }else SendError(L,Sec("CreateThread not enough arguments")); + } else + SendError(L, Sec("CreateThread wrong argument [2] number must be between 1 and 500")); + } else + SendError(L, Sec("CreateThread wrong argument [2] need number")); + } else + SendError(L, Sec("CreateThread wrong argument [1] need string")); + } else + SendError(L, Sec("CreateThread not enough arguments")); return 0; } -int lua_Sleep(lua_State *L){ - if(lua_isnumber(L,1)){ +int lua_Sleep(lua_State* L) { + if (lua_isnumber(L, 1)) { int t = int(lua_tonumber(L, 1)); std::this_thread::sleep_for(std::chrono::milliseconds(t)); - }else{ - SendError(L,Sec("Sleep not enough arguments")); + } else { + SendError(L, Sec("Sleep not enough arguments")); return 0; } return 1; } -Client* GetClient(int ID){ - for(Client*c : CI->Clients) { - if(c != nullptr && c->GetID() == ID)return c; +Client* GetClient(int ID) { + for (Client* c : CI->Clients) { + if (c != nullptr && c->GetID() == ID) + return c; } return nullptr; } -int lua_isConnected(lua_State *L){ - if(lua_isnumber(L,1)){ +int lua_isConnected(lua_State* L) { + if (lua_isnumber(L, 1)) { int ID = int(lua_tonumber(L, 1)); - Client*c = GetClient(ID); - if(c != nullptr)lua_pushboolean(L, c->isConnected); - else return 0; - }else{ - SendError(L,Sec("isConnected not enough arguments")); + Client* c = GetClient(ID); + if (c != nullptr) + lua_pushboolean(L, c->isConnected); + else + return 0; + } else { + SendError(L, Sec("isConnected not enough arguments")); return 0; } return 1; } -int lua_GetPlayerName(lua_State *L){ - if(lua_isnumber(L,1)){ +int lua_GetPlayerName(lua_State* L) { + if (lua_isnumber(L, 1)) { int ID = int(lua_tonumber(L, 1)); - Client*c = GetClient(ID); - if(c != nullptr)lua_pushstring(L, c->GetName().c_str()); - else return 0; - }else{ - SendError(L,Sec("GetPlayerName not enough arguments")); + Client* c = GetClient(ID); + if (c != nullptr) + lua_pushstring(L, c->GetName().c_str()); + else + return 0; + } else { + SendError(L, Sec("GetPlayerName not enough arguments")); return 0; } return 1; } -int lua_GetPlayerCount(lua_State *L){ +int lua_GetPlayerCount(lua_State* L) { lua_pushinteger(L, CI->Size()); return 1; } -int lua_GetDID(lua_State *L){ - if(lua_isnumber(L,1)){ +int lua_GetDID(lua_State* L) { + if (lua_isnumber(L, 1)) { int ID = int(lua_tonumber(L, 1)); - Client*c = GetClient(ID); - if(c != nullptr)lua_pushstring(L, c->GetDID().c_str()); - else return 0; - }else{ - SendError(L,Sec("GetDID not enough arguments")); + Client* c = GetClient(ID); + if (c != nullptr) + lua_pushstring(L, c->GetDID().c_str()); + else + return 0; + } else { + SendError(L, Sec("GetDID not enough arguments")); return 0; } return 1; } -int lua_GetAllPlayers(lua_State *L){ +int lua_GetAllPlayers(lua_State* L) { lua_newtable(L); int i = 1; - for (Client *c : CI->Clients) { - if(c == nullptr)continue; + for (Client* c : CI->Clients) { + if (c == nullptr) + continue; lua_pushinteger(L, c->GetID()); lua_pushstring(L, c->GetName().c_str()); - lua_settable(L,-3); + lua_settable(L, -3); i++; } - if(CI->Clients.empty())return 0; + if (CI->Clients.empty()) + return 0; return 1; } -int lua_GetCars(lua_State *L){ - if(lua_isnumber(L,1)){ +int lua_GetCars(lua_State* L) { + if (lua_isnumber(L, 1)) { int ID = int(lua_tonumber(L, 1)); - Client*c = GetClient(ID); - if(c != nullptr){ + Client* c = GetClient(ID); + if (c != nullptr) { int i = 1; - for (VData*v : c->GetAllCars()) { - if(v != nullptr) { + for (VData* v : c->GetAllCars()) { + if (v != nullptr) { lua_pushinteger(L, v->ID); lua_pushstring(L, v->Data.substr(3).c_str()); lua_settable(L, -3); i++; } } - if(c->GetAllCars().empty())return 0; - }else return 0; - }else{ - SendError(L,Sec("GetPlayerVehicles not enough arguments")); + if (c->GetAllCars().empty()) + return 0; + } else + return 0; + } else { + SendError(L, Sec("GetPlayerVehicles not enough arguments")); return 0; } return 1; } -int lua_dropPlayer(lua_State *L){ +int lua_dropPlayer(lua_State* L) { int Args = lua_gettop(L); - if(lua_isnumber(L,1)){ + if (lua_isnumber(L, 1)) { int ID = int(lua_tonumber(L, 1)); - Client*c = GetClient(ID); - if(c == nullptr)return 0; - if(c->GetRole() == Sec("MDEV"))return 0; + Client* c = GetClient(ID); + if (c == nullptr) + return 0; + if (c->GetRole() == Sec("MDEV")) + return 0; std::string Reason; - if(Args > 1 && lua_isstring(L,2)){ - Reason = std::string(Sec(" Reason : "))+lua_tostring(L,2); + if (Args > 1 && lua_isstring(L, 2)) { + Reason = std::string(Sec(" Reason : ")) + lua_tostring(L, 2); } - Respond(c,"C:Server:You have been Kicked from the server! " + Reason,true); + Respond(c, "C:Server:You have been Kicked from the server! " + Reason, true); c->SetStatus(-2); closesocket(c->GetTCPSock()); - }else SendError(L,Sec("DropPlayer not enough arguments")); + } else + SendError(L, Sec("DropPlayer not enough arguments")); return 0; } -int lua_sendChat(lua_State *L){ - if(lua_isinteger(L,1) || lua_isnumber(L,1)){ - if(lua_isstring(L,2)){ - int ID = int(lua_tointeger(L,1)); - if(ID == -1){ +int lua_sendChat(lua_State* L) { + if (lua_isinteger(L, 1) || lua_isnumber(L, 1)) { + if (lua_isstring(L, 2)) { + int ID = int(lua_tointeger(L, 1)); + if (ID == -1) { std::string Packet = "C:Server: " + std::string(lua_tostring(L, 2)); - SendToAll(nullptr,Packet,true,true); - }else{ - Client*c = GetClient(ID); - if(c != nullptr) { - if(!c->isSynced)return 0; - std::string Packet ="C:Server: " + std::string(lua_tostring(L, 2)); + SendToAll(nullptr, Packet, true, true); + } else { + Client* c = GetClient(ID); + if (c != nullptr) { + if (!c->isSynced) + return 0; + std::string Packet = "C:Server: " + std::string(lua_tostring(L, 2)); Respond(c, Packet, true); - }else SendError(L,Sec("SendChatMessage invalid argument [1] invalid ID")); + } else + SendError(L, Sec("SendChatMessage invalid argument [1] invalid ID")); } - }else SendError(L,Sec("SendChatMessage invalid argument [2] expected string")); - }else SendError(L,Sec("SendChatMessage invalid argument [1] expected number")); + } else + SendError(L, Sec("SendChatMessage invalid argument [2] expected string")); + } else + SendError(L, Sec("SendChatMessage invalid argument [1] expected number")); return 0; } -int lua_RemoveVehicle(lua_State *L){ +int lua_RemoveVehicle(lua_State* L) { int Args = lua_gettop(L); - if(Args != 2){ - SendError(L,Sec("RemoveVehicle invalid argument count expected 2 got ") + std::to_string(Args)); + if (Args != 2) { + SendError(L, Sec("RemoveVehicle invalid argument count expected 2 got ") + std::to_string(Args)); return 0; } - if((lua_isinteger(L,1) || lua_isnumber(L,1)) && (lua_isinteger(L,2) || lua_isnumber(L,2))){ - int PID = int(lua_tointeger(L,1)); - int VID = int(lua_tointeger(L,2)); - Client *c = GetClient(PID); - if(c == nullptr){ - SendError(L,Sec("RemoveVehicle invalid Player ID")); + if ((lua_isinteger(L, 1) || lua_isnumber(L, 1)) && (lua_isinteger(L, 2) || lua_isnumber(L, 2))) { + int PID = int(lua_tointeger(L, 1)); + int VID = int(lua_tointeger(L, 2)); + Client* c = GetClient(PID); + if (c == nullptr) { + SendError(L, Sec("RemoveVehicle invalid Player ID")); return 0; } - if(c->GetRole() == "MDEV")return 0; - if(!c->GetCarData(VID).empty()){ - std::string Destroy = "Od:" + std::to_string(PID)+"-"+std::to_string(VID); - SendToAll(nullptr,Destroy,true,true); + if (c->GetRole() == "MDEV") + return 0; + if (!c->GetCarData(VID).empty()) { + std::string Destroy = "Od:" + std::to_string(PID) + "-" + std::to_string(VID); + SendToAll(nullptr, Destroy, true, true); c->DeleteCar(VID); } - }else SendError(L,Sec("RemoveVehicle invalid argument expected number")); + } else + SendError(L, Sec("RemoveVehicle invalid argument expected number")); return 0; } -int lua_HWID(lua_State *L){ +int lua_HWID(lua_State* L) { lua_pushinteger(L, -1); return 1; } -int lua_RemoteEvent(lua_State *L){ +int lua_RemoteEvent(lua_State* L) { int Args = lua_gettop(L); - if(Args != 3){ - SendError(L,Sec("TriggerClientEvent invalid argument count expected 3 got ") + std::to_string(Args)); + if (Args != 3) { + SendError(L, Sec("TriggerClientEvent invalid argument count expected 3 got ") + std::to_string(Args)); return 0; } - if(!lua_isnumber(L,1)){ - SendError(L,Sec("TriggerClientEvent invalid argument [1] expected number")); + if (!lua_isnumber(L, 1)) { + SendError(L, Sec("TriggerClientEvent invalid argument [1] expected number")); return 0; } - if(!lua_isstring(L,2)){ - SendError(L,Sec("TriggerClientEvent invalid argument [2] expected string")); + if (!lua_isstring(L, 2)) { + SendError(L, Sec("TriggerClientEvent invalid argument [2] expected string")); return 0; } - if(!lua_isstring(L,3)){ - SendError(L,Sec("TriggerClientEvent invalid argument [3] expected string")); + if (!lua_isstring(L, 3)) { + SendError(L, Sec("TriggerClientEvent invalid argument [3] expected string")); return 0; } - int ID = int(lua_tointeger(L,1)); - std::string Packet = "E:" + std::string(lua_tostring(L,2)) + ":" + std::string(lua_tostring(L,3)); - if(ID == -1)SendToAll(nullptr,Packet,true,true); - else{ - Client *c = GetClient(ID); - if(c == nullptr){ - SendError(L,Sec("TriggerClientEvent invalid Player ID")); + int ID = int(lua_tointeger(L, 1)); + std::string Packet = "E:" + std::string(lua_tostring(L, 2)) + ":" + std::string(lua_tostring(L, 3)); + if (ID == -1) + SendToAll(nullptr, Packet, true, true); + else { + Client* c = GetClient(ID); + if (c == nullptr) { + SendError(L, Sec("TriggerClientEvent invalid Player ID")); return 0; } - Respond(c,Packet,true); + Respond(c, Packet, true); } return 0; } -int lua_ServerExit(lua_State *){ +int lua_ServerExit(lua_State*) { exit(0); } -int lua_Set(lua_State *L){ +int lua_Set(lua_State* L) { int Args = lua_gettop(L); - if(Args != 2){ - SendError(L,Sec("set invalid argument count expected 2 got ") + std::to_string(Args)); + if (Args != 2) { + SendError(L, Sec("set invalid argument count expected 2 got ") + std::to_string(Args)); return 0; } - if(!lua_isnumber(L,1)){ - SendError(L,Sec("set invalid argument [1] expected number")); + if (!lua_isnumber(L, 1)) { + SendError(L, Sec("set invalid argument [1] expected number")); return 0; } - Lua* Src = GetScript(L); + auto MaybeSrc = GetScript(L); std::string Name; - if(Src == nullptr)Name = Sec("Console"); - else Name = Src->GetPluginName(); - int C = int(lua_tointeger(L,1)); - switch(C){ - case 0: //debug - if(lua_isboolean(L,2)){ - Debug = lua_toboolean(L,2); - info(Name + Sec(" | Debug -> ") + (Debug?"true":"false")); - } - else SendError(L,Sec("set invalid argument [2] expected boolean for ID : 0")); - break; - case 1: //private - if(lua_isboolean(L,2)){ - Private = lua_toboolean(L,2); - info(Name + Sec(" | Private -> ") + (Private?"true":"false")); - } - else SendError(L,Sec("set invalid argument [2] expected boolean for ID : 1")); - break; - case 2: //max cars - if(lua_isnumber(L,2)){ - MaxCars = int(lua_tointeger(L,2)); - info(Name + Sec(" | MaxCars -> ") + std::to_string(MaxCars)); - } - else SendError(L,Sec("set invalid argument [2] expected number for ID : 2")); - break; - case 3: //max players - if(lua_isnumber(L,2)){ - MaxPlayers = int(lua_tointeger(L,2)); - info(Name + Sec(" | MaxPlayers -> ") + std::to_string(MaxPlayers)); - } - else SendError(L,Sec("set invalid argument [2] expected number for ID : 3")); - break; - case 4: //Map - if(lua_isstring(L,2)){ - MapName = lua_tostring(L,2); - info(Name + Sec(" | MapName -> ") + MapName); - } - else SendError(L,Sec("set invalid argument [2] expected string for ID : 4")); - break; - case 5: //Name - if(lua_isstring(L,2)){ - ServerName = lua_tostring(L,2); - info(Name + Sec(" | ServerName -> ") + ServerName); - } - else SendError(L,Sec("set invalid argument [2] expected string for ID : 5")); - break; - case 6: //Desc - if(lua_isstring(L,2)){ - ServerDesc = lua_tostring(L,2); - info(Name + Sec(" | ServerDesc -> ") + ServerDesc); - } - else SendError(L,Sec("set invalid argument [2] expected string for ID : 6")); - break; - default: - warn(Sec("Invalid config ID : ") + std::to_string(C)); - break; + if (!MaybeSrc.has_value()) { + Name = Sec("_Console"); + } else { + Name = MaybeSrc.value().get().GetPluginName(); + } + int C = int(lua_tointeger(L, 1)); + switch (C) { + case 0: //debug + if (lua_isboolean(L, 2)) { + Debug = lua_toboolean(L, 2); + info(Name + Sec(" | Debug -> ") + (Debug ? "true" : "false")); + } else + SendError(L, Sec("set invalid argument [2] expected boolean for ID : 0")); + break; + case 1: //private + if (lua_isboolean(L, 2)) { + Private = lua_toboolean(L, 2); + info(Name + Sec(" | Private -> ") + (Private ? "true" : "false")); + } else + SendError(L, Sec("set invalid argument [2] expected boolean for ID : 1")); + break; + case 2: //max cars + if (lua_isnumber(L, 2)) { + MaxCars = int(lua_tointeger(L, 2)); + info(Name + Sec(" | MaxCars -> ") + std::to_string(MaxCars)); + } else + SendError(L, Sec("set invalid argument [2] expected number for ID : 2")); + break; + case 3: //max players + if (lua_isnumber(L, 2)) { + MaxPlayers = int(lua_tointeger(L, 2)); + info(Name + Sec(" | MaxPlayers -> ") + std::to_string(MaxPlayers)); + } else + SendError(L, Sec("set invalid argument [2] expected number for ID : 3")); + break; + case 4: //Map + if (lua_isstring(L, 2)) { + MapName = lua_tostring(L, 2); + info(Name + Sec(" | MapName -> ") + MapName); + } else + SendError(L, Sec("set invalid argument [2] expected string for ID : 4")); + break; + case 5: //Name + if (lua_isstring(L, 2)) { + ServerName = lua_tostring(L, 2); + info(Name + Sec(" | ServerName -> ") + ServerName); + } else + SendError(L, Sec("set invalid argument [2] expected string for ID : 5")); + break; + case 6: //Desc + if (lua_isstring(L, 2)) { + ServerDesc = lua_tostring(L, 2); + info(Name + Sec(" | ServerDesc -> ") + ServerDesc); + } else + SendError(L, Sec("set invalid argument [2] expected string for ID : 6")); + break; + default: + warn(Sec("Invalid config ID : ") + std::to_string(C)); + break; } return 0; } extern "C" { - int lua_Print(lua_State *L) { - int Arg = lua_gettop(L); - for (int i = 1; i <= Arg; i++){ - ConsoleOut(lua_tostring(L, i) + std::string("\n")); - } - return 0; +int lua_Print(lua_State* L) { + int Arg = lua_gettop(L); + for (int i = 1; i <= Arg; i++) { + ConsoleOut(lua_tostring(L, i) + std::string("\n")); } + return 0; +} } -void Lua::Init(){ - luaL_openlibs(luaState); - lua_register(luaState,"TriggerGlobalEvent",lua_TriggerEventG); - lua_register(luaState,"TriggerLocalEvent",lua_TriggerEventL); - lua_register(luaState,"TriggerClientEvent",lua_RemoteEvent); - lua_register(luaState,"GetPlayerCount",lua_GetPlayerCount); - lua_register(luaState,"isPlayerConnected",lua_isConnected); - lua_register(luaState,"RegisterEvent",lua_RegisterEvent); - lua_register(luaState,"GetPlayerName",lua_GetPlayerName); - lua_register(luaState,"RemoveVehicle",lua_RemoveVehicle); - lua_register(luaState,"GetPlayerDiscordID",lua_GetDID); - lua_register(luaState,"GetPlayerVehicles",lua_GetCars); - lua_register(luaState,"CreateThread",lua_CreateThread); - lua_register(luaState,"SendChatMessage",lua_sendChat); - lua_register(luaState,"GetPlayers",lua_GetAllPlayers); - lua_register(luaState,"StopThread",lua_StopThread); - lua_register(luaState,"DropPlayer",lua_dropPlayer); - lua_register(luaState,"GetPlayerHWID",lua_HWID); - lua_register(luaState,"exit",lua_ServerExit); - lua_register(luaState,"Sleep",lua_Sleep); - lua_register(luaState,"print",lua_Print); - lua_register(luaState,"Set",lua_Set); - if(!Console)Reload(); +Lua::Lua(const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote, bool Console) + : luaState(luaL_newstate()) { + Assert(luaState); + if (!PluginName.empty()) { + SetPluginName(PluginName); + } + if (!FileName.empty()) { + SetFileName(FileName); + } + SetLastWrite(LastWrote); + _Console = Console; + Init(); } -void Lua::Execute(const std::string& Command){ - if(ConsoleCheck(luaState,luaL_dostring(luaState,Command.c_str()))){ + +Lua::Lua(bool Console) + : luaState(luaL_newstate()) { + _Console = Console; + Init(); +} + +void Lua::Execute(const std::string& Command) { + if (ConsoleCheck(luaState, luaL_dostring(luaState, Command.c_str()))) { lua_settop(luaState, 0); } } -void Lua::Reload(){ - if(CheckLua(luaState,luaL_dofile(luaState,FileName.c_str()))){ - CallFunction(this,Sec("onInit"), nullptr); +void Lua::Reload() { + if (CheckLua(luaState, luaL_dofile(luaState, _FileName.c_str()))) { + CallFunction(this, Sec("onInit"), nullptr); } } -char* Lua::GetOrigin(){ +char* Lua::GetOrigin() { std::string T = GetFileName().substr(GetFileName().find('\\')); char* Data = new char[T.size()]; - ZeroMemory(Data,T.size()); - memcpy(Data,T.c_str(),T.size()); + ZeroMemory(Data, T.size()); + memcpy(Data, T.c_str(), T.size()); return Data; } -int CallFunction(Lua*lua,const std::string& FuncName,LuaArg* Arg){ - lua_State*luaState = lua->GetState(); + +int CallFunction(Lua* lua, const std::string& FuncName, LuaArg* Arg) { + lua_State* luaState = lua->GetState(); lua_getglobal(luaState, FuncName.c_str()); - if(lua_isfunction(luaState, -1)) { + if (lua_isfunction(luaState, -1)) { int Size = 0; - if(Arg != nullptr){ + if (Arg != nullptr) { Size = int(Arg->args.size()); Arg->PushArgs(luaState); delete Arg; @@ -516,63 +575,102 @@ int CallFunction(Lua*lua,const std::string& FuncName,LuaArg* Arg){ int R = 0; char* Origin = lua->GetOrigin(); #ifdef WIN32 - __try{ + __try { #endif // WIN32 R = lua_pcall(luaState, Size, 1, 0); - if (CheckLua(luaState, R)){ + if (CheckLua(luaState, R)) { if (lua_isnumber(luaState, -1)) { return int(lua_tointeger(luaState, -1)); } } #ifdef WIN32 - }__except(Handle(GetExceptionInformation(),Origin)){} + } __except (Handle(GetExceptionInformation(), Origin)) { + } #endif // WIN32 - delete [] Origin; + delete[] Origin; } ClearStack(luaState); return 0; } -void Lua::SetPluginName(const std::string&Name){ - PluginName = Name; +void Lua::SetPluginName(const std::string& Name) { + _PluginName = Name; } -void Lua::SetFileName(const std::string&Name){ - FileName = Name; +void Lua::SetFileName(const std::string& Name) { + _FileName = Name; } -void Lua::RegisterEvent(const std::string& Event,const std::string& FunctionName){ - RegisteredEvents.insert(std::make_pair(Event,FunctionName)); +void Lua::Init() { + Assert(luaState); + luaL_openlibs(luaState); + lua_register(luaState, "TriggerGlobalEvent", lua_TriggerEventG); + lua_register(luaState, "TriggerLocalEvent", lua_TriggerEventL); + lua_register(luaState, "TriggerClientEvent", lua_RemoteEvent); + lua_register(luaState, "GetPlayerCount", lua_GetPlayerCount); + lua_register(luaState, "isPlayerConnected", lua_isConnected); + lua_register(luaState, "RegisterEvent", lua_RegisterEvent); + lua_register(luaState, "GetPlayerName", lua_GetPlayerName); + lua_register(luaState, "RemoveVehicle", lua_RemoveVehicle); + lua_register(luaState, "GetPlayerDiscordID", lua_GetDID); + lua_register(luaState, "GetPlayerVehicles", lua_GetCars); + lua_register(luaState, "CreateThread", lua_CreateThread); + lua_register(luaState, "SendChatMessage", lua_sendChat); + lua_register(luaState, "GetPlayers", lua_GetAllPlayers); + lua_register(luaState, "StopThread", lua_StopThread); + lua_register(luaState, "DropPlayer", lua_dropPlayer); + lua_register(luaState, "GetPlayerHWID", lua_HWID); + lua_register(luaState, "exit", lua_ServerExit); + lua_register(luaState, "Sleep", lua_Sleep); + lua_register(luaState, "print", lua_Print); + lua_register(luaState, "Set", lua_Set); + if (!_Console) + Reload(); } -void Lua::UnRegisterEvent(const std::string&Event){ - for(const std::pair& a : RegisteredEvents){ - if(a.first == Event) { - RegisteredEvents.erase(a); + +void Lua::RegisterEvent(const std::string& Event, const std::string& FunctionName) { + _RegisteredEvents.insert(std::make_pair(Event, FunctionName)); +} +void Lua::UnRegisterEvent(const std::string& Event) { + for (const std::pair& a : _RegisteredEvents) { + if (a.first == Event) { + _RegisteredEvents.erase(a); break; } } } -bool Lua::IsRegistered(const std::string&Event){ - for(const std::pair& a : RegisteredEvents){ - if(a.first == Event)return true; +bool Lua::IsRegistered(const std::string& Event) { + for (const std::pair& a : _RegisteredEvents) { + if (a.first == Event) + return true; } return false; } -std::string Lua::GetRegistered(const std::string&Event){ - for(const std::pair& a : RegisteredEvents){ - if(a.first == Event)return a.second; +std::string Lua::GetRegistered(const std::string& Event) const { + for (const std::pair& a : _RegisteredEvents) { + if (a.first == Event) + return a.second; } return ""; } -std::string Lua::GetFileName(){ - return FileName; +std::string Lua::GetFileName() const { + return _FileName; } -std::string Lua::GetPluginName(){ - return PluginName; +std::string Lua::GetPluginName() const { + return _PluginName; } -lua_State* Lua::GetState(){ +lua_State* Lua::GetState() { return luaState; } -void Lua::SetLastWrite(fs::file_time_type time){ - LastWrote = time; + +const lua_State* Lua::GetState() const { + return luaState; } -fs::file_time_type Lua::GetLastWrite(){ - return LastWrote; + +void Lua::SetLastWrite(fs::file_time_type time) { + _LastWrote = time; +} +fs::file_time_type Lua::GetLastWrite() { + return _LastWrote; +} + +Lua::~Lua() { + lua_close(luaState); } From 36db73b562fd1e6efb23f7dd349a16f149d1e43f Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Wed, 4 Nov 2020 14:35:28 +0100 Subject: [PATCH 21/30] Add more safety on some memory handling --- include/Lua/LuaSystem.hpp | 8 ++++---- src/Console.cpp | 4 ++-- src/Lua/LuaSystem.cpp | 40 ++++++++++++++++---------------------- src/Network/GParser.cpp | 17 +++++++++------- src/Network/InitClient.cpp | 6 +++--- src/main.cpp | 5 +++++ 6 files changed, 41 insertions(+), 39 deletions(-) diff --git a/include/Lua/LuaSystem.hpp b/include/Lua/LuaSystem.hpp index 2d2bea9..2d63a9f 100644 --- a/include/Lua/LuaSystem.hpp +++ b/include/Lua/LuaSystem.hpp @@ -7,8 +7,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -64,7 +64,7 @@ public: std::string GetFileName() const; lua_State* GetState(); const lua_State* GetState() const; - char* GetOrigin(); + std::string GetOrigin(); std::mutex Lock; void Reload(); Lua(const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote, bool Console = false); @@ -73,6 +73,6 @@ public: void SetStopThread(bool StopThread) { _StopThread = StopThread; } bool GetStopThread() const { return _StopThread; } }; -int CallFunction(Lua* lua, const std::string& FuncName, LuaArg* args); -int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, LuaArg* arg, bool Wait); +int CallFunction(Lua* lua, const std::string& FuncName, std::unique_ptr args); +int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, std::unique_ptr arg, bool Wait); extern std::set> PluginEngine; diff --git a/src/Console.cpp b/src/Console.cpp index 91c27f9..9dda48d 100644 --- a/src/Console.cpp +++ b/src/Console.cpp @@ -20,7 +20,7 @@ typedef unsigned long DWORD, *PDWORD, *LPDWORD; std::vector QConsoleOut; std::string CInputBuff; std::mutex MLock; -Lua* LuaConsole; +std::unique_ptr LuaConsole; void HandleInput(const std::string& cmd) { std::cout << std::endl; if (cmd == "exit") { @@ -130,7 +130,7 @@ void SetupConsole() { } void ConsoleInit() { SetupConsole(); - LuaConsole = new Lua(true); + LuaConsole = std::make_unique(true); printf("> "); std::thread In(ReadCin); In.detach(); diff --git a/src/Lua/LuaSystem.cpp b/src/Lua/LuaSystem.cpp index 4e36506..48df26c 100644 --- a/src/Lua/LuaSystem.cpp +++ b/src/Lua/LuaSystem.cpp @@ -13,10 +13,10 @@ #include #include -LuaArg* CreateArg(lua_State* L, int T, int S) { +std::unique_ptr CreateArg(lua_State* L, int T, int S) { if (S > T) return nullptr; - auto* temp = new LuaArg; + std::unique_ptr temp(new LuaArg); for (int C = S; C <= T; C++) { if (lua_isstring(L, C)) { temp->args.emplace_back(std::string(lua_tostring(L, C))); @@ -52,11 +52,11 @@ void SendError(lua_State* L, const std::string& msg) { } warn(a + Sec(" | Incorrect Call of ") + msg); } -int Trigger(Lua* lua, const std::string& R, LuaArg* arg) { +int Trigger(Lua* lua, const std::string& R, std::unique_ptr arg) { std::lock_guard lockGuard(lua->Lock); - std::packaged_task task([lua, R, arg] { return CallFunction(lua, R, arg); }); + std::packaged_task)> task([lua, R](std::unique_ptr arg) { return CallFunction(lua, R, std::move(arg)); }); std::future f1 = task.get_future(); - std::thread t(std::move(task)); + std::thread t(std::move(task), std::move(arg)); t.detach(); auto status = f1.wait_for(std::chrono::seconds(5)); if (status != std::future_status::timeout) @@ -64,11 +64,11 @@ int Trigger(Lua* lua, const std::string& R, LuaArg* arg) { SendError(lua->GetState(), R + " took too long to respond"); return 0; } -int FutureWait(Lua* lua, const std::string& R, LuaArg* arg, bool Wait) { +int FutureWait(Lua* lua, const std::string& R, std::unique_ptr arg, bool Wait) { Assert(lua); - std::packaged_task task([lua, R, arg] { return Trigger(lua, R, arg); }); + std::packaged_task)> task([lua, R](std::unique_ptr arg) { return Trigger(lua, R, std::move(arg)); }); std::future f1 = task.get_future(); - std::thread t(std::move(task)); + std::thread t(std::move(task), std::move(arg)); t.detach(); int T = 0; if (Wait) @@ -78,16 +78,16 @@ int FutureWait(Lua* lua, const std::string& R, LuaArg* arg, bool Wait) { return f1.get(); return 0; } -int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, LuaArg* arg, bool Wait) { +int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, std::unique_ptr arg, bool Wait) { int R = 0; for (auto& Script : PluginEngine) { if (Script->IsRegistered(Event)) { if (local) { if (Script->GetPluginName() == Caller->GetPluginName()) { - R += FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait); + R += FutureWait(Script.get(), Script->GetRegistered(Event), std::move(arg), Wait); } } else - R += FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait); + R += FutureWait(Script.get(), Script->GetRegistered(Event), std::move(arg), Wait); } } return R; @@ -553,15 +553,11 @@ void Lua::Reload() { CallFunction(this, Sec("onInit"), nullptr); } } -char* Lua::GetOrigin() { - std::string T = GetFileName().substr(GetFileName().find('\\')); - char* Data = new char[T.size()]; - ZeroMemory(Data, T.size()); - memcpy(Data, T.c_str(), T.size()); - return Data; +std::string Lua::GetOrigin() { + return GetFileName().substr(GetFileName().find('\\')); } -int CallFunction(Lua* lua, const std::string& FuncName, LuaArg* Arg) { +int CallFunction(Lua* lua, const std::string& FuncName, std::unique_ptr Arg) { lua_State* luaState = lua->GetState(); lua_getglobal(luaState, FuncName.c_str()); if (lua_isfunction(luaState, -1)) { @@ -569,11 +565,9 @@ int CallFunction(Lua* lua, const std::string& FuncName, LuaArg* Arg) { if (Arg != nullptr) { Size = int(Arg->args.size()); Arg->PushArgs(luaState); - delete Arg; - Arg = nullptr; } int R = 0; - char* Origin = lua->GetOrigin(); + std::string Origin = lua->GetOrigin(); #ifdef WIN32 __try { #endif // WIN32 @@ -584,10 +578,9 @@ int CallFunction(Lua* lua, const std::string& FuncName, LuaArg* Arg) { } } #ifdef WIN32 - } __except (Handle(GetExceptionInformation(), Origin)) { + } __except (Handle(GetExceptionInformation(), Origin.data())) { } #endif // WIN32 - delete[] Origin; } ClearStack(luaState); return 0; @@ -672,5 +665,6 @@ fs::file_time_type Lua::GetLastWrite() { } Lua::~Lua() { + info("closing lua state"); lua_close(luaState); } diff --git a/src/Network/GParser.cpp b/src/Network/GParser.cpp index f337f20..1ddd992 100644 --- a/src/Network/GParser.cpp +++ b/src/Network/GParser.cpp @@ -47,7 +47,8 @@ void VehicleParser(Client*c,const std::string& Pckt){ Packet = "Os:"+c->GetRole()+":"+c->GetName()+":"+std::to_string(c->GetID())+"-"+std::to_string(CarID)+Packet.substr(4); if(c->GetCarCount() >= MaxCars || TriggerLuaEvent(Sec("onVehicleSpawn"),false,nullptr, - new LuaArg{{c->GetID(),CarID,Packet.substr(3)}},true)){ + std::unique_ptr(new LuaArg{{c->GetID(),CarID,Packet.substr(3)}}), + true)){ Respond(c,Packet,true); std::string Destroy = "Od:" + std::to_string(c->GetID())+"-"+std::to_string(CarID); Respond(c,Destroy,true); @@ -67,7 +68,8 @@ void VehicleParser(Client*c,const std::string& Pckt){ } if(PID != -1 && VID != -1 && PID == c->GetID()){ if(!TriggerLuaEvent(Sec("onVehicleEdited"),false,nullptr, - new LuaArg{{c->GetID(),VID,Packet.substr(3)}},true)) { + std::unique_ptr(new LuaArg{{c->GetID(),VID,Packet.substr(3)}}), + true)) { SendToAll(c, Packet, false, true); Apply(c,VID,Packet); }else{ @@ -87,7 +89,7 @@ void VehicleParser(Client*c,const std::string& Pckt){ if(PID != -1 && VID != -1 && PID == c->GetID()){ SendToAll(nullptr,Packet,true,true); TriggerLuaEvent(Sec("onVehicleDeleted"),false,nullptr, - new LuaArg{{c->GetID(),VID}},false); + std::unique_ptr(new LuaArg{{c->GetID(),VID}}),false); c->DeleteCar(VID); debug(c->GetName() + Sec(" deleted car with ID ") + std::to_string(VID)); } @@ -107,7 +109,7 @@ void SyncClient(Client*c){ std::this_thread::sleep_for(std::chrono::seconds(1)); Respond(c,Sec("Sn")+c->GetName(),true); SendToAll(c,Sec("JWelcome ")+c->GetName()+"!",false,true); - TriggerLuaEvent(Sec("onPlayerJoin"),false,nullptr,new LuaArg{{c->GetID()}},false); + TriggerLuaEvent(Sec("onPlayerJoin"),false,nullptr,std::unique_ptr(new LuaArg{{c->GetID()}}),false); for (Client*client : CI->Clients) { if(client != nullptr){ if (client != c) { @@ -144,7 +146,7 @@ void HandleEvent(Client*c ,const std::string&Data){ Name = t; break; case 2: - TriggerLuaEvent(Name, false, nullptr,new LuaArg{{c->GetID(),t}},false); + TriggerLuaEvent(Name, false, nullptr,std::unique_ptr(new LuaArg{{c->GetID(),t}}),false); break; default: break; @@ -189,9 +191,10 @@ void GlobalParser(Client*c, const std::string& Pack){ return; case 'C': if(Packet.length() < 4 || Packet.find(':', 3) == std::string::npos)break; - if (TriggerLuaEvent(Sec("onChatMessage"), false, nullptr,new LuaArg{ + if (TriggerLuaEvent(Sec("onChatMessage"), false, nullptr, + std::unique_ptr(new LuaArg{ {c->GetID(), c->GetName(), Packet.substr(Packet.find(':', 3) + 1)} - },true))break; + }),true))break; SendToAll(nullptr, Packet, true, true); return; case 'E': diff --git a/src/Network/InitClient.cpp b/src/Network/InitClient.cpp index a31c0f1..0474331 100644 --- a/src/Network/InitClient.cpp +++ b/src/Network/InitClient.cpp @@ -71,7 +71,7 @@ void OnDisconnect(Client*c,bool kicked){ Packet = Sec("L")+c->GetName()+Sec(" Left the server!"); SendToAll(c, Packet,false,true); Packet.clear(); - TriggerLuaEvent(Sec("onPlayerDisconnect"),false,nullptr,new LuaArg{{c->GetID()}},false); + TriggerLuaEvent(Sec("onPlayerDisconnect"),false,nullptr,std::unique_ptr(new LuaArg{{c->GetID()}}),false); c->ClearCars(); CI->RemoveClient(c); ///Removes the Client from existence } @@ -80,10 +80,10 @@ void OnConnect(Client*c){ info(Sec("Client connected")); c->SetID(OpenID()); info(Sec("Assigned ID ") + std::to_string(c->GetID()) + Sec(" to ") + c->GetName()); - TriggerLuaEvent(Sec("onPlayerConnecting"),false,nullptr,new LuaArg{{c->GetID()}},false); + TriggerLuaEvent(Sec("onPlayerConnecting"),false,nullptr,std::unique_ptr(new LuaArg{{c->GetID()}}),false); SyncResources(c); if(c->GetStatus() < 0)return; Respond(c,"M"+MapName,true); //Send the Map on connect info(c->GetName() + Sec(" : Connected")); - TriggerLuaEvent(Sec("onPlayerJoining"),false,nullptr,new LuaArg{{c->GetID()}},false); + TriggerLuaEvent(Sec("onPlayerJoining"),false,nullptr,std::unique_ptr(new LuaArg{{c->GetID()}}),false); } diff --git a/src/main.cpp b/src/main.cpp index d6067a2..813358c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,6 @@ #include "Startup.h" #include "CustomAssert.h" +#include "Curl/curl.h" #include #include [[noreturn]] void loop(){ @@ -11,6 +12,8 @@ } int main(int argc, char* argv[]) { DebugPrintTID(); + // curl needs to be initialized to properly deallocate its resources later + Assert(curl_global_init(CURL_GLOBAL_DEFAULT) == CURLE_OK); #ifdef DEBUG std::thread t1(loop); t1.detach(); @@ -23,5 +26,7 @@ int main(int argc, char* argv[]) { HBInit(); StatInit(); NetMain(); + // clean up curl at the end to be sure + curl_global_cleanup(); return 0; } From fbbdc084a4a6a65672eca9d9819e25b651ebdc57 Mon Sep 17 00:00:00 2001 From: Anonymous275 Date: Thu, 5 Nov 2020 16:49:49 +0200 Subject: [PATCH 22/30] Windows compile fix --- CMakeLists.txt | 2 -- src/Lua/LuaSystem.cpp | 17 +++++------------ src/Network/TCPHandler.cpp | 8 +------- 3 files changed, 6 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 28295fd..d777da4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,8 +13,6 @@ elseif (WIN32) # completely cross platform. For fixes to common issues arising from /permissive- visit: # https://docs.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /permissive-") - # disables warnings about _s variants of stdc functions - add_definitions(_CRT_SECURE_NO_DEPRECATE _CRT_NONSTDC_NO_DEPRECATE) endif () find_package(Boost 1.71.0 REQUIRED COMPONENTS system thread) diff --git a/src/Lua/LuaSystem.cpp b/src/Lua/LuaSystem.cpp index 48df26c..d2f52d2 100644 --- a/src/Lua/LuaSystem.cpp +++ b/src/Lua/LuaSystem.cpp @@ -12,6 +12,7 @@ #include #include #include +#include std::unique_ptr CreateArg(lua_State* L, int T, int S) { if (S > T) @@ -566,21 +567,13 @@ int CallFunction(Lua* lua, const std::string& FuncName, std::unique_ptr Size = int(Arg->args.size()); Arg->PushArgs(luaState); } - int R = 0; std::string Origin = lua->GetOrigin(); -#ifdef WIN32 - __try { -#endif // WIN32 - R = lua_pcall(luaState, Size, 1, 0); - if (CheckLua(luaState, R)) { - if (lua_isnumber(luaState, -1)) { - return int(lua_tointeger(luaState, -1)); - } + int R = lua_pcall(luaState, Size, 1, 0); + if (CheckLua(luaState, R)) { + if (lua_isnumber(luaState, -1)) { + return int(lua_tointeger(luaState, -1)); } -#ifdef WIN32 - } __except (Handle(GetExceptionInformation(), Origin.data())) { } -#endif // WIN32 } ClearStack(luaState); return 0; diff --git a/src/Network/TCPHandler.cpp b/src/Network/TCPHandler.cpp index 2c8914e..d4d5ed3 100644 --- a/src/Network/TCPHandler.cpp +++ b/src/Network/TCPHandler.cpp @@ -71,13 +71,7 @@ void TCPClient(Client*c){ } OnConnect(c); while (c->GetStatus() > -1)TCPRcv(c); -#ifdef WIN32 - __try{ -#endif // WIN32 - OnDisconnect(c, c->GetStatus() == -2); -#ifdef WIN32 - }__except(Handle(GetExceptionInformation(),Sec("OnDisconnect"))){} -#endif // WIN32 + OnDisconnect(c, c->GetStatus() == -2); } void InitClient(Client*c){ std::thread NewClient(TCPClient,c); From f0c87341ab0dae51027993c857d922f162b7735b Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Thu, 5 Nov 2020 23:57:07 +0100 Subject: [PATCH 23/30] implement size header for auth --- src/Network/Auth.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/Network/Auth.cpp b/src/Network/Auth.cpp index 601ac59..9776fbd 100644 --- a/src/Network/Auth.cpp +++ b/src/Network/Auth.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "UnixCompat.h" @@ -30,10 +31,22 @@ bool Send(SOCKET TCPSock,std::string Data){ return true; } std::string Rcv(SOCKET TCPSock){ - char buf[6768]; - size_t len = 6768; - ZeroMemory(buf, len); - int64_t BytesRcv = recv(TCPSock, buf, len,0); + uint32_t RealSize; + int64_t BytesRcv = recv(TCPSock, &RealSize, sizeof(RealSize), 0); + if (BytesRcv != sizeof(RealSize)) { + error(Sec("invalid packet (1)")); + return ""; + } + // RealSize is big-endian, so we convert it to host endianness + RealSize = ntohl(RealSize); + if (RealSize > 7000) { + error(Sec("Larger than allowed TCP packet received")); + return ""; + } + RealSize = std::min(RealSize, 7000); + char buf[7000]; + std::fill_n(buf, sizeof(buf), 0); + BytesRcv = recv(TCPSock, buf, RealSize, 0); if (BytesRcv <= 0)return ""; return std::string(buf); } From 6a3b933df1a354366989c032d64e8e26fc2a60bd Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Fri, 6 Nov 2020 00:31:35 +0100 Subject: [PATCH 24/30] more verbose errors --- src/Network/Auth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Network/Auth.cpp b/src/Network/Auth.cpp index 9776fbd..31e994a 100644 --- a/src/Network/Auth.cpp +++ b/src/Network/Auth.cpp @@ -34,7 +34,7 @@ std::string Rcv(SOCKET TCPSock){ uint32_t RealSize; int64_t BytesRcv = recv(TCPSock, &RealSize, sizeof(RealSize), 0); if (BytesRcv != sizeof(RealSize)) { - error(Sec("invalid packet (1)")); + error(std::string(Sec("invalid packet: expected 4, got ")) + std::to_string(BytesRcv)); return ""; } // RealSize is big-endian, so we convert it to host endianness From 8ba89e491faed318e37321c13aa1e70a889d1582 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Fri, 6 Nov 2020 00:54:05 +0100 Subject: [PATCH 25/30] add even more debugging prints --- src/Network/Auth.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Network/Auth.cpp b/src/Network/Auth.cpp index 31e994a..bef57fd 100644 --- a/src/Network/Auth.cpp +++ b/src/Network/Auth.cpp @@ -116,12 +116,14 @@ void Identification(SOCKET TCPSock,Hold*S,RSA*Skey){ Timeout.detach(); std::string Name,DID,Role; if(!Send(TCPSock,GenerateM(Skey))){ + error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__)); closesocket(TCPSock); return; } std::string msg = Rcv(TCPSock); auto Keys = Parse(msg); if(!Send(TCPSock,RSA_E("HC",Keys.second,Keys.first))){ + error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__)); closesocket(TCPSock); return; } @@ -133,19 +135,23 @@ void Identification(SOCKET TCPSock,Hold*S,RSA*Skey){ if(Ver.size() > 3 && Ver.substr(0,2) == Sec("VC")){ Ver = Ver.substr(2); if(Ver.length() > 4 || Ver != GetCVer()){ + error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__)); closesocket(TCPSock); return; } }else{ + error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__)); closesocket(TCPSock); return; } Res = RSA_D(Res,Skey); if(Res.size() < 3 || Res.substr(0,2) != Sec("NR")) { + error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__)); closesocket(TCPSock); return; } if(Res.find(':') == std::string::npos){ + error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__)); closesocket(TCPSock); return; } @@ -153,6 +159,7 @@ void Identification(SOCKET TCPSock,Hold*S,RSA*Skey){ DID = Res.substr(Res.find(':')+1); Role = GetRole(DID); if(Role.empty() || Role.find(Sec("Error")) != std::string::npos){ + error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__)); closesocket(TCPSock); return; } @@ -160,6 +167,7 @@ void Identification(SOCKET TCPSock,Hold*S,RSA*Skey){ for(Client*c: CI->Clients){ if(c != nullptr){ if(c->GetDID() == DID){ + error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__)); closesocket(c->GetTCPSock()); c->SetStatus(-2); break; @@ -168,7 +176,11 @@ void Identification(SOCKET TCPSock,Hold*S,RSA*Skey){ } if(Role == Sec("MDEV") || CI->Size() < Max()){ CreateClient(TCPSock,Name,DID,Role); - }else closesocket(TCPSock); + } else { + error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__)); + closesocket(TCPSock); + } + debug("Identification success"); } void Identify(SOCKET TCPSock){ auto* S = new Hold; @@ -186,6 +198,7 @@ void Identify(SOCKET TCPSock){ #endif // WIN32 if(TCPSock != -1){ + error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__)); closesocket(TCPSock); } #ifdef WIN32 @@ -267,6 +280,7 @@ void TCPServerMain(){ ID.detach(); }while(client); + debug("all ok, arrived at " + std::string(__func__) + ":" + std::to_string(__LINE__)); closesocket(client); #endif // WIN32 } From 24eaa1e0797ec8b1cc48a027634edd1166164377 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Fri, 6 Nov 2020 00:58:25 +0100 Subject: [PATCH 26/30] add even more prints --- src/Network/Auth.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Network/Auth.cpp b/src/Network/Auth.cpp index bef57fd..dca66d1 100644 --- a/src/Network/Auth.cpp +++ b/src/Network/Auth.cpp @@ -39,15 +39,19 @@ std::string Rcv(SOCKET TCPSock){ } // RealSize is big-endian, so we convert it to host endianness RealSize = ntohl(RealSize); + debug(std::string("got ") + std::to_string(RealSize) + " as size"); if (RealSize > 7000) { error(Sec("Larger than allowed TCP packet received")); return ""; } - RealSize = std::min(RealSize, 7000); char buf[7000]; - std::fill_n(buf, sizeof(buf), 0); + std::fill_n(buf, 7000, 0); BytesRcv = recv(TCPSock, buf, RealSize, 0); - if (BytesRcv <= 0)return ""; + if (BytesRcv != RealSize) { + debug("expected " + std::to_string(RealSize) + " bytes, got " + std::to_string(BytesRcv) + " instead"); + } + if (BytesRcv <= 0) + return ""; return std::string(buf); } std::string GetRole(const std::string &DID){ From e41b3df09589fa3ff253e45dbd24cb67153600fb Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Fri, 6 Nov 2020 01:07:55 +0100 Subject: [PATCH 27/30] fix glaring f*cking error --- src/Network/Auth.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Network/Auth.cpp b/src/Network/Auth.cpp index dca66d1..92d9650 100644 --- a/src/Network/Auth.cpp +++ b/src/Network/Auth.cpp @@ -179,12 +179,12 @@ void Identification(SOCKET TCPSock,Hold*S,RSA*Skey){ } } if(Role == Sec("MDEV") || CI->Size() < Max()){ + debug("Identification success"); CreateClient(TCPSock,Name,DID,Role); } else { error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__)); closesocket(TCPSock); } - debug("Identification success"); } void Identify(SOCKET TCPSock){ auto* S = new Hold; @@ -199,13 +199,10 @@ void Identify(SOCKET TCPSock){ Identification(TCPSock,S,Skey); #ifdef WIN32 }__except(1){ -#endif // WIN32 - if(TCPSock != -1){ error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__)); closesocket(TCPSock); } -#ifdef WIN32 } #endif // WIN32 From 1de29dc5e4ee76c63ea192f0334dfb9e30b3e8dd Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Fri, 6 Nov 2020 01:34:55 +0100 Subject: [PATCH 28/30] fix assert in SendToAll --- src/Network/InitClient.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Network/InitClient.cpp b/src/Network/InitClient.cpp index 0474331..e69616c 100644 --- a/src/Network/InitClient.cpp +++ b/src/Network/InitClient.cpp @@ -32,7 +32,9 @@ void Respond(Client*c, const std::string& MSG, bool Rel){ }else UDPSend(c,MSG); } void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel){ - Assert(c); + if (Self) { + Assert(c); + } char C = Data.at(0); for(Client*client : CI->Clients){ if(client != nullptr) { From 775e46788c75f7adc2622e54403e7d0be7407b9b Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Fri, 6 Nov 2020 01:40:08 +0100 Subject: [PATCH 29/30] fix SendAll again --- src/Network/InitClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Network/InitClient.cpp b/src/Network/InitClient.cpp index e69616c..9a3fa20 100644 --- a/src/Network/InitClient.cpp +++ b/src/Network/InitClient.cpp @@ -32,7 +32,7 @@ void Respond(Client*c, const std::string& MSG, bool Rel){ }else UDPSend(c,MSG); } void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel){ - if (Self) { + if (!Self) { Assert(c); } char C = Data.at(0); From 3eb2bd0dfcd5145247e10d4c2abf413008613516 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Fri, 6 Nov 2020 01:58:36 +0100 Subject: [PATCH 30/30] possibly fixed UDPSend error on unix --- src/Network/VehicleData.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index 29aa3ef..0634a97 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -58,10 +58,14 @@ void UDPSend(Client* c, std::string Data) { c->SetStatus(-1); } #else // unix - if (sendOk != 0) { + if (sendOk == -1) { debug(Sec("(UDP) Send Failed Code : ") + std::string(strerror(errno))); if (c->GetStatus() > -1) c->SetStatus(-1); + } else if (sendOk == 0) { + debug(Sec("(UDP) sendto returned 0")); + if (c->GetStatus() > -1) + c->SetStatus(-1); } #endif // WIN32 }