Fix various memory leaks with RAII

This commit is contained in:
Lion Kortlepel
2020-11-04 13:10:45 +01:00
parent 5452aeb558
commit f2d87078ae
4 changed files with 512 additions and 408 deletions
+44 -34
View File
@@ -3,33 +3,36 @@
/// ///
#pragma once #pragma once
#include "lua.hpp"
#include <any>
#include <filesystem> #include <filesystem>
#include <iostream> #include <iostream>
#include "lua.hpp"
#include <vector>
#include <thread>
#include <mutex> #include <mutex>
#include <memory>
#include <set> #include <set>
#include <any> #include <thread>
#include <vector>
namespace fs = std::filesystem; namespace fs = std::filesystem;
struct LuaArg{ struct LuaArg {
std::vector<std::any> args; std::vector<std::any> args;
void PushArgs(lua_State *State){ void PushArgs(lua_State* State) {
for(std::any arg : args){ for (std::any arg : args) {
if(!arg.has_value())return; if (!arg.has_value())
return;
std::string Type = arg.type().name(); std::string Type = arg.type().name();
if(Type.find("bool") != std::string::npos){ if (Type.find("bool") != std::string::npos) {
lua_pushboolean(State,std::any_cast<bool>(arg)); lua_pushboolean(State, std::any_cast<bool>(arg));
} }
if(Type.find("basic_string") != std::string::npos || Type.find("char") != std::string::npos){ 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(State, std::any_cast<std::string>(arg).c_str());
} }
if(Type.find("int") != std::string::npos){ if (Type.find("int") != std::string::npos) {
lua_pushinteger(State,std::any_cast<int>(arg)); lua_pushinteger(State, std::any_cast<int>(arg));
} }
if(Type.find("float") != std::string::npos){ lua_pushnumber(State,std::any_cast<float>(arg)); if (Type.find("float") != std::string::npos) {
lua_pushnumber(State, std::any_cast<float>(arg));
} }
} }
} }
@@ -37,32 +40,39 @@ struct LuaArg{
class Lua { class Lua {
private: private:
std::set<std::pair<std::string,std::string>> RegisteredEvents; std::set<std::pair<std::string, std::string>> _RegisteredEvents;
lua_State *luaState = luaL_newstate(); lua_State* luaState { nullptr };
fs::file_time_type LastWrote; fs::file_time_type _LastWrote;
std::string PluginName; std::string _PluginName;
std::string FileName; std::string _FileName;
bool _StopThread = false;
bool _Console = false;
// this is called by the ctor to ensure RAII
void Init();
public: public:
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); 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);
void SetPluginName(const std::string&Name); void SetPluginName(const std::string& Name);
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(); std::string GetPluginName() const;
std::string GetFileName(); std::string GetFileName() const;
bool StopThread = false;
bool Console = false;
lua_State* GetState(); lua_State* GetState();
const lua_State* GetState() const;
char* GetOrigin(); char* GetOrigin();
std::mutex Lock; std::mutex Lock;
void Reload(); void Reload();
void Init(); Lua(const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote, bool Console = false);
Lua(bool Console = false);
~Lua();
void SetStopThread(bool StopThread) { _StopThread = StopThread; }
bool GetStopThread() const { return _StopThread; }
}; };
int CallFunction(Lua*lua,const std::string& FuncName,LuaArg* args); int CallFunction(Lua* lua, const std::string& FuncName, LuaArg* args);
int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller,LuaArg* arg,bool Wait); int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, LuaArg* arg, bool Wait);
extern std::set<Lua*> PluginEngine; extern std::set<std::unique_ptr<Lua>> PluginEngine;
+1 -3
View File
@@ -130,9 +130,7 @@ void SetupConsole() {
} }
void ConsoleInit() { void ConsoleInit() {
SetupConsole(); SetupConsole();
LuaConsole = new Lua(); LuaConsole = new Lua(true);
LuaConsole->Console = true;
LuaConsole->Init();
printf("> "); printf("> ");
std::thread In(ReadCin); std::thread In(ReadCin);
In.detach(); In.detach();
+37 -39
View File
@@ -2,10 +2,10 @@
/// Created by Anonymous275 on 5/20/2020 /// Created by Anonymous275 on 5/20/2020
/// ///
#include "Logger.h"
#include "Lua/LuaSystem.hpp" #include "Lua/LuaSystem.hpp"
#include "Security/Enc.h" #include "Security/Enc.h"
#include "Settings.h" #include "Settings.h"
#include "Logger.h"
#include <thread> #include <thread>
#ifdef __linux #ifdef __linux
@@ -13,75 +13,73 @@
#include <sys/stat.h> #include <sys/stat.h>
#endif // __linux #endif // __linux
std::set<Lua*> PluginEngine; std::set<std::unique_ptr<Lua>> PluginEngine;
bool NewFile(const std::string&Path){ bool NewFile(const std::string& Path) {
for(Lua*Script : PluginEngine){ for (auto& Script : PluginEngine) {
if(Path == Script->GetFileName())return false; if (Path == Script->GetFileName())
return false;
} }
return true; return true;
} }
void RegisterFiles(const std::string& Path,bool HotSwap){ void RegisterFiles(const std::string& Path, bool HotSwap) {
std::string Name = Path.substr(Path.find_last_of('\\')+1); std::string Name = Path.substr(Path.find_last_of('\\') + 1);
if(!HotSwap)info(Sec("Loading plugin : ") + Name); if (!HotSwap)
for (const auto &entry : fs::directory_iterator(Path)){ info(Sec("Loading plugin : ") + Name);
for (const auto& entry : fs::directory_iterator(Path)) {
auto pos = entry.path().string().find(Sec(".lua")); auto pos = entry.path().string().find(Sec(".lua"));
if (pos != std::string::npos && entry.path().string().length() - pos == 4) { if (pos != std::string::npos && entry.path().string().length() - pos == 4) {
if(!HotSwap || NewFile(entry.path().string())){ if (!HotSwap || NewFile(entry.path().string())) {
Lua *Script = new Lua(); auto FileName = entry.path().string();
PluginEngine.insert(Script); std::unique_ptr<Lua> ScriptToInsert(new Lua(Name, FileName, fs::last_write_time(FileName)));
Script->SetFileName(entry.path().string()); auto& Script = *ScriptToInsert;
Script->SetPluginName(Name); PluginEngine.insert(std::move(ScriptToInsert));
Script->SetLastWrite(fs::last_write_time(Script->GetFileName())); if (HotSwap)
Script->Init(); info(Sec("[HOTSWAP] Added : ") + Script.GetFileName().substr(Script.GetFileName().find('\\')));
if(HotSwap)info(Sec("[HOTSWAP] Added : ") +
Script->GetFileName().substr(Script->GetFileName().find('\\')));
} }
} }
} }
} }
void FolderList(const std::string& Path,bool HotSwap){ void FolderList(const std::string& Path, bool HotSwap) {
for (const auto &entry : fs::directory_iterator(Path)) { for (const auto& entry : fs::directory_iterator(Path)) {
auto pos = entry.path().filename().string().find('.'); auto pos = entry.path().filename().string().find('.');
if (pos == std::string::npos) { if (pos == std::string::npos) {
RegisterFiles(entry.path().string(),HotSwap); RegisterFiles(entry.path().string(), HotSwap);
} }
} }
} }
[[noreturn]]void HotSwaps(const std::string& path){ [[noreturn]] void HotSwaps(const std::string& path) {
DebugPrintTID(); DebugPrintTID();
while(true){ while (true) {
for(Lua*Script : PluginEngine){ for (auto& Script : PluginEngine) {
struct stat Info{}; struct stat Info {};
if(stat(Script->GetFileName().c_str(), &Info) != 0){ if (stat(Script->GetFileName().c_str(), &Info) != 0) {
Script->StopThread = true; Script->SetStopThread(true);
PluginEngine.erase(Script); PluginEngine.erase(Script);
info(Sec("[HOTSWAP] Removed : ")+ info(Sec("[HOTSWAP] Removed : ") + Script->GetFileName().substr(Script->GetFileName().find('\\')));
Script->GetFileName().substr(Script->GetFileName().find('\\')));
break; break;
} }
if(Script->GetLastWrite() != fs::last_write_time(Script->GetFileName())){ if (Script->GetLastWrite() != fs::last_write_time(Script->GetFileName())) {
Script->StopThread = true; Script->SetStopThread(true);
info(Sec("[HOTSWAP] Updated : ")+ info(Sec("[HOTSWAP] Updated : ") + Script->GetFileName().substr(Script->GetFileName().find('\\')));
Script->GetFileName().substr(Script->GetFileName().find('\\')));
Script->SetLastWrite(fs::last_write_time(Script->GetFileName())); Script->SetLastWrite(fs::last_write_time(Script->GetFileName()));
Script->Reload(); Script->Reload();
} }
} }
FolderList(path,true); FolderList(path, true);
std::this_thread::sleep_for(std::chrono::seconds(2)); std::this_thread::sleep_for(std::chrono::seconds(2));
} }
} }
void InitLua(){ void InitLua() {
if(!fs::exists(Resource)){ if (!fs::exists(Resource)) {
fs::create_directory(Resource); fs::create_directory(Resource);
} }
std::string Path = Resource + Sec("/Server"); std::string Path = Resource + Sec("/Server");
if(!fs::exists(Path)){ if (!fs::exists(Path)) {
fs::create_directory(Path); fs::create_directory(Path);
} }
FolderList(Path,false); FolderList(Path, false);
std::thread t1(HotSwaps,Path); std::thread t1(HotSwaps, Path);
t1.detach(); t1.detach();
info(Sec("Lua system online")); info(Sec("Lua system online"));
} }
+400 -302
View File
@@ -3,446 +3,508 @@
/// ///
#include "Lua/LuaSystem.hpp" #include "Lua/LuaSystem.hpp"
#include "Security/Enc.h"
#include "Client.hpp" #include "Client.hpp"
#include "Settings.h"
#include "Network.h"
#include "Logger.h" #include "Logger.h"
#include "Network.h"
#include "Security/Enc.h"
#include "Settings.h"
#include "UnixCompat.h" #include "UnixCompat.h"
#include <iostream>
#include <future> #include <future>
#include <iostream>
#include <utility> #include <utility>
LuaArg* CreateArg(lua_State *L,int T,int S){ LuaArg* CreateArg(lua_State* L, int T, int S) {
if(S > T)return nullptr; if (S > T)
return nullptr;
auto* temp = new LuaArg; auto* temp = new LuaArg;
for(int C = S;C <= T;C++){ for (int C = S; C <= T; C++) {
if(lua_isstring(L,C)){ if (lua_isstring(L, C)) {
temp->args.emplace_back(std::string(lua_tostring(L,C))); temp->args.emplace_back(std::string(lua_tostring(L, C)));
}else if(lua_isinteger(L,C)){ } else if (lua_isinteger(L, C)) {
temp->args.emplace_back(int(lua_tointeger(L,C))); temp->args.emplace_back(int(lua_tointeger(L, C)));
}else if(lua_isboolean(L,C)){ } else if (lua_isboolean(L, C)) {
temp->args.emplace_back(bool(lua_toboolean(L,C))); temp->args.emplace_back(bool(lua_toboolean(L, C)));
}else if(lua_isnumber(L,C)) { } else if (lua_isnumber(L, C)) {
temp->args.emplace_back(float(lua_tonumber(L, C))); temp->args.emplace_back(float(lua_tonumber(L, C)));
} }
} }
return temp; return temp;
} }
void ClearStack(lua_State *L){ void ClearStack(lua_State* L) {
lua_settop(L,0); lua_settop(L, 0);
} }
Lua* GetScript(lua_State *L){ std::optional<std::reference_wrapper<Lua>> GetScript(lua_State* L) {
for(Lua*Script : PluginEngine){ for (auto& Script : PluginEngine) {
if (Script->GetState() == L)return Script; if (Script->GetState() == L)
return *Script;
} }
return nullptr; return std::nullopt;
} }
void SendError(lua_State *L,const std::string&msg){ void SendError(lua_State* L, const std::string& msg) {
Lua* S = GetScript(L); Assert(L);
auto MaybeS = GetScript(L);
std::string a; std::string a;
if(S == nullptr)a = Sec("Console"); if (!MaybeS.has_value()) {
else a = S->GetFileName().substr(S->GetFileName().find('\\')); a = Sec("_Console");
} else {
Lua& S = MaybeS.value();
a = S.GetFileName().substr(S.GetFileName().find('\\'));
}
warn(a + Sec(" | Incorrect Call of ") + msg); warn(a + Sec(" | Incorrect Call of ") + msg);
} }
int Trigger(Lua*lua,const std::string& R, LuaArg*arg){ int Trigger(Lua* lua, const std::string& R, LuaArg* arg) {
std::lock_guard<std::mutex> lockGuard(lua->Lock); std::lock_guard<std::mutex> lockGuard(lua->Lock);
std::packaged_task<int()> task([lua,R,arg]{return CallFunction(lua,R,arg);}); std::packaged_task<int()> task([lua, R, arg] { return CallFunction(lua, R, arg); });
std::future<int> f1 = task.get_future(); std::future<int> f1 = task.get_future();
std::thread t(std::move(task)); std::thread t(std::move(task));
t.detach(); t.detach();
auto status = f1.wait_for(std::chrono::seconds(5)); auto status = f1.wait_for(std::chrono::seconds(5));
if(status != std::future_status::timeout)return f1.get(); if (status != std::future_status::timeout)
SendError(lua->GetState(),R + " took too long to respond"); return f1.get();
SendError(lua->GetState(), R + " took too long to respond");
return 0; return 0;
} }
int FutureWait(Lua*lua,const std::string& R, LuaArg*arg,bool Wait){ int FutureWait(Lua* lua, const std::string& R, LuaArg* arg, bool Wait) {
std::packaged_task<int()> task([lua,R,arg]{return Trigger(lua,R,arg);}); Assert(lua);
std::packaged_task<int()> task([lua, R, arg] { return Trigger(lua, R, arg); });
std::future<int> f1 = task.get_future(); std::future<int> f1 = task.get_future();
std::thread t(std::move(task)); std::thread t(std::move(task));
t.detach(); t.detach();
int T = 0; int T = 0;
if(Wait)T = 6; if (Wait)
T = 6;
auto status = f1.wait_for(std::chrono::seconds(T)); auto status = f1.wait_for(std::chrono::seconds(T));
if(status != std::future_status::timeout)return f1.get(); if (status != std::future_status::timeout)
return f1.get();
return 0; return 0;
} }
int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller,LuaArg* arg,bool Wait){ int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, LuaArg* arg, bool Wait) {
int R = 0; int R = 0;
for(Lua*Script : PluginEngine){ for (auto& Script : PluginEngine) {
if(Script->IsRegistered(Event)){ if (Script->IsRegistered(Event)) {
if(local){ if (local) {
if (Script->GetPluginName() == Caller->GetPluginName()){ if (Script->GetPluginName() == Caller->GetPluginName()) {
R += FutureWait(Script,Script->GetRegistered(Event),arg,Wait); R += FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait);
} }
}else R += FutureWait(Script,Script->GetRegistered(Event), arg,Wait); } else
R += FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait);
} }
} }
return R; return R;
} }
bool ConsoleCheck(lua_State *L, int r){ bool ConsoleCheck(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);
warn(Sec("Console | ") + msg); warn(Sec("_Console | ") + msg);
return false; return false;
} }
return true; return true;
} }
bool CheckLua(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);
Lua * S = GetScript(L); auto MaybeS = GetScript(L);
std::string a = S->GetFileName().substr(S->GetFileName().find('\\')); if (MaybeS.has_value()) {
Lua& S = MaybeS.value();
std::string a = S.GetFileName().substr(S.GetFileName().find('\\'));
warn(a + " | " + msg); warn(a + " | " + msg);
return false; return false;
} }
// What the fuck, what do we do?!
AssertNotReachable();
}
return true; return true;
} }
int lua_RegisterEvent(lua_State *L){ int lua_RegisterEvent(lua_State* L) {
int Args = lua_gettop(L); int Args = lua_gettop(L);
Lua* Script = GetScript(L); auto MaybeScript = GetScript(L);
if(Args == 2 && lua_isstring(L,1) && lua_isstring(L,2)){ Assert(MaybeScript.has_value());
Script->RegisterEvent(lua_tostring(L,1),lua_tostring(L,2)); Lua& Script = MaybeScript.value();
}else SendError(L,Sec("RegisterEvent invalid argument count expected 2 got ") + std::to_string(Args)); if (Args == 2 && lua_isstring(L, 1) && lua_isstring(L, 2)) {
Script.RegisterEvent(lua_tostring(L, 1), lua_tostring(L, 2));
} else
SendError(L, Sec("RegisterEvent invalid argument count expected 2 got ") + std::to_string(Args));
return 0; return 0;
} }
int lua_TriggerEventL(lua_State *L){ int lua_TriggerEventL(lua_State* L) {
int Args = lua_gettop(L); int Args = lua_gettop(L);
Lua* Script = GetScript(L); auto MaybeScript = GetScript(L);
if(Args > 0){ Assert(MaybeScript.has_value());
if(lua_isstring(L,1)){ Lua& Script = MaybeScript.value();
TriggerLuaEvent(lua_tostring(L, 1), true, Script, CreateArg(L,Args,2),false); if (Args > 0) {
}else SendError(L,Sec("TriggerLocalEvent wrong argument [1] need string")); if (lua_isstring(L, 1)) {
}else{ TriggerLuaEvent(lua_tostring(L, 1), true, &Script, CreateArg(L, Args, 2), false);
SendError(L,Sec("TriggerLocalEvent not enough arguments expected 1 got 0")); } else
SendError(L, Sec("TriggerLocalEvent wrong argument [1] need string"));
} else {
SendError(L, Sec("TriggerLocalEvent not enough arguments expected 1 got 0"));
} }
return 0; return 0;
} }
int lua_TriggerEventG(lua_State *L){ int lua_TriggerEventG(lua_State* L) {
int Args = lua_gettop(L); int Args = lua_gettop(L);
Lua* Script = GetScript(L); auto MaybeScript = GetScript(L);
if(Args > 0){ Assert(MaybeScript.has_value());
if(lua_isstring(L,1)) { Lua& Script = MaybeScript.value();
TriggerLuaEvent(lua_tostring(L, 1), false, Script, CreateArg(L,Args,2),false); if (Args > 0) {
}else SendError(L,Sec("TriggerGlobalEvent wrong argument [1] need string")); if (lua_isstring(L, 1)) {
}else SendError(L,Sec("TriggerGlobalEvent not enough arguments")); TriggerLuaEvent(lua_tostring(L, 1), false, &Script, CreateArg(L, Args, 2), false);
} else
SendError(L, Sec("TriggerGlobalEvent wrong argument [1] need string"));
} else
SendError(L, Sec("TriggerGlobalEvent not enough arguments"));
return 0; return 0;
} }
char* ThreadOrigin(Lua*lua){ char* ThreadOrigin(Lua* lua) {
std::string T = "Thread in " + lua->GetFileName().substr(lua->GetFileName().find('\\')); std::string T = "Thread in " + lua->GetFileName().substr(lua->GetFileName().find('\\'));
char* Data = new char[T.size()+1]; char* Data = new char[T.size() + 1];
ZeroMemory(Data,T.size()+1); ZeroMemory(Data, T.size() + 1);
memcpy(Data, T.c_str(),T.size()); memcpy(Data, T.c_str(), T.size());
return Data; return Data;
} }
void SafeExecution(Lua* lua,const std::string& FuncName){ void SafeExecution(Lua* lua, const std::string& FuncName) {
lua_State* luaState = lua->GetState(); lua_State* luaState = lua->GetState();
lua_getglobal(luaState, FuncName.c_str()); lua_getglobal(luaState, FuncName.c_str());
if(lua_isfunction(luaState, -1)) { if (lua_isfunction(luaState, -1)) {
char* Origin = ThreadOrigin(lua); char* Origin = ThreadOrigin(lua);
#ifdef WIN32 #ifdef WIN32
__try{ __try {
int R = lua_pcall(luaState, 0, 0, 0); int R = lua_pcall(luaState, 0, 0, 0);
CheckLua(luaState, R); CheckLua(luaState, R);
}__except(Handle(GetExceptionInformation(),Origin)){} } __except (Handle(GetExceptionInformation(), Origin)) {
}
#else // unix #else // unix
int R = lua_pcall(luaState, 0, 0, 0); int R = lua_pcall(luaState, 0, 0, 0);
CheckLua(luaState, R); CheckLua(luaState, R);
#endif // WIN32 #endif // WIN32
delete [] Origin; delete[] Origin;
} }
ClearStack(luaState); ClearStack(luaState);
} }
void ExecuteAsync(Lua* lua,const std::string& FuncName){ void ExecuteAsync(Lua* lua, const std::string& FuncName) {
std::lock_guard<std::mutex> lockGuard(lua->Lock); std::lock_guard<std::mutex> lockGuard(lua->Lock);
SafeExecution(lua,FuncName); SafeExecution(lua, FuncName);
} }
void CallAsync(Lua* lua,const std::string& Func,int U){ void CallAsync(Lua* lua, const std::string& Func, int U) {
DebugPrintTID(); DebugPrintTID();
lua->StopThread = false; lua->SetStopThread(false);
int D = 1000 / U; int D = 1000 / U;
while(!lua->StopThread){ while (!lua->GetStopThread()) {
ExecuteAsync(lua,Func); ExecuteAsync(lua, Func);
std::this_thread::sleep_for(std::chrono::milliseconds(D)); std::this_thread::sleep_for(std::chrono::milliseconds(D));
} }
} }
int lua_StopThread(lua_State *L){ int lua_StopThread(lua_State* L) {
GetScript(L)->StopThread = true; auto MaybeScript = GetScript(L);
Assert(MaybeScript.has_value());
// ugly, but whatever, this is safe as fuck
MaybeScript.value().get().SetStopThread(true);
return 0; return 0;
} }
int lua_CreateThread(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)) {
std::string STR = lua_tostring(L,1); std::string STR = lua_tostring(L, 1);
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) {
std::thread t1(CallAsync,GetScript(L),STR,U); auto MaybeScript = GetScript(L);
Assert(MaybeScript.has_value());
Lua& Script = MaybeScript.value();
std::thread t1(CallAsync, &Script, STR, U);
t1.detach(); t1.detach();
}else SendError(L,Sec("CreateThread wrong argument [2] number must be between 1 and 500")); } else
}else SendError(L,Sec("CreateThread wrong argument [2] need number")); SendError(L, Sec("CreateThread wrong argument [2] number must be between 1 and 500"));
}else SendError(L,Sec("CreateThread wrong argument [1] need string")); } else
}else SendError(L,Sec("CreateThread not enough arguments")); SendError(L, Sec("CreateThread wrong argument [2] need number"));
} else
SendError(L, Sec("CreateThread wrong argument [1] need string"));
} else
SendError(L, Sec("CreateThread not enough arguments"));
return 0; return 0;
} }
int lua_Sleep(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(L,Sec("Sleep not enough arguments")); SendError(L, Sec("Sleep not enough arguments"));
return 0; return 0;
} }
return 1; return 1;
} }
Client* GetClient(int ID){ Client* GetClient(int ID) {
for(Client*c : CI->Clients) { for (Client* c : CI->Clients) {
if(c != nullptr && c->GetID() == ID)return c; if (c != nullptr && c->GetID() == ID)
return c;
} }
return nullptr; return nullptr;
} }
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); Client* c = GetClient(ID);
if(c != nullptr)lua_pushboolean(L, c->isConnected); if (c != nullptr)
else return 0; lua_pushboolean(L, c->isConnected);
}else{ else
SendError(L,Sec("isConnected not enough arguments")); return 0;
} else {
SendError(L, Sec("isConnected not enough arguments"));
return 0; return 0;
} }
return 1; return 1;
} }
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); Client* c = GetClient(ID);
if(c != nullptr)lua_pushstring(L, c->GetName().c_str()); if (c != nullptr)
else return 0; lua_pushstring(L, c->GetName().c_str());
}else{ else
SendError(L,Sec("GetPlayerName not enough arguments")); return 0;
} else {
SendError(L, Sec("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, CI->Size());
return 1; return 1;
} }
int lua_GetDID(lua_State *L){ int lua_GetDID(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); Client* c = GetClient(ID);
if(c != nullptr)lua_pushstring(L, c->GetDID().c_str()); if (c != nullptr)
else return 0; lua_pushstring(L, c->GetDID().c_str());
}else{ else
SendError(L,Sec("GetDID not enough arguments")); return 0;
} else {
SendError(L, Sec("GetDID 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; int i = 1;
for (Client *c : CI->Clients) { for (Client* c : CI->Clients) {
if(c == nullptr)continue; if (c == nullptr)
continue;
lua_pushinteger(L, c->GetID()); lua_pushinteger(L, c->GetID());
lua_pushstring(L, c->GetName().c_str()); lua_pushstring(L, c->GetName().c_str());
lua_settable(L,-3); lua_settable(L, -3);
i++; i++;
} }
if(CI->Clients.empty())return 0; if (CI->Clients.empty())
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); Client* c = GetClient(ID);
if(c != nullptr){ if (c != nullptr) {
int i = 1; int i = 1;
for (VData*v : c->GetAllCars()) { for (VData* v : c->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())return 0; if (c->GetAllCars().empty())
}else return 0; return 0;
}else{ } else
SendError(L,Sec("GetPlayerVehicles not enough arguments")); return 0;
} else {
SendError(L, Sec("GetPlayerVehicles not enough arguments"));
return 0; return 0;
} }
return 1; return 1;
} }
int lua_dropPlayer(lua_State *L){ 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); Client* c = GetClient(ID);
if(c == nullptr)return 0; if (c == nullptr)
if(c->GetRole() == Sec("MDEV"))return 0; return 0;
if (c->GetRole() == Sec("MDEV"))
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(Sec(" Reason : "))+lua_tostring(L,2); Reason = std::string(Sec(" Reason : ")) + lua_tostring(L, 2);
} }
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);
closesocket(c->GetTCPSock()); closesocket(c->GetTCPSock());
}else SendError(L,Sec("DropPlayer not enough arguments")); } else
SendError(L, Sec("DropPlayer not enough arguments"));
return 0; return 0;
} }
int lua_sendChat(lua_State *L){ int lua_sendChat(lua_State* L) {
if(lua_isinteger(L,1) || lua_isnumber(L,1)){ if (lua_isinteger(L, 1) || lua_isnumber(L, 1)) {
if(lua_isstring(L,2)){ if (lua_isstring(L, 2)) {
int ID = int(lua_tointeger(L,1)); int ID = int(lua_tointeger(L, 1));
if(ID == -1){ if (ID == -1) {
std::string Packet = "C:Server: " + std::string(lua_tostring(L, 2));
SendToAll(nullptr, Packet, true, true);
} else {
Client* c = GetClient(ID);
if (c != nullptr) {
if (!c->isSynced)
return 0;
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);
}else{
Client*c = GetClient(ID);
if(c != nullptr) {
if(!c->isSynced)return 0;
std::string Packet ="C:Server: " + std::string(lua_tostring(L, 2));
Respond(c, Packet, true); Respond(c, Packet, true);
}else SendError(L,Sec("SendChatMessage invalid argument [1] invalid ID")); } else
SendError(L, Sec("SendChatMessage invalid argument [1] invalid ID"));
} }
}else SendError(L,Sec("SendChatMessage invalid argument [2] expected string")); } else
}else SendError(L,Sec("SendChatMessage invalid argument [1] expected number")); SendError(L, Sec("SendChatMessage invalid argument [2] expected string"));
} else
SendError(L, Sec("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,Sec("RemoveVehicle invalid argument count expected 2 got ") + std::to_string(Args)); SendError(L, Sec("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); Client* c = GetClient(PID);
if(c == nullptr){ if (c == nullptr) {
SendError(L,Sec("RemoveVehicle invalid Player ID")); SendError(L, Sec("RemoveVehicle invalid Player ID"));
return 0; return 0;
} }
if(c->GetRole() == "MDEV")return 0; if (c->GetRole() == "MDEV")
if(!c->GetCarData(VID).empty()){ return 0;
std::string Destroy = "Od:" + std::to_string(PID)+"-"+std::to_string(VID); if (!c->GetCarData(VID).empty()) {
SendToAll(nullptr,Destroy,true,true); std::string Destroy = "Od:" + std::to_string(PID) + "-" + std::to_string(VID);
SendToAll(nullptr, Destroy, true, true);
c->DeleteCar(VID); c->DeleteCar(VID);
} }
}else SendError(L,Sec("RemoveVehicle invalid argument expected number")); } else
SendError(L, Sec("RemoveVehicle invalid argument expected number"));
return 0; return 0;
} }
int lua_HWID(lua_State *L){ int lua_HWID(lua_State* L) {
lua_pushinteger(L, -1); lua_pushinteger(L, -1);
return 1; return 1;
} }
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,Sec("TriggerClientEvent invalid argument count expected 3 got ") + std::to_string(Args)); SendError(L, Sec("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,Sec("TriggerClientEvent invalid argument [1] expected number")); SendError(L, Sec("TriggerClientEvent invalid argument [1] expected number"));
return 0; return 0;
} }
if(!lua_isstring(L,2)){ if (!lua_isstring(L, 2)) {
SendError(L,Sec("TriggerClientEvent invalid argument [2] expected string")); SendError(L, Sec("TriggerClientEvent invalid argument [2] expected string"));
return 0; return 0;
} }
if(!lua_isstring(L,3)){ if (!lua_isstring(L, 3)) {
SendError(L,Sec("TriggerClientEvent invalid argument [3] expected string")); SendError(L, Sec("TriggerClientEvent invalid argument [3] expected string"));
return 0; return 0;
} }
int ID = int(lua_tointeger(L,1)); int ID = int(lua_tointeger(L, 1));
std::string Packet = "E:" + std::string(lua_tostring(L,2)) + ":" + std::string(lua_tostring(L,3)); std::string Packet = "E:" + std::string(lua_tostring(L, 2)) + ":" + std::string(lua_tostring(L, 3));
if(ID == -1)SendToAll(nullptr,Packet,true,true); if (ID == -1)
else{ SendToAll(nullptr, Packet, true, true);
Client *c = GetClient(ID); else {
if(c == nullptr){ Client* c = GetClient(ID);
SendError(L,Sec("TriggerClientEvent invalid Player ID")); if (c == nullptr) {
SendError(L, Sec("TriggerClientEvent invalid Player ID"));
return 0; return 0;
} }
Respond(c,Packet,true); Respond(c, Packet, true);
} }
return 0; return 0;
} }
int lua_ServerExit(lua_State *){ int lua_ServerExit(lua_State*) {
exit(0); exit(0);
} }
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,Sec("set invalid argument count expected 2 got ") + std::to_string(Args)); SendError(L, Sec("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,Sec("set invalid argument [1] expected number")); SendError(L, Sec("set invalid argument [1] expected number"));
return 0; return 0;
} }
Lua* Src = GetScript(L); auto MaybeSrc = GetScript(L);
std::string Name; std::string Name;
if(Src == nullptr)Name = Sec("Console"); if (!MaybeSrc.has_value()) {
else Name = Src->GetPluginName(); Name = Sec("_Console");
int C = int(lua_tointeger(L,1)); } else {
switch(C){ Name = MaybeSrc.value().get().GetPluginName();
case 0: //debug
if(lua_isboolean(L,2)){
Debug = lua_toboolean(L,2);
info(Name + Sec(" | Debug -> ") + (Debug?"true":"false"));
} }
else SendError(L,Sec("set invalid argument [2] expected boolean for ID : 0")); int C = int(lua_tointeger(L, 1));
switch (C) {
case 0: //debug
if (lua_isboolean(L, 2)) {
Debug = lua_toboolean(L, 2);
info(Name + Sec(" | Debug -> ") + (Debug ? "true" : "false"));
} else
SendError(L, Sec("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); Private = lua_toboolean(L, 2);
info(Name + Sec(" | Private -> ") + (Private?"true":"false")); info(Name + Sec(" | Private -> ") + (Private ? "true" : "false"));
} } else
else SendError(L,Sec("set invalid argument [2] expected boolean for ID : 1")); SendError(L, Sec("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)); MaxCars = int(lua_tointeger(L, 2));
info(Name + Sec(" | MaxCars -> ") + std::to_string(MaxCars)); info(Name + Sec(" | MaxCars -> ") + std::to_string(MaxCars));
} } else
else SendError(L,Sec("set invalid argument [2] expected number for ID : 2")); SendError(L, Sec("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)); MaxPlayers = int(lua_tointeger(L, 2));
info(Name + Sec(" | MaxPlayers -> ") + std::to_string(MaxPlayers)); info(Name + Sec(" | MaxPlayers -> ") + std::to_string(MaxPlayers));
} } else
else SendError(L,Sec("set invalid argument [2] expected number for ID : 3")); SendError(L, Sec("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); MapName = lua_tostring(L, 2);
info(Name + Sec(" | MapName -> ") + MapName); info(Name + Sec(" | MapName -> ") + MapName);
} } else
else SendError(L,Sec("set invalid argument [2] expected string for ID : 4")); SendError(L, Sec("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); ServerName = lua_tostring(L, 2);
info(Name + Sec(" | ServerName -> ") + ServerName); info(Name + Sec(" | ServerName -> ") + ServerName);
} } else
else SendError(L,Sec("set invalid argument [2] expected string for ID : 5")); SendError(L, Sec("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); ServerDesc = lua_tostring(L, 2);
info(Name + Sec(" | ServerDesc -> ") + ServerDesc); info(Name + Sec(" | ServerDesc -> ") + ServerDesc);
} } else
else SendError(L,Sec("set invalid argument [2] expected string for ID : 6")); SendError(L, Sec("set invalid argument [2] expected string for ID : 6"));
break; break;
default: default:
warn(Sec("Invalid config ID : ") + std::to_string(C)); warn(Sec("Invalid config ID : ") + std::to_string(C));
@@ -452,62 +514,59 @@ int lua_Set(lua_State *L){
return 0; return 0;
} }
extern "C" { extern "C" {
int lua_Print(lua_State *L) { int lua_Print(lua_State* L) {
int Arg = lua_gettop(L); int Arg = lua_gettop(L);
for (int i = 1; i <= Arg; i++){ for (int i = 1; i <= Arg; i++) {
ConsoleOut(lua_tostring(L, i) + std::string("\n")); ConsoleOut(lua_tostring(L, i) + std::string("\n"));
} }
return 0; return 0;
} }
} }
void Lua::Init(){ Lua::Lua(const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote, bool Console)
luaL_openlibs(luaState); : luaState(luaL_newstate()) {
lua_register(luaState,"TriggerGlobalEvent",lua_TriggerEventG); Assert(luaState);
lua_register(luaState,"TriggerLocalEvent",lua_TriggerEventL); if (!PluginName.empty()) {
lua_register(luaState,"TriggerClientEvent",lua_RemoteEvent); SetPluginName(PluginName);
lua_register(luaState,"GetPlayerCount",lua_GetPlayerCount); }
lua_register(luaState,"isPlayerConnected",lua_isConnected); if (!FileName.empty()) {
lua_register(luaState,"RegisterEvent",lua_RegisterEvent); SetFileName(FileName);
lua_register(luaState,"GetPlayerName",lua_GetPlayerName); }
lua_register(luaState,"RemoveVehicle",lua_RemoveVehicle); SetLastWrite(LastWrote);
lua_register(luaState,"GetPlayerDiscordID",lua_GetDID); _Console = Console;
lua_register(luaState,"GetPlayerVehicles",lua_GetCars); Init();
lua_register(luaState,"CreateThread",lua_CreateThread);
lua_register(luaState,"SendChatMessage",lua_sendChat);
lua_register(luaState,"GetPlayers",lua_GetAllPlayers);
lua_register(luaState,"StopThread",lua_StopThread);
lua_register(luaState,"DropPlayer",lua_dropPlayer);
lua_register(luaState,"GetPlayerHWID",lua_HWID);
lua_register(luaState,"exit",lua_ServerExit);
lua_register(luaState,"Sleep",lua_Sleep);
lua_register(luaState,"print",lua_Print);
lua_register(luaState,"Set",lua_Set);
if(!Console)Reload();
} }
void Lua::Execute(const std::string& Command){
if(ConsoleCheck(luaState,luaL_dostring(luaState,Command.c_str()))){ Lua::Lua(bool Console)
: luaState(luaL_newstate()) {
_Console = Console;
Init();
}
void Lua::Execute(const std::string& Command) {
if (ConsoleCheck(luaState, luaL_dostring(luaState, Command.c_str()))) {
lua_settop(luaState, 0); lua_settop(luaState, 0);
} }
} }
void Lua::Reload(){ void Lua::Reload() {
if(CheckLua(luaState,luaL_dofile(luaState,FileName.c_str()))){ if (CheckLua(luaState, luaL_dofile(luaState, _FileName.c_str()))) {
CallFunction(this,Sec("onInit"), nullptr); CallFunction(this, Sec("onInit"), nullptr);
} }
} }
char* Lua::GetOrigin(){ char* Lua::GetOrigin() {
std::string T = GetFileName().substr(GetFileName().find('\\')); std::string T = GetFileName().substr(GetFileName().find('\\'));
char* Data = new char[T.size()]; char* Data = new char[T.size()];
ZeroMemory(Data,T.size()); ZeroMemory(Data, T.size());
memcpy(Data,T.c_str(),T.size()); memcpy(Data, T.c_str(), T.size());
return Data; return Data;
} }
int CallFunction(Lua*lua,const std::string& FuncName,LuaArg* Arg){
lua_State*luaState = lua->GetState(); int CallFunction(Lua* lua, const std::string& FuncName, LuaArg* Arg) {
lua_State* luaState = lua->GetState();
lua_getglobal(luaState, FuncName.c_str()); lua_getglobal(luaState, FuncName.c_str());
if(lua_isfunction(luaState, -1)) { if (lua_isfunction(luaState, -1)) {
int Size = 0; int Size = 0;
if(Arg != nullptr){ if (Arg != nullptr) {
Size = int(Arg->args.size()); Size = int(Arg->args.size());
Arg->PushArgs(luaState); Arg->PushArgs(luaState);
delete Arg; delete Arg;
@@ -516,63 +575,102 @@ int CallFunction(Lua*lua,const std::string& FuncName,LuaArg* Arg){
int R = 0; int R = 0;
char* Origin = lua->GetOrigin(); char* Origin = lua->GetOrigin();
#ifdef WIN32 #ifdef WIN32
__try{ __try {
#endif // WIN32 #endif // WIN32
R = lua_pcall(luaState, Size, 1, 0); R = lua_pcall(luaState, Size, 1, 0);
if (CheckLua(luaState, R)){ if (CheckLua(luaState, R)) {
if (lua_isnumber(luaState, -1)) { if (lua_isnumber(luaState, -1)) {
return int(lua_tointeger(luaState, -1)); return int(lua_tointeger(luaState, -1));
} }
} }
#ifdef WIN32 #ifdef WIN32
}__except(Handle(GetExceptionInformation(),Origin)){} } __except (Handle(GetExceptionInformation(), Origin)) {
}
#endif // WIN32 #endif // WIN32
delete [] Origin; delete[] Origin;
} }
ClearStack(luaState); ClearStack(luaState);
return 0; return 0;
} }
void Lua::SetPluginName(const std::string&Name){ void Lua::SetPluginName(const std::string& Name) {
PluginName = Name; _PluginName = Name;
} }
void Lua::SetFileName(const std::string&Name){ void Lua::SetFileName(const std::string& Name) {
FileName = Name; _FileName = Name;
} }
void Lua::RegisterEvent(const std::string& Event,const std::string& FunctionName){ void Lua::Init() {
RegisteredEvents.insert(std::make_pair(Event,FunctionName)); Assert(luaState);
luaL_openlibs(luaState);
lua_register(luaState, "TriggerGlobalEvent", lua_TriggerEventG);
lua_register(luaState, "TriggerLocalEvent", lua_TriggerEventL);
lua_register(luaState, "TriggerClientEvent", lua_RemoteEvent);
lua_register(luaState, "GetPlayerCount", lua_GetPlayerCount);
lua_register(luaState, "isPlayerConnected", lua_isConnected);
lua_register(luaState, "RegisterEvent", lua_RegisterEvent);
lua_register(luaState, "GetPlayerName", lua_GetPlayerName);
lua_register(luaState, "RemoveVehicle", lua_RemoveVehicle);
lua_register(luaState, "GetPlayerDiscordID", lua_GetDID);
lua_register(luaState, "GetPlayerVehicles", lua_GetCars);
lua_register(luaState, "CreateThread", lua_CreateThread);
lua_register(luaState, "SendChatMessage", lua_sendChat);
lua_register(luaState, "GetPlayers", lua_GetAllPlayers);
lua_register(luaState, "StopThread", lua_StopThread);
lua_register(luaState, "DropPlayer", lua_dropPlayer);
lua_register(luaState, "GetPlayerHWID", lua_HWID);
lua_register(luaState, "exit", lua_ServerExit);
lua_register(luaState, "Sleep", lua_Sleep);
lua_register(luaState, "print", lua_Print);
lua_register(luaState, "Set", lua_Set);
if (!_Console)
Reload();
} }
void Lua::UnRegisterEvent(const std::string&Event){
for(const std::pair<std::string,std::string>& a : RegisteredEvents){ void Lua::RegisterEvent(const std::string& Event, const std::string& FunctionName) {
if(a.first == Event) { _RegisteredEvents.insert(std::make_pair(Event, FunctionName));
RegisteredEvents.erase(a); }
void Lua::UnRegisterEvent(const std::string& Event) {
for (const std::pair<std::string, std::string>& a : _RegisteredEvents) {
if (a.first == Event) {
_RegisteredEvents.erase(a);
break; break;
} }
} }
} }
bool Lua::IsRegistered(const std::string&Event){ bool Lua::IsRegistered(const std::string& Event) {
for(const std::pair<std::string,std::string>& a : RegisteredEvents){ for (const std::pair<std::string, std::string>& a : _RegisteredEvents) {
if(a.first == Event)return true; if (a.first == Event)
return true;
} }
return false; return false;
} }
std::string Lua::GetRegistered(const std::string&Event){ std::string Lua::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 : _RegisteredEvents) {
if(a.first == Event)return a.second; if (a.first == Event)
return a.second;
} }
return ""; return "";
} }
std::string Lua::GetFileName(){ std::string Lua::GetFileName() const {
return FileName; return _FileName;
} }
std::string Lua::GetPluginName(){ std::string Lua::GetPluginName() const {
return PluginName; return _PluginName;
} }
lua_State* Lua::GetState(){ lua_State* Lua::GetState() {
return luaState; return luaState;
} }
void Lua::SetLastWrite(fs::file_time_type time){
LastWrote = time; const lua_State* Lua::GetState() const {
return luaState;
} }
fs::file_time_type Lua::GetLastWrite(){
return LastWrote; void Lua::SetLastWrite(fs::file_time_type time) {
_LastWrote = time;
}
fs::file_time_type Lua::GetLastWrite() {
return _LastWrote;
}
Lua::~Lua() {
lua_close(luaState);
} }