From 43f0bce0596ec60434e48d8037ffed373bc13852 Mon Sep 17 00:00:00 2001 From: cat_or_not <41955154+catornot@users.noreply.github.com> Date: Thu, 14 Dec 2023 07:07:02 -0500 Subject: Add plugin dependency constants (#458) Adds dependency constants for plugins so mods can rely on plugins without always producing script errors when the plugin is missing --- NorthstarDLL/mods/modmanager.cpp | 28 ++++++++++++++++++++++++++++ NorthstarDLL/mods/modmanager.h | 4 ++++ NorthstarDLL/plugins/plugins.cpp | 9 +++++++++ NorthstarDLL/squirrel/squirrel.cpp | 7 +++++++ 4 files changed, 48 insertions(+) (limited to 'NorthstarDLL') diff --git a/NorthstarDLL/mods/modmanager.cpp b/NorthstarDLL/mods/modmanager.cpp index b7194d04..982f5068 100644 --- a/NorthstarDLL/mods/modmanager.cpp +++ b/NorthstarDLL/mods/modmanager.cpp @@ -104,6 +104,7 @@ Mod::Mod(fs::path modDir, char* jsonBuf) ParseScripts(modJson); ParseLocalization(modJson); ParseDependencies(modJson); + ParsePluginDependencies(modJson); ParseInitScript(modJson); // A mod is remote if it's located in the remote mods folder @@ -483,6 +484,28 @@ void Mod::ParseDependencies(rapidjson_document& json) } } +void Mod::ParsePluginDependencies(rapidjson_document& json) +{ + if (!json.HasMember("PluginDependencies")) + return; + + if (!json["PluginDependencies"].IsArray()) + { + spdlog::warn("'PluginDependencies' field is not an object, skipping..."); + return; + } + + for (auto& name : json["PluginDependencies"].GetArray()) + { + if (!name.IsString()) + continue; + + spdlog::info("Plugin Constant {} defined by {}", name.GetString(), Name); + + PluginDependencyConstants.push_back(name.GetString()); + } +} + void Mod::ParseInitScript(rapidjson_document& json) { if (!json.HasMember("InitScript")) @@ -688,6 +711,11 @@ void ModManager::LoadMods() m_DependencyConstants.emplace(pair); } + for (std::string& dependency : mod.PluginDependencyConstants) + { + m_PluginDependencyConstants.insert(dependency); + } + if (m_bHasEnabledModsCfg && m_EnabledModsCfg.HasMember(mod.Name.c_str())) mod.m_bEnabled = m_EnabledModsCfg[mod.Name.c_str()].IsTrue(); else diff --git a/NorthstarDLL/mods/modmanager.h b/NorthstarDLL/mods/modmanager.h index 813edec7..c141414f 100644 --- a/NorthstarDLL/mods/modmanager.h +++ b/NorthstarDLL/mods/modmanager.h @@ -7,6 +7,7 @@ #include #include #include +#include const std::string MOD_FOLDER_SUFFIX = "\\mods"; const std::string THUNDERSTORE_MOD_FOLDER_SUFFIX = "\\packages"; @@ -124,6 +125,7 @@ class Mod // hashed with STR_HASH std::unordered_map DependencyConstants; + std::vector PluginDependencyConstants; public: Mod(fs::path modPath, char* jsonBuf); @@ -134,6 +136,7 @@ class Mod void ParseScripts(rapidjson_document& json); void ParseLocalization(rapidjson_document& json); void ParseDependencies(rapidjson_document& json); + void ParsePluginDependencies(rapidjson_document& json); void ParseInitScript(rapidjson_document& json); }; @@ -160,6 +163,7 @@ class ModManager std::vector m_LoadedMods; std::unordered_map m_ModFiles; std::unordered_map m_DependencyConstants; + std::unordered_set m_PluginDependencyConstants; public: ModManager(); diff --git a/NorthstarDLL/plugins/plugins.cpp b/NorthstarDLL/plugins/plugins.cpp index d8087e5c..72b64566 100644 --- a/NorthstarDLL/plugins/plugins.cpp +++ b/NorthstarDLL/plugins/plugins.cpp @@ -170,6 +170,15 @@ std::optional PluginManager::LoadPlugin(fs::path path, PluginInitFuncs* plugin.dependencyName = plugin.name; } + if (std::find_if( + plugin.dependencyName.begin(), + plugin.dependencyName.end(), + [&](char c) -> bool { return !((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_'); }) != + plugin.dependencyName.end()) + { + NS::log::PLUGINSYS->warn("Dependency string \"{}\" in {} is not valid a squirrel constant!", plugin.dependencyName, plugin.name); + } + plugin.init_sqvm_client = (PLUGIN_INIT_SQVM_TYPE)GetProcAddress(pluginLib, "PLUGIN_INIT_SQVM_CLIENT"); plugin.init_sqvm_server = (PLUGIN_INIT_SQVM_TYPE)GetProcAddress(pluginLib, "PLUGIN_INIT_SQVM_SERVER"); plugin.inform_sqvm_created = (PLUGIN_INFORM_SQVM_CREATED_TYPE)GetProcAddress(pluginLib, "PLUGIN_INFORM_SQVM_CREATED"); diff --git a/NorthstarDLL/squirrel/squirrel.cpp b/NorthstarDLL/squirrel/squirrel.cpp index 68fffb9b..d8eff0d6 100644 --- a/NorthstarDLL/squirrel/squirrel.cpp +++ b/NorthstarDLL/squirrel/squirrel.cpp @@ -264,6 +264,13 @@ template void SquirrelManager::VMCreated(CSquir defconst(m_pSQVM, pair.first.c_str(), bWasFound); } + auto loadedPlugins = &g_pPluginManager->m_vLoadedPlugins; + for (const auto& pluginName : g_pModManager->m_PluginDependencyConstants) + { + auto f = [&](Plugin plugin) -> bool { return plugin.dependencyName == pluginName; }; + defconst(m_pSQVM, pluginName.c_str(), std::find_if(loadedPlugins->begin(), loadedPlugins->end(), f) != loadedPlugins->end()); + } + defconst(m_pSQVM, "MAX_FOLDER_SIZE", GetMaxSaveFolderSize() / 1024); // define squirrel constants for northstar(.dll) version -- cgit v1.2.3