aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NorthstarDedicatedTest/dllmain.cpp1
-rw-r--r--NorthstarDedicatedTest/keyvalues.cpp3
-rw-r--r--NorthstarDedicatedTest/modmanager.cpp45
-rw-r--r--NorthstarDedicatedTest/modmanager.h6
-rw-r--r--NorthstarDedicatedTest/scriptmodmenu.cpp39
-rw-r--r--NorthstarDedicatedTest/scriptsrson.cpp3
-rw-r--r--NorthstarDedicatedTest/squirrel.cpp18
-rw-r--r--NorthstarDedicatedTest/squirrel.h4
8 files changed, 117 insertions, 2 deletions
diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp
index 684f968e..7bf1c091 100644
--- a/NorthstarDedicatedTest/dllmain.cpp
+++ b/NorthstarDedicatedTest/dllmain.cpp
@@ -2,6 +2,7 @@
#include "hooks.h"
#include "main.h"
#include "squirrel.h"
+#include "tier0.h"
#include "dedicated.h"
#include "dedicatedmaterialsystem.h"
#include "sourceconsole.h"
diff --git a/NorthstarDedicatedTest/keyvalues.cpp b/NorthstarDedicatedTest/keyvalues.cpp
index 3d527e62..3bf4ff48 100644
--- a/NorthstarDedicatedTest/keyvalues.cpp
+++ b/NorthstarDedicatedTest/keyvalues.cpp
@@ -52,6 +52,9 @@ void ModManager::TryBuildKeyValues(const char* filename)
// note: #include should be identical but it's actually just broken, thanks respawn
for (int i = m_loadedMods.size() - 1; i > -1; i--)
{
+ if (!m_loadedMods[i]->Enabled)
+ continue;
+
size_t fileHash = std::hash<std::string>{}(normalisedPath);
for (int j = 0; j < m_loadedMods[i]->KeyValuesHash.size(); j++)
{
diff --git a/NorthstarDedicatedTest/modmanager.cpp b/NorthstarDedicatedTest/modmanager.cpp
index f5deed1a..b561c03b 100644
--- a/NorthstarDedicatedTest/modmanager.cpp
+++ b/NorthstarDedicatedTest/modmanager.cpp
@@ -5,6 +5,8 @@
#include "rapidjson/error/en.h"
#include "rapidjson/document.h"
+#include "rapidjson/ostreamwrapper.h"
+#include "rapidjson/writer.h"
#include <filesystem>
#include <fstream>
#include <string>
@@ -184,13 +186,32 @@ ModManager::ModManager()
void ModManager::LoadMods()
{
- UnloadMods();
+ if (m_hasLoadedMods)
+ UnloadMods();
+
+ m_hasLoadedMods = true;
std::vector<fs::path> modDirs;
// ensure dirs exist
+ fs::remove_all(COMPILED_ASSETS_PATH);
fs::create_directories(MOD_FOLDER_PATH);
+ // read enabled mods cfg
+ std::ifstream enabledModsStream("R2Northstar/enabledmods.json");
+ std::stringstream enabledModsStringStream;
+
+ if (!enabledModsStream.fail())
+ {
+ while (enabledModsStream.peek() != EOF)
+ enabledModsStringStream << (char)enabledModsStream.get();
+
+ enabledModsStream.close();
+ m_enabledModsCfg.Parse<rapidjson::ParseFlag::kParseCommentsFlag | rapidjson::ParseFlag::kParseTrailingCommasFlag>(enabledModsStringStream.str().c_str());
+
+ m_hasEnabledModsCfg = m_enabledModsCfg.IsObject();
+ }
+
// get mod directories
for (fs::directory_entry dir : fs::directory_iterator(MOD_FOLDER_PATH))
if (fs::exists(dir.path() / "mod.json"))
@@ -216,6 +237,11 @@ void ModManager::LoadMods()
Mod* mod = new Mod(modDir, (char*)jsonStringStream.str().c_str());
+ if (m_hasEnabledModsCfg && m_enabledModsCfg.HasMember(mod->Name.c_str()))
+ mod->Enabled = m_enabledModsCfg[mod->Name.c_str()].IsTrue();
+ else
+ mod->Enabled = true;
+
if (mod->wasReadSuccessfully)
{
spdlog::info("Loaded mod {} successfully", mod->Name);
@@ -311,6 +337,9 @@ void ModManager::UnloadMods()
m_modFiles.clear();
fs::remove_all(COMPILED_ASSETS_PATH);
+ if (!m_hasEnabledModsCfg)
+ m_enabledModsCfg.SetObject();
+
for (Mod* mod : m_loadedMods)
{
// remove all built kvs
@@ -319,8 +348,19 @@ void ModManager::UnloadMods()
mod->KeyValuesHash.clear();
mod->KeyValues.clear();
+
+ // write to m_enabledModsCfg
+ if (!m_enabledModsCfg.HasMember(mod->Name.c_str()))
+ m_enabledModsCfg.AddMember(rapidjson::StringRef(mod->Name.c_str()), rapidjson::Value(false), m_enabledModsCfg.GetAllocator());
+
+ m_enabledModsCfg[mod->Name.c_str()].SetBool(mod->Enabled);
}
+ std::ofstream writeStream("R2Northstar/enabledmods.json");
+ rapidjson::OStreamWrapper writeStreamWrapper(writeStream);
+ rapidjson::Writer<rapidjson::OStreamWrapper> writer(writeStreamWrapper);
+ m_enabledModsCfg.Accept(writer);
+
// do we need to dealloc individual entries in m_loadedMods? idk, rework
m_loadedMods.clear();
}
@@ -336,6 +376,9 @@ void ModManager::CompileAssetsForFile(const char* filename)
// check if we should build keyvalues, depending on whether any of our mods have patch kvs for this file
for (Mod* mod : m_loadedMods)
{
+ if (!mod->Enabled)
+ continue;
+
size_t fileHash = std::hash<std::string>{}(fs::path(filename).lexically_normal().string());
if (std::find(mod->KeyValuesHash.begin(), mod->KeyValuesHash.end(), fileHash) != mod->KeyValuesHash.end())
{
diff --git a/NorthstarDedicatedTest/modmanager.h b/NorthstarDedicatedTest/modmanager.h
index 079e1613..03160dd8 100644
--- a/NorthstarDedicatedTest/modmanager.h
+++ b/NorthstarDedicatedTest/modmanager.h
@@ -3,6 +3,7 @@
#include <string>
#include <vector>
#include <filesystem>
+#include "rapidjson/document.h"
namespace fs = std::filesystem;
@@ -96,6 +97,11 @@ public:
class ModManager
{
+private:
+ bool m_hasLoadedMods = false;
+ bool m_hasEnabledModsCfg;
+ rapidjson::Document m_enabledModsCfg;
+
public:
std::vector<Mod*> m_loadedMods;
std::unordered_map<std::string, ModOverrideFile*> m_modFiles;
diff --git a/NorthstarDedicatedTest/scriptmodmenu.cpp b/NorthstarDedicatedTest/scriptmodmenu.cpp
index ca7d047d..74319f56 100644
--- a/NorthstarDedicatedTest/scriptmodmenu.cpp
+++ b/NorthstarDedicatedTest/scriptmodmenu.cpp
@@ -18,6 +18,43 @@ SQInteger SQ_GetModNames(void* sqvm)
return 1;
}
+// bool NSIsModEnabled(string modName)
+SQInteger SQ_IsModEnabled(void* sqvm)
+{
+ const SQChar* modName = ClientSq_getstring(sqvm, 1);
+
+ // manual lookup, not super performant but eh not a big deal
+ for (Mod* mod : g_ModManager->m_loadedMods)
+ {
+ if (!mod->Name.compare(modName))
+ {
+ ClientSq_pushbool(sqvm, mod->Enabled);
+ return 1;
+ }
+ }
+
+ return 0; // return null
+}
+
+// void NSSetModEnabled(string modName, bool enabled)
+SQInteger SQ_SetModEnabled(void* sqvm)
+{
+ const SQChar* modName = ClientSq_getstring(sqvm, 1);
+ const SQBool enabled = ClientSq_getbool(sqvm, 2);
+
+ // manual lookup, not super performant but eh not a big deal
+ for (Mod* mod : g_ModManager->m_loadedMods)
+ {
+ if (!mod->Name.compare(modName))
+ {
+ mod->Enabled = enabled;
+ return 0; // return null
+ }
+ }
+
+ return 0; // return null
+}
+
// string NSGetModDescriptionByModName(string modName)
SQInteger SQ_GetModDescription(void* sqvm)
{
@@ -127,6 +164,8 @@ void InitialiseScriptModMenu(HMODULE baseAddress)
return;
g_UISquirrelManager->AddFuncRegistration("array<string>", "NSGetModNames", "", "Returns the names of all loaded mods", SQ_GetModNames);
+ g_UISquirrelManager->AddFuncRegistration("bool", "NSIsModEnabled", "string modName", "Returns whether a given mod is enabled", SQ_IsModEnabled);
+ g_UISquirrelManager->AddFuncRegistration("void", "NSSetModEnabled", "string modName, bool enabled", "Sets whether a given mod is enabled", SQ_SetModEnabled);
g_UISquirrelManager->AddFuncRegistration("string", "NSGetModDescriptionByModName", "string modName", "Returns a given mod's description", SQ_GetModDescription);
g_UISquirrelManager->AddFuncRegistration("string", "NSGetModVersionByModName", "string modName", "Returns a given mod's version", SQ_GetModVersion);
g_UISquirrelManager->AddFuncRegistration("string", "NSGetModDownloadLinkByModName", "string modName", "Returns a given mod's download link", SQ_GetModDownloadLink);
diff --git a/NorthstarDedicatedTest/scriptsrson.cpp b/NorthstarDedicatedTest/scriptsrson.cpp
index bc49ed26..514d4f1c 100644
--- a/NorthstarDedicatedTest/scriptsrson.cpp
+++ b/NorthstarDedicatedTest/scriptsrson.cpp
@@ -19,6 +19,9 @@ void ModManager::BuildScriptsRson()
for (Mod* mod : m_loadedMods)
{
+ if (!mod->Enabled)
+ continue;
+
// this isn't needed at all, just nice to have imo
scriptsRson += "// MOD: ";
scriptsRson += mod->Name;
diff --git a/NorthstarDedicatedTest/squirrel.cpp b/NorthstarDedicatedTest/squirrel.cpp
index 85e26c45..dfeb1805 100644
--- a/NorthstarDedicatedTest/squirrel.cpp
+++ b/NorthstarDedicatedTest/squirrel.cpp
@@ -81,6 +81,9 @@ sq_getintegerType ServerSq_getinteger;
sq_getfloatType ClientSq_getfloat;
sq_getfloatType ServerSq_getfloat;
+sq_getboolType ClientSq_getbool;
+sq_getboolType ServerSq_getbool;
+
template<Context context> void ExecuteCodeCommand(const CCommand& args);
@@ -130,6 +133,7 @@ void InitialiseClientSquirrel(HMODULE baseAddress)
ClientSq_getstring = (sq_getstringType)((char*)baseAddress + 0x60C0);
ClientSq_getinteger = (sq_getintegerType)((char*)baseAddress + 0x60E0);
ClientSq_getfloat = (sq_getfloatType)((char*)baseAddress + 0x6100);
+ ClientSq_getbool = (sq_getboolType)((char*)baseAddress + 0x6130);
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x26130, &CreateNewVMHook<CLIENT>, reinterpret_cast<LPVOID*>(&ClientCreateNewVM)); // client createnewvm function
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x26E70, &DestroyVMHook<CLIENT>, reinterpret_cast<LPVOID*>(&ClientDestroyVM)); // client destroyvm function
@@ -140,7 +144,6 @@ void InitialiseClientSquirrel(HMODULE baseAddress)
void InitialiseServerSquirrel(HMODULE baseAddress)
{
g_ServerSquirrelManager = new SquirrelManager<SERVER>();
- g_ServerSquirrelManager->AddFuncRegistration("void", "SavePdataForEntityIndex", "int i", "idk", NSTestFunc);
HookEnabler hook;
@@ -160,6 +163,7 @@ void InitialiseServerSquirrel(HMODULE baseAddress)
ServerSq_getstring = (sq_getstringType)((char*)baseAddress + 0x60A0);
ServerSq_getinteger = (sq_getintegerType)((char*)baseAddress + 0x60C0);
ServerSq_getfloat = (sq_getfloatType)((char*)baseAddress + 0x60E0);
+ ServerSq_getbool = (sq_getboolType)((char*)baseAddress + 0x6110);
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1FE90, &SQPrintHook<SERVER>, reinterpret_cast<LPVOID*>(&ServerSQPrint)); // server print function
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x260E0, &CreateNewVMHook<SERVER>, reinterpret_cast<LPVOID*>(&ServerCreateNewVM)); // server createnewvm function
@@ -280,6 +284,9 @@ template<Context context> char CallScriptInitCallbackHook(void* sqvm, const char
{
for (Mod* mod : g_ModManager->m_loadedMods)
{
+ if (!mod->Enabled)
+ continue;
+
for (ModScript* script : mod->Scripts)
{
for (ModScriptCallback* modCallback : script->Callbacks)
@@ -304,6 +311,9 @@ template<Context context> char CallScriptInitCallbackHook(void* sqvm, const char
{
for (Mod* mod : g_ModManager->m_loadedMods)
{
+ if (!mod->Enabled)
+ continue;
+
for (ModScript* script : mod->Scripts)
{
for (ModScriptCallback* modCallback : script->Callbacks)
@@ -329,6 +339,9 @@ template<Context context> char CallScriptInitCallbackHook(void* sqvm, const char
{
for (Mod* mod : g_ModManager->m_loadedMods)
{
+ if (!mod->Enabled)
+ continue;
+
for (ModScript* script : mod->Scripts)
{
for (ModScriptCallback* modCallback : script->Callbacks)
@@ -353,6 +366,9 @@ template<Context context> char CallScriptInitCallbackHook(void* sqvm, const char
{
for (Mod* mod : g_ModManager->m_loadedMods)
{
+ if (!mod->Enabled)
+ continue;
+
for (ModScript* script : mod->Scripts)
{
for (ModScriptCallback* modCallback : script->Callbacks)
diff --git a/NorthstarDedicatedTest/squirrel.h b/NorthstarDedicatedTest/squirrel.h
index 66abcd76..5ccab090 100644
--- a/NorthstarDedicatedTest/squirrel.h
+++ b/NorthstarDedicatedTest/squirrel.h
@@ -114,6 +114,10 @@ typedef SQFloat(*sq_getfloatType)(void*, SQInteger stackpos);
extern sq_getfloatType ClientSq_getfloat;
extern sq_getfloatType ServerSq_getfloat;
+typedef SQBool(*sq_getboolType)(void*, SQInteger stackpos);
+extern sq_getboolType ClientSq_getbool;
+extern sq_getboolType ServerSq_getbool;
+
template<Context context> class SquirrelManager
{