From 96cb429382dace2718e578f425a9cdb147fa71c2 Mon Sep 17 00:00:00 2001 From: Philip Kristoffersen Date: Thu, 7 Apr 2022 23:12:40 +0200 Subject: [PATCH] Origin proton (#73) Find and add games from origin when installed with proton --- gui/mainview.fl | 4 -- src/origin/origin_game.rs | 30 +++++++++- src/origin/origin_platform.rs | 102 +++++++++++++++++++++++----------- src/origin/settings.rs | 1 - src/ui/ui.rs | 15 +---- 5 files changed, 99 insertions(+), 53 deletions(-) diff --git a/gui/mainview.fl b/gui/mainview.fl index f36af76..6c437c6 100644 --- a/gui/mainview.fl +++ b/gui/mainview.fl @@ -75,10 +75,6 @@ class UserInterface {open label Origin xywh {25 275 155 25} down_box DOWN_BOX } - Fl_Input origin_folder_input { - label {Origin Data Folder} - xywh {175 275 300 25} align 5 - } } # ----- GOG ----- diff --git a/src/origin/origin_game.rs b/src/origin/origin_game.rs index 3f48fb7..396d364 100644 --- a/src/origin/origin_game.rs +++ b/src/origin/origin_game.rs @@ -1,16 +1,40 @@ +use std::path::PathBuf; + use steam_shortcuts_util::{shortcut::ShortcutOwned, Shortcut}; #[derive(Clone)] pub struct OriginGame { pub id: String, pub title: String, + pub origin_location : Option, } impl From for ShortcutOwned { fn from(game: OriginGame) -> Self { - let launch = format!("origin2://game/launch?offerIds={}&autoDownload=1", game.id); - let shortcut = Shortcut::new("0", game.title.as_str(), launch.as_str(), "", "", "", ""); - let mut owned_shortcut = shortcut.to_owned(); + let launch = format!("\"origin2://game/launch?offerIds={}&autoDownload=1&authCode=&cmdParams=\"", game.id); + + let mut owned_shortcut = if let Some(origin_location) = game.origin_location{ + let origin_location = format!("\"{}\"",origin_location.to_string_lossy()); + Shortcut::new( + "0", + game.title.as_str(), + &origin_location, + "", + "", + "", + launch.as_str() + ).to_owned() + }else{ + Shortcut::new( + "0", + game.title.as_str(), + launch.as_str(), + "", + "", + "", + "" + ).to_owned() + }; owned_shortcut.tags.push("Origin".to_owned()); owned_shortcut.tags.push("Ready TO Play".to_owned()); owned_shortcut.tags.push("Installed".to_owned()); diff --git a/src/origin/origin_platform.rs b/src/origin/origin_platform.rs index 6f04b58..f6bb60a 100644 --- a/src/origin/origin_platform.rs +++ b/src/origin/origin_platform.rs @@ -27,24 +27,20 @@ impl Platform for OriginPlatform { } fn get_shortcuts(&self) -> Result, OriginErrors> { - let origin_folder = Path::new( - &self - .settings - .path - .clone() - .unwrap_or_else(get_default_location), - ) - .join("LocalContent"); - if !origin_folder.exists() { - return Err(OriginErrors::PathNotFound { - path: origin_folder.to_str().unwrap().to_string(), - }); + + let origin_folders = get_default_locations(); + if origin_folders.local_content_path.is_none(){ + return Err(OriginErrors::PathNotFound { path: "Default path".to_string() }); } + + let origin_folder = origin_folders.local_content_path.unwrap(); + let origin_exe = origin_folders.exe_path; let game_folders = origin_folder + .join("LocalContent") .read_dir() .map_err(|e| OriginErrors::CouldNotReadGameDir { - path: origin_folder, + path: origin_folder.join("LocalContent"), error: format!("{:?}", e), })?; let games = game_folders @@ -61,6 +57,7 @@ impl Platform for OriginPlatform { id.map(|id| OriginGame { id, title: game_title, + origin_location:origin_exe.clone() }) }); Ok(games.collect()) @@ -87,6 +84,7 @@ impl Platform for OriginPlatform { } } + fn get_folder_mfst_file_content(game_folder_path: &Path) -> Option { let game_folder_files = game_folder_path.read_dir(); if let Ok(game_folder_files) = game_folder_files { @@ -116,29 +114,71 @@ fn parse_id_from_file(i: &str) -> nom::IResult<&str, &str> { take_until("&")(i) } -#[cfg(target_family = "unix")] -pub fn get_default_location() -> String { - //TODO implement this for linux: - // https://www.toptensoftware.com/blog/running-ea-origin-games-under-linux-via-steam-and-proton/ - //If we don't have a home drive we have to just die - let home = std::env::var("HOME").expect("Expected a home variable to be defined"); - Path::new(&home) - .join("Games/origin/drive_c/ProgramData/Origin/") - .to_str() - .unwrap() - .to_string() +#[derive(Default)] +struct OriginPathData{ + //~/.steam/steam/steamapps/compatdata/X/pfx/drive_c/Program Files (x86)/Origin/Origin.exe + exe_path:Option, + //~/.steam/steam/steamapps/compatdata/X/pfx/drive_c/ProgramData/Origin/LocalContent + local_content_path:Option } + + +#[cfg(target_family = "unix")] + fn get_default_locations() -> OriginPathData { + let mut res = OriginPathData::default(); + 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 game_folder in compat_folder { + if let Ok(dir) = game_folder{ + let origin_exe_path= dir.path() + .join("pfx") + .join("drive_c") + .join("Program Files (x86)") + .join("Origin") + .join("Origin.exe"); + + let origin_local_content= dir.path() + .join("pfx") + .join("drive_c") + .join("ProgramData") + .join("Origin"); + + if origin_exe_path.exists() && origin_local_content.exists(){ + res.exe_path = Some(origin_exe_path); + res.local_content_path = Some(origin_local_content); + } + } + } + } + } + res +} + + + + #[cfg(target_os = "windows")] -pub fn get_default_location() -> String { +fn get_default_locations() -> OriginPathData { + let mut res = OriginPathData::default(); + let key = "PROGRAMDATA"; - let program_data = std::env::var(key).expect("Expected a APPDATA variable to be defined"); - Path::new(&program_data) - .join("Origin") - .to_str() - .unwrap() - .to_string() + let program_data = std::env::var(key); + if let Ok(program_data) =program_data { + let origin_folder = Path::new(&program_data) + .join("Origin"); + if origin_folder.exists(){ + res.exe_path = Some(origin_folder.to_owned()); + } + } + res } #[derive(Debug, Fail)] diff --git a/src/origin/settings.rs b/src/origin/settings.rs index b8ecdd2..a0e8fab 100644 --- a/src/origin/settings.rs +++ b/src/origin/settings.rs @@ -4,5 +4,4 @@ use serde::{Deserialize, Serialize}; pub struct OriginSettings { pub enabled: bool, - pub path: Option, } diff --git a/src/ui/ui.rs b/src/ui/ui.rs index 9790d12..f0d1e47 100644 --- a/src/ui/ui.rs +++ b/src/ui/ui.rs @@ -73,7 +73,6 @@ fn update_settings_with_ui_values(settings: &mut Settings, ui: &UserInterface) { // Origin settings.origin.enabled = ui.enable_origin_checkbox.value(); - settings.origin.path = empty_or_whitespace(ui.origin_folder_input.value()); // Epic settings.epic_games.enabled = ui.enable_egs_checkbox.value(); @@ -107,7 +106,7 @@ fn save_settings_to_file(settings: &Settings) { fn update_ui_with_settings(ui: &mut UserInterface, settings: &Settings) { use std::path::Path; - use crate::{gog, itch, origin, steam}; + use crate::{gog, itch, steam}; ui.steam_location_input.set_value( &settings @@ -167,18 +166,6 @@ fn update_ui_with_settings(ui: &mut UserInterface, settings: &Settings) { .unwrap_or(default_itch_location), ); ui.enable_origin_checkbox.set_value(settings.origin.enabled); - let mut default_origin_location = origin::get_default_location(); - if !Path::new(&default_origin_location).exists() { - default_origin_location = String::from(""); - } - ui.origin_folder_input.set_value( - &settings - .origin - .path - .clone() - .unwrap_or(default_origin_location), - ); - ui.enable_gog_checkbox.set_value(settings.gog.enabled); let default_gog_location = gog::default_location(); let default_gog_location = if !default_gog_location.exists() {