From 817e8f5cd26739c69d930d21cd9dc4c0b6e4984e Mon Sep 17 00:00:00 2001 From: SulfurNitride Date: Sat, 14 Feb 2026 02:45:12 -0600 Subject: 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 --- .../installer/FomodPlusInstaller.h | 115 +++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 libs/installer_fomod_plus/installer/FomodPlusInstaller.h (limited to 'libs/installer_fomod_plus/installer/FomodPlusInstaller.h') 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 +#include +#include + +#include +#include "FomodInstallerWindow.h" +#include "lib/Logger.h" +#include "xml/FomodInfoFile.h" +#include "xml/ModuleConfiguration.h" + +#include +#include +#include + +class FomodInstallerWindow; + +using namespace MOBase; +using namespace std; + +using ParsedFilesTuple = std::tuple, std::unique_ptr, 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 > requirements() const override; + + [[nodiscard]] bool isManualInstaller() const override { return false; } + + [[nodiscard]] bool isArchiveSupported(std::shared_ptr tree) const override; + + [[nodiscard]] QList settings() const override; + + std::pair getExistingFomodJson(const GuessedValue& modName, + const int& nexusId, const int& stepsInCurrentFomod) const; + + void clearPriorInstallData(); + + EInstallResult install(GuessedValue& modName, std::shared_ptr& 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 mFomodJson{ nullptr }; + bool mInstallerUsed{ false }; + std::shared_ptr mFomodContent{ nullptr }; + std::unique_ptr 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 findFomodDirectory(const shared_ptr& tree); + + [[nodiscard]] static QDialog::DialogCode showInstallerWindow(const shared_ptr& window); + + [[nodiscard]] ParsedFilesTuple parseFomodFiles(const shared_ptr& tree); + + static void appendImageFiles(vector >& entries, + const shared_ptr& tree); + + void appendPluginFiles(vector >& entries, const shared_ptr& 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); + } +}; -- cgit v1.3.1