diff options
| author | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-02-20 23:53:26 -0600 |
|---|---|---|
| committer | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-02-20 23:53:26 -0600 |
| commit | d22d8c267b012729b6b84142def2a30ca4691d7a (patch) | |
| tree | 4d04382b6c9a44fa72ade906e0bf51e8f97855a8 /libs/nak/src/game_finder/mod.rs | |
| parent | 5467e210668eb24de9a4429ef0ddcbc6442e8932 (diff) | |
Fix AppImage plugin loading, save timestamps, and INI corruption
- Add AppConfig::pluginsPath()/dllsPath() that respect MO2_PLUGINS_DIR
and MO2_DLLS_DIR env vars, fixing plugin discovery when plugins live
inside read-only AppImage squashfs (#22, game plugin not found errors)
- Preserve file modification times in save deploy/sync so games display
correct save timestamps instead of all showing the same time (#17)
- Replace QSettings INI reader in saves tab with direct line-by-line
parser to avoid backslash-as-line-continuation corruption of
sLocalSavePath=__MO_Saves\ (#22, saves tab showing wrong directory)
- Add diagnostic logging to plugin symlink creation, save backup/restore
operations to help diagnose silent failures through prefix symlinks
- Fix Python SONAME mismatch in AppImage build (patch portable Python
SONAME to match librunner.so DT_NEEDED, preventing dual libpython load)
- Bundle PyQt6 Qt dependencies, improve RPATH for lib/ and plugins/
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'libs/nak/src/game_finder/mod.rs')
| -rw-r--r-- | libs/nak/src/game_finder/mod.rs | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/libs/nak/src/game_finder/mod.rs b/libs/nak/src/game_finder/mod.rs index c383c8a..600751a 100644 --- a/libs/nak/src/game_finder/mod.rs +++ b/libs/nak/src/game_finder/mod.rs @@ -20,7 +20,10 @@ use std::path::PathBuf; pub use bottles::detect_bottles_games; pub use heroic::detect_heroic_games; -pub use known_games::{find_by_gog_id, find_by_name, find_by_steam_id, KnownGame, KNOWN_GAMES}; +pub use known_games::{ + find_by_epic_id, find_by_gog_id, find_by_name, find_by_steam_id, find_by_title, KnownGame, + KNOWN_GAMES, +}; pub use registry::{read_registry_value, wine_path_to_linux}; pub use steam::{detect_steam_games, find_game_install_path, find_game_prefix_path, get_known_game}; @@ -161,10 +164,16 @@ impl GameScanResult { // Public API // ============================================================================ -/// Detect all installed games from all supported launchers +/// Detect all installed games from all supported launchers. +/// +/// Games are detected in priority order: Steam -> Heroic (GOG -> Epic) -> Bottles. +/// When the same game is found from multiple launchers, the higher-priority +/// detection is kept and duplicates are skipped. This ensures registry entries +/// (which are shared across storefronts) prefer Steam paths, then GOG, then Epic. pub fn detect_all_games() -> GameScanResult { let mut result = GameScanResult::default(); + // Detect in priority order: Steam first, then GOG (via Heroic), then Epic, then Bottles. let steam_games = detect_steam_games(); result.steam_count = steam_games.len(); result.games.extend(steam_games); @@ -177,9 +186,27 @@ pub fn detect_all_games() -> GameScanResult { result.bottles_count = bottles_games.len(); result.games.extend(bottles_games); + // Deduplicate: keep the first occurrence of each game (by registry_path), + // which respects the detection order (Steam > GOG > Epic > Bottles). + deduplicate_games(&mut result); + result } +/// Remove duplicate game detections, keeping the first (highest-priority) entry. +/// Two games are considered duplicates if they have the same registry_path. +fn deduplicate_games(result: &mut GameScanResult) { + let mut seen_registry_paths = std::collections::HashSet::new(); + result.games.retain(|game| { + if let Some(ref reg_path) = game.registry_path { + seen_registry_paths.insert(reg_path.clone()) + } else { + // Games without registry paths are always kept (no risk of conflict) + true + } + }); +} + /// Detect only Steam games pub fn detect_steam_only() -> GameScanResult { let steam_games = detect_steam_games(); |
