aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* Fix game launchers failing to find INI files due to registry key casingSulfurNitride2026-04-113-11/+23
| | | | | | | | | | Wine registry value names are case-sensitive. Game launchers (FNV, Oblivion, etc.) look up "installed path" (lowercase) but Fluorine was writing "Installed Path" (capitalized), causing "Unable to find an INI file" errors. Also adds trailing backslash to match Steam's path format and fixes the registry mismatch dialog to ignore trailing separator differences. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix VFS rename failing for backing and mod filesSulfurNitride2026-04-111-8/+31
| | | | | | | | | | | | | | | xEdit (and similar tools) rename game files to create backups before saving (e.g. DLCHorseArmor.esp -> TES4Edit Backups/...backup...). OverwriteManager::rename() only searches staging and overwrite directories, so renames of backing (game) or mod files failed with EACCES since those files live in the real game/mod directories. Now when OverwriteManager::rename() can't find the source file, the VFS copies it to staging at the destination path via COW instead of failing. The file disappears from its old path and appears at the new path in the virtual view, without modifying the real game/mod dirs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix SLR download silently failing due to response data being discardedSulfurNitride2026-04-101-4/+4
| | | | | | | | | The readyRead handler consumed data via readAll() but discarded it when no destination file was set. The final readAll() then returned empty since the buffer was already drained, causing all in-memory HTTP responses (like BUILD_ID.txt) to appear empty. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Sync upstream MO2 2.5.3 Beta 3 fixesSulfurNitride2026-04-105-6/+12
| | | | | | | | | - FO4VR: Add Daytripper4.dll to ESL support detection - Remove empty categories tooltip when mod has no categories - Fix QDialogButtonBox/QMessageBox enum mismatch in profile dialogs - Use refreshESPList(false) after LOOT sort (no full re-read needed) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix VFS rename rejecting RENAME_NOREPLACE flag from WineSulfurNitride2026-04-101-1/+20
| | | | | | | | | | | | | | Wine uses renameat2(RENAME_NOREPLACE) when translating MoveFileW() calls where ReplaceIfExists is FALSE (e.g. xEdit saving plugins). The VFS was rejecting all non-zero flags with EINVAL, which a real filesystem like ext4 handles correctly. This caused "Could not rename" errors in xEdit and similar tools. Now properly handles RENAME_NOREPLACE: checks if the destination exists in the VFS tree and returns EEXIST (matching ext4 behavior), otherwise proceeds with the rename. Adds diagnostic logging on EACCES failures. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add BethINI Pie tool pluginSulfurNitride2026-04-107-0/+544
| | | | | | | | | | | | | | | | Native IPluginTool that integrates BethINI Pie (performance INI editor) into the Tools menu. Auto-downloads the latest Linux build from GitHub releases, checks for updates via commit SHA, and pre-configures it for the current game and profile INI directory. Supports: Skyrim SE, Fallout 4, Fallout New Vegas, Starfield. Includes post-extraction fixes for PyInstaller bundle quirks: - Patches tm.tcl hardcoded Tcl module path - Symlinks apps/icons/fonts from _internal/ to executable directory - Sets TCL_LIBRARY/TK_LIBRARY env vars on launch Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix backup restore failing when destination file already existsSulfurNitride2026-04-101-0/+2
| | | | | | | | QFile::copy() does not overwrite existing files, unlike Windows SHFileOperation. Remove destination before copying to match the expected overwrite behavior. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Pin PyQt6 to 6.10.x to match bundled Qt versionSulfurNitride2026-04-081-1/+1
| | | | | | | PyQt6 6.11.0 requires Qt_6.11 symbols not present in our bundled Qt 6.10.2, causing all Python plugins to fail with ImportError. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Remove NaK/Rust dependency, port remaining functionality to native C++SulfurNitride2026-04-0865-8341/+2201
| | | | | | | | | | | | | | | Replace NaK Rust crate and nak_ffi with native C++ implementations: - Game detection (Steam, Heroic, Bottles), VDF parser, icon extraction - Prefix symlinks, SLR manager, Steam path detection - Known games database Add FUSE VFS optimizations: zero-copy reads via fuse_reply_data, default_permissions mount option, FUSE_CAP_ASYNC_DIO, FUSE_CAP_EXPIRE_ONLY, lookup cache parent index, cached mode bits, increased I/O buffer sizes. Update build system, prefix setup, and various fixes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Use fluorine data dir for NXM socket instead of XDG_RUNTIME_DIRSulfurNitride2026-04-061-4/+7
| | | | | | | | XDG_RUNTIME_DIR may point to a read-only location on Steam Deck (SteamOS has a read-only root filesystem). Use ~/.local/share/fluorine/tmp/ instead, which is always writable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Create parent directory for NXM socket if it doesn't existSulfurNitride2026-04-061-0/+7
| | | | | | | | | XDG_RUNTIME_DIR may point to a non-existent path on some configurations, causing QLocalServer::listen to fail with "Name error". Ensure the parent directory exists before attempting to create the socket. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix misleading "No Wine Prefix" error when launch binary not foundSulfurNitride2026-04-061-1/+1
| | | | | | | | | | ENOENT from process execution was always shown as "No Wine Prefix" when useProton was set, even when the prefix was properly configured. Now checks FluorineConfig::isSetup() first — if the prefix exists, falls through to the generic spawnFailed dialog which shows the actual missing binary path. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add VFS performance optimizations: node cache, lookup cache, access handlerSulfurNitride2026-04-063-29/+327
| | | | | | | | | | | | | - Add inode→VfsNode* cache to skip splitPath + full tree walks on lookup/getattr/open (O(1) hash lookup instead of tree traversal) - Combine canonicalChildName + snapshotForPath into single lookupChild function (one tree lock, one parent resolution, one child hash probe) - Add userspace lookup cache keyed by (parent_ino, normalized_name) to absorb Wine's case-variant probes that bypass the kernel FUSE dcache - Add mo2_access handler to avoid kernel fallback to lookup+getattr - Invalidate all caches correctly on tree mutations (create/unlink/rename/mkdir) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Consolidate prefix setup steps and update .NET versionsSulfurNitride2026-04-062-156/+127
| | | | | | | | | | | | | - Merge all DirectX June 2010 extractions into single "DirectX Runtimes" step (d3dcompiler_42/43/47, d3dx9, d3dx10, d3dx11_42/43, xinput, xact) - Merge .NET 6/7/8/9 runtimes into single "NET Runtimes (6-9)" step - Replace .NET 9 SDK with .NET 9 Runtime (9.0.14) - Add .NET 10 SDK (10.0.201) - Remove .NET Desktop Runtime 10 - Add xinput, d3dcompiler_42, d3dx10, d3dx11_42 extractions - Move .NET Desktop Runtime 6 before runtime installs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Replace winetricks dependency setup with native implementationsSulfurNitride2026-04-055-66/+664
| | | | | | | | | | | | | | | | | | | | Direct DLL extraction and installer execution instead of shelling out to winetricks for all prefix dependencies. Fixes d3dcompiler_47 being sourced from wrong SDK cabs (broke CommunityShaders), and eliminates the fragile cabextract-in-pressure-vessel PATH issue. - d3dcompiler_47: direct download from Mozilla fxc2 repo - d3dcompiler_43, d3dx9, d3dx11_43: cabextract from DirectX June 2010 redist with correct system32/syswow64 mapping - xact/xact_x64: cab extraction + batched regsvr32 registration - vcrun2022: direct installer with msvcp140.dll workaround (Wine #57518) - dotnet6/7/8, dotnetdesktop6: direct x86+x64 installer pairs - Game detection: batched into single .reg file import - All DLL overrides added to WINE_SETTINGS_REG - SHA256 verification for downloaded files - Winetricks kept only for win11 mode step Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add modl:// protocol support for mod.pub downloadsSulfurNitride2026-04-036-20/+46
| | | | | | | | | | | | | | Handle modl:// links alongside nxm:// for downloading mods from mod.pub. mod.pub uses a different URL format than Nexus — the download URL is embedded as a query parameter: modl://game/?url=<encoded-url> - Register x-scheme-handler/modl in desktop files and MIME lists - Accept both nxm and modl schemes in URL parsing (NxmLink, NXMUrl) - Parse modl:// direct download links and route to startDownloadURLs - Make key/expires optional in NxmLink::parse (not used by mod.pub) - Add debug logging for received URLs to aid troubleshooting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Replace Rust prefix setup with C++ step-by-step dialogSulfurNitride2026-04-038-160/+1723
| | | | | | | | | | | | | | | | | | | | Move Wine prefix creation from NaK Rust FFI to native C++ with a new modal dialog showing per-step progress, retry support, and proper failure cleanup. - PrefixSetupRunner: runs each step (proton init, drive cleanup, 11 individual winetricks verbs, .NET installers, game detection, wine registry, win11 mode, post-setup) as discrete retryable operations - PrefixSetupDialog: step list with status icons, filtered log output, cancel/retry-failed/delete-prefix buttons - Downloads use QNetworkAccessManager (no host curl dependency) - Zip extraction uses downloaded 7zz binary (no host unzip dependency) - Winetricks runs on host (not in pressure-vessel) so cabextract is always findable via PATH - Wine/winetricks debug spam filtered from log output - Skip Python basic_games proxy since native equivalent exists Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix cabextract not found in pressure-vessel and TTW game detectionSulfurNitride2026-04-033-16/+39
| | | | | | | | | | | | | | | | cabextract: The system binary under /usr is invisible inside the pressure-vessel container where winetricks runs. Always download a local copy to ~/.local/share/fluorine/bin/ instead of short-circuiting when the host has it installed. TTW: The game plugin was calling the base class identifyGamePath() which tried matching "TTW" against NaK's detected game names — never matching "Fallout New Vegas". Now explicitly searches for FNV in the NaK results, mirroring how the Windows path uses the FalloutNV registry key. Also adds HAS_NAK_FFI and nak_ffi linkage to the TTW CMake target since it was previously only defined for the game_gamebryo target. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Default new executables to Use Proton enabledSulfurNitride2026-04-021-1/+1
| | | | | | | | New executables added via the Modify Executables dialog now have "Use Proton" checked by default, matching user expectations for a Linux mod manager. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix SLR download failures and CMake rebuild detectionSulfurNitride2026-04-015-272/+293
| | | | | | | | | | | | | | | Replace SHA256SUMS verification with Content-Length check for SLR downloads. Valve's CDN frequently serves stale SHA256SUMS that don't match the current archive, causing persistent checksum mismatches. Fix CMake DEPENDS for nak_ffi to glob all .rs sources instead of hardcoding a few files — previously changes to slr.rs (and most other Rust files) were silently ignored by ninja. Also wrap prefix init and runtime commands through SLR pressure-vessel container, and expose Proton install directories to the container. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Enable multi-select in downloads tabSulfurNitride2026-03-311-0/+6
| | | | | | | | The downloadView widget was missing selectionMode and selectionBehavior properties, defaulting to SingleSelection. All other list views in the UI already had ExtendedSelection set. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix zenity symbol lookup errors when launching winetricksSulfurNitride2026-03-311-5/+22
| | | | | | | | | | The restoreOrig lambda only restored env vars when FLUORINE_ORIG_* was set, with no fallback. If those vars were missing, bundled library paths leaked into winetricks/zenity causing FcConfigSetDefaultSubstitute symbol errors. Now uses the same restoreOrStrip pattern as protonlauncher.cpp — strip paths containing "fluorine" as fallback. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Write logs to instance directory instead of CWDSulfurNitride2026-03-292-16/+3
| | | | | | | | | Logs were being created in the current working directory (defaulting to $HOME when launched from a desktop entry). Now uses the instance directory passed to setLogDirectory() so each instance gets its own logs/ folder. Removes unused FLUORINE_LAUNCH_DIR env var. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Block game launch when no Wine prefix is configuredSulfurNitride2026-03-291-6/+20
| | | | | | | | Instead of logging a warning and attempting to launch (which fails with EACCES), show a clear error dialog directing the user to Settings → Wine/Proton to create a prefix. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Block rootbuilder directory plugin in Python proxySulfurNitride2026-03-281-1/+2
| | | | | | | | The hard-blacklist in plugincontainer.cpp only catches rootbuilder at the top-level scan, but the Python proxy independently scans the plugins directory for packages (dirs with __init__.py) and was still loading it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add debug logging to game symlink creationSulfurNitride2026-03-281-0/+18
| | | | | | | | | | Log each game's prefix path, detected username, and whether the Documents/My Games directory exists. Also log when scan_and_link_all skips a game due to missing directories. This will help diagnose why some games are not getting their Documents folders symlinked during prefix setup. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Search all Steam library folders for game compatdataSulfurNitride2026-03-281-18/+20
| | | | | | | | | | Steam can place a game's compatdata in a different library folder than the game itself (e.g. game on SD card, compatdata on internal storage). Previously we only looked in the same steamapps directory as the appmanifest, causing games to have no prefix_path and their Documents/My Games folders to not get symlinked during prefix setup. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Clean bundled library paths before launching winetricksSulfurNitride2026-03-281-0/+19
| | | | | | | | | | Winetricks spawns kdialog/zenity for its GUI, which inherit Fluorine's LD_LIBRARY_PATH pointing at bundled Qt .so files. On SteamOS (Steam Deck) this causes symbol lookup errors in the system kdialog. Restore the original host library paths from FLUORINE_ORIG_* env vars before launching winetricks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Hard-blacklist rootbuilder plugin from loadingSulfurNitride2026-03-281-0/+11
| | | | | | | | RootBuilder is incompatible with Fluorine/Linux. Add a permanent hard blacklist (case-insensitive) in loadPlugins() so it is silently skipped for all users. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* VFS case-insensitive inode paths, Root Builder browse, multi-select download ↵SulfurNitride2026-03-2711-5/+184
| | | | | | | | | | | | | | | | | delete, hide LOOT sort - VFS: resolve canonical (mod-provided) case for inode paths instead of Wine's requested case, preventing duplicate Overwrite entries with mismatched casing - Root Builder: fix deployRootFiles not running (m_gameDir set too late, setRootBuilderEnabled missing from prepareVFS path) - Root Builder: add "Browse Root Builder" button to Data tab, opens game root with deployed Root files visible - Mod validity: treat mods with only a Root/ folder as valid when VFS Root Builder is enabled - Downloads: multi-select delete via Delete key and context menu - Hide LOOT Sort button on Linux Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Multi-dir plugin loading, VFS Root Builder, Wine registry check, column ↵SulfurNitride2026-03-2217-636/+770
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | visibility fix Plugin loading: - Remove symlink-based ensureBundledPluginsLinked(), replace with multi-dir search (bundled dir takes priority, instance dir adds extras only) - Auto-clean stale symlinks from instance plugins/ dirs on startup - Add mergedProxyList() for proxy plugin discovery across both dirs VFS Root Builder (replaces Python rootbuilder.py): - Native C++ Root Builder integrated into FuseConnector - Deploy mod Root/ files to game dir before FUSE mount, clear on unmount - Per-instance toggle in Instance Manager (default: on) - Root Builder path normalization in processrunner.cpp: rewrite binary and start-in paths from mods/.../Root/ to Game Root for correct Wine path resolution (fixes SKSE + EngineFixes versionlib lookup) - Expose game dir and prefix to SLR pressure-vessel via --filesystem= Wine registry check: - Read/write Wine prefix system.reg (HKLM) with timestamp-aware parsing - Auto-check game install path before launch, prompt to fix if mismatched - Updates both Software\ and Wow6432Node\ registry keys Column visibility fix: - Guard updateGroupByProxy() during QHeaderView::restoreState() to prevent sort indicator restoration from triggering setSourceModel() which resets all columns to visible Python proxy: - Skip FixGameRegKey.py, crashlogtools, rootbuilder.py (Windows-only or replaced by native implementations) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Raise open file descriptor limit to 65536 in all launchersSulfurNitride2026-03-213-0/+17
| | | | | | | | Large modlists (e.g. Gate To Sovngarde) exceed the default 1024 fd limit during FUSE VFS recursive directory iteration, causing "Too many open files" errors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add per-session timestamped log files in launch directory, keep last 5SulfurNitride2026-03-182-5/+31
| | | | | | | | | | Each launch creates a new mo_interface_YYYY-MM-DD_HH-MM-SS.log in a logs/ folder next to where fluorine-manager was run from. Old logs are cleaned up to keep only the 5 most recent. Launcher scripts export FLUORINE_LAUNCH_DIR before cd'ing to the bin directory so the C++ side knows the original working directory. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Steam game mode: strip LD_PRELOAD, robust looksValid(), restore env for ↵SulfurNitride2026-03-174-2/+61
| | | | | | | | | | | | | | | | | | games Steam injects 32-bit gameoverlayrenderer.so via LD_PRELOAD which causes "wrong ELF class" errors for 64-bit Qt6 apps. Save and clear LD_PRELOAD in both launcher and AppRun scripts, restore it in ProtonLauncher for game processes. Also hardens looksValid() with QFileInfo::exists() for absolute paths (QDir::exists() has edge cases with relative subdirectory paths), adds case-insensitive directory walking fallback, and adds debug logging to both looksValid() and detectGame(). Adds ~/.steam/debian-installation to Python steam_utils.py candidates. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Steam game mode: clear LD_LIBRARY_PATH, deploy native basic_games, add ↵SulfurNitride2026-03-174-4/+25
| | | | | | | | | | | | | | | | | | | | | env var detection Steam game mode injects its scout/soldier runtime into LD_LIBRARY_PATH, which breaks Python extension modules and Qt internals that resolve dependencies via LD_LIBRARY_PATH rather than RPATH. This caused all Python-based basic_games plugins (Witcher 3, Oblivion Remastered, BG3, etc.) to fail to load when launched through Steam. Changes: - Launcher script: set LD_LIBRARY_PATH to only bundled lib/ dir instead of leaving Steam's runtime in the path - AppRun: same fix — replace rather than append to LD_LIBRARY_PATH - Deploy libbasic_games_native.so in tarball (was built but never copied) so basic_games entries work without Python dependency - Add STEAM_COMPAT_CLIENT_INSTALL_PATH env var check to Python steam_utils.py (mirrors C++ fix from e41a79a) for game mode detection Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Steam game detection in game mode + add result cacheSulfurNitride2026-03-161-4/+26
| | | | | | | | | | | | | | | | | - Prepend STEAM_COMPAT_CLIENT_INSTALL_PATH as first Steam path candidate. Steam always sets this env var when launching any app (including in gamescope/game mode), so it reliably points to the correct Steam root even when $HOME resolves differently inside the gamescope session. - Canonicalize VDF-sourced library paths before dedup in getAllLibraryFolders() so /home/ ↔ /var/home/ symlinks (Bazzite/Fedora immutable distros) don't produce duplicate scan entries. - Cache findSteamGames() results in a static hash. Previously, findSteamGamePath() rebuilt the full library scan 45+ times per launch (once per registered game plugin). Now the scan runs at most once. Fixes game detection on Bazzite in Steam Game Mode. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix looksValid() for games with nested data directories (e.g. Oblivion ↵SulfurNitride2026-03-161-1/+20
| | | | | | | | | | | | | | | Remastered) Some UE5 games have their binary nested under a subdirectory of the Steam installdir even though the appmanifest points one level up. looksValid() was checking only for the binary at the game root, causing "does not seem to contain a game Mod Organizer can manage" when manually browsing. Add a fallback: if the binary isn't found at root, resolve the game's %GAME_PATH%-based dataDirectory and check if that path exists. The data path is unique enough to positively identify the game directory. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix stale symlink check in ensureBundledPluginsLinked for /var/home distrosSulfurNitride2026-03-161-1/+7
| | | | | | | | | | | | | | | On Bazzite (and other Fedora immutable distros), /home/ is a symlink to /var/home/. This caused the symlink staleness check to always fail when desktop mode and game mode resolved $HOME differently, deleting and re-creating plugin symlinks on every game-mode launch. If re-creation failed (e.g. race or gamescope restriction), libbasic_games.so would be missing from the per-instance plugin dir, producing the "game plugin 'Oblivion Remastered' doesn't exist" (PluginGone) error. Fix: use canonicalFilePath() on both sides of the comparison so paths that differ only by symlink component (/home/ vs /var/home/) compare equal. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix game domain override for all Nexus API request types (site mods)SulfurNitride2026-03-152-11/+21
| | | | | | | | | | | | | | | | | | The previous fix only overrode m_GameName in requestFileInfo and requestDownloadURL, but after the download completes STATE_FETCHINGMODINFO triggers requestDescription with the same fallback game plugin issue, causing 404s for nexusmods.com/site mods. Consolidate into applyGameNameOverride() helper called from: - requestFileInfo - requestDownloadURL - requestDescription - requestModInfo This ensures all API calls use "site" as the game domain when no matching game plugin is found. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix const mismatch: foundGame must be const IPluginGame* to accept m_ManagedGameSulfurNitride2026-03-151-1/+1
| | | | Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix NXM handler rejecting nexusmods.com/site tool downloadsSulfurNitride2026-03-152-13/+41
| | | | | | | | | | | | | | | | | | Tools like BethINI Pie use the "site" game domain on Nexus, which has no matching game plugin. Previously this triggered the "Wrong Game" error. Now "site" (and any other domain with no plugin) is allowed: - downloadmanager: detect "site" NXM links and allow download using managed game as context; propagate raw game name ("site") through pending tracking and API requests for correct Nexus API URLs - downloadmanager: in nxmFileInfoAvailable, default info->gameName to the raw game name before plugin lookup so "site" is preserved when no matching plugin is found - nexusinterface: override m_GameName with raw game name in both requestFileInfo and requestDownloadURL when the plugin is a fallback (i.e. doesn't actually match the requested game domain) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add Steam Linux Runtime (SLR) support + fix Use Proton defaultSulfurNitride2026-03-1518-14/+663
| | | | | | | | | | | | | | | | | | | | | | Steam Linux Runtime: - New Rust module (libs/nak/src/slr.rs): download SteamLinuxRuntime_sniper from repo.steampowered.com, SHA256 verification, BUILD_ID update checks - nak_ffi exports: nak_slr_is_installed, nak_slr_get_run_script, nak_download_slr - ProtonLauncher: wraps Proton launch inside SLR pressure-vessel container when enabled (run -- proton waitforexitandrun game.exe) - Instance Manager: SLR checkbox (default on) beside Steam DRM checkbox - Main window: pre-check downloads SLR before launch if needed - Proton settings tab: "Download Steam Linux Runtime" button - spawn.cpp: reads fluorine/use_slr per-instance INI key - Logs "Final command:" showing full assembled launch command Bug fixes: - Fix Use Proton off by default for plugin executables (executableslist.cpp) - Fix Use Proton off by default for file tree right-click (filetree.cpp) - Fix Fedora 43 Qt platform plugin crash: explicit QT_QPA_PLATFORM_PLUGIN_PATH - Add Qt6::Concurrent to CMakeLists for QtConcurrent background downloads Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix false 'libfuse3 not found' warning on Debian/UbuntuSulfurNitride2026-03-141-6/+23
| | | | | | | | | On Debian/Ubuntu, libfuse3-3 (runtime) installs libfuse3.so.3 but not the unversioned libfuse3.so symlink — that requires libfuse3-dev. Add .so.3 variants to the FUSE detection check so users with only the runtime package don't get a spurious warning. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix Qt version mixing: patchelf qt6plugins to use bundled lib/SulfurNitride2026-03-141-0/+6
| | | | | | | | | | | | | | | Qt platform plugins (libqxcb.so, libqxcb-glx-integration.so, etc.) kept aqtinstall's hardcoded RPATH (/opt/qt6/6.10.2/gcc_64/lib) which doesn't exist on user systems. The linker fell through to system Qt, loading the wrong version into the process link map. When PyQt6 bindings later loaded libQt6OpenGLWidgets, glibc reused the already-cached system version, causing private-API symbol mismatches against our bundled Qt 6.10 (seen on Mint, Bazzite, and likely all distros with system Qt installed). All Qt plugins are one subdir deep under qt6plugins/, so $ORIGIN/../../lib correctly resolves to our lib/ for all of them. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Bundle Qt libs missing from PyQt6 dep scan (fixes Bazzite crash)SulfurNitride2026-03-141-0/+16
| | | | | | | | | | | | PyQt6 is staged after the main dep-collection loop, so its .so deps (e.g. libQt6OpenGLWidgets) were never copied to lib/. The dynamic linker then fell back to the host's Qt RPM build, which exports Qt_6.*_PRIVATE_API version symbols that aqtinstall's Qt doesn't — causing a crash on Fedora- based distros (Bazzite, etc.) whenever a Python plugin imported PyQt6 OpenGL. Add a post-PyQt6 dep scan that bundles any Qt libs not yet present in lib/. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Bundle libxcb-cursor to fix Qt xcb platform plugin crashSulfurNitride2026-03-141-0/+11
| | | | | | | | | Qt >= 6.5.0 requires libxcb-cursor0 to load the xcb platform plugin, but it's frequently absent on user systems. All other libxcb libs are skipped (must match host X server ABI), but libxcb-cursor is a pure utility library safe to bundle. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Update README: add Building section and NixOS runtime requirementsSulfurNitride2026-03-131-0/+35
| | | | | | | | | - Replace Flatpak build/install instructions with Docker-based build.sh - Add Runtime Requirements section with unbundled library list - Add NixOS nix-ld configuration snippet (from PR #37 by Anseryde) - Update Installing section to reflect native tarball distribution Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix image link and clean up README.mdSulfurNitride2026-03-131-2/+1
| | | Updated image link in README.md and removed unnecessary HTML tags.
* Revise installation and running instructions in READMESulfurNitride2026-03-131-13/+2
| | | Updated installation instructions and clarified running commands.
* Fix DDS and winreg missing in Python pluginsSulfurNitride2026-03-132-3/+17
| | | | | | | | | | | - Stage DDS/ package from source directly to plugins/data/DDS/ in build-inner.sh (cmake MO2_STAGE_PYTHON_PLUGIN_PAYLOAD is OFF by default so the cmake-sourced path was silently skipped) - Stage winreg.py from libs/ directly as well (same root cause) - Guard `import winreg` in gog_utils.py with try/except ImportError and early-exit to Heroic GOG path if the shim is unavailable Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>