aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEladNLG <e1lad8955@gmail.com>2022-07-10 18:22:59 +0300
committerGitHub <noreply@github.com>2022-07-10 16:22:59 +0100
commit85635ad99dbdfa909341e4138f6fdb0c9bf73bf1 (patch)
tree03a9198f9be9edc3496b3a72510987373369125e
parent151d678453f3e321fcccf2512e6e2f53436f1469 (diff)
downloadNorthstarLauncher-85635ad99dbdfa909341e4138f6fdb0c9bf73bf1.tar.gz
NorthstarLauncher-85635ad99dbdfa909341e4138f6fdb0c9bf73bf1.zip
Add dependency constants (#156)v1.9.1-rc4v1.9.1-rc3v1.9.1-rc2v1.9.1
* Fix duplicate script in scripts.rson when 2 mods add a custom script with the same path Allow mods to force a VPK to load through vpk.json * Remove unnecessary print * Fix match predicate using the value instead of the name * - Add a dependency constant system for use in compile flags - Remove the duplicate script engine error fix - Add ClientSq_defconst & ServerSq_defconst * Format fix * - Fix access violation - Separate dependency constants into mod and add checks for conflicts * - Remove unnecessary comment * Remove VPK loading for now and allow 2 mods to use the same constant if the mod names match * Fix bugs * fix mistake * fix keyvalues not working with modded files * simplify code * Fix formatting * Remove keyvalues fix
-rw-r--r--NorthstarDedicatedTest/modmanager.cpp34
-rw-r--r--NorthstarDedicatedTest/modmanager.h6
-rw-r--r--NorthstarDedicatedTest/squirrel.cpp7
-rw-r--r--NorthstarDedicatedTest/squirrel.h21
4 files changed, 68 insertions, 0 deletions
diff --git a/NorthstarDedicatedTest/modmanager.cpp b/NorthstarDedicatedTest/modmanager.cpp
index 9de1c7b1..de45bd23 100644
--- a/NorthstarDedicatedTest/modmanager.cpp
+++ b/NorthstarDedicatedTest/modmanager.cpp
@@ -186,6 +186,26 @@ Mod::Mod(fs::path modDir, char* jsonBuf)
}
}
+ if (modJson.HasMember("Dependencies") && modJson["Dependencies"].IsObject())
+ {
+ for (auto v = modJson["Dependencies"].MemberBegin(); v != modJson["Dependencies"].MemberEnd(); v++)
+ {
+ if (!v->name.IsString() || !v->value.IsString())
+ continue;
+
+ spdlog::info("Constant {} defined by {} for mod {}", v->name.GetString(), Name, v->value.GetString());
+ if (DependencyConstants.find(v->name.GetString()) != DependencyConstants.end() &&
+ v->value.GetString() != DependencyConstants[v->name.GetString()])
+ {
+ spdlog::error("A dependency constant with the same name already exists for another mod. Change the constant name.");
+ return;
+ }
+
+ if (DependencyConstants.find(v->name.GetString()) == DependencyConstants.end())
+ DependencyConstants.emplace(v->name.GetString(), v->value.GetString());
+ }
+ }
+
wasReadSuccessfully = true;
}
@@ -212,6 +232,8 @@ void ModManager::LoadMods()
fs::remove_all(GetCompiledAssetsPath());
fs::create_directories(GetModFolderPath());
+ DependencyConstants.clear();
+
// read enabled mods cfg
std::ifstream enabledModsStream(GetNorthstarPrefix() + "/enabledmods.json");
std::stringstream enabledModsStringStream;
@@ -253,6 +275,18 @@ void ModManager::LoadMods()
Mod mod(modDir, (char*)jsonStringStream.str().c_str());
+ for (auto& pair : mod.DependencyConstants)
+ {
+ if (DependencyConstants.find(pair.first) != DependencyConstants.end() && DependencyConstants[pair.first] != pair.second)
+ {
+ spdlog::error("Constant {} in mod {} already exists in another mod.", pair.first, mod.Name);
+ mod.wasReadSuccessfully = false;
+ break;
+ }
+ if (DependencyConstants.find(pair.first) == DependencyConstants.end())
+ DependencyConstants.emplace(pair);
+ }
+
if (m_hasEnabledModsCfg && m_enabledModsCfg.HasMember(mod.Name.c_str()))
mod.Enabled = m_enabledModsCfg[mod.Name.c_str()].IsTrue();
else
diff --git a/NorthstarDedicatedTest/modmanager.h b/NorthstarDedicatedTest/modmanager.h
index 00c0384a..d605eec2 100644
--- a/NorthstarDedicatedTest/modmanager.h
+++ b/NorthstarDedicatedTest/modmanager.h
@@ -100,6 +100,9 @@ class Mod
std::vector<ModRpakEntry> Rpaks;
std::unordered_map<std::string, std::string>
RpakAliases; // paks we alias to other rpaks, e.g. to load sp_crashsite paks on the map mp_crashsite
+ // iterated over to create squirrel VM constants depending if a mod exists or not.
+ // this only exists because we cannot access g_ModManager whilst mods are being loaded for the first time for some reason.
+ std::unordered_map<std::string, std::string> DependencyConstants;
// other stuff
@@ -130,6 +133,9 @@ class ModManager
public:
std::vector<Mod> m_loadedMods;
std::unordered_map<std::string, ModOverrideFile> m_modFiles;
+ // iterated over to create squirrel VM constants depending if a mod exists or not.
+ // here because constants are global anyways.
+ std::unordered_map<std::string, std::string> DependencyConstants;
public:
ModManager();
diff --git a/NorthstarDedicatedTest/squirrel.cpp b/NorthstarDedicatedTest/squirrel.cpp
index d0d54a3a..a0680d9a 100644
--- a/NorthstarDedicatedTest/squirrel.cpp
+++ b/NorthstarDedicatedTest/squirrel.cpp
@@ -72,6 +72,9 @@ sq_pushboolType ServerSq_pushbool;
sq_pusherrorType ClientSq_pusherror;
sq_pusherrorType ServerSq_pusherror;
+sq_defconst ClientSq_defconst;
+sq_defconst ServerSq_defconst;
+
sq_pushAssetType ClientSq_pushAsset;
sq_pushAssetType ServerSq_pushAsset;
@@ -148,6 +151,8 @@ void InitialiseClientSquirrel(HMODULE baseAddress)
ClientSq_sq_get = (sq_getType)((char*)baseAddress + 0x7C30);
+ ClientSq_defconst = (sq_defconst)((char*)baseAddress + 0x12120);
+
ENABLER_CREATEHOOK(
hook,
(char*)baseAddress + 0x26130,
@@ -203,6 +208,8 @@ void InitialiseServerSquirrel(HMODULE baseAddress)
ServerSq_sq_get = (sq_getType)((char*)baseAddress + 0x7C00);
+ ServerSq_defconst = (sq_defconst)((char*)baseAddress + 0x1F550);
+
ENABLER_CREATEHOOK(
hook,
(char*)baseAddress + 0x1FE90,
diff --git a/NorthstarDedicatedTest/squirrel.h b/NorthstarDedicatedTest/squirrel.h
index cbdf0c8c..0e49c7f8 100644
--- a/NorthstarDedicatedTest/squirrel.h
+++ b/NorthstarDedicatedTest/squirrel.h
@@ -1,3 +1,4 @@
+#include <../modmanager.h>
#pragma once
void InitialiseClientSquirrel(HMODULE baseAddress);
@@ -121,6 +122,10 @@ typedef SQInteger (*sq_pusherrorType)(void* sqvm, const SQChar* error);
extern sq_pusherrorType ClientSq_pusherror;
extern sq_pusherrorType ServerSq_pusherror;
+typedef void (*sq_defconst)(void* sqvm, const SQChar* name, int value);
+extern sq_defconst ClientSq_defconst;
+extern sq_defconst ServerSq_defconst;
+
typedef SQRESULT (*sq_pushAssetType)(void* sqvm, const SQChar* assetName, SQInteger nameLength);
extern sq_pushAssetType ServerSq_pushAsset;
extern sq_pushAssetType ClientSq_pushAsset;
@@ -172,6 +177,22 @@ template <ScriptContext context> class SquirrelManager
else
ServerRegisterSquirrelFunc(sqvm, funcReg, 1);
}
+ for (auto& pair : g_ModManager->DependencyConstants)
+ {
+ bool wasFound = false;
+ for (Mod& dependency : g_ModManager->m_loadedMods)
+ {
+ if (dependency.Name == pair.second)
+ {
+ wasFound = dependency.Enabled;
+ break;
+ }
+ }
+ if (context == ScriptContext::SERVER)
+ ServerSq_defconst(sqvm, pair.first.c_str(), wasFound);
+ else
+ ClientSq_defconst(sqvm, pair.first.c_str(), wasFound);
+ }
}
void VMDestroyed()