aboutsummaryrefslogtreecommitdiff
path: root/primedev/mods
diff options
context:
space:
mode:
Diffstat (limited to 'primedev/mods')
-rw-r--r--primedev/mods/modmanager.cpp49
-rw-r--r--primedev/mods/modmanager.h29
2 files changed, 63 insertions, 15 deletions
diff --git a/primedev/mods/modmanager.cpp b/primedev/mods/modmanager.cpp
index a3e0a5f5..52fc6e8b 100644
--- a/primedev/mods/modmanager.cpp
+++ b/primedev/mods/modmanager.cpp
@@ -866,7 +866,9 @@ void ModManager::LoadMods()
if (fs::is_regular_file(file) && file.path().extension() == ".rpak")
{
std::string pakName(file.path().filename().string());
- ModRpakEntry& modPak = mod.Rpaks.emplace_back();
+ ModRpakEntry& modPak = mod.Rpaks.emplace_back(mod);
+
+ modPak.m_pakName = pakName;
if (!bUseRpakJson)
{
@@ -874,19 +876,47 @@ void ModManager::LoadMods()
}
else
{
- modPak.m_bAutoLoad =
+ modPak.m_preload =
(dRpakJson.HasMember("Preload") && dRpakJson["Preload"].IsObject() && dRpakJson["Preload"].HasMember(pakName) &&
dRpakJson["Preload"][pakName].IsTrue());
+ // only one load method can be used for an rpak.
+ if (modPak.m_preload)
+ goto REGISTER_STARPAK;
+
// postload things
if (dRpakJson.HasMember("Postload") && dRpakJson["Postload"].IsObject() && dRpakJson["Postload"].HasMember(pakName))
{
- modPak.m_sLoadAfterPak = dRpakJson["Postload"][pakName].GetString();
+ modPak.m_dependentPakHash = STR_HASH(dRpakJson["Postload"][pakName].GetString());
+
+ // only one load method can be used for an rpak.
+ goto REGISTER_STARPAK;
}
- }
- modPak.m_sPakName = pakName;
+ // this is the only bit of rpak.json that isn't really deprecated. Even so, it will be moved over to the mod.json
+ // eventually
+ if (dRpakJson.HasMember(pakName))
+ {
+ if (!dRpakJson[pakName].IsString())
+ {
+ spdlog::error("Mod {} has invalid rpak.json. Rpak entries must be strings.", mod.Name);
+ continue;
+ }
+
+ std::string loadStr = dRpakJson[pakName].GetString();
+ try
+ {
+ modPak.m_loadRegex = std::regex(loadStr);
+ }
+ catch (...)
+ {
+ spdlog::error("Mod {} has invalid rpak.json. Malformed regex \"{}\" for {}", mod.Name, loadStr, pakName);
+ return;
+ }
+ }
+ }
+ REGISTER_STARPAK:
// read header of file and get the starpak paths
// this is done here as opposed to on starpak load because multiple rpaks can load a starpak
// and there is seemingly no good way to tell which rpak is causing the load of a starpak :/
@@ -926,12 +956,11 @@ void ModManager::LoadMods()
}
}
}
-
- // not using atm because we need to resolve path to rpak
- // if (m_hasLoadedMods && modPak.m_bAutoLoad)
- // g_pPakLoadManager->LoadPakAsync(pakName.c_str());
}
}
+
+ if (g_pPakLoadManager != nullptr)
+ g_pPakLoadManager->TrackModPaks(mod);
}
// read keyvalues paths
@@ -1059,6 +1088,8 @@ void ModManager::UnloadMods()
fs::remove_all(GetCompiledAssetsPath());
g_CustomAudioManager.ClearAudioOverrides();
+ if (g_pPakLoadManager != nullptr)
+ g_pPakLoadManager->UnloadAllModPaks();
if (!m_bHasEnabledModsCfg)
m_EnabledModsCfg.SetObject();
diff --git a/primedev/mods/modmanager.h b/primedev/mods/modmanager.h
index 95a8fe12..7859d618 100644
--- a/primedev/mods/modmanager.h
+++ b/primedev/mods/modmanager.h
@@ -8,6 +8,7 @@
#include <vector>
#include <filesystem>
#include <unordered_set>
+#include <regex>
namespace fs = std::filesystem;
@@ -19,6 +20,8 @@ const std::string COMPILED_ASSETS_SUFFIX = "\\runtime\\compiled";
const std::set<std::string> MODS_BLACKLIST = {"Mod Settings"};
+class Mod;
+
struct ModConVar
{
public:
@@ -71,9 +74,22 @@ public:
struct ModRpakEntry
{
public:
- bool m_bAutoLoad;
- std::string m_sPakName;
- std::string m_sLoadAfterPak;
+ ModRpakEntry(Mod& parent)
+ : m_parent(parent)
+ , m_loadRegex("^thisMatchesNothing^") // discord couldnt give me a funny string
+ {
+ }
+
+ Mod& m_parent;
+ std::string m_pakName;
+ std::regex m_loadRegex;
+
+ // these exist purely for backwards compatibility, i don't really like them anymore
+
+ // Preload, loads before the first rpak is loaded
+ bool m_preload = false;
+ // Postload, this rpak depends on an rpak with this hash
+ size_t m_dependentPakHash;
};
class Mod
@@ -120,11 +136,12 @@ public:
std::string Pdiff; // only need one per 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
- std::vector<size_t> StarpakPaths; // starpaks that this mod contains
+ // paks we alias to other rpaks, e.g. to load sp_crashsite paks on the map mp_crashsite
+ std::unordered_map<std::string, std::string> RpakAliases;
+ // starpaks that this mod contains
// there seems to be no nice way to get the rpak that is causing the load of a starpak?
// hashed with STR_HASH
+ std::vector<size_t> StarpakPaths;
std::unordered_map<std::string, std::string> DependencyConstants;
std::vector<std::string> PluginDependencyConstants;