From 55a620aa4d10c433e39c9e58773865dc2b71eabf Mon Sep 17 00:00:00 2001 From: Marvin D <41352111+IcePixelx@users.noreply.github.com> Date: Sat, 20 Aug 2022 01:59:36 +0200 Subject: [PATCH] CPluginSystem init, for native mods. * Not finished yet. * Need to make a proper ModuleManager * Handle PluginSystem_Reload() --- r5dev/pluginsystem/pluginsystem.cpp | 116 ++++++++++++++++++++++++++ r5dev/pluginsystem/pluginsystem.h | 34 ++++++++ r5dev/public/utility/module.cpp | 2 +- r5dev/vproj/clientsdk.vcxproj | 2 + r5dev/vproj/clientsdk.vcxproj.filters | 9 ++ r5dev/vproj/dedicated.vcxproj | 2 + r5dev/vproj/dedicated.vcxproj.filters | 9 ++ r5dev/vproj/gamesdk.vcxproj | 2 + r5dev/vproj/gamesdk.vcxproj.filters | 9 ++ 9 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 r5dev/pluginsystem/pluginsystem.cpp create mode 100644 r5dev/pluginsystem/pluginsystem.h diff --git a/r5dev/pluginsystem/pluginsystem.cpp b/r5dev/pluginsystem/pluginsystem.cpp new file mode 100644 index 00000000..5f22ccbd --- /dev/null +++ b/r5dev/pluginsystem/pluginsystem.cpp @@ -0,0 +1,116 @@ +//=============================================================================// +// +// Purpose: Manager that manages Plugins! +// +//----------------------------------------------------------------------------- +// +//=============================================================================// + +#include "core/stdafx.h" +#include "pluginsystem.h" + +//----------------------------------------------------------------------------- +// Purpose: initialize the plugin system +// Input : +//----------------------------------------------------------------------------- +void CPluginSystem::PluginSystem_Init() +{ + CreateDirectories("bin\\x64_plugins\\."); + + for (auto& it : fs::directory_iterator("bin\\x64_plugins")) + { + if (!it.is_regular_file()) + continue; + + if (auto path = it.path(); path.has_filename() && path.has_extension() && path.extension().compare(".dll") == 0) + { + pluginInstances.push_back(PluginInstance(path.filename().u8string(), path.u8string())); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: reload the plugin system +// Input : +//----------------------------------------------------------------------------- +void CPluginSystem::PluginSystem_Reload() +{ + +} + +//----------------------------------------------------------------------------- +// Purpose: load a plugin instance +// Input : pluginInst* - +// Output : bool +//----------------------------------------------------------------------------- +bool CPluginSystem::LoadPluginInstance(PluginInstance& pluginInst) +{ + if (pluginInst.m_bIsLoaded) // Ugh need to make proper module manager. + return false; + + HMODULE loadedPlugin = LoadLibraryA(pluginInst.m_svPluginFullPath.c_str()); + if (!loadedPlugin) + return false; + + pluginInst.m_hModule = CModule(pluginInst.m_svPluginName); + + auto onLoadFn = pluginInst.m_hModule.GetExportedFunction("PluginInstance_OnLoad").RCast(); + if (!onLoadFn) + return false; + + onLoadFn(pluginInst.m_hModule, g_GameDll); + + auto getVersFn = pluginInst.m_hModule.GetExportedFunction("PluginInstance_GetVersion").RCast(); + if (getVersFn) + pluginInst.m_nVersion = getVersFn(); + + auto getDescFn = pluginInst.m_hModule.GetExportedFunction("PluginInstance_GetDescription").RCast(); + if (getDescFn) + pluginInst.m_svDescription = getDescFn(); + + return pluginInst.m_bIsLoaded = true; // Change this sooooooon. +} + +//----------------------------------------------------------------------------- +// Purpose: unload a plugin instance +// Input : pluginInst* - +// Output : bool +//----------------------------------------------------------------------------- +bool CPluginSystem::UnloadPluginInstance(PluginInstance& pluginInst) +{ + if (!pluginInst.m_bIsLoaded) + return false; + + if (!pluginInst.m_hModule.GetModuleBase()) + return false; + + auto onUnloadFn = pluginInst.m_hModule.GetExportedFunction("PluginInstance_OnUnload").RCast(); + if (onUnloadFn) + onUnloadFn(g_GameDll); + + bool unloadOk = FreeLibrary((HMODULE)pluginInst.m_hModule.GetModuleBase()); + if (unloadOk) + pluginInst.m_bIsLoaded = false; + + return unloadOk; +} + +//----------------------------------------------------------------------------- +// Purpose: reload a plugin instance +// Input : pluginInst* - +// Output : bool +//----------------------------------------------------------------------------- +bool CPluginSystem::ReloadPluginInstance(PluginInstance& pluginInst) +{ + return UnloadPluginInstance(pluginInst) ? LoadPluginInstance(pluginInst) : false; +} + +//----------------------------------------------------------------------------- +// Purpose: get all plugin instances +// Input : +// Output : vector& +//----------------------------------------------------------------------------- +vector& CPluginSystem::GetPluginInstances() +{ + return pluginInstances; +} \ No newline at end of file diff --git a/r5dev/pluginsystem/pluginsystem.h b/r5dev/pluginsystem/pluginsystem.h new file mode 100644 index 00000000..ec9c3ad2 --- /dev/null +++ b/r5dev/pluginsystem/pluginsystem.h @@ -0,0 +1,34 @@ +#pragma once + +class CPluginSystem +{ +public: + struct PluginInstance + { + PluginInstance(string svPluginName, string svPluginFullPath) : m_svPluginName(svPluginName), m_svPluginFullPath(svPluginFullPath), m_svDescription(std::string()), m_nVersion(0), m_hModule(""), m_bIsLoaded(false) {}; + + // Might wanna make a status code system. + typedef void(*OnLoad)(CModule, CModule); + typedef void(*OnUnload)(CModule); + typedef int16_t (*GetVersion)(); + typedef const char* (*GetDescription)(); + + CModule m_hModule; + string m_svPluginName; + string m_svPluginFullPath; + string m_svDescription; + int16_t m_nVersion; + 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 processand adds each module / removes module that passes through DLLMain. + }; + + void PluginSystem_Init(); + void PluginSystem_Reload(); + bool ReloadPluginInstance(PluginInstance& pluginInst); + bool LoadPluginInstance(PluginInstance& pluginInst); + bool UnloadPluginInstance(PluginInstance& pluginInst); + vector& GetPluginInstances(); + +private: + vector pluginInstances; +}; diff --git a/r5dev/public/utility/module.cpp b/r5dev/public/utility/module.cpp index dfea50c6..a51d7a48 100644 --- a/r5dev/public/utility/module.cpp +++ b/r5dev/public/utility/module.cpp @@ -118,7 +118,7 @@ CMemory CModule::FindPatternSIMD(const uint8_t* szPattern, const char* szMask, c //----------------------------------------------------------------------------- // Purpose: find array of bytes in process memory using SIMD instructions -// Input : *szPattern +// Input : *svPattern // Output : CMemory //----------------------------------------------------------------------------- CMemory CModule::FindPatternSIMD(const string& svPattern, const ModuleSections_t& moduleSection) const diff --git a/r5dev/vproj/clientsdk.vcxproj b/r5dev/vproj/clientsdk.vcxproj index b71de9d4..0a072fb1 100644 --- a/r5dev/vproj/clientsdk.vcxproj +++ b/r5dev/vproj/clientsdk.vcxproj @@ -79,6 +79,7 @@ + NotUsing NotUsing @@ -236,6 +237,7 @@ + diff --git a/r5dev/vproj/clientsdk.vcxproj.filters b/r5dev/vproj/clientsdk.vcxproj.filters index 302c518a..18c57184 100644 --- a/r5dev/vproj/clientsdk.vcxproj.filters +++ b/r5dev/vproj/clientsdk.vcxproj.filters @@ -220,6 +220,9 @@ {91e5c68f-327d-446c-840d-5e7a53d9a631} + + {b22e88ea-1ee0-4431-82a4-e877a6798f23} + @@ -585,6 +588,9 @@ sdk\tier0 + + sdk\pluginsystem + @@ -1739,6 +1745,9 @@ sdk\tier0 + + sdk\pluginsystem + diff --git a/r5dev/vproj/dedicated.vcxproj b/r5dev/vproj/dedicated.vcxproj index 80c60ae9..15a5b672 100644 --- a/r5dev/vproj/dedicated.vcxproj +++ b/r5dev/vproj/dedicated.vcxproj @@ -209,6 +209,7 @@ + @@ -531,6 +532,7 @@ + NotUsing NotUsing diff --git a/r5dev/vproj/dedicated.vcxproj.filters b/r5dev/vproj/dedicated.vcxproj.filters index 426ad0ba..223b3c1c 100644 --- a/r5dev/vproj/dedicated.vcxproj.filters +++ b/r5dev/vproj/dedicated.vcxproj.filters @@ -193,6 +193,9 @@ {e0155821-8fb2-4fb6-aa6a-d3e6d980b64c} + + {d0650f0e-6359-4322-82c2-97f2e40f141f} + @@ -1239,6 +1242,9 @@ sdk\tier0 + + sdk\pluginsystem + @@ -1550,6 +1556,9 @@ sdk\tier0 + + sdk\pluginsystem + diff --git a/r5dev/vproj/gamesdk.vcxproj b/r5dev/vproj/gamesdk.vcxproj index 7a8ae3e1..8d4a163c 100644 --- a/r5dev/vproj/gamesdk.vcxproj +++ b/r5dev/vproj/gamesdk.vcxproj @@ -87,6 +87,7 @@ + NotUsing NotUsing @@ -260,6 +261,7 @@ + diff --git a/r5dev/vproj/gamesdk.vcxproj.filters b/r5dev/vproj/gamesdk.vcxproj.filters index 5436d58a..c8398480 100644 --- a/r5dev/vproj/gamesdk.vcxproj.filters +++ b/r5dev/vproj/gamesdk.vcxproj.filters @@ -229,6 +229,9 @@ {2828835b-d972-4793-83f7-8eb1741b78ba} + + {cd7b0538-e28c-4181-9e19-588f77d41d36} + @@ -624,6 +627,9 @@ sdk\engine + + sdk\pluginsystem + @@ -1826,6 +1832,9 @@ sdk\public + + sdk\pluginsystem +