use crate::platform::Platform; use std::error::Error; #[cfg(target_os = "windows")] use std::path::Path; #[cfg(target_os = "windows")] use std::path::PathBuf; use super::{game::Game, settings::UplaySettings}; pub struct Uplay { pub settings: UplaySettings, } impl Platform> for Uplay { fn enabled(&self) -> bool { #[cfg(target_family = "unix")] { false } #[cfg(target_os = "windows")] { self.settings.enabled } } fn name(&self) -> &str { "Uplay" } fn settings_valid(&self) -> crate::platform::SettingsValidity { #[cfg(target_family = "unix")] { //Linux not supported yet crate::platform::SettingsValidity::Invalid { reason: "Linux not supported yet".to_string(), } } #[cfg(target_os = "windows")] { if get_launcher_path().is_some() { crate::platform::SettingsValidity::Valid } else { crate::platform::SettingsValidity::Invalid { reason: "Could not find UPlay instalation".to_string(), } } } } fn get_shortcuts(&self) -> Result, Box> { #[cfg(target_family = "unix")] { Ok(vec![]) } #[cfg(target_os = "windows")] { get_games_from_winreg() } } #[cfg(target_family = "unix")] fn create_symlinks(&self) -> bool { false } fn needs_proton(&self, _input: &Game) -> bool { #[cfg(target_os = "windows")] return false; #[cfg(target_family = "unix")] { //TODO update this when uplay gets proton support on linux true } } } #[cfg(target_os = "windows")] fn get_launcher_path() -> Option { use winreg::enums::*; use winreg::RegKey; let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); if let Ok(launcher_key) = hklm.open_subkey("SOFTWARE\\WOW6432Node\\Ubisoft\\Launcher") { let launcher_dir: Result = launcher_key.get_value("InstallDir"); if let Ok(launcher_dir) = launcher_dir { let path = Path::new(&launcher_dir).join("upc.exe"); if path.exists() { return Some(path); } } } None } #[cfg(target_os = "windows")] fn get_games_from_winreg() -> Result, Box> { use winreg::enums::*; use winreg::RegKey; let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); let mut games = vec![]; let mut installed_ids = vec![]; let launcher_path = get_launcher_path().expect("This should only be called if launcher is found"); if let Ok(installs) = hklm.open_subkey("SOFTWARE\\WOW6432Node\\Ubisoft\\Launcher\\Installs") { for i in installs.enum_keys().filter_map(|i| i.ok()) { if let Ok(install) = installs.open_subkey(&i) { let install_dir: Result = install.get_value("InstallDir"); if let Ok(folder) = install_dir { let path = Path::new(&folder); if path.exists() { installed_ids.push(i); } } } } } for id in installed_ids { let path = format!("SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Uplay Install {}",id); let subkey = hklm.open_subkey(path); if let Ok(subkey) = subkey { let name: Result = subkey.get_value("DisplayName"); if let Ok(name) = name { let icon: String = subkey.get_value("DisplayIcon").unwrap_or_default(); games.push(Game { name, icon, id, launcher: launcher_path.clone(), }) } } } Ok(games) }