diff --git a/include/Common.h b/include/Common.h index c74a16e..d36cf6f 100644 --- a/include/Common.h +++ b/include/Common.h @@ -133,6 +133,9 @@ void RegisterThread(const std::string str); Application::Console().Write(_this_location + std::string("[DEBUG] ") + (x)); \ } \ } while (false) +// for those times when you just need to ignore something :^) +// explicity disables a [[nodiscard]] warning +#define beammp_ignore(x) (void)x #define Biggest 30000 std::string Comp(std::string Data); diff --git a/include/LuaAPI.h b/include/LuaAPI.h index 053e8c2..091de13 100644 --- a/include/LuaAPI.h +++ b/include/LuaAPI.h @@ -6,12 +6,12 @@ namespace LuaAPI { void Print(sol::variadic_args); namespace MP { - static inline TLuaEngine* Engine { nullptr }; + extern TLuaEngine* Engine; std::string GetOSName(); std::tuple GetServerVersion(); bool TriggerClientEvent(int PlayerID, const std::string& EventName, const std::string& Data); - size_t GetPlayerCount() { return Engine->Server().ClientCount(); } + inline size_t GetPlayerCount() { return Engine->Server().ClientCount(); } void DropPlayer(int ID, std::optional MaybeReason); void SendChatMessage(int ID, const std::string& Message); void RemoveVehicle(int PlayerID, int VehicleID); diff --git a/include/TLuaEngine.h b/include/TLuaEngine.h index cf3c01f..5a64a16 100644 --- a/include/TLuaEngine.h +++ b/include/TLuaEngine.h @@ -4,6 +4,7 @@ #include "TServer.h" #include #include +#include #include #include #include @@ -40,21 +41,39 @@ struct TLuaPluginConfig { class TLuaEngine : IThreaded { public: - TLuaEngine(TServer& Server, TNetwork& Network); + TLuaEngine(); ~TLuaEngine() noexcept { beammp_debug("Lua Engine terminated"); } void operator()() override; - TNetwork& Network() { return mNetwork; } - TServer& Server() { return mServer; } + TNetwork& Network() { return *mNetwork; } + TServer& Server() { return *mServer; } + void SetNetwork(TNetwork* Network) { mNetwork = Network; } + void SetServer(TServer* Server) { mServer = Server; } + + static void WaitForAll(std::vector>& Results); [[nodiscard]] std::shared_ptr EnqueueScript(TLuaStateId StateID, const std::shared_ptr& Script); - [[nodiscard]] std::shared_ptr EnqueueFunctionCall(TLuaStateId StateID, const std::string& FunctionName); + [[nodiscard]] std::shared_ptr EnqueueFunctionCall(TLuaStateId StateID, const std::string& FunctionName, const std::initializer_list& Args); void EnsureStateExists(TLuaStateId StateId, const std::string& Name, bool DontCallOnInit = false); void RegisterEvent(const std::string& EventName, TLuaStateId StateId, const std::string& FunctionName); - [[nodiscard]] std::vector> TriggerEvent(const std::string& EventName); + template + [[nodiscard]] std::vector> TriggerEvent(const std::string& EventName, ArgsT&&... Args) { + std::unique_lock Lock(mEventsMutex); + if (mEvents.find(EventName) == mEvents.end()) { + return {}; + } + std::vector> Results; + for (const auto& Event : mEvents.at(EventName)) { + for (const auto& Function : Event.second) { + beammp_debug("TriggerEvent: triggering \"" + Function + "\" on \"" + Event.first + "\""); + Results.push_back(EnqueueFunctionCall(Event.first, Function, { std::forward(Args)... })); + } + } + return Results; + } std::set GetEventHandlersForState(const std::string& EventName, TLuaStateId StateId); static constexpr const char* BeamMPFnNotFoundError = "BEAMMP_FN_NOT_FOUND"; @@ -70,7 +89,7 @@ private: StateThreadData(const StateThreadData&) = delete; ~StateThreadData() noexcept { beammp_debug("\"" + mStateId + "\" destroyed"); } [[nodiscard]] std::shared_ptr EnqueueScript(const std::shared_ptr& Script); - [[nodiscard]] std::shared_ptr EnqueueFunctionCall(const std::string& FunctionName); + [[nodiscard]] std::shared_ptr EnqueueFunctionCall(const std::string& FunctionName, const std::initializer_list& Args); void RegisterEvent(const std::string& EventName, const std::string& FunctionName); void operator()() override; @@ -87,14 +106,14 @@ private: std::thread mThread; std::queue, std::shared_ptr>> mStateExecuteQueue; std::recursive_mutex mStateExecuteQueueMutex; - std::queue>> mStateFunctionQueue; + std::queue, std::initializer_list>> mStateFunctionQueue; std::recursive_mutex mStateFunctionQueueMutex; TLuaEngine* mEngine; sol::state_view mStateView { mState }; }; - TNetwork& mNetwork; - TServer& mServer; + TNetwork* mNetwork; + TServer* mServer; std::atomic_bool mShutdown { false }; fs::path mResourceServerPath; std::vector mLuaPlugins; @@ -104,10 +123,4 @@ private: std::recursive_mutex mEventsMutex; }; -#include -// DEAD CODE -struct TLuaArg { - std::vector args; - void PushArgs(lua_State* State); -}; -std::any TriggerLuaEvent(const std::string& Event, bool local, TLuaPlugin* Caller, std::shared_ptr arg, bool Wait); +//std::any TriggerLuaEvent(const std::string& Event, bool local, TLuaPlugin* Caller, std::shared_ptr arg, bool Wait); diff --git a/src/LuaAPI.cpp b/src/LuaAPI.cpp index d3fa197..6717b19 100644 --- a/src/LuaAPI.cpp +++ b/src/LuaAPI.cpp @@ -4,11 +4,32 @@ static std::string LuaToString(const sol::object& Value, size_t Indent = 1) { switch (Value.get_type()) { + case sol::type::userdata: { + std::stringstream ss; + ss << "[[userdata: " << Value.as().pointer() << "]]"; + return ss.str(); + } + case sol::type::thread: { + std::stringstream ss; + ss << "[[thread: " << Value.as().pointer() << "]] {" + << "\n"; + for (size_t i = 0; i < Indent; ++i) { + ss << "\t"; + } + ss << "status: " << std::to_string(int(Value.as().status())) << "\n}"; + return ss.str(); + } + case sol::type::lightuserdata: { + std::stringstream ss; + ss << "[[lightuserdata: " << Value.as().pointer() << "]]"; + return ss.str(); + } case sol::type::string: return Value.as(); case sol::type::number: return std::to_string(Value.as()); case sol::type::nil: + case sol::type::none: return ""; case sol::type::boolean: return Value.as() ? "true" : "false"; @@ -130,13 +151,13 @@ void LuaAPI::MP::RemoveVehicle(int PID, int VID) { c->DeleteCar(VID); } } - +/* void LuaAPI::MP::Set(int ConfigID, sol::object NewValue) { switch (ConfigID) { case 0: //debug if (lua_isboolean(L, 2)) { Application::Settings.DebugModeEnabled = NewValue.as(); - beammp_info("Set `Debug` to ") + (Application::Settings.DebugModeEnabled ? "true" : "false")); + beammp_info("Set `Debug` to " + (Application::Settings.DebugModeEnabled ? "true" : "false")); } else SendError(Engine(), L, ("set invalid argument [2] expected boolean for ID : 0")); break; @@ -187,6 +208,7 @@ void LuaAPI::MP::Set(int ConfigID, sol::object NewValue) { break; } } +*/ void LuaAPI::MP::Sleep(size_t Ms) { std::this_thread::sleep_for(std::chrono::milliseconds(Ms)); diff --git a/src/TConsole.cpp b/src/TConsole.cpp index 423e132..841a76d 100644 --- a/src/TConsole.cpp +++ b/src/TConsole.cpp @@ -84,6 +84,6 @@ void TConsole::WriteRaw(const std::string& str) { } void TConsole::InitializeLuaConsole(TLuaEngine& Engine) { - Engine.EnsureStateExists(mStateId, "Console"); mLuaEngine = &Engine; + Engine.EnsureStateExists(mStateId, "Console"); } diff --git a/src/TLuaEngine.cpp b/src/TLuaEngine.cpp index e09c968..a5d40c7 100644 --- a/src/TLuaEngine.cpp +++ b/src/TLuaEngine.cpp @@ -14,9 +14,9 @@ static TLuaStateId GenerateUniqueStateId() { return std::to_string(MTGen64()) + std::to_string(std::chrono::duration_cast(Time).count()); } -TLuaEngine::TLuaEngine(TServer& Server, TNetwork& Network) - : mNetwork(Network) - , mServer(Server) { +TLuaEngine* LuaAPI::MP::Engine; + +TLuaEngine::TLuaEngine() { LuaAPI::MP::Engine = this; if (!fs::exists(Application::Settings.Resource)) { fs::create_directory(Application::Settings.Resource); @@ -41,7 +41,7 @@ void TLuaEngine::operator()() { CollectAndInitPlugins(); // now call all onInit's for (const auto& Pair : mLuaStates) { - auto Res = EnqueueFunctionCall(Pair.first, "onInit"); + auto Res = EnqueueFunctionCall(Pair.first, "onInit", {}); Res->WaitUntilReady(); if (Res->Error && Res->ErrorMessage != TLuaEngine::BeamMPFnNotFoundError) { beammp_lua_error("Calling \"onInit\" on \"" + Pair.first + "\" failed: " + Res->ErrorMessage); @@ -53,16 +53,24 @@ void TLuaEngine::operator()() { } } +void TLuaEngine::WaitForAll(std::vector>& Results) { + for (const auto& Result : Results) { + while (!Result->Ready) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + } +} + std::shared_ptr TLuaEngine::EnqueueScript(TLuaStateId StateID, const std::shared_ptr& Script) { std::unique_lock Lock(mLuaStatesMutex); beammp_debug("enqueuing script into \"" + StateID + "\""); return mLuaStates.at(StateID)->EnqueueScript(Script); } -std::shared_ptr TLuaEngine::EnqueueFunctionCall(TLuaStateId StateID, const std::string& FunctionName) { +std::shared_ptr TLuaEngine::EnqueueFunctionCall(TLuaStateId StateID, const std::string& FunctionName, const std::initializer_list& Args) { std::unique_lock Lock(mLuaStatesMutex); beammp_debug("calling \"" + FunctionName + "\" in \"" + StateID + "\""); - return mLuaStates.at(StateID)->EnqueueFunctionCall(FunctionName); + return mLuaStates.at(StateID)->EnqueueFunctionCall(FunctionName, Args); } void TLuaEngine::CollectAndInitPlugins() { @@ -119,7 +127,7 @@ void TLuaEngine::EnsureStateExists(TLuaStateId StateId, const std::string& Name, mLuaStates[StateId] = std::move(DataPtr); RegisterEvent("onInit", StateId, "onInit"); if (!DontCallOnInit) { - auto Res = EnqueueFunctionCall(StateId, "onInit"); + auto Res = EnqueueFunctionCall(StateId, "onInit", {}); Res->WaitUntilReady(); if (Res->Error && Res->ErrorMessage != TLuaEngine::BeamMPFnNotFoundError) { beammp_lua_error("Calling \"onInit\" on \"" + StateId + "\" failed: " + Res->ErrorMessage); @@ -133,21 +141,6 @@ void TLuaEngine::RegisterEvent(const std::string& EventName, TLuaStateId StateId mEvents[EventName][StateId].insert(FunctionName); } -std::vector> TLuaEngine::TriggerEvent(const std::string& EventName) { - std::unique_lock Lock(mEventsMutex); - if (mEvents.find(EventName) == mEvents.end()) { - return {}; - } - std::vector> Results; - for (const auto& Event : mEvents.at(EventName)) { - for (const auto& Function : Event.second) { - beammp_debug("TriggerEvent: triggering \"" + Function + "\" on \"" + Event.first + "\""); - Results.push_back(EnqueueFunctionCall(Event.first, Function)); - } - } - return Results; -} - std::set TLuaEngine::GetEventHandlersForState(const std::string& EventName, TLuaStateId StateId) { return mEvents[EventName][StateId]; } @@ -227,8 +220,8 @@ TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomi : mName(Name) , mShutdown(Shutdown) , mStateId(StateId) + , mState(luaL_newstate()) , mEngine(&Engine) { - mState = luaL_newstate(); luaL_openlibs(mState); sol::state_view StateView(mState); // StateView.globals()["package"].get() @@ -262,7 +255,7 @@ TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomi return Lua_GetPlayerIdentifiers(ID); }); Table.set_function("Sleep", &LuaAPI::MP::Sleep); - Table.set_function("Set", &LuaAPI::MP::Set); + //Table.set_function("Set", &LuaAPI::MP::Set); //Table.set_function("HttpsGET", &LuaAPI::MP::HttpsGET); //Table.set_function("HttpsPOST", &LuaAPI::MP::HttpsPOST); Table.create_named("Settings", @@ -284,13 +277,13 @@ std::shared_ptr TLuaEngine::StateThreadData::EnqueueScript(const std return Result; } -std::shared_ptr TLuaEngine::StateThreadData::EnqueueFunctionCall(const std::string& FunctionName) { +std::shared_ptr TLuaEngine::StateThreadData::EnqueueFunctionCall(const std::string& FunctionName, const std::initializer_list& Args) { beammp_debug("calling \"" + FunctionName + "\" in \"" + mName + "\""); auto Result = std::make_shared(); Result->StateId = mStateId; Result->Function = FunctionName; std::unique_lock Lock(mStateFunctionQueueMutex); - mStateFunctionQueue.push({ FunctionName, Result }); + mStateFunctionQueue.push({ FunctionName, Result, Args }); return Result; } @@ -327,26 +320,29 @@ void TLuaEngine::StateThreadData::operator()() { auto FnNameResultPair = mStateFunctionQueue.front(); mStateFunctionQueue.pop(); Lock.unlock(); - FnNameResultPair.second->StateId = mStateId; - beammp_debug("Running function \"" + FnNameResultPair.first + "\""); + auto& StateId = std::get<0>(FnNameResultPair); + auto& Result = std::get<1>(FnNameResultPair); + auto& Args = std::get<1>(FnNameResultPair); + Result->StateId = mStateId; + beammp_debug("Running function \"" + std::get<0>(FnNameResultPair) + "\""); sol::state_view StateView(mState); - auto Fn = StateView[FnNameResultPair.first]; - beammp_debug("Done running function \"" + FnNameResultPair.first + "\""); + auto Fn = StateView[StateId]; + beammp_debug("Done running function \"" + StateId + "\""); if (Fn.valid() && Fn.get_type() == sol::type::function) { - auto Res = Fn(); + auto Res = Fn(Args); if (Res.valid()) { - FnNameResultPair.second->Error = false; - FnNameResultPair.second->Result = std::move(Res); + Result->Error = false; + Result->Result = std::move(Res); } else { - FnNameResultPair.second->Error = true; + Result->Error = true; sol::error Err = Res; - FnNameResultPair.second->ErrorMessage = Err.what(); + Result->ErrorMessage = Err.what(); } - FnNameResultPair.second->Ready = true; + Result->Ready = true; } else { - FnNameResultPair.second->Error = true; - FnNameResultPair.second->ErrorMessage = BeamMPFnNotFoundError; // special error kind that we can ignore later - FnNameResultPair.second->Ready = true; + Result->Error = true; + Result->ErrorMessage = BeamMPFnNotFoundError; // special error kind that we can ignore later + Result->Ready = true; } } } @@ -359,10 +355,3 @@ void TLuaResult::WaitUntilReady() { std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } - -// AHHH -std::any TriggerLuaEvent(const std::string& Event, bool local, TLuaPlugin* Caller, std::shared_ptr arg, bool Wait) { -} - -void TLuaArg::PushArgs(lua_State* State) { -} diff --git a/src/TNetwork.cpp b/src/TNetwork.cpp index c76ae9c..c01b287 100644 --- a/src/TNetwork.cpp +++ b/src/TNetwork.cpp @@ -6,6 +6,8 @@ #include #include +#include "LuaAPI.h" + TNetwork::TNetwork(TServer& Server, TPPSMonitor& PPSMonitor, TResourceManager& ResourceManager) : mServer(Server) , mPPSMonitor(PPSMonitor) @@ -289,14 +291,27 @@ void TNetwork::Authentication(const TConnection& ClientConnection) { return true; }); + auto Futures = LuaAPI::MP::Engine->TriggerEvent("onPlayerAuth", Client->GetName(), Client->GetRoles(), Client->IsGuest()); + TLuaEngine::WaitForAll(Futures); + bool NotAllowed = std::any_of(Futures.begin(), Futures.end(), + [](const std::shared_ptr& Result) { + return !Result->Error && Result->Result.is() && bool(Result->Result.as()); + }); + std::string Reason; + bool NotAllowedWithReason = std::any_of(Futures.begin(), Futures.end(), + [&Reason](const std::shared_ptr& Result) -> bool { + if (!Result->Error && Result->Result.is()) { + Reason = Result->Result.as(); + return true; + } + return false; + }); - auto arg = std::make_unique(TLuaArg { { Client->GetName(), Client->GetRoles(), Client->IsGuest() } }); - std::any Res = TriggerLuaEvent("onPlayerAuth", false, nullptr, std::move(arg), true); - if (Res.type() == typeid(int) && std::any_cast(Res)) { + if (NotAllowed) { ClientKick(*Client, "you are not allowed on the server!"); return; - } else if (Res.type() == typeid(std::string)) { - ClientKick(*Client, std::any_cast(Res)); + } else if (NotAllowedWithReason) { + ClientKick(*Client, Reason); return; } @@ -563,7 +578,8 @@ void TNetwork::OnDisconnect(const std::weak_ptr& ClientPtr, bool kicked Packet = ("L") + c.GetName() + (" left the server!"); SendToAll(&c, Packet, false, true); Packet.clear(); - TriggerLuaEvent(("onPlayerDisconnect"), false, nullptr, std::make_unique(TLuaArg { { c.GetID() } }), false); + auto Futures = LuaAPI::MP::Engine->TriggerEvent("onPlayerDisconnect", c.GetID()); + beammp_ignore(Futures); if (c.GetTCPSock()) CloseSocketProper(c.GetTCPSock()); if (c.GetDownSock()) @@ -597,13 +613,13 @@ void TNetwork::OnConnect(const std::weak_ptr& c) { auto LockedClient = c.lock(); LockedClient->SetID(OpenID()); beammp_info("Assigned ID " + std::to_string(LockedClient->GetID()) + " to " + LockedClient->GetName()); - TriggerLuaEvent("onPlayerConnecting", false, nullptr, std::make_unique(TLuaArg { { LockedClient->GetID() } }), false); + beammp_ignore(LuaAPI::MP::Engine->TriggerEvent("onPlayerConnecting", LockedClient->GetID())); SyncResources(*LockedClient); if (LockedClient->GetStatus() < 0) return; (void)Respond(*LockedClient, "M" + Application::Settings.MapName, true); //Send the Map on connect beammp_info(LockedClient->GetName() + " : Connected"); - TriggerLuaEvent("onPlayerJoining", false, nullptr, std::make_unique(TLuaArg { { LockedClient->GetID() } }), false); + beammp_ignore(LuaAPI::MP::Engine->TriggerEvent("onPlayerJoining", LockedClient->GetID())); } void TNetwork::SyncResources(TClient& c) { @@ -802,7 +818,7 @@ bool TNetwork::SyncClient(const std::weak_ptr& c) { // ignore error (void)SendToAll(LockedClient.get(), ("JWelcome ") + LockedClient->GetName() + "!", false, true); - TriggerLuaEvent(("onPlayerJoin"), false, nullptr, std::make_unique(TLuaArg { { LockedClient->GetID() } }), false); + beammp_ignore(LuaAPI::MP::Engine->TriggerEvent("onPlayerJoin", LockedClient->GetID())); LockedClient->SetIsSyncing(true); bool Return = false; bool res = true; diff --git a/src/TServer.cpp b/src/TServer.cpp index 38b5d9e..2eea8c0 100644 --- a/src/TServer.cpp +++ b/src/TServer.cpp @@ -7,6 +7,8 @@ #include #include +#include "LuaAPI.h" + #undef GetObject //Fixes Windows #include "Json.h" @@ -119,17 +121,25 @@ void TServer::GlobalParser(const std::weak_ptr& Client, std::string Pac #endif Network.SendToAll(LockedClient.get(), Packet, false, true); return; - case 'C': + case 'C': { #ifdef DEBUG beammp_debug(std::string(("got 'C' packet: '")) + Packet + ("' (") + std::to_string(Packet.size()) + (")")); #endif if (Packet.length() < 4 || Packet.find(':', 3) == std::string::npos) break; - Res = TriggerLuaEvent("onChatMessage", false, nullptr, std::make_unique(TLuaArg { { LockedClient->GetID(), LockedClient->GetName(), Packet.substr(Packet.find(':', 3) + 1) } }), true); - if (std::any_cast(Res)) + auto Futures = LuaAPI::MP::Engine->TriggerEvent("onChatMessage", LockedClient->GetID(), LockedClient->GetName(), Packet.substr(Packet.find(':', 3) + 1)); + TLuaEngine::WaitForAll(Futures); + if (std::any_of(Futures.begin(), Futures.end(), + [](const std::shared_ptr& Elem) { + return !Elem->Error + && Elem->Result.is() + && bool(Elem->Result.as()); + })) { break; + } Network.SendToAll(nullptr, Packet, true, true); return; + } case 'E': #ifdef DEBUG beammp_debug(std::string(("got 'E' packet: '")) + Packet + ("' (") + std::to_string(Packet.size()) + (")")); @@ -154,7 +164,7 @@ void TServer::HandleEvent(TClient& c, const std::string& Data) { Name = t; break; case 2: - TriggerLuaEvent(Name, false, nullptr, std::make_unique(TLuaArg { { c.GetID(), t } }), false); + beammp_ignore(LuaAPI::MP::Engine->TriggerEvent(Name, c.GetID(), t)); break; default: break; @@ -207,9 +217,14 @@ void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Networ std::string CarJson = Packet.substr(5); Packet = "Os:" + c.GetRoles() + ":" + c.GetName() + ":" + std::to_string(c.GetID()) + "-" + std::to_string(CarID) + ":" + CarJson; - auto Res = TriggerLuaEvent(("onVehicleSpawn"), false, nullptr, std::make_unique(TLuaArg { { c.GetID(), CarID, Packet.substr(3) } }), true); + auto Futures = LuaAPI::MP::Engine->TriggerEvent("onVehicleSpawn", c.GetID(), CarID, Packet.substr(3)); + TLuaEngine::WaitForAll(Futures); + bool ShouldntSpawn = std::any_of(Futures.begin(), Futures.end(), + [](const std::shared_ptr& Result) { + return !Result->Error && Result->Result.is() && Result->Result.as() != 0; + }); - if (ShouldSpawn(c, CarJson, CarID) && std::any_cast(Res) == 0) { + if (ShouldSpawn(c, CarJson, CarID) && !ShouldntSpawn) { c.AddNewCar(CarID, Packet); Network.SendToAll(nullptr, Packet, true, true); } else { @@ -235,14 +250,17 @@ void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Networ VID = stoi(vid); } if (PID != -1 && VID != -1 && PID == c.GetID()) { - auto Res = TriggerLuaEvent(("onVehicleEdited"), false, nullptr, - std::make_unique(TLuaArg { { c.GetID(), VID, Packet.substr(3) } }), - true); + auto Futures = LuaAPI::MP::Engine->TriggerEvent("onVehicleEdited", c.GetID(), VID, Packet.substr(3)); + TLuaEngine::WaitForAll(Futures); + bool ShouldntAllow = std::any_of(Futures.begin(), Futures.end(), + [](const std::shared_ptr& Result) { + return !Result->Error && Result->Result.is() && Result->Result.as() != 0; + }); auto FoundPos = Packet.find('{'); FoundPos = FoundPos == std::string::npos ? 0 : FoundPos; // attempt at sanitizing this if ((c.GetUnicycleID() != VID || IsUnicycle(c, Packet.substr(FoundPos))) - && std::any_cast(Res) == 0) { + && !ShouldntAllow) { Network.SendToAll(&c, Packet, false, true); Apply(c, VID, Packet); } else { @@ -272,8 +290,7 @@ void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Networ c.SetUnicycleID(-1); } Network.SendToAll(nullptr, Packet, true, true); - TriggerLuaEvent(("onVehicleDeleted"), false, nullptr, - std::make_unique(TLuaArg { { c.GetID(), VID } }), false); + beammp_ignore(LuaAPI::MP::Engine->TriggerEvent("onVehicleDeleted", c.GetID(), VID)); c.DeleteCar(VID); beammp_debug(c.GetName() + (" deleted car with ID ") + std::to_string(VID)); } @@ -293,9 +310,7 @@ void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Networ if (PID != -1 && VID != -1 && PID == c.GetID()) { Data = Data.substr(Data.find('{')); - TriggerLuaEvent("onVehicleReset", false, nullptr, - std::make_unique(TLuaArg { { c.GetID(), VID, Data } }), - false); + beammp_ignore(LuaAPI::MP::Engine->TriggerEvent("onVehicleReset", c.GetID(), VID, Data)); Network.SendToAll(&c, Packet, false, true); } return; diff --git a/src/main.cpp b/src/main.cpp index 03bbbc0..fcbead8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,6 @@ #include "Common.h" #include "Http.h" +#include "LuaAPI.h" #include "TConfig.h" #include "THeartbeatThread.h" #include "TLuaEngine.h" @@ -48,10 +49,15 @@ int main(int argc, char** argv) { bool Shutdown = false; Application::RegisterShutdownHandler([&Shutdown] { Shutdown = true; }); - Application::RegisterShutdownHandler([] { TriggerLuaEvent("onShutdown", false, nullptr, {}, true); }); + Application::RegisterShutdownHandler([] { + auto Futures = LuaAPI::MP::Engine->TriggerEvent("onShutdown"); + TLuaEngine::WaitForAll(Futures); + }); TServer Server(argc, argv); TConfig Config; + TLuaEngine LuaEngine; + LuaEngine.SetServer(&Server); if (Config.Failed()) { beammp_info("Closing in 10 seconds"); @@ -64,7 +70,7 @@ int main(int argc, char** argv) { TPPSMonitor PPSMonitor(Server); THeartbeatThread Heartbeat(ResourceManager, Server); TNetwork Network(Server, PPSMonitor, ResourceManager); - TLuaEngine LuaEngine(Server, Network); + LuaEngine.SetNetwork(&Network); PPSMonitor.SetNetwork(Network); Application::Console().InitializeLuaConsole(LuaEngine);