Support of 1Gps+ internet

This commit is contained in:
Anonymous275 2020-12-19 01:15:52 +02:00
parent 19b7f7f579
commit 2e7f2cc6bd
14 changed files with 233 additions and 133 deletions

View File

@ -8,15 +8,15 @@ if (UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic -static-libstdc++") 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_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og -g")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -s -fno-builtin") 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 # 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: # completely cross platform. For fixes to common issues arising from /permissive- visit:
# https://docs.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance # https://docs.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /permissive-") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /permissive-")
message(STATUS "MSVC -> forcing use of statically-linked runtime.") #message(STATUS "MSVC -> forcing use of statically-linked runtime.")
STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) #STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) #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 #-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static
endif () endif ()
@ -34,8 +34,8 @@ if (UNIX)
target_link_libraries(BeamMP-Server z pthread stdc++fs ${Boost_LINK_DIRS} lua curl dl) target_link_libraries(BeamMP-Server z pthread stdc++fs ${Boost_LINK_DIRS} lua curl dl)
elseif (WIN32) elseif (WIN32)
include(FindLua) include(FindLua)
find_package(CURL CONFIG REQUIRED)
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
find_package(CURL CONFIG REQUIRED)
target_link_libraries(BeamMP-Server PRIVATE ws2_32 CURL::libcurl ZLIB::ZLIB ${LUA_LIBRARIES}) target_link_libraries(BeamMP-Server PRIVATE ws2_32 CURL::libcurl ZLIB::ZLIB ${LUA_LIBRARIES})
#${Boost_LINK_DIRS} #${Boost_LINK_DIRS}
endif () endif ()

View File

@ -24,11 +24,11 @@ struct VData{
class Client { class Client {
private: private:
std::set<std::unique_ptr<VData>> VehicleData; //ID and Data; std::set<std::unique_ptr<VData>> VehicleData; //ID and Data;
std::string Name = Sec("Unknown Client"); std::string Name = "Unknown Client";
SOCKET SOCK[2]{SOCKET(-1)};
sockaddr_in UDPADDR; sockaddr_in UDPADDR;
std::string Role; std::string Role;
std::string DID; std::string DID;
SOCKET TCPSOCK;
int Status = 0; int Status = 0;
int ID = -1; int ID = -1;
public: public:
@ -39,6 +39,7 @@ public:
void SetRoles(const std::string& role); void SetRoles(const std::string& role);
std::string GetCarData(int ident); std::string GetCarData(int ident);
void SetUDPAddr(sockaddr_in Addr); void SetUDPAddr(sockaddr_in Addr);
void SetDownSock(SOCKET CSock);
void SetTCPSock(SOCKET CSock); void SetTCPSock(SOCKET CSock);
void SetStatus(int status); void SetStatus(int status);
void DeleteCar(int ident); void DeleteCar(int ident);
@ -48,6 +49,7 @@ public:
std::string GetName(); std::string GetName();
bool isSynced = false; bool isSynced = false;
bool isGuest = false; bool isGuest = false;
SOCKET GetDownSock();
SOCKET GetTCPSock(); SOCKET GetTCPSock();
void SetID(int ID); void SetID(int ID);
int GetOpenCarID(); int GetOpenCarID();

View File

@ -72,6 +72,6 @@ public:
void SetStopThread(bool StopThread) { _StopThread = StopThread; } void SetStopThread(bool StopThread) { _StopThread = StopThread; }
bool GetStopThread() const { return _StopThread; } bool GetStopThread() const { return _StopThread; }
}; };
int CallFunction(Lua* lua, const std::string& FuncName, std::shared_ptr<LuaArg> args); std::any CallFunction(Lua* lua, const std::string& FuncName, std::shared_ptr<LuaArg> args);
int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, std::shared_ptr<LuaArg> arg, bool Wait); std::any TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, std::shared_ptr<LuaArg> arg, bool Wait);
extern std::set<std::unique_ptr<Lua>> PluginEngine; extern std::set<std::unique_ptr<Lua>> PluginEngine;

View File

