aboutsummaryrefslogtreecommitdiff
path: root/libs/bsapacker/src/ModContext.cpp
diff options
context:
space:
mode:
authorSulfurNitride <SulfurNitride@users.noreply.github.com>2026-02-11 02:37:39 -0600
committerSulfurNitride <SulfurNitride@users.noreply.github.com>2026-02-11 02:37:39 -0600
commit7ee008e150bc5bcf76082d726f719ee0fdfda982 (patch)
tree27fb39be241fdb5ac2734c574de678977d1856d0 /libs/bsapacker/src/ModContext.cpp
Fluorine Manager: full Linux port of Mod Organizer 2
Complete native Linux port with FUSE-based virtual filesystem, Proton/umu-run integration, and Flatpak packaging. Key features: - FUSE VFS replacing Windows USVFS (in-process + standalone helper for Flatpak) - Proton/GE-Proton/umu-run launcher with env var forwarding - Flatpak support (sandbox-aware VFS, NXM handler, umu-run) - Wine prefix management UI - Case-insensitive path resolution for Linux filesystems - QSettings-safe INI handling (avoids Bethesda INI corruption) - Portable instance support with auto-generated launcher scripts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'libs/bsapacker/src/ModContext.cpp')
-rw-r--r--libs/bsapacker/src/ModContext.cpp66
1 files changed, 66 insertions, 0 deletions
diff --git a/libs/bsapacker/src/ModContext.cpp b/libs/bsapacker/src/ModContext.cpp
new file mode 100644
index 0000000..896df9b
--- /dev/null
+++ b/libs/bsapacker/src/ModContext.cpp
@@ -0,0 +1,66 @@
+#include "ModContext.h"
+
+#include <array>
+#include <functional>
+#include "iplugingame.h"
+#include "imodinterface.h"
+#include "imodlist.h"
+#include "NexusId.h"
+#include <QtConcurrent/QtConcurrentFilter>
+#include <QtConcurrent/QtConcurrentMap>
+
+namespace BsaPacker
+{
+ const QStringList& ModContext::PLUGIN_TYPES = { "*.esm", "*.esp", "*.esl" };
+
+ ModContext::ModContext(MOBase::IOrganizer *moInfo) : m_Organizer(moInfo)
+ {
+ }
+
+ QString ModContext::GetAbsoluteModPath(const QString &modName) const
+ {
+ const MOBase::IModInterface* const mod = m_Organizer->modList()->getMod(modName);
+ return mod->absolutePath();
+ }
+
+ int ModContext::GetNexusId() const
+ {
+ const MOBase::IPluginGame* managedGame = this->m_Organizer->managedGame();
+ int nexusId = managedGame->nexusGameID();
+
+ // Games with no Nexus page have an ID of 0. Use primarySources in that case
+ if (nexusId != 0) {
+ return nexusId;
+ }
+ if (!managedGame->primarySources().isEmpty()) {
+ QString primarySource = managedGame->primarySources().first();
+ if (primarySource == "FalloutNV") { // TTW
+ return NexusId::NewVegas;
+ }
+ }
+ return nexusId;
+ }
+
+ QStringList ModContext::GetPlugins(const QDir& modDirectory) const
+ {
+ const int nexusId = this->GetNexusId();
+ const QString extension = (nexusId == NexusId::Fallout4 || nexusId == NexusId::Starfield) ? ".ba2" : ".bsa";
+ const std::function<QString(QString)> replace_extension = [&](QString fname) {
+ return fname.replace(fname.lastIndexOf('.'), 4, extension);
+ };
+
+ QStringList filenames = QtConcurrent::blockingMapped(modDirectory.entryList(PLUGIN_TYPES, QDir::Files), replace_extension);
+ filenames.removeDuplicates();
+ return filenames << QStringLiteral("<new filename>") + extension;
+ }
+
+ QStringList ModContext::GetValidMods() const
+ {
+ const MOBase::IModList* const list = m_Organizer->modList();
+ const std::function<bool(const QString&)> modStateValid = [&](const QString& mod)
+ {
+ return !mod.endsWith("_separator", Qt::CaseInsensitive) && (list->state(mod) & MOBase::IModList::STATE_VALID);
+ };
+ return QtConcurrent::blockingFiltered(list->allMods(), modStateValid);
+ }
+} // namespace BsaPacker