use std::path::PathBuf; #[derive(Default, Clone, Debug)] pub struct EpicPaths { pub(crate) launcher_path: PathBuf, pub(crate) compat_folder_path: Option, pub(crate) manifest_folder_path: PathBuf, } pub fn get_locations() -> Option { #[cfg(target_family = "unix")] { unix::get_locations() } #[cfg(target_os = "windows")] { windows::get_locations() } } #[cfg(target_family = "unix")] mod unix { use super::EpicPaths; use std::path::Path; pub fn get_locations() -> Option { if let Ok(home) = std::env::var("HOME") { let compat_folder_path = Path::new(&home) .join(".steam") .join("steam") .join("steamapps") .join("compatdata"); if let Ok(compat_folder) = std::fs::read_dir(&compat_folder_path) { for dir in compat_folder.flatten() { let binary_path = dir .path() .join("pfx") .join("drive_c") .join("Program Files (x86)") .join("Epic Games") .join("Launcher") .join("Engine") .join("Binaries"); if binary_path.exists() { let launcher_path = if binary_path .join("Win32") .join("EpicGamesLauncher.exe") .exists() { binary_path.join("Win32").join("EpicGamesLauncher.exe") } else { binary_path.join("Win64").join("EpicGamesLauncher.exe") }; if launcher_path.exists() { //We found a launcher, lets find the manifests let manifest_folder_path = dir .path() .join("pfx") .join("drive_c") .join("ProgramData") .join("Epic") .join("EpicGamesLauncher") .join("Data") .join("Manifests"); if manifest_folder_path.exists() { //We found all we need return Some(EpicPaths { launcher_path, compat_folder_path: Some(dir.path().to_path_buf()), manifest_folder_path, }); } } } } } } None } } #[cfg(target_os = "windows")] mod windows { use super::EpicPaths; use std::{path::{Path, PathBuf}, env}; fn manifest_location_from_registry() -> Option { use winreg::enums::*; use winreg::RegKey; let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); if let Ok(launcher) = hklm.open_subkey("SOFTWARE\\WOW6432Node\\Epic Games\\EpicGamesLauncher") { let path_string: Result = launcher.get_value("AppDataPath"); if let Ok(path_string) = path_string { let path = Path::new(&path_string).join("Manifests"); if path.exists() { return Some(path); } } } None } fn guess_default_launcher_location() -> PathBuf { let key = "SYSTEMDRIVE"; let system_drive = env::var(key).expect("We are on windows, we must know what the SYSTEMDRIVE is"); let path = Path::new(format!("{}\\", system_drive).as_str()) .join("Program Files (x86)") .join("Epic Games") .join("Launcher") .join("Portal") .join("Binaries") .join("Win64") .join("EpicGamesLauncher.exe"); path } fn launcher_location_from_registry() -> Option { use winreg::enums::*; use winreg::RegKey; let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); if let Ok(launcher) = hklm.open_subkey("SOFTWARE\\Classes\\com.epicgames.launcher\\shell\\open\\command") { let launch_string: Result = launcher.get_value(""); if let Ok(launch_string) = launch_string { let path = Path::new(&launch_string[1..launch_string.len() - 4]); if path.exists() { return Some(path.to_path_buf()); } } } None } fn guess_default_manifest_location() -> PathBuf { let key = "SYSTEMDRIVE"; let system_drive = env::var(key).expect("We are on windows, we must know what the SYSTEMDRIVE is"); let path = Path::new(format!("{}\\", system_drive).as_str()) .join("ProgramData") .join("Epic") .join("EpicGamesLauncher") .join("Data") .join("Manifests"); path } pub fn get_locations() -> Option { { let manifest_folder_path = manifest_location_from_registry() .unwrap_or_else(guess_default_manifest_location); let launcer_path = launcher_location_from_registry() .unwrap_or_else(guess_default_launcher_location); if launcer_path.exists() && manifest_folder_path.exists() { Some(EpicPaths { compat_folder_path: None, manifest_folder_path, launcher_path: launcer_path, }) } else { None } } } }