From 9f2da3be274115d90ce74cd33da5b9722674be7d Mon Sep 17 00:00:00 2001 From: Rolv Apneseth Date: Sat, 2 May 2026 17:04:53 +0100 Subject: [PATCH 1/3] fix(lutris): only show installed games When a user logs in, games attached to their profile will all appear in this DB table, even if not installed. --- src/linux/launchers/lutris.rs | 6 ++++-- .../linux/.local/share/lutris/pga.db | Bin 40960 -> 40960 bytes 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/linux/launchers/lutris.rs b/src/linux/launchers/lutris.rs index 8a93114..d855eae 100644 --- a/src/linux/launchers/lutris.rs +++ b/src/linux/launchers/lutris.rs @@ -19,8 +19,7 @@ use crate::{ }; // DB DATA -------------------------------------------------------------------------------- -const PGA_DB_QUERY: &str = - "SELECT id, name, slug, installer_slug, parent_slug, directory, playtime FROM games;"; +const PGA_DB_QUERY: &str = "SELECT id, name, slug, installer_slug, parent_slug, directory, playtime, installed FROM games;"; /// Data returned directly by the query to the pga.db #[derive(Debug, Clone)] @@ -30,6 +29,7 @@ struct DbRow { slug: String, installer_slug: Option, game_dir: Option, + installed: bool, _parent_slug: Option, _playtime: Option, } @@ -46,6 +46,7 @@ impl<'stmt> TryFrom<&rusqlite::Row<'stmt>> for DbRow { _parent_slug: row.get("parent_slug")?, game_dir: row.get("directory")?, _playtime: row.get("playtime")?, + installed: row.get("installed")?, }) } } @@ -125,6 +126,7 @@ impl Lutris { stmt.query(params![]) .inspect_err(|e| error!("{LAUNCHER} - failed to execute DB query: {e}"))? .map(|r| DbRow::try_from(r)) + .filter(|r| Ok(r.installed)) .collect::>() .inspect(|rows| { if rows.is_empty() { diff --git a/tests/file_system_mocks/linux/.local/share/lutris/pga.db b/tests/file_system_mocks/linux/.local/share/lutris/pga.db index be6bb4293c16c84fc31f1922eed349865b441e7e..1a8df13f60194e3fd5df04943b7d467b289171cc 100644 GIT binary patch delta 115 zcmZoTz|?SnX@WGP+(a2?RyhW}sV6q3EZ`Sn=ibS{@5{HJ_ZcrYPY3sR?wy+z1r~GL z*|1A67y=;#aBy&d86Yw&zo;a&LcupbMZq^QFEKr}s0=Kko134an+p-y{9T%}1pwA8 BAKL%` delta 50 zcmV-20L}k^zyg540+1U49g!SE1swn`jry@ Date: Sat, 2 May 2026 17:28:27 +0100 Subject: [PATCH 2/3] chore: lint --- src/linux/launchers/bottles.rs | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/linux/launchers/bottles.rs b/src/linux/launchers/bottles.rs index 0e9284b..3eef1dd 100644 --- a/src/linux/launchers/bottles.rs +++ b/src/linux/launchers/bottles.rs @@ -222,13 +222,9 @@ impl Bottles { let mut parsed_games_data: Vec = Vec::new(); let mut file_content_str: &str = &file_content; - loop { - let Ok((new_file_content, parsed_data)) = parse_game_from_bottle_yml(file_content_str) - else { - break; - }; + while let Ok((new_file_content, parsed_data)) = parse_game_from_bottle_yml(file_content_str) + { file_content_str = new_file_content; - parsed_games_data.push(parsed_data) } @@ -263,13 +259,9 @@ impl Bottles { let mut parsed_data: Vec = Vec::new(); let mut library_file_content_str: &str = &library_file_content; - loop { - let Ok((new_library_file_content, parsed_library_data)) = - parse_game_from_library(library_file_content_str) - else { - break; - }; - + while let Ok((new_library_file_content, parsed_library_data)) = + parse_game_from_library(library_file_content_str) + { library_file_content_str = new_library_file_content; parsed_data.push(parsed_library_data); } From 5f22988f2a86de8b51c29d3a87b599123a002466 Mon Sep 17 00:00:00 2001 From: Rolv Apneseth Date: Sat, 2 May 2026 23:55:11 +0100 Subject: [PATCH 3/3] fix!(lutris): ignore Steam entries from Lutris to avoid duplicates --- src/linux/launchers/lutris.rs | 13 ++++++++++++- .../linux/.local/share/lutris/pga.db | Bin 40960 -> 40960 bytes 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/linux/launchers/lutris.rs b/src/linux/launchers/lutris.rs index d855eae..864fd08 100644 --- a/src/linux/launchers/lutris.rs +++ b/src/linux/launchers/lutris.rs @@ -19,12 +19,16 @@ use crate::{ }; // DB DATA -------------------------------------------------------------------------------- -const PGA_DB_QUERY: &str = "SELECT id, name, slug, installer_slug, parent_slug, directory, playtime, installed FROM games;"; +const PGA_DB_QUERY: &str = "\ + SELECT id, name, slug, installer_slug, parent_slug, directory, playtime, installed, runner \ + FROM games;\ +"; /// Data returned directly by the query to the pga.db #[derive(Debug, Clone)] struct DbRow { run_id: String, + runner: Option, title: String, slug: String, installer_slug: Option, @@ -40,6 +44,7 @@ impl<'stmt> TryFrom<&rusqlite::Row<'stmt>> for DbRow { fn try_from(row: &rusqlite::Row) -> std::result::Result { Ok(Self { run_id: row.get::<&str, i32>("id")?.to_string(), + runner: row.get("runner")?, title: row.get("name")?, slug: row.get("slug")?, installer_slug: row.get("installer_slug")?, @@ -127,6 +132,12 @@ impl Lutris { .inspect_err(|e| error!("{LAUNCHER} - failed to execute DB query: {e}"))? .map(|r| DbRow::try_from(r)) .filter(|r| Ok(r.installed)) + // WARN: Ignore Steam entries entirely. + // This is more of an opinion, as these lead to duplicate entries, + // and do not inherently belong to Lutris anyway (will still just + // launch through Steam). Feel free to start a discussion if you disagree. + // See: https://github.com/Rolv-Apneseth/lib_game_detector/issues/53 + .filter(|r| Ok(r.runner.as_ref().is_none_or(|s| s != "steam"))) .collect::>() .inspect(|rows| { if rows.is_empty() { diff --git a/tests/file_system_mocks/linux/.local/share/lutris/pga.db b/tests/file_system_mocks/linux/.local/share/lutris/pga.db index 1a8df13f60194e3fd5df04943b7d467b289171cc..f23f858c03ac6527a3353123fa2bfdd10082e4f8 100644 GIT binary patch delta 149 zcmZoTz|?SnX@WGP{6raNM){2iOZY`NxWgIvefjqDKI7%)>EQm(y^}k9v!Z}KcTxg} z1cNMttSW=JI0FL%2PX%EHHa3MWN<3VPs=Y#PECT+#U-hUxw=N?CWe*