use std::{ error::Error, path::{Path, PathBuf}, }; use sqlite::State; use crate::platform::Platform; use super::{AmazonGame, AmazonSettings}; pub struct AmazonPlatform { pub settings: AmazonSettings, } impl Platform> for AmazonPlatform { #[cfg(windows)] fn enabled(&self) -> bool { self.settings.enabled } #[cfg(target_family = "unix")] fn enabled(&self) -> bool { false } fn name(&self) -> &str { "Amazon" } fn get_shortcuts(&self) -> Result, Box> { let sqllite_path = get_sqlite_path().expect("This should never get called if settings are invalid"); let launcher_path = get_launcher_path().expect("This should never get called if settings are invalid"); let mut result = vec![]; let connection = sqlite::open(sqllite_path)?; let mut statement = connection.prepare("SELECT Id, ProductTitle FROM DbSet WHERE Installed = 1")?; while let State::Row = statement.next().unwrap() { let id = statement.read::(0); let title = statement.read::(1); if let (Ok(id), Ok(title)) = (id, title) { result.push(AmazonGame { title, id, launcher_path: launcher_path.clone(), }); } } Ok(result) } fn settings_valid(&self) -> crate::platform::SettingsValidity { let path = get_sqlite_path(); let launcher = get_launcher_path(); if path.is_some() && launcher.is_some() { crate::platform::SettingsValidity::Valid } else { crate::platform::SettingsValidity::Invalid { reason: "Could not find Amazon Games installation".to_string(), } } } #[cfg(target_family = "unix")] fn create_symlinks(&self) -> bool { false } fn needs_proton(&self, _input: &AmazonGame) -> bool { false } } fn get_sqlite_path() -> Option { match std::env::var("LOCALAPPDATA") { Ok(localdata) => { let path = Path::new(&localdata) .join("Amazon Games") .join("Data") .join("Games") .join("Sql") .join("GameInstallInfo.sqlite"); if path.exists() { Some(path) } else { None } } Err(_e) => None, } } fn get_launcher_path() -> Option { match std::env::var("LOCALAPPDATA") { Ok(localdata) => { let path = Path::new(&localdata) .join("Amazon Games") .join("App") .join("Amazon Games.exe"); if path.exists() { Some(path) } else { None } } Err(_e) => None, } }