#pragma once #include "TNetwork.h" #include "TServer.h" #include #include #include #include #include #include #include #include #include #include #define SOL_ALL_SAFETIES_ON 1 #include using TLuaStateId = std::string; namespace fs = std::filesystem; class TLuaPlugin; struct TLuaResult { std::atomic_bool Ready; std::atomic_bool Error; std::string ErrorMessage; sol::protected_function_result Result; // TODO: Add condition_variable void WaitUntilReady(); }; struct TLuaPluginConfig { static inline const std::string FileName = "PluginConfig.toml"; TLuaStateId StateId; // TODO: Add execute list }; class TLuaEngine : IThreaded { public: TLuaEngine(TServer& Server, TNetwork& Network); void operator()() override; [[nodiscard]] std::shared_ptr EnqueueScript(TLuaStateId StateID, const std::shared_ptr& Script); [[nodiscard]] std::shared_ptr EnqueueFunctionCall(TLuaStateId StateID, const std::string& FunctionName); 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); static constexpr const char* BeamMPFnNotFoundError = "BEAMMP_FN_NOT_FOUND"; private: void CollectAndInitPlugins(); void InitializePlugin(const fs::path& Folder, const TLuaPluginConfig& Config); void FindAndParseConfig(const fs::path& Folder, TLuaPluginConfig& Config); class StateThreadData : IThreaded { public: StateThreadData(const std::string& Name, std::atomic_bool& Shutdown, TLuaStateId StateId, TLuaEngine& Engine); StateThreadData(const StateThreadData&) = delete; [[nodiscard]] std::shared_ptr EnqueueScript(const std::shared_ptr& Script); [[nodiscard]] std::shared_ptr EnqueueFunctionCall(const std::string& FunctionName); void RegisterEvent(const std::string& EventName, const std::string& FunctionName); void operator()() override; private: std::string mName; std::atomic_bool& mShutdown; TLuaStateId mStateId; lua_State* mState; std::thread mThread; std::queue, std::shared_ptr>> mStateExecuteQueue; std::recursive_mutex mStateExecuteQueueMutex; std::queue>> mStateFunctionQueue; std::recursive_mutex mStateFunctionQueueMutex; TLuaEngine* mEngine; }; TNetwork& mNetwork; TServer& mServer; std::atomic_bool mShutdown { false }; fs::path mResourceServerPath; std::vector mLuaPlugins; std::unordered_map> mLuaStates; std::recursive_mutex mLuaStatesMutex; std::unordered_map>> mEvents; 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);