diff options
Diffstat (limited to 'flatpak')
| -rw-r--r-- | flatpak/com.fluorine.manager.desktop | 22 | ||||
| -rw-r--r-- | flatpak/com.fluorine.manager.metainfo.xml | 38 | ||||
| -rw-r--r-- | flatpak/com.fluorine.manager.png | bin | 51022 -> 0 bytes | |||
| -rw-r--r-- | flatpak/com.fluorine.manager.yml | 371 | ||||
| -rwxr-xr-x | flatpak/flatpak-install.sh | 60 | ||||
| -rwxr-xr-x | flatpak/fluorine-manager-wrapper.sh | 114 |
6 files changed, 0 insertions, 605 deletions
diff --git a/flatpak/com.fluorine.manager.desktop b/flatpak/com.fluorine.manager.desktop deleted file mode 100644 index ff62c76..0000000 --- a/flatpak/com.fluorine.manager.desktop +++ /dev/null @@ -1,22 +0,0 @@ -[Desktop Entry] -Type=Application -Name=Fluorine Manager -GenericName=Mod Manager -Comment=Mod Organizer 2 for Linux - manage your game mods -Exec=fluorine-manager -Icon=com.fluorine.manager -Terminal=false -Categories=Game;Utility; -Keywords=mod;organizer;modding;skyrim;fallout; -MimeType=x-scheme-handler/nxm; -Actions=create-portable;list-instances; - -[Desktop Action create-portable] -Name=Create Portable Instance -Exec=fluorine-manager create-portable -Icon=com.fluorine.manager - -[Desktop Action list-instances] -Name=List Instances -Exec=fluorine-manager list-instances -Icon=com.fluorine.manager diff --git a/flatpak/com.fluorine.manager.metainfo.xml b/flatpak/com.fluorine.manager.metainfo.xml deleted file mode 100644 index 1200d3e..0000000 --- a/flatpak/com.fluorine.manager.metainfo.xml +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<component type="desktop-application"> - <id>com.fluorine.manager</id> - <name>Fluorine Manager</name> - <summary>Mod Organizer 2 for Linux</summary> - <metadata_license>CC0-1.0</metadata_license> - <project_license>GPL-3.0-or-later</project_license> - - <description> - <p> - Fluorine Manager is a Linux port of Mod Organizer 2, a powerful mod management - tool for Bethesda games and other titles. It uses a virtual filesystem to keep - your game directory clean while allowing complex mod setups with load order - management, conflict resolution, and profile support. - </p> - <p>Features:</p> - <ul> - <li>Virtual filesystem - mods never touch your game folder</li> - <li>Profile system for different mod configurations</li> - <li>Plugin load order management</li> - <li>Mod conflict detection and resolution</li> - <li>Nexus Mods integration for downloading</li> - <li>Proton/Wine prefix management for running Windows games</li> - <li>UMU launcher support</li> - </ul> - </description> - - <launchable type="desktop-id">com.fluorine.manager.desktop</launchable> - - <url type="homepage">https://github.com/ModOrganizer2/modorganizer</url> - <url type="bugtracker">https://github.com/ModOrganizer2/modorganizer/issues</url> - - <provides> - <binary>fluorine-manager</binary> - </provides> - - <content_rating type="oars-1.1" /> -</component> diff --git a/flatpak/com.fluorine.manager.png b/flatpak/com.fluorine.manager.png Binary files differdeleted file mode 100644 index 3a9fbdd..0000000 --- a/flatpak/com.fluorine.manager.png +++ /dev/null diff --git a/flatpak/com.fluorine.manager.yml b/flatpak/com.fluorine.manager.yml deleted file mode 100644 index 5ed65dc..0000000 --- a/flatpak/com.fluorine.manager.yml +++ /dev/null @@ -1,371 +0,0 @@ -app-id: com.fluorine.manager -runtime: org.kde.Platform -runtime-version: '6.10' -sdk: org.kde.Sdk -sdk-extensions: - - org.freedesktop.Sdk.Extension.rust-stable -command: fluorine-manager - -finish-args: - - --share=ipc - - --share=network - - --socket=x11 - - --socket=wayland - - --device=all - - --filesystem=home - - --filesystem=/mnt - - --filesystem=/media - - --filesystem=/run/media - - --filesystem=~/.steam:ro - - --filesystem=~/.local/share/Steam - - --filesystem=~/.var/app/com.valvesoftware.Steam:ro - - --talk-name=org.freedesktop.Flatpak - -cleanup: - - /include - - /lib/cmake - - /lib/pkgconfig - - /share/doc - - /share/man - - '*.a' - - '*.la' - -modules: - # ── 1. Boost ── - - name: boost - buildsystem: simple - build-commands: - - ./bootstrap.sh --prefix=/app --with-libraries=program_options,thread,filesystem,system,locale - - ./b2 install -j$FLATPAK_BUILDER_N_JOBS link=shared variant=release - sources: - - type: archive - url: https://archives.boost.io/release/1.87.0/source/boost_1_87_0.tar.gz - sha256: f55c340aa49763b1925ccf02b2e83f35fdcf634c9d5164a2acb87540173c741d - - # ── 2. spdlog ── - - name: spdlog - buildsystem: cmake-ninja - config-opts: - - -DCMAKE_BUILD_TYPE=Release - - -DSPDLOG_BUILD_SHARED=ON - sources: - - type: git - url: https://github.com/gabime/spdlog.git - tag: v1.15.2 - - # ── 3. tinyxml2 ── - - name: tinyxml2 - buildsystem: cmake-ninja - config-opts: - - -DCMAKE_BUILD_TYPE=Release - sources: - - type: git - url: https://github.com/leethomason/tinyxml2.git - tag: 10.0.0 - - # ── 4. tomlplusplus ── - - name: tomlplusplus - buildsystem: cmake-ninja - config-opts: - - -DCMAKE_BUILD_TYPE=Release - sources: - - type: git - url: https://github.com/marzer/tomlplusplus.git - tag: v3.4.0 - - # ── 5. libfuse3 ── - # Built manually to install fusermount3 without setuid (chown root fails in sandbox). - # default_library=both produces libfuse3.a so the VFS helper can link statically. - - name: libfuse3 - buildsystem: simple - build-commands: - - meson setup _build --prefix=/app -Dexamples=false -Dtests=false -Dutils=true -Ddefault_library=both - - ninja -C _build - # Install library and headers (skip meson install which runs chown). - - ninja -C _build install || true - # Ensure fusermount3 is installed even if install_helper.sh failed. - - install -Dm755 _build/util/fusermount3 /app/bin/fusermount3 2>/dev/null || true - sources: - - type: git - url: https://github.com/libfuse/libfuse.git - tag: fuse-3.16.2 - - # ── 6. libloot ── - # libloot has a Rust crate at the root and a C++ cmake project in cpp/. - # The Rust static library must be built first, then cmake links against it. - - name: libloot - buildsystem: simple - build-options: - append-path: /usr/lib/sdk/rust-stable/bin - env: - CARGO_HOME: /run/build/libloot/cargo - # Network needed for cargo deps and cmake FetchContent (googletest). - build-args: - - --share=network - build-commands: - # Build Rust static library first. - - cargo build --release - # Build the C++ shared library (links against Rust static lib). - - | - cmake -S cpp -B cpp/build -G Ninja \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=ON \ - -DLIBLOOT_INSTALL_DOCS=OFF \ - -DCMAKE_INSTALL_PREFIX=/app - - cmake --build cpp/build --parallel - - cmake --install cpp/build - # Create pkg-config metadata. - - mkdir -p /app/lib/pkgconfig - - | - printf '%s\n' \ - 'prefix=/app' \ - 'exec_prefix=${prefix}' \ - 'libdir=${prefix}/lib' \ - 'includedir=${prefix}/include' \ - '' \ - 'Name: libloot' \ - 'Description: LOOT C++ API library' \ - 'Version: 0.29.0' \ - 'Libs: -L${libdir} -lloot' \ - 'Cflags: -I${includedir}' \ - > /app/lib/pkgconfig/libloot.pc - sources: - - type: git - url: https://github.com/loot/libloot.git - branch: master - - # ── 7. icoutils ── - - name: icoutils - buildsystem: autotools - build-options: - # icoutils 0.32.3 uses K&R-style () declarations that GCC 14+ rejects. - cflags: -std=gnu17 - sources: - - type: archive - url: https://download.savannah.gnu.org/releases/icoutils/icoutils-0.32.3.tar.bz2 - sha256: 17abe02d043a253b68b47e3af69c9fc755b895db68fdc8811786125df564c6e0 - - # ── 8. cabextract ── - # Required by winetricks for extracting Windows cab archives. - - name: cabextract - buildsystem: autotools - sources: - - type: archive - url: https://www.cabextract.org.uk/cabextract-1.11.tar.gz - sha256: b5546db1155e4c718ff3d4b278573604f30dd64c3c5bfd4657cd089b823a3ac6 - - # ── 9. Portable Python runtime ── - # Pre-built Python used as the embedded interpreter for MO2's Python plugins. - # pip packages are installed via network during build (--share=network). - - name: portable-python - buildsystem: simple - build-options: - build-args: - - --share=network - build-commands: - # Extract, trim, symlink, and install pip packages in one step - # (each build-command runs in its own shell). - - | - set -e - mkdir -p /app/lib/fluorine/python - unzip portable-python.zip -d /tmp/pp - PP_DIR="$(find /tmp/pp -maxdepth 1 -mindepth 1 -type d | head -1)" - cp -a "${PP_DIR}/." /app/lib/fluorine/python/ - rm -rf /tmp/pp - # Versioned soname symlink (pybind11 links against libpython3.13.so.1.0). - if [ -f /app/lib/fluorine/python/lib/libpython3.13.so ] && \ - [ ! -f /app/lib/fluorine/python/lib/libpython3.13.so.1.0 ]; then - ln -sf libpython3.13.so /app/lib/fluorine/python/lib/libpython3.13.so.1.0 - fi - # Trim test suites and unnecessary files. - rm -rf /app/lib/fluorine/python/lib/python3.13/test \ - /app/lib/fluorine/python/lib/python3.13/unittest/test \ - /app/lib/fluorine/python/lib/python3.13/idlelib \ - /app/lib/fluorine/python/lib/python3.13/tkinter \ - /app/lib/fluorine/python/lib/python3.13/turtledemo \ - /app/lib/fluorine/python/include \ - /app/lib/fluorine/python/share \ - 2>/dev/null || true - find /app/lib/fluorine/python -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true - find /app/lib/fluorine/python -name "*.pyc" -delete 2>/dev/null || true - # Install uv for Python package management. - curl -LsSf https://astral.sh/uv/install.sh | INSTALLER_NO_MODIFY_PATH=1 UV_INSTALL_DIR=/app/bin sh - # Install Python packages via uv (PyQt6 for plugin UI, psutil, vdf). - /app/bin/uv pip install --python /app/lib/fluorine/python/bin/python3 PyQt6 psutil vdf - sources: - - type: file - url: https://github.com/bjia56/portable-python/releases/download/cpython-v3.13.9-build.0/python-headless-3.13.9-linux-x86_64.zip - sha256: d03507d107da86d74aa38bbc4957b8db5753de567024c5724a254909ae6b86d6 - dest-filename: portable-python.zip - - # ── 10. Fluorine Manager (main project) ── - # uv (installed in portable-python step) handles pybind11 + sip for the build. - - name: fluorine - buildsystem: simple - build-options: - append-path: /usr/lib/sdk/rust-stable/bin - env: - CARGO_HOME: /run/build/fluorine/cargo - PYTHONPATH: /app/lib/python3/dist-packages - # Network needed for FetchContent (7zip, etc.) and cargo deps. - build-args: - - --share=network - build-commands: - # ── Configure and build ── - # Install pybind11 + sip into /app (SDK /usr is read-only). - # Uses SDK's python3 directly (not a venv) so find_package(Python) - # finds Development headers on cmake reconfiguration. - - | - /app/bin/uv pip install --target /app/lib/python3/dist-packages pybind11==2.13.6 sip - PYBIND11_DIR="$(python3 -c 'import pybind11; print(pybind11.get_cmake_dir())')" - cmake -S . -B _build -G Ninja \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_PREFIX_PATH=/app \ - -DPython_EXECUTABLE=/usr/bin/python3 \ - -Dpybind11_DIR="${PYBIND11_DIR}" \ - -DBUILD_PLUGIN_PYTHON=ON - - cmake --build _build --parallel - - # ── Create output layout ── - - mkdir -p /app/lib/fluorine/plugins /app/lib/fluorine/dlls /app/lib/fluorine/lib - - # Main binary. - - cp -f _build/src/src/ModOrganizer /app/lib/fluorine/ModOrganizer-core - - # umu-run (patch and repackage if present). - - | - if [ -f _build/src/src/umu-run ]; then - UMU_PATCH_DIR="$(mktemp -d)" - cd "${UMU_PATCH_DIR}" - python3 << 'PATCHEOF' - import zipfile, pathlib - zf = zipfile.ZipFile('/run/build/fluorine/_build/src/src/umu-run') - zf.extractall('src') - run_py = pathlib.Path('src/umu/umu_run.py') - src = run_py.read_text() - old1 = ' env["STEAM_COMPAT_INSTALL_PATH"] = os.environ.get("STEAM_COMPAT_INSTALL_PATH", "")' - new1 = (old1 - + '\n env["STEAM_COMPAT_CLIENT_INSTALL_PATH"] = os.environ.get(' - + '\n "STEAM_COMPAT_CLIENT_INSTALL_PATH", ""' - + '\n )') - if old1 in src and 'STEAM_COMPAT_CLIENT_INSTALL_PATH"] = os.environ' not in src: - src = src.replace(old1, new1) - old2 = ' os.environ[key] = val' - new2 = (old2 - + '\n\n # GE-Proton treats games with UMU_ID as non-Steam titles and skips' - + '\n # the steam.exe DRM bridge. Remove it for Steam games.' - + '\n if "UMU_ID" in os.environ and env.get("SteamAppId", "0") != "0":' - + '\n del os.environ["UMU_ID"]') - if old2 in src and 'del os.environ["UMU_ID"]' not in src: - src = src.replace(old2, new2, 1) - run_py.write_text(src) - PATCHEOF - python3 -m zipapp src -o /app/lib/fluorine/umu-run -p '/usr/bin/env python3' - chmod +x /app/lib/fluorine/umu-run - cd /run/build/fluorine - rm -rf "${UMU_PATCH_DIR}" - fi - - # VFS helper (standalone, runs on host for Flatpak FUSE support). - # Statically linked against libfuse3 — no runtime deps beyond glibc. - - test -f _build/src/src/mo2-vfs-helper && cp -f _build/src/src/mo2-vfs-helper /app/lib/fluorine/ || true - - test -f _build/src/src/mo2-process-helper && cp -f _build/src/src/mo2-process-helper /app/lib/fluorine/ || true - - # lootcli. - - test -f _build/libs/lootcli/src/lootcli && cp -f _build/libs/lootcli/src/lootcli /app/lib/fluorine/ || true - - # icoutils (symlink from /app/bin where the icoutils module installed them). - - ln -sf /app/bin/wrestool /app/lib/fluorine/wrestool - - ln -sf /app/bin/icotool /app/lib/fluorine/icotool - - ln -sf /app/bin/fusermount3 /app/lib/fluorine/fusermount3 - - ln -sf /app/bin/cabextract /app/lib/fluorine/cabextract - - # fluorine-manager CLI helper. - - test -f src/fluorine-manager && cp -f src/fluorine-manager /app/lib/fluorine/ || true - - # MO2 plugins (.so). - - | - find _build/libs -type f \( \ - -name "libgame_*.so" -o \ - -name "libinstaller_*.so" -o \ - -name "libfomod_plus_*.so" -o \ - -name "libpreview_*.so" -o \ - -name "libdiagnose_*.so" -o \ - -name "libcheck_*.so" -o \ - -name "libtool_*.so" -o \ - -name "libinieditor.so" -o \ - -name "libinibakery.so" -o \ - -name "libbsa_extractor.so" -o \ - -name "libbsa_packer.so" -o \ - -name "libproxy.so" \ - \) -exec cp -f {} /app/lib/fluorine/plugins/ \; - - # Python plugin payload. - - | - for f in libplugin_python.so lzokay.py winreg.py \ - DDSPreview.py Form43Checker.py ScriptExtenderPluginChecker.py; do - [ -f "_build/src/src/plugins/${f}" ] && cp -f "_build/src/src/plugins/${f}" /app/lib/fluorine/plugins/ - done - for d in basic_games data libs dlls; do - [ -d "_build/src/src/plugins/${d}" ] && cp -a "_build/src/src/plugins/${d}" /app/lib/fluorine/plugins/ - done - rm -f /app/lib/fluorine/plugins/FNIS*.py - - # Source-tree Python plugins (rootbuilder, omod installer, etc.). - - | - for f in src/plugins/*.py; do - [ -f "${f}" ] && cp -f "${f}" /app/lib/fluorine/plugins/ - done - - # Stylesheets / themes. - - cp -a src/src/stylesheets /app/lib/fluorine/stylesheets - - # 7z runtime. - - | - if [ -f _build/src/src/dlls/7z.so ]; then - cp -f _build/src/src/dlls/7z.so /app/lib/fluorine/dlls/7z.so - cp -f _build/src/src/dlls/7z.so /app/lib/fluorine/dlls/7zip.dll - fi - - # Project shared libraries. - - cp -f _build/libs/uibase/src/libuibase.so /app/lib/fluorine/lib/ - - cp -f _build/libs/libbsarch/liblibbsarch.so /app/lib/fluorine/lib/ - - cp -f _build/libs/archive/src/libarchive.so /app/lib/fluorine/lib/ - - test -f _build/libs/plugin_python/src/runner/librunner.so && cp -f _build/libs/plugin_python/src/runner/librunner.so /app/lib/fluorine/lib/ || true - - test -f libs/bsa_ffi/target/release/libbsa_ffi.so && cp -f libs/bsa_ffi/target/release/libbsa_ffi.so /app/lib/fluorine/lib/ || true - - test -f libs/nak_ffi/target/release/libnak_ffi.so && cp -f libs/nak_ffi/target/release/libnak_ffi.so /app/lib/fluorine/lib/ || true - - # Boost libraries (from /app/lib where the boost module installed them). - - cp -Lf /app/lib/libboost_program_options.so* /app/lib/fluorine/lib/ 2>/dev/null || true - - cp -Lf /app/lib/libboost_thread.so* /app/lib/fluorine/lib/ 2>/dev/null || true - - # libloot (from /app/lib where the libloot module installed it). - - | - if [ -f /app/lib/libloot.so.0 ]; then - cp -Lf /app/lib/libloot.so.0 /app/lib/fluorine/lib/ - ln -sf libloot.so.0 /app/lib/fluorine/lib/libloot.so - elif [ -f /app/lib/libloot.so ]; then - cp -Lf /app/lib/libloot.so /app/lib/fluorine/lib/ - fi - - # Build-tree Python plugin payload. - - test -d _build/src/src/python && cp -a _build/src/src/python/. /app/lib/fluorine/python/ || true - - # Strip binaries. - - strip --strip-unneeded /app/lib/fluorine/ModOrganizer-core 2>/dev/null || true - - find /app/lib/fluorine/plugins -name "*.so" -exec strip --strip-unneeded {} \; 2>/dev/null || true - - find /app/lib/fluorine/dlls \( -name "*.so" -o -name "*.dll" \) -exec strip --strip-unneeded {} \; 2>/dev/null || true - - find /app/lib/fluorine/lib -name "*.so*" -exec strip --strip-unneeded {} \; 2>/dev/null || true - - test -f /app/lib/fluorine/lootcli && strip --strip-unneeded /app/lib/fluorine/lootcli 2>/dev/null || true - - test -f /app/lib/fluorine/mo2-vfs-helper && strip --strip-unneeded /app/lib/fluorine/mo2-vfs-helper 2>/dev/null || true - - test -f /app/lib/fluorine/mo2-process-helper && strip --strip-unneeded /app/lib/fluorine/mo2-process-helper 2>/dev/null || true - - # Install wrapper script, desktop file, metainfo, and icon. - - install -Dm755 flatpak/fluorine-manager-wrapper.sh /app/bin/fluorine-manager - - install -Dm644 flatpak/com.fluorine.manager.desktop /app/share/applications/com.fluorine.manager.desktop - - install -Dm644 flatpak/com.fluorine.manager.metainfo.xml /app/share/metainfo/com.fluorine.manager.metainfo.xml - - install -Dm644 flatpak/com.fluorine.manager.png /app/share/icons/hicolor/256x256/apps/com.fluorine.manager.png - - sources: - - type: dir - path: .. diff --git a/flatpak/flatpak-install.sh b/flatpak/flatpak-install.sh deleted file mode 100755 index 984d12b..0000000 --- a/flatpak/flatpak-install.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env bash -# Build the Fluorine Manager Flatpak. -# -# Usage: -# cd flatpak && bash flatpak-install.sh # build & install locally -# cd flatpak && bash flatpak-install.sh bundle # build a .flatpak file to share -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -PROJECT_DIR="$(dirname "${SCRIPT_DIR}")" -MANIFEST="${SCRIPT_DIR}/com.fluorine.manager.yml" -APP_ID="com.fluorine.manager" -BUILD_DIR="${PROJECT_DIR}/.flatpak-build" -MODE="${1:-install}" - -# ── Ensure flathub remote exists ── -if ! flatpak remote-list --user | grep -q flathub; then - echo "Adding flathub remote..." - flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo -fi - -# ── Install required Flatpak runtime and SDK ── -echo "Installing KDE Platform and SDK (may take a while on first run)..." -flatpak install --user --noninteractive flathub org.kde.Platform//6.10 org.kde.Sdk//6.10 - -echo "Installing Rust SDK extension..." -flatpak install --user --noninteractive flathub org.freedesktop.Sdk.Extension.rust-stable//25.08 - -cd "${PROJECT_DIR}" - -if [ "${MODE}" = "bundle" ]; then - # ── Build a distributable .flatpak file ── - echo "" - echo "Building Flatpak bundle (this may take a while)..." - flatpak-builder --disable-rofiles-fuse --repo="${PROJECT_DIR}/flatpak-repo" --force-clean --ccache \ - "${BUILD_DIR}" "${MANIFEST}" - flatpak build-bundle \ - --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo \ - "${PROJECT_DIR}/flatpak-repo" "${PROJECT_DIR}/fluorine-manager.flatpak" "${APP_ID}" - BUNDLE_SIZE="$(du -sh fluorine-manager.flatpak | cut -f1)" - echo "" - echo "=== Bundle created: fluorine-manager.flatpak (${BUNDLE_SIZE}) ===" - echo "" - echo "Share this file with testers. They install it with:" - echo " flatpak install --user fluorine-manager.flatpak" -else - # ── Build and install locally ── - echo "" - echo "Building and installing Flatpak locally (this may take a while)..." - flatpak-builder --disable-rofiles-fuse --install --user --force-clean --ccache \ - "${BUILD_DIR}" "${MANIFEST}" - echo "" - echo "=== Flatpak installed successfully ===" -fi - -echo "" -echo "Usage:" -echo " flatpak run ${APP_ID} # launch GUI" -echo " flatpak run ${APP_ID} create-portable --name myinstance --game falloutnv" -echo " flatpak run ${APP_ID} list-instances" diff --git a/flatpak/fluorine-manager-wrapper.sh b/flatpak/fluorine-manager-wrapper.sh deleted file mode 100755 index eba2b77..0000000 --- a/flatpak/fluorine-manager-wrapper.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/bin/bash -# Flatpak wrapper for Fluorine Manager (MO2 Linux) -# Sets up a writable overlay so users can add custom plugins while still -# loading the bundled ones from the read-only /app tree. -# -# For portable instances (--instance /path), the overlay is created INSIDE the -# instance directory so each portable install is fully self-contained. -# For the global instance (no --instance), a shared overlay is used. - -BUNDLED="/app/lib/fluorine" - -# ── Detect --instance argument ── -# If launching a portable instance, use its directory as the overlay target. -INSTANCE_DIR="" -PREV="" -for arg in "$@"; do - if [ "$PREV" = "--instance" ] || [ "$PREV" = "-i" ]; then - INSTANCE_DIR="$arg" - break - fi - PREV="$arg" -done - -if [ -n "$INSTANCE_DIR" ] && [ -d "$INSTANCE_DIR" ]; then - # Portable instance: overlay goes into the instance directory itself. - # Everything is self-contained: mods, profiles, plugins, dlls, libs. - USER_DIR="$INSTANCE_DIR" -else - # Global instance: shared overlay at ~/.local/share/fluorine/ - # Use $HOME directly to bypass Flatpak's XDG_DATA_HOME remapping. - USER_DIR="$HOME/.var/app/com.fluorine.manager" -fi - -# ── Create writable overlay with symlinks to bundled files ── -# This lets MO2 load bundled plugins AND any custom ones the user drops in. -# Existing files are never overwritten (user overrides take priority). -setup_overlay() { - mkdir -p "${USER_DIR}/plugins" "${USER_DIR}/dlls" "${USER_DIR}/lib" - - # Symlink bundled plugins (skip existing - user overrides take priority) - for f in "${BUNDLED}/plugins/"*; do - [ -e "$f" ] || continue - local base="$(basename "$f")" - local target="${USER_DIR}/plugins/${base}" - [ -e "$target" ] || [ -L "$target" ] || ln -sf "$f" "$target" - done - - # Symlink bundled dlls - for f in "${BUNDLED}/dlls/"*; do - [ -e "$f" ] || continue - local base="$(basename "$f")" - local target="${USER_DIR}/dlls/${base}" - [ -e "$target" ] || [ -L "$target" ] || ln -sf "$f" "$target" - done - - # Symlink bundled libs - for f in "${BUNDLED}/lib/"*; do - [ -e "$f" ] || continue - local base="$(basename "$f")" - local target="${USER_DIR}/lib/${base}" - [ -e "$target" ] || [ -L "$target" ] || ln -sf "$f" "$target" - done - - # Symlink other bundled files (binaries, tools) directly - for f in ModOrganizer-core lootcli wrestool icotool fusermount3 cabextract; do - [ -e "${BUNDLED}/$f" ] || continue - [ -e "${USER_DIR}/$f" ] || [ -L "${USER_DIR}/$f" ] || ln -sf "${BUNDLED}/$f" "${USER_DIR}/$f" - done - - # umu-run must be a real copy (not symlink to /app/) because it runs on - # the host via flatpak-spawn --host, where /app/ doesn't exist. - # Remove any stale symlink first (cp -f follows symlinks, won't replace them). - if [ -e "${BUNDLED}/umu-run" ]; then - rm -f "${USER_DIR}/umu-run" - cp "${BUNDLED}/umu-run" "${USER_DIR}/umu-run" - chmod +x "${USER_DIR}/umu-run" - fi - - # VFS helper must be a real binary copy (not a symlink to /app/) because - # it runs on the host via flatpak-spawn --host, where /app/ doesn't exist. - # libfuse3 is statically linked, so no extra .so files needed. - VFS_HELPER_DIR="$HOME/.var/app/com.fluorine.manager/bin" - mkdir -p "${VFS_HELPER_DIR}" - if [ -e "${BUNDLED}/mo2-vfs-helper" ]; then - cp -f "${BUNDLED}/mo2-vfs-helper" "${VFS_HELPER_DIR}/mo2-vfs-helper" - chmod +x "${VFS_HELPER_DIR}/mo2-vfs-helper" - fi - if [ -e "${BUNDLED}/mo2-process-helper" ]; then - cp -f "${BUNDLED}/mo2-process-helper" "${VFS_HELPER_DIR}/mo2-process-helper" - chmod +x "${VFS_HELPER_DIR}/mo2-process-helper" - fi -} - -setup_overlay - -export PATH="${USER_DIR}:${BUNDLED}:${PATH}" -export LD_LIBRARY_PATH="${USER_DIR}/lib:${BUNDLED}/lib:${BUNDLED}/python/lib:${LD_LIBRARY_PATH:-}" - -# MO2 resolves plugins/dlls relative to MO2_BASE_DIR (or basePath()). -# Point it at the overlay so custom plugins are found. -export MO2_BASE_DIR="${USER_DIR}" -export MO2_PLUGINS_DIR="${USER_DIR}/plugins" -export MO2_DLLS_DIR="${USER_DIR}/dlls" -export MO2_PYTHON_DIR="${BUNDLED}/python" - -# Do NOT set PYTHONHOME globally -- it leaks into child processes (umu-run, -# Proton, winetricks) and breaks their Python. The plugin_python runner reads -# MO2_PYTHON_DIR and sets PYTHONHOME internally before loading the interpreter. -unset PYTHONHOME PYTHONPATH PYTHONNOUSERSITE - -# Qt6 plugins from KDE runtime. -export QT_PLUGIN_PATH="/usr/lib/plugins" - -exec "${BUNDLED}/ModOrganizer-core" "$@" |
