mirror of
https://github.com/an-anime-team/an-anime-game-launcher.git
synced 2024-11-21 20:36:01 +03:00
feat(core): added background picture downloading
This commit is contained in:
parent
5651544ada
commit
6340ccbd6e
9 changed files with 115 additions and 9 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -57,12 +57,15 @@ version = "2.0.0-dev"
|
|||
dependencies = [
|
||||
"anime-launcher-sdk",
|
||||
"anyhow",
|
||||
"cached",
|
||||
"fluent-templates",
|
||||
"glib-build-tools",
|
||||
"gtk4",
|
||||
"lazy_static",
|
||||
"libadwaita",
|
||||
"md5",
|
||||
"relm4",
|
||||
"serde_json",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"unic-langid",
|
||||
|
|
|
@ -30,3 +30,6 @@ unic-langid = "0.9"
|
|||
|
||||
lazy_static = "1.4.0"
|
||||
anyhow = "1.0"
|
||||
cached = { version = "0.42", features = ["proc_macro"] }
|
||||
serde_json = "1"
|
||||
md5 = "0.7"
|
||||
|
|
|
@ -5,6 +5,7 @@ debug-file-opening-error = Failed to open debug file
|
|||
|
||||
game-launching-failed = Failed to launch game
|
||||
|
||||
background-downloading-failed = Failed to download background picture
|
||||
config-flush-error = Failed to flush config
|
||||
wine-prefix-update-failed = Failed to update wine prefix
|
||||
dxvk-install-failed = Failed to install DXVK
|
||||
|
|
|
@ -6,6 +6,7 @@ close = Close
|
|||
save = Save
|
||||
|
||||
|
||||
downloading-background-picture = Downloading background picture
|
||||
loading-game-version = Loading game version
|
||||
loading-patch-status = Loading patch status
|
||||
loading-launcher-state = Loading launcher state
|
||||
|
|
|
@ -5,6 +5,7 @@ debug-file-opening-error = Не удалось открыть файл отла
|
|||
|
||||
game-launching-failed = Не удалось запустить игру
|
||||
|
||||
background-downloading-failed = Не удалось загрузить фоновое изображение
|
||||
config-flush-error = Ошибка сохранения настроек
|
||||
wine-prefix-update-failed = Ошибка обновления префикса Wine
|
||||
dxvk-install-failed = Ошибка установки DXVK
|
||||
|
|
|
@ -6,6 +6,7 @@ close = Закрыть
|
|||
save = Сохранить
|
||||
|
||||
|
||||
downloading-background-picture = Загрузка фонового изображения
|
||||
loading-game-version = Загрузка версии игры
|
||||
loading-patch-status = Загрузка статуса патча
|
||||
loading-launcher-state = Загрузка статуса лаунчера
|
||||
|
|
77
src/background.rs
Normal file
77
src/background.rs
Normal file
|
@ -0,0 +1,77 @@
|
|||
use anime_launcher_sdk::anime_game_core::installer::downloader::Downloader;
|
||||
use anime_launcher_sdk::anime_game_core::curl::fetch;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Background {
|
||||
pub uri: String,
|
||||
pub hash: String
|
||||
}
|
||||
|
||||
pub fn get_uri() -> String {
|
||||
let mut lang;
|
||||
|
||||
unsafe {
|
||||
lang = crate::i18n::LANG.language.as_str().to_string();
|
||||
|
||||
if let Some(region) = crate::i18n::LANG.region {
|
||||
lang += "-";
|
||||
lang += ®ion.as_str().to_ascii_lowercase();
|
||||
}
|
||||
}
|
||||
|
||||
let uri = concat!("https://sdk-os-static.", "ho", "yo", "verse", ".com/hk4e_global/mdk/launcher/api/content?filter_adv=true&key=gcStgarh&launcher_id=10&language=");
|
||||
|
||||
uri.to_owned() + &lang
|
||||
}
|
||||
|
||||
#[cached::proc_macro::cached(result)]
|
||||
pub fn get_background_info() -> anyhow::Result<Background> {
|
||||
let json = serde_json::from_slice::<serde_json::Value>(&fetch(get_uri(), None)?.get_body()?)?;
|
||||
|
||||
let uri = match json["data"]["adv"]["background"].as_str() {
|
||||
Some(uri) => uri.to_owned(),
|
||||
None => anyhow::bail!("Failed to get background picture uri")
|
||||
};
|
||||
|
||||
// This API field contains wrong md5 hash, but file's name
|
||||
// from the uri above actually contains correct one, so
|
||||
// I parse and use it few lines below
|
||||
|
||||
/*let hash = match json["data"]["adv"]["bg_checksum"].as_str() {
|
||||
Some(uri) => uri.to_owned(),
|
||||
None => anyhow::bail!("Failed to get background picture checksum")
|
||||
};*/
|
||||
|
||||
let hash = uri.split('/').last().unwrap_or_default().split('_').next().unwrap_or_default().to_owned();
|
||||
|
||||
Ok(Background {
|
||||
uri,
|
||||
hash
|
||||
})
|
||||
}
|
||||
|
||||
pub fn download_background() -> anyhow::Result<()> {
|
||||
tracing::debug!("Downloading background picture");
|
||||
|
||||
let info = get_background_info()?;
|
||||
|
||||
if crate::BACKGROUND_FILE.exists() {
|
||||
let hash = md5::compute(std::fs::read(crate::BACKGROUND_FILE.as_path())?);
|
||||
|
||||
if format!("{:x}", hash).to_lowercase() == info.hash {
|
||||
tracing::debug!("Background picture is already downloaded. Skipping");
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
let mut downloader = Downloader::new(info.uri)?;
|
||||
|
||||
if let Err(err) = downloader.download_to(crate::BACKGROUND_FILE.as_path(), |_, _| {}) {
|
||||
let err: std::io::Error = err.into();
|
||||
|
||||
anyhow::bail!(err);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
20
src/main.rs
20
src/main.rs
|
@ -11,6 +11,7 @@ use std::path::PathBuf;
|
|||
|
||||
pub mod i18n;
|
||||
pub mod ui;
|
||||
pub mod background;
|
||||
|
||||
mod prettify_bytes;
|
||||
|
||||
|
@ -30,14 +31,17 @@ pub fn is_ready() -> bool {
|
|||
}
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
/// Path to `debug.log` file. Standard is `$HOME/.local/share/anime-game-launcher/debug.log`
|
||||
pub static ref DEBUG_FILE: std::path::PathBuf = anime_launcher_sdk::consts::launcher_dir().unwrap_or_default().join("debug.log");
|
||||
|
||||
/// Config loaded on the app's start. Use `config::get()` to get up to date config instead.
|
||||
/// 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);
|
||||
|
||||
/// Path to `debug.log` file. Standard is `$HOME/.local/share/anime-game-launcher/debug.log`
|
||||
pub static ref DEBUG_FILE: PathBuf = anime_launcher_sdk::consts::launcher_dir().unwrap_or_default().join("debug.log");
|
||||
|
||||
/// Path to `background` file. Standard is `$HOME/.local/share/anime-game-launcher/background`
|
||||
pub static ref BACKGROUND_FILE: PathBuf = anime_launcher_sdk::consts::launcher_dir().unwrap_or_default().join("background");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -66,7 +70,7 @@ fn main() {
|
|||
|
||||
let debug_log = tracing_subscriber::fmt::layer()
|
||||
.pretty()
|
||||
// .with_ansi(false) // sadly doesn't work with pretty style
|
||||
.with_ansi(false)
|
||||
.with_writer(std::sync::Arc::new(file))
|
||||
.with_filter(filter_fn(|metadata| {
|
||||
!metadata.target().contains("rustls")
|
||||
|
@ -77,7 +81,7 @@ fn main() {
|
|||
.with(debug_log)
|
||||
.init();
|
||||
|
||||
tracing::info!("Starting application");
|
||||
tracing::info!("Starting application ({APP_VERSION})");
|
||||
|
||||
adw::init().expect("Libadwaita initialization failed");
|
||||
|
||||
|
@ -106,13 +110,11 @@ fn main() {
|
|||
}}
|
||||
|
||||
window.classic-style {{
|
||||
background: url(\"file://{}/background\");
|
||||
background: url(\"file://{}\");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
}}
|
||||
",
|
||||
CONFIG.launcher.temp.as_ref().unwrap_or(&PathBuf::from("/tmp")).to_string_lossy()
|
||||
));
|
||||
", BACKGROUND_FILE.to_string_lossy()));
|
||||
|
||||
// Run the app
|
||||
app.run::<ui::main::App>(());
|
||||
|
|
|
@ -401,10 +401,27 @@ impl SimpleComponent for App {
|
|||
|
||||
tracing::info!("Main window initialized");
|
||||
|
||||
let download_picture = model.style == LauncherStyle::Classic;
|
||||
|
||||
// Initialize some heavy tasks
|
||||
std::thread::spawn(move || {
|
||||
tracing::info!("Initializing heavy tasks");
|
||||
|
||||
// Download background picture if needed
|
||||
|
||||
if download_picture {
|
||||
sender.input(AppMsg::UpdateLoadingStatus(Some(Some(tr("downloading-background-picture")))));
|
||||
|
||||
if let Err(err) = crate::background::download_background() {
|
||||
tracing::error!("Failed to download background picture");
|
||||
|
||||
sender.input(AppMsg::Toast {
|
||||
title: tr("background-downloading-failed"),
|
||||
description: Some(err.to_string())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Update initial game version status
|
||||
|
||||
sender.input(AppMsg::UpdateLoadingStatus(Some(Some(tr("loading-game-version")))));
|
||||
|
|
Loading…
Reference in a new issue