From aaede9b6cbb8c564fa85220463e695d5cecc8e64 Mon Sep 17 00:00:00 2001 From: mxve <68632137+mxve@users.noreply.github.com> Date: Sun, 10 Sep 2023 18:29:30 +0200 Subject: [PATCH] download bonus content --- README.md | 3 +++ src/config.rs | 12 +++++++++++ src/main.rs | 55 +++++++++++++++++++++++++++++++++++++++----------- src/structs.rs | 25 +++++++++++++---------- 4 files changed, 72 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 5c9ba68..b64b972 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,9 @@ - Passing ```iw4-sp```, ```iw4x```, ```iw5-mod```, ```iw6-mod``` or ```s1-mod``` as the first argument will skip automatic game detection - Passing ```update``` will stop the launcher from launching the game - ```skip-launcher-update``` skips launcher self-update +- ```bonus``` download bonus content + +Some arguments can be set in alterware-launcher.json, args generally override the values of the config. --- diff --git a/src/config.rs b/src/config.rs index 5599880..2c3fed2 100644 --- a/src/config.rs +++ b/src/config.rs @@ -15,3 +15,15 @@ pub fn load(config_path: PathBuf) -> Config { pub fn save(config_path: PathBuf, config: Config) { fs::write(config_path, serde_json::to_string(&config).unwrap()).unwrap(); } + +pub fn save_value(config_path: PathBuf, key: &str, value: bool) { + let mut config = load(config_path.clone()); + match key { + "update_only" => config.update_only = value, + "skip_self_update" => config.skip_self_update = value, + "download_bonus_content" => config.download_bonus_content = value, + "ask_bonus_content" => config.ask_bonus_content = value, + _ => (), + } + save(config_path, config); +} diff --git a/src/main.rs b/src/main.rs index 826d405..d9d83ba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -91,7 +91,7 @@ fn setup_desktop_links(path: &Path, game: &Game) { fn auto_install(path: &Path, game: &Game) { setup_client_links(game, path); setup_desktop_links(path, game); - update(game, path); + update(game, path, false); } #[cfg(windows)] @@ -166,25 +166,21 @@ fn prompt_client_selection(games: &[Game]) -> String { fn manual_install(games: &[Game]) { let selection = prompt_client_selection(games); let game = games.iter().find(|&g| g.client[0] == selection).unwrap(); - update(game, &std::env::current_dir().unwrap()); + update(game, &std::env::current_dir().unwrap(), false); println!("Installation complete. Please run the launcher again or use a shortcut to launch the game."); std::io::stdin().read_line(&mut String::new()).unwrap(); std::process::exit(0); } -fn update(game: &Game, dir: &Path) { - let cdn_info: Vec = serde_json::from_str(&http::get_body_string( - format!("{}/files.json", MASTER).as_str(), - )) - .unwrap(); +fn update_dir(cdn_info: &Vec, remote_dir: &str, dir: &Path) { + let remote_dir = format!("{}/", remote_dir); - let engine_str = format!("{}/", game.engine); for file in cdn_info { - if !file.name.starts_with(&engine_str) || file.name == "iw4/iw4x.dll" { + if !file.name.starts_with(&remote_dir) || file.name == "iw4/iw4x.dll" { continue; } - let file_path = dir.join(&file.name.replace(&format!("{}/", game.engine), "")); + let file_path = dir.join(&file.name.replace(remote_dir.as_str(), "")); if file_path.exists() { let sha1_local = misc::get_file_sha1(&file_path).to_lowercase(); let sha1_remote = file.hash.to_lowercase(); @@ -207,10 +203,25 @@ fn update(game: &Game, dir: &Path) { http::download_file(&format!("{}/{}", MASTER, file.name), &file_path); } } +} + +fn update(game: &Game, dir: &Path, bonus_content: bool) { + let cdn_info: Vec = serde_json::from_str(&http::get_body_string( + format!("{}/files.json", MASTER).as_str(), + )) + .unwrap(); + + update_dir(&cdn_info, game.engine, dir); if game.engine == "iw4" { iw4x::update(dir); } + + if bonus_content && !game.bonus.is_empty() { + for bonus in game.bonus.iter() { + update_dir(&cdn_info, bonus, dir); + } + } } fn launch(file_path: &PathBuf) { @@ -242,7 +253,7 @@ fn main() { } if args.contains(&String::from("bonus")) { - cfg.bonus_content = true; + cfg.download_bonus_content = true; args.iter() .position(|r| r == "bonus") .map(|e| args.remove(e)); @@ -286,7 +297,27 @@ fn main() { for g in games.iter() { for c in g.client.iter() { if c == &game { - update(g, &std::env::current_dir().unwrap()); + if cfg.ask_bonus_content && !g.bonus.is_empty() { + println!("Download bonus content? (Y/n)"); + let input = misc::stdin().to_ascii_lowercase(); + cfg.download_bonus_content = input != "n"; + config::save_value( + PathBuf::from("alterware-launcher.json"), + "download_bonus_content", + cfg.download_bonus_content, + ); + config::save_value( + PathBuf::from("alterware-launcher.json"), + "ask_bonus_content", + false, + ); + } + + update( + g, + &std::env::current_dir().unwrap(), + cfg.download_bonus_content, + ); if !cfg.update_only { launch(&PathBuf::from(format!("{}.exe", c))); } diff --git a/src/structs.rs b/src/structs.rs index ffc6011..cc76443 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -11,21 +11,24 @@ pub struct Game<'a> { pub client: Vec<&'a str>, pub references: Vec<&'a str>, pub app_id: u32, + pub bonus: Vec<&'a str>, } -#[derive(Default, serde::Deserialize, serde::Serialize)] +#[derive(serde::Deserialize, serde::Serialize)] pub struct Config { pub update_only: bool, pub skip_self_update: bool, - pub bonus_content: bool, + pub download_bonus_content: bool, + pub ask_bonus_content: bool, } -// impl Default for Config { -// fn default() -> Self { -// Self { -// update_only: false, -// skip_self_update: false, -// bonus_content: false, -// } -// } -// } +impl Default for Config { + fn default() -> Self { + Self { + update_only: false, + skip_self_update: false, + download_bonus_content: false, + ask_bonus_content: true, + } + } +}