#pragma once #include "ipluginsystem.h" class CModAppSystemGroup; class CServer; class CClient; struct user_creds_s; template class CPluginCallbackList { public: CPluginCallbackList() : m_vCallbacks() {} CPluginCallbackList(const vector& cbs) : m_vCallbacks(cbs) {} vector& GetCallbacks() { return m_vCallbacks; } operator bool() { return !this->m_vCallbacks.empty; } vector& operator!() { return this->m_vCallbacks; } CPluginCallbackList& operator+=(const T& rhs) { if (rhs) this->m_vCallbacks.push_back(rhs); return *this; } CPluginCallbackList& operator+=(const vector& rhs) { for (auto it : rhs) { if (it) this->m_vCallbacks.push_back(it); } return *this; } CPluginCallbackList& operator-=(const T& rhs) { if (rhs) { auto it = std::find(m_vCallbacks.begin(), m_vCallbacks.end(), rhs); if (it != m_vCallbacks.end()) m_vCallbacks.erase(it); } return *this; } CPluginCallbackList& operator-=(const vector& rhs) { for (auto itc : rhs) { if (itc) { auto it = std::find(m_vCallbacks.begin(), m_vCallbacks.end(), itc); if (it != m_vCallbacks.end()) m_vCallbacks.erase(it); } } return *this; } private: vector m_vCallbacks; }; class CPluginSystem : IPluginSystem { public: struct PluginInstance_t { PluginInstance_t(string svPluginName, string svPluginFullPath) : m_svPluginName(svPluginName), m_svPluginFullPath(svPluginFullPath), m_svDescription(std::string()), m_bIsLoaded(false) {}; // Might wanna make a status code system. typedef bool(*OnLoad)(const char*, const char*); typedef void(*OnUnload)(); CModule m_hModule; string m_svPluginName; string m_svPluginFullPath; string m_svDescription; bool m_bIsLoaded; // [ PIXIE ]: I don't like this and it's bad. // I will make a module manager later which will grab all modules from the process and adds each module / removes module that passes through DLLMain. }; void PluginSystem_Init(); bool ReloadPluginInstance(PluginInstance_t& pluginInst); bool LoadPluginInstance(PluginInstance_t& pluginInst); bool UnloadPluginInstance(PluginInstance_t& pluginInst); void AddPluginCallback(PluginHelpWithAnything_t* help); void RemovePluginCallback(PluginHelpWithAnything_t* help); vector& GetPluginInstances(); virtual void* HelpWithAnything(PluginHelpWithAnything_t* help); #define CREATE_PLUGIN_CALLBACK(typeName, type, funcName, varName) public: using typeName = type; CPluginCallbackList& funcName() { return varName; } private: CPluginCallbackList varName; CREATE_PLUGIN_CALLBACK(CreateFn, bool(*)(CModAppSystemGroup*), GetCreateCallbacks, createCallbacks); CREATE_PLUGIN_CALLBACK(ConnectClientFn, bool(*)(CServer*, CClient*, user_creds_s*), GetConnectClientCallbacks, connectClientCallbacks); #undef CREATE_PLUGIN_CALLBACK private: vector pluginInstances; }; extern CPluginSystem* g_pPluginSystem; // Monitor this and performance profile this if fps drops are detected. #define CALL_PLUGIN_CALLBACKS(callback, ...) \ for (auto& cb : !callback) \ cb(__VA_ARGS__)