aboutsummaryrefslogtreecommitdiff
path: root/libs/nak/src/game_finder/known_games.rs
diff options
context:
space:
mode:
Diffstat (limited to 'libs/nak/src/game_finder/known_games.rs')
-rw-r--r--libs/nak/src/game_finder/known_games.rs386
1 files changed, 0 insertions, 386 deletions
diff --git a/libs/nak/src/game_finder/known_games.rs b/libs/nak/src/game_finder/known_games.rs
deleted file mode 100644
index 117b0c7..0000000
--- a/libs/nak/src/game_finder/known_games.rs
+++ /dev/null
@@ -1,386 +0,0 @@
-//! Known games configuration
-//!
-//! Contains metadata for games that NaK supports, including:
-//! - Steam App ID
-//! - GOG App ID
-//! - Epic Games Store App Name (Legendary/Heroic internal identifier)
-//! - My Games folder name (Documents/My Games/*)
-//! - AppData/Local folder name
-//! - Registry path for game detection
-
-/// Configuration for a known game
-#[derive(Debug, Clone)]
-pub struct KnownGame {
- /// Display name
- pub name: &'static str,
- /// Steam App ID
- pub steam_app_id: &'static str,
- /// GOG App ID (if available on GOG)
- pub gog_app_id: Option<&'static str>,
- /// Epic Games Store AppName / Legendary internal ID (if available on Epic)
- pub epic_app_id: Option<&'static str>,
- /// Folder name in Documents/My Games (if applicable)
- pub my_games_folder: Option<&'static str>,
- /// Folder name in AppData/Local (if applicable)
- pub appdata_local_folder: Option<&'static str>,
- /// Folder name in AppData/Roaming (if applicable)
- pub appdata_roaming_folder: Option<&'static str>,
- /// Registry path under HKLM\Software\ (for game detection)
- pub registry_path: &'static str,
- /// Registry value name for install path
- pub registry_value: &'static str,
- /// Expected folder name in steamapps/common/
- pub steam_folder: &'static str,
-}
-
-/// All known games that NaK supports
-pub const KNOWN_GAMES: &[KnownGame] = &[
- // Bethesda Games
- KnownGame {
- name: "Enderal",
- steam_app_id: "933480",
- gog_app_id: Some("1708684988"), // Enderal: Forgotten Stories on GOG
- epic_app_id: None,
- my_games_folder: Some("Enderal"),
- appdata_local_folder: None,
- appdata_roaming_folder: None,
- registry_path: r"Software\SureAI\Enderal",
- registry_value: "Install_Path",
- steam_folder: "Enderal",
- },
- KnownGame {
- name: "Enderal Special Edition",
- steam_app_id: "976620",
- gog_app_id: None, // Not on GOG (only original Enderal)
- epic_app_id: None,
- my_games_folder: Some("Enderal Special Edition"),
- appdata_local_folder: None,
- appdata_roaming_folder: None,
- registry_path: r"Software\SureAI\Enderal SE",
- registry_value: "installed path",
- steam_folder: "Enderal Special Edition",
- },
- KnownGame {
- name: "Fallout 3",
- steam_app_id: "22300",
- gog_app_id: Some("1454315831"), // Fallout 3 GOTY
- epic_app_id: Some("adeae8bbfc94427db57c7dfecce3f1d4"),
- my_games_folder: Some("Fallout3"),
- appdata_local_folder: Some("Fallout3"),
- appdata_roaming_folder: None,
- registry_path: r"Software\Bethesda Softworks\Fallout3",
- registry_value: "Installed Path",
- steam_folder: "Fallout 3",
- },
- KnownGame {
- name: "Fallout 4",
- steam_app_id: "377160",
- gog_app_id: Some("1998527297"), // Fallout 4 GOTY on GOG
- epic_app_id: Some("61d52ce4d09d41e48800c22784d13ae8"),
- my_games_folder: Some("Fallout4"),
- appdata_local_folder: Some("Fallout4"),
- appdata_roaming_folder: None,
- registry_path: r"Software\Bethesda Softworks\Fallout4",
- registry_value: "Installed Path",
- steam_folder: "Fallout 4",
- },
- KnownGame {
- name: "Fallout 4 VR",
- steam_app_id: "611660",
- gog_app_id: None,
- epic_app_id: None,
- my_games_folder: Some("Fallout4VR"),
- appdata_local_folder: None,
- appdata_roaming_folder: None,
- registry_path: r"Software\Bethesda Softworks\Fallout 4 VR",
- registry_value: "Installed Path",
- steam_folder: "Fallout 4 VR",
- },
- KnownGame {
- name: "Fallout New Vegas",
- steam_app_id: "22380",
- gog_app_id: Some("1454587428"), // Fallout NV Ultimate
- epic_app_id: Some("5daeb974a22a435988892319b3a4f476"),
- my_games_folder: Some("FalloutNV"),
- appdata_local_folder: Some("FalloutNV"),
- appdata_roaming_folder: None,
- registry_path: r"Software\Bethesda Softworks\FalloutNV",
- registry_value: "Installed Path",
- steam_folder: "Fallout New Vegas",
- },
- KnownGame {
- name: "Morrowind",
- steam_app_id: "22320",
- gog_app_id: Some("1440163901"), // Morrowind GOTY
- epic_app_id: None, // On Epic but internal AppName not yet known
- my_games_folder: Some("Morrowind"),
- appdata_local_folder: None,
- appdata_roaming_folder: None,
- registry_path: r"Software\Bethesda Softworks\Morrowind",
- registry_value: "Installed Path",
- steam_folder: "Morrowind",
- },
- KnownGame {
- name: "Oblivion",
- steam_app_id: "22330",
- gog_app_id: Some("1458058109"), // Oblivion GOTY Deluxe
- epic_app_id: None, // On Epic but internal AppName not yet known
- my_games_folder: Some("Oblivion"),
- appdata_local_folder: Some("Oblivion"),
- appdata_roaming_folder: None,
- registry_path: r"Software\Bethesda Softworks\Oblivion",
- registry_value: "Installed Path",
- steam_folder: "Oblivion",
- },
- KnownGame {
- name: "Skyrim",
- steam_app_id: "72850",
- gog_app_id: None, // Not on GOG (only SE/AE)
- epic_app_id: None, // Not on Epic (only SE/AE)
- my_games_folder: Some("Skyrim"),
- appdata_local_folder: Some("Skyrim"),
- appdata_roaming_folder: None,
- registry_path: r"Software\Bethesda Softworks\Skyrim",
- registry_value: "Installed Path",
- steam_folder: "Skyrim",
- },
- KnownGame {
- name: "Skyrim Special Edition",
- steam_app_id: "489830",
- gog_app_id: Some("1711230643"), // Skyrim SE on GOG
- epic_app_id: Some("ac82db5035584c7f8a2c548d98c86b2c"),
- my_games_folder: Some("Skyrim Special Edition"),
- appdata_local_folder: Some("Skyrim Special Edition"),
- appdata_roaming_folder: None,
- registry_path: r"Software\Bethesda Softworks\Skyrim Special Edition",
- registry_value: "Installed Path",
- steam_folder: "Skyrim Special Edition",
- },
- KnownGame {
- name: "Skyrim VR",
- steam_app_id: "611670",
- gog_app_id: None,
- epic_app_id: None,
- my_games_folder: Some("Skyrim VR"),
- appdata_local_folder: None,
- appdata_roaming_folder: None,
- registry_path: r"Software\Bethesda Softworks\Skyrim VR",
- registry_value: "Installed Path",
- steam_folder: "Skyrim VR",
- },
- KnownGame {
- name: "Starfield",
- steam_app_id: "1716740",
- gog_app_id: None, // Xbox/Steam exclusive
- epic_app_id: None,
- my_games_folder: Some("Starfield"),
- appdata_local_folder: None,
- appdata_roaming_folder: None,
- registry_path: r"Software\Bethesda Softworks\Starfield",
- registry_value: "Installed Path",
- steam_folder: "Starfield",
- },
- // CD Projekt RED Games
- KnownGame {
- name: "The Witcher 3",
- steam_app_id: "292030",
- gog_app_id: Some("1495134320"), // Witcher 3 GOTY
- epic_app_id: None,
- my_games_folder: Some("The Witcher 3"),
- appdata_local_folder: None,
- appdata_roaming_folder: None,
- registry_path: r"Software\CD Projekt Red\The Witcher 3",
- registry_value: "InstallFolder",
- steam_folder: "The Witcher 3 Wild Hunt",
- },
- KnownGame {
- name: "Cyberpunk 2077",
- steam_app_id: "1091500",
- gog_app_id: Some("1423049311"),
- epic_app_id: None,
- my_games_folder: None,
- appdata_local_folder: Some("CD Projekt Red/Cyberpunk 2077"),
- appdata_roaming_folder: None,
- registry_path: r"Software\CD Projekt Red\Cyberpunk 2077",
- registry_value: "InstallFolder",
- steam_folder: "Cyberpunk 2077",
- },
- // Other popular moddable games
- KnownGame {
- name: "Baldur's Gate 3",
- steam_app_id: "1086940",
- gog_app_id: Some("1456460669"),
- epic_app_id: None,
- my_games_folder: None,
- appdata_local_folder: Some("Larian Studios/Baldur's Gate 3"),
- appdata_roaming_folder: None,
- registry_path: r"Software\Larian Studios\Baldur's Gate 3",
- registry_value: "InstallDir",
- steam_folder: "Baldurs Gate 3",
- },
-];
-
-/// Alternative GOG App IDs that should map to the same game.
-/// Some games have multiple GOG product IDs (e.g. different editions).
-const GOG_ID_ALIASES: &[(&str, &str)] = &[
- // Morrowind: Vortex uses 1435828767, NaK primary is 1440163901
- ("1435828767", "1440163901"),
- // Skyrim Anniversary Edition is a separate GOG product but same game as SE
- ("1801825368", "1711230643"),
-];
-
-/// Find a known game by Steam App ID
-pub fn find_by_steam_id(app_id: &str) -> Option<&'static KnownGame> {
- let normalized_id = normalize_steam_id(app_id);
- KNOWN_GAMES.iter().find(|g| g.steam_app_id == normalized_id)
-}
-
-/// Find a known game by GOG App ID
-pub fn find_by_gog_id(app_id: &str) -> Option<&'static KnownGame> {
- // Direct match first
- if let Some(game) = KNOWN_GAMES.iter().find(|g| g.gog_app_id == Some(app_id)) {
- return Some(game);
- }
- // Check aliases: resolve alternate GOG ID to primary, then look up
- for &(alias, primary) in GOG_ID_ALIASES {
- if app_id == alias {
- return KNOWN_GAMES.iter().find(|g| g.gog_app_id == Some(primary));
- }
- }
- None
-}
-
-/// Find a known game by Epic Games Store AppName (Legendary/Heroic internal ID)
-pub fn find_by_epic_id(app_id: &str) -> Option<&'static KnownGame> {
- KNOWN_GAMES
- .iter()
- .find(|g| g.epic_app_id == Some(app_id))
-}
-
-/// Strip punctuation and collapse whitespace for fuzzy title matching.
-fn normalize_for_matching(s: &str) -> String {
- s.chars()
- .map(|c| if c.is_alphanumeric() || c == ' ' { c } else { ' ' })
- .collect::<String>()
- .split_whitespace()
- .collect::<Vec<_>>()
- .join(" ")
-}
-
-/// Find a known game by title, using fuzzy matching.
-/// Strips common suffixes like "Game of the Year Edition" for comparison.
-pub fn find_by_title(title: &str) -> Option<&'static KnownGame> {
- let title_lower = title.to_lowercase();
-
- // Exact match first
- if let Some(game) = KNOWN_GAMES.iter().find(|g| g.name.to_lowercase() == title_lower) {
- return Some(game);
- }
-
- // Check if the title starts with or contains a known game name
- // Sort by name length descending so "Skyrim Special Edition" matches before "Skyrim"
- let mut games_by_name_len: Vec<&KnownGame> = KNOWN_GAMES.iter().collect();
- games_by_name_len.sort_by(|a, b| b.name.len().cmp(&a.name.len()));
-
- // Normalize both title and game names: strip colons and extra whitespace for comparison
- let title_normalized = normalize_for_matching(&title_lower);
-
- for game in games_by_name_len {
- let game_lower = game.name.to_lowercase();
- let game_normalized = normalize_for_matching(&game_lower);
-
- // Direct containment (e.g. "Fallout 3: Game of the Year Edition" contains "Fallout 3")
- if title_lower.contains(&game_lower) {
- return Some(game);
- }
-
- // Normalized containment (e.g. "Fallout: New Vegas" normalized to "fallout new vegas"
- // matches game name "Fallout New Vegas" normalized to "fallout new vegas")
- if title_normalized.contains(&game_normalized) {
- return Some(game);
- }
-
- // After-colon match: "The Elder Scrolls III: Morrowind" -> check "Morrowind"
- if let Some(after_colon) = title_lower.split(':').nth(1) {
- let after_colon = after_colon.trim();
- if after_colon.starts_with(&game_lower) {
- return Some(game);
- }
- }
- }
-
- None
-}
-
-/// Find a known game by name (case-insensitive)
-pub fn find_by_name(name: &str) -> Option<&'static KnownGame> {
- let name_lower = name.to_lowercase();
- KNOWN_GAMES
- .iter()
- .find(|g| g.name.to_lowercase() == name_lower)
-}
-
-/// Normalize Steam App IDs that have equivalent variants.
-fn normalize_steam_id(app_id: &str) -> &str {
- match app_id {
- // Fallout 3 often appears as GOTY App ID 22370.
- // We treat it as Fallout 3 for shared metadata/registry mapping.
- "22370" => "22300",
- _ => app_id,
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn fallout_3_goty_alias_maps_to_fallout_3() {
- let game = find_by_steam_id("22370").expect("22370 should map to Fallout 3");
- assert_eq!(game.name, "Fallout 3");
- assert_eq!(game.steam_app_id, "22300");
- }
-
- #[test]
- fn find_by_epic_id_works() {
- let game = find_by_epic_id("ac82db5035584c7f8a2c548d98c86b2c")
- .expect("Should find Skyrim SE by Epic ID");
- assert_eq!(game.name, "Skyrim Special Edition");
- }
-
- #[test]
- fn gog_alias_maps_correctly() {
- // Skyrim Anniversary Edition GOG ID maps to Skyrim SE
- let game = find_by_gog_id("1801825368")
- .expect("Skyrim AE GOG ID should map to Skyrim SE");
- assert_eq!(game.name, "Skyrim Special Edition");
- }
-
- #[test]
- fn find_by_title_matches_full_titles() {
- let game = find_by_title("The Elder Scrolls III: Morrowind Game of the Year Edition")
- .expect("Should find Morrowind by full Epic title");
- assert_eq!(game.name, "Morrowind");
- }
-
- #[test]
- fn find_by_title_matches_colon_titles() {
- let game = find_by_title("The Elder Scrolls IV: Oblivion Game of the Year Edition")
- .expect("Should find Oblivion by full title");
- assert_eq!(game.name, "Oblivion");
- }
-
- #[test]
- fn find_by_title_prefers_longer_match() {
- let game = find_by_title("Skyrim Special Edition")
- .expect("Should find Skyrim SE, not Skyrim");
- assert_eq!(game.name, "Skyrim Special Edition");
- }
-
- #[test]
- fn find_by_title_fallout_nv() {
- let game = find_by_title("Fallout: New Vegas Ultimate Edition")
- .expect("Should find Fallout NV");
- assert_eq!(game.name, "Fallout New Vegas");
- }
-}