From 2e7f2cc6bd8359916c2c21b4cea916c51d701293 Mon Sep 17 00:00:00 2001 From: Anonymous275 Date: Sat, 19 Dec 2020 01:15:52 +0200 Subject: [PATCH] Support of 1Gps+ internet --- CMakeLists.txt | 10 ++-- include/Client.hpp | 6 +- include/Lua/LuaSystem.hpp | 4 +- include/Network.h | 3 +- src/Init/Heartbeat.cpp | 10 ++-- src/Init/Resources.cpp | 12 ++-- src/Init/Startup.cpp | 4 +- src/Lua/LuaSystem.cpp | 50 ++++++++++------ src/Network/Auth.cpp | 61 ++++++++++++++------ src/Network/Client.cpp | 12 +++- src/Network/GParser.cpp | 29 +++++----- src/Network/InitClient.cpp | 29 +++++----- src/Network/Sync.cpp | 114 +++++++++++++++++++++++++++---------- src/Network/TCPHandler.cpp | 22 +++---- 14 files changed, 233 insertions(+), 133 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 854ec52..90ff9eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,15 +8,15 @@ if (UNIX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic -static-libstdc++") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og -g") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -s -fno-builtin") -elseif (WIN32) +#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-") - 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}) + #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 () @@ -34,8 +34,8 @@ if (UNIX) target_link_libraries(BeamMP-Server z pthread stdc++fs ${Boost_LINK_DIRS} lua curl dl) elseif (WIN32) include(FindLua) - find_package(CURL CONFIG REQUIRED) find_package(ZLIB REQUIRED) + find_package(CURL CONFIG REQUIRED) target_link_libraries(BeamMP-Server PRIVATE ws2_32 CURL::libcurl ZLIB::ZLIB ${LUA_LIBRARIES}) #${Boost_LINK_DIRS} endif () diff --git a/include/Client.hpp b/include/Client.hpp index a48cfe8..ed646ab 100644 --- a/include/Client.hpp +++ b/include/Client.hpp @@ -24,11 +24,11 @@ struct VData{ class Client { private: std::set> VehicleData; //ID and Data; - std::string Name = Sec("Unknown Client"); + std::string Name = "Unknown Client"; + SOCKET SOCK[2]{SOCKET(-1)}; sockaddr_in UDPADDR; std::string Role; std::string DID; - SOCKET TCPSOCK; int Status = 0; int ID = -1; public: @@ -39,6 +39,7 @@ public: void SetRoles(const std::string& role); std::string GetCarData(int ident); void SetUDPAddr(sockaddr_in Addr); + void SetDownSock(SOCKET CSock); void SetTCPSock(SOCKET CSock); void SetStatus(int status); void DeleteCar(int ident); @@ -48,6 +49,7 @@ public: std::string GetName(); bool isSynced = false; bool isGuest = false; + SOCKET GetDownSock(); SOCKET GetTCPSock(); void SetID(int ID); int GetOpenCarID(); diff --git a/include/Lua/LuaSystem.hpp b/include/Lua/LuaSystem.hpp index 68dfe13..bc9f181 100644 --- a/include/Lua/LuaSystem.hpp +++ b/include/Lua/LuaSystem.hpp @@ -72,6 +72,6 @@ public: void SetStopThread(bool StopThread) { _StopThread = StopThread; } bool GetStopThread() const { return _StopThread; } }; -int CallFunction(Lua* lua, const std::string& FuncName, std::shared_ptr args); -int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, std::shared_ptr arg, bool Wait); +std::any CallFunction(Lua* lua, const std::string& FuncName, std::shared_ptr args); +std::any TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, std::shared_ptr arg, bool Wait); extern std::set> PluginEngine; diff --git a/include/Network.h b/include/Network.h index eae7590..db7986c 100644 --- a/include/Network.h +++ b/include/Network.h @@ -7,7 +7,7 @@ void TCPServerMain(); void UpdatePlayers(); void OnConnect(Client* c); -void InitClient(Client* c); +void TCPClient(Client* c); std::string TCPRcv(Client* c); void SyncResources(Client* c); [[noreturn]] void UDPServerMain(); @@ -16,5 +16,6 @@ void UDPSend(Client* c, std::string Data); void SendLarge(Client* c, std::string Data); bool TCPSend(Client* c, const std::string& Data); void GParser(Client* c, const std::string& Packet); +std::string StaticReason(bool Set,const std::string& R); void Respond(Client* c, const std::string& MSG, bool Rel); void SendToAll(Client* c, const std::string& Data, bool Self, bool Rel); diff --git a/src/Init/Heartbeat.cpp b/src/Init/Heartbeat.cpp index 12dc48e..49cce82 100644 --- a/src/Init/Heartbeat.cpp +++ b/src/Init/Heartbeat.cpp @@ -4,7 +4,6 @@ #include "Client.hpp" #include "Curl/Http.h" #include "Logger.h" -#include "Security/Enc.h" #include "Settings.h" #include #include @@ -38,12 +37,11 @@ std::string RunPromise(const std::string& IP, const std::string& R) { std::future f1 = task.get_future(); std::thread t(std::move(task)); t.detach(); - auto status = f1.wait_for(std::chrono::seconds(10)); + auto status = f1.wait_for(std::chrono::seconds(15)); 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); + error("Backend system Timeout please try again later"); + return ""; } [[noreturn]] void Heartbeat() { @@ -75,7 +73,7 @@ std::string RunPromise(const std::string& IP, const std::string& R) { WebsocketInit(); isAuth = true; } - std::this_thread::sleep_for(std::chrono::seconds(1)); + std::this_thread::sleep_for(std::chrono::seconds(5)); } } void HBInit() { diff --git a/src/Init/Resources.cpp b/src/Init/Resources.cpp index 5c11e7c..46eaf95 100644 --- a/src/Init/Resources.cpp +++ b/src/Init/Resources.cpp @@ -15,22 +15,20 @@ std::string FileList; int ModsLoaded = 0; void InitRes() { - std::string Path = Resource + Sec("/Client"); + std::string Path = Resource + "/Client"; if (!fs::exists(Path)) fs::create_directory(Path); for (const auto& entry : fs::directory_iterator(Path)) { - auto pos = entry.path().string().find(Sec(".zip")); + auto pos = entry.path().string().find(".zip"); if (pos != std::string::npos) { if (entry.path().string().length() - pos == 4) { FileList += entry.path().string() + ";"; - FileSizes += std::to_string(fs::file_size(entry.path())) + ";"; - MaxModSize += fs::file_size(entry.path()); + FileSizes += std::to_string(uint64_t(fs::file_size(entry.path()))) + ";"; + MaxModSize += uint64_t(fs::file_size(entry.path())); ModsLoaded++; } } } std::replace(FileList.begin(), FileList.end(), '\\', '/'); - if (ModsLoaded) { - info(Sec("Loaded ") + std::to_string(ModsLoaded) + Sec(" Mods")); - } + if(ModsLoaded)info("Loaded " + std::to_string(ModsLoaded) + " Mods"); } diff --git a/src/Init/Startup.cpp b/src/Init/Startup.cpp index ed927a5..c8b15f5 100644 --- a/src/Init/Startup.cpp +++ b/src/Init/Startup.cpp @@ -9,10 +9,10 @@ std::string CustomIP; std::string GetSVer() { - return std::string(Sec("1.20")); + return "1.20"; } std::string GetCVer() { - return std::string(Sec("1.71")); + return "1.72"; } void Args(int argc, char* argv[]) { info("BeamMP Server Running version " + GetSVer()); diff --git a/src/Lua/LuaSystem.cpp b/src/Lua/LuaSystem.cpp index 6126e4b..a9f413e 100644 --- a/src/Lua/LuaSystem.cpp +++ b/src/Lua/LuaSystem.cpp @@ -53,10 +53,10 @@ void SendError(lua_State* L, const std::string& msg) { } warn(a + Sec(" | Incorrect Call of ") + msg); } -int Trigger(Lua* lua, const std::string& R, std::shared_ptr arg) { +std::any Trigger(Lua* lua, const std::string& R, std::shared_ptr arg) { std::lock_guard lockGuard(lua->Lock); - std::packaged_task)> task([lua, R](std::shared_ptr arg) { return CallFunction(lua, R, arg); }); - std::future f1 = task.get_future(); + std::packaged_task)> task([lua, R](std::shared_ptr arg) { return CallFunction(lua, R, arg); }); + std::future f1 = task.get_future(); std::thread t(std::move(task), arg); t.detach(); auto status = f1.wait_for(std::chrono::seconds(5)); @@ -65,10 +65,10 @@ int Trigger(Lua* lua, const std::string& R, std::shared_ptr arg) { SendError(lua->GetState(), R + " took too long to respond"); return 0; } -int FutureWait(Lua* lua, const std::string& R, std::shared_ptr arg, bool Wait) { +std::any FutureWait(Lua* lua, const std::string& R, std::shared_ptr arg, bool Wait) { Assert(lua); - std::packaged_task)> task([lua, R](std::shared_ptr arg) { return Trigger(lua, R, arg); }); - std::future f1 = task.get_future(); + std::packaged_task)> task([lua, R](std::shared_ptr arg) { return Trigger(lua, R, arg); }); + std::future f1 = task.get_future(); std::thread t(std::move(task), arg); t.detach(); int T = 0; @@ -79,19 +79,30 @@ int FutureWait(Lua* lua, const std::string& R, std::shared_ptr arg, bool return f1.get(); return 0; } -int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, std::shared_ptr arg, bool Wait) { - int R = 0; +std::any TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, std::shared_ptr arg, bool Wait) { + std::any R; + std::string Type; + int Ret = 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), arg, Wait); + Type = R.type().name(); + if(Type.find("int") != std::string::npos){ + if(std::any_cast(R))Ret++; + }else if(Event == "onPlayerAuth") return R; } - } else - R += FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait); + }else{ + R = FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait); + Type = R.type().name(); + if(Type.find("int") != std::string::npos){ + if(std::any_cast(R))Ret++; + }else if(Event == "onPlayerAuth") return R; + } } } - return R; + return Ret; } bool ConsoleCheck(lua_State* L, int r) { if (r != LUA_OK) { @@ -345,9 +356,7 @@ int lua_dropPlayer(lua_State* L) { c->SetStatus(-2); info(Sec("Closing socket due to kick")); CloseSocketProper(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) { @@ -432,7 +441,12 @@ int lua_RemoteEvent(lua_State* L) { } return 0; } -int lua_ServerExit(lua_State*) { +int lua_ServerExit(lua_State*L) { + if(lua_gettop(L) > 0){ + if(lua_isnumber(L,1)){ + _Exit(int(lua_tointeger(L, 1))); + } + } _Exit(0); } int lua_Set(lua_State* L) { @@ -557,7 +571,7 @@ std::string Lua::GetOrigin() { return fs::path(GetFileName()).filename().string(); } -int CallFunction(Lua* lua, const std::string& FuncName, std::shared_ptr Arg) { +std::any CallFunction(Lua* lua, const std::string& FuncName, std::shared_ptr Arg) { lua_State* luaState = lua->GetState(); lua_getglobal(luaState, FuncName.c_str()); if (lua_isfunction(luaState, -1)) { @@ -571,6 +585,8 @@ int CallFunction(Lua* lua, const std::string& FuncName, std::shared_ptr if (CheckLua(luaState, R)) { if (lua_isnumber(luaState, -1)) { return int(lua_tointeger(luaState, -1)); + }else if(lua_isstring(luaState,-1)){ + return std::string(lua_tostring(luaState,-1)); } } } diff --git a/src/Network/Auth.cpp b/src/Network/Auth.cpp index fb574a6..b211f76 100644 --- a/src/Network/Auth.cpp +++ b/src/Network/Auth.cpp @@ -25,9 +25,6 @@ std::string GetClientInfo(const std::string& PK) { Client* CreateClient(SOCKET TCPSock) { auto* c = new Client; c->SetTCPSock(TCPSock); - //c->SetRoles(Roles); - //c->isGuest = Guest; - //c->SetName(Name); return c; } @@ -38,7 +35,7 @@ void ClientKick(Client* c, const std::string& R){ } -void Identification(SOCKET TCPSock) { +void Authentication(SOCKET TCPSock) { DebugPrintTID(); auto* c = CreateClient(TCPSock); @@ -84,7 +81,7 @@ void Identification(SOCKET TCPSock) { debug("Name -> " + c->GetName() + ", Guest -> " + std::to_string(c->isGuest) + ", Roles -> " + c->GetRoles()); for (auto& Cl : CI->Clients) { if (Cl != nullptr) { - if (Cl->GetName() == c->GetName()) { + if (Cl->GetName() == c->GetName() && Cl->isGuest == c->isGuest) { info("Old client (" +Cl->GetName()+ ") kicked: Reconnecting"); CloseSocketProper(Cl->GetTCPSock()); Cl->SetStatus(-2); @@ -92,26 +89,58 @@ void Identification(SOCKET TCPSock) { } } } + auto arg = std::make_unique(LuaArg{{c->GetName(),c->GetRoles(),c->isGuest}}); - int Res = TriggerLuaEvent("onPlayerAuth",false,nullptr, std::move(arg), true); - if(Res){ + std::any Res = TriggerLuaEvent("onPlayerAuth",false,nullptr, std::move(arg), true); + std::string Type = Res.type().name(); + if(Type.find("int") != std::string::npos && std::any_cast(Res)){ ClientKick(c,"you are not allowed on the server!"); return; + }else if(Type.find("string") != std::string::npos){ + ClientKick(c,std::any_cast(Res)); + return; } if (CI->Size() < MaxPlayers) { info("Identification success"); Client& Client = *c; CI->AddClient(std::move(c)); - InitClient(&Client); + TCPClient(&Client); } else ClientKick(c,"Server full!"); } +void HandleDownload(SOCKET TCPSock){ + char D; + if(recv(TCPSock,&D,1,0) != 1){ + CloseSocketProper(TCPSock); + return; + } + auto ID = uint8_t(D); + for(auto& c : CI->Clients){ + if(c->GetID() == ID){ + c->SetDownSock(TCPSock); + } + } +} + +void Identify(SOCKET TCPSock){ + char Code; + if(recv(TCPSock,&Code,1,0) != 1) { + CloseSocketProper(TCPSock); + return; + } + if(Code == 'C'){ + Authentication(TCPSock); + }else if(Code == 'D'){ + HandleDownload(TCPSock); + }else CloseSocketProper(TCPSock); +} + void TCPServerMain() { DebugPrintTID(); #ifdef WIN32 WSADATA wsaData; if (WSAStartup(514, &wsaData)) { - error(Sec("Can't start Winsock!")); + error("Can't start Winsock!"); return; } SOCKET client, Listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); @@ -120,30 +149,30 @@ void TCPServerMain() { addr.sin_family = AF_INET; addr.sin_port = htons(Port); if (bind(Listener, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) { - error(Sec("Can't bind socket! ") + std::to_string(WSAGetLastError())); + error("Can't bind socket! " + std::to_string(WSAGetLastError())); std::this_thread::sleep_for(std::chrono::seconds(5)); _Exit(-1); } if (Listener == -1) { - error(Sec("Invalid listening socket")); + error("Invalid listening socket"); return; } if (listen(Listener, SOMAXCONN)) { - error(Sec("listener failed ") + std::to_string(GetLastError())); + error("listener failed " + std::to_string(GetLastError())); return; } - info(Sec("Vehicle event network online")); + info("Vehicle event network online"); do { try { client = accept(Listener, nullptr, nullptr); if (client == -1) { - warn(Sec("Got an invalid client socket on connect! Skipping...")); + warn("Got an invalid client socket on connect! Skipping..."); continue; } - std::thread ID(Identification, client); + std::thread ID(Identify, client); ID.detach(); } catch (const std::exception& e) { - error(Sec("fatal: ") + std::string(e.what())); + error("fatal: " + std::string(e.what())); } } while (client); diff --git a/src/Network/Client.cpp b/src/Network/Client.cpp index f8a8d69..c2dd858 100644 --- a/src/Network/Client.cpp +++ b/src/Network/Client.cpp @@ -32,15 +32,23 @@ int Client::GetStatus() { void Client::SetUDPAddr(sockaddr_in Addr) { UDPADDR = Addr; } + +void Client::SetDownSock(SOCKET CSock){ + SOCK[1] = CSock; +} +SOCKET Client::GetDownSock(){ + return SOCK[1]; +} sockaddr_in Client::GetUDPAddr() { return UDPADDR; } void Client::SetTCPSock(SOCKET CSock) { - TCPSOCK = CSock; + SOCK[0] = CSock; } SOCKET Client::GetTCPSock() { - return TCPSOCK; + return SOCK[0]; } + void Client::DeleteCar(int ident) { for (auto& v : VehicleData) { if (v != nullptr && v->ID == ident) { diff --git a/src/Network/GParser.cpp b/src/Network/GParser.cpp index 6058a9f..f39fbae 100644 --- a/src/Network/GParser.cpp +++ b/src/Network/GParser.cpp @@ -49,7 +49,8 @@ void VehicleParser(Client* c, const std::string& Pckt) { int CarID = c->GetOpenCarID(); debug(c->GetName() + Sec(" created a car with ID ") + std::to_string(CarID)); Packet = "Os:" + c->GetRoles() + ":" + c->GetName() + ":" + std::to_string(c->GetID()) + "-" + std::to_string(CarID) + Packet.substr(4); - if (c->GetCarCount() >= MaxCars || TriggerLuaEvent(Sec("onVehicleSpawn"), false, nullptr, std::make_unique(LuaArg { { c->GetID(), CarID, Packet.substr(3) } }), true)) { + auto Res = TriggerLuaEvent(Sec("onVehicleSpawn"), false, nullptr, std::make_unique(LuaArg { { c->GetID(), CarID, Packet.substr(3) } }), true); + if (c->GetCarCount() >= MaxCars || std::any_cast(Res)) { Respond(c, Packet, true); std::string Destroy = "Od:" + std::to_string(c->GetID()) + "-" + std::to_string(CarID); Respond(c, Destroy, true); @@ -71,9 +72,10 @@ void VehicleParser(Client* c, const std::string& Pckt) { VID = stoi(vid); } if (PID != -1 && VID != -1 && PID == c->GetID()) { - if (!TriggerLuaEvent(Sec("onVehicleEdited"), false, nullptr, - std::unique_ptr(new LuaArg { { c->GetID(), VID, Packet.substr(3) } }), - true)) { + auto Res = TriggerLuaEvent(Sec("onVehicleEdited"), false, nullptr, + std::make_unique(LuaArg { { c->GetID(), VID, Packet.substr(3) } }), + true); + if (!std::any_cast(Res)) { SendToAll(c, Packet, false, true); Apply(c, VID, Packet); } else { @@ -96,7 +98,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, - std::unique_ptr(new LuaArg { { c->GetID(), VID } }), false); + std::make_unique(LuaArg { { c->GetID(), VID } }), false); c->DeleteCar(VID); debug(c->GetName() + Sec(" deleted car with ID ") + std::to_string(VID)); } @@ -128,7 +130,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, std::unique_ptr(new LuaArg { { c->GetID() } }), false); + TriggerLuaEvent(Sec("onPlayerJoin"), false, nullptr, std::make_unique(LuaArg { { c->GetID() } }), false); for (auto& client : CI->Clients) { if (client != nullptr) { if (client.get() != c) { @@ -166,7 +168,7 @@ void HandleEvent(Client* c, const std::string& Data) { Name = t; break; case 2: - TriggerLuaEvent(Name, false, nullptr, std::unique_ptr(new LuaArg { { c->GetID(), t } }), false); + TriggerLuaEvent(Name, false, nullptr, std::make_unique(LuaArg { { c->GetID(), t } }), false); break; default: break; @@ -181,6 +183,7 @@ void GlobalParser(Client* c, const std::string& Pack) { Assert(c); if (Pack.empty() || c == nullptr) return; + std::any Res; std::string Packet = Pack.substr(0, strlen(Pack.c_str())); std::string pct; char Code = Packet.at(0); @@ -192,11 +195,10 @@ void GlobalParser(Client* c, const std::string& Pack) { return; } switch (Code) { - case 'P': // initial connection + case 'H': // initial connection #ifdef DEBUG - debug(std::string(Sec("got 'P' packet: '")) + Pack + Sec("' (") + std::to_string(Packet.size()) + Sec(")")); + debug(std::string("got 'H' packet: '") + Pack + "' (" + std::to_string(Packet.size()) + ")"); #endif - Respond(c, Sec("P") + std::to_string(c->GetID()), true); SyncClient(c); return; case 'p': @@ -221,10 +223,9 @@ void GlobalParser(Client* c, const std::string& Pack) { #endif if (Packet.length() < 4 || Packet.find(':', 3) == std::string::npos) break; - if (TriggerLuaEvent(Sec("onChatMessage"), false, nullptr, - std::unique_ptr(new LuaArg { - { c->GetID(), c->GetName(), Packet.substr(Packet.find(':', 3) + 1) } }), - true)) + Res = TriggerLuaEvent("onChatMessage", false, nullptr,std::make_unique(LuaArg { + { c->GetID(), c->GetName(), Packet.substr(Packet.find(':', 3) + 1) } }),true); + if (std::any_cast(Res)) break; SendToAll(nullptr, Packet, true, true); return; diff --git a/src/Network/InitClient.cpp b/src/Network/InitClient.cpp index 097392c..20340ea 100644 --- a/src/Network/InitClient.cpp +++ b/src/Network/InitClient.cpp @@ -1,14 +1,16 @@ /// /// Created by Anonymous275 on 8/1/2020 /// -#include "Client.hpp" - -#include -#include "Logger.h" #include "Lua/LuaSystem.hpp" -#include "Network.h" -#include "Security/Enc.h" +#include "Client.hpp" +#include "UnixCompat.h" #include "Settings.h" +#include "Network.h" +#include "Logger.h" +#include + + + int OpenID() { int ID = 0; bool found; @@ -83,18 +85,19 @@ void OnDisconnect(Client* c, bool kicked) { SendToAll(c, Packet, false, true); Packet.clear(); TriggerLuaEvent(Sec("onPlayerDisconnect"), false, nullptr, std::make_unique(LuaArg { { c->GetID() } }), false); + if(c->GetTCPSock())CloseSocketProper(c->GetTCPSock()); + if(c->GetDownSock())CloseSocketProper(c->GetDownSock()); CI->RemoveClient(c); ///Removes the Client from existence } void OnConnect(Client* c) { Assert(c); - info(Sec("Client connected")); + info("Client connected"); c->SetID(OpenID()); - info(Sec("Assigned ID ") + std::to_string(c->GetID()) + Sec(" to ") + c->GetName()); - TriggerLuaEvent(Sec("onPlayerConnecting"), false, nullptr, std::make_unique(LuaArg { { c->GetID() } }), false); + info("Assigned ID " + std::to_string(c->GetID()) +" to " + c->GetName()); + TriggerLuaEvent("onPlayerConnecting", false, nullptr, std::make_unique(LuaArg { { c->GetID() } }), false); SyncResources(c); - if (c->GetStatus() < 0) - return; + 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, std::make_unique(LuaArg { { c->GetID() } }), false); + info(c->GetName() +" : Connected"); + TriggerLuaEvent("onPlayerJoining", false, nullptr, std::make_unique(LuaArg { { c->GetID() } }), false); } diff --git a/src/Network/Sync.cpp b/src/Network/Sync.cpp index 571d12e..fc863a0 100644 --- a/src/Network/Sync.cpp +++ b/src/Network/Sync.cpp @@ -5,48 +5,97 @@ #include "UnixCompat.h" #include "Settings.h" #include "Client.hpp" +#include #include "Network.h" #include "Logger.h" #include -#ifdef __linux -// we need this for `struct stat` -#include -#endif // __linux -void SendFile(Client* c, const std::string& Name) { - Assert(c); - info(c->GetName() + " requesting : " + Name.substr(Name.find_last_of('/'))); - struct stat Info { }; - if (stat(Name.c_str(), &Info) != 0) { - TCPSend(c, "Cannot Open"); - return; - } +bool TCPSendRaw(SOCKET C, char* Data, int32_t Size){ + int64_t Sent = 0, Temp; + do { + Temp = send(C, &Data[Sent], int(Size - Sent), 0); + if(Temp < 1) { + info("Socket Closed! " + std::to_string(C)); + CloseSocketProper(C); + return false; + } + Sent += Temp; + } while (Sent < Size); + return true; +} + +void SplitLoad(Client*c,int64_t Sent,int64_t Size, bool D,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(); - auto Size = size_t(fileSize); - size_t Sent = 0; - size_t Diff; - int64_t Split = 64000; + int32_t Split = 0x7735940; //125MB + int64_t Diff; + char* Data; + if(Size > Split)Data = new char[Split]; + else Data = new char[Size]; + SOCKET TCPSock = c->GetTCPSock(); + if(D){ + TCPSock = c->GetDownSock(); + } + info("Split load Socket " + std::to_string(TCPSock)); while (c->GetStatus() > -1 && Sent < Size) { Diff = Size - Sent; - if (Diff > size_t(Split)) { - std::string Data(size_t(Split), 0); - f.seekg(int64_t(Sent), std::ios_base::beg); - f.read(&Data[0], Split); - TCPSend(c, Data); - Sent += size_t(Split); + if (Diff > Split) { + f.seekg(Sent, std::ios_base::beg); + f.read(Data, Split); + if(!TCPSendRaw(TCPSock, Data, Split)){ + if(c->GetStatus() > -1)c->SetStatus(-1); + break; + } + Sent += Split; } else { - std::string Data(Diff, 0); - f.seekg(int64_t(Sent), std::ios_base::beg); - f.read(&Data[0], int64_t(Diff)); - TCPSend(c, Data); + f.seekg(Sent, std::ios_base::beg); + f.read(Data, Diff); + if(!TCPSendRaw(TCPSock, Data, int32_t(Diff))){ + if(c->GetStatus() > -1)c->SetStatus(-1); + break; + } Sent += Diff; } } + delete[] Data; f.close(); } + +void SendFile(Client*c, const std::string& Name) { + Assert(c); + info(c->GetName() + " requesting : " + Name.substr(Name.find_last_of('/'))); + + if(!std::filesystem::exists(Name)) { + TCPSend(c, "CO"); + warn("File " + Name + " could not be accessed!"); + return; + }else TCPSend(c, "AG"); + + ///Wait for connections + int T = 0; + while(c->GetDownSock() < 1 && T < 30){ + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + T++; + } + + + if(c->GetDownSock() < 1){ + error("Client doesn't have a download socket!"); + if(c->GetStatus() > -1)c->SetStatus(-1); + return; + } + + + int64_t Size = std::filesystem::file_size(Name), MSize = Size/2; + + std::thread Dt(SplitLoad,c,0,MSize,false,Name); + Dt.detach(); + + SplitLoad(c,MSize,Size,true,Name); + + if(Dt.joinable())Dt.join(); +} + void Parse(Client* c, const std::string& Packet) { Assert(c); if (c == nullptr || Packet.empty()) @@ -62,8 +111,7 @@ void Parse(Client* c, const std::string& Packet) { if (SubCode == 'R') { debug(Sec("Sending Mod Info")); std::string ToSend = FileList + FileSizes; - if (ToSend.empty()) - ToSend = "-"; + if (ToSend.empty())ToSend = "-"; TCPSend(c, ToSend); } return; @@ -75,16 +123,20 @@ void Parse(Client* c, const std::string& Packet) { void SyncResources(Client* c) { Assert(c); if (c == nullptr)return; +#ifndef DEBUG try { - TCPSend(c, "WS"); +#endif + TCPSend(c, "P" + std::to_string(c->GetID())); std::string Data; while (c->GetStatus() > -1){ Data = TCPRcv(c); if(Data == "Done")break; Parse(c, Data); } +#ifndef DEBUG } catch (std::exception& e) { except("Exception! : " + std::string(e.what())); c->SetStatus(-1); } +#endif } diff --git a/src/Network/TCPHandler.cpp b/src/Network/TCPHandler.cpp index 97f695f..0a32089 100644 --- a/src/Network/TCPHandler.cpp +++ b/src/Network/TCPHandler.cpp @@ -1,20 +1,17 @@ /// /// Created by Anonymous275 on 8/1/2020 /// -#include "Compressor.h" -#include "Logger.h" -#include "Network.h" #include "Security/Enc.h" #include "UnixCompat.h" +#include "Compressor.h" +#include "Network.h" +#include "Logger.h" #include bool TCPSend(Client* c, const std::string& Data) { Assert(c); - if (c == nullptr) - return false; - // Size is BIG ENDIAN now, use only for header! - //auto Size = htonl(int32_t(Data.size())); - ///TODO : BIG ENDIAN for other OS + if (c == nullptr)return false; + int32_t Size, Sent, Temp; std::string Send(4, 0); Size = int32_t(Data.size()); @@ -31,7 +28,6 @@ bool TCPSend(Client* c, const std::string& Data) { } else if (Temp < 0) { if (c->GetStatus() > -1) c->SetStatus(-1); - // info(Sec("Closing socket, Temp < 0")); CloseSocketProper(c->GetTCPSock()); return false; } @@ -43,7 +39,7 @@ bool TCPSend(Client* c, const std::string& Data) { bool CheckBytes(Client* c, int32_t BytesRcv) { Assert(c); if (BytesRcv == 0) { - debug(Sec("(TCP) Connection closing...")); + debug("(TCP) Connection closing..."); if (c->GetStatus() > -1) c->SetStatus(-1); return false; @@ -122,7 +118,7 @@ std::string TCPRcv(Client* c) { } void TCPClient(Client* c) { - DebugPrintTIDInternal(Sec("Client(") + c->GetName() + Sec(")"), true); + DebugPrintTIDInternal("Client(" + c->GetName() + ")", true); Assert(c); if (c->GetTCPSock() == -1) { CI->RemoveClient(c); @@ -134,7 +130,3 @@ void TCPClient(Client* c) { } OnDisconnect(c, c->GetStatus() == -2); } -void InitClient(Client* c) { - std::thread NewClient(TCPClient, c); - NewClient.detach(); -}