aboutsummaryrefslogtreecommitdiff
path: root/libs/game_features/src
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/game_features/src
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/game_features/src')
-rw-r--r--libs/game_features/src/CMakeLists.txt6
-rw-r--r--libs/game_features/src/bsainvalidation.h24
-rw-r--r--libs/game_features/src/dataarchives.h32
-rw-r--r--libs/game_features/src/gamefeatures.pro25
-rw-r--r--libs/game_features/src/gamefeatures_en.ts4
-rw-r--r--libs/game_features/src/gameplugins.h22
-rw-r--r--libs/game_features/src/localsavegames.h24
-rw-r--r--libs/game_features/src/moddatachecker.h68
-rw-r--r--libs/game_features/src/moddatacontent.h112
-rw-r--r--libs/game_features/src/savegameinfo.h49
-rw-r--r--libs/game_features/src/scriptextender.h41
-rw-r--r--libs/game_features/src/unmanagedmods.h44
12 files changed, 451 insertions, 0 deletions
diff --git a/libs/game_features/src/CMakeLists.txt b/libs/game_features/src/CMakeLists.txt
new file mode 100644
index 0000000..23d6313
--- /dev/null
+++ b/libs/game_features/src/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.16)
+if(DEFINED DEPENDENCIES_DIR)
+ include(${DEPENDENCIES_DIR}/modorganizer_super/cmake_common/src.cmake)
+else()
+ include(../../cmake_common/src.cmake)
+endif() \ No newline at end of file
diff --git a/libs/game_features/src/bsainvalidation.h b/libs/game_features/src/bsainvalidation.h
new file mode 100644
index 0000000..e2c9d9b
--- /dev/null
+++ b/libs/game_features/src/bsainvalidation.h
@@ -0,0 +1,24 @@
+#ifndef BSAINVALIDATION_H
+#define BSAINVALIDATION_H
+
+namespace MOBase { class IProfile; }
+
+class QString;
+
+class BSAInvalidation
+{
+public:
+
+ virtual ~BSAInvalidation() {}
+
+ virtual bool isInvalidationBSA(const QString &bsaName) = 0;
+
+ virtual void deactivate(MOBase::IProfile *profile) = 0;
+
+ virtual void activate(MOBase::IProfile *profile) = 0;
+
+ virtual bool prepareProfile(MOBase::IProfile *profile) = 0;
+
+};
+
+#endif // BSAINVALIDATION_H
diff --git a/libs/game_features/src/dataarchives.h b/libs/game_features/src/dataarchives.h
new file mode 100644
index 0000000..26688ba
--- /dev/null
+++ b/libs/game_features/src/dataarchives.h
@@ -0,0 +1,32 @@
+#ifndef DATAARCHIVES
+#define DATAARCHIVES
+
+namespace MOBase { class IProfile; }
+
+class QString;
+class QStringList;
+
+class DataArchives {
+
+public:
+
+ virtual ~DataArchives() {}
+
+ virtual QStringList vanillaArchives() const = 0;
+
+ virtual QStringList archives(const MOBase::IProfile *profile) const = 0;
+
+ /**
+ * @brief add an archive to the archive list
+ * @param profile the profile for which to change the archive list
+ * @param index index to insert before. 0 is the beginning of the list, INT_MAX can be used for the end of the list
+ * @param archiveName the archive to add
+ */
+ virtual void addArchive(MOBase::IProfile *profile, int index, const QString &archiveName) = 0;
+
+ virtual void removeArchive(MOBase::IProfile *profile, const QString &archiveName) = 0;
+
+};
+
+#endif // DATAARCHIVES
+
diff --git a/libs/game_features/src/gamefeatures.pro b/libs/game_features/src/gamefeatures.pro
new file mode 100644
index 0000000..1af5d6f
--- /dev/null
+++ b/libs/game_features/src/gamefeatures.pro
@@ -0,0 +1,25 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2015-01-25T12:54:57
+#
+#-------------------------------------------------
+
+QT -= gui
+
+TARGET = gamefeatures
+TEMPLATE = lib
+
+CONFIG += staticlib
+
+DEFINES += GAMEFEATURES_LIBRARY
+
+SOURCES +=
+
+HEADERS += \
+ bsainvalidation.h \
+ scriptextender.h \
+ dataarchives.h \
+ savegameinfo.h \
+ localsavegames.h
+
+INCLUDEPATH += $${PWD}/../../uibase
diff --git a/libs/game_features/src/gamefeatures_en.ts b/libs/game_features/src/gamefeatures_en.ts
new file mode 100644
index 0000000..bc6d6e7
--- /dev/null
+++ b/libs/game_features/src/gamefeatures_en.ts
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="en_US">
+</TS>
diff --git a/libs/game_features/src/gameplugins.h b/libs/game_features/src/gameplugins.h
new file mode 100644
index 0000000..37ab112
--- /dev/null
+++ b/libs/game_features/src/gameplugins.h
@@ -0,0 +1,22 @@
+#ifndef GAMEPLUGINS_H
+#define GAMEPLUGINS_H
+
+#include <QStringList>
+
+namespace MOBase {
+ class IPluginList;
+}
+
+
+class GamePlugins {
+
+public:
+
+ virtual void writePluginLists(const MOBase::IPluginList *pluginList) = 0;
+ virtual void readPluginLists(MOBase::IPluginList *pluginList) = 0;
+ virtual QStringList getLoadOrder() = 0;
+ virtual bool lightPluginsAreSupported() = 0;
+
+};
+
+#endif // GAMEPLUGINS_H
diff --git a/libs/game_features/src/localsavegames.h b/libs/game_features/src/localsavegames.h
new file mode 100644
index 0000000..86be073
--- /dev/null
+++ b/libs/game_features/src/localsavegames.h
@@ -0,0 +1,24 @@
+#ifndef LOCALSAVEGAMES_H
+#define LOCALSAVEGAMES_H
+
+
+#include "filemapping.h"
+
+namespace MOBase {
+ class IProfile;
+}
+
+class QDir;
+
+class LocalSavegames {
+
+public:
+
+ virtual ~LocalSavegames() {}
+
+ virtual MappingType mappings(const QDir &profileSaveDir) const = 0;
+ virtual bool prepareProfile(MOBase::IProfile *profile) = 0;
+
+};
+
+#endif // LOCALSAVEGAMES_H
diff --git a/libs/game_features/src/moddatachecker.h b/libs/game_features/src/moddatachecker.h
new file mode 100644
index 0000000..7c4c404
--- /dev/null
+++ b/libs/game_features/src/moddatachecker.h
@@ -0,0 +1,68 @@
+#ifndef MODDATACHECKER_H
+#define MODDATACHECKER_H
+
+#include <memory>
+
+namespace MOBase {
+
+ class IFileTree;
+
+};
+
+class ModDataChecker {
+public:
+
+ /**
+ *
+ */
+ enum class CheckReturn {
+ INVALID,
+ FIXABLE,
+ VALID
+ };
+
+ /**
+ * @brief Check that the given filetree represent a valid mod layout, or can be easily
+ * fixed.
+ *
+ * This method is mainly used during installation (to find which installer should
+ * be used or to recurse into multi-level archives), or to quickly indicates to a
+ * user if a mod looks valid.
+ *
+ * This method does not have to be exact, it only has to indicate if the given tree
+ * looks like a valid mod or not by quickly checking the structure (heavy operations
+ * should be avoided).
+ *
+ * If the tree can be fixed by the `fix()` method, this method should return `FIXABLE`.
+ * `FIXABLE` should only be returned when it is guaranteed that `fix()` can fix the tree.
+ *
+ * @param tree The tree starting at the root of the "data" folder.
+ *
+ * @return whether the tree is invalid, fixable or valid.
+ */
+ virtual CheckReturn dataLooksValid(std::shared_ptr<const MOBase::IFileTree> fileTree) const = 0;
+
+ /**
+ * @brief Try to fix the given tree.
+ *
+ * This method is used during installation to try to fix invalid archives and will only be
+ * called if dataLooksValid returned `FIXABLE`.
+ *
+ * @param tree The tree to try to fix. Can be modified during the process.
+ *
+ * @return the fixed tree, or a null pointer if the tree could not be fixed.
+ */
+ virtual std::shared_ptr<MOBase::IFileTree> fix(std::shared_ptr<MOBase::IFileTree> fileTree) const {
+ return nullptr;
+ }
+
+public:
+
+ /**
+ *
+ */
+ virtual ~ModDataChecker() { }
+
+};
+
+#endif \ No newline at end of file
diff --git a/libs/game_features/src/moddatacontent.h b/libs/game_features/src/moddatacontent.h
new file mode 100644
index 0000000..e17bd66
--- /dev/null
+++ b/libs/game_features/src/moddatacontent.h
@@ -0,0 +1,112 @@
+#ifndef MODDATACONTENT_H
+#define MODDATACONTENT_H
+
+#include <algorithm>
+#include <memory>
+#include <vector>
+
+#include <QString>
+
+namespace MOBase {
+
+ class IFileTree;
+
+};
+
+/**
+ * The ModDataContent feature is used (when available) to indicate to users the content
+ * of mods in the "Content" column.
+ *
+ * The feature exposes a list of possible content types, each associated with an ID, a name
+ * and an icon. The icon is the path to either:
+ * - A Qt resource or;
+ * - A file on the disk.
+ *
+ * In order to facilitate the implementation, MO2 already provides a set of icons that can
+ * be used. Those icons are all under :/MO/gui/content (e.g. :/MO/gui/content/plugin or :/MO/gui/content/music).
+ *
+ * The list of available icons is:
+ * - plugin: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/jigsaw-piece.png
+ * - skyproc: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/hand-of-god.png
+ * - texture: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/empty-chessboard.png
+ * - music: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/double-quaver.png
+ * - sound: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/lyre.png
+ * - interface: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/usable.png
+ * - skse: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/checkbox-tree.png
+ * - script: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/tinker.png
+ * - mesh: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/breastplate.png
+ * - string: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/conversation.png
+ * - bsa: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/locked-chest.png
+ * - menu: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/config.png
+ * - inifile: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/feather-and-scroll.png
+ * - modgroup: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/xedit.png
+ */
+class ModDataContent {
+public:
+
+ struct Content {
+
+ /**
+ * @param id ID of this content.
+ * @param name Name of this content.
+ * @param icon Path to the icon for this content. Can be either a path
+ * to an image on the disk, or to a resource. Can be an empty string if filterOnly
+ * is true.
+ * @param filterOnly Indicates if the content should only be show in the filter
+ * criteria and not in the actual Content column.
+ */
+ Content(int id, QString name, QString icon, bool filterOnly = false) :
+ m_Id{ id }, m_Name{ name }, m_Icon{ icon }, m_FilterOnly{ filterOnly } { }
+
+ /**
+ * @return the ID of this content.
+ */
+ int id() const { return m_Id; }
+
+ /**
+ * @return the name of this content.
+ */
+ QString name() const { return m_Name; }
+
+ /**
+ * @return the path to the icon of this content (can be a Qt resource path).
+ */
+ QString icon() const { return m_Icon; }
+
+ /**
+ * @return true if this content is only meant to be used as a filter criteria.
+ */
+ bool isOnlyForFilter() const { return m_FilterOnly; }
+
+ private:
+
+ int m_Id;
+ QString m_Name;
+ QString m_Icon;
+ bool m_FilterOnly;
+ };
+
+ /**
+ * @return the list of all possible contents for the corresponding game.
+ */
+ virtual std::vector<Content> getAllContents() const = 0;
+
+ /**
+ * @brief Retrieve the list of contents in the given tree.
+ *
+ * @param fileTree The tree corresponding to the mod to retrieve contents for.
+ *
+ * @return the IDs of the content in the given tree.
+ */
+ virtual std::vector<int> getContentsFor(std::shared_ptr<const MOBase::IFileTree> fileTree) const = 0;
+
+public:
+
+ /**
+ *
+ */
+ virtual ~ModDataContent() { }
+
+};
+
+#endif \ No newline at end of file
diff --git a/libs/game_features/src/savegameinfo.h b/libs/game_features/src/savegameinfo.h
new file mode 100644
index 0000000..10edaad
--- /dev/null
+++ b/libs/game_features/src/savegameinfo.h
@@ -0,0 +1,49 @@
+#ifndef SAVEGAMEINFO_H
+#define SAVEGAMEINFO_H
+
+namespace MOBase { class ISaveGame; }
+namespace MOBase { class ISaveGameInfoWidget; }
+
+#include <QMap>
+
+class QString;
+class QStringList;
+class QWidget;
+
+/** Feature to get hold of stuff to do with save games */
+class SaveGameInfo
+{
+public:
+ virtual ~SaveGameInfo() {}
+
+ typedef QStringList ProvidingModules;
+ typedef QMap<QString, ProvidingModules> MissingAssets;
+
+ /**
+ * @brief Get missing items from a save.
+ *
+ * @param save The save to retrieve missing assets from.
+ *
+ * @returns a collection of missing assets and the modules that can supply those
+ * assets.
+ *
+ * Note that in the situation where 'module' and 'asset' are indistinguishable,
+ * both still have to be supplied.
+ */
+ virtual MissingAssets getMissingAssets(MOBase::ISaveGame const& save) const = 0;
+
+ /**
+ * @brief Get a widget to display over the save game list.
+ *
+ * @param parent The parent widget.
+ *
+ * @returns a Qt widget to display saves Widget.
+ *
+ * It is permitted to return a null pointer to indicate the plugin does not have a
+ * nice visual way of displaying save game contents.
+ */
+ virtual MOBase::ISaveGameInfoWidget *getSaveGameWidget(QWidget *parent = 0) const = 0;
+};
+
+#endif // SAVEGAMEINFO_H
+
diff --git a/libs/game_features/src/scriptextender.h b/libs/game_features/src/scriptextender.h
new file mode 100644
index 0000000..1f91df6
--- /dev/null
+++ b/libs/game_features/src/scriptextender.h
@@ -0,0 +1,41 @@
+#ifndef SCRIPTEXTENDER
+#define SCRIPTEXTENDER
+
+#include <windows.h>
+
+class QString;
+class QStringList;
+
+class ScriptExtender {
+
+public:
+
+ virtual ~ScriptExtender() {}
+
+ /** Get the name of the script extender binary */
+ virtual QString BinaryName() const = 0;
+
+ /** Get the script extender plugin path*/
+ virtual QString PluginPath() const = 0;
+
+ /** The loader to use to ensure the game runs with the script extender */
+ virtual QString loaderName() const = 0;
+
+ /** Full path of the loader */
+ virtual QString loaderPath() const = 0;
+
+ /** Extension of the script extender save game */
+ virtual QString savegameExtension() const = 0;
+
+ /** Returns true if the extender is installed */
+ virtual bool isInstalled() const = 0;
+
+ /** Get version of extender */
+ virtual QString getExtenderVersion() const = 0;
+
+ /** Get CPU platform of extender */
+ virtual WORD getArch() const = 0;
+};
+
+#endif // SCRIPTEXTENDER
+
diff --git a/libs/game_features/src/unmanagedmods.h b/libs/game_features/src/unmanagedmods.h
new file mode 100644
index 0000000..545b369
--- /dev/null
+++ b/libs/game_features/src/unmanagedmods.h
@@ -0,0 +1,44 @@
+#ifndef UNMANAGEDMODS_H
+#define UNMANAGEDMODS_H
+
+class QString;
+class QFileInfo;
+class QStringList;
+
+
+class UnmanagedMods {
+
+public:
+
+public:
+
+ virtual ~UnmanagedMods() {}
+
+ /**
+ * @param onlyOfficial if set, only official mods (dlcs) are returned
+ * @return the list of unmanaged mods (internal names)
+ */
+ virtual QStringList mods(bool onlyOfficial) const = 0;
+
+ /**
+ * @param modName (internal) name of the mod being requested
+ * @return display name of the mod
+ */
+ virtual QString displayName(const QString &modName) const = 0;
+
+ /**
+ * @param modName name of the mod being requested
+ * @return reference file info
+ */
+ virtual QFileInfo referenceFile(const QString &modName) const = 0;
+
+ /**
+ * @param modName name of the mod being requested
+ * @return list of file names (absolute paths)
+ */
+ virtual QStringList secondaryFiles(const QString &modName) const = 0;
+
+};
+
+#endif // UNMANAGEDMODS_H
+