@ -7,7 +7,7 @@
void TCPServerMain(); void TCPServerMain();
void UpdatePlayers(); void UpdatePlayers();
void OnConnect(Client* c); void OnConnect(Client* c);
void InitClient(Client* c); void TCPClient(Client* c);
std::string TCPRcv(Client* c); std::string TCPRcv(Client* c);
void SyncResources(Client* c); void SyncResources(Client* c);
[[noreturn]] void UDPServerMain(); [[noreturn]] void UDPServerMain();
@ -16,5 +16,6 @@ void UDPSend(Client* c, std::string Data);
void SendLarge(Client* c, std::string Data); void SendLarge(Client* c, std::string Data);
bool TCPSend(Client* c, const std::string& Data); bool TCPSend(Client* c, const std::string& Data);
void GParser(Client* c, const std::string& Packet); 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 Respond(Client* c, const std::string& MSG, bool Rel);
void SendToAll(Client* c, const std::string& Data, bool Self, bool Rel); void SendToAll(Client* c, const std::string& Data, bool Self, bool Rel);

View File

@ -4,7 +4,6 @@
#include "Client.hpp" #include "Client.hpp"
#include "Curl/Http.h" #include "Curl/Http.h"
#include "Logger.h" #include "Logger.h"
#include "Security/Enc.h"
#include "Settings.h" #include "Settings.h"
#include <chrono> #include <chrono>
#include <future> #include <future>
@ -38,12 +37,11 @@ std::string RunPromise(const std::string& IP, const std::string& R) {
std::future<std::string> f1 = task.get_future(); std::future<std::string> f1 = task.get_future();
std::thread t(std::move(task)); std::thread t(std::move(task));
t.detach(); 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) if (status != std::future_status::timeout)
return f1.get(); return f1.get();
error(Sec("Backend system Timeout please try again later")); error("Backend system Timeout please try again later");
std::this_thread::sleep_for(std::chrono::seconds(3)); return "";
_Exit(0);
} }
[[noreturn]] void Heartbeat() { [[noreturn]] void Heartbeat() {
@ -75,7 +73,7 @@ std::string RunPromise(const std::string& IP, const std::string& R) {
WebsocketInit(); WebsocketInit();
isAuth = true; isAuth = true;
} }
std::this_thread::sleep_for(std::chrono::seconds(1)); std::this_thread::sleep_for(std::chrono::seconds(5));
} }
} }
void HBInit() { void HBInit() {

View File

@ -15,22 +15,20 @@ std::string FileList;
int ModsLoaded = 0; int ModsLoaded = 0;
void InitRes() { void InitRes() {
std::string Path = Resource + Sec("/Client"); std::string Path = Resource + "/Client";
if (!fs::exists(Path)) if (!fs::exists(Path))
fs::create_directory(Path); fs::create_directory(Path);
for (const auto& entry : fs::directory_iterator(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 (pos != std::string::npos) {
if (entry.path().string().length() - pos == 4) { if (entry.path().string().length() - pos == 4) {
FileList += entry.path().string() + ";"; FileList += entry.path().string() + ";";
FileSizes += std::to_string(fs::file_size(entry.path())) + ";"; FileSizes += std::to_string(uint64_t(fs::file_size(entry.path()))) + ";";
MaxModSize += fs::file_size(entry.path()); MaxModSize += uint64_t(fs::file_size(entry.path()));
ModsLoaded++; ModsLoaded++;
} }
} }
} }
std::replace(FileList.begin(), FileList.end(), '\\', '/'); std::replace(FileList.begin(), FileList.end(), '\\', '/');
if (ModsLoaded) { if(ModsLoaded)info("Loaded " + std::to_string(ModsLoaded) + " Mods");
info(Sec("Loaded ") + std::to_string(ModsLoaded) + Sec(" Mods"));
}
} }

View File

@ -9,10 +9,10 @@
std::string CustomIP; std::string CustomIP;
std::string GetSVer() { std::string GetSVer() {
return std::string(Sec("1.20")); return "1.20";
} }
std::string GetCVer() { std::string GetCVer() {
return std::string(Sec("1.71")); return "1.72";
} }
void Args(int argc, char* argv[]) { void Args(int argc, char* argv[]) {
info("BeamMP Server Running version " + GetSVer()); info("BeamMP Server Running version " + GetSVer());

View File

@ -53,10 +53,10 @@ void SendError(lua_State* L, const std::string& msg) {
} }
warn(a + Sec(" | Incorrect Call of ") + msg); warn(a + Sec(" | Incorrect Call of ") + msg);
} }
int Trigger(Lua* lua, const std::string& R, std::shared_ptr<LuaArg> arg) { std::any Trigger(Lua* lua, const std::string& R, std::shared_ptr<LuaArg> arg) {
std::lock_guard<std::mutex> lockGuard(lua->Lock); std::lock_guard<std::mutex> lockGuard(lua->Lock);
std::packaged_task<int(std::shared_ptr<LuaArg>)> task([lua, R](std::shared_ptr<LuaArg> arg) { return CallFunction(lua, R, arg); }); std::packaged_task<std::any(std::shared_ptr<LuaArg>)> task([lua, R](std::shared_ptr<LuaArg> arg) { return CallFunction(lua, R, arg); });
std::future<int> f1 = task.get_future(); std::future<std::any> f1 = task.get_future();
std::thread t(std::move(task), arg); std::thread t(std::move(task), arg);
t.detach(); t.detach();
auto status = f1.wait_for(std::chrono::seconds(5)); auto status = f1.wait_for(std::chrono::seconds(5));
@ -65,10 +65,10 @@ int Trigger(Lua* lua, const std::string& R, std::shared_ptr<LuaArg> arg) {
SendError(lua->GetState(), R + " took too long to respond"); SendError(lua->GetState(), R + " took too long to respond");
return 0; return 0;
} }
int FutureWait(Lua* lua, const std::string& R, std::shared_ptr<LuaArg> arg, bool Wait) { std::any FutureWait(Lua* lua, const std::string& R, std::shared_ptr<LuaArg> arg, bool Wait) {
Assert(lua); Assert(lua);
std::packaged_task<int(std::shared_ptr<LuaArg>)> task([lua, R](std::shared_ptr<LuaArg> arg) { return Trigger(lua, R, arg); }); std::packaged_task<std::any(std::shared_ptr<LuaArg>)> task([lua, R](std::shared_ptr<LuaArg> arg) { return Trigger(lua, R, arg); });
std::future<int> f1 = task.get_future(); std::future<std::any> f1 = task.get_future();
std::thread t(std::move(task), arg); std::thread t(std::move(task), arg);
t.detach(); t.detach();
int T = 0; int T = 0;
@ -79,19 +79,30 @@ int FutureWait(Lua* lua, const std::string& R, std::shared_ptr<LuaArg> arg, bool
return f1.get(); return f1.get();
return 0; return 0;
} }
int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, std::shared_ptr<LuaArg> arg, bool Wait) { std::any TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, std::shared_ptr<LuaArg> arg, bool Wait) {
int R = 0; std::any R;
std::string Type;
int Ret = 0;
for (auto& Script : PluginEngine) { for (auto& Script : PluginEngine) {
if (Script->IsRegistered(Event)) { if (Script->IsRegistered(Event)) {
if (local) { if (local) {
if (Script->GetPluginName() == Caller->GetPluginName()) { 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<int>(R))Ret++;
}else if(Event == "onPlayerAuth") return R;
} }
} else }else{
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<int>(R))Ret++;
}else if(Event == "onPlayerAuth") return R;
}
} }
} }
return R; return Ret;
} }
bool ConsoleCheck(lua_State* L, int r) { bool ConsoleCheck(lua_State* L, int r) {
if (r != LUA_OK) { if (r != LUA_OK) {
@ -345,9 +356,7 @@ int lua_dropPlayer(lua_State* L) {
c->SetStatus(-2); c->SetStatus(-2);
info(Sec("Closing socket due to kick")); info(Sec("Closing socket due to kick"));
CloseSocketProper(c->GetTCPSock()); CloseSocketProper(c->GetTCPSock());
} else SendError(L, Sec("DropPlayer not enough arguments"));
} else
SendError(L, Sec("DropPlayer not enough arguments"));
return 0; return 0;
} }
int lua_sendChat(lua_State* L) { int lua_sendChat(lua_State* L) {
@ -432,7 +441,12 @@ int lua_RemoteEvent(lua_State* L) {
} }
return 0; 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); _Exit(0);
} }
int lua_Set(lua_State* L) { int lua_Set(lua_State* L) {
@ -557,7 +571,7 @@ std::string Lua::GetOrigin() {
return fs::path(GetFileName()).filename().string(); return fs::path(GetFileName()).filename().string();
} }
int CallFunction(Lua* lua, const std::string& FuncName, std::shared_ptr<LuaArg> Arg) { std::any CallFunction(Lua* lua, const std::string& FuncName, std::shared_ptr<LuaArg> Arg) {
lua_State* luaState = lua->GetState(); lua_State* luaState = lua->GetState();
lua_getglobal(luaState, FuncName.c_str()); lua_getglobal(luaState, FuncName.c_str());
if (lua_isfunction(luaState, -1)) { if (lua_isfunction(luaState, -1)) {
@ -571,6 +585,8 @@ int CallFunction(Lua* lua, const std::string& FuncName, std::shared_ptr<LuaArg>
if (CheckLua(luaState, R)) { if (CheckLua(luaState, R)) {
if (lua_isnumber(luaState, -1)) { if (lua_isnumber(luaState, -1)) {
return int(lua_tointeger(luaState, -1)); return int(lua_tointeger(luaState, -1));
}else if(lua_isstring(luaState,-1)){
return std::string(lua_tostring(luaState,-1));
} }
} }
} }

View File

@ -25,9 +25,6 @@ std::string GetClientInfo(const std::string& PK) {
Client* CreateClient(SOCKET TCPSock) { Client* CreateClient(SOCKET TCPSock) {
auto* c = new Client; auto* c = new Client;
c->SetTCPSock(TCPSock); c->SetTCPSock(TCPSock);
//c->SetRoles(Roles);
//c->isGuest = Guest;
//c->SetName(Name);
return c; return c;
} }
@ -38,7 +35,7 @@ void ClientKick(Client* c, const std::string& R){
} }
void Identification(SOCKET TCPSock) { void Authentication(SOCKET TCPSock) {
DebugPrintTID(); DebugPrintTID();
auto* c = CreateClient(TCPSock); 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()); debug("Name -> " + c->GetName() + ", Guest -> " + std::to_string(c->isGuest) + ", Roles -> " + c->GetRoles());
for (auto& Cl : CI->Clients) { for (auto& Cl : CI->Clients) {
if (Cl != nullptr) { if (Cl != nullptr) {
if (Cl->GetName() == c->GetName()) { if (Cl->GetName() == c->GetName() && Cl->isGuest == c->isGuest) {
info("Old client (" +Cl->GetName()+ ") kicked: Reconnecting"); info("Old client (" +Cl->GetName()+ ") kicked: Reconnecting");
CloseSocketProper(Cl->GetTCPSock()); CloseSocketProper(Cl->GetTCPSock());
Cl->SetStatus(-2); Cl->SetStatus(-2);
@ -92,26 +89,58 @@ void Identification(SOCKET TCPSock) {
} }
} }
} }
auto arg = std::make_unique<LuaArg>(LuaArg{{c->GetName(),c->GetRoles(),c->isGuest}}); auto arg = std::make_unique<LuaArg>(LuaArg{{c->GetName(),c->GetRoles(),c->isGuest}});
int Res = TriggerLuaEvent("onPlayerAuth",false,nullptr, std::move(arg), true); std::any Res = TriggerLuaEvent("onPlayerAuth",false,nullptr, std::move(arg), true);
if(Res){ std::string Type = Res.type().name();
if(Type.find("int") != std::string::npos && std::any_cast<int>(Res)){
ClientKick(c,"you are not allowed on the server!"); ClientKick(c,"you are not allowed on the server!");
return; return;
}else if(Type.find("string") != std::string::npos){
ClientKick(c,std::any_cast<std::string>(Res));
return;
} }
if (CI->Size() < MaxPlayers) { if (CI->Size() < MaxPlayers) {
info("Identification success"); info("Identification success");
Client& Client = *c; Client& Client = *c;
CI->AddClient(std::move(c)); CI->AddClient(std::move(c));
InitClient(&Client); TCPClient(&Client);
} else ClientKick(c,"Server full!"); } 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() { void TCPServerMain() {
DebugPrintTID(); DebugPrintTID();
#ifdef WIN32 #ifdef WIN32
WSADATA wsaData; WSADATA wsaData;
if (WSAStartup(514, &wsaData)) { if (WSAStartup(514, &wsaData)) {
error(Sec("Can't start Winsock!")); error("Can't start Winsock!");
return; return;
} }
SOCKET client, Listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); SOCKET client, Listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
@ -120,30 +149,30 @@ void TCPServerMain() {
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
addr.sin_port = htons(Port); addr.sin_port = htons(Port);
if (bind(Listener, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) { 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)); std::this_thread::sleep_for(std::chrono::seconds(5));
_Exit(-1); _Exit(-1);
} }
if (Listener == -1) { if (Listener == -1) {
error(Sec("Invalid listening socket")); error("Invalid listening socket");
return; return;
} }
if (listen(Listener, SOMAXCONN)) { if (listen(Listener, SOMAXCONN)) {
error(Sec("listener failed ") + std::to_string(GetLastError())); error("listener failed " + std::to_string(GetLastError()));
return; return;
} }
info(Sec("Vehicle event network online")); info("Vehicle event network online");
do { do {
try { try {
client = accept(Listener, nullptr, nullptr); client = accept(Listener, nullptr, nullptr);
if (client == -1) { if (client == -1) {
warn(Sec("Got an invalid client socket on connect! Skipping...")); warn("Got an invalid client socket on connect! Skipping...");
continue; continue;
} }
std::thread ID(Identification, client); std::thread ID(Identify, client);
ID.detach(); ID.detach();
} catch (const std::exception& e) { } catch (const std::exception& e) {
error(Sec("fatal: ") + std::string(e.what())); error("fatal: " + std::string(e.what()));
} }
} while (client); } while (client);

View File

@ -32,15 +32,23 @@ int Client::GetStatus() {
void Client::SetUDPAddr(sockaddr_in Addr) { void Client::SetUDPAddr(sockaddr_in Addr) {
UDPADDR = Addr; UDPADDR = Addr;
} }
void Client::SetDownSock(SOCKET CSock){
SOCK[1] = CSock;
}
SOCKET Client::GetDownSock(){
return SOCK[1];
}
sockaddr_in Client::GetUDPAddr() { sockaddr_in Client::GetUDPAddr() {
return UDPADDR; return UDPADDR;
} }
void Client::SetTCPSock(SOCKET CSock) { void Client::SetTCPSock(SOCKET CSock) {
TCPSOCK = CSock; SOCK[0] = CSock;
} }
SOCKET Client::GetTCPSock() { SOCKET Client::GetTCPSock() {
return TCPSOCK; return SOCK[0];
} }
void Client::DeleteCar(int ident) { void Client::DeleteCar(int ident) {
for (auto& v : VehicleData) { for (auto& v : VehicleData) {
if (v != nullptr && v->ID == ident) { if (v != nullptr && v->ID == ident) {

View File

@ -49,7 +49,8 @@ void VehicleParser(Client* c, const std::string& Pckt) {
int CarID = c->GetOpenCarID(); int CarID = c->GetOpenCarID();
debug(c->GetName() + Sec(" created a car with ID ") + std::to_string(CarID)); 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); 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>(LuaArg { { c->GetID(), CarID, Packet.substr(3) } }), true)) { auto Res = TriggerLuaEvent(Sec("onVehicleSpawn"), false, nullptr, std::make_unique<LuaArg>(LuaArg { { c->GetID(), CarID, Packet.substr(3) } }), true);
if (c->GetCarCount() >= MaxCars || std::any_cast<int>(Res)) {
Respond(c, Packet, true); Respond(c, Packet, true);
std::string Destroy = "Od:" + std::to_string(c->GetID()) + "-" + std::to_string(CarID); std::string Destroy = "Od:" + std::to_string(c->GetID()) + "-" + std::to_string(CarID);
Respond(c, Destroy, true); Respond(c, Destroy, true);
@ -71,9 +72,10 @@ void VehicleParser(Client* c, const std::string& Pckt) {
VID = stoi(vid); VID = stoi(vid);
} }
if (PID != -1 && VID != -1 && PID == c->GetID()) { if (PID != -1 && VID != -1 && PID == c->GetID()) {
if (!TriggerLuaEvent(Sec("onVehicleEdited"), false, nullptr, auto Res = TriggerLuaEvent(Sec("onVehicleEdited"), false, nullptr,
std::unique_ptr<LuaArg>(new LuaArg { { c->GetID(), VID, Packet.substr(3) } }), std::make_unique<LuaArg>(LuaArg { { c->GetID(), VID, Packet.substr(3) } }),
true)) { true);
if (!std::any_cast<int>(Res)) {
SendToAll(c, Packet, false, true); SendToAll(c, Packet, false, true);
Apply(c, VID, Packet); Apply(c, VID, Packet);
} else { } else {
@ -96,7 +98,7 @@ void VehicleParser(Client* c, const std::string& Pckt) {
if (PID != -1 && VID != -1 && PID == c->GetID()) { if (PID != -1 && VID != -1 && PID == c->GetID()) {
SendToAll(nullptr, Packet, true, true); SendToAll(nullptr, Packet, true, true);
TriggerLuaEvent(Sec("onVehicleDeleted"), false, nullptr, TriggerLuaEvent(Sec("onVehicleDeleted"), false, nullptr,
std::unique_ptr<LuaArg>(new LuaArg { { c->GetID(), VID } }), false); std::make_unique<LuaArg>(LuaArg { { c->GetID(), VID } }), false);
c->DeleteCar(VID); c->DeleteCar(VID);
debug(c->GetName() + Sec(" deleted car with ID ") + std::to_string(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)); std::this_thread::sleep_for(std::chrono::seconds(1));
Respond(c, Sec("Sn") + c->GetName(), true); Respond(c, Sec("Sn") + c->GetName(), true);
SendToAll(c, Sec("JWelcome ") + c->GetName() + "!", false, true); SendToAll(c, Sec("JWelcome ") + c->GetName() + "!", false, true);
TriggerLuaEvent(Sec("onPlayerJoin"), false, nullptr, std::unique_ptr<LuaArg>(new LuaArg { { c->GetID() } }), false); TriggerLuaEvent(Sec("onPlayerJoin"), false, nullptr, std::make_unique<LuaArg>(LuaArg { { c->GetID() } }), false);
for (auto& client : CI->Clients) { for (auto& client : CI->Clients) {
if (client != nullptr) { if (client != nullptr) {
if (client.get() != c) { if (client.get() != c) {
@ -166,7 +168,7 @@ void HandleEvent(Client* c, const std::string& Data) {
Name = t; Name = t;
break; break;
case 2: case 2:
TriggerLuaEvent(Name, false, nullptr, std::unique_ptr<LuaArg>(new LuaArg { { c->GetID(), t } }), false); TriggerLuaEvent(Name, false, nullptr, std::make_unique<LuaArg>(LuaArg { { c->GetID(), t } }), false);
break; break;
default: default:
break; break;
@ -181,6 +183,7 @@ void GlobalParser(Client* c, const std::string& Pack) {
Assert(c); Assert(c);
if (Pack.empty() || c == nullptr) if (Pack.empty() || c == nullptr)
return; return;
std::any Res;
std::string Packet = Pack.substr(0, strlen(Pack.c_str())); std::string Packet = Pack.substr(0, strlen(Pack.c_str()));
std::string pct; std::string pct;
char Code = Packet.at(0); char Code = Packet.at(0);
@ -192,11 +195,10 @@ void GlobalParser(Client* c, const std::string& Pack) {
return; return;
} }
switch (Code) { switch (Code) {
case 'P': // initial connection case 'H': // initial connection
#ifdef DEBUG #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 #endif
Respond(c, Sec("P") + std::to_string(c->GetID()), true);
SyncClient(c); SyncClient(c);
return; return;
case 'p': case 'p':
@ -221,10 +223,9 @@ void GlobalParser(Client* c, const std::string& Pack) {
#endif #endif
if (Packet.length() < 4 || Packet.find(':', 3) == std::string::npos) if (Packet.length() < 4 || Packet.find(':', 3) == std::string::npos)
break; break;
if (TriggerLuaEvent(Sec("onChatMessage"), false, nullptr, Res = TriggerLuaEvent("onChatMessage", false, nullptr,std::make_unique<LuaArg>(LuaArg {
std::unique_ptr<LuaArg>(new LuaArg { { c->GetID(), c->GetName(), Packet.substr(Packet.find(':', 3) + 1) } }),true);
{ c->GetID(), c->GetName(), Packet.substr(Packet.find(':', 3) + 1) } }), if (std::any_cast<int>(Res))
true))
break; break;
SendToAll(nullptr, Packet, true, true); SendToAll(nullptr, Packet, true, true);
return; return;

View File

@ -1,14 +1,16 @@
/// ///
/// Created by Anonymous275 on 8/1/2020 /// Created by Anonymous275 on 8/1/2020
/// ///
#include "Client.hpp"
#include <memory>
#include "Logger.h"
#include "Lua/LuaSystem.hpp" #include "Lua/LuaSystem.hpp"
#include "Network.h" #include "Client.hpp"
#include "Security/Enc.h" #include "UnixCompat.h"
#include "Settings.h" #include "Settings.h"
#include "Network.h"
#include "Logger.h"
#include <memory>
int OpenID() { int OpenID() {
int ID = 0; int ID = 0;
bool found; bool found;
@ -83,18 +85,19 @@ void OnDisconnect(Client* c, bool kicked) {
SendToAll(c, Packet, false, true); SendToAll(c, Packet, false, true);
Packet.clear(); Packet.clear();
TriggerLuaEvent(Sec("onPlayerDisconnect"), false, nullptr, std::make_unique<LuaArg>(LuaArg { { c->GetID() } }), false); TriggerLuaEvent(Sec("onPlayerDisconnect"), false, nullptr, std::make_unique<LuaArg>(LuaArg { { c->GetID() } }), false);
if(c->GetTCPSock())CloseSocketProper(c->GetTCPSock());
if(c->GetDownSock())CloseSocketProper(c->GetDownSock());
CI->RemoveClient(c); ///Removes the Client from existence CI->RemoveClient(c); ///Removes the Client from existence
} }
void OnConnect(Client* c) { void OnConnect(Client* c) {
Assert(c); Assert(c);
info(Sec("Client connected")); info("Client connected");
c->SetID(OpenID()); c->SetID(OpenID());
info(Sec("Assigned ID ") + std::to_string(c->GetID()) + Sec(" to ") + c->GetName()); info("Assigned ID " + std::to_string(c->GetID()) +" to " + c->GetName());
TriggerLuaEvent(Sec("onPlayerConnecting"), false, nullptr, std::make_unique<LuaArg>(LuaArg { { c->GetID() } }), false); TriggerLuaEvent("onPlayerConnecting", false, nullptr, std::make_unique<LuaArg>(LuaArg { { c->GetID() } }), false);
SyncResources(c); SyncResources(c);
if (c->GetStatus() < 0) if (c->GetStatus() < 0)return;
return;
Respond(c, "M" + MapName, true); //Send the Map on connect Respond(c, "M" + MapName, true); //Send the Map on connect
info(c->GetName() + Sec(" : Connected")); info(c->GetName() +" : Connected");
TriggerLuaEvent(Sec("onPlayerJoining"), false, nullptr, std::make_unique<LuaArg>(LuaArg { { c->GetID() } }), false); TriggerLuaEvent("onPlayerJoining", false, nullptr, std::make_unique<LuaArg>(LuaArg { { c->GetID() } }), false);
} }

View File

@ -5,48 +5,97 @@
#include "UnixCompat.h" #include "UnixCompat.h"
#include "Settings.h" #include "Settings.h"
#include "Client.hpp" #include "Client.hpp"
#include <filesystem>
#include "Network.h" #include "Network.h"
#include "Logger.h" #include "Logger.h"
#include <fstream> #include <fstream>
#ifdef __linux
// we need this for `struct stat`
#include <sys/stat.h>
#endif // __linux
void SendFile(Client* c, const std::string& Name) { bool TCPSendRaw(SOCKET C, char* Data, int32_t Size){
Assert(c); int64_t Sent = 0, Temp;
info(c->GetName() + " requesting : " + Name.substr(Name.find_last_of('/'))); do {
struct stat Info { }; Temp = send(C, &Data[Sent], int(Size - Sent), 0);
if (stat(Name.c_str(), &Info) != 0) { if(Temp < 1) {
TCPSend(c, "Cannot Open"); info("Socket Closed! " + std::to_string(C));
return; 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); std::ifstream f(Name.c_str(), std::ios::binary);
f.seekg(0, std::ios_base::end); int32_t Split = 0x7735940; //125MB
std::streampos fileSize = f.tellg(); int64_t Diff;
auto Size = size_t(fileSize); char* Data;
size_t Sent = 0; if(Size > Split)Data = new char[Split];
size_t Diff; else Data = new char[Size];
int64_t Split = 64000; SOCKET TCPSock = c->GetTCPSock();
if(D){
TCPSock = c->GetDownSock();
}
info("Split load Socket " + std::to_string(TCPSock));
while (c->GetStatus() > -1 && Sent < Size) { while (c->GetStatus() > -1 && Sent < Size) {
Diff = Size - Sent; Diff = Size - Sent;
if (Diff > size_t(Split)) { if (Diff > Split) {
std::string Data(size_t(Split), 0); f.seekg(Sent, std::ios_base::beg);
f.seekg(int64_t(Sent), std::ios_base::beg); f.read(Data, Split);
f.read(&Data[0], Split); if(!TCPSendRaw(TCPSock, Data, Split)){
TCPSend(c, Data); if(c->GetStatus() > -1)c->SetStatus(-1);
Sent += size_t(Split); break;
}
Sent += Split;
} else { } else {
std::string Data(Diff, 0); f.seekg(Sent, std::ios_base::beg);
f.seekg(int64_t(Sent), std::ios_base::beg); f.read(Data, Diff);
f.read(&Data[0], int64_t(Diff)); if(!TCPSendRaw(TCPSock, Data, int32_t(Diff))){
TCPSend(c, Data); if(c->GetStatus() > -1)c->SetStatus(-1);
break;
}
Sent += Diff; Sent += Diff;
} }
} }
delete[] Data;
f.close(); 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) { void Parse(Client* c, const std::string& Packet) {
Assert(c); Assert(c);
if (c == nullptr || Packet.empty()) if (c == nullptr || Packet.empty())
@ -62,8 +111,7 @@ void Parse(Client* c, const std::string& Packet) {
if (SubCode == 'R') { if (SubCode == 'R') {
debug(Sec("Sending Mod Info")); debug(Sec("Sending Mod Info"));
std::string ToSend = FileList + FileSizes; std::string ToSend = FileList + FileSizes;
if (ToSend.empty()) if (ToSend.empty())ToSend = "-";
ToSend = "-";
TCPSend(c, ToSend); TCPSend(c, ToSend);
} }
return; return;
@ -75,16 +123,20 @@ void Parse(Client* c, const std::string& Packet) {
void SyncResources(Client* c) { void SyncResources(Client* c) {
Assert(c); Assert(c);
if (c == nullptr)return; if (c == nullptr)return;
#ifndef DEBUG
try { try {
TCPSend(c, "WS"); #endif
TCPSend(c, "P" + std::to_string(c->GetID()));
std::string Data; std::string Data;
while (c->GetStatus() > -1){ while (c->GetStatus() > -1){
Data = TCPRcv(c); Data = TCPRcv(c);
if(Data == "Done")break; if(Data == "Done")break;
Parse(c, Data); Parse(c, Data);
} }
#ifndef DEBUG
} catch (std::exception& e) { } catch (std::exception& e) {
except("Exception! : " + std::string(e.what())); except("Exception! : " + std::string(e.what()));
c->SetStatus(-1); c->SetStatus(-1);
} }
#endif
} }

View File

@ -1,20 +1,17 @@
/// ///
/// Created by Anonymous275 on 8/1/2020 /// Created by Anonymous275 on 8/1/2020
/// ///
#include "Compressor.h"
#include "Logger.h"
#include "Network.h"
#include "Security/Enc.h" #include "Security/Enc.h"
#include "UnixCompat.h" #include "UnixCompat.h"
#include "Compressor.h"
#include "Network.h"
#include "Logger.h"
#include <thread> #include <thread>
bool TCPSend(Client* c, const std::string& Data) { bool TCPSend(Client* c, const std::string& Data) {
Assert(c); Assert(c);
if (c == nullptr) if (c == nullptr)return false;
return false;
// Size is BIG ENDIAN now, use only for header!
//auto Size = htonl(int32_t(Data.size()));
///TODO : BIG ENDIAN for other OS
int32_t Size, Sent, Temp; int32_t Size, Sent, Temp;
std::string Send(4, 0); std::string Send(4, 0);
Size = int32_t(Data.size()); Size = int32_t(Data.size());
@ -31,7 +28,6 @@ bool TCPSend(Client* c, const std::string& Data) {
} else if (Temp < 0) { } else if (Temp < 0) {
if (c->GetStatus() > -1) if (c->GetStatus() > -1)
c->SetStatus(-1); c->SetStatus(-1);
// info(Sec("Closing socket, Temp < 0"));
CloseSocketProper(c->GetTCPSock()); CloseSocketProper(c->GetTCPSock());
return false; return false;
} }
@ -43,7 +39,7 @@ bool TCPSend(Client* c, const std::string& Data) {
bool CheckBytes(Client* c, int32_t BytesRcv) { bool CheckBytes(Client* c, int32_t BytesRcv) {
Assert(c); Assert(c);
if (BytesRcv == 0) { if (BytesRcv == 0) {
debug(Sec("(TCP) Connection closing...")); debug("(TCP) Connection closing...");
if (c->GetStatus() > -1) if (c->GetStatus() > -1)
c->SetStatus(-1); c->SetStatus(-1);
return false; return false;
@ -122,7 +118,7 @@ std::string TCPRcv(Client* c) {
} }
void TCPClient(Client* c) { void TCPClient(Client* c) {
DebugPrintTIDInternal(Sec("Client(") + c->GetName() + Sec(")"), true); DebugPrintTIDInternal("Client(" + c->GetName() + ")", true);
Assert(c); Assert(c);
if (c->GetTCPSock() == -1) { if (c->GetTCPSock() == -1) {
CI->RemoveClient(c); CI->RemoveClient(c);
@ -134,7 +130,3 @@ void TCPClient(Client* c) {
} }
OnDisconnect(c, c->GetStatus() == -2); OnDisconnect(c, c->GetStatus() == -2);
} }
void InitClient(Client* c) {
std::thread NewClient(TCPClient, c);
NewClient.detach();
}