From 9e1dee23b62d5db1953c0e93dc475eee07842b00 Mon Sep 17 00:00:00 2001 From: Alystrasz Date: Sat, 4 Feb 2023 18:35:56 +0100 Subject: [PATCH 01/18] feat: display a warning message if no mod.json file was found in mod directory --- NorthstarDLL/mods/modmanager.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/NorthstarDLL/mods/modmanager.cpp b/NorthstarDLL/mods/modmanager.cpp index 38966236d..a71fea970 100644 --- a/NorthstarDLL/mods/modmanager.cpp +++ b/NorthstarDLL/mods/modmanager.cpp @@ -17,6 +17,7 @@ #include #include #include +#include ModManager* g_pModManager; @@ -382,6 +383,17 @@ void ModManager::LoadMods() for (fs::directory_entry dir : modIterator) if (fs::exists(dir.path() / "mod.json")) modDirs.push_back(dir.path()); + else + { + spdlog::warn("Directory {} has no mod.json file.", dir.path().generic_string().c_str()); + std::string errorMessage = std::format( + "The directory {} does not contain a mod.json file.\nMake sure you correctly installed it.", + dir.path().generic_string().c_str()); + MessageBoxA( + GetForegroundWindow(), errorMessage.c_str(), + "Badly formatted mod", + 0); + } for (fs::path modDir : modDirs) { From e9059abc7a524614b852589ad311cee2c0b22067 Mon Sep 17 00:00:00 2001 From: Alystrasz Date: Sun, 5 Feb 2023 00:17:54 +0100 Subject: [PATCH 02/18] feat: don't display error messages with hidden directories (hello Gecko) --- NorthstarDLL/mods/modmanager.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/NorthstarDLL/mods/modmanager.cpp b/NorthstarDLL/mods/modmanager.cpp index a71fea970..97da142b4 100644 --- a/NorthstarDLL/mods/modmanager.cpp +++ b/NorthstarDLL/mods/modmanager.cpp @@ -381,19 +381,23 @@ void ModManager::LoadMods() for (std::filesystem::directory_iterator modIterator : {classicModsDir, remoteModsDir}) for (fs::directory_entry dir : modIterator) + { if (fs::exists(dir.path() / "mod.json")) modDirs.push_back(dir.path()); else { + std::string filename = dir.path().filename().generic_string().c_str(); + // Don't display an error for hidden directories + if (filename.at(0) == '.') + continue; + spdlog::warn("Directory {} has no mod.json file.", dir.path().generic_string().c_str()); std::string errorMessage = std::format( "The directory {} does not contain a mod.json file.\nMake sure you correctly installed it.", dir.path().generic_string().c_str()); - MessageBoxA( - GetForegroundWindow(), errorMessage.c_str(), - "Badly formatted mod", - 0); + MessageBoxA(GetForegroundWindow(), errorMessage.c_str(), "Badly formatted mod", 0); } + } for (fs::path modDir : modDirs) { From f5e816cd884b45e7549634fb3c73f1a090555412 Mon Sep 17 00:00:00 2001 From: Alystrasz Date: Sun, 5 Feb 2023 00:24:13 +0100 Subject: [PATCH 03/18] refactor: remove useless import --- NorthstarDLL/mods/modmanager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/NorthstarDLL/mods/modmanager.cpp b/NorthstarDLL/mods/modmanager.cpp index 97da142b4..16cee8220 100644 --- a/NorthstarDLL/mods/modmanager.cpp +++ b/NorthstarDLL/mods/modmanager.cpp @@ -17,7 +17,6 @@ #include #include #include -#include ModManager* g_pModManager; From c0e44c9936bf90483d536426cb079f6e1eb6459b Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Sun, 5 Feb 2023 21:44:06 +0100 Subject: [PATCH 04/18] fix: display error message when mod.json is located at the wrong location --- NorthstarDLL/mods/modmanager.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/NorthstarDLL/mods/modmanager.cpp b/NorthstarDLL/mods/modmanager.cpp index 16cee8220..01887a50c 100644 --- a/NorthstarDLL/mods/modmanager.cpp +++ b/NorthstarDLL/mods/modmanager.cpp @@ -383,18 +383,28 @@ void ModManager::LoadMods() { if (fs::exists(dir.path() / "mod.json")) modDirs.push_back(dir.path()); - else + else if (fs::is_directory(dir.path())) { std::string filename = dir.path().filename().generic_string().c_str(); // Don't display an error for hidden directories if (filename.at(0) == '.') continue; - spdlog::warn("Directory {} has no mod.json file.", dir.path().generic_string().c_str()); - std::string errorMessage = std::format( - "The directory {} does not contain a mod.json file.\nMake sure you correctly installed it.", - dir.path().generic_string().c_str()); - MessageBoxA(GetForegroundWindow(), errorMessage.c_str(), "Badly formatted mod", 0); + for (fs::directory_entry subdir : fs::recursive_directory_iterator(dir.path())) + if (fs::exists(subdir.path() / "mod.json")) + { + spdlog::warn( + "mod.json file for directory {} is located at the wrong location ({}).", + dir.path().generic_string().c_str(), + subdir.path().generic_string().c_str()); + std::string errorMessage = std::format( + "The folder {} does contain a mod.json file, but not at the correct location.\n\nExpected: {}\nFound: {}\n\nMake sure you correctly installed it.", + dir.path().filename().generic_string(), + dir.path().generic_string().append("/mod.json"), + subdir.path().generic_string().append("/mod.json") + ); + MessageBoxA(GetForegroundWindow(), errorMessage.c_str(), "Badly formatted mod", 0); + } } } From d200783af4c40fed3d62604394ea7bf5df1b3abe Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Sun, 5 Feb 2023 21:44:27 +0100 Subject: [PATCH 05/18] style: format --- NorthstarDLL/mods/modmanager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NorthstarDLL/mods/modmanager.cpp b/NorthstarDLL/mods/modmanager.cpp index 01887a50c..28a72f014 100644 --- a/NorthstarDLL/mods/modmanager.cpp +++ b/NorthstarDLL/mods/modmanager.cpp @@ -398,11 +398,11 @@ void ModManager::LoadMods() dir.path().generic_string().c_str(), subdir.path().generic_string().c_str()); std::string errorMessage = std::format( - "The folder {} does contain a mod.json file, but not at the correct location.\n\nExpected: {}\nFound: {}\n\nMake sure you correctly installed it.", + "The folder {} does contain a mod.json file, but not at the correct location.\n\nExpected: {}\nFound: " + "{}\n\nMake sure you correctly installed it.", dir.path().filename().generic_string(), dir.path().generic_string().append("/mod.json"), - subdir.path().generic_string().append("/mod.json") - ); + subdir.path().generic_string().append("/mod.json")); MessageBoxA(GetForegroundWindow(), errorMessage.c_str(), "Badly formatted mod", 0); } } From 8b2ebf3907ef610889661f8cf00524cf84986c55 Mon Sep 17 00:00:00 2001 From: uniboi Date: Sun, 26 Feb 2023 12:42:03 +0100 Subject: [PATCH 06/18] expose incorrect installs to UI and fix typing --- NorthstarDLL/mods/modmanager.cpp | 10 +++---- NorthstarDLL/mods/modmanager.h | 1 + NorthstarDLL/scripts/client/scriptmodmenu.cpp | 26 ++++++++++++++----- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/NorthstarDLL/mods/modmanager.cpp b/NorthstarDLL/mods/modmanager.cpp index c772e7214..d9e5d3bcb 100644 --- a/NorthstarDLL/mods/modmanager.cpp +++ b/NorthstarDLL/mods/modmanager.cpp @@ -386,6 +386,8 @@ void ModManager::LoadMods() std::filesystem::directory_iterator classicModsDir = fs::directory_iterator(GetModFolderPath()); std::filesystem::directory_iterator remoteModsDir = fs::directory_iterator(GetRemoteModFolderPath()); + this->m_invalidMods.clear(); + for (std::filesystem::directory_iterator modIterator : {classicModsDir, remoteModsDir}) for (fs::directory_entry dir : modIterator) { @@ -405,13 +407,7 @@ void ModManager::LoadMods() "mod.json file for directory {} is located at the wrong location ({}).", dir.path().generic_string().c_str(), subdir.path().generic_string().c_str()); - std::string errorMessage = std::format( - "The folder {} does contain a mod.json file, but not at the correct location.\n\nExpected: {}\nFound: " - "{}\n\nMake sure you correctly installed it.", - dir.path().filename().generic_string(), - dir.path().generic_string().append("/mod.json"), - subdir.path().generic_string().append("/mod.json")); - MessageBoxA(GetForegroundWindow(), errorMessage.c_str(), "Badly formatted mod", 0); + this->m_invalidMods.push_back(dir.path().generic_string().c_str()); } } } diff --git a/NorthstarDLL/mods/modmanager.h b/NorthstarDLL/mods/modmanager.h index 369eb07be..7d356e24e 100644 --- a/NorthstarDLL/mods/modmanager.h +++ b/NorthstarDLL/mods/modmanager.h @@ -147,6 +147,7 @@ class ModManager std::vector m_LoadedMods; std::unordered_map m_ModFiles; std::unordered_map m_DependencyConstants; + std::vector m_invalidMods; public: ModManager(); diff --git a/NorthstarDLL/scripts/client/scriptmodmenu.cpp b/NorthstarDLL/scripts/client/scriptmodmenu.cpp index a88478fb7..7bb60744d 100644 --- a/NorthstarDLL/scripts/client/scriptmodmenu.cpp +++ b/NorthstarDLL/scripts/client/scriptmodmenu.cpp @@ -28,7 +28,8 @@ ADD_SQFUNC("bool", NSIsModEnabled, "string modName", "", ScriptContext::SERVER | } } - return SQRESULT_NULL; + g_pSquirrel->pushbool(sqvm, false); + return SQRESULT_NOTNULL; } ADD_SQFUNC("void", NSSetModEnabled, "string modName, bool enabled", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) @@ -49,7 +50,7 @@ ADD_SQFUNC("void", NSSetModEnabled, "string modName, bool enabled", "", ScriptCo return SQRESULT_NULL; } -ADD_SQFUNC("string", NSGetModDescriptionByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +ADD_SQFUNC("string ornull", NSGetModDescriptionByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); @@ -66,7 +67,7 @@ ADD_SQFUNC("string", NSGetModDescriptionByModName, "string modName", "", ScriptC return SQRESULT_NULL; } -ADD_SQFUNC("string", NSGetModVersionByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +ADD_SQFUNC("string ornull", NSGetModVersionByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); @@ -83,7 +84,7 @@ ADD_SQFUNC("string", NSGetModVersionByModName, "string modName", "", ScriptConte return SQRESULT_NULL; } -ADD_SQFUNC("string", NSGetModDownloadLinkByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +ADD_SQFUNC("string ornull", NSGetModDownloadLinkByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); @@ -100,7 +101,7 @@ ADD_SQFUNC("string", NSGetModDownloadLinkByModName, "string modName", "", Script return SQRESULT_NULL; } -ADD_SQFUNC("int", NSGetModLoadPriority, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +ADD_SQFUNC("int ornull", NSGetModLoadPriority, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); @@ -117,7 +118,7 @@ ADD_SQFUNC("int", NSGetModLoadPriority, "string modName", "", ScriptContext::SER return SQRESULT_NULL; } -ADD_SQFUNC("bool", NSIsModRequiredOnClient, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +ADD_SQFUNC("bool ornull", NSIsModRequiredOnClient, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); @@ -163,3 +164,16 @@ ADD_SQFUNC("void", NSReloadMods, "", "", ScriptContext::UI) g_pModManager->LoadMods(); return SQRESULT_NULL; } + +ADD_SQFUNC("array", NSGetInvalidMods, "", "", ScriptContext::UI) +{ + g_pSquirrel->newarray(sqvm, 0); + + for (std::string path : g_pModManager->m_invalidMods) + { + g_pSquirrel->pushstring(sqvm, path.c_str()); + g_pSquirrel->arrayappend(sqvm, -2); + } + + return SQRESULT_NOTNULL; +} From d107ee8db5feffc9b7e07d002319e461229e0820 Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Sun, 26 Feb 2023 22:59:43 +0100 Subject: [PATCH 07/18] style: format --- NorthstarDLL/scripts/client/scriptmodmenu.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/NorthstarDLL/scripts/client/scriptmodmenu.cpp b/NorthstarDLL/scripts/client/scriptmodmenu.cpp index 7bb60744d..f100de102 100644 --- a/NorthstarDLL/scripts/client/scriptmodmenu.cpp +++ b/NorthstarDLL/scripts/client/scriptmodmenu.cpp @@ -50,7 +50,8 @@ ADD_SQFUNC("void", NSSetModEnabled, "string modName, bool enabled", "", ScriptCo return SQRESULT_NULL; } -ADD_SQFUNC("string ornull", NSGetModDescriptionByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +ADD_SQFUNC( + "string ornull", NSGetModDescriptionByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); @@ -67,7 +68,8 @@ ADD_SQFUNC("string ornull", NSGetModDescriptionByModName, "string modName", "", return SQRESULT_NULL; } -ADD_SQFUNC("string ornull", NSGetModVersionByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +ADD_SQFUNC( + "string ornull", NSGetModVersionByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); @@ -84,7 +86,8 @@ ADD_SQFUNC("string ornull", NSGetModVersionByModName, "string modName", "", Scri return SQRESULT_NULL; } -ADD_SQFUNC("string ornull", NSGetModDownloadLinkByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +ADD_SQFUNC( + "string ornull", NSGetModDownloadLinkByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); From 364da35e7e11c69b932ff795c42be1ca886edfa2 Mon Sep 17 00:00:00 2001 From: uniboi Date: Mon, 3 Apr 2023 17:48:00 +0200 Subject: [PATCH 08/18] include path and mod name in sq api --- NorthstarDLL/mods/modmanager.cpp | 18 ++++++++++++++++-- NorthstarDLL/mods/modmanager.h | 2 +- NorthstarDLL/scripts/client/scriptmodmenu.cpp | 14 +++++++++++--- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/NorthstarDLL/mods/modmanager.cpp b/NorthstarDLL/mods/modmanager.cpp index d9e5d3bcb..6108e09b5 100644 --- a/NorthstarDLL/mods/modmanager.cpp +++ b/NorthstarDLL/mods/modmanager.cpp @@ -401,14 +401,28 @@ void ModManager::LoadMods() continue; for (fs::directory_entry subdir : fs::recursive_directory_iterator(dir.path())) - if (fs::exists(subdir.path() / "mod.json")) + { + fs::path modPath = subdir.path() / "mod.json"; + if (fs::exists(modPath)) { spdlog::warn( "mod.json file for directory {} is located at the wrong location ({}).", dir.path().generic_string().c_str(), subdir.path().generic_string().c_str()); - this->m_invalidMods.push_back(dir.path().generic_string().c_str()); + + // read mod json file + std::ifstream jsonStream(modPath); + std::stringstream jsonStringStream; + + while (jsonStream.peek() != EOF) + jsonStringStream << (char)jsonStream.get(); + + jsonStream.close(); + std::shared_ptr mod = std::shared_ptr(new Mod(subdir, (char*)jsonStringStream.str().c_str())); + + this->m_invalidMods.push_back(mod); } + } } } diff --git a/NorthstarDLL/mods/modmanager.h b/NorthstarDLL/mods/modmanager.h index 7d356e24e..55206fa41 100644 --- a/NorthstarDLL/mods/modmanager.h +++ b/NorthstarDLL/mods/modmanager.h @@ -147,7 +147,7 @@ class ModManager std::vector m_LoadedMods; std::unordered_map m_ModFiles; std::unordered_map m_DependencyConstants; - std::vector m_invalidMods; + std::vector> m_invalidMods; public: ModManager(); diff --git a/NorthstarDLL/scripts/client/scriptmodmenu.cpp b/NorthstarDLL/scripts/client/scriptmodmenu.cpp index f100de102..e52e2955f 100644 --- a/NorthstarDLL/scripts/client/scriptmodmenu.cpp +++ b/NorthstarDLL/scripts/client/scriptmodmenu.cpp @@ -168,13 +168,21 @@ ADD_SQFUNC("void", NSReloadMods, "", "", ScriptContext::UI) return SQRESULT_NULL; } -ADD_SQFUNC("array", NSGetInvalidMods, "", "", ScriptContext::UI) +ADD_SQFUNC("array< table >", NSGetInvalidMods, "", "", ScriptContext::UI) { g_pSquirrel->newarray(sqvm, 0); - for (std::string path : g_pModManager->m_invalidMods) + for (std::shared_ptr mod : g_pModManager->m_invalidMods) { - g_pSquirrel->pushstring(sqvm, path.c_str()); + g_pSquirrel->newtable(sqvm); + // path slot + g_pSquirrel->pushstring(sqvm, "path"); + g_pSquirrel->pushstring(sqvm, mod->m_ModDirectory.generic_string().c_str()); + g_pSquirrel->newslot(sqvm, -3, false); + // invalid mod name slot + g_pSquirrel->pushstring(sqvm, "name"); + g_pSquirrel->pushstring(sqvm, mod->Name.c_str()); + g_pSquirrel->newslot(sqvm, -3, false); g_pSquirrel->arrayappend(sqvm, -2); } From 42c0888ec129dae5a44140dca992c7e23158d2aa Mon Sep 17 00:00:00 2001 From: uniboi Date: Sun, 7 May 2023 19:19:05 +0200 Subject: [PATCH 09/18] use structs for the script mod menu --- NorthstarDLL/scripts/client/scriptmodmenu.cpp | 197 +++++------------- 1 file changed, 55 insertions(+), 142 deletions(-) diff --git a/NorthstarDLL/scripts/client/scriptmodmenu.cpp b/NorthstarDLL/scripts/client/scriptmodmenu.cpp index e52e2955f..918c65e8b 100644 --- a/NorthstarDLL/scripts/client/scriptmodmenu.cpp +++ b/NorthstarDLL/scripts/client/scriptmodmenu.cpp @@ -1,189 +1,102 @@ #include "mods/modmanager.h" #include "squirrel/squirrel.h" -ADD_SQFUNC("array", NSGetModNames, "", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +template void PushModStruct(HSquirrelVM* sqvm, const Mod& mod, SQInteger index) { - g_pSquirrel->newarray(sqvm, 0); + g_pSquirrel->pushnewstructinstance(sqvm, 10); - for (Mod& mod : g_pModManager->m_LoadedMods) - { - g_pSquirrel->pushstring(sqvm, mod.Name.c_str()); - g_pSquirrel->arrayappend(sqvm, -2); - } + // index + g_pSquirrel->pushinteger(sqvm, index); + g_pSquirrel->sealstructslot(sqvm, 0); - return SQRESULT_NOTNULL; -} + // name + g_pSquirrel->pushstring(sqvm, mod.Name.c_str(), -1); + g_pSquirrel->sealstructslot(sqvm, 1); -ADD_SQFUNC("bool", NSIsModEnabled, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) -{ - const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); + // description + g_pSquirrel->pushstring(sqvm, mod.Description.c_str(), -1); + g_pSquirrel->sealstructslot(sqvm, 2); - // manual lookup, not super performant but eh not a big deal - for (Mod& mod : g_pModManager->m_LoadedMods) - { - if (!mod.Name.compare(modName)) - { - g_pSquirrel->pushbool(sqvm, mod.m_bEnabled); - return SQRESULT_NOTNULL; - } - } + // version + g_pSquirrel->pushstring(sqvm, mod.Version.c_str(), -1); + g_pSquirrel->sealstructslot(sqvm, 3); - g_pSquirrel->pushbool(sqvm, false); - return SQRESULT_NOTNULL; -} + // link + g_pSquirrel->pushstring(sqvm, mod.DownloadLink.c_str(), -1); + g_pSquirrel->sealstructslot(sqvm, 4); -ADD_SQFUNC("void", NSSetModEnabled, "string modName, bool enabled", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) -{ - const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); - const SQBool enabled = g_pSquirrel->getbool(sqvm, 2); + // installLocation + g_pSquirrel->pushstring(sqvm, mod.m_ModDirectory.generic_string().c_str()); + g_pSquirrel->sealstructslot(sqvm, 5); - // manual lookup, not super performant but eh not a big deal - for (Mod& mod : g_pModManager->m_LoadedMods) - { - if (!mod.Name.compare(modName)) - { - mod.m_bEnabled = enabled; - return SQRESULT_NULL; - } - } - - return SQRESULT_NULL; -} - -ADD_SQFUNC( - "string ornull", NSGetModDescriptionByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) -{ - const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); - - // manual lookup, not super performant but eh not a big deal - for (Mod& mod : g_pModManager->m_LoadedMods) - { - if (!mod.Name.compare(modName)) - { - g_pSquirrel->pushstring(sqvm, mod.Description.c_str()); - return SQRESULT_NOTNULL; - } - } + // loadPriority + g_pSquirrel->pushinteger(sqvm, mod.LoadPriority); + g_pSquirrel->sealstructslot(sqvm, 6); - return SQRESULT_NULL; -} + // requiredOnClient + g_pSquirrel->pushbool(sqvm, mod.RequiredOnClient); + g_pSquirrel->sealstructslot(sqvm, 7); -ADD_SQFUNC( - "string ornull", NSGetModVersionByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) -{ - const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); + // enabled + g_pSquirrel->pushbool(sqvm, mod.m_bEnabled); + g_pSquirrel->sealstructslot(sqvm, 8); - // manual lookup, not super performant but eh not a big deal - for (Mod& mod : g_pModManager->m_LoadedMods) + // conVars + g_pSquirrel->newarray(sqvm, 0); + for (ModConVar* conVar : mod.ConVars) { - if (!mod.Name.compare(modName)) - { - g_pSquirrel->pushstring(sqvm, mod.Version.c_str()); - return SQRESULT_NOTNULL; - } + g_pSquirrel->pushstring(sqvm, conVar->Name.c_str()); + g_pSquirrel->arrayappend(sqvm, -2); } + g_pSquirrel->sealstructslot(sqvm, 9); - return SQRESULT_NULL; + g_pSquirrel->arrayappend(sqvm, -2); } -ADD_SQFUNC( - "string ornull", NSGetModDownloadLinkByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +ADD_SQFUNC("void", NSSetModEnabled, "int index, bool enabled", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { - const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); + const int index = g_pSquirrel->getinteger(sqvm, 1); + const SQBool enabled = g_pSquirrel->getbool(sqvm, 2); - // manual lookup, not super performant but eh not a big deal - for (Mod& mod : g_pModManager->m_LoadedMods) + if (index < 0 || index >= g_pModManager->m_LoadedMods.size()) { - if (!mod.Name.compare(modName)) - { - g_pSquirrel->pushstring(sqvm, mod.DownloadLink.c_str()); - return SQRESULT_NOTNULL; - } + spdlog::warn("Tried disabling mod at {} but only {} mods are loaded", index, g_pModManager->m_LoadedMods.size()); + return SQRESULT_ERROR; } - return SQRESULT_NULL; -} - -ADD_SQFUNC("int ornull", NSGetModLoadPriority, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) -{ - const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); - - // manual lookup, not super performant but eh not a big deal - for (Mod& mod : g_pModManager->m_LoadedMods) - { - if (!mod.Name.compare(modName)) - { - g_pSquirrel->pushinteger(sqvm, mod.LoadPriority); - return SQRESULT_NOTNULL; - } - } + g_pModManager->m_LoadedMods[index].m_bEnabled = enabled; return SQRESULT_NULL; } -ADD_SQFUNC("bool ornull", NSIsModRequiredOnClient, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +ADD_SQFUNC("void", NSReloadMods, "", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { - const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); - - // manual lookup, not super performant but eh not a big deal - for (Mod& mod : g_pModManager->m_LoadedMods) - { - if (!mod.Name.compare(modName)) - { - g_pSquirrel->pushbool(sqvm, mod.RequiredOnClient); - return SQRESULT_NOTNULL; - } - } - + g_pModManager->LoadMods(); return SQRESULT_NULL; } -ADD_SQFUNC( - "array", NSGetModConvarsByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +ADD_SQFUNC("array", NSGetInvalidMods, "", "Get all mods that are installed in a subfolder", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { - const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); g_pSquirrel->newarray(sqvm, 0); - // manual lookup, not super performant but eh not a big deal - for (Mod& mod : g_pModManager->m_LoadedMods) + for (auto& invalidMod : g_pModManager->m_invalidMods) { - if (!mod.Name.compare(modName)) - { - for (ModConVar* cvar : mod.ConVars) - { - g_pSquirrel->pushstring(sqvm, cvar->Name.c_str()); - g_pSquirrel->arrayappend(sqvm, -2); - } - - return SQRESULT_NOTNULL; - } + const Mod& mod = *invalidMod.get(); + PushModStruct(sqvm, mod, -1); } - return SQRESULT_NOTNULL; // return empty array -} - -ADD_SQFUNC("void", NSReloadMods, "", "", ScriptContext::UI) -{ - g_pModManager->LoadMods(); - return SQRESULT_NULL; + return SQRESULT_NOTNULL; } -ADD_SQFUNC("array< table >", NSGetInvalidMods, "", "", ScriptContext::UI) +ADD_SQFUNC("array", NSGetMods, "", "Get all installed mods", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { g_pSquirrel->newarray(sqvm, 0); - for (std::shared_ptr mod : g_pModManager->m_invalidMods) + for (SQInteger i = 0; i < g_pModManager->m_LoadedMods.size(); i++) { - g_pSquirrel->newtable(sqvm); - // path slot - g_pSquirrel->pushstring(sqvm, "path"); - g_pSquirrel->pushstring(sqvm, mod->m_ModDirectory.generic_string().c_str()); - g_pSquirrel->newslot(sqvm, -3, false); - // invalid mod name slot - g_pSquirrel->pushstring(sqvm, "name"); - g_pSquirrel->pushstring(sqvm, mod->Name.c_str()); - g_pSquirrel->newslot(sqvm, -3, false); - g_pSquirrel->arrayappend(sqvm, -2); + const Mod& mod = g_pModManager->m_LoadedMods[i]; + + PushModStruct(sqvm, mod, i); } return SQRESULT_NOTNULL; From d0f9b3a347915b40a14af11f60a12847446ee3cb Mon Sep 17 00:00:00 2001 From: uniboi Date: Sun, 7 May 2023 21:21:54 +0200 Subject: [PATCH 10/18] remove duplicate NSGetInvalidMods definition --- NorthstarDLL/scripts/client/scriptmodmenu.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/NorthstarDLL/scripts/client/scriptmodmenu.cpp b/NorthstarDLL/scripts/client/scriptmodmenu.cpp index 472fcc663..918c65e8b 100644 --- a/NorthstarDLL/scripts/client/scriptmodmenu.cpp +++ b/NorthstarDLL/scripts/client/scriptmodmenu.cpp @@ -101,16 +101,3 @@ ADD_SQFUNC("array", NSGetMods, "", "Get all installed mods", ScriptContext: return SQRESULT_NOTNULL; } - -ADD_SQFUNC("array", NSGetInvalidMods, "", "", ScriptContext::UI) -{ - g_pSquirrel->newarray(sqvm, 0); - - for (std::string path : g_pModManager->m_invalidMods) - { - g_pSquirrel->pushstring(sqvm, path.c_str()); - g_pSquirrel->arrayappend(sqvm, -2); - } - - return SQRESULT_NOTNULL; -} From 3b996162572dc90a51cd801297070d227ecf5404 Mon Sep 17 00:00:00 2001 From: uniboi Date: Sun, 7 May 2023 22:47:55 +0200 Subject: [PATCH 11/18] formatting --- NorthstarDLL/scripts/client/scriptmodmenu.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/NorthstarDLL/scripts/client/scriptmodmenu.cpp b/NorthstarDLL/scripts/client/scriptmodmenu.cpp index 918c65e8b..aec8b034d 100644 --- a/NorthstarDLL/scripts/client/scriptmodmenu.cpp +++ b/NorthstarDLL/scripts/client/scriptmodmenu.cpp @@ -75,7 +75,12 @@ ADD_SQFUNC("void", NSReloadMods, "", "", ScriptContext::SERVER | ScriptContext:: return SQRESULT_NULL; } -ADD_SQFUNC("array", NSGetInvalidMods, "", "Get all mods that are installed in a subfolder", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +ADD_SQFUNC( + "array", + NSGetInvalidMods, + "", + "Get all mods that are installed in a subfolder", + ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { g_pSquirrel->newarray(sqvm, 0); From 25847b44dedc639c53fa1d64c7037da16ab78573 Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Sat, 10 Jun 2023 17:24:02 +0200 Subject: [PATCH 12/18] refactor: use `rdbuf` to read mod json file Co-authored-by: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> --- NorthstarDLL/mods/modmanager.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/NorthstarDLL/mods/modmanager.cpp b/NorthstarDLL/mods/modmanager.cpp index 53380941e..5845e4c10 100644 --- a/NorthstarDLL/mods/modmanager.cpp +++ b/NorthstarDLL/mods/modmanager.cpp @@ -421,16 +421,14 @@ void ModManager::LoadMods() "mod.json file for directory {} is located at the wrong location ({}).", dir.path().generic_string().c_str(), subdir.path().generic_string().c_str()); + // read mod json file std::ifstream jsonStream(modPath); std::stringstream jsonStringStream; - - while (jsonStream.peek() != EOF) - jsonStringStream << (char)jsonStream.get(); - + jsonStringStream << jsonStream.rdbuf(); jsonStream.close(); - std::shared_ptr mod = std::shared_ptr(new Mod(subdir, (char*)jsonStringStream.str().c_str())); + std::shared_ptr mod = std::shared_ptr(new Mod(subdir, (char*)jsonStringStream.str().c_str())); this->m_invalidMods.push_back(mod); } } From e398b5cb5a40ed08b0fff20ed78df9dddf51170e Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Mon, 23 Oct 2023 01:12:47 +0200 Subject: [PATCH 13/18] refactor: export manifest location checking to dedicated function --- NorthstarDLL/mods/modmanager.cpp | 55 +++++++++++++++++--------------- NorthstarDLL/mods/modmanager.h | 3 ++ 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/NorthstarDLL/mods/modmanager.cpp b/NorthstarDLL/mods/modmanager.cpp index 85d016989..99de547ae 100644 --- a/NorthstarDLL/mods/modmanager.cpp +++ b/NorthstarDLL/mods/modmanager.cpp @@ -581,6 +581,35 @@ auto ModConCommandCallback(const CCommand& command) }; } +void ModManager::VerifyModManifestLocation(fs::directory_entry modDir) +{ + std::string filename = modDir.path().filename().generic_string().c_str(); + // Don't display an error for hidden directories + if (filename.at(0) == '.') + return; + + for (fs::directory_entry subdir : fs::recursive_directory_iterator(modDir.path())) + { + fs::path modPath = subdir.path() / "mod.json"; + if (fs::exists(modPath)) + { + spdlog::warn( + "mod.json file for directory {} is located at the wrong location ({}).", + modDir.path().generic_string().c_str(), + subdir.path().generic_string().c_str()); + + // read mod json file + std::ifstream jsonStream(modPath); + std::stringstream jsonStringStream; + jsonStringStream << jsonStream.rdbuf(); + jsonStream.close(); + + std::shared_ptr mod = std::shared_ptr(new Mod(subdir, (char*)jsonStringStream.str().c_str())); + this->m_invalidMods.push_back(mod); + } + } +} + void ModManager::LoadMods() { if (m_bHasLoadedMods) @@ -626,31 +655,7 @@ void ModManager::LoadMods() modDirs.push_back(dir.path()); else if (fs::is_directory(dir.path())) { - std::string filename = dir.path().filename().generic_string().c_str(); - // Don't display an error for hidden directories - if (filename.at(0) == '.') - continue; - - for (fs::directory_entry subdir : fs::recursive_directory_iterator(dir.path())) - { - fs::path modPath = subdir.path() / "mod.json"; - if (fs::exists(modPath)) - { - spdlog::warn( - "mod.json file for directory {} is located at the wrong location ({}).", - dir.path().generic_string().c_str(), - subdir.path().generic_string().c_str()); - - // read mod json file - std::ifstream jsonStream(modPath); - std::stringstream jsonStringStream; - jsonStringStream << jsonStream.rdbuf(); - jsonStream.close(); - - std::shared_ptr mod = std::shared_ptr(new Mod(subdir, (char*)jsonStringStream.str().c_str())); - this->m_invalidMods.push_back(mod); - } - } + VerifyModManifestLocation(dir); } } diff --git a/NorthstarDLL/mods/modmanager.h b/NorthstarDLL/mods/modmanager.h index b15a15ef2..3aaffe487 100644 --- a/NorthstarDLL/mods/modmanager.h +++ b/NorthstarDLL/mods/modmanager.h @@ -174,6 +174,9 @@ class ModManager void TryBuildKeyValues(const char* filename); void BuildPdef(); void BuildKBActionsList(); + + private: + void VerifyModManifestLocation(fs::directory_entry modDir); }; fs::path GetModFolderPath(); From 0d6b62491326bbf764bbb5ad32fad5dc8772cb9d Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Mon, 23 Oct 2023 01:17:15 +0200 Subject: [PATCH 14/18] feat: verify mods in packages directory --- NorthstarDLL/mods/modmanager.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NorthstarDLL/mods/modmanager.cpp b/NorthstarDLL/mods/modmanager.cpp index 99de547ae..bc9b2bf24 100644 --- a/NorthstarDLL/mods/modmanager.cpp +++ b/NorthstarDLL/mods/modmanager.cpp @@ -682,6 +682,10 @@ void ModManager::LoadMods() { modDirs.push_back(subDir.path()); } + else + { + VerifyModManifestLocation(subDir); + } } } } From 4ed6c7a466bc220d3a45605de2575f0dd79b9619 Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Mon, 23 Oct 2023 01:21:40 +0200 Subject: [PATCH 15/18] fix: do not iterate classicModsDir twice --- NorthstarDLL/mods/modmanager.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/NorthstarDLL/mods/modmanager.cpp b/NorthstarDLL/mods/modmanager.cpp index bc9b2bf24..dac6b9f62 100644 --- a/NorthstarDLL/mods/modmanager.cpp +++ b/NorthstarDLL/mods/modmanager.cpp @@ -648,16 +648,15 @@ void ModManager::LoadMods() this->m_invalidMods.clear(); - for (std::filesystem::directory_iterator modIterator : {classicModsDir, remoteModsDir}) - for (fs::directory_entry dir : modIterator) + for (fs::directory_entry dir : classicModsDir) + { + if (fs::exists(dir.path() / "mod.json")) + modDirs.push_back(dir.path()); + else if (fs::is_directory(dir.path())) { - if (fs::exists(dir.path() / "mod.json")) - modDirs.push_back(dir.path()); - else if (fs::is_directory(dir.path())) - { - VerifyModManifestLocation(dir); - } + VerifyModManifestLocation(dir); } + } // Special case for Thunderstore and remote mods directories // Set up regex for `AUTHOR-MOD-VERSION` pattern From 31497ab1e8bec15e058747f90ccf2335e090f958 Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Mon, 23 Oct 2023 01:59:03 +0200 Subject: [PATCH 16/18] build: restore scriptmodmenu.cpp to main branch state --- NorthstarDLL/scripts/client/scriptmodmenu.cpp | 181 ++++++++++++------ 1 file changed, 119 insertions(+), 62 deletions(-) diff --git a/NorthstarDLL/scripts/client/scriptmodmenu.cpp b/NorthstarDLL/scripts/client/scriptmodmenu.cpp index aec8b034d..a88478fb7 100644 --- a/NorthstarDLL/scripts/client/scriptmodmenu.cpp +++ b/NorthstarDLL/scripts/client/scriptmodmenu.cpp @@ -1,108 +1,165 @@ #include "mods/modmanager.h" #include "squirrel/squirrel.h" -template void PushModStruct(HSquirrelVM* sqvm, const Mod& mod, SQInteger index) +ADD_SQFUNC("array", NSGetModNames, "", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { - g_pSquirrel->pushnewstructinstance(sqvm, 10); + g_pSquirrel->newarray(sqvm, 0); - // index - g_pSquirrel->pushinteger(sqvm, index); - g_pSquirrel->sealstructslot(sqvm, 0); + for (Mod& mod : g_pModManager->m_LoadedMods) + { + g_pSquirrel->pushstring(sqvm, mod.Name.c_str()); + g_pSquirrel->arrayappend(sqvm, -2); + } - // name - g_pSquirrel->pushstring(sqvm, mod.Name.c_str(), -1); - g_pSquirrel->sealstructslot(sqvm, 1); + return SQRESULT_NOTNULL; +} - // description - g_pSquirrel->pushstring(sqvm, mod.Description.c_str(), -1); - g_pSquirrel->sealstructslot(sqvm, 2); +ADD_SQFUNC("bool", NSIsModEnabled, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +{ + const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); - // version - g_pSquirrel->pushstring(sqvm, mod.Version.c_str(), -1); - g_pSquirrel->sealstructslot(sqvm, 3); + // manual lookup, not super performant but eh not a big deal + for (Mod& mod : g_pModManager->m_LoadedMods) + { + if (!mod.Name.compare(modName)) + { + g_pSquirrel->pushbool(sqvm, mod.m_bEnabled); + return SQRESULT_NOTNULL; + } + } - // link - g_pSquirrel->pushstring(sqvm, mod.DownloadLink.c_str(), -1); - g_pSquirrel->sealstructslot(sqvm, 4); + return SQRESULT_NULL; +} - // installLocation - g_pSquirrel->pushstring(sqvm, mod.m_ModDirectory.generic_string().c_str()); - g_pSquirrel->sealstructslot(sqvm, 5); +ADD_SQFUNC("void", NSSetModEnabled, "string modName, bool enabled", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +{ + const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); + const SQBool enabled = g_pSquirrel->getbool(sqvm, 2); - // loadPriority - g_pSquirrel->pushinteger(sqvm, mod.LoadPriority); - g_pSquirrel->sealstructslot(sqvm, 6); + // manual lookup, not super performant but eh not a big deal + for (Mod& mod : g_pModManager->m_LoadedMods) + { + if (!mod.Name.compare(modName)) + { + mod.m_bEnabled = enabled; + return SQRESULT_NULL; + } + } - // requiredOnClient - g_pSquirrel->pushbool(sqvm, mod.RequiredOnClient); - g_pSquirrel->sealstructslot(sqvm, 7); + return SQRESULT_NULL; +} - // enabled - g_pSquirrel->pushbool(sqvm, mod.m_bEnabled); - g_pSquirrel->sealstructslot(sqvm, 8); +ADD_SQFUNC("string", NSGetModDescriptionByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +{ + const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); - // conVars - g_pSquirrel->newarray(sqvm, 0); - for (ModConVar* conVar : mod.ConVars) + // manual lookup, not super performant but eh not a big deal + for (Mod& mod : g_pModManager->m_LoadedMods) { - g_pSquirrel->pushstring(sqvm, conVar->Name.c_str()); - g_pSquirrel->arrayappend(sqvm, -2); + if (!mod.Name.compare(modName)) + { + g_pSquirrel->pushstring(sqvm, mod.Description.c_str()); + return SQRESULT_NOTNULL; + } } - g_pSquirrel->sealstructslot(sqvm, 9); - g_pSquirrel->arrayappend(sqvm, -2); + return SQRESULT_NULL; } -ADD_SQFUNC("void", NSSetModEnabled, "int index, bool enabled", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +ADD_SQFUNC("string", NSGetModVersionByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { - const int index = g_pSquirrel->getinteger(sqvm, 1); - const SQBool enabled = g_pSquirrel->getbool(sqvm, 2); + const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); - if (index < 0 || index >= g_pModManager->m_LoadedMods.size()) + // manual lookup, not super performant but eh not a big deal + for (Mod& mod : g_pModManager->m_LoadedMods) { - spdlog::warn("Tried disabling mod at {} but only {} mods are loaded", index, g_pModManager->m_LoadedMods.size()); - return SQRESULT_ERROR; + if (!mod.Name.compare(modName)) + { + g_pSquirrel->pushstring(sqvm, mod.Version.c_str()); + return SQRESULT_NOTNULL; + } } - g_pModManager->m_LoadedMods[index].m_bEnabled = enabled; + return SQRESULT_NULL; +} + +ADD_SQFUNC("string", NSGetModDownloadLinkByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +{ + const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); + + // manual lookup, not super performant but eh not a big deal + for (Mod& mod : g_pModManager->m_LoadedMods) + { + if (!mod.Name.compare(modName)) + { + g_pSquirrel->pushstring(sqvm, mod.DownloadLink.c_str()); + return SQRESULT_NOTNULL; + } + } return SQRESULT_NULL; } -ADD_SQFUNC("void", NSReloadMods, "", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +ADD_SQFUNC("int", NSGetModLoadPriority, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { - g_pModManager->LoadMods(); + const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); + + // manual lookup, not super performant but eh not a big deal + for (Mod& mod : g_pModManager->m_LoadedMods) + { + if (!mod.Name.compare(modName)) + { + g_pSquirrel->pushinteger(sqvm, mod.LoadPriority); + return SQRESULT_NOTNULL; + } + } + return SQRESULT_NULL; } -ADD_SQFUNC( - "array", - NSGetInvalidMods, - "", - "Get all mods that are installed in a subfolder", - ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +ADD_SQFUNC("bool", NSIsModRequiredOnClient, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { - g_pSquirrel->newarray(sqvm, 0); + const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); - for (auto& invalidMod : g_pModManager->m_invalidMods) + // manual lookup, not super performant but eh not a big deal + for (Mod& mod : g_pModManager->m_LoadedMods) { - const Mod& mod = *invalidMod.get(); - PushModStruct(sqvm, mod, -1); + if (!mod.Name.compare(modName)) + { + g_pSquirrel->pushbool(sqvm, mod.RequiredOnClient); + return SQRESULT_NOTNULL; + } } - return SQRESULT_NOTNULL; + return SQRESULT_NULL; } -ADD_SQFUNC("array", NSGetMods, "", "Get all installed mods", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +ADD_SQFUNC( + "array", NSGetModConvarsByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { + const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); g_pSquirrel->newarray(sqvm, 0); - for (SQInteger i = 0; i < g_pModManager->m_LoadedMods.size(); i++) + // manual lookup, not super performant but eh not a big deal + for (Mod& mod : g_pModManager->m_LoadedMods) { - const Mod& mod = g_pModManager->m_LoadedMods[i]; - - PushModStruct(sqvm, mod, i); + if (!mod.Name.compare(modName)) + { + for (ModConVar* cvar : mod.ConVars) + { + g_pSquirrel->pushstring(sqvm, cvar->Name.c_str()); + g_pSquirrel->arrayappend(sqvm, -2); + } + + return SQRESULT_NOTNULL; + } } - return SQRESULT_NOTNULL; + return SQRESULT_NOTNULL; // return empty array +} + +ADD_SQFUNC("void", NSReloadMods, "", "", ScriptContext::UI) +{ + g_pModManager->LoadMods(); + return SQRESULT_NULL; } From 31210dea334c7594a82cf93763740443dd37dfdc Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Mon, 23 Oct 2023 01:59:39 +0200 Subject: [PATCH 17/18] fix: make VerifyModManifestLocation abort if input is not a directory --- NorthstarDLL/mods/modmanager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NorthstarDLL/mods/modmanager.cpp b/NorthstarDLL/mods/modmanager.cpp index dac6b9f62..e958b9d7c 100644 --- a/NorthstarDLL/mods/modmanager.cpp +++ b/NorthstarDLL/mods/modmanager.cpp @@ -583,6 +583,11 @@ auto ModConCommandCallback(const CCommand& command) void ModManager::VerifyModManifestLocation(fs::directory_entry modDir) { + if (!fs::is_directory(modDir)) + { + return; + } + std::string filename = modDir.path().filename().generic_string().c_str(); // Don't display an error for hidden directories if (filename.at(0) == '.') From 233054f3d13d71aab9f2d57ca5c1c5588ee2d83a Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Thu, 7 Nov 2024 23:44:22 +0100 Subject: [PATCH 18/18] style: apply clang formatting --- primedev/mods/modmanager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primedev/mods/modmanager.h b/primedev/mods/modmanager.h index a7b203664..83c471066 100644 --- a/primedev/mods/modmanager.h +++ b/primedev/mods/modmanager.h @@ -198,7 +198,7 @@ class ModManager void BuildPdef(); void BuildKBActionsList(); - private: +private: void VerifyModManifestLocation(fs::directory_entry modDir); };