mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2025-07-03 16:25:35 +00:00
Begin Lua Rewrite
The idea is to move everything to TLuaEngine.
This commit is contained in:
parent
1228c2fabe
commit
3805d7ce6c
12
.gitignore
vendored
12
.gitignore
vendored
@ -468,3 +468,15 @@ cmake-build-debug/include/commandline/Makefile
|
||||
*.manifest
|
||||
*.rc
|
||||
*.res
|
||||
changelog-2.0.txt
|
||||
compile_commands.json
|
||||
err.html
|
||||
file.c
|
||||
log.txt
|
||||
nohup.out
|
||||
notes/
|
||||
patch.patch
|
||||
new-backend.txt
|
||||
sanitizer.txt
|
||||
speedcc.fit
|
||||
socket.txt
|
||||
|
@ -9,30 +9,42 @@
|
||||
#include <optional>
|
||||
#include <set>
|
||||
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
struct TLuaArgs final {
|
||||
std::vector<std::any> Args;
|
||||
};
|
||||
|
||||
class TLuaEngine : public IThreaded {
|
||||
public:
|
||||
explicit TLuaEngine(TServer& Server, TNetwork& Network);
|
||||
|
||||
using TSetOfLuaFile = std::set<std::unique_ptr<TLuaFile>>;
|
||||
using TSetOfLuaFile = std::vector<std::shared_ptr<TLuaFile>>;
|
||||
|
||||
void operator()() override;
|
||||
|
||||
[[nodiscard]] const TSetOfLuaFile& LuaFiles() const { return mLuaFiles; }
|
||||
std::any TriggerLuaEvent(const std::string& Event, bool local, std::weak_ptr<TLuaFile> Caller, std::shared_ptr<TLuaArgs> arg, bool Wait);
|
||||
|
||||
[[nodiscard]] TServer& Server() { return mServer; }
|
||||
[[nodiscard]] const TServer& Server() const { return mServer; }
|
||||
[[nodiscard]] TNetwork& Network() { return mNetwork; }
|
||||
[[nodiscard]] const TNetwork& Network() const { return mNetwork; }
|
||||
|
||||
std::optional<std::reference_wrapper<TLuaFile>> GetScript(lua_State* L);
|
||||
void UnregisterScript(std::shared_ptr<TLuaFile> Script);
|
||||
std::shared_ptr<TLuaFile> GetLuaFileOfScript(lua_State* L);
|
||||
std::shared_ptr<TLuaFile> InsertNewLuaFile(const fs::path& FileName, const std::string& PluginName);
|
||||
void SendError(lua_State* L, const std::string& msg);
|
||||
|
||||
private:
|
||||
void FolderList(const std::string& Path, bool HotSwap);
|
||||
void RegisterFiles(const std::string& Path, bool HotSwap);
|
||||
bool NewFile(const std::string& Path);
|
||||
void RegisterFiles(const fs::path& Path, bool HotSwap);
|
||||
bool IsNewFile(const std::string& Path);
|
||||
|
||||
TNetwork& mNetwork;
|
||||
TServer& mServer;
|
||||
std::string mPath;
|
||||
bool mShutdown { false };
|
||||
mutable std::mutex mLuaFilesMutex;
|
||||
TSetOfLuaFile mLuaFiles;
|
||||
};
|
||||
|
7
include/TLuaEvent.h
Normal file
7
include/TLuaEvent.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
class TLuaEvent final {
|
||||
};
|
@ -11,15 +11,14 @@
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
struct TLuaArg {
|
||||
std::vector<std::any> args;
|
||||
void PushArgs(lua_State* State);
|
||||
};
|
||||
|
||||
class TLuaEngine;
|
||||
class TLuaArgs;
|
||||
|
||||
class TLuaFile {
|
||||
public:
|
||||
explicit TLuaFile(TLuaEngine& Engine, bool Console = false);
|
||||
~TLuaFile();
|
||||
|
||||
void RegisterEvent(const std::string& Event, const std::string& FunctionName);
|
||||
void UnRegisterEvent(const std::string& Event);
|
||||
void SetLastWrite(fs::file_time_type time);
|
||||
@ -30,11 +29,8 @@ public:
|
||||
fs::file_time_type GetLastWrite();
|
||||
lua_State* GetState();
|
||||
std::string GetOrigin();
|
||||
std::mutex Lock;
|
||||
void Reload();
|
||||
void Init(const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote);
|
||||
explicit TLuaFile(TLuaEngine& Engine, bool Console = false);
|
||||
~TLuaFile();
|
||||
void SetStopThread(bool StopThread) { mStopThread = StopThread; }
|
||||
TLuaEngine& Engine() { return mEngine; }
|
||||
[[nodiscard]] std::string GetPluginName() const;
|
||||
@ -43,8 +39,14 @@ public:
|
||||
[[nodiscard]] bool GetStopThread() const { return mStopThread; }
|
||||
[[nodiscard]] const TLuaEngine& Engine() const { return mEngine; }
|
||||
[[nodiscard]] std::string GetRegistered(const std::string& Event) const;
|
||||
void PushArgs(const TLuaArgs& args);
|
||||
|
||||
bool operator==(const TLuaFile& Other) const;
|
||||
|
||||
void Load();
|
||||
|
||||
private:
|
||||
std::mutex Lock;
|
||||
TLuaEngine& mEngine;
|
||||
std::set<std::pair<std::string, std::string>> mRegisteredEvents;
|
||||
lua_State* mLuaState { nullptr };
|
||||
@ -53,9 +55,6 @@ private:
|
||||
std::string mFileName {};
|
||||
bool mStopThread = false;
|
||||
bool mConsole = false;
|
||||
void Load();
|
||||
};
|
||||
|
||||
std::any TriggerLuaEvent(const std::string& Event, bool local, TLuaFile* Caller, std::shared_ptr<TLuaArg> arg, bool Wait);
|
||||
|
||||
#endif // TLUAFILE_H
|
||||
|
@ -1,18 +1,16 @@
|
||||
#include "TLuaEngine.h"
|
||||
#include "Client.h"
|
||||
#include "CustomAssert.h"
|
||||
#include "TLuaFile.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <sys/stat.h>
|
||||
#include <lua.hpp>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
// necessary as lua relies on global state
|
||||
TLuaEngine* TheEngine;
|
||||
extern TLuaEngine* TheLuaEngine;
|
||||
|
||||
TLuaEngine::TLuaEngine(TServer& Server, TNetwork& Network)
|
||||
: mNetwork(Network)
|
||||
, mServer(Server) {
|
||||
TheEngine = this;
|
||||
TheLuaEngine = this;
|
||||
if (!fs::exists(Application::Settings.Resource)) {
|
||||
fs::create_directory(Application::Settings.Resource);
|
||||
}
|
||||
@ -31,16 +29,27 @@ TLuaEngine::TLuaEngine(TServer& Server, TNetwork& Network)
|
||||
Start();
|
||||
}
|
||||
|
||||
void TLuaEngine::UnregisterScript(std::shared_ptr<TLuaFile> Script) {
|
||||
std::unique_lock Lock(mLuaFilesMutex);
|
||||
auto Iter = std::find_if(mLuaFiles.begin(), mLuaFiles.end(), [&](const auto& ScriptPtr) {
|
||||
return *Script == *ScriptPtr;
|
||||
});
|
||||
if (Iter != mLuaFiles.end()) {
|
||||
// found!
|
||||
mLuaFiles.erase(Iter);
|
||||
}
|
||||
}
|
||||
|
||||
void TLuaEngine::operator()() {
|
||||
RegisterThread("LuaEngine");
|
||||
info("Lua system online");
|
||||
while (!mShutdown) {
|
||||
if (!mLuaFiles.empty()) {
|
||||
for (auto& Script : mLuaFiles) {
|
||||
struct stat Info { };
|
||||
if (stat(Script->GetFileName().c_str(), &Info) != 0) {
|
||||
const auto& filename = Script->GetFileName();
|
||||
if (!fs::is_regular_file(filename)) {
|
||||
Script->SetStopThread(true);
|
||||
mLuaFiles.erase(Script);
|
||||
UnregisterScript(Script);
|
||||
info(("[HOTSWAP] Removed removed script due to delete"));
|
||||
break;
|
||||
}
|
||||
@ -57,47 +66,178 @@ void TLuaEngine::operator()() {
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<std::reference_wrapper<TLuaFile>> TLuaEngine::GetScript(lua_State* L) {
|
||||
std::any TLuaEngine::TriggerLuaEvent(const std::string& Event, bool local, std::weak_ptr<TLuaFile> Caller, std::shared_ptr<TLuaArgs> arg, bool Wait) {
|
||||
std::any R;
|
||||
std::string Type;
|
||||
int Ret = 0;
|
||||
// TODO: lock
|
||||
for (auto& Script : mLuaFiles) {
|
||||
if (Script->IsRegistered(Event)) {
|
||||
if (local) {
|
||||
if (Script->GetPluginName() == Caller->GetPluginName()) {
|
||||
R = FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait);
|
||||
Type = R.type().name();
|
||||
if (Type.find("int") != std::string::npos) {
|
||||
if (std::any_cast<int>(R))
|
||||
Ret++;
|
||||
} else if (Event == "onPlayerAuth")
|
||||
return R;
|
||||
}
|
||||
} else {
|
||||
R = FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait);
|
||||
Type = R.type().name();
|
||||
if (Type.find("int") != std::string::npos) {
|
||||
if (std::any_cast<int>(R))
|
||||
Ret++;
|
||||
} else if (Event == "onPlayerAuth")
|
||||
return R;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
std::shared_ptr<TLuaFile> TLuaEngine::GetLuaFileOfScript(lua_State* L) {
|
||||
std::unique_lock Lock(mLuaFilesMutex);
|
||||
for (auto& Script : mLuaFiles) {
|
||||
if (Script->GetState() == L)
|
||||
return *Script;
|
||||
return Script;
|
||||
}
|
||||
return std::nullopt;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TLuaEngine::FolderList(const std::string& Path, bool HotSwap) {
|
||||
for (const auto& entry : fs::directory_iterator(Path)) {
|
||||
auto pos = entry.path().filename().string().find('.');
|
||||
if (pos == std::string::npos) {
|
||||
RegisterFiles(entry.path().string(), HotSwap);
|
||||
if (fs::is_directory(entry)) {
|
||||
RegisterFiles(entry.path(), HotSwap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TLuaEngine::RegisterFiles(const std::string& Path, bool HotSwap) {
|
||||
std::string Name = Path.substr(Path.find_last_of('\\') + 1);
|
||||
if (!HotSwap)
|
||||
void TLuaEngine::RegisterFiles(const fs::path& Path, bool HotSwap) {
|
||||
std::string Name = Path.filename();
|
||||
if (!HotSwap) {
|
||||
info(("Loading plugin : ") + Name);
|
||||
}
|
||||
for (const auto& entry : fs::directory_iterator(Path)) {
|
||||
auto pos = entry.path().string().find((".lua"));
|
||||
if (pos != std::string::npos && entry.path().string().length() - pos == 4) {
|
||||
if (!HotSwap || NewFile(entry.path().string())) {
|
||||
auto FileName = entry.path().string();
|
||||
std::unique_ptr<TLuaFile> ScriptToInsert(new TLuaFile(*this));
|
||||
auto& Script = *ScriptToInsert;
|
||||
mLuaFiles.insert(std::move(ScriptToInsert));
|
||||
Script.Init(Name, FileName, fs::last_write_time(FileName));
|
||||
if (HotSwap)
|
||||
info(("[HOTSWAP] Added : ") + Script.GetFileName().substr(Script.GetFileName().find('\\')));
|
||||
if (entry.is_regular_file() && entry.path().extension() == ".lua") {
|
||||
if (!HotSwap || IsNewFile(entry.path().string())) {
|
||||
InsertNewLuaFile(entry.path(), Path.filename());
|
||||
if (HotSwap) {
|
||||
info(("[HOTSWAP] Added : ") + entry.path().filename().string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TLuaEngine::NewFile(const std::string& Path) {
|
||||
bool TLuaEngine::IsNewFile(const std::string& Path) {
|
||||
std::unique_lock Lock(mLuaFilesMutex);
|
||||
for (auto& Script : mLuaFiles) {
|
||||
// TODO: use std::any_of
|
||||
if (Path == Script->GetFileName())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void TLuaEngine::SendError(lua_State* L, const std::string& msg) {
|
||||
Assert(L);
|
||||
auto MaybeS = GetLuaFileOfScript(L);
|
||||
std::string a;
|
||||
if (!MaybeS) {
|
||||
a = ("_Console");
|
||||
} else {
|
||||
// FIXME: GetFileName already returns the filename. This is redundant.
|
||||
a = fs::path(MaybeS->GetFileName()).filename().string();
|
||||
}
|
||||
warn(a + (" | Incorrect call of ") + msg);
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////
|
||||
// ////////// LUA *ONLY* BELOW //////////////////
|
||||
// //////////////////////////////////////////////
|
||||
|
||||
std::shared_ptr<TClient> GetClient(TServer& Server, int ID) {
|
||||
std::shared_ptr<TClient> MaybeClient = nullptr;
|
||||
Server.ForEachClient([&](std::weak_ptr<TClient> CPtr) -> bool {
|
||||
ReadLock Lock(Server.GetClientMutex());
|
||||
if (!CPtr.expired()) {
|
||||
auto C = CPtr.lock();
|
||||
if (C->GetID() == ID) {
|
||||
MaybeClient = C;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return MaybeClient;
|
||||
}
|
||||
|
||||
int ServerLua_GetIdentifiers(lua_State* L) {
|
||||
Assert(TheLuaEngine);
|
||||
Assert(L);
|
||||
if (lua_isnumber(L, 1)) {
|
||||
// do not store this
|
||||
// FIXME: should this not be lua_tointeger?!
|
||||
auto MaybeClient = GetClient(TheLuaEngine->Server(), int(lua_tonumber(L, 1)));
|
||||
if (MaybeClient) {
|
||||
auto IDs = MaybeClient->GetIdentifiers();
|
||||
if (IDs.empty())
|
||||
return 0;
|
||||
// FIXME: What does this entire thing do? Add comments.
|
||||
lua_newtable(L);
|
||||
for (const std::string& ID : IDs) {
|
||||
lua_pushstring(L, ID.substr(0, ID.find(':')).c_str());
|
||||
lua_pushstring(L, ID.c_str());
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
} else
|
||||
return 0;
|
||||
} else {
|
||||
SendError(*TheLuaEngine, L, "lua_GetIdentifiers wrong arguments");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// LEAVE THIS AT THE **VERY** BOTTOM OF THE FILE
|
||||
|
||||
std::shared_ptr<TLuaFile> TLuaEngine::InsertNewLuaFile(const fs::path& FileName, const std::string& PluginName) {
|
||||
std::shared_ptr<TLuaFile> Script(new TLuaFile(*this));
|
||||
mLuaFiles.push_back(Script);
|
||||
Script->SetPluginName(PluginName);
|
||||
Script->SetFileName(FileName);
|
||||
Script->SetLastWrite(fs::last_write_time(FileName));
|
||||
lua_State* State = Script->GetState();
|
||||
luaL_openlibs(State);
|
||||
lua_register(State, "GetPlayerIdentifiers", ServerLua_GetIdentifiers);
|
||||
lua_register(State, "TriggerGlobalEvent", lua_TriggerEventG);
|
||||
lua_register(State, "TriggerLocalEvent", lua_TriggerEventL);
|
||||
lua_register(State, "TriggerClientEvent", lua_RemoteEvent);
|
||||
lua_register(State, "GetPlayerCount", lua_GetPlayerCount);
|
||||
lua_register(State, "isPlayerConnected", lua_isConnected);
|
||||
lua_register(State, "RegisterEvent", lua_RegisterEvent);
|
||||
lua_register(State, "GetPlayerName", lua_GetPlayerName);
|
||||
lua_register(State, "RemoveVehicle", lua_RemoveVehicle);
|
||||
lua_register(State, "GetPlayerDiscordID", lua_TempFix);
|
||||
lua_register(State, "CreateThread", lua_CreateThread);
|
||||
lua_register(State, "GetPlayerVehicles", lua_GetCars);
|
||||
lua_register(State, "SendChatMessage", lua_sendChat);
|
||||
lua_register(State, "GetPlayers", lua_GetAllPlayers);
|
||||
lua_register(State, "GetPlayerGuest", lua_GetGuest);
|
||||
lua_register(State, "StopThread", lua_StopThread);
|
||||
lua_register(State, "DropPlayer", lua_dropPlayer);
|
||||
lua_register(State, "GetPlayerHWID", lua_HWID);
|
||||
lua_register(State, "exit", lua_ServerExit);
|
||||
lua_register(State, "Sleep", lua_Sleep);
|
||||
lua_register(State, "print", lua_Print);
|
||||
lua_register(State, "Set", lua_Set);
|
||||
if (!Script->IsConsole()) {
|
||||
Reload();
|
||||
}
|
||||
debug("inserted new lua file: " + PluginName + " - " + FileName.string());
|
||||
return Script;
|
||||
}
|
||||
|
2
src/TLuaEvent.cpp
Normal file
2
src/TLuaEvent.cpp
Normal file
@ -0,0 +1,2 @@
|
||||
#include "TLuaEvent.h"
|
||||
|
176
src/TLuaFile.cpp
176
src/TLuaFile.cpp
@ -12,41 +12,13 @@
|
||||
// TODO: REWRITE
|
||||
|
||||
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 TriggerLuaEvent(TLuaEngine& Engine, const std::string& Event, bool local, TLuaFile* Caller, std::shared_ptr<TLuaArg> arg, bool Wait);
|
||||
std::any CallFunction(TLuaFile* lua, const std::string& FuncName, std::shared_ptr<TLuaArgs> Arg);
|
||||
std::any TriggerLuaEvent(TLuaEngine& Engine, const std::string& Event, bool local, TLuaFile* Caller, std::shared_ptr<TLuaArgs> arg, bool Wait);
|
||||
|
||||
extern TLuaEngine* TheEngine;
|
||||
|
||||
static TLuaEngine& Engine() {
|
||||
Assert(TheEngine);
|
||||
return *TheEngine;
|
||||
}
|
||||
|
||||
std::shared_ptr<TLuaArg> CreateArg(lua_State* L, int T, int S) {
|
||||
if (S > T)
|
||||
return nullptr;
|
||||
std::shared_ptr<TLuaArg> temp(new TLuaArg);
|
||||
for (int C = S; 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;
|
||||
}
|
||||
void ClearStack(lua_State* L) {
|
||||
lua_settop(L, 0);
|
||||
}
|
||||
|
||||
std::any Trigger(TLuaFile* lua, const std::string& R, std::shared_ptr<TLuaArg> arg) {
|
||||
std::any Trigger(TLuaFile* lua, const std::string& R, std::shared_ptr<TLuaArgs> arg) {
|
||||
RegisterThread(lua->GetFileName());
|
||||
std::lock_guard<std::mutex> lockGuard(lua->Lock);
|
||||
std::packaged_task<std::any(std::shared_ptr<TLuaArg>)> task([lua, R](std::shared_ptr<TLuaArg> arg) { return CallFunction(lua, R, arg); });
|
||||
std::packaged_task<std::any(std::shared_ptr<TLuaArg>)> task([lua, R](std::shared_ptr<TLuaArgs> arg) { return CallFunction(lua, R, arg); });
|
||||
std::future<std::any> f1 = task.get_future();
|
||||
std::thread t(std::move(task), arg);
|
||||
t.detach();
|
||||
@ -56,9 +28,9 @@ std::any Trigger(TLuaFile* lua, const std::string& R, std::shared_ptr<TLuaArg> a
|
||||
SendError(lua->Engine(), lua->GetState(), R + " took too long to respond");
|
||||
return 0;
|
||||
}
|
||||
std::any FutureWait(TLuaFile* lua, const std::string& R, std::shared_ptr<TLuaArg> arg, bool Wait) {
|
||||
std::any FutureWait(TLuaFile* lua, const std::string& R, std::shared_ptr<TLuaArgs> arg, bool Wait) {
|
||||
Assert(lua);
|
||||
std::packaged_task<std::any(std::shared_ptr<TLuaArg>)> task([lua, R](std::shared_ptr<TLuaArg> arg) { return Trigger(lua, R, arg); });
|
||||
std::packaged_task<std::any(std::shared_ptr<TLuaArg>)> task([lua, R](std::shared_ptr<TLuaArgs> arg) { return Trigger(lua, R, arg); });
|
||||
std::future<std::any> f1 = task.get_future();
|
||||
std::thread t(std::move(task), arg);
|
||||
t.detach();
|
||||
@ -70,35 +42,6 @@ std::any FutureWait(TLuaFile* lua, const std::string& R, std::shared_ptr<TLuaArg
|
||||
return f1.get();
|
||||
return 0;
|
||||
}
|
||||
std::any TriggerLuaEvent(const std::string& Event, bool local, TLuaFile* Caller, std::shared_ptr<TLuaArg> arg, bool Wait) {
|
||||
std::any R;
|
||||
std::string Type;
|
||||
int Ret = 0;
|
||||
for (auto& Script : Engine().LuaFiles()) {
|
||||
if (Script->IsRegistered(Event)) {
|
||||
if (local) {
|
||||
if (Script->GetPluginName() == Caller->GetPluginName()) {
|
||||
R = FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait);
|
||||
Type = R.type().name();
|
||||
if (Type.find("int") != std::string::npos) {
|
||||
if (std::any_cast<int>(R))
|
||||
Ret++;
|
||||
} else if (Event == "onPlayerAuth")
|
||||
return R;
|
||||
}
|
||||
} else {
|
||||
R = FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait);
|
||||
Type = R.type().name();
|
||||
if (Type.find("int") != std::string::npos) {
|
||||
if (std::any_cast<int>(R))
|
||||
Ret++;
|
||||
} else if (Event == "onPlayerAuth")
|
||||
return R;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
bool ConsoleCheck(lua_State* L, int r) {
|
||||
if (r != LUA_OK) {
|
||||
std::string msg = lua_tostring(L, -1);
|
||||
@ -230,21 +173,7 @@ int lua_Sleep(lua_State* L) {
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
std::optional<std::weak_ptr<TClient>> GetClient(TServer& Server, int ID) {
|
||||
std::optional<std::weak_ptr<TClient>> MaybeClient { std::nullopt };
|
||||
Server.ForEachClient([&](std::weak_ptr<TClient> CPtr) -> bool {
|
||||
ReadLock Lock(Server.GetClientMutex());
|
||||
if (!CPtr.expired()) {
|
||||
auto C = CPtr.lock();
|
||||
if (C->GetID() == ID) {
|
||||
MaybeClient = CPtr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return MaybeClient;
|
||||
}
|
||||
|
||||
// CONTINUE
|
||||
int lua_isConnected(lua_State* L) {
|
||||
if (lua_isnumber(L, 1)) {
|
||||
@ -311,27 +240,6 @@ int lua_GetAllPlayers(lua_State* L) {
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
int lua_GetIdentifiers(lua_State* L) {
|
||||
if (lua_isnumber(L, 1)) {
|
||||
auto MaybeClient = GetClient(Engine().Server(), int(lua_tonumber(L, 1)));
|
||||
if (MaybeClient && !MaybeClient.value().expired()) {
|
||||
auto IDs = MaybeClient.value().lock()->GetIdentifiers();
|
||||
if (IDs.empty())
|
||||
return 0;
|
||||
lua_newtable(L);
|
||||
for (const std::string& ID : IDs) {
|
||||
lua_pushstring(L, ID.substr(0, ID.find(':')).c_str());
|
||||
lua_pushstring(L, ID.c_str());
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
} else
|
||||
return 0;
|
||||
} else {
|
||||
SendError(Engine(), L, "lua_GetIdentifiers wrong arguments");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lua_GetCars(lua_State* L) {
|
||||
if (lua_isnumber(L, 1)) {
|
||||
@ -590,19 +498,7 @@ int lua_Print(lua_State* L) {
|
||||
int lua_TempFix(lua_State* L);
|
||||
|
||||
void TLuaFile::Init(const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote) {
|
||||
// set global engine for lua_* functions
|
||||
if (!TheEngine) {
|
||||
TheEngine = &mEngine;
|
||||
}
|
||||
Assert(mLuaState);
|
||||
if (!PluginName.empty()) {
|
||||
SetPluginName(PluginName);
|
||||
}
|
||||
if (!FileName.empty()) {
|
||||
SetFileName(FileName);
|
||||
}
|
||||
SetLastWrite(LastWrote);
|
||||
Load();
|
||||
}
|
||||
|
||||
TLuaFile::TLuaFile(TLuaEngine& Engine, bool Console)
|
||||
@ -628,7 +524,7 @@ std::string TLuaFile::GetOrigin() {
|
||||
return fs::path(GetFileName()).filename().string();
|
||||
}
|
||||
|
||||
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<TLuaArgs> Arg) {
|
||||
RegisterThread(lua->GetFileName());
|
||||
lua_State* luaState = lua->GetState();
|
||||
lua_getglobal(luaState, FuncName.c_str());
|
||||
@ -660,32 +556,6 @@ void TLuaFile::SetFileName(const std::string& Name) {
|
||||
}
|
||||
|
||||
void TLuaFile::Load() {
|
||||
Assert(mLuaState);
|
||||
luaL_openlibs(mLuaState);
|
||||
lua_register(mLuaState, "GetPlayerIdentifiers", lua_GetIdentifiers);
|
||||
lua_register(mLuaState, "TriggerGlobalEvent", lua_TriggerEventG);
|
||||
lua_register(mLuaState, "TriggerLocalEvent", lua_TriggerEventL);
|
||||
lua_register(mLuaState, "TriggerClientEvent", lua_RemoteEvent);
|
||||
lua_register(mLuaState, "GetPlayerCount", lua_GetPlayerCount);
|
||||
lua_register(mLuaState, "isPlayerConnected", lua_isConnected);
|
||||
lua_register(mLuaState, "RegisterEvent", lua_RegisterEvent);
|
||||
lua_register(mLuaState, "GetPlayerName", lua_GetPlayerName);
|
||||
lua_register(mLuaState, "RemoveVehicle", lua_RemoveVehicle);
|
||||
lua_register(mLuaState, "GetPlayerDiscordID", lua_TempFix);
|
||||
lua_register(mLuaState, "CreateThread", lua_CreateThread);
|
||||
lua_register(mLuaState, "GetPlayerVehicles", lua_GetCars);
|
||||
lua_register(mLuaState, "SendChatMessage", lua_sendChat);
|
||||
lua_register(mLuaState, "GetPlayers", lua_GetAllPlayers);
|
||||
lua_register(mLuaState, "GetPlayerGuest", lua_GetGuest);
|
||||
lua_register(mLuaState, "StopThread", lua_StopThread);
|
||||
lua_register(mLuaState, "DropPlayer", lua_dropPlayer);
|
||||
lua_register(mLuaState, "GetPlayerHWID", lua_HWID);
|
||||
lua_register(mLuaState, "exit", lua_ServerExit);
|
||||
lua_register(mLuaState, "Sleep", lua_Sleep);
|
||||
lua_register(mLuaState, "print", lua_Print);
|
||||
lua_register(mLuaState, "Set", lua_Set);
|
||||
if (!mConsole)
|
||||
Reload();
|
||||
}
|
||||
|
||||
void TLuaFile::RegisterEvent(const std::string& Event, const std::string& FunctionName) {
|
||||
@ -713,6 +583,12 @@ std::string TLuaFile::GetRegistered(const std::string& Event) const {
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool TLuaFile::operator==(const TLuaFile& Other) const {
|
||||
return mPluginName == Other.mPluginName
|
||||
&& mFileName == Other.mFileName;
|
||||
}
|
||||
|
||||
std::string TLuaFile::GetFileName() const {
|
||||
return mFileName;
|
||||
}
|
||||
@ -739,18 +615,6 @@ TLuaFile::~TLuaFile() {
|
||||
lua_close(mLuaState);
|
||||
}
|
||||
|
||||
void SendError(TLuaEngine& Engine, lua_State* L, const std::string& msg) {
|
||||
Assert(L);
|
||||
auto MaybeS = Engine.GetScript(L);
|
||||
std::string a;
|
||||
if (!MaybeS.has_value()) {
|
||||
a = ("_Console");
|
||||
} else {
|
||||
TLuaFile& S = MaybeS.value();
|
||||
a = fs::path(S.GetFileName()).filename().string();
|
||||
}
|
||||
warn(a + (" | Incorrect Call of ") + msg);
|
||||
}
|
||||
int lua_TempFix(lua_State* L) {
|
||||
if (lua_isnumber(L, 1)) {
|
||||
int ID = int(lua_tonumber(L, 1));
|
||||
@ -769,22 +633,22 @@ int lua_TempFix(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void TLuaArg::PushArgs(lua_State* State) {
|
||||
for (std::any arg : args) {
|
||||
void TLuaFile::PushArgs(const TLuaArgs& args) {
|
||||
for (const std::any& arg : args.Args) {
|
||||
if (!arg.has_value())
|
||||
return;
|
||||
std::string Type = arg.type().name();
|
||||
if (Type.find("bool") != std::string::npos) {
|
||||
lua_pushboolean(State, std::any_cast<bool>(arg));
|
||||
lua_pushboolean(mLuaState, std::any_cast<bool>(arg));
|
||||
}
|
||||
if (Type.find("basic_string") != std::string::npos || Type.find("char") != std::string::npos) {
|
||||
lua_pushstring(State, std::any_cast<std::string>(arg).c_str());
|
||||
lua_pushstring(mLuaState, std::any_cast<std::string>(arg).c_str());
|
||||
}
|
||||
if (Type.find("int") != std::string::npos) {
|
||||
lua_pushinteger(State, std::any_cast<int>(arg));
|
||||
lua_pushinteger(mLuaState, std::any_cast<int>(arg));
|
||||
}
|
||||
if (Type.find("float") != std::string::npos) {
|
||||
lua_pushnumber(State, std::any_cast<float>(arg));
|
||||
lua_pushnumber(mLuaState, std::any_cast<float>(arg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "TServer.h"
|
||||
#include <thread>
|
||||
|
||||
TLuaEngine* TheLuaEngine = nullptr;
|
||||
|
||||
#ifdef __unix
|
||||
#include <csignal>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user