diff --git a/Cargo.toml b/Cargo.toml index f9cf85b..b55e58b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anime-game-launcher" -version = "0.5.1" +version = "0.5.2" description = "Anime Game launcher" authors = ["Nikita Podvirnyy "] license = "GPL-3.0" diff --git a/anime-game-core b/anime-game-core index cc93b43..e040b40 160000 --- a/anime-game-core +++ b/anime-game-core @@ -1 +1 @@ -Subproject commit cc93b435dfa72de188168354395c36b60708fc31 +Subproject commit e040b40c0598c48630d7a06110a4aaccbcea6c53 diff --git a/assets/ui/preferences/general.blp b/assets/ui/preferences/general.blp index a28643d..cf74028 100644 --- a/assets/ui/preferences/general.blp +++ b/assets/ui/preferences/general.blp @@ -17,6 +17,9 @@ Adw.PreferencesPage general_page { "Chinese" ] }; + + sensitive: false; + tooltip-text: "Work in progress"; } Adw.ExpanderRow voiceovers_row { @@ -55,10 +58,16 @@ Adw.PreferencesPage general_page { Gtk.Button { label: "Revert patch"; + + sensitive: false; + tooltip-text: "Work in progress"; } Gtk.Button { label: "Re-apply patch"; + + sensitive: false; + tooltip-text: "Work in progress"; } } } diff --git a/src/lib/config/mod.rs b/src/lib/config/mod.rs index 8f62832..289ade4 100644 --- a/src/lib/config/mod.rs +++ b/src/lib/config/mod.rs @@ -187,7 +187,8 @@ impl Default for Launcher { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Patch { pub path: String, - pub servers: Vec + pub servers: Vec, + pub root: bool } impl Default for Patch { @@ -200,7 +201,8 @@ impl Default for Patch { servers: vec![ "https://notabug.org/Krock/dawn".to_string(), "https://dev.kaifa.ch/Maroxy/dawn".to_string() - ] + ], + root: true } } } diff --git a/src/ui/main.rs b/src/ui/main.rs index 7a1329c..f2a7963 100644 --- a/src/ui/main.rs +++ b/src/ui/main.rs @@ -262,7 +262,72 @@ impl App { } }, - LauncherState::PatchAvailable(_) => todo!(), + LauncherState::PatchAvailable(patch) => { + match patch { + Patch::NotAvailable | + Patch::Outdated { .. } | + Patch::Preparation { .. } => unreachable!(), + + Patch::Testing { version, host, .. } | + Patch::Available { version, host, .. } => { + this.widgets.launch_game.set_sensitive(false); + this.widgets.open_preferences.set_sensitive(false); + + let this = this.clone(); + + std::thread::spawn(move || { + let applier = PatchApplier::new(&config.patch.path); + + let mut synced = false; + + match applier.is_sync(&config.patch.servers) { + Ok(true) => synced = true, + + Ok(false) => { + match applier.sync(host) { + Ok(true) => synced = true, + + Ok(false) => { + this.update(Actions::ToastError(Rc::new(( + String::from("Failed to sync patch folder"), Error::last_os_error() + )))).unwrap(); + } + + Err(err) => { + this.update(Actions::ToastError(Rc::new(( + String::from("Failed to sync patch folder"), err + )))).unwrap(); + } + } + } + + Err(err) => this.update(Actions::ToastError(Rc::new(( + String::from("Failed to check patch folder state"), err + )))).unwrap() + } + + if synced { + match applier.apply(&config.game.path, version, config.patch.root) { + Ok(_) => (), + + Err(err) => { + this.update(Actions::ToastError(Rc::new(( + String::from("Failed to patch game"), err + )))).unwrap(); + } + } + } + + glib::MainContext::default().invoke(move || { + this.widgets.launch_game.set_sensitive(true); + this.widgets.open_preferences.set_sensitive(true); + + this.update_state(); + }); + }); + } + } + } LauncherState::WineNotInstalled => { match WineList::list_downloaded(&config.game.wine.builds) { @@ -479,13 +544,34 @@ impl App { self.widgets.launch_game.set_tooltip_text(None); self.widgets.launch_game.set_sensitive(true); - match state { + self.widgets.launch_game.add_css_class("suggested-action"); + self.widgets.launch_game.remove_css_class("warning"); + + match &state { LauncherState::Launch => { self.widgets.launch_game.set_label("Launch"); } - LauncherState::PatchAvailable(_) => { - self.widgets.launch_game.set_label("Apply patch"); + LauncherState::PatchAvailable(patch) => { + match patch { + Patch::NotAvailable | + Patch::Outdated { .. } | + Patch::Preparation { .. } => { + self.widgets.launch_game.set_label("Patch not available"); + self.widgets.launch_game.set_sensitive(false); + } + + Patch::Testing { .. } => { + self.widgets.launch_game.set_label("Apply test patch"); + + self.widgets.launch_game.remove_css_class("suggested-action"); + self.widgets.launch_game.add_css_class("warning"); + } + + Patch::Available { .. } => { + self.widgets.launch_game.set_label("Apply patch"); + } + } } LauncherState::WineNotInstalled => { @@ -522,21 +608,20 @@ impl App { } pub fn update_state(&self) -> Await> { - let this = self.clone(); - - let (send, recv) = std::sync::mpsc::channel(); - - this.widgets.status_page.show(); - this.widgets.launcher_content.hide(); + self.widgets.status_page.show(); + self.widgets.launcher_content.hide(); let (sender, receiver) = glib::MainContext::channel::(glib::PRIORITY_DEFAULT); + let (send, recv) = std::sync::mpsc::channel(); - receiver.attach(None, clone!(@strong this.widgets.status_page as status_page => move |description| { + receiver.attach(None, clone!(@strong self.widgets.status_page as status_page => move |description| { status_page.set_description(Some(&description)); glib::Continue(true) })); + let this = self.clone(); + std::thread::spawn(move || { match LauncherState::get(move |status| sender.send(status.to_string()).unwrap()) { Ok(state) => { diff --git a/src/ui/preferences/general_page.rs b/src/ui/preferences/general_page.rs index 07ebfcf..b547f62 100644 --- a/src/ui/preferences/general_page.rs +++ b/src/ui/preferences/general_page.rs @@ -629,7 +629,9 @@ impl App { // Update patch version status_page.set_description(Some("Updating patch info...")); - match Patch::try_fetch(config.patch.servers)? { + let patch = Patch::try_fetch(config.patch.servers)?; + + match patch { Patch::NotAvailable => { self.widgets.patch_version.set_label("not available"); self.widgets.patch_version.set_css_classes(&["error"]); @@ -656,7 +658,15 @@ impl App { }, Patch::Available { version, .. } => { self.widgets.patch_version.set_label(&version.to_string()); - self.widgets.patch_version.set_css_classes(&["success"]); + + if let Ok(true) = patch.is_applied(&config.game.path) { + self.widgets.patch_version.set_css_classes(&["success"]); + } + + else { + self.widgets.patch_version.set_css_classes(&["warning"]); + self.widgets.patch_version.set_tooltip_text(Some("Patch is not applied")); + } } }