mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2025-07-01 23:35:41 +00:00
Mod Sync
This commit is contained in:
parent
ed6b2d236a
commit
a05acee04f
@ -4,7 +4,7 @@ project(BeamMP-Server)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O2")
|
||||
include_directories(${PROJECT_SOURCE_DIR}/curl)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
file(GLOB source_files
|
||||
"src/*.h" "src/*.hpp" "src/*.cpp"
|
||||
|
@ -4,37 +4,65 @@
|
||||
|
||||
#include "LuaSystem.hpp"
|
||||
#include "../logger.h"
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include "../Network 2.0/Client.hpp"
|
||||
std::set<Lua*> PluginEngine;
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
void RegisterFiles(const std::string& Path){
|
||||
bool NewFile(const std::string&Path){
|
||||
for(Lua*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);
|
||||
info("Loading plugin : " + Name);
|
||||
for (const auto &entry : fs::directory_iterator(Path)) {
|
||||
if(!HotSwap)info("Loading plugin : " + Name);
|
||||
for (const auto &entry : fs::directory_iterator(Path)){
|
||||
int pos = entry.path().string().find(".lua");
|
||||
if (pos != std::string::npos && entry.path().string().length() - pos == 4) {
|
||||
Lua *Script = new Lua();
|
||||
PluginEngine.insert(Script);
|
||||
Script->SetFileName(entry.path().string());
|
||||
Script->SetPluginName(Name);
|
||||
Script->Init();
|
||||
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("[HOTSWAP] Added : " +
|
||||
Script->GetFileName().substr(Script->GetFileName().find('\\')));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FolderList(const std::string& Path){
|
||||
void FolderList(const std::string& Path,bool HotSwap){
|
||||
for (const auto &entry : fs::directory_iterator(Path)) {
|
||||
int pos = entry.path().filename().string().find('.');
|
||||
if (pos == std::string::npos) {
|
||||
RegisterFiles(entry.path().string());
|
||||
RegisterFiles(entry.path().string(),HotSwap);
|
||||
}
|
||||
}
|
||||
}
|
||||
[[noreturn]]void HotSwaps(const std::string& path){
|
||||
while(true){
|
||||
for(Lua*Script : PluginEngine){
|
||||
struct stat Info{};
|
||||
if(stat(Script->GetFileName().c_str(), &Info) != 0){
|
||||
PluginEngine.erase(Script);
|
||||
info("[HOTSWAP] Removed : "+
|
||||
Script->GetFileName().substr(Script->GetFileName().find('\\')));
|
||||
break;
|
||||
}
|
||||
if(Script->GetLastWrite() != fs::last_write_time(Script->GetFileName())){
|
||||
Script->SetLastWrite(fs::last_write_time(Script->GetFileName()));
|
||||
Script->Reload();
|
||||
info("[HOTSWAP] Updated : "+
|
||||
Script->GetFileName().substr(Script->GetFileName().find('\\')));
|
||||
}
|
||||
}
|
||||
FolderList(path,true);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LuaMain(std::string Path){
|
||||
Path += "/Server";
|
||||
@ -42,6 +70,8 @@ void LuaMain(std::string Path){
|
||||
if(stat( Path.c_str(), &Info) != 0){
|
||||
fs::create_directory(Path);
|
||||
}
|
||||
FolderList(Path);
|
||||
FolderList(Path,false);
|
||||
std::thread t1(HotSwaps,Path);
|
||||
t1.detach();
|
||||
info("Lua system online");
|
||||
}
|
||||
|
@ -1,21 +1,38 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 5/19/2020
|
||||
///
|
||||
|
||||
#include "../Network 2.0/Client.hpp"
|
||||
#include "LuaSystem.hpp"
|
||||
#include "../logger.h"
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller){
|
||||
LuaArg* CreateArg(lua_State *L,int T){
|
||||
LuaArg* temp = new LuaArg;
|
||||
for(int C = 2;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;
|
||||
}
|
||||
|
||||
int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller,LuaArg* arg){
|
||||
int R = 0;
|
||||
for(Lua*Script : PluginEngine){
|
||||
if(Script->IsRegistered(Event)){
|
||||
if(local){
|
||||
if (Script->GetPluginName() == Caller->GetPluginName()){
|
||||
R += Script->CallFunction(Script->GetRegistered(Event));
|
||||
R += Script->CallFunction(Script->GetRegistered(Event),arg);
|
||||
}
|
||||
}else R += Script->CallFunction(Script->GetRegistered(Event));
|
||||
}else R += Script->CallFunction(Script->GetRegistered(Event),arg);
|
||||
}
|
||||
}
|
||||
return R;
|
||||
@ -59,9 +76,9 @@ int lua_TriggerEventL(lua_State *L)
|
||||
Lua* Script = GetScript(L);
|
||||
if(Args > 0){
|
||||
if(lua_isstring(L,1)) {
|
||||
TriggerLuaEvent(lua_tostring(L, 1), true, Script);
|
||||
TriggerLuaEvent(lua_tostring(L, 1), true, Script, CreateArg(L,Args));
|
||||
}else{
|
||||
SendError(L,"TriggerLocalEvent wrong arguments need string");
|
||||
SendError(L,"TriggerLocalEvent wrong argument [1] need string");
|
||||
}
|
||||
}else{
|
||||
SendError(L,"TriggerLocalEvent not enough arguments");
|
||||
@ -75,24 +92,24 @@ int lua_TriggerEventG(lua_State *L)
|
||||
Lua* Script = GetScript(L);
|
||||
if(Args > 0){
|
||||
if(lua_isstring(L,1)) {
|
||||
TriggerLuaEvent(lua_tostring(L, 1), true, Script);
|
||||
}else SendError(L,"TriggerGlobalEvent wrong arguments need string");
|
||||
TriggerLuaEvent(lua_tostring(L, 1), false, Script, CreateArg(L,Args));
|
||||
}else SendError(L,"TriggerGlobalEvent wrong argument [1] need string");
|
||||
}else{
|
||||
SendError(L,"TriggerGlobalEvent not enough arguments");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void CallAsync(Lua* Script,const std::string&FuncName){
|
||||
Script->CallFunction(FuncName);
|
||||
void CallAsync(Lua* Script,const std::string&FuncName,LuaArg* args){
|
||||
Script->CallFunction(FuncName,args);
|
||||
}
|
||||
int lua_CreateThread(lua_State *L){
|
||||
int Args = lua_gettop(L);
|
||||
Lua* Script = GetScript(L);
|
||||
if(Args > 0){
|
||||
if(lua_isstring(L,1)) {
|
||||
std::thread Worker(CallAsync,Script,lua_tostring(L,1));
|
||||
std::thread Worker(CallAsync,Script,lua_tostring(L,1),CreateArg(L,Args));
|
||||
Worker.detach();
|
||||
}else SendError(L,"CreateThread wrong arguments need string");
|
||||
}else SendError(L,"CreateThread wrong argument [1] need string");
|
||||
}else SendError(L,"CreateThread not enough arguments");
|
||||
return 0;
|
||||
}
|
||||
@ -193,18 +210,35 @@ int lua_dropPlayer(lua_State *L){
|
||||
if(c != nullptr){
|
||||
Respond(c,"C:Server:You have been Kicked from the server!",true);
|
||||
c->SetStatus(-2);
|
||||
closesocket(c->GetTCPSock());
|
||||
}
|
||||
}else SendError(L,"DropPlayer not enough arguments");
|
||||
return 0;
|
||||
}
|
||||
void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel);
|
||||
int lua_sendChat(lua_State *L){
|
||||
if(lua_isstring(L,1)){
|
||||
std::string Packet = "C:Server: " + std::string(lua_tostring(L, 1));
|
||||
SendToAll(nullptr,Packet,true,true);
|
||||
}else SendError(L,"SendChatMessage not enough arguments");
|
||||
if(lua_isinteger(L,1) || lua_isnumber(L,1)){
|
||||
if(lua_isstring(L,2)){
|
||||
int ID = lua_tointeger(L,1);
|
||||
if(ID == -1){
|
||||
std::string Packet = "C:Server: " + std::string(lua_tostring(L, 1));
|
||||
SendToAll(nullptr,Packet,true,true);
|
||||
}else{
|
||||
Client*c = GetClient(ID);
|
||||
if(c != nullptr) {
|
||||
std::string Packet = "C:Server: " + std::string(lua_tostring(L, 1));
|
||||
Respond(c, Packet, true);
|
||||
}else SendError(L,"SendChatMessage invalid argument [1] invalid ID");
|
||||
}
|
||||
}else SendError(L,"SendChatMessage invalid argument [2] expected string");
|
||||
}else SendError(L,"SendChatMessage invalid argument [1] expected number");
|
||||
return 0;
|
||||
}
|
||||
int lua_HWID(lua_State *L){
|
||||
lua_pushinteger(L, -1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Lua::Init(){
|
||||
luaL_openlibs(luaState);
|
||||
lua_register(luaState,"TriggerGlobalEvent",lua_TriggerEventG);
|
||||
@ -213,23 +247,31 @@ void Lua::Init(){
|
||||
lua_register(luaState,"isPlayerConnected",lua_isConnected);
|
||||
lua_register(luaState,"RegisterEvent",lua_RegisterEvent);
|
||||
lua_register(luaState,"GetPlayerName",lua_GetPlayerName);
|
||||
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,"DropPlayer",lua_dropPlayer);
|
||||
lua_register(luaState,"GetPlayers",lua_GetAllIDs);
|
||||
lua_register(luaState,"GetDID",lua_GetDID);
|
||||
lua_register(luaState,"GetPlayerHWID",lua_HWID);
|
||||
lua_register(luaState,"Sleep",lua_Sleep);
|
||||
Reload();
|
||||
}
|
||||
void Lua::Reload(){
|
||||
if(CheckLua(luaState,luaL_dofile(luaState,FileName.c_str()))){
|
||||
CallFunction("onInit");
|
||||
CallFunction("onInit",{});
|
||||
}
|
||||
}
|
||||
int Lua::CallFunction(const std::string&FuncName){
|
||||
int Lua::CallFunction(const std::string&FuncName,LuaArg* Arg){
|
||||
lua_getglobal(luaState, FuncName.c_str());
|
||||
if (lua_isfunction(luaState, -1)) {
|
||||
/*lua_pushstring(luaState, "Anonymous275");
|
||||
lua_pushinteger(luaState, 1);*/
|
||||
if(CheckLua(luaState, lua_pcall(luaState, 0, 1, 0))){
|
||||
int Size = 0;
|
||||
if(Arg != nullptr){
|
||||
Size = Arg->args.size();
|
||||
Arg->PushArgs(luaState);
|
||||
}
|
||||
if(CheckLua(luaState, lua_pcall(luaState, Size, 1, 0))){
|
||||
|
||||
if(lua_isnumber(luaState,-1)){
|
||||
return lua_tointeger(luaState,-1);
|
||||
}
|
||||
@ -275,3 +317,9 @@ std::string Lua::GetPluginName(){
|
||||
lua_State* Lua::GetState(){
|
||||
return luaState;
|
||||
}
|
||||
void Lua::SetLastWrite(fs::file_time_type time){
|
||||
LastWrote = time;
|
||||
}
|
||||
fs::file_time_type Lua::GetLastWrite(){
|
||||
return LastWrote;
|
||||
}
|
||||
|
@ -4,11 +4,39 @@
|
||||
|
||||
#pragma once
|
||||
#include <set>
|
||||
#include <any>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <filesystem>
|
||||
#include "../lua/lua.hpp"
|
||||
namespace fs = std::filesystem;
|
||||
struct LuaArg{
|
||||
std::vector<std::any> args;
|
||||
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") != -1){
|
||||
lua_pushboolean(State,std::any_cast<bool>(arg));
|
||||
}
|
||||
if(Type.find("basic_string") != -1 || Type.find("char") != -1){
|
||||
lua_pushstring(State,std::any_cast<std::string>(arg).c_str());
|
||||
}
|
||||
if(Type.find("int") != -1){
|
||||
lua_pushinteger(State,std::any_cast<int>(arg));
|
||||
}
|
||||
if(Type.find("float") != -1){
|
||||
lua_pushnumber(State,std::any_cast<float>(arg));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Lua {
|
||||
private:
|
||||
std::set<std::pair<std::string,std::string>> RegisteredEvents;
|
||||
lua_State *luaState = luaL_newstate();
|
||||
fs::file_time_type LastWrote;
|
||||
std::string PluginName;
|
||||
std::string FileName;
|
||||
|
||||
@ -16,13 +44,16 @@ public:
|
||||
void RegisterEvent(const std::string&Event,const std::string&FunctionName);
|
||||
std::string GetRegistered(const std::string&Event);
|
||||
void UnRegisterEvent(const std::string&Event);
|
||||
int CallFunction(const std::string&FuncName);
|
||||
int CallFunction(const std::string&FuncName,LuaArg* args);
|
||||
void SetLastWrite(fs::file_time_type time);
|
||||
bool IsRegistered(const std::string&Event);
|
||||
void SetPluginName(const std::string&Name);
|
||||
void SetFileName(const std::string&Name);
|
||||
fs::file_time_type GetLastWrite();
|
||||
std::string GetPluginName();
|
||||
std::string GetFileName();
|
||||
lua_State* GetState();
|
||||
void Reload();
|
||||
void Init();
|
||||
};
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <WS2tcpip.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <chrono>
|
||||
#include <set>
|
||||
|
||||
class Client {
|
||||
@ -19,8 +20,6 @@ private:
|
||||
SOCKET TCPSOCK;
|
||||
int Status = 0;
|
||||
int ID = -1; //PlayerID
|
||||
|
||||
|
||||
public:
|
||||
std::set<std::pair<int,std::string>> GetAllCars();
|
||||
void AddNewCar(int ident,const std::string& Data);
|
||||
|
@ -37,7 +37,7 @@ void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel){
|
||||
for(Client*client : Clients){
|
||||
if(Self || client != c){
|
||||
if(Rel){
|
||||
if(C == 'O' || C == 'T' || Data.length() > 1000)SendLarge(client,Data);
|
||||
if(C == 'C' || C == 'O' || C == 'T' || Data.length() > 1000)SendLarge(client,Data);
|
||||
else TCPSend(client,Data);
|
||||
}
|
||||
else UDPSend(client,Data);
|
||||
@ -53,7 +53,12 @@ void UpdatePlayers(){
|
||||
Packet = Packet.substr(0,Packet.length()-1);
|
||||
SendToAll(nullptr, Packet,true,true);
|
||||
}
|
||||
int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller,LuaArg* arg);
|
||||
|
||||
void Destroy(Client*c){
|
||||
Clients.erase(c);
|
||||
delete c;
|
||||
}
|
||||
void OnDisconnect(Client*c,bool kicked){
|
||||
std::string Packet;
|
||||
for(const std::pair<int,std::string>&a : c->GetAllCars()){
|
||||
@ -64,13 +69,15 @@ void OnDisconnect(Client*c,bool kicked){
|
||||
Packet = "L"+c->GetName()+" Left the server!";
|
||||
SendToAll(c, Packet,false,true);
|
||||
Packet.clear();
|
||||
Clients.erase(c); ///Removes the Client from existence
|
||||
TriggerLuaEvent("onPlayerDisconnect",false,nullptr,new LuaArg{{c->GetID()}});
|
||||
Destroy(c); ///Removes the Client from existence
|
||||
}
|
||||
int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller);
|
||||
void SyncResources(Client*c);
|
||||
void OnConnect(Client*c){
|
||||
c->SetID(OpenID());
|
||||
std::cout << "New Client Created! ID : " << c->GetID() << std::endl;
|
||||
Respond(c,"NR",true);
|
||||
TriggerLuaEvent("onPlayerConnecting",false,nullptr,new LuaArg{{c->GetID()}});
|
||||
SyncResources(c);
|
||||
Respond(c,"M"+MapName,true); //Send the Map on connect
|
||||
TriggerLuaEvent("onPlayerJoining",false,nullptr);
|
||||
TriggerLuaEvent("onPlayerJoining",false,nullptr,new LuaArg{{c->GetID()}});
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ void Respond(Client*c, const std::string& MSG, bool Rel);
|
||||
void UpdatePlayers();
|
||||
|
||||
|
||||
int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller);
|
||||
int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller,LuaArg* arg);
|
||||
void VehicleParser(Client*c, std::string Packet){
|
||||
char Code = Packet.at(1);
|
||||
int PID = -1;
|
||||
@ -23,11 +23,12 @@ void VehicleParser(Client*c, std::string Packet){
|
||||
switch(Code){ //Spawned Destroyed Switched/Moved NotFound Reset
|
||||
case 's':
|
||||
if(Data.at(0) == '0'){
|
||||
if(TriggerLuaEvent("onVehicleSpawn",false,nullptr))break;
|
||||
int CarID = c->GetOpenCarID();
|
||||
std::cout << c->GetName() << " CarID : " << CarID << std::endl;
|
||||
Packet = "Os:"+c->GetRole()+":"+c->GetName()+":"+std::to_string(c->GetID())+"-"+std::to_string(CarID)+Packet.substr(4);
|
||||
if(c->GetCarCount() >= MaxCars){
|
||||
if(TriggerLuaEvent("onVehicleSpawn",false,nullptr,
|
||||
new LuaArg{{c->GetID(),CarID,Packet.substr(3)}})
|
||||
|| c->GetCarCount() >= MaxCars){
|
||||
Respond(c,Packet,true);
|
||||
std::string Destroy = "Od:" + std::to_string(c->GetID())+"-"+std::to_string(CarID);
|
||||
Respond(c,Destroy,true);
|
||||
@ -37,6 +38,9 @@ void VehicleParser(Client*c, std::string Packet){
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
SendToAll(c,Packet,false,true);
|
||||
break;
|
||||
case 'd':
|
||||
pid = Data.substr(0,Data.find('-'));
|
||||
vid = Data.substr(Data.find('-')+1);
|
||||
@ -49,17 +53,17 @@ void VehicleParser(Client*c, std::string Packet){
|
||||
c->DeleteCar(VID);
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
break;
|
||||
case 'r':
|
||||
SendToAll(c,Packet,false,true);
|
||||
break;
|
||||
case 'm':
|
||||
break;
|
||||
}
|
||||
}
|
||||
void SyncVehicles(Client*c){
|
||||
Respond(c,"Sn"+c->GetName(),true);
|
||||
SendToAll(c,"JWelcome "+c->GetName()+"!",false,true);
|
||||
TriggerLuaEvent("onPlayerJoin",false,nullptr);
|
||||
TriggerLuaEvent("onPlayerJoin",false,nullptr,new LuaArg{{c->GetID()}});
|
||||
for (Client*client : Clients) {
|
||||
if (client != c) {
|
||||
for(const std::pair<int,std::string>&a : client->GetAllCars()){
|
||||
@ -74,8 +78,10 @@ void HTTP(Client*c){
|
||||
std::string a = HTTP_REQUEST("https://beamng-mp.com/entitlement?did="+c->GetDID(),443);
|
||||
if(!a.empty()){
|
||||
int pos = a.find('"');
|
||||
c->SetRole(a.substr(pos+1,a.find('"',pos+1)-2));
|
||||
if(Debug)debug("ROLE -> " + c->GetRole() + " ID -> " + c->GetDID());
|
||||
if(c != nullptr){
|
||||
c->SetRole(a.substr(pos+1,a.find('"',pos+1)-2));
|
||||
if(Debug)debug("ROLE -> " + c->GetRole() + " ID -> " + c->GetDID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -116,7 +122,8 @@ void GlobalParser(Client*c, const std::string&Packet){
|
||||
SendToAll(c,Packet,false,true);
|
||||
break;
|
||||
case 'C':
|
||||
if(TriggerLuaEvent("onChatMessage",false,nullptr))break;
|
||||
if(TriggerLuaEvent("onChatMessage",false,nullptr,
|
||||
new LuaArg{{c->GetID(),c->GetName(),Packet.substr(Packet.find(':',3)+1)}}))break;
|
||||
SendToAll(nullptr,Packet,true,true);
|
||||
break;
|
||||
case 'E':
|
||||
|
@ -12,17 +12,16 @@ void TCPSend(Client*c,const std::string&Data){
|
||||
int BytesSent = send(c->GetTCPSock(), Data.c_str(), int(Data.length())+1, 0);
|
||||
if (BytesSent == 0){
|
||||
std::cout << "(TCP) Connection closing..." << std::endl;
|
||||
c->SetStatus(-1);
|
||||
if(c->GetStatus() > -1)c->SetStatus(-1);
|
||||
}
|
||||
else if (BytesSent < 0) {
|
||||
std::cout << "(TCP) send failed with error: " << WSAGetLastError() << std::endl;
|
||||
if(c->GetStatus() > -1)c->SetStatus(-1);
|
||||
closesocket(c->GetTCPSock());
|
||||
c->SetStatus(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalParser(Client*c, const std::string&Packet);
|
||||
|
||||
void TCPRcv(Client*c){
|
||||
char buf[4096];
|
||||
int len = 4096;
|
||||
@ -30,12 +29,12 @@ void TCPRcv(Client*c){
|
||||
int BytesRcv = recv(c->GetTCPSock(), buf, len,0);
|
||||
if (BytesRcv == 0){
|
||||
std::cout << "(TCP) Connection closing..." << std::endl;
|
||||
c->SetStatus(-1);
|
||||
if(c->GetStatus() > -1)c->SetStatus(-1);
|
||||
}
|
||||
else if (BytesRcv < 0) {
|
||||
std::cout << "(TCP) recv failed with error: " << WSAGetLastError() << std::endl;
|
||||
if(c->GetStatus() > -1)c->SetStatus(-1);
|
||||
closesocket(c->GetTCPSock());
|
||||
c->SetStatus(-1);
|
||||
}
|
||||
GlobalParser(c, std::string(buf));
|
||||
}
|
||||
|
118
src/Network 2.0/ResourceSync.cpp
Normal file
118
src/Network 2.0/ResourceSync.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 6/10/2020
|
||||
///
|
||||
#include <string>
|
||||
#include "../Settings.hpp"
|
||||
#include "Client.hpp"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <thread>
|
||||
#include <any>
|
||||
|
||||
|
||||
void GrabRole(Client*c);
|
||||
|
||||
void STCPSend(Client*c,const std::any& Data,size_t Size){
|
||||
char *MSG;
|
||||
if(std::string(Data.type().name()).find("string") != std::string::npos){
|
||||
MSG = (char*)(std::any_cast<std::string>(Data).c_str());
|
||||
}else MSG = std::any_cast<char*>(Data);
|
||||
if(Size == 0)Size = strlen(MSG)+1;
|
||||
int BytesSent = send(c->GetTCPSock(), MSG, Size, 0);
|
||||
if (BytesSent == 0){
|
||||
std::cout << "(TCP) Connection closing..." << std::endl;
|
||||
if(c->GetStatus() > -1)c->SetStatus(-1);
|
||||
}
|
||||
else if (BytesSent < 0) {
|
||||
std::cout << "(TCP) send failed with error: " << WSAGetLastError() << std::endl;
|
||||
if(c->GetStatus() > -1)c->SetStatus(-1);
|
||||
closesocket(c->GetTCPSock());
|
||||
}
|
||||
}
|
||||
void SendFile(Client*c,const std::string&Name){
|
||||
std::cout << c->GetName() << " requesting : "
|
||||
<< Name.substr(Name.find_last_of('/')) << std::endl;
|
||||
struct stat Info{};
|
||||
if(stat(Name.c_str(), &Info) != 0){
|
||||
STCPSend(c,std::string("Cannot Open"),0);
|
||||
return;
|
||||
}
|
||||
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;
|
||||
char* Data = new char[Size];
|
||||
f.seekg(0, std::ios_base::beg);
|
||||
f.read(Data, fileSize);
|
||||
f.close();
|
||||
char* Chunk;
|
||||
int Split = 64000;
|
||||
while(c->GetStatus() > -1 && Sent < Size){
|
||||
Diff = Size - Sent;
|
||||
if(Diff > Split){
|
||||
Chunk = new char[Split];
|
||||
memcpy_s(Chunk,Split,Data+Sent,Split);
|
||||
STCPSend(c,Chunk,Split);
|
||||
Sent += Split;
|
||||
}else{
|
||||
Chunk = new char[Diff];
|
||||
memcpy_s(Chunk,Diff,Data+Sent,Diff);
|
||||
STCPSend(c,Chunk,Diff);
|
||||
Sent += Diff;
|
||||
}
|
||||
}
|
||||
delete[] Data;
|
||||
delete[] Chunk;
|
||||
}
|
||||
|
||||
void Parse(Client*c,char*data){
|
||||
std::string Packet = data;
|
||||
if(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'){
|
||||
std::cout << "Sending File Info" << std::endl;
|
||||
STCPSend(c,FileList+FileSizes,0);
|
||||
}
|
||||
return;
|
||||
case 'N':
|
||||
if(SubCode == 'R'){
|
||||
c->SetName(Packet.substr(2,Packet.find(':')-2));
|
||||
c->SetDID(Packet.substr(Packet.find(':')+1));
|
||||
GrabRole(c);
|
||||
}
|
||||
std::cout << "Name : " << c->GetName() << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
bool STCPRecv(Client*c){
|
||||
char buf[200];
|
||||
int len = 200;
|
||||
ZeroMemory(buf, len);
|
||||
int BytesRcv = recv(c->GetTCPSock(), buf, len,0);
|
||||
if (BytesRcv == 0){
|
||||
std::cout << "(TCP) Connection closing..." << std::endl;
|
||||
if(c->GetStatus() > -1)c->SetStatus(-1);
|
||||
return false;
|
||||
}
|
||||
else if (BytesRcv < 0) {
|
||||
std::cout << "(TCP) recv failed with error: " << WSAGetLastError() << std::endl;
|
||||
if(c->GetStatus() > -1)c->SetStatus(-1);
|
||||
closesocket(c->GetTCPSock());
|
||||
return false;
|
||||
}
|
||||
if(strcmp(buf,"Done") == 0)return false;
|
||||
char* Ret = new char[BytesRcv];
|
||||
memcpy_s(Ret,BytesRcv,buf,BytesRcv);
|
||||
ZeroMemory(buf, len);
|
||||
Parse(c,Ret);
|
||||
return true;
|
||||
}
|
||||
void SyncResources(Client*c){
|
||||
while(c->GetStatus() > -1 && STCPRecv(c));
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
std::string FileList;
|
||||
std::string FileSizes;
|
||||
@ -13,12 +13,12 @@ std::string FileSizes;
|
||||
void LuaMain(std::string Path);
|
||||
void HandleResources(std::string path){
|
||||
struct stat info{};
|
||||
if(stat( path.c_str(), &info) != 0){
|
||||
if(stat(path.c_str(), &info) != 0){
|
||||
fs::create_directory(path);
|
||||
}
|
||||
LuaMain(path);
|
||||
path += "/Client";
|
||||
if(stat( path.c_str(), &info) != 0) {
|
||||
if(stat(path.c_str(), &info) != 0) {
|
||||
fs::create_directory(path);
|
||||
}
|
||||
for (const auto & entry : fs::directory_iterator(path)){
|
||||
|
@ -8,12 +8,12 @@
|
||||
#include "logger.h"
|
||||
|
||||
void GenerateConfig();
|
||||
string RemoveComments(const string& Line);
|
||||
void SetValues(const string& Line, int Index);
|
||||
string MapName = "/levels/gridmap/info.json";
|
||||
string ServerName = "BeamMP Server";
|
||||
string Resource = "Resources";
|
||||
string Key;
|
||||
std::string RemoveComments(const std::string& Line);
|
||||
void SetValues(const std::string& Line, int Index);
|
||||
std::string MapName = "/levels/gridmap/info.json";
|
||||
std::string ServerName = "BeamMP Server";
|
||||
std::string Resource = "Resources";
|
||||
std::string Key;
|
||||
bool Private = false;
|
||||
bool Debug = false;
|
||||
int MaxPlayers = 10;
|
||||
@ -22,15 +22,15 @@ int MaxCars = 1;
|
||||
|
||||
//Generates or Reads Config
|
||||
void ParseConfig(){
|
||||
ifstream InFileStream;
|
||||
std::ifstream InFileStream;
|
||||
InFileStream.open("Server.cfg");
|
||||
if(InFileStream.good()){ //Checks if Config Exists
|
||||
info("Config Found Updating Values");
|
||||
string line;
|
||||
std::string line;
|
||||
int index = 1;
|
||||
while (getline(InFileStream, line)) {
|
||||
if(line.rfind('#', 0) != 0){ //Checks if it starts as Comment
|
||||
string CleanLine = RemoveComments(line); //Cleans it from the Comments
|
||||
std::string CleanLine = RemoveComments(line); //Cleans it from the Comments
|
||||
SetValues(CleanLine,index); //sets the values
|
||||
index++;
|
||||
}
|
||||
@ -44,7 +44,7 @@ void ParseConfig(){
|
||||
|
||||
|
||||
|
||||
void SetValues(const string& Line, int Index) {
|
||||
void SetValues(const std::string& Line, int Index) {
|
||||
int i = 0, state = 0;
|
||||
char Data[50] = "";
|
||||
bool Switch = false;
|
||||
@ -67,18 +67,18 @@ void SetValues(const string& Line, int Index) {
|
||||
for (int C = 1; C <= i; C++){
|
||||
Data[C-1] = Data[C];
|
||||
}
|
||||
string::size_type sz;
|
||||
bool Boolean = std::string(Data).find("true") != string::npos;//searches for "true"
|
||||
std::string::size_type sz;
|
||||
bool Boolean = std::string(Data).find("true") != std::string::npos;//searches for "true"
|
||||
switch (Index){
|
||||
case 1 : Debug = Boolean;//checks and sets the Debug Value
|
||||
break;
|
||||
case 2 : Private = Boolean;//checks and sets the Private Value
|
||||
break;
|
||||
case 3 : Port = stoi(Data, &sz);//sets the Port
|
||||
case 3 : Port = std::stoi(Data, &sz);//sets the Port
|
||||
break;
|
||||
case 4 : MaxCars = stoi(Data, &sz);//sets the Max Car amount
|
||||
case 4 : MaxCars = std::stoi(Data, &sz);//sets the Max Car amount
|
||||
break;
|
||||
case 5 : MaxPlayers = stoi(Data, &sz); //sets the Max Amount of player
|
||||
case 5 : MaxPlayers = std::stoi(Data, &sz); //sets the Max Amount of player
|
||||
break;
|
||||
case 6 : MapName = Data; //Map
|
||||
break;
|
||||
@ -94,7 +94,7 @@ void SetValues(const string& Line, int Index) {
|
||||
|
||||
//generates default Config
|
||||
void GenerateConfig(){
|
||||
ofstream FileStream;
|
||||
std::ofstream FileStream;
|
||||
FileStream.open ("Server.cfg");
|
||||
FileStream << "# This is the BeamMP Server Configuration File\n"
|
||||
"Debug = false # true or false to enable debug console output\n"
|
||||
@ -110,7 +110,7 @@ void GenerateConfig(){
|
||||
}
|
||||
|
||||
|
||||
string RemoveComments(const string& Line){
|
||||
std::string RemoveComments(const std::string& Line){
|
||||
int i = 0;
|
||||
char Data[50] = "";
|
||||
for(char c : Line) {
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "Settings.hpp"
|
||||
#include "Network 2.0/Client.hpp"
|
||||
|
||||
string HTTP_REQUEST(const std::string&,int);
|
||||
std::string HTTP_REQUEST(const std::string&,int);
|
||||
std::string PostHTTP(const std::string& IP,const std::string& Fields);
|
||||
std::string HTA(const std::string& hex)
|
||||
{
|
||||
@ -29,8 +29,8 @@ void Heartbeat()
|
||||
while(true)
|
||||
{
|
||||
State = Private ? "true" : "false";
|
||||
R = "uuid="+Key+"&players="+to_string(Clients.size())+"&maxplayers="+to_string(MaxPlayers)+"&port="
|
||||
+ to_string(Port) + "&map=" + MapName + "&private="+State+"&version="+ServerVersion+
|
||||
R = "uuid="+Key+"&players="+std::to_string(Clients.size())+"&maxplayers="+std::to_string(MaxPlayers)+"&port="
|
||||
+ std::to_string(Port) + "&map=" + MapName + "&private="+State+"&version="+ServerVersion+
|
||||
"&clientversion="+ClientVersion+"&name="+ServerName;
|
||||
if(!CustomIP.empty())R+="&ip="+CustomIP;
|
||||
// https://beamng-mp.com/heartbeatv2
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "logger.h"
|
||||
#include <string>
|
||||
void addToLog(const std::string& Data);
|
||||
using namespace std;
|
||||
int loggerlevel;
|
||||
|
||||
void setLoggerLevel(int level) {
|
||||
@ -15,7 +14,7 @@ void setLoggerLevel(int level) {
|
||||
loggerlevel = level;
|
||||
}
|
||||
|
||||
stringstream getDate() {
|
||||
std::stringstream getDate() {
|
||||
// current date/time based on current system
|
||||
time_t now = time(nullptr);
|
||||
tm* ltm = localtime(&now);
|
||||
@ -26,25 +25,25 @@ stringstream getDate() {
|
||||
int minutes = ltm->tm_min;
|
||||
int seconds = ltm->tm_sec;
|
||||
|
||||
string month_string;
|
||||
if (month < 10) month_string = "0" + to_string(month);
|
||||
else month_string = to_string(month);
|
||||
std::string month_string;
|
||||
if (month < 10) month_string = "0" + std::to_string(month);
|
||||
else month_string = std::to_string(month);
|
||||
|
||||
string day_string;
|
||||
if (day < 10) day_string = "0" + to_string(day);
|
||||
else day_string = to_string(day);
|
||||
std::string day_string;
|
||||
if (day < 10) day_string = "0" + std::to_string(day);
|
||||
else day_string = std::to_string(day);
|
||||
|
||||
string hours_string;
|
||||
if (hours < 10) hours_string = "0" + to_string(hours);
|
||||
else hours_string = to_string(hours);
|
||||
std::string hours_string;
|
||||
if (hours < 10) hours_string = "0" + std::to_string(hours);
|
||||
else hours_string = std::to_string(hours);
|
||||
|
||||
string minutes_string;
|
||||
if (minutes < 10) minutes_string = "0" + to_string(minutes);
|
||||
else minutes_string = to_string(minutes);
|
||||
std::string minutes_string;
|
||||
if (minutes < 10) minutes_string = "0" + std::to_string(minutes);
|
||||
else minutes_string = std::to_string(minutes);
|
||||
|
||||
string seconds_string;
|
||||
if (seconds < 10) seconds_string = "0" + to_string(seconds);
|
||||
else seconds_string = to_string(seconds);
|
||||
std::string seconds_string;
|
||||
if (seconds < 10) seconds_string = "0" + std::to_string(seconds);
|
||||
else seconds_string = std::to_string(seconds);
|
||||
|
||||
std::stringstream date;
|
||||
date
|
||||
@ -62,14 +61,14 @@ stringstream getDate() {
|
||||
|
||||
void info(const std::string& toPrint) {
|
||||
if (loggerlevel <= 2){
|
||||
cout << getDate().str() << "[INFO] " << toPrint << endl;
|
||||
std::cout << getDate().str() << "[INFO] " << toPrint << std::endl;
|
||||
addToLog(getDate().str() + "[INFO] " + toPrint + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void error(const std::string& toPrint) {
|
||||
if (loggerlevel <= 4) {
|
||||
cout << getDate().str() << "[ERROR] " << toPrint << endl;
|
||||
std::cout << getDate().str() << "[ERROR] " << toPrint << std::endl;
|
||||
addToLog(getDate().str() + "[ERROR] " + toPrint + "\n");
|
||||
}
|
||||
}
|
||||
@ -77,7 +76,7 @@ void error(const std::string& toPrint) {
|
||||
|
||||
void warn(const std::string& toPrint) {
|
||||
if (loggerlevel <= 3) {
|
||||
cout << getDate().str() << "[WARN] " << toPrint << endl;
|
||||
std::cout << getDate().str() << "[WARN] " << toPrint << std::endl;
|
||||
addToLog(getDate().str() + "[WARN] " + toPrint + "\n");
|
||||
}
|
||||
}
|
||||
@ -85,7 +84,7 @@ void warn(const std::string& toPrint) {
|
||||
|
||||
void debug(const std::string& toPrint) {
|
||||
if (loggerlevel <= 1) {
|
||||
cout << getDate().str() << "[DEBUG] " << toPrint << endl;
|
||||
std::cout << getDate().str() << "[DEBUG] " << toPrint << std::endl;
|
||||
addToLog(getDate().str() + "[DEBUG] " + toPrint + "\n");
|
||||
}
|
||||
}
|
@ -6,9 +6,8 @@
|
||||
#include <ctime>
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
using namespace std;
|
||||
extern int loggerlevel;
|
||||
stringstream getDate();
|
||||
std::stringstream getDate();
|
||||
void setLoggerLevel(int level);
|
||||
void info(const std::string& toPrint);
|
||||
void warn(const std::string& toPrint);
|
||||
|
18
src/main.cpp
18
src/main.cpp
@ -14,7 +14,7 @@
|
||||
void DebugData();
|
||||
void LogInit();
|
||||
void ParseConfig();
|
||||
void addToLog(const string& Data);
|
||||
void addToLog(const std::string& Data);
|
||||
//void ServerMain(int Port, int MaxClients);
|
||||
void HeartbeatInit();
|
||||
std::string ServerVersion = "0.3";
|
||||
@ -49,11 +49,11 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
|
||||
void DebugData(){
|
||||
debug(string("Debug : ") + (Debug?"true":"false"));
|
||||
debug(string("Private : ") + (Private?"true":"false"));
|
||||
debug("Port : " + to_string(Port));
|
||||
debug("Max Cars : " + to_string(MaxCars));
|
||||
debug("MaxPlayers : " + to_string(MaxPlayers));
|
||||
debug(std::string("Debug : ") + (Debug?"true":"false"));
|
||||
debug(std::string("Private : ") + (Private?"true":"false"));
|
||||
debug("Port : " + std::to_string(Port));
|
||||
debug("Max Cars : " + std::to_string(MaxCars));
|
||||
debug("MaxPlayers : " + std::to_string(MaxPlayers));
|
||||
debug("MapName : " + MapName);
|
||||
debug("ServerName : " + ServerName );
|
||||
debug("File : " + Resource);
|
||||
@ -62,13 +62,13 @@ void DebugData(){
|
||||
|
||||
|
||||
void LogInit(){
|
||||
ofstream LFS;
|
||||
std::ofstream LFS;
|
||||
LFS.open ("Server.log");
|
||||
LFS.close();
|
||||
}
|
||||
|
||||
void addToLog(const string& Data){
|
||||
ofstream LFS;
|
||||
void addToLog(const std::string& Data){
|
||||
std::ofstream LFS;
|
||||
LFS.open ("Server.log", std::ios_base::app);
|
||||
LFS << Data.c_str();
|
||||
LFS.close();
|
||||
|
Loading…
x
Reference in New Issue
Block a user