diff --git a/src/iw4x.rs b/src/iw4x.rs index 080addf..9f4312b 100644 --- a/src/iw4x.rs +++ b/src/iw4x.rs @@ -2,24 +2,17 @@ use crate::github; use crate::global::*; use crate::http_async; use crate::misc; +use crate::structs; -use std::{fs, path::Path}; - -pub fn local_revision(dir: &Path) -> u16 { - if let Ok(revision) = fs::read_to_string(dir.join(".iw4xrevision")) { - misc::rev_to_int(&revision) - } else { - 0 - } -} +use std::path::Path; pub async fn remote_revision() -> u16 { misc::rev_to_int(&github::latest_tag(GH_IW4X_OWNER, GH_IW4X_REPO).await) } -pub async fn update(dir: &Path) { +pub async fn update(dir: &Path, cache: &mut structs::Cache) { let remote = remote_revision().await; - let local = local_revision(dir); + let local = misc::rev_to_int(&cache.iw4x_revision); if remote <= local && dir.join("iw4x.dll").exists() { crate::println_info!("No files to download for IW4x"); @@ -44,5 +37,6 @@ pub async fn update(dir: &Path) { ) .await .unwrap(); - fs::write(dir.join(".iw4xrevision"), format!("r{remote}")).unwrap(); + + cache.iw4x_revision = format!("r{remote}"); } diff --git a/src/main.rs b/src/main.rs index 37d409a..1005f33 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,12 @@ use indicatif::ProgressBar; #[cfg(windows)] use mslnk::ShellLink; use simple_log::LogConfigBuilder; -use std::{borrow::Cow, collections::HashMap, env, fs, path::Path, path::PathBuf}; +use std::{ + borrow::Cow, + collections::HashMap, + env, fs, + path::{Path, PathBuf}, +}; #[cfg(windows)] use steamlocate::SteamDir; @@ -328,20 +333,14 @@ async fn update( } } - let mut hashes = HashMap::new(); - let hash_file = dir.join(".hashes"); - if hash_file.exists() && !force { - let hash_file = fs::read_to_string(hash_file).unwrap(); - for line in hash_file.lines() { - let mut split = line.split_whitespace(); - let hash = split.next().unwrap(); - let file = split.next().unwrap(); - hashes.insert(file.to_owned(), hash.to_owned()); - } - } + let mut cache = if force { + structs::Cache::default() + } else { + misc::get_cache(dir) + }; if game.engine == "iw4" { - iw4x::update(dir).await; + iw4x::update(dir, &mut cache).await; let iw4x_dirs = vec!["iw4x", "zone/patch"]; for d in &iw4x_dirs { @@ -400,11 +399,19 @@ async fn update( } let pb = ProgressBar::new(0); - update_dir(&cdn_info, game.engine, dir, &mut hashes, &pb, skip_iw4x_sp).await; + update_dir( + &cdn_info, + game.engine, + dir, + &mut cache.hashes, + &pb, + skip_iw4x_sp, + ) + .await; if bonus_content && !game.bonus.is_empty() { for bonus in game.bonus.iter() { - update_dir(&cdn_info, bonus, dir, &mut hashes, &pb, skip_iw4x_sp).await; + update_dir(&cdn_info, bonus, dir, &mut cache.hashes, &pb, skip_iw4x_sp).await; } } @@ -435,11 +442,7 @@ async fn update( } } - let mut hash_file_content = String::new(); - for (file, hash) in hashes.iter() { - hash_file_content.push_str(&format!("{hash} {file}\n")); - } - fs::write(dir.join(".hashes"), hash_file_content).unwrap(); + misc::save_cache(dir, cache); } #[cfg(windows)] diff --git a/src/misc.rs b/src/misc.rs index 53c52d0..ac1ccb1 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -1,7 +1,11 @@ use indicatif::{ProgressBar, ProgressStyle}; -use std::{fs, path::Path}; +use std::{ + fs::{self, OpenOptions}, + io::Write, + path::Path, +}; -use crate::global; +use crate::{global, structs}; pub fn file_blake3(file: &std::path::Path) -> std::io::Result { let mut blake3 = blake3::Hasher::new(); @@ -164,3 +168,31 @@ pub fn prefix(tag_name: &str) -> String { .get(tag_name) .map_or_else(|| tag_name.to_string(), |tag| tag.formatted()) } + +pub fn get_cache(dir: &Path) -> structs::Cache { + let mut cache_file = OpenOptions::new() + .read(true) + .create(true) + .append(true) + .open(dir.join("awcache.json")) + .unwrap(); + let mut cache_s = String::new(); + std::io::Read::read_to_string(&mut cache_file, &mut cache_s).unwrap(); + let cache: structs::Cache = if cache_s.trim().is_empty() { + structs::Cache::default() + } else { + serde_json::from_str(&cache_s).unwrap_or(structs::Cache::default()) + }; + cache +} + +pub fn save_cache(dir: &Path, cache: structs::Cache) { + let mut cache_file = OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(dir.join("awcache.json")) + .unwrap(); + let cache_serialized = serde_json::to_string_pretty(&cache).unwrap(); + cache_file.write_all(cache_serialized.as_bytes()).unwrap(); +} diff --git a/src/structs.rs b/src/structs.rs index 94552e4..c8c6d72 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -1,5 +1,5 @@ use colored::*; -use std::path::Path; +use std::{collections::HashMap, path::Path}; #[derive(serde::Deserialize, serde::Serialize, Clone)] pub struct CdnFile { @@ -74,3 +74,9 @@ impl PrintPrefix { format!("[{}]{:width$}", self.text, "", width = self.padding).to_string() } } + +#[derive(serde::Deserialize, serde::Serialize, Default)] +pub struct Cache { + pub iw4x_revision: String, + pub hashes: HashMap, +}