diff --git a/CMakeLists.txt b/CMakeLists.txt index 39a6506..ba912f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ elseif (WIN32) message(STATUS "MSVC -> forcing use of statically-linked runtime.") STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) + #-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static endif () find_package(Boost 1.70.0 REQUIRED COMPONENTS system thread) @@ -23,12 +24,12 @@ file(GLOB source_files "src/*.cpp" "src/*/*.cpp" "include/*.h" "include/*/*.h" " add_executable(BeamMP-Server ${source_files}) target_include_directories(BeamMP-Server SYSTEM PUBLIC $) -target_include_directories(BeamMP-Server SYSTEM PRIVATE ${LUA_INCLUDE_DIR} ${Boost_INCLUDE_DIRS}) +target_include_directories(BeamMP-Server SYSTEM PUBLIC ${LUA_INCLUDE_DIR} ${Boost_INCLUDE_DIRS}) if (UNIX) find_package(Lua 5.3 REQUIRED) target_include_directories(BeamMP-Server PRIVATE ) - target_link_libraries(BeamMP-Server curl krb5 z pthread stdc++fs ${Boost_LINK_DIRS} ${LUA_LIBRARIES}) + target_link_libraries(BeamMP-Server curl z pthread stdc++fs ${Boost_LINK_DIRS} ${LUA_LIBRARIES}) elseif (WIN32) include(FindLua) find_package(CURL CONFIG REQUIRED) diff --git a/cmake-build-debug/BeamMP-Server b/cmake-build-debug/BeamMP-Server new file mode 100644 index 0000000..046583a Binary files /dev/null and b/cmake-build-debug/BeamMP-Server differ diff --git a/include/Client.hpp b/include/Client.hpp index 5344f46..6015499 100644 --- a/include/Client.hpp +++ b/include/Client.hpp @@ -61,6 +61,8 @@ public: struct ClientInterface{ std::set Clients; void RemoveClient(Client *c){ + Assert(c); + c->ClearCars(); Clients.erase(c); delete c; c = nullptr; diff --git a/include/Logger.h b/include/Logger.h index 93d4e48..c4890b8 100644 --- a/include/Logger.h +++ b/include/Logger.h @@ -5,7 +5,6 @@ #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 20cb838..1fe8345 100644 --- a/src/Console.cpp +++ b/src/Console.cpp @@ -24,7 +24,7 @@ std::unique_ptr LuaConsole; void HandleInput(const std::string& cmd) { std::cout << std::endl; if (cmd == "exit") { - exit(0); + _Exit(0); } else LuaConsole->Execute(cmd); } @@ -89,19 +89,19 @@ void SetupConsole() { if (stdoutHandle == INVALID_HANDLE_VALUE) { error("Invalid handle"); std::this_thread::sleep_for(std::chrono::seconds(3)); - exit(GetLastError()); + _Exit(GetLastError()); } if (!GetConsoleMode(stdoutHandle, &outMode)) { error("Invalid console mode"); std::this_thread::sleep_for(std::chrono::seconds(3)); - exit(GetLastError()); + _Exit(GetLastError()); } // Enable ANSI escape codes outMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; if (!SetConsoleMode(stdoutHandle, outMode)) { error("failed to set console mode"); std::this_thread::sleep_for(std::chrono::seconds(3)); - exit(GetLastError()); + _Exit(GetLastError()); } #else #endif // WIN32 diff --git a/src/Init/Config.cpp b/src/Init/Config.cpp index 0c2d294..e77477c 100644 --- a/src/Init/Config.cpp +++ b/src/Init/Config.cpp @@ -87,7 +87,7 @@ void LoadConfig(std::ifstream& IFS){ if(index-1 < 11){ error(Sec("Outdated/Incorrect config please remove it server will close in 5 secs")); std::this_thread::sleep_for(std::chrono::seconds(3)); - exit(0); + _Exit(0); } IFS.close(); IFS.open(Sec("Server.cfg")); @@ -122,7 +122,7 @@ void Default(){ GenerateConfig(); warn(Sec("You are required to input the AuthKey")); std::this_thread::sleep_for(std::chrono::seconds(3)); - exit(0); + _Exit(0); } void DebugData(){ debug(std::string(Sec("Debug : ")) + (Debug?"true":"false")); @@ -145,7 +145,7 @@ void InitConfig(){ if(Key.empty()){ error(Sec("No AuthKey was found")); std::this_thread::sleep_for(std::chrono::seconds(3)); - exit(0); + _Exit(0); } if(Debug)DebugData(); } diff --git a/src/Init/Heartbeat.cpp b/src/Init/Heartbeat.cpp index 0b45c87..9645ce5 100644 --- a/src/Init/Heartbeat.cpp +++ b/src/Init/Heartbeat.cpp @@ -8,6 +8,7 @@ #include "Logger.h" #include #include +#include void WebsocketInit(); std::string GetPlayers(){ @@ -29,6 +30,18 @@ std::string GenerateCall(){ +"&playerslist="+GetPlayers()+"&desc="+ServerDesc; return ret; } +std::string RunPromise(const std::string& IP, const std::string& R) { + std::packaged_task task([&]() { return PostHTTP(IP,R); }); + std::future f1 = task.get_future(); + std::thread t(std::move(task)); + t.detach(); + auto status = f1.wait_for(std::chrono::seconds(10)); + if (status != std::future_status::timeout)return f1.get(); + error(Sec("Backend system Timeout please try again later")); + std::this_thread::sleep_for(std::chrono::seconds(3)); + _Exit(0); +} + void Heartbeat(){ DebugPrintTID(); std::string R,T; @@ -37,17 +50,16 @@ void Heartbeat(){ R = GenerateCall(); if(!CustomIP.empty())R+="&ip="+CustomIP; std::string link = Sec("https://beammp.com/heartbeatv2"); - T = PostHTTP(link,R); - + T = RunPromise(link,R); if(T.find_first_not_of(Sec("20")) != std::string::npos){ //Backend system refused server startup! std::this_thread::sleep_for(std::chrono::seconds(10)); std::string Backup = Sec("https://backup1.beammp.com/heartbeatv2"); - T = PostHTTP(Backup,R); + T = RunPromise(Backup,R); if(T.find_first_not_of(Sec("20")) != std::string::npos) { error(Sec("Backend system refused server! Check your AuthKey")); std::this_thread::sleep_for(std::chrono::seconds(3)); - exit(-1); + _Exit(-1); } } //Server Authenticated diff --git a/src/Lua/LuaMain.cpp b/src/Lua/LuaMain.cpp index 5d9f706..c55b02c 100644 --- a/src/Lua/LuaMain.cpp +++ b/src/Lua/LuaMain.cpp @@ -50,19 +50,21 @@ void FolderList(const std::string& Path, bool HotSwap) { [[noreturn]] void HotSwaps(const std::string& path) { DebugPrintTID(); 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('\\'))); - break; - } - 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(); + if(!PluginEngine.empty()) { + 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('\\'))); + break; + } + 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); diff --git a/src/Lua/LuaSystem.cpp b/src/Lua/LuaSystem.cpp index d2f52d2..d1b8fa9 100644 --- a/src/Lua/LuaSystem.cpp +++ b/src/Lua/LuaSystem.cpp @@ -437,7 +437,7 @@ int lua_RemoteEvent(lua_State* L) { return 0; } int lua_ServerExit(lua_State*) { - exit(0); + _Exit(0); } int lua_Set(lua_State* L) { int Args = lua_gettop(L); diff --git a/src/Network/Auth.cpp b/src/Network/Auth.cpp index b5ecdf6..77af733 100644 --- a/src/Network/Auth.cpp +++ b/src/Network/Auth.cpp @@ -230,7 +230,7 @@ void TCPServerMain(){ if (bind(Listener, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR){ error(Sec("Can't bind socket! ") + std::to_string(WSAGetLastError())); std::this_thread::sleep_for(std::chrono::seconds(5)); - exit(-1); + _Exit(-1); } if(Listener == -1){ error(Sec("Invalid listening socket")); @@ -264,7 +264,7 @@ void TCPServerMain(){ 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); + _Exit(-1); } if(Listener == -1){ error(Sec("Invalid listening socket")); diff --git a/src/Network/GParser.cpp b/src/Network/GParser.cpp index 1ddd992..45fed2d 100644 --- a/src/Network/GParser.cpp +++ b/src/Network/GParser.cpp @@ -8,6 +8,7 @@ #include "Network.h" #include "Logger.h" #include "UnixCompat.h" +#include #include @@ -47,7 +48,7 @@ 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, - std::unique_ptr(new LuaArg{{c->GetID(),CarID,Packet.substr(3)}}), + std::make_unique(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); diff --git a/src/Network/Http.cpp b/src/Network/Http.cpp index 321c8d0..efcdfbe 100644 --- a/src/Network/Http.cpp +++ b/src/Network/Http.cpp @@ -35,7 +35,7 @@ std::string PostHTTP(const std::string& IP,const std::string& Fields){ Assert(curl); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, IP.c_str()); - /*curl_easy_setopt(curl, CURLOPT_URL, "95.216.35.232/heartbeatv2"); + /*curl_easy_setopt(curl, CURLOPT_URL, "https://95.216.35.232/heartbeatv2"); curl_easy_setopt(curl, CURLOPT_PORT, 3600);*/ curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, Fields.size()); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, Fields.c_str()); diff --git a/src/Network/InitClient.cpp b/src/Network/InitClient.cpp index a5a9781..163e00a 100644 --- a/src/Network/InitClient.cpp +++ b/src/Network/InitClient.cpp @@ -75,7 +75,6 @@ void OnDisconnect(Client*c,bool kicked){ SendToAll(c, Packet,false,true); Packet.clear(); TriggerLuaEvent(Sec("onPlayerDisconnect"),false,nullptr,std::unique_ptr(new LuaArg{{c->GetID()}}),false); - c->ClearCars(); CI->RemoveClient(c); ///Removes the Client from existence } void OnConnect(Client*c){ diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index 6bd6f25..3d4fcb2 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -269,18 +269,20 @@ void UDPParser(Client* c, std::string Packet) { void LOOP() { DebugPrintTID(); while (UDPSock != -1) { - for (PacketData* p : DataAcks) { - if (p != nullptr) { - if (p->Client == nullptr || p->Client->GetTCPSock() == -1) { - DataAcks.erase(p); - break; - } - if (p->Tries < 15) { - UDPSend(p->Client, p->Data); - p->Tries++; - } else { - DataAcks.erase(p); - break; + if(!DataAcks.empty()) { + for (PacketData *p : DataAcks) { + if (p != nullptr) { + if (p->Client == nullptr || p->Client->GetTCPSock() == -1) { + DataAcks.erase(p); + break; + } + if (p->Tries < 15) { + UDPSend(p->Client, p->Data); + p->Tries++; + } else { + DataAcks.erase(p); + break; + } } } } @@ -306,7 +308,7 @@ void LOOP() { 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); + _Exit(-1); //return; } @@ -348,7 +350,7 @@ void LOOP() { 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); + _Exit(-1); //return; } diff --git a/src/Network/Websocket.cpp b/src/Network/Websocket.cpp index 9793c9a..feb1a75 100644 --- a/src/Network/Websocket.cpp +++ b/src/Network/Websocket.cpp @@ -46,7 +46,7 @@ void SyncData(){ }catch(std::exception const& e){ error(e.what()); std::this_thread::sleep_for(std::chrono::seconds(3)); - exit(0); + _Exit(0); }*/ } diff --git a/src/logger.cpp b/src/logger.cpp index 5b9e99a..b1fba55 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -10,16 +10,6 @@ #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 -} std::string getDate() { typedef std::chrono::duration>::type> days; @@ -67,6 +57,19 @@ void InitLog() { LFS.close(); } std::mutex LogLock; + +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 + LogLock.lock(); + std::stringstream Print; + Print << "(debug build) Thread '" << std::this_thread::get_id() << "' is " << func << "\n"; + ConsoleOut(Print.str()); + LogLock.unlock(); +#endif // DEBUG +} + void addToLog(const std::string& Line) { std::ofstream LFS; LFS.open(Sec("Server.log"), std::ios_base::app); @@ -103,7 +106,7 @@ void error(const std::string& toPrint) { ConsoleOut(Print); addToLog(Print); if (ECounter > 10) - exit(7); + _Exit(7); ECounter++; LogLock.unlock(); }