aboutsummaryrefslogtreecommitdiff
path: root/libs/installer_fomod_plus/installer/FomodPlusInstaller.h
diff options
context:
space:
mode:
authorSulfurNitride <SulfurNitride@users.noreply.github.com>2026-02-14 02:45:12 -0600
committerSulfurNitride <SulfurNitride@users.noreply.github.com>2026-02-14 02:45:25 -0600
commit817e8f5cd26739c69d930d21cd9dc4c0b6e4984e (patch)
tree52aed11d6751bb7d20b06acf197d56fac113203d /libs/installer_fomod_plus/installer/FomodPlusInstaller.h
parent51a9f8f197727f00896e5de44569b098923527dd (diff)
Add FUSE external mapping support, BG3/Oblivion Remastered fixes, fomod-plus and NaK integration
FUSE VFS now deploys non-data-dir mod mappings (Paks, OBSE, UE4SS, etc.) via real symlinks and injects file-level data-dir mappings (plugins.txt, loadorder.txt) into the VFS tree. Fixes game launches for Oblivion Remastered (Root Builder path resolution, script extender support) and BG3 (Wine prefix documents directory, file mapper symlinks on Linux). Vendors mo2-fomod-plus plugin and NaK crate for FOMOD installer and game finder/runtime support. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'libs/installer_fomod_plus/installer/FomodPlusInstaller.h')
-rw-r--r--libs/installer_fomod_plus/installer/FomodPlusInstaller.h115
1 files changed, 115 insertions, 0 deletions
diff --git a/libs/installer_fomod_plus/installer/FomodPlusInstaller.h b/libs/installer_fomod_plus/installer/FomodPlusInstaller.h
new file mode 100644
index 0000000..494ad8e
--- /dev/null
+++ b/libs/installer_fomod_plus/installer/FomodPlusInstaller.h
@@ -0,0 +1,115 @@
+#pragma once
+
+#include "stringutil.h"
+
+#include <iplugin.h>
+#include <iplugininstaller.h>
+#include <iplugininstallersimple.h>
+
+#include <nlohmann/json.hpp>
+#include "FomodInstallerWindow.h"
+#include "lib/Logger.h"
+#include "xml/FomodInfoFile.h"
+#include "xml/ModuleConfiguration.h"
+
+#include <QDialog>
+#include <integration/FomodDataContent.h>
+#include <FOMODData/FomodDB.h>
+
+class FomodInstallerWindow;
+
+using namespace MOBase;
+using namespace std;
+
+using ParsedFilesTuple = std::tuple<std::unique_ptr<FomodInfoFile>, std::unique_ptr<ModuleConfiguration>, QStringList>;
+
+class FomodPlusInstaller final : public IPluginInstallerSimple {
+ Q_OBJECT
+ Q_INTERFACES(MOBase::IPlugin MOBase::IPluginInstaller)
+ Q_PLUGIN_METADATA(IID "io.clearing.FomodPlus" FILE "fomodplus.json")
+
+public:
+ bool init(IOrganizer* organizer) override;
+
+ // constant values
+ [[nodiscard]] QString name() const override { return StringConstants::Plugin::NAME.data(); }
+ [[nodiscard]] QString author() const override { return StringConstants::Plugin::AUTHOR.data(); }
+ [[nodiscard]] QString description() const override { return StringConstants::Plugin::DESCRIPTION.data(); }
+ [[nodiscard]] VersionInfo version() const override { return { 1, 0, 0, VersionInfo::RELEASE_FINAL }; }
+
+ [[nodiscard]] unsigned int priority() const override
+ {
+ return 999; /* Above installer_fomod's highest priority. */
+ }
+
+ [[nodiscard]] std::vector<std::shared_ptr<const IPluginRequirement> > requirements() const override;
+
+ [[nodiscard]] bool isManualInstaller() const override { return false; }
+
+ [[nodiscard]] bool isArchiveSupported(std::shared_ptr<const IFileTree> tree) const override;
+
+ [[nodiscard]] QList<PluginSetting> settings() const override;
+
+ std::pair<nlohmann::json, IModInterface*> getExistingFomodJson(const GuessedValue<QString>& modName,
+ const int& nexusId, const int& stepsInCurrentFomod) const;
+
+ void clearPriorInstallData();
+
+ EInstallResult install(GuessedValue<QString>& modName, std::shared_ptr<IFileTree>& tree, QString& version,
+ int& nexusID) override;
+
+ void onInstallationStart(QString const& archive, bool reinstallation, IModInterface* currentMod) override;
+
+ void onInstallationEnd(EInstallResult result, IModInterface* newMod) override;
+
+ [[nodiscard]] bool shouldShowImages() const;
+
+ [[nodiscard]] bool shouldShowNotifications() const;
+ bool shouldShowSidebarFilter() const;
+
+ [[nodiscard]] bool shouldAutoRestoreChoices() const;
+
+ [[nodiscard]] bool isWizardIntegrated() const;
+
+ void toggleShouldShowImages() const;
+
+ QString getSelectedColor() const;
+
+private:
+ Logger& log = Logger::getInstance();
+ IOrganizer* mOrganizer = nullptr;
+ QString mFomodPath{};
+ std::shared_ptr<nlohmann::json> mFomodJson{ nullptr };
+ bool mInstallerUsed{ false };
+ std::shared_ptr<FomodDataContent> mFomodContent{ nullptr };
+ std::unique_ptr<FomodDB> mFomodDb;
+
+ /**
+ * @brief Retrieve the tree entry corresponding to the fomod directory.
+ *
+ * @param tree Tree to look-up the directory in.
+ *
+ * @return the entry corresponding to the fomod directory in the tree, or a null
+ * pointer if the entry was not found.
+ */
+ [[nodiscard]] static shared_ptr<const IFileTree> findFomodDirectory(const shared_ptr<const IFileTree>& tree);
+
+ [[nodiscard]] static QDialog::DialogCode showInstallerWindow(const shared_ptr<FomodInstallerWindow>& window);
+
+ [[nodiscard]] ParsedFilesTuple parseFomodFiles(const shared_ptr<IFileTree>& tree);
+
+ static void appendImageFiles(vector<shared_ptr<const FileTreeEntry> >& entries,
+ const shared_ptr<const IFileTree>& tree);
+
+ void appendPluginFiles(vector<shared_ptr<const FileTreeEntry> >& entries, const shared_ptr<const IFileTree>& tree);
+
+ void setupUiInjection() const;
+ void toggleFeature(bool enabled) const;
+
+ [[nodiscard]] bool shouldFallbackToLegacyInstaller() const;
+
+ void logMessage(const LogLevel level, const std::string& message) const
+ {
+ log.logMessage(level, "[INSTALLER] " + message);
+ }
+};