mirror of
https://github.com/an-anime-team/sleepy-launcher.git
synced 2025-03-15 14:38:29 +03:00
0.2.1
- removed excess code - tested and fixed game downloading
This commit is contained in:
parent
3e9f32a16c
commit
c85805d14f
10 changed files with 36 additions and 392 deletions
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "anime-game-launcher"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
description = "Anime Game launcher"
|
||||
authors = ["Nikita Podvirnyy <suimin.tu.mu.ga.mi@gmail.com>"]
|
||||
license = "GPL-3.0"
|
||||
|
|
|
@ -242,7 +242,7 @@ Adw.ApplicationWindow window {
|
|||
text: "Downloading: 37% (3.7 of 10 GB)";
|
||||
show-text: true;
|
||||
|
||||
width-request: 260;
|
||||
width-request: 360;
|
||||
fraction: 0.37;
|
||||
valign: center;
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ Adw.ApplicationWindow window {
|
|||
text: "Downloading: 37% (3.7 of 10 GB)";
|
||||
show-text: true;
|
||||
|
||||
width-request: 260;
|
||||
width-request: 360;
|
||||
fraction: 0.37;
|
||||
valign: center;
|
||||
}
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
use std::io::Error;
|
||||
|
||||
use wait_not_await::Await;
|
||||
|
||||
use crate::ui::components::progress_bar::ProgressBar;
|
||||
|
||||
use crate::lib::wine_prefix::WinePrefix;
|
||||
use crate::lib::config::Config;
|
||||
|
||||
pub fn create_prefix(config: Config, progress_bar: ProgressBar) -> Await<Result<(), (String, Error)>> {
|
||||
Await::new(move || {
|
||||
// Create prefix if needed
|
||||
let prefix = WinePrefix::new(&config.game.wine.prefix);
|
||||
|
||||
if !prefix.exists() {
|
||||
progress_bar.update(0.0, Some("Creating prefix..."));
|
||||
|
||||
match config.try_get_selected_wine_info() {
|
||||
Some(wine_version) => match prefix.update(&config.game.wine.builds, wine_version) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => Err((String::from("Failed to create prefix"), err))
|
||||
},
|
||||
None => {
|
||||
// TODO: download default wine
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
use std::io::Error;
|
||||
|
||||
use anime_game_core::prelude::*;
|
||||
use wait_not_await::Await;
|
||||
|
||||
use crate::ui::components::progress_bar::ProgressBar;
|
||||
use crate::lib::prettify_bytes::prettify_bytes;
|
||||
|
||||
/*pub fn download_diff(diff: &VersionDiff, progress_bar: ProgressBar, suffix: Option<String>) -> Await<Result<(), (String, Error)>> {
|
||||
let (send, recv) = std::sync::mpsc::channel();
|
||||
|
||||
diff.install(move |state| {
|
||||
match state {
|
||||
InstallerUpdate::DownloadingStarted(_) => progress_bar.update(0.0, Some("Downloading...")),
|
||||
|
||||
InstallerUpdate::DownloadingProgress(curr, total) => {
|
||||
// To reduce amount of action requests
|
||||
// if curr % 10000 < 200 {
|
||||
let progress = curr as f64 / total as f64;
|
||||
|
||||
progress_bar.update(progress, Some(&format!(
|
||||
"Downloading{}: {:.2}% ({} of {})",
|
||||
if let Some(suffix) = suffix { format!(" {}", suffix) } else { String::new() },
|
||||
progress * 100.0,
|
||||
prettify_bytes(curr),
|
||||
prettify_bytes(total)
|
||||
)));
|
||||
// }
|
||||
}
|
||||
|
||||
InstallerUpdate::UnpackingStarted(_) => progress_bar.update(0.0, Some("Unpacking...")),
|
||||
|
||||
InstallerUpdate::UnpackingProgress(curr, total) => {
|
||||
let progress = curr as f64 / total as f64;
|
||||
|
||||
progress_bar.update(progress, Some(&format!(
|
||||
"Unpacking{}: {:.2}% ({} of {})",
|
||||
if let Some(suffix) = suffix { format!(" {}", suffix) } else { String::new() },
|
||||
progress * 100.0,
|
||||
prettify_bytes(curr),
|
||||
prettify_bytes(total)
|
||||
)));
|
||||
}
|
||||
|
||||
InstallerUpdate::DownloadingFinished => (),
|
||||
|
||||
InstallerUpdate::UnpackingFinished => {
|
||||
send.send(Ok(()));
|
||||
},
|
||||
|
||||
InstallerUpdate::DownloadingError(err) => {
|
||||
send.send(Err((String::from("Failed to download"), err.into())));
|
||||
}
|
||||
|
||||
InstallerUpdate::UnpackingError => {
|
||||
send.send(Err((String::from("Failed to unpack"), Error::last_os_error())));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Await::new(move || {
|
||||
recv.recv().unwrap()
|
||||
})
|
||||
}*/
|
|
@ -1,32 +0,0 @@
|
|||
mod create_prefix;
|
||||
mod download_diff;
|
||||
|
||||
pub use create_prefix::*;
|
||||
pub use download_diff::*;
|
||||
|
||||
use crate::lib::config;
|
||||
use crate::lib::wine_prefix::WinePrefix;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Component {
|
||||
Wine,
|
||||
DXVK,
|
||||
Prefix
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ComponentsChain {
|
||||
pub chain: Vec<Component>
|
||||
}
|
||||
|
||||
impl ComponentsChain {
|
||||
pub fn get() -> std::io::Result<Self> {
|
||||
let config = config::get()?;
|
||||
|
||||
let wine_prefix = WinePrefix::new(&config.game.wine.prefix);
|
||||
|
||||
|
||||
|
||||
todo!();
|
||||
}
|
||||
}
|
|
@ -1,2 +1 @@
|
|||
pub mod states;
|
||||
pub mod executors;
|
||||
|
|
|
@ -4,17 +4,18 @@ use libadwaita::{self as adw, prelude::*};
|
|||
use std::io::{Error, ErrorKind};
|
||||
|
||||
use anime_game_core::prelude::*;
|
||||
use wait_not_await::Await;
|
||||
|
||||
use crate::ui::components::progress_bar::ProgressBar;
|
||||
use crate::lib::config;
|
||||
use crate::lib::prettify_bytes::prettify_bytes;
|
||||
use crate::lib::wine_prefix::WinePrefix;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum LauncherState {
|
||||
Launch,
|
||||
PatchAvailable(Patch),
|
||||
|
||||
WineNotInstalled,
|
||||
PrefixNotExists,
|
||||
|
||||
// Always contains `VersionDiff::Diff`
|
||||
VoiceUpdateAvailable(VersionDiff),
|
||||
|
||||
|
@ -43,12 +44,22 @@ impl Default for LauncherState {
|
|||
impl LauncherState {
|
||||
pub fn get(status_page: Option<&adw::StatusPage>) -> std::io::Result<Self> {
|
||||
let config = config::get()?;
|
||||
let game = Game::new(&config.game.path);
|
||||
|
||||
if config.game.wine.selected == None {
|
||||
return Ok(Self::WineNotInstalled);
|
||||
}
|
||||
|
||||
let prefix = WinePrefix::new(&config.game.wine.prefix);
|
||||
|
||||
if !prefix.exists() {
|
||||
return Ok(Self::PrefixNotExists);
|
||||
}
|
||||
|
||||
if let Some(status_page) = &status_page {
|
||||
status_page.set_description(Some("Updating game info..."));
|
||||
}
|
||||
|
||||
let game = Game::new(&config.game.path);
|
||||
let diff = game.try_get_diff()?;
|
||||
|
||||
Ok(match diff {
|
||||
|
@ -105,171 +116,4 @@ impl LauncherState {
|
|||
VersionDiff::NotInstalled { .. } => Self::GameNotInstalled(diff)
|
||||
})
|
||||
}
|
||||
|
||||
/*pub fn execute(&self, progress_bar: &ProgressBar) -> Await<Result<(), (&str, Error)>> {
|
||||
match self {
|
||||
Self::Launch => {
|
||||
// Display toast message if the game is failed to run
|
||||
/*if let Err(err) = game::run(false) {
|
||||
this.toast_error("Failed to run game", err);
|
||||
}*/
|
||||
|
||||
todo!();
|
||||
},
|
||||
|
||||
Self::PatchAvailable(_) => todo!(),
|
||||
|
||||
Self::VoiceUpdateAvailable(diff) |
|
||||
Self::VoiceNotInstalled(diff) |
|
||||
Self::GameUpdateAvailable(diff) |
|
||||
Self::GameNotInstalled(diff) => {
|
||||
// this.update(Actions::DownloadDiff(Rc::new(diff))).unwrap();
|
||||
|
||||
// Download wine version if not installed
|
||||
match WineVersion::latest() {
|
||||
Ok(wine) => match Installer::new(wine.uri) {
|
||||
Ok(mut installer) => {
|
||||
let (send, recv) = std::sync::mpsc::channel();
|
||||
let wine_title = wine.title.clone();
|
||||
|
||||
installer.install(&config.game.wine.builds, clone!(@strong this => move |state| {
|
||||
match state {
|
||||
InstallerUpdate::UnpackingFinished => {
|
||||
send.send(true).unwrap();
|
||||
}
|
||||
|
||||
InstallerUpdate::DownloadingError(_) |
|
||||
InstallerUpdate::UnpackingError => {
|
||||
send.send(false).unwrap();
|
||||
}
|
||||
|
||||
_ => ()
|
||||
}
|
||||
|
||||
this.update(Actions::UpdateProgressByState(Rc::new((state, Some(wine_title.clone()))))).unwrap();
|
||||
}));
|
||||
|
||||
// Block thread until downloading finished
|
||||
if recv.recv().unwrap() {
|
||||
config.game.wine.selected = Some(wine.name);
|
||||
|
||||
config::update(config.clone());
|
||||
}
|
||||
|
||||
else {
|
||||
println!("I'm tired, Boss!");
|
||||
|
||||
return;
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
toast_error(&this, "Failed to init wine version installer", err.into());
|
||||
|
||||
return;
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
toast_error(&this, "Failed to load wine versions list", err.into());
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Create prefix if needed
|
||||
let prefix = WinePrefix::new(&config.game.wine.prefix);
|
||||
|
||||
if !prefix.exists() {
|
||||
this.update(Actions::UpdateProgress {
|
||||
fraction: Rc::new(0.0),
|
||||
title: Rc::new(String::from("Creating prefix..."))
|
||||
}).unwrap();
|
||||
|
||||
match config.try_get_selected_wine_info() {
|
||||
Some(wine_version) => {
|
||||
if let Err(err) = prefix.update(&config.game.wine.builds, wine_version) {
|
||||
toast_error(&this, "Failed to create wineprefix", err);
|
||||
|
||||
return;
|
||||
}
|
||||
},
|
||||
None => return
|
||||
}
|
||||
}
|
||||
|
||||
// Download and apply DXVK if not installed
|
||||
match DxvkVersion::latest() {
|
||||
Ok(dxvk) => match Installer::new(&dxvk.uri) {
|
||||
Ok(mut installer) => {
|
||||
let (send, recv) = std::sync::mpsc::channel();
|
||||
let dxvk_title = dxvk.name.clone();
|
||||
|
||||
installer.install(&config.game.dxvk.builds, clone!(@strong this => move |state| {
|
||||
match state {
|
||||
InstallerUpdate::UnpackingFinished => {
|
||||
send.send(true).unwrap();
|
||||
}
|
||||
|
||||
InstallerUpdate::DownloadingError(_) |
|
||||
InstallerUpdate::UnpackingError => {
|
||||
send.send(false).unwrap();
|
||||
}
|
||||
|
||||
_ => ()
|
||||
}
|
||||
|
||||
this.update(Actions::UpdateProgressByState(Rc::new((state, Some(dxvk_title.clone()))))).unwrap();
|
||||
}));
|
||||
|
||||
// Block thread until downloading finished
|
||||
if recv.recv().unwrap() {
|
||||
config.game.dxvk.selected = Some(dxvk.name.clone());
|
||||
|
||||
config::update(config.clone());
|
||||
}
|
||||
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply DXVK
|
||||
this.update(Actions::UpdateProgress {
|
||||
fraction: Rc::new(100.0),
|
||||
title: Rc::new(String::from("Applying DXVK..."))
|
||||
}).unwrap();
|
||||
|
||||
match dxvk.apply(&config.game.dxvk.builds, &config.game.wine.prefix) {
|
||||
Ok(_) => {
|
||||
config.game.dxvk.selected = Some(dxvk.name);
|
||||
|
||||
config::update(config.clone());
|
||||
},
|
||||
Err(err) => {
|
||||
toast_error(&this, "Failed to apply DXVK", err);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
toast_error(&this, "Failed to init wine version installer", err.into());
|
||||
|
||||
return;
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
toast_error(&this, "Failed to load wine versions list", err.into());
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
todo!();
|
||||
},
|
||||
|
||||
Self::GameOutdated(_) => (),
|
||||
Self::VoiceOutdated(_) => ()
|
||||
}
|
||||
|
||||
todo!();
|
||||
}*/
|
||||
}
|
||||
|
|
104
src/ui/main.rs
104
src/ui/main.rs
|
@ -14,25 +14,12 @@ use crate::ui::*;
|
|||
|
||||
use super::preferences::PreferencesStack;
|
||||
use super::traits::toast_error::ToastError;
|
||||
use super::components::progress_bar::ProgressBar;
|
||||
use super::components::progress_bar::*;
|
||||
|
||||
use crate::lib::config;
|
||||
use crate::lib::game;
|
||||
use crate::lib::tasks;
|
||||
use crate::lib::launcher::states::LauncherState;
|
||||
use crate::lib::wine_prefix::WinePrefix;
|
||||
use crate::lib::wine::Version as WineVersion;
|
||||
use crate::lib::dxvk::Version as DxvkVersion;
|
||||
use crate::lib::prettify_bytes::prettify_bytes;
|
||||
|
||||
fn toast_error(app: &App, msg: &str, err: Error) {
|
||||
app.update(Actions::ToastError(Rc::new((
|
||||
String::from(msg), err
|
||||
)))).unwrap();
|
||||
|
||||
app.update(Actions::HideProgressBar).unwrap();
|
||||
app.update_state();
|
||||
}
|
||||
|
||||
/// This structure is used to describe widgets used in application
|
||||
///
|
||||
|
@ -138,7 +125,6 @@ pub enum Actions {
|
|||
PreferencesGoBack,
|
||||
PerformButtonEvent,
|
||||
DownloadDiff(Rc<VersionDiff>),
|
||||
UpdateProgressByState(Rc<(InstallerUpdate, Option<String>)>),
|
||||
ShowProgressBar,
|
||||
UpdateProgress { fraction: Rc<f64>, title: Rc<String> },
|
||||
HideProgressBar,
|
||||
|
@ -272,6 +258,9 @@ impl App {
|
|||
|
||||
LauncherState::PatchAvailable(_) => todo!(),
|
||||
|
||||
LauncherState::WineNotInstalled => todo!(),
|
||||
LauncherState::PrefixNotExists => todo!(),
|
||||
|
||||
LauncherState::VoiceUpdateAvailable(diff) |
|
||||
LauncherState::VoiceNotInstalled(diff) |
|
||||
LauncherState::GameUpdateAvailable(diff) |
|
||||
|
@ -286,7 +275,7 @@ impl App {
|
|||
|
||||
Actions::DownloadDiff(diff) => {
|
||||
match config::get() {
|
||||
Ok(mut config) => {
|
||||
Ok(config) => {
|
||||
let diff = (*diff).clone();
|
||||
let this = this.clone();
|
||||
|
||||
|
@ -297,7 +286,11 @@ impl App {
|
|||
|
||||
// Download diff
|
||||
diff.install_to_by(config.game.path, config.launcher.temp, move |state| {
|
||||
this.update(Actions::UpdateProgressByState(Rc::new((state, None)))).unwrap();
|
||||
match this.widgets.progress_bar.update_from_state(state) {
|
||||
ProgressUpdateResult::Updated => (),
|
||||
ProgressUpdateResult::Error(msg, err) => this.update(Actions::ToastError(Rc::new((msg, err)))).unwrap(),
|
||||
ProgressUpdateResult::Finished => this.update(Actions::HideProgressBar).unwrap()
|
||||
}
|
||||
}).unwrap();
|
||||
});
|
||||
},
|
||||
|
@ -309,75 +302,6 @@ impl App {
|
|||
}
|
||||
}
|
||||
|
||||
Actions::UpdateProgressByState(state) => {
|
||||
todo!();
|
||||
// let (state, suffix) = (&*state).clone();
|
||||
|
||||
match &state.0 {
|
||||
InstallerUpdate::DownloadingStarted(_) => {
|
||||
this.update(Actions::UpdateProgress {
|
||||
fraction: Rc::new(0.0),
|
||||
title: Rc::new(String::from("Downloading..."))
|
||||
}).unwrap();
|
||||
}
|
||||
|
||||
InstallerUpdate::DownloadingProgress(curr, total) => {
|
||||
// To reduce amount of action requests
|
||||
// if curr % 10000 < 200 {
|
||||
let progress = *curr as f64 / *total as f64;
|
||||
|
||||
this.update(Actions::UpdateProgress {
|
||||
fraction: Rc::new(progress),
|
||||
title: Rc::new(format!(
|
||||
"Downloading{}: {:.2}% ({} of {})",
|
||||
if let Some(suffix) = &state.1 { format!(" {}", suffix) } else { String::new() },
|
||||
progress * 100.0,
|
||||
prettify_bytes(*curr),
|
||||
prettify_bytes(*total)
|
||||
))
|
||||
}).unwrap();
|
||||
// }
|
||||
}
|
||||
|
||||
InstallerUpdate::UnpackingStarted(_) => {
|
||||
this.update(Actions::UpdateProgress {
|
||||
fraction: Rc::new(0.0),
|
||||
title: Rc::new(String::from("Unpacking..."))
|
||||
}).unwrap();
|
||||
}
|
||||
|
||||
InstallerUpdate::UnpackingProgress(curr, total) => {
|
||||
let progress = *curr as f64 / *total as f64;
|
||||
|
||||
this.update(Actions::UpdateProgress {
|
||||
fraction: Rc::new(progress),
|
||||
title: Rc::new(format!(
|
||||
"Unpacking{}: {:.2}% ({} of {})",
|
||||
if let Some(suffix) = &state.1 { format!(" {}", suffix) } else { String::new() },
|
||||
progress * 100.0,
|
||||
prettify_bytes(*curr),
|
||||
prettify_bytes(*total)
|
||||
))
|
||||
}).unwrap();
|
||||
}
|
||||
|
||||
InstallerUpdate::DownloadingFinished => (),
|
||||
|
||||
InstallerUpdate::UnpackingFinished => {
|
||||
this.update(Actions::HideProgressBar).unwrap();
|
||||
this.update_state();
|
||||
}
|
||||
|
||||
InstallerUpdate::DownloadingError(err) => {
|
||||
toast_error(&this, "Failed to download", err.clone().into());
|
||||
}
|
||||
|
||||
InstallerUpdate::UnpackingError => {
|
||||
toast_error(&this, "Failed to unpack", Error::last_os_error());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Actions::ShowProgressBar => {
|
||||
this.widgets.progress_bar.show();
|
||||
}
|
||||
|
@ -436,6 +360,14 @@ impl App {
|
|||
self.widgets.launch_game.set_label("Apply patch");
|
||||
}
|
||||
|
||||
LauncherState::WineNotInstalled => {
|
||||
self.widgets.launch_game.set_label("Download wine");
|
||||
}
|
||||
|
||||
LauncherState::PrefixNotExists => {
|
||||
self.widgets.launch_game.set_label("Create prefix");
|
||||
}
|
||||
|
||||
LauncherState::GameUpdateAvailable(_) |
|
||||
LauncherState::VoiceUpdateAvailable(_) => {
|
||||
self.widgets.launch_game.set_label("Update");
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use gtk4::{self as gtk, prelude::*};
|
||||
use libadwaita::{self as adw, prelude::*};
|
||||
|
||||
use gtk::glib;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue