From deacef37591131c758229c1cec0738f2412a217c Mon Sep 17 00:00:00 2001 From: Observer KRypt0n_ Date: Sat, 8 Apr 2023 19:46:28 +0200 Subject: [PATCH] feat(core): implemented SDK 0.5.12 This change allows to support game edition switching in settings --- Cargo.lock | 4 +- Cargo.toml | 2 +- src/main.rs | 2 +- src/ui/first_run/default_paths.rs | 37 ++++++++++----- src/ui/main/apply_patch.rs | 2 +- src/ui/main/download_diff.rs | 3 +- src/ui/main/mod.rs | 13 ++++-- src/ui/main/repair_game.rs | 18 +++---- src/ui/preferences/general.rs | 78 ++++++++++++++++++++++++++----- 9 files changed, 118 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a11a135..c64db32 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -86,8 +86,8 @@ dependencies = [ [[package]] name = "anime-launcher-sdk" -version = "0.5.11" -source = "git+https://github.com/an-anime-team/anime-launcher-sdk?tag=0.5.11#46547a886f51ba8c58918c0903273c3d3c63d5fa" +version = "0.5.12" +source = "git+https://github.com/an-anime-team/anime-launcher-sdk?tag=0.5.12#06f0f486b9e099fc96db71be339332e1961dd0f6" dependencies = [ "anime-game-core", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index c1cbad7..6a3bca9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ glib-build-tools = "0.17" [dependencies.anime-launcher-sdk] git = "https://github.com/an-anime-team/anime-launcher-sdk" -tag = "0.5.11" +tag = "0.5.12" # path = "../anime-launcher-sdk" # ! for dev purposes only diff --git a/src/main.rs b/src/main.rs index 95eb775..70c2f77 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,7 +37,7 @@ lazy_static::lazy_static! { /// This one is used to prepare some launcher UI components on start pub static ref CONFIG: config::Config = config::get().expect("Failed to load config"); - pub static ref GAME: Game = Game::new(&CONFIG.game.path); + pub static ref GAME: Game = Game::new(CONFIG.game.path.for_edition(CONFIG.launcher.edition)); /// Path to launcher folder. Standard is `$HOME/.local/share/anime-game-launcher` pub static ref LAUNCHER_FOLDER: PathBuf = launcher_dir().expect("Failed to get launcher folder"); diff --git a/src/ui/first_run/default_paths.rs b/src/ui/first_run/default_paths.rs index d2543d9..78cc320 100644 --- a/src/ui/first_run/default_paths.rs +++ b/src/ui/first_run/default_paths.rs @@ -18,7 +18,8 @@ pub struct DefaultPathsApp { runners: PathBuf, dxvks: PathBuf, prefix: PathBuf, - game: PathBuf, + game_global: PathBuf, + game_china: PathBuf, fps_unlocker: PathBuf, components: PathBuf, patch: PathBuf, @@ -31,7 +32,8 @@ pub enum Folders { Runners, DXVK, Prefix, - Game, + GameGlobal, + GameChina, FpsUnlocker, Components, Patch, @@ -144,9 +146,20 @@ impl SimpleAsyncComponent for DefaultPathsApp { set_activatable: true, #[watch] - set_subtitle: model.game.to_str().unwrap(), + set_subtitle: model.game_global.to_str().unwrap(), - connect_activated => DefaultPathsAppMsg::ChoosePath(Folders::Game) + connect_activated => DefaultPathsAppMsg::ChoosePath(Folders::GameGlobal) + }, + + adw::ActionRow { + set_title: &tr("game-installation-folder"), // FIXME + set_icon_name: Some("folder-symbolic"), + set_activatable: true, + + #[watch] + set_subtitle: model.game_china.to_str().unwrap(), + + connect_activated => DefaultPathsAppMsg::ChoosePath(Folders::GameChina) }, adw::ActionRow { @@ -233,7 +246,8 @@ impl SimpleAsyncComponent for DefaultPathsApp { runners: CONFIG.game.wine.builds.clone(), dxvks: CONFIG.game.dxvk.builds.clone(), prefix: CONFIG.game.wine.prefix.clone(), - game: CONFIG.game.path.clone(), + game_global: CONFIG.game.path.global.clone(), + game_china: CONFIG.game.path.china.clone(), fps_unlocker: CONFIG.game.enhancements.fps_unlocker.path.clone(), components: CONFIG.components.path.clone(), patch: CONFIG.patch.path.clone(), @@ -264,23 +278,21 @@ impl SimpleAsyncComponent for DefaultPathsApp { self.runners = result.join("runners"); self.dxvks = result.join("dxvks"); self.prefix = result.join("prefix"); + self.game_global = result.join(concat!("Ge", "nshi", "n Imp", "act")); + self.game_china = result.join(concat!("Yu", "anS", "hen")); self.fps_unlocker = result.join("fps-unlocker"); self.components = result.join("components"); self.patch = result.join("patch"); self.temp = result.clone(); - self.game = result.join(match CONFIG.launcher.edition.into() { - GameEdition::Global => concat!("Ge", "nshi", "n Imp", "act"), - GameEdition::China => concat!("Yu", "anS", "hen") - }); - self.launcher = result; } Folders::Runners => self.runners = result, Folders::DXVK => self.dxvks = result, Folders::Prefix => self.prefix = result, - Folders::Game => self.game = result, + Folders::GameGlobal => self.game_global = result, + Folders::GameChina => self.game_china = result, Folders::FpsUnlocker => self.fps_unlocker = result, Folders::Components => self.components = result, Folders::Patch => self.patch = result, @@ -313,7 +325,8 @@ impl DefaultPathsApp { config.game.wine.builds = self.runners.clone(); config.game.dxvk.builds = self.dxvks.clone(); config.game.wine.prefix = self.prefix.clone(); - config.game.path = self.game.clone(); + config.game.path.global = self.game_global.clone(); + config.game.path.china = self.game_china.clone(); config.components.path = self.components.clone(); config.patch.path = self.patch.clone(); config.launcher.temp = Some(self.temp.clone()); diff --git a/src/ui/main/apply_patch.rs b/src/ui/main/apply_patch.rs index 6cecf8c..794a3be 100644 --- a/src/ui/main/apply_patch.rs +++ b/src/ui/main/apply_patch.rs @@ -21,7 +21,7 @@ pub fn apply_patch(sender: ComponentSender< std::thread::spawn(move || { let mut apply_patch_if_needed = true; - if let Err(err) = patch.apply(&config.game.path, config.patch.root) { + if let Err(err) = patch.apply(config.game.path.for_edition(config.launcher.edition), config.patch.root) { tracing::error!("Failed to patch the game"); sender.input(AppMsg::Toast { diff --git a/src/ui/main/download_diff.rs b/src/ui/main/download_diff.rs index 5aa8859..48a778a 100644 --- a/src/ui/main/download_diff.rs +++ b/src/ui/main/download_diff.rs @@ -18,9 +18,10 @@ pub fn download_diff(sender: ComponentSender, progress_bar_input: Sender move |state| { + let result = diff.install_to_by(game_path, config.launcher.temp, clone!(@strong sender => move |state| { match &state { InstallerUpdate::DownloadingError(err) => { tracing::error!("Downloading failed: {err}"); diff --git a/src/ui/main/mod.rs b/src/ui/main/mod.rs index 26931af..060b899 100644 --- a/src/ui/main/mod.rs +++ b/src/ui/main/mod.rs @@ -554,7 +554,12 @@ impl SimpleComponent for App { }))); group.add_action::(&RelmAction::new_stateless(clone!(@strong sender => move |_| { - if let Err(err) = open::that(&CONFIG.game.path) { + let path = match config::get() { + Ok(config) => config.game.path.for_edition(config.launcher.edition).to_path_buf(), + Err(_) => CONFIG.game.path.for_edition(CONFIG.launcher.edition).to_path_buf(), + }; + + if let Err(err) = open::that(path) { sender.input(AppMsg::Toast { title: tr("game-folder-opening-error"), description: Some(err.to_string()) @@ -590,8 +595,10 @@ impl SimpleComponent for App { group.add_action::(&RelmAction::new_stateless(clone!(@strong sender => move |_| { std::thread::spawn(clone!(@strong sender => move || { - let web_cache = CONFIG.game.path - .join(GameEdition::selected().data_folder()) + let config = config::get().unwrap_or_else(|_| CONFIG.clone()); + + let web_cache = config.game.path.for_edition(config.launcher.edition) + .join(GameEdition::from(config.launcher.edition).data_folder()) .join("webCaches/Cache/Cache_Data/data_2"); if !web_cache.exists() { diff --git a/src/ui/main/repair_game.rs b/src/ui/main/repair_game.rs index dcf3a7c..243c699 100644 --- a/src/ui/main/repair_game.rs +++ b/src/ui/main/repair_game.rs @@ -3,6 +3,8 @@ use relm4::{ Sender }; +use gtk::glib::clone; + use std::path::Path; use anime_launcher_sdk::config; @@ -23,7 +25,8 @@ pub fn repair_game(sender: ComponentSender, progress_bar_input: Sender { // Add voiceovers files - let game = Game::new(&config.game.path); + let game_path = config.game.path.for_edition(config.launcher.edition).to_path_buf(); + let game = Game::new(&game_path); if let Ok(voiceovers) = game.get_voice_packages() { for package in voiceovers { @@ -61,10 +64,9 @@ pub fn repair_game(sender: ComponentSender, progress_bar_input: Sender move || { for file in thread_files { let status = if config.launcher.repairer.fast { file.fast_verify(&game_path) @@ -74,7 +76,7 @@ pub fn repair_game(sender: ComponentSender, progress_bar_input: Sender, progress_bar_input: Sender, progress_bar_input: Sender adw::ExpanderRow { - set_title: &tr("game-voiceovers"), - set_subtitle: "List of downloaded game voiceovers. You can select them in the game settings" + adw::ComboRow { + set_title: "Game edition", + + set_model: Some(>k::StringList::new(&[ + "Global", + "China" + ])), + + set_selected: match CONFIG.launcher.edition { + GameEdition::Global => 0, + GameEdition::China => 1 + }, + + connect_selected_notify[sender] => move |row| { + if is_ready() { + #[allow(unused_must_use)] + if let Ok(mut config) = config::get() { + config.launcher.edition = match row.selected() { + 0 => GameEdition::Global, + 1 => GameEdition::China, + + _ => unreachable!() + }; + + config::update(config); + + sender.output(PreferencesAppMsg::UpdateLauncherState); + } + } + } }, adw::ComboRow { - set_title: "Environment emulation", - set_subtitle: "Experimental feature. Emulate game environment to get specific features like additional payment methods", + set_title: "Game environment", + set_subtitle: "Get specific features like additional payment methods", set_model: Some(>k::StringList::new(&[ "PC", @@ -339,6 +366,12 @@ impl SimpleAsyncComponent for GeneralApp { } }, + #[local_ref] + voice_packages -> adw::ExpanderRow { + set_title: &tr("game-voiceovers"), + set_subtitle: "List of downloaded game voiceovers. You can select them in the game settings" + }, + gtk::Box { set_orientation: gtk::Orientation::Horizontal, set_spacing: 8, @@ -442,7 +475,12 @@ impl SimpleAsyncComponent for GeneralApp { PatchStatus::Preparation { .. } | PatchStatus::Testing { .. } => &["warning"], PatchStatus::Available { .. } => unsafe { - if let Ok(true) = model.unity_player_patch.as_ref().unwrap_unchecked().is_applied(&CONFIG.game.path) { + let path = match config::get() { + Ok(config) => config.game.path.for_edition(config.launcher.edition).to_path_buf(), + Err(_) => CONFIG.game.path.for_edition(CONFIG.launcher.edition).to_path_buf(), + }; + + if let Ok(true) = model.unity_player_patch.as_ref().unwrap_unchecked().is_applied(path) { &["success"] } else { &["warning"] @@ -464,7 +502,12 @@ impl SimpleAsyncComponent for GeneralApp { PatchStatus::Preparation { .. } => tr("patch-preparation-tooltip"), PatchStatus::Testing { .. } => tr("patch-testing-tooltip"), PatchStatus::Available { .. } => unsafe { - if let Ok(true) = model.unity_player_patch.as_ref().unwrap_unchecked().is_applied(&CONFIG.game.path) { + let path = match config::get() { + Ok(config) => config.game.path.for_edition(config.launcher.edition).to_path_buf(), + Err(_) => CONFIG.game.path.for_edition(CONFIG.launcher.edition).to_path_buf(), + }; + + if let Ok(true) = model.unity_player_patch.as_ref().unwrap_unchecked().is_applied(path) { String::new() } else { tr("patch-not-applied-tooltip") @@ -503,7 +546,12 @@ impl SimpleAsyncComponent for GeneralApp { PatchStatus::Preparation { .. } | PatchStatus::Testing { .. } => &["warning"], PatchStatus::Available { .. } => unsafe { - if let Ok(true) = model.xlua_patch.as_ref().unwrap_unchecked().is_applied(&CONFIG.game.path) { + let path = match config::get() { + Ok(config) => config.game.path.for_edition(config.launcher.edition).to_path_buf(), + Err(_) => CONFIG.game.path.for_edition(CONFIG.launcher.edition).to_path_buf(), + }; + + if let Ok(true) = model.xlua_patch.as_ref().unwrap_unchecked().is_applied(path) { &["success"] } else { &["warning"] @@ -525,7 +573,12 @@ impl SimpleAsyncComponent for GeneralApp { PatchStatus::Preparation { .. } => tr("patch-preparation-tooltip"), PatchStatus::Testing { .. } => tr("patch-testing-tooltip"), PatchStatus::Available { .. } => unsafe { - if let Ok(true) = model.xlua_patch.as_ref().unwrap_unchecked().is_applied(&CONFIG.game.path) { + let path = match config::get() { + Ok(config) => config.game.path.for_edition(config.launcher.edition).to_path_buf(), + Err(_) => CONFIG.game.path.for_edition(CONFIG.launcher.edition).to_path_buf(), + }; + + if let Ok(true) = model.xlua_patch.as_ref().unwrap_unchecked().is_applied(path) { String::new() } else { tr("patch-not-applied-tooltip") @@ -867,10 +920,11 @@ impl SimpleAsyncComponent for GeneralApp { config::update(config.clone()); let package = VoicePackage::with_locale(package.locale).unwrap(); + let game_path = config.game.path.for_edition(config.launcher.edition).to_path_buf(); - if package.is_installed_in(&config.game.path) { + if package.is_installed_in(&game_path) { std::thread::spawn(move || { - if let Err(err) = package.delete_in(&config.game.path) { + if let Err(err) = package.delete_in(game_path) { tracing::error!("Failed to delete voice package: {:?}", package.locale()); sender.input(GeneralAppMsg::Toast {