aboutsummaryrefslogtreecommitdiff
path: root/flatpak/fluorine-manager-wrapper.sh
diff options
context:
space:
mode:
Diffstat (limited to 'flatpak/fluorine-manager-wrapper.sh')
-rwxr-xr-xflatpak/fluorine-manager-wrapper.sh109
1 files changed, 109 insertions, 0 deletions
diff --git a/flatpak/fluorine-manager-wrapper.sh b/flatpak/fluorine-manager-wrapper.sh
new file mode 100755
index 0000000..fabe535
--- /dev/null
+++ b/flatpak/fluorine-manager-wrapper.sh
@@ -0,0 +1,109 @@
+#!/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/
+ USER_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/fluorine"
+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="${XDG_DATA_HOME:-$HOME/.local/share}/fluorine/bin"
+ if [ -e "${BUNDLED}/mo2-vfs-helper" ]; then
+ mkdir -p "${VFS_HELPER_DIR}"
+ cp -f "${BUNDLED}/mo2-vfs-helper" "${VFS_HELPER_DIR}/mo2-vfs-helper"
+ chmod +x "${VFS_HELPER_DIR}/mo2-vfs-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" "$@"