mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2025-08-16 16:26:26 +00:00
fully implement lua
This commit is contained in:
parent
459814a6ec
commit
4cda6e8bc3
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
boost_*
|
boost_*
|
||||||
Resources
|
Resources
|
||||||
|
.idea*
|
||||||
## Ignore Visual Studio temporary files, build results, and
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
## files generated by popular Visual Studio add-ons.
|
## files generated by popular Visual Studio add-ons.
|
||||||
##
|
##
|
||||||
|
@ -17,7 +17,7 @@ class Application final {
|
|||||||
public:
|
public:
|
||||||
// types
|
// types
|
||||||
struct TSettings {
|
struct TSettings {
|
||||||
TSettings()
|
TSettings() noexcept
|
||||||
: DebugModeEnabled(true) { }
|
: DebugModeEnabled(true) { }
|
||||||
std::string ServerName;
|
std::string ServerName;
|
||||||
std::string ServerDesc;
|
std::string ServerDesc;
|
||||||
@ -30,7 +30,7 @@ public:
|
|||||||
bool DebugModeEnabled;
|
bool DebugModeEnabled;
|
||||||
int Port;
|
int Port;
|
||||||
std::string CustomIP;
|
std::string CustomIP;
|
||||||
bool HasCustomIP() const { return !CustomIP.empty(); }
|
[[nodiscard]] bool HasCustomIP() const { return !CustomIP.empty(); }
|
||||||
|
|
||||||
// new settings
|
// new settings
|
||||||
std::string ResourceFolder;
|
std::string ResourceFolder;
|
||||||
@ -44,20 +44,21 @@ public:
|
|||||||
static void RegisterShutdownHandler(const TShutdownHandler& Handler);
|
static void RegisterShutdownHandler(const TShutdownHandler& Handler);
|
||||||
// Causes all threads to finish up and exit gracefull gracefully
|
// Causes all threads to finish up and exit gracefull gracefully
|
||||||
static void GracefullyShutdown();
|
static void GracefullyShutdown();
|
||||||
static TConsole& Console() { return *_Console; }
|
static TConsole& Console() { return *mConsole; }
|
||||||
static std::string ServerVersion() { return "v1.20"; }
|
static std::string ServerVersion() { return "v1.20"; }
|
||||||
|
|
||||||
static inline TSettings Settings {};
|
static inline TSettings Settings {};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::unique_ptr<TConsole> _Console;
|
static std::unique_ptr<TConsole> mConsole;
|
||||||
static inline std::mutex _ShutdownHandlersMutex {};
|
static inline std::mutex mShutdownHandlersMutex {};
|
||||||
static inline std::vector<TShutdownHandler> _ShutdownHandlers {};
|
static inline std::vector<TShutdownHandler> mShutdownHandlers {};
|
||||||
};
|
};
|
||||||
|
|
||||||
#define warn(x) Application::Console().Write(std::string("[WARN] ") + (x))
|
#define warn(x) Application::Console().Write(std::string("[WARN] ") + (x))
|
||||||
#define error(x) Application::Console().Write(std::string("[ERROR] ") + (x))
|
#define error(x) Application::Console().Write(std::string("[ERROR] ") + (x))
|
||||||
#define info(x) Application::Console().Write(std::string("[INFO] ") + (x))
|
#define info(x) Application::Console().Write(std::string("[INFO] ") + (x))
|
||||||
|
#define luaprint(x) Application::Console().Write(std::string("[LUA] ") + (x))
|
||||||
#define debug(x) \
|
#define debug(x) \
|
||||||
do { \
|
do { \
|
||||||
if (Application::Settings.DebugModeEnabled) { \
|
if (Application::Settings.DebugModeEnabled) { \
|
||||||
|
@ -11,6 +11,5 @@ public:
|
|||||||
void Write(const std::string& str);
|
void Write(const std::string& str);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Commandline _Commandline;
|
Commandline mCommandline;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "IThreaded.h"
|
#include "IThreaded.h"
|
||||||
|
#include "TServer.h"
|
||||||
#include <lua.hpp>
|
#include <lua.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <set>
|
#include <set>
|
||||||
@ -11,13 +12,15 @@ class TLuaFile;
|
|||||||
|
|
||||||
class TLuaEngine : public IThreaded {
|
class TLuaEngine : public IThreaded {
|
||||||
public:
|
public:
|
||||||
|
explicit TLuaEngine(TServer& Server);
|
||||||
|
|
||||||
using TSetOfLuaFile = std::set<std::unique_ptr<TLuaFile>>;
|
using TSetOfLuaFile = std::set<std::unique_ptr<TLuaFile>>;
|
||||||
|
|
||||||
TLuaEngine();
|
void operator()() override;
|
||||||
|
|
||||||
virtual void operator()() override;
|
[[nodiscard]] const TSetOfLuaFile& LuaFiles() const { return mLuaFiles; }
|
||||||
|
[[nodiscard]] TServer& Server() { return mServer; }
|
||||||
const TSetOfLuaFile& LuaFiles() const { return _LuaFiles; }
|
[[nodiscard]] const TServer& Server() const { return mServer; }
|
||||||
|
|
||||||
std::optional<std::reference_wrapper<TLuaFile>> GetScript(lua_State* L);
|
std::optional<std::reference_wrapper<TLuaFile>> GetScript(lua_State* L);
|
||||||
|
|
||||||
@ -26,7 +29,8 @@ private:
|
|||||||
void RegisterFiles(const std::string& Path, bool HotSwap);
|
void RegisterFiles(const std::string& Path, bool HotSwap);
|
||||||
bool NewFile(const std::string& Path);
|
bool NewFile(const std::string& Path);
|
||||||
|
|
||||||
TSetOfLuaFile _LuaFiles;
|
TServer& mServer;
|
||||||
|
TSetOfLuaFile mLuaFiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TLUAENGINE_H
|
#endif // TLUAENGINE_H
|
||||||
|
@ -21,7 +21,6 @@ class TLuaFile {
|
|||||||
public:
|
public:
|
||||||
void Init();
|
void Init();
|
||||||
void RegisterEvent(const std::string& Event, const std::string& FunctionName);
|
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 UnRegisterEvent(const std::string& Event);
|
||||||
void SetLastWrite(fs::file_time_type time);
|
void SetLastWrite(fs::file_time_type time);
|
||||||
bool IsRegistered(const std::string& Event);
|
bool IsRegistered(const std::string& Event);
|
||||||
@ -29,30 +28,31 @@ public:
|
|||||||
void Execute(const std::string& Command);
|
void Execute(const std::string& Command);
|
||||||
void SetFileName(const std::string& Name);
|
void SetFileName(const std::string& Name);
|
||||||
fs::file_time_type GetLastWrite();
|
fs::file_time_type GetLastWrite();
|
||||||
std::string GetPluginName() const;
|
|
||||||
std::string GetFileName() const;
|
|
||||||
lua_State* GetState();
|
lua_State* GetState();
|
||||||
const lua_State* GetState() const;
|
|
||||||
std::string GetOrigin();
|
std::string GetOrigin();
|
||||||
std::mutex Lock;
|
std::mutex Lock;
|
||||||
void Reload();
|
void Reload();
|
||||||
TLuaFile(TLuaEngine& Engine, const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote, bool Console = false);
|
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);
|
explicit TLuaFile(TLuaEngine& Engine, bool Console = false);
|
||||||
~TLuaFile();
|
~TLuaFile();
|
||||||
void SetStopThread(bool StopThread) { _StopThread = StopThread; }
|
void SetStopThread(bool StopThread) { mStopThread = StopThread; }
|
||||||
bool GetStopThread() const { return _StopThread; }
|
TLuaEngine& Engine() { return mEngine; }
|
||||||
TLuaEngine& Engine() { return _Engine; }
|
[[nodiscard]] std::string GetPluginName() const;
|
||||||
const TLuaEngine& Engine() const { return _Engine; }
|
[[nodiscard]] std::string GetFileName() const;
|
||||||
|
[[nodiscard]] const lua_State* GetState() const;
|
||||||
|
[[nodiscard]] bool GetStopThread() const { return mStopThread; }
|
||||||
|
[[nodiscard]] const TLuaEngine& Engine() const { return mEngine; }
|
||||||
|
[[nodiscard]] std::string GetRegistered(const std::string& Event) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TLuaEngine& _Engine;
|
TLuaEngine& mEngine;
|
||||||
std::set<std::pair<std::string, std::string>> _RegisteredEvents;
|
std::set<std::pair<std::string, std::string>> mRegisteredEvents;
|
||||||
lua_State* luaState { nullptr };
|
lua_State* mLuaState { nullptr };
|
||||||
fs::file_time_type _LastWrote;
|
fs::file_time_type mLastWrote;
|
||||||
std::string _PluginName {};
|
std::string mPluginName {};
|
||||||
std::string _FileName {};
|
std::string mFileName {};
|
||||||
bool _StopThread = false;
|
bool mStopThread = false;
|
||||||
bool _Console = false;
|
bool mConsole = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TLUAFILE_H
|
#endif // TLUAFILE_H
|
||||||
|
@ -17,10 +17,10 @@ public:
|
|||||||
|
|
||||||
std::weak_ptr<TClient> InsertNewClient();
|
std::weak_ptr<TClient> InsertNewClient();
|
||||||
void RemoveClient(std::weak_ptr<TClient>);
|
void RemoveClient(std::weak_ptr<TClient>);
|
||||||
void ForEachClient(std::function<bool(std::weak_ptr<TClient>)>);
|
void ForEachClient(const std::function<bool(std::weak_ptr<TClient>)>& Fn);
|
||||||
size_t ClientCount() const;
|
size_t ClientCount() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TClientSet _Clients;
|
TClientSet mClients;
|
||||||
mutable RWMutex _ClientsMutex;
|
mutable RWMutex mClientsMutex;
|
||||||
};
|
};
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "TConsole.h"
|
#include "TConsole.h"
|
||||||
|
|
||||||
std::unique_ptr<TConsole> Application::_Console = std::make_unique<TConsole>();
|
std::unique_ptr<TConsole> Application::mConsole = std::make_unique<TConsole>();
|
||||||
|
|
||||||
void Application::RegisterShutdownHandler(const TShutdownHandler& Handler) {
|
void Application::RegisterShutdownHandler(const TShutdownHandler& Handler) {
|
||||||
std::unique_lock Lock(_ShutdownHandlersMutex);
|
std::unique_lock Lock(mShutdownHandlersMutex);
|
||||||
if (Handler) {
|
if (Handler) {
|
||||||
_ShutdownHandlers.push_back(Handler);
|
mShutdownHandlers.push_back(Handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::GracefullyShutdown() {
|
void Application::GracefullyShutdown() {
|
||||||
std::unique_lock Lock(_ShutdownHandlersMutex);
|
std::unique_lock Lock(mShutdownHandlersMutex);
|
||||||
for (auto& Handler : _ShutdownHandlers) {
|
for (auto& Handler : mShutdownHandlers) {
|
||||||
Handler();
|
Handler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,12 +40,12 @@ std::string GetDate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TConsole::TConsole() {
|
TConsole::TConsole() {
|
||||||
_Commandline.enable_history();
|
mCommandline.enable_history();
|
||||||
_Commandline.set_history_limit(20);
|
mCommandline.set_history_limit(20);
|
||||||
_Commandline.set_prompt("> ");
|
mCommandline.set_prompt("> ");
|
||||||
_Commandline.on_command = [this](Commandline& c) {
|
mCommandline.on_command = [this](Commandline& c) {
|
||||||
auto cmd = c.get_command();
|
auto cmd = c.get_command();
|
||||||
_Commandline.write("> " + cmd);
|
mCommandline.write("> " + cmd);
|
||||||
if (cmd == "exit") {
|
if (cmd == "exit") {
|
||||||
info("gracefully shutting down");
|
info("gracefully shutting down");
|
||||||
Application::GracefullyShutdown();
|
Application::GracefullyShutdown();
|
||||||
@ -59,7 +59,7 @@ TConsole::TConsole() {
|
|||||||
|
|
||||||
void TConsole::Write(const std::string& str) {
|
void TConsole::Write(const std::string& str) {
|
||||||
auto ToWrite = GetDate() + str;
|
auto ToWrite = GetDate() + str;
|
||||||
_Commandline.write(ToWrite);
|
mCommandline.write(ToWrite);
|
||||||
// TODO write to logfile, too
|
// TODO write to logfile, too
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
TLuaEngine::TLuaEngine() {
|
TLuaEngine::TLuaEngine(TServer& Server)
|
||||||
|
: mServer(Server) {
|
||||||
if (!fs::exists(Application::Settings.ResourceFolder)) {
|
if (!fs::exists(Application::Settings.ResourceFolder)) {
|
||||||
fs::create_directory(Application::Settings.ResourceFolder);
|
fs::create_directory(Application::Settings.ResourceFolder);
|
||||||
}
|
}
|
||||||
@ -22,7 +23,7 @@ void TLuaEngine::operator()() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::reference_wrapper<TLuaFile>> TLuaEngine::GetScript(lua_State* L) {
|
std::optional<std::reference_wrapper<TLuaFile>> TLuaEngine::GetScript(lua_State* L) {
|
||||||
for (auto& Script : _LuaFiles) {
|
for (auto& Script : mLuaFiles) {
|
||||||
if (Script->GetState() == L)
|
if (Script->GetState() == L)
|
||||||
return *Script;
|
return *Script;
|
||||||
}
|
}
|
||||||
@ -49,7 +50,7 @@ void TLuaEngine::RegisterFiles(const std::string& Path, bool HotSwap) {
|
|||||||
auto FileName = entry.path().string();
|
auto FileName = entry.path().string();
|
||||||
std::unique_ptr<TLuaFile> ScriptToInsert(new TLuaFile(*this, Name, FileName, fs::last_write_time(FileName)));
|
std::unique_ptr<TLuaFile> ScriptToInsert(new TLuaFile(*this, Name, FileName, fs::last_write_time(FileName)));
|
||||||
auto& Script = *ScriptToInsert;
|
auto& Script = *ScriptToInsert;
|
||||||
_LuaFiles.insert(std::move(ScriptToInsert));
|
mLuaFiles.insert(std::move(ScriptToInsert));
|
||||||
Script.Init();
|
Script.Init();
|
||||||
if (HotSwap)
|
if (HotSwap)
|
||||||
info(("[HOTSWAP] Added : ") + Script.GetFileName().substr(Script.GetFileName().find('\\')));
|
info(("[HOTSWAP] Added : ") + Script.GetFileName().substr(Script.GetFileName().find('\\')));
|
||||||
@ -59,7 +60,7 @@ void TLuaEngine::RegisterFiles(const std::string& Path, bool HotSwap) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TLuaEngine::NewFile(const std::string& Path) {
|
bool TLuaEngine::NewFile(const std::string& Path) {
|
||||||
for (auto& Script : _LuaFiles) {
|
for (auto& Script : mLuaFiles) {
|
||||||
if (Path == Script->GetFileName())
|
if (Path == Script->GetFileName())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
345
src/TLuaFile.cpp
345
src/TLuaFile.cpp
@ -1,17 +1,25 @@
|
|||||||
#include "TLuaFile.h"
|
#include "TLuaFile.h"
|
||||||
#include "Client.h"
|
#include "Client.h"
|
||||||
|
#include "Common.h"
|
||||||
#include "CustomAssert.h"
|
#include "CustomAssert.h"
|
||||||
#include "TServer.h"
|
#include "TServer.h"
|
||||||
|
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
// TODO: REWRITE >:(
|
// TODO: REWRITE
|
||||||
|
|
||||||
void SendError(TLuaEngine& Engine, lua_State* L, const std::string& msg);
|
void SendError(TLuaEngine& Engine, lua_State* L, const std::string& msg);
|
||||||
std::any CallFunction(TLuaFile* lua, const std::string& FuncName, std::shared_ptr<TLuaArg> Arg);
|
std::any CallFunction(TLuaFile* lua, const std::string& FuncName, std::shared_ptr<TLuaArg> Arg);
|
||||||
std::any TriggerLuaEvent(TLuaEngine& Engine, const std::string& Event, bool local, TLuaFile* Caller, std::shared_ptr<TLuaArg> arg, bool Wait);
|
std::any TriggerLuaEvent(TLuaEngine& Engine, const std::string& Event, bool local, TLuaFile* Caller, std::shared_ptr<TLuaArg> arg, bool Wait);
|
||||||
|
|
||||||
|
static TLuaEngine* TheEngine { nullptr };
|
||||||
|
|
||||||
|
static TLuaEngine& Engine() {
|
||||||
|
Assert(TheEngine);
|
||||||
|
return *TheEngine;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<TLuaArg> CreateArg(lua_State* L, int T, int S) {
|
std::shared_ptr<TLuaArg> CreateArg(lua_State* L, int T, int S) {
|
||||||
if (S > T)
|
if (S > T)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -96,10 +104,10 @@ bool ConsoleCheck(lua_State* L, int r) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool CheckLua(TLuaEngine& Engine, lua_State* L, int r) {
|
bool CheckLua(lua_State* L, int r) {
|
||||||
if (r != LUA_OK) {
|
if (r != LUA_OK) {
|
||||||
std::string msg = lua_tostring(L, -1);
|
std::string msg = lua_tostring(L, -1);
|
||||||
auto MaybeS = Engine.GetScript(L);
|
auto MaybeS = Engine().GetScript(L);
|
||||||
if (MaybeS.has_value()) {
|
if (MaybeS.has_value()) {
|
||||||
TLuaFile& S = MaybeS.value();
|
TLuaFile& S = MaybeS.value();
|
||||||
std::string a = fs::path(S.GetFileName()).filename().string();
|
std::string a = fs::path(S.GetFileName()).filename().string();
|
||||||
@ -112,45 +120,45 @@ bool CheckLua(TLuaEngine& Engine, lua_State* L, int r) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lua_RegisterEvent(TLuaEngine& Engine, lua_State* L) {
|
int lua_RegisterEvent(lua_State* L) {
|
||||||
int Args = lua_gettop(L);
|
int Args = lua_gettop(L);
|
||||||
auto MaybeScript = Engine.GetScript(L);
|
auto MaybeScript = Engine().GetScript(L);
|
||||||
Assert(MaybeScript.has_value());
|
Assert(MaybeScript.has_value());
|
||||||
TLuaFile& Script = MaybeScript.value();
|
TLuaFile& Script = MaybeScript.value();
|
||||||
if (Args == 2 && lua_isstring(L, 1) && lua_isstring(L, 2)) {
|
if (Args == 2 && lua_isstring(L, 1) && lua_isstring(L, 2)) {
|
||||||
Script.RegisterEvent(lua_tostring(L, 1), lua_tostring(L, 2));
|
Script.RegisterEvent(lua_tostring(L, 1), lua_tostring(L, 2));
|
||||||
} else
|
} else
|
||||||
SendError(Engine, L, ("RegisterEvent invalid argument count expected 2 got ") + std::to_string(Args));
|
SendError(Engine(), L, ("RegisterEvent invalid argument count expected 2 got ") + std::to_string(Args));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int lua_TriggerEventL(TLuaEngine& Engine, lua_State* L) {
|
int lua_TriggerEventL(lua_State* L) {
|
||||||
int Args = lua_gettop(L);
|
int Args = lua_gettop(L);
|
||||||
auto MaybeScript = Engine.GetScript(L);
|
auto MaybeScript = Engine().GetScript(L);
|
||||||
Assert(MaybeScript.has_value());
|
Assert(MaybeScript.has_value());
|
||||||
TLuaFile& Script = MaybeScript.value();
|
TLuaFile& Script = MaybeScript.value();
|
||||||
if (Args > 0) {
|
if (Args > 0) {
|
||||||
if (lua_isstring(L, 1)) {
|
if (lua_isstring(L, 1)) {
|
||||||
TriggerLuaEvent(Engine, lua_tostring(L, 1), true, &Script, CreateArg(L, Args, 2), false);
|
TriggerLuaEvent(Engine(), lua_tostring(L, 1), true, &Script, CreateArg(L, Args, 2), false);
|
||||||
} else
|
} else
|
||||||
SendError(Engine, L, ("TriggerLocalEvent wrong argument [1] need string"));
|
SendError(Engine(), L, ("TriggerLocalEvent wrong argument [1] need string"));
|
||||||
} else {
|
} else {
|
||||||
SendError(Engine, L, ("TriggerLocalEvent not enough arguments expected 1 got 0"));
|
SendError(Engine(), L, ("TriggerLocalEvent not enough arguments expected 1 got 0"));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lua_TriggerEventG(TLuaEngine& Engine, lua_State* L) {
|
int lua_TriggerEventG(lua_State* L) {
|
||||||
int Args = lua_gettop(L);
|
int Args = lua_gettop(L);
|
||||||
auto MaybeScript = Engine.GetScript(L);
|
auto MaybeScript = Engine().GetScript(L);
|
||||||
Assert(MaybeScript.has_value());
|
Assert(MaybeScript.has_value());
|
||||||
TLuaFile& Script = MaybeScript.value();
|
TLuaFile& Script = MaybeScript.value();
|
||||||
if (Args > 0) {
|
if (Args > 0) {
|
||||||
if (lua_isstring(L, 1)) {
|
if (lua_isstring(L, 1)) {
|
||||||
TriggerLuaEvent(Engine, lua_tostring(L, 1), false, &Script, CreateArg(L, Args, 2), false);
|
TriggerLuaEvent(Engine(), lua_tostring(L, 1), false, &Script, CreateArg(L, Args, 2), false);
|
||||||
} else
|
} else
|
||||||
SendError(Engine, L, ("TriggerGlobalEvent wrong argument [1] need string"));
|
SendError(Engine(), L, ("TriggerGlobalEvent wrong argument [1] need string"));
|
||||||
} else
|
} else
|
||||||
SendError(Engine, L, ("TriggerGlobalEvent not enough arguments"));
|
SendError(Engine(), L, ("TriggerGlobalEvent not enough arguments"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +182,7 @@ void SafeExecution(TLuaEngine& Engine, TLuaFile* lua, const std::string& FuncNam
|
|||||||
}
|
}
|
||||||
#else // unix
|
#else // unix
|
||||||
int R = lua_pcall(luaState, 0, 0, 0);
|
int R = lua_pcall(luaState, 0, 0, 0);
|
||||||
CheckLua(Engine, luaState, R);
|
CheckLua(luaState, R);
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
delete[] Origin;
|
delete[] Origin;
|
||||||
}
|
}
|
||||||
@ -185,23 +193,23 @@ void ExecuteAsync(TLuaEngine& Engine, TLuaFile* lua, const std::string& FuncName
|
|||||||
std::lock_guard<std::mutex> lockGuard(lua->Lock);
|
std::lock_guard<std::mutex> lockGuard(lua->Lock);
|
||||||
SafeExecution(Engine, lua, FuncName);
|
SafeExecution(Engine, lua, FuncName);
|
||||||
}
|
}
|
||||||
void CallAsync(TLuaEngine& Engine, TLuaFile* lua, const std::string& Func, int U) {
|
void CallAsync(TLuaFile* lua, const std::string& Func, int U) {
|
||||||
//DebugPrintTID();
|
//DebugPrintTID();
|
||||||
lua->SetStopThread(false);
|
lua->SetStopThread(false);
|
||||||
int D = 1000 / U;
|
int D = 1000 / U;
|
||||||
while (!lua->GetStopThread()) {
|
while (!lua->GetStopThread()) {
|
||||||
ExecuteAsync(Engine, lua, Func);
|
ExecuteAsync(Engine(), lua, Func);
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(D));
|
std::this_thread::sleep_for(std::chrono::milliseconds(D));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int lua_StopThread(TLuaEngine& Engine, lua_State* L) {
|
int lua_StopThread(lua_State* L) {
|
||||||
auto MaybeScript = Engine.GetScript(L);
|
auto MaybeScript = Engine().GetScript(L);
|
||||||
Assert(MaybeScript.has_value());
|
Assert(MaybeScript.has_value());
|
||||||
// ugly, but whatever, this is safe as fuck
|
// ugly, but whatever, this is safe as fuck
|
||||||
MaybeScript.value().get().SetStopThread(true);
|
MaybeScript.value().get().SetStopThread(true);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int lua_CreateThread(TLuaEngine& Engine, lua_State* L) {
|
int lua_CreateThread(lua_State* L) {
|
||||||
int Args = lua_gettop(L);
|
int Args = lua_gettop(L);
|
||||||
if (Args > 1) {
|
if (Args > 1) {
|
||||||
if (lua_isstring(L, 1)) {
|
if (lua_isstring(L, 1)) {
|
||||||
@ -209,55 +217,56 @@ int lua_CreateThread(TLuaEngine& Engine, lua_State* L) {
|
|||||||
if (lua_isinteger(L, 2) || lua_isnumber(L, 2)) {
|
if (lua_isinteger(L, 2) || lua_isnumber(L, 2)) {
|
||||||
int U = int(lua_tointeger(L, 2));
|
int U = int(lua_tointeger(L, 2));
|
||||||
if (U > 0 && U < 501) {
|
if (U > 0 && U < 501) {
|
||||||
auto MaybeScript = Engine.GetScript(L);
|
auto MaybeScript = Engine().GetScript(L);
|
||||||
Assert(MaybeScript.has_value());
|
Assert(MaybeScript.has_value());
|
||||||
TLuaFile& Script = MaybeScript.value();
|
TLuaFile& Script = MaybeScript.value();
|
||||||
std::thread t1(CallAsync, &Script, STR, U);
|
std::thread t1(CallAsync, &Script, STR, U);
|
||||||
t1.detach();
|
t1.detach();
|
||||||
} else
|
} else
|
||||||
SendError(Engine, L, ("CreateThread wrong argument [2] number must be between 1 and 500"));
|
SendError(Engine(), L, ("CreateThread wrong argument [2] number must be between 1 and 500"));
|
||||||
} else
|
} else
|
||||||
SendError(Engine, L, ("CreateThread wrong argument [2] need number"));
|
SendError(Engine(), L, ("CreateThread wrong argument [2] need number"));
|
||||||
} else
|
} else
|
||||||
SendError(Engine, L, ("CreateThread wrong argument [1] need string"));
|
SendError(Engine(), L, ("CreateThread wrong argument [1] need string"));
|
||||||
} else
|
} else
|
||||||
SendError(Engine, L, ("CreateThread not enough arguments"));
|
SendError(Engine(), L, ("CreateThread not enough arguments"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int lua_Sleep(TLuaEngine& Engine, lua_State* L) {
|
int lua_Sleep(lua_State* L) {
|
||||||
if (lua_isnumber(L, 1)) {
|
if (lua_isnumber(L, 1)) {
|
||||||
int t = int(lua_tonumber(L, 1));
|
int t = int(lua_tonumber(L, 1));
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(t));
|
std::this_thread::sleep_for(std::chrono::milliseconds(t));
|
||||||
} else {
|
} else {
|
||||||
SendError(Engine, L, ("Sleep not enough arguments"));
|
SendError(Engine(), L, ("Sleep not enough arguments"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
std::weak_ptr<TClient> GetClient(TServer& Server, int ID) {
|
std::optional<std::weak_ptr<TClient>> GetClient(TServer& Server, int ID) {
|
||||||
std::weak_ptr<TClient> Client;
|
std::optional<std::weak_ptr<TClient>> MaybeClient { std::nullopt };
|
||||||
Server.ForEachClient([&](std::weak_ptr<TClient> CPtr) {
|
Server.ForEachClient([&](std::weak_ptr<TClient> CPtr) -> bool {
|
||||||
if (!CPtr.expired()) {
|
if (!CPtr.expired()) {
|
||||||
auto C = CPtr.lock();
|
auto C = CPtr.lock();
|
||||||
if (C != nullptr && C->GetID() == ID) {
|
if (C->GetID() == ID) {
|
||||||
|
MaybeClient = CPtr;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
return std::weak_ptr<TClient>();
|
return MaybeClient;
|
||||||
}
|
}
|
||||||
// CONTINUE
|
// CONTINUE
|
||||||
int lua_isConnected(lua_State* L) {
|
int lua_isConnected(lua_State* L) {
|
||||||
if (lua_isnumber(L, 1)) {
|
if (lua_isnumber(L, 1)) {
|
||||||
int ID = int(lua_tonumber(L, 1));
|
int ID = int(lua_tonumber(L, 1));
|
||||||
Client* c = GetClient(ID);
|
auto MaybeClient = GetClient(Engine().Server(), ID);
|
||||||
if (c != nullptr)
|
if (MaybeClient && !MaybeClient.value().expired())
|
||||||
lua_pushboolean(L, c->isConnected);
|
lua_pushboolean(L, MaybeClient.value().lock()->IsConnected());
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
SendError(L, ("isConnected not enough arguments"));
|
SendError(Engine(), L, ("isConnected not enough arguments"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -265,70 +274,71 @@ int lua_isConnected(lua_State* L) {
|
|||||||
int lua_GetPlayerName(lua_State* L) {
|
int lua_GetPlayerName(lua_State* L) {
|
||||||
if (lua_isnumber(L, 1)) {
|
if (lua_isnumber(L, 1)) {
|
||||||
int ID = int(lua_tonumber(L, 1));
|
int ID = int(lua_tonumber(L, 1));
|
||||||
Client* c = GetClient(ID);
|
auto MaybeClient = GetClient(Engine().Server(), ID);
|
||||||
if (c != nullptr)
|
if (MaybeClient && !MaybeClient.value().expired())
|
||||||
lua_pushstring(L, c->GetName().c_str());
|
lua_pushstring(L, MaybeClient.value().lock()->GetName().c_str());
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
SendError(L, ("GetPlayerName not enough arguments"));
|
SendError(Engine(), L, ("GetPlayerName not enough arguments"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
int lua_GetPlayerCount(lua_State* L) {
|
int lua_GetPlayerCount(lua_State* L) {
|
||||||
lua_pushinteger(L, CI->Size());
|
lua_pushinteger(L, Engine().Server().ClientCount());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
int lua_GetGuest(lua_State* L) {
|
int lua_GetGuest(lua_State* L) {
|
||||||
if (lua_isnumber(L, 1)) {
|
if (lua_isnumber(L, 1)) {
|
||||||
int ID = int(lua_tonumber(L, 1));
|
int ID = int(lua_tonumber(L, 1));
|
||||||
Client* c = GetClient(ID);
|
auto MaybeClient = GetClient(Engine().Server(), ID);
|
||||||
if (c != nullptr)
|
if (MaybeClient && !MaybeClient.value().expired())
|
||||||
lua_pushboolean(L, c->isGuest);
|
lua_pushboolean(L, MaybeClient.value().lock()->IsGuest());
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
SendError(L, "GetGuest not enough arguments");
|
SendError(Engine(), L, "GetGuest not enough arguments");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
int lua_GetAllPlayers(lua_State* L) {
|
int lua_GetAllPlayers(lua_State* L) {
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
int i = 1;
|
Engine().Server().ForEachClient([&](std::weak_ptr<TClient> ClientPtr) -> bool {
|
||||||
for (auto& c : CI->Clients) {
|
if (ClientPtr.expired())
|
||||||
if (c == nullptr)
|
return true;
|
||||||
continue;
|
auto Client = ClientPtr.lock();
|
||||||
lua_pushinteger(L, c->GetID());
|
lua_pushinteger(L, Client->GetID());
|
||||||
lua_pushstring(L, c->GetName().c_str());
|
lua_pushstring(L, Client->GetName().c_str());
|
||||||
lua_settable(L, -3);
|
lua_settable(L, -3);
|
||||||
i++;
|
return true;
|
||||||
}
|
});
|
||||||
if (CI->Clients.empty())
|
if (Engine().Server().ClientCount() == 0)
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
int lua_GetCars(lua_State* L) {
|
int lua_GetCars(lua_State* L) {
|
||||||
if (lua_isnumber(L, 1)) {
|
if (lua_isnumber(L, 1)) {
|
||||||
int ID = int(lua_tonumber(L, 1));
|
int ID = int(lua_tonumber(L, 1));
|
||||||
Client* c = GetClient(ID);
|
auto MaybeClient = GetClient(Engine().Server(), ID);
|
||||||
if (c != nullptr) {
|
if (MaybeClient && !MaybeClient.value().expired()) {
|
||||||
|
auto Client = MaybeClient.value().lock();
|
||||||
int i = 1;
|
int i = 1;
|
||||||
for (auto& v : c->GetAllCars()) {
|
for (auto& v : Client->GetAllCars()) {
|
||||||
if (v != nullptr) {
|
if (v != nullptr) {
|
||||||
lua_pushinteger(L, v->ID);
|
lua_pushinteger(L, v->ID());
|
||||||
lua_pushstring(L, v->Data.substr(3).c_str());
|
lua_pushstring(L, v->Data().substr(3).c_str());
|
||||||
lua_settable(L, -3);
|
lua_settable(L, -3);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (c->GetAllCars().empty())
|
if (Client->GetAllCars().empty())
|
||||||
return 0;
|
return 0;
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
SendError(L, ("GetPlayerVehicles not enough arguments"));
|
SendError(Engine(), L, ("GetPlayerVehicles not enough arguments"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -337,19 +347,20 @@ int lua_dropPlayer(lua_State* L) {
|
|||||||
int Args = lua_gettop(L);
|
int Args = lua_gettop(L);
|
||||||
if (lua_isnumber(L, 1)) {
|
if (lua_isnumber(L, 1)) {
|
||||||
int ID = int(lua_tonumber(L, 1));
|
int ID = int(lua_tonumber(L, 1));
|
||||||
Client* c = GetClient(ID);
|
auto MaybeClient = GetClient(Engine().Server(), ID);
|
||||||
if (c == nullptr)
|
if (!MaybeClient || MaybeClient.value().expired())
|
||||||
return 0;
|
return 0;
|
||||||
std::string Reason;
|
std::string Reason;
|
||||||
if (Args > 1 && lua_isstring(L, 2)) {
|
if (Args > 1 && lua_isstring(L, 2)) {
|
||||||
Reason = std::string((" Reason : ")) + lua_tostring(L, 2);
|
Reason = std::string((" Reason : ")) + lua_tostring(L, 2);
|
||||||
}
|
}
|
||||||
|
auto c = MaybeClient.value().lock();
|
||||||
Respond(c, "C:Server:You have been Kicked from the server! " + Reason, true);
|
Respond(c, "C:Server:You have been Kicked from the server! " + Reason, true);
|
||||||
c->SetStatus(-2);
|
c->SetStatus(-2);
|
||||||
info(("Closing socket due to kick"));
|
info(("Closing socket due to kick"));
|
||||||
CloseSocketProper(c->GetTCPSock());
|
CloseSocketProper(c->GetTCPSock());
|
||||||
} else
|
} else
|
||||||
SendError(L, ("DropPlayer not enough arguments"));
|
SendError(Engine(), L, ("DropPlayer not enough arguments"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int lua_sendChat(lua_State* L) {
|
int lua_sendChat(lua_State* L) {
|
||||||
@ -360,42 +371,44 @@ int lua_sendChat(lua_State* L) {
|
|||||||
std::string Packet = "C:Server: " + std::string(lua_tostring(L, 2));
|
std::string Packet = "C:Server: " + std::string(lua_tostring(L, 2));
|
||||||
SendToAll(nullptr, Packet, true, true);
|
SendToAll(nullptr, Packet, true, true);
|
||||||
} else {
|
} else {
|
||||||
Client* c = GetClient(ID);
|
auto MaybeClient = GetClient(Engine().Server(), ID);
|
||||||
if (c != nullptr) {
|
if (MaybeClient && !MaybeClient.value().expired()) {
|
||||||
if (!c->isSynced)
|
auto c = MaybeClient.value().lock();
|
||||||
|
if (!c->IsSynced())
|
||||||
return 0;
|
return 0;
|
||||||
std::string Packet = "C:Server: " + std::string(lua_tostring(L, 2));
|
std::string Packet = "C:Server: " + std::string(lua_tostring(L, 2));
|
||||||
Respond(c, Packet, true);
|
Respond(c, Packet, true);
|
||||||
} else
|
} else
|
||||||
SendError(L, ("SendChatMessage invalid argument [1] invalid ID"));
|
SendError(Engine(), L, ("SendChatMessage invalid argument [1] invalid ID"));
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
SendError(L, ("SendChatMessage invalid argument [2] expected string"));
|
SendError(Engine(), L, ("SendChatMessage invalid argument [2] expected string"));
|
||||||
} else
|
} else
|
||||||
SendError(L, ("SendChatMessage invalid argument [1] expected number"));
|
SendError(Engine(), L, ("SendChatMessage invalid argument [1] expected number"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int lua_RemoveVehicle(lua_State* L) {
|
int lua_RemoveVehicle(lua_State* L) {
|
||||||
int Args = lua_gettop(L);
|
int Args = lua_gettop(L);
|
||||||
if (Args != 2) {
|
if (Args != 2) {
|
||||||
SendError(L, ("RemoveVehicle invalid argument count expected 2 got ") + std::to_string(Args));
|
SendError(Engine(), L, ("RemoveVehicle invalid argument count expected 2 got ") + std::to_string(Args));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((lua_isinteger(L, 1) || lua_isnumber(L, 1)) && (lua_isinteger(L, 2) || lua_isnumber(L, 2))) {
|
if ((lua_isinteger(L, 1) || lua_isnumber(L, 1)) && (lua_isinteger(L, 2) || lua_isnumber(L, 2))) {
|
||||||
int PID = int(lua_tointeger(L, 1));
|
int PID = int(lua_tointeger(L, 1));
|
||||||
int VID = int(lua_tointeger(L, 2));
|
int VID = int(lua_tointeger(L, 2));
|
||||||
Client* c = GetClient(PID);
|
auto MaybeClient = GetClient(Engine().Server(), PID);
|
||||||
if (c == nullptr) {
|
if (!MaybeClient || MaybeClient.value().expired()) {
|
||||||
SendError(L, ("RemoveVehicle invalid Player ID"));
|
SendError(Engine(), L, ("RemoveVehicle invalid Player ID"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
auto c = MaybeClient.value().lock();
|
||||||
if (!c->GetCarData(VID).empty()) {
|
if (!c->GetCarData(VID).empty()) {
|
||||||
std::string Destroy = "Od:" + std::to_string(PID) + "-" + std::to_string(VID);
|
std::string Destroy = "Od:" + std::to_string(PID) + "-" + std::to_string(VID);
|
||||||
SendToAll(nullptr, Destroy, true, true);
|
SendToAll(nullptr, Destroy, true, true);
|
||||||
c->DeleteCar(VID);
|
c->DeleteCar(VID);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
SendError(L, ("RemoveVehicle invalid argument expected number"));
|
SendError(Engine(), L, ("RemoveVehicle invalid argument expected number"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int lua_HWID(lua_State* L) {
|
int lua_HWID(lua_State* L) {
|
||||||
@ -405,19 +418,19 @@ int lua_HWID(lua_State* L) {
|
|||||||
int lua_RemoteEvent(lua_State* L) {
|
int lua_RemoteEvent(lua_State* L) {
|
||||||
int Args = lua_gettop(L);
|
int Args = lua_gettop(L);
|
||||||
if (Args != 3) {
|
if (Args != 3) {
|
||||||
SendError(L, ("TriggerClientEvent invalid argument count expected 3 got ") + std::to_string(Args));
|
SendError(Engine(), L, ("TriggerClientEvent invalid argument count expected 3 got ") + std::to_string(Args));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!lua_isnumber(L, 1)) {
|
if (!lua_isnumber(L, 1)) {
|
||||||
SendError(L, ("TriggerClientEvent invalid argument [1] expected number"));
|
SendError(Engine(), L, ("TriggerClientEvent invalid argument [1] expected number"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!lua_isstring(L, 2)) {
|
if (!lua_isstring(L, 2)) {
|
||||||
SendError(L, ("TriggerClientEvent invalid argument [2] expected string"));
|
SendError(Engine(), L, ("TriggerClientEvent invalid argument [2] expected string"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!lua_isstring(L, 3)) {
|
if (!lua_isstring(L, 3)) {
|
||||||
SendError(L, ("TriggerClientEvent invalid argument [3] expected string"));
|
SendError(Engine(), L, ("TriggerClientEvent invalid argument [3] expected string"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int ID = int(lua_tointeger(L, 1));
|
int ID = int(lua_tointeger(L, 1));
|
||||||
@ -425,11 +438,12 @@ int lua_RemoteEvent(lua_State* L) {
|
|||||||
if (ID == -1)
|
if (ID == -1)
|
||||||
SendToAll(nullptr, Packet, true, true);
|
SendToAll(nullptr, Packet, true, true);
|
||||||
else {
|
else {
|
||||||
Client* c = GetClient(ID);
|
auto MaybeClient = GetClient(Engine().Server(), ID);
|
||||||
if (c == nullptr) {
|
if (!MaybeClient || MaybeClient.value().expired()) {
|
||||||
SendError(L, ("TriggerClientEvent invalid Player ID"));
|
SendError(Engine(), L, ("TriggerClientEvent invalid Player ID"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
auto c = MaybeClient.value().lock();
|
||||||
Respond(c, Packet, true);
|
Respond(c, Packet, true);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -445,14 +459,14 @@ int lua_ServerExit(lua_State* L) {
|
|||||||
int lua_Set(lua_State* L) {
|
int lua_Set(lua_State* L) {
|
||||||
int Args = lua_gettop(L);
|
int Args = lua_gettop(L);
|
||||||
if (Args != 2) {
|
if (Args != 2) {
|
||||||
SendError(L, ("set invalid argument count expected 2 got ") + std::to_string(Args));
|
SendError(Engine(), L, ("set invalid argument count expected 2 got ") + std::to_string(Args));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!lua_isnumber(L, 1)) {
|
if (!lua_isnumber(L, 1)) {
|
||||||
SendError(L, ("set invalid argument [1] expected number"));
|
SendError(Engine(), L, ("set invalid argument [1] expected number"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
auto MaybeSrc = GetScript(L);
|
auto MaybeSrc = Engine().GetScript(L);
|
||||||
std::string Name;
|
std::string Name;
|
||||||
if (!MaybeSrc.has_value()) {
|
if (!MaybeSrc.has_value()) {
|
||||||
Name = ("_Console");
|
Name = ("_Console");
|
||||||
@ -463,52 +477,52 @@ int lua_Set(lua_State* L) {
|
|||||||
switch (C) {
|
switch (C) {
|
||||||
case 0: //debug
|
case 0: //debug
|
||||||
if (lua_isboolean(L, 2)) {
|
if (lua_isboolean(L, 2)) {
|
||||||
Debug = lua_toboolean(L, 2);
|
Application::Settings.DebugModeEnabled = lua_toboolean(L, 2);
|
||||||
info(Name + (" | Debug -> ") + (Debug ? "true" : "false"));
|
info(Name + (" | Debug -> ") + (Application::Settings.DebugModeEnabled ? "true" : "false"));
|
||||||
} else
|
} else
|
||||||
SendError(L, ("set invalid argument [2] expected boolean for ID : 0"));
|
SendError(Engine(), L, ("set invalid argument [2] expected boolean for ID : 0"));
|
||||||
break;
|
break;
|
||||||
case 1: //private
|
case 1: //private
|
||||||
if (lua_isboolean(L, 2)) {
|
if (lua_isboolean(L, 2)) {
|
||||||
Private = lua_toboolean(L, 2);
|
Application::Settings.Private = lua_toboolean(L, 2);
|
||||||
info(Name + (" | Private -> ") + (Private ? "true" : "false"));
|
info(Name + (" | Private -> ") + (Application::Settings.Private ? "true" : "false"));
|
||||||
} else
|
} else
|
||||||
SendError(L, ("set invalid argument [2] expected boolean for ID : 1"));
|
SendError(Engine(), L, ("set invalid argument [2] expected boolean for ID : 1"));
|
||||||
break;
|
break;
|
||||||
case 2: //max cars
|
case 2: //max cars
|
||||||
if (lua_isnumber(L, 2)) {
|
if (lua_isnumber(L, 2)) {
|
||||||
MaxCars = int(lua_tointeger(L, 2));
|
Application::Settings.MaxCars = int(lua_tointeger(L, 2));
|
||||||
info(Name + (" | MaxCars -> ") + std::to_string(MaxCars));
|
info(Name + (" | MaxCars -> ") + std::to_string(Application::Settings.MaxCars));
|
||||||
} else
|
} else
|
||||||
SendError(L, ("set invalid argument [2] expected number for ID : 2"));
|
SendError(Engine(), L, ("set invalid argument [2] expected number for ID : 2"));
|
||||||
break;
|
break;
|
||||||
case 3: //max players
|
case 3: //max players
|
||||||
if (lua_isnumber(L, 2)) {
|
if (lua_isnumber(L, 2)) {
|
||||||
MaxPlayers = int(lua_tointeger(L, 2));
|
Application::Settings.MaxPlayers = int(lua_tointeger(L, 2));
|
||||||
info(Name + (" | MaxPlayers -> ") + std::to_string(MaxPlayers));
|
info(Name + (" | MaxPlayers -> ") + std::to_string(Application::Settings.MaxPlayers));
|
||||||
} else
|
} else
|
||||||
SendError(L, ("set invalid argument [2] expected number for ID : 3"));
|
SendError(Engine(), L, ("set invalid argument [2] expected number for ID : 3"));
|
||||||
break;
|
break;
|
||||||
case 4: //Map
|
case 4: //Map
|
||||||
if (lua_isstring(L, 2)) {
|
if (lua_isstring(L, 2)) {
|
||||||
MapName = lua_tostring(L, 2);
|
Application::Settings.MapName = lua_tostring(L, 2);
|
||||||
info(Name + (" | MapName -> ") + MapName);
|
info(Name + (" | MapName -> ") + Application::Settings.MapName);
|
||||||
} else
|
} else
|
||||||
SendError(L, ("set invalid argument [2] expected string for ID : 4"));
|
SendError(Engine(), L, ("set invalid argument [2] expected string for ID : 4"));
|
||||||
break;
|
break;
|
||||||
case 5: //Name
|
case 5: //Name
|
||||||
if (lua_isstring(L, 2)) {
|
if (lua_isstring(L, 2)) {
|
||||||
ServerName = lua_tostring(L, 2);
|
Application::Settings.ServerName = lua_tostring(L, 2);
|
||||||
info(Name + (" | ServerName -> ") + ServerName);
|
info(Name + (" | ServerName -> ") + Application::Settings.ServerName);
|
||||||
} else
|
} else
|
||||||
SendError(L, ("set invalid argument [2] expected string for ID : 5"));
|
SendError(Engine(), L, ("set invalid argument [2] expected string for ID : 5"));
|
||||||
break;
|
break;
|
||||||
case 6: //Desc
|
case 6: //Desc
|
||||||
if (lua_isstring(L, 2)) {
|
if (lua_isstring(L, 2)) {
|
||||||
ServerDesc = lua_tostring(L, 2);
|
Application::Settings.ServerDesc = lua_tostring(L, 2);
|
||||||
info(Name + (" | ServerDesc -> ") + ServerDesc);
|
info(Name + (" | ServerDesc -> ") + Application::Settings.ServerDesc);
|
||||||
} else
|
} else
|
||||||
SendError(L, ("set invalid argument [2] expected string for ID : 6"));
|
SendError(Engine(), L, ("set invalid argument [2] expected string for ID : 6"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
warn(("Invalid config ID : ") + std::to_string(C));
|
warn(("Invalid config ID : ") + std::to_string(C));
|
||||||
@ -523,9 +537,9 @@ int lua_Print(lua_State* L) {
|
|||||||
for (int i = 1; i <= Arg; i++) {
|
for (int i = 1; i <= Arg; i++) {
|
||||||
auto str = lua_tostring(L, i);
|
auto str = lua_tostring(L, i);
|
||||||
if (str != nullptr) {
|
if (str != nullptr) {
|
||||||
ConsoleOut(str + std::string(("\n")));
|
luaprint(str + std::string(("\n")));
|
||||||
} else {
|
} else {
|
||||||
ConsoleOut(("nil\n"));
|
luaprint("nil\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -533,9 +547,13 @@ int lua_Print(lua_State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TLuaFile::TLuaFile(TLuaEngine& Engine, const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote, bool Console)
|
TLuaFile::TLuaFile(TLuaEngine& Engine, const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote, bool Console)
|
||||||
: _Engine(Engine)
|
: mEngine(Engine)
|
||||||
, luaState(luaL_newstate()) {
|
, mLuaState(luaL_newstate()) {
|
||||||
Assert(luaState);
|
// set global engine for lua_* functions
|
||||||
|
if (!TheEngine) {
|
||||||
|
TheEngine = &mEngine;
|
||||||
|
}
|
||||||
|
Assert(mLuaState);
|
||||||
if (!PluginName.empty()) {
|
if (!PluginName.empty()) {
|
||||||
SetPluginName(PluginName);
|
SetPluginName(PluginName);
|
||||||
}
|
}
|
||||||
@ -543,22 +561,22 @@ TLuaFile::TLuaFile(TLuaEngine& Engine, const std::string& PluginName, const std:
|
|||||||
SetFileName(FileName);
|
SetFileName(FileName);
|
||||||
}
|
}
|
||||||
SetLastWrite(LastWrote);
|
SetLastWrite(LastWrote);
|
||||||
_Console = Console;
|
mConsole = Console;
|
||||||
}
|
}
|
||||||
|
|
||||||
TLuaFile::TLuaFile(TLuaEngine& Engine, bool Console)
|
TLuaFile::TLuaFile(TLuaEngine& Engine, bool Console)
|
||||||
: _Engine(Engine)
|
: mEngine(Engine)
|
||||||
, luaState(luaL_newstate()) {
|
, mLuaState(luaL_newstate()) {
|
||||||
_Console = Console;
|
mConsole = Console;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TLuaFile::Execute(const std::string& Command) {
|
void TLuaFile::Execute(const std::string& Command) {
|
||||||
if (ConsoleCheck(luaState, luaL_dostring(luaState, Command.c_str()))) {
|
if (ConsoleCheck(mLuaState, luaL_dostring(mLuaState, Command.c_str()))) {
|
||||||
lua_settop(luaState, 0);
|
lua_settop(mLuaState, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void TLuaFile::Reload() {
|
void TLuaFile::Reload() {
|
||||||
if (CheckLua(luaState, luaL_dofile(luaState, _FileName.c_str()))) {
|
if (CheckLua(mLuaState, luaL_dofile(mLuaState, mFileName.c_str()))) {
|
||||||
CallFunction(this, ("onInit"), nullptr);
|
CallFunction(this, ("onInit"), nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -588,104 +606,105 @@ std::any CallFunction(TLuaFile* lua, const std::string& FuncName, std::shared_pt
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
void TLuaFile::SetPluginName(const std::string& Name) {
|
void TLuaFile::SetPluginName(const std::string& Name) {
|
||||||
_PluginName = Name;
|
mPluginName = Name;
|
||||||
}
|
}
|
||||||
void TLuaFile::SetFileName(const std::string& Name) {
|
void TLuaFile::SetFileName(const std::string& Name) {
|
||||||
_FileName = Name;
|
mFileName = Name;
|
||||||
}
|
}
|
||||||
int lua_TempFix(TLuaEngine& Engine, lua_State* L) {
|
int lua_TempFix(lua_State* L) {
|
||||||
if (lua_isnumber(L, 1)) {
|
if (lua_isnumber(L, 1)) {
|
||||||
int ID = int(lua_tonumber(L, 1));
|
int ID = int(lua_tonumber(L, 1));
|
||||||
Client* c = GetClient(ID);
|
auto MaybeClient = GetClient(Engine().Server(), ID);
|
||||||
if (c == nullptr)
|
if (!MaybeClient || MaybeClient.value().expired())
|
||||||
return 0;
|
return 0;
|
||||||
std::string Ret;
|
std::string Ret;
|
||||||
if (c->isGuest) {
|
auto c = MaybeClient.value().lock();
|
||||||
|
if (c->IsGuest()) {
|
||||||
Ret = "Guest-" + c->GetName();
|
Ret = "Guest-" + c->GetName();
|
||||||
} else
|
} else
|
||||||
Ret = c->GetName();
|
Ret = c->GetName();
|
||||||
lua_pushstring(L, Ret.c_str());
|
lua_pushstring(L, Ret.c_str());
|
||||||
} else
|
} else
|
||||||
SendError(Engine, L, "GetDID not enough arguments");
|
SendError(Engine(), L, "GetDID not enough arguments");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
void TLuaFile::Init() {
|
void TLuaFile::Init() {
|
||||||
Assert(luaState);
|
Assert(mLuaState);
|
||||||
luaL_openlibs(luaState);
|
luaL_openlibs(mLuaState);
|
||||||
lua_register(luaState, "TriggerGlobalEvent", lua_TriggerEventG);
|
lua_register(mLuaState, "TriggerGlobalEvent", lua_TriggerEventG);
|
||||||
lua_register(luaState, "TriggerLocalEvent", lua_TriggerEventL);
|
lua_register(mLuaState, "TriggerLocalEvent", lua_TriggerEventL);
|
||||||
lua_register(luaState, "TriggerClientEvent", lua_RemoteEvent);
|
lua_register(mLuaState, "TriggerClientEvent", lua_RemoteEvent);
|
||||||
lua_register(luaState, "GetPlayerCount", lua_GetPlayerCount);
|
lua_register(mLuaState, "GetPlayerCount", lua_GetPlayerCount);
|
||||||
lua_register(luaState, "isPlayerConnected", lua_isConnected);
|
lua_register(mLuaState, "isPlayerConnected", lua_isConnected);
|
||||||
lua_register(luaState, "RegisterEvent", lua_RegisterEvent);
|
lua_register(mLuaState, "RegisterEvent", lua_RegisterEvent);
|
||||||
lua_register(luaState, "GetPlayerName", lua_GetPlayerName);
|
lua_register(mLuaState, "GetPlayerName", lua_GetPlayerName);
|
||||||
lua_register(luaState, "RemoveVehicle", lua_RemoveVehicle);
|
lua_register(mLuaState, "RemoveVehicle", lua_RemoveVehicle);
|
||||||
lua_register(luaState, "GetPlayerDiscordID", lua_TempFix);
|
lua_register(mLuaState, "GetPlayerDiscordID", lua_TempFix);
|
||||||
lua_register(luaState, "CreateThread", lua_CreateThread);
|
lua_register(mLuaState, "CreateThread", lua_CreateThread);
|
||||||
lua_register(luaState, "GetPlayerVehicles", lua_GetCars);
|
lua_register(mLuaState, "GetPlayerVehicles", lua_GetCars);
|
||||||
lua_register(luaState, "SendChatMessage", lua_sendChat);
|
lua_register(mLuaState, "SendChatMessage", lua_sendChat);
|
||||||
lua_register(luaState, "GetPlayers", lua_GetAllPlayers);
|
lua_register(mLuaState, "GetPlayers", lua_GetAllPlayers);
|
||||||
lua_register(luaState, "GetPlayerGuest", lua_GetGuest);
|
lua_register(mLuaState, "GetPlayerGuest", lua_GetGuest);
|
||||||
lua_register(luaState, "StopThread", lua_StopThread);
|
lua_register(mLuaState, "StopThread", lua_StopThread);
|
||||||
lua_register(luaState, "DropPlayer", lua_dropPlayer);
|
lua_register(mLuaState, "DropPlayer", lua_dropPlayer);
|
||||||
lua_register(luaState, "GetPlayerHWID", lua_HWID);
|
lua_register(mLuaState, "GetPlayerHWID", lua_HWID);
|
||||||
lua_register(luaState, "exit", lua_ServerExit);
|
lua_register(mLuaState, "exit", lua_ServerExit);
|
||||||
lua_register(luaState, "Sleep", lua_Sleep);
|
lua_register(mLuaState, "Sleep", lua_Sleep);
|
||||||
lua_register(luaState, "print", lua_Print);
|
lua_register(mLuaState, "print", lua_Print);
|
||||||
lua_register(luaState, "Set", lua_Set);
|
lua_register(mLuaState, "Set", lua_Set);
|
||||||
if (!_Console)
|
if (!mConsole)
|
||||||
Reload();
|
Reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TLuaFile::RegisterEvent(const std::string& Event, const std::string& FunctionName) {
|
void TLuaFile::RegisterEvent(const std::string& Event, const std::string& FunctionName) {
|
||||||
_RegisteredEvents.insert(std::make_pair(Event, FunctionName));
|
mRegisteredEvents.insert(std::make_pair(Event, FunctionName));
|
||||||
}
|
}
|
||||||
void TLuaFile::UnRegisterEvent(const std::string& Event) {
|
void TLuaFile::UnRegisterEvent(const std::string& Event) {
|
||||||
for (const std::pair<std::string, std::string>& a : _RegisteredEvents) {
|
for (const std::pair<std::string, std::string>& a : mRegisteredEvents) {
|
||||||
if (a.first == Event) {
|
if (a.first == Event) {
|
||||||
_RegisteredEvents.erase(a);
|
mRegisteredEvents.erase(a);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool TLuaFile::IsRegistered(const std::string& Event) {
|
bool TLuaFile::IsRegistered(const std::string& Event) {
|
||||||
for (const std::pair<std::string, std::string>& a : _RegisteredEvents) {
|
for (const std::pair<std::string, std::string>& a : mRegisteredEvents) {
|
||||||
if (a.first == Event)
|
if (a.first == Event)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string TLuaFile::GetRegistered(const std::string& Event) const {
|
std::string TLuaFile::GetRegistered(const std::string& Event) const {
|
||||||
for (const std::pair<std::string, std::string>& a : _RegisteredEvents) {
|
for (const std::pair<std::string, std::string>& a : mRegisteredEvents) {
|
||||||
if (a.first == Event)
|
if (a.first == Event)
|
||||||
return a.second;
|
return a.second;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
std::string TLuaFile::GetFileName() const {
|
std::string TLuaFile::GetFileName() const {
|
||||||
return _FileName;
|
return mFileName;
|
||||||
}
|
}
|
||||||
std::string TLuaFile::GetPluginName() const {
|
std::string TLuaFile::GetPluginName() const {
|
||||||
return _PluginName;
|
return mPluginName;
|
||||||
}
|
}
|
||||||
lua_State* TLuaFile::GetState() {
|
lua_State* TLuaFile::GetState() {
|
||||||
return luaState;
|
return mLuaState;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lua_State* TLuaFile::GetState() const {
|
const lua_State* TLuaFile::GetState() const {
|
||||||
return luaState;
|
return mLuaState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TLuaFile::SetLastWrite(fs::file_time_type time) {
|
void TLuaFile::SetLastWrite(fs::file_time_type time) {
|
||||||
_LastWrote = time;
|
mLastWrote = time;
|
||||||
}
|
}
|
||||||
fs::file_time_type TLuaFile::GetLastWrite() {
|
fs::file_time_type TLuaFile::GetLastWrite() {
|
||||||
return _LastWrote;
|
return mLastWrote;
|
||||||
}
|
}
|
||||||
|
|
||||||
TLuaFile::~TLuaFile() {
|
TLuaFile::~TLuaFile() {
|
||||||
info("closing lua state");
|
info("closing lua state");
|
||||||
lua_close(luaState);
|
lua_close(mLuaState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendError(TLuaEngine& Engine, lua_State* L, const std::string& msg) {
|
void SendError(TLuaEngine& Engine, lua_State* L, const std::string& msg) {
|
||||||
|
@ -22,21 +22,21 @@ void TServer::RemoveClient(std::weak_ptr<TClient> WeakClientPtr) {
|
|||||||
TClient& Client = *WeakClientPtr.lock();
|
TClient& Client = *WeakClientPtr.lock();
|
||||||
debug("removing client " + Client.GetName() + " (" + std::to_string(ClientCount()) + ")");
|
debug("removing client " + Client.GetName() + " (" + std::to_string(ClientCount()) + ")");
|
||||||
Client.ClearCars();
|
Client.ClearCars();
|
||||||
WriteLock Lock(_ClientsMutex);
|
WriteLock Lock(mClientsMutex);
|
||||||
_Clients.erase(WeakClientPtr.lock());
|
mClients.erase(WeakClientPtr.lock());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::weak_ptr<TClient> TServer::InsertNewClient() {
|
std::weak_ptr<TClient> TServer::InsertNewClient() {
|
||||||
debug("inserting new client (" + std::to_string(ClientCount()) + ")");
|
debug("inserting new client (" + std::to_string(ClientCount()) + ")");
|
||||||
WriteLock Lock(_ClientsMutex);
|
WriteLock Lock(mClientsMutex);
|
||||||
auto [Iter, Replaced] = _Clients.insert(std::make_shared<TClient>());
|
auto [Iter, Replaced] = mClients.insert(std::make_shared<TClient>());
|
||||||
return *Iter;
|
return *Iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TServer::ForEachClient(std::function<bool(std::weak_ptr<TClient>)> Fn) {
|
void TServer::ForEachClient(const std::function<bool(std::weak_ptr<TClient>)>& Fn) {
|
||||||
ReadLock Lock(_ClientsMutex);
|
ReadLock Lock(mClientsMutex);
|
||||||
for (auto& Client : _Clients) {
|
for (auto& Client : mClients) {
|
||||||
if (!Fn(Client)) {
|
if (!Fn(Client)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -44,6 +44,6 @@ void TServer::ForEachClient(std::function<bool(std::weak_ptr<TClient>)> Fn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t TServer::ClientCount() const {
|
size_t TServer::ClientCount() const {
|
||||||
ReadLock Lock(_ClientsMutex);
|
ReadLock Lock(mClientsMutex);
|
||||||
return _Clients.size();
|
return mClients.size();
|
||||||
}
|
}
|
||||||
|
21
src/main.cpp
21
src/main.cpp
@ -3,6 +3,7 @@
|
|||||||
#include "IThreaded.h"
|
#include "IThreaded.h"
|
||||||
#include "TConfig.h"
|
#include "TConfig.h"
|
||||||
#include "TConsole.h"
|
#include "TConsole.h"
|
||||||
|
#include "TLuaEngine.h"
|
||||||
#include "TServer.h"
|
#include "TServer.h"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@ -25,13 +26,16 @@ void UnixSignalHandler(int sig) {
|
|||||||
info("gracefully shutting down via SIGINT");
|
info("gracefully shutting down via SIGINT");
|
||||||
Application::GracefullyShutdown();
|
Application::GracefullyShutdown();
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
debug("unhandled signal: " + std::to_string(sig));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // __unix
|
#endif // __unix
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
#ifdef __unix
|
#ifdef __unix
|
||||||
info("registering SIGPIPE and SIGTERM handlers");
|
info("registering handlers for SIGINT, SIGTERM, SIGPIPE");
|
||||||
signal(SIGPIPE, UnixSignalHandler);
|
signal(SIGPIPE, UnixSignalHandler);
|
||||||
signal(SIGTERM, UnixSignalHandler);
|
signal(SIGTERM, UnixSignalHandler);
|
||||||
signal(SIGINT, UnixSignalHandler);
|
signal(SIGINT, UnixSignalHandler);
|
||||||
@ -39,20 +43,9 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
TServer Server(argc, argv);
|
TServer Server(argc, argv);
|
||||||
TConfig Config("Server.cfg");
|
TConfig Config("Server.cfg");
|
||||||
|
TLuaEngine LuaEngine(Server);
|
||||||
|
|
||||||
auto Client = Server.InsertNewClient();
|
// TODO: replace
|
||||||
if (!Client.expired()) {
|
|
||||||
Client.lock()->SetName("Lion");
|
|
||||||
} else {
|
|
||||||
error("fuckj");
|
|
||||||
_Exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Server.ForEachClient([](auto client) -> bool { debug(client.lock()->GetName()); return true; });
|
|
||||||
|
|
||||||
Server.RemoveClient(Client);
|
|
||||||
|
|
||||||
// TODO: replace with blocking heartbeat
|
|
||||||
bool Shutdown = false;
|
bool Shutdown = false;
|
||||||
Application::RegisterShutdownHandler([&Shutdown] { Shutdown = true; });
|
Application::RegisterShutdownHandler([&Shutdown] { Shutdown = true; });
|
||||||
while (!Shutdown) {
|
while (!Shutdown) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user