- removed excess code
- tested and fixed game downloading
This commit is contained in:
Observer KRypt0n_ 2022-07-28 13:50:44 +02:00
parent 3e9f32a16c
commit c85805d14f
No known key found for this signature in database
GPG key ID: 844DA47BA25FE1E2
10 changed files with 36 additions and 392 deletions

View file

@ -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"

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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(())
}
})
}

View file

@ -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()
})
}*/

View file

@ -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!();
}
}

View file

@ -1,2 +1 @@
pub mod states;
pub mod executors;

View file

@ -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!();
}*/
}

View file

@ -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");

View file

@ -1,5 +1,4 @@
use gtk4::{self as gtk, prelude::*};
use libadwaita::{self as adw, prelude::*};
use gtk::glib;