mirror of
https://github.com/SantaSpeen/BeamMP-Server.git
synced 2026-02-16 11:50:39 +00:00
add lua engine, lua file, server, client, vehicle data, other stuff
This commit is contained in:
committed by
Anonymous275
parent
e5e447c7af
commit
459814a6ec
53
include/Client.h
Normal file
53
include/Client.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "Common.h"
|
||||
#include "Compat.h"
|
||||
#include "VehicleData.h"
|
||||
|
||||
class TClient final {
|
||||
public:
|
||||
using TSetOfVehicleData = std::unordered_set<std::unique_ptr<TVehicleData>>;
|
||||
|
||||
void AddNewCar(int Ident, const std::string& Data);
|
||||
void SetCarData(int Ident, const std::string& Data);
|
||||
TSetOfVehicleData& GetAllCars();
|
||||
void SetName(const std::string& Name) { _Name = Name; }
|
||||
void SetRoles(const std::string& Role) { _Role = Role; }
|
||||
std::string GetCarData(int Ident);
|
||||
void SetUDPAddr(sockaddr_in Addr) { _UDPAddress = Addr; }
|
||||
void SetDownSock(SOCKET CSock) { _Socket[1] = CSock; }
|
||||
void SetTCPSock(SOCKET CSock) { _Socket[0] = CSock; }
|
||||
void SetStatus(int Status) { _Status = Status; }
|
||||
void DeleteCar(int Ident);
|
||||
sockaddr_in GetUDPAddr() { return _UDPAddress; }
|
||||
std::string GetRoles() { return _Role; }
|
||||
std::string GetName() { return _Name; }
|
||||
SOCKET GetDownSock() { return _Socket[1]; }
|
||||
SOCKET GetTCPSock() { return _Socket[0]; }
|
||||
void SetID(int ID) { _ID = ID; }
|
||||
int GetOpenCarID();
|
||||
int GetCarCount();
|
||||
void ClearCars();
|
||||
int GetStatus() { return _Status; }
|
||||
int GetID() { return _ID; }
|
||||
bool IsConnected() const { return _IsConnected; }
|
||||
bool IsSynced() const { return _IsSynced; }
|
||||
bool IsGuest() const { return _IsGuest; }
|
||||
|
||||
private:
|
||||
bool _IsConnected = false;
|
||||
bool _IsSynced = false;
|
||||
bool _IsGuest = false;
|
||||
TSetOfVehicleData _VehicleData;
|
||||
std::string _Name = "Unknown Client";
|
||||
SOCKET _Socket[2] { SOCKET(-1) };
|
||||
sockaddr_in _UDPAddress;
|
||||
std::string _Role;
|
||||
std::string _DID;
|
||||
int _Status = 0;
|
||||
int _ID = -1;
|
||||
};
|
||||
66
include/Common.h
Normal file
66
include/Common.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include "TConsole.h"
|
||||
|
||||
// static class handling application start, shutdown, etc.
|
||||
// yes, static classes, singletons, globals are all pretty
|
||||
// bad idioms. In this case we need a central way to access
|
||||
// stuff like graceful shutdown, global settings (its in the name),
|
||||
// etc.
|
||||
class Application final {
|
||||
public:
|
||||
// types
|
||||
struct TSettings {
|
||||
TSettings()
|
||||
: DebugModeEnabled(true) { }
|
||||
std::string ServerName;
|
||||
std::string ServerDesc;
|
||||
std::string Resource;
|
||||
std::string MapName;
|
||||
std::string Key;
|
||||
int MaxPlayers;
|
||||
bool Private;
|
||||
int MaxCars;
|
||||
bool DebugModeEnabled;
|
||||
int Port;
|
||||
std::string CustomIP;
|
||||
bool HasCustomIP() const { return !CustomIP.empty(); }
|
||||
|
||||
// new settings
|
||||
std::string ResourceFolder;
|
||||
};
|
||||
using TShutdownHandler = std::function<void()>;
|
||||
|
||||
// methods
|
||||
Application() = delete;
|
||||
|
||||
// 'Handler' is called when GracefullyShutdown is called
|
||||
static void RegisterShutdownHandler(const TShutdownHandler& Handler);
|
||||
// Causes all threads to finish up and exit gracefull gracefully
|
||||
static void GracefullyShutdown();
|
||||
static TConsole& Console() { return *_Console; }
|
||||
static std::string ServerVersion() { return "v1.20"; }
|
||||
|
||||
static inline TSettings Settings {};
|
||||
|
||||
private:
|
||||
static std::unique_ptr<TConsole> _Console;
|
||||
static inline std::mutex _ShutdownHandlersMutex {};
|
||||
static inline std::vector<TShutdownHandler> _ShutdownHandlers {};
|
||||
};
|
||||
|
||||
#define warn(x) Application::Console().Write(std::string("[WARN] ") + (x))
|
||||
#define error(x) Application::Console().Write(std::string("[ERROR] ") + (x))
|
||||
#define info(x) Application::Console().Write(std::string("[INFO] ") + (x))
|
||||
#define debug(x) \
|
||||
do { \
|
||||
if (Application::Settings.DebugModeEnabled) { \
|
||||
Application::Console().Write(std::string("[DEBUG] ") + (x)); \
|
||||
} \
|
||||
} while (false)
|
||||
@@ -1,17 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
// Unix - Win32 compatibility stuff
|
||||
// ======================= UNIX ========================
|
||||
|
||||
#ifdef __unix
|
||||
#include <arpa/inet.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
using SOCKET = int;
|
||||
using DWORD = unsigned long;
|
||||
using PDWORD = unsigned long*;
|
||||
using LPDWORD = unsigned long*;
|
||||
char _getch(void);
|
||||
#endif // unix
|
||||
|
||||
// ======================= WIN32 =======================
|
||||
|
||||
#ifdef WIN32
|
||||
#include <conio.h>
|
||||
#include <windows.h>
|
||||
#else // *nix
|
||||
typedef unsigned long DWORD, *PDWORD, *LPDWORD;
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#endif // WIN32
|
||||
|
||||
#ifndef WIN32
|
||||
// ======================= OTHER =======================
|
||||
|
||||
char _getch(void);
|
||||
#if !defined(WIN32) && !defined(__unix)
|
||||
#error "OS not supported"
|
||||
#endif
|
||||
|
||||
#endif // !WIN32
|
||||
|
||||
68
include/CustomAssert.h
Normal file
68
include/CustomAssert.h
Normal file
@@ -0,0 +1,68 @@
|
||||
// Author: lionkor
|
||||
|
||||
/*
|
||||
* Asserts are to be used anywhere where assumptions about state are made
|
||||
* implicitly. AssertNotReachable is used where code should never go, like in
|
||||
* default switch cases which shouldn't trigger. They make it explicit
|
||||
* that a place cannot normally be reached and make it an error if they do.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
static const char* const ANSI_RESET = "\u001b[0m";
|
||||
|
||||
static const char* const ANSI_BLACK = "\u001b[30m";
|
||||
static const char* const ANSI_RED = "\u001b[31m";
|
||||
static const char* const ANSI_GREEN = "\u001b[32m";
|
||||
static const char* const ANSI_YELLOW = "\u001b[33m";
|
||||
static const char* const ANSI_BLUE = "\u001b[34m";
|
||||
static const char* const ANSI_MAGENTA = "\u001b[35m";
|
||||
static const char* const ANSI_CYAN = "\u001b[36m";
|
||||
static const char* const ANSI_WHITE = "\u001b[37m";
|
||||
|
||||
static const char* const ANSI_BLACK_BOLD = "\u001b[30;1m";
|
||||
static const char* const ANSI_RED_BOLD = "\u001b[31;1m";
|
||||
static const char* const ANSI_GREEN_BOLD = "\u001b[32;1m";
|
||||
static const char* const ANSI_YELLOW_BOLD = "\u001b[33;1m";
|
||||
static const char* const ANSI_BLUE_BOLD = "\u001b[34;1m";
|
||||
static const char* const ANSI_MAGENTA_BOLD = "\u001b[35;1m";
|
||||
static const char* const ANSI_CYAN_BOLD = "\u001b[36;1m";
|
||||
static const char* const ANSI_WHITE_BOLD = "\u001b[37;1m";
|
||||
|
||||
static const char* const ANSI_BOLD = "\u001b[1m";
|
||||
static const char* const ANSI_UNDERLINE = "\u001b[4m";
|
||||
|
||||
#if DEBUG
|
||||
#include <iostream>
|
||||
inline void _assert([[maybe_unused]] const char* file, [[maybe_unused]] const char* function, [[maybe_unused]] unsigned line,
|
||||
[[maybe_unused]] const char* condition_string, [[maybe_unused]] bool result) {
|
||||
if (!result) {
|
||||
std::cout << std::flush << "(debug build) TID "
|
||||
<< std::this_thread::get_id() << ": ASSERTION FAILED: at "
|
||||
<< file << ":" << line << " \n\t-> in "
|
||||
<< function << ", Line " << line << ": \n\t\t-> "
|
||||
<< "Failed Condition: " << condition_string << std::endl;
|
||||
std::cout << "... terminating ..." << std::endl;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
#define Assert(cond) _assert(__FILE__, __func__, __LINE__, #cond, (cond))
|
||||
#define AssertNotReachable() _assert(__FILE__, __func__, __LINE__, "reached unreachable code", false)
|
||||
#else
|
||||
// In release build, these macros turn into NOPs. The compiler will optimize these out.
|
||||
#define Assert(x) \
|
||||
do { \
|
||||
} while (false)
|
||||
#define AssertNotReachable() \
|
||||
do { \
|
||||
} while (false)
|
||||
#endif // DEBUG
|
||||
19
include/RWMutex.h
Normal file
19
include/RWMutex.h
Normal file
@@ -0,0 +1,19 @@
|
||||
// Author: lionkor
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* An RWMutex allows multiple simultaneous readlocks but only one writelock at a time,
|
||||
* and write locks and read locks are mutually exclusive.
|
||||
*/
|
||||
|
||||
#include <shared_mutex>
|
||||
|
||||
// Use ReadLock(m) and WriteLock(m) to lock it.
|
||||
using RWMutex = std::shared_mutex;
|
||||
// Construct with an RWMutex as a non-const reference.
|
||||
// locks the mutex in lock_shared mode (for reading). Locking in a thread that already owns a lock
|
||||
// i.e. locking multiple times successively is UB. Construction may be blocking. Destruction is guaranteed to release the lock.
|
||||
using ReadLock = std::shared_lock<RWMutex>;
|
||||
// Construct with an RWMutex as a non-const reference.
|
||||
// locks the mutex for writing. Construction may be blocking. Destruction is guaranteed to release the lock.
|
||||
using WriteLock = std::unique_lock<RWMutex>;
|
||||
12
include/TConfig.h
Normal file
12
include/TConfig.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
class TConfig {
|
||||
public:
|
||||
TConfig(const std::string& ConfigFile);
|
||||
|
||||
private:
|
||||
std::string RemoveComments(const std::string& Line);
|
||||
void SetValues(const std::string& Line, int Index);
|
||||
};
|
||||
@@ -1,12 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "commandline/commandline.h"
|
||||
#include <atomic>
|
||||
#include <commandline/commandline.h>
|
||||
#include <fstream>
|
||||
|
||||
class TConsole {
|
||||
public:
|
||||
TConsole();
|
||||
|
||||
void Write(const std::string& str);
|
||||
|
||||
private:
|
||||
Commandline _Commandline;
|
||||
};
|
||||
|
||||
|
||||
32
include/TLuaEngine.h
Normal file
32
include/TLuaEngine.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef TLUAENGINE_H
|
||||
#define TLUAENGINE_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "IThreaded.h"
|
||||
#include <lua.hpp>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
class TLuaFile;
|
||||
|
||||
class TLuaEngine : public IThreaded {
|
||||
public:
|
||||
using TSetOfLuaFile = std::set<std::unique_ptr<TLuaFile>>;
|
||||
|
||||
TLuaEngine();
|
||||
|
||||
virtual void operator()() override;
|
||||
|
||||
const TSetOfLuaFile& LuaFiles() const { return _LuaFiles; }
|
||||
|
||||
std::optional<std::reference_wrapper<TLuaFile>> GetScript(lua_State* L);
|
||||
|
||||
private:
|
||||
void FolderList(const std::string& Path, bool HotSwap);
|
||||
void RegisterFiles(const std::string& Path, bool HotSwap);
|
||||
bool NewFile(const std::string& Path);
|
||||
|
||||
TSetOfLuaFile _LuaFiles;
|
||||
};
|
||||
|
||||
#endif // TLUAENGINE_H
|
||||
58
include/TLuaFile.h
Normal file
58
include/TLuaFile.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#ifndef TLUAFILE_H
|
||||
#define TLUAFILE_H
|
||||
|
||||
#include "TLuaEngine.h"
|
||||
#include <any>
|
||||
#include <filesystem>
|
||||
#include <lua.hpp>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
struct TLuaArg {
|
||||
std::vector<std::any> args;
|
||||
void PushArgs(lua_State* State);
|
||||
};
|
||||
|
||||
class TLuaFile {
|
||||
public:
|
||||
void Init();
|
||||
void RegisterEvent(const std::string& Event, const std::string& FunctionName);
|
||||
std::string GetRegistered(const std::string& Event) const;
|
||||
void UnRegisterEvent(const std::string& Event);
|
||||
void SetLastWrite(fs::file_time_type time);
|
||||
bool IsRegistered(const std::string& Event);
|
||||
void SetPluginName(const std::string& Name);
|
||||
void Execute(const std::string& Command);
|
||||
void SetFileName(const std::string& Name);
|
||||
fs::file_time_type GetLastWrite();
|
||||
std::string GetPluginName() const;
|
||||
std::string GetFileName() const;
|
||||
lua_State* GetState();
|
||||
const lua_State* GetState() const;
|
||||
std::string GetOrigin();
|
||||
std::mutex Lock;
|
||||
void Reload();
|
||||
TLuaFile(TLuaEngine& Engine, const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote, bool Console = false);
|
||||
TLuaFile(TLuaEngine& Engine, bool Console = false);
|
||||
~TLuaFile();
|
||||
void SetStopThread(bool StopThread) { _StopThread = StopThread; }
|
||||
bool GetStopThread() const { return _StopThread; }
|
||||
TLuaEngine& Engine() { return _Engine; }
|
||||
const TLuaEngine& Engine() const { return _Engine; }
|
||||
|
||||
private:
|
||||
TLuaEngine& _Engine;
|
||||
std::set<std::pair<std::string, std::string>> _RegisteredEvents;
|
||||
lua_State* luaState { nullptr };
|
||||
fs::file_time_type _LastWrote;
|
||||
std::string _PluginName {};
|
||||
std::string _FileName {};
|
||||
bool _StopThread = false;
|
||||
bool _Console = false;
|
||||
};
|
||||
|
||||
#endif // TLUAFILE_H
|
||||
26
include/TServer.h
Normal file
26
include/TServer.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "RWMutex.h"
|
||||
|
||||
class TClient;
|
||||
|
||||
class TServer final {
|
||||
public:
|
||||
using TClientSet = std::unordered_set<std::shared_ptr<TClient>>;
|
||||
|
||||
TServer(int argc, char** argv);
|
||||
|
||||
std::weak_ptr<TClient> InsertNewClient();
|
||||
void RemoveClient(std::weak_ptr<TClient>);
|
||||
void ForEachClient(std::function<bool(std::weak_ptr<TClient>)>);
|
||||
size_t ClientCount() const;
|
||||
|
||||
private:
|
||||
TClientSet _Clients;
|
||||
mutable RWMutex _ClientsMutex;
|
||||
};
|
||||
18
include/VehicleData.h
Normal file
18
include/VehicleData.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class TVehicleData final {
|
||||
public:
|
||||
TVehicleData(int ID, const std::string& Data);
|
||||
|
||||
bool IsInvalid() const { return _ID == -1; }
|
||||
int ID() const { return _ID; }
|
||||
|
||||
std::string Data() const { return _Data; }
|
||||
void SetData(const std::string& Data) { _Data = Data; }
|
||||
|
||||
private:
|
||||
int _ID { -1 };
|
||||
std::string _Data;
|
||||
};
|
||||
Reference in New Issue
Block a user