feat(core): added background picture downloading

This commit is contained in:
Observer KRypt0n_ 2023-02-23 16:41:13 +02:00
parent 5651544ada
commit 6340ccbd6e
No known key found for this signature in database
GPG key ID: 844DA47BA25FE1E2
9 changed files with 115 additions and 9 deletions

3
Cargo.lock generated
View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -6,6 +6,7 @@ close = Закрыть
save = Сохранить
downloading-background-picture = Загрузка фонового изображения
loading-game-version = Загрузка версии игры
loading-patch-status = Загрузка статуса патча
loading-launcher-state = Загрузка статуса лаунчера

77
src/background.rs Normal file
View 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 += &region.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(())
}

View file

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

View file

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