From 694f2fd46e5838eda72aede6217fca6ec916f034 Mon Sep 17 00:00:00 2001 From: DecDuck Date: Tue, 24 Dec 2024 12:52:40 +1100 Subject: [PATCH] chore(stored manifest): swap file name and to binary encoding --- src-tauri/Cargo.lock | 21 ++++++++ src-tauri/Cargo.toml | 1 + src-tauri/src/downloads/download_agent.rs | 21 ++++---- .../src/downloads/download_manager_builder.rs | 2 +- src-tauri/src/downloads/stored_manifest.rs | 50 ++++++++++++------- src-tauri/src/lib.rs | 1 + src-tauri/src/process/process_manager.rs | 12 +++-- 7 files changed, 75 insertions(+), 33 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 9a75a23..f9523c7 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -294,6 +294,15 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "binary-stream" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4ef03ef225ea9a0b680a5926a58cb45d8eb56abf23d8a8b5c5dbc61235e2dac" +dependencies = [ + "thiserror 1.0.69", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -969,6 +978,7 @@ dependencies = [ "rustbreak", "rustix", "serde", + "serde-binary", "serde_json", "tauri", "tauri-build", @@ -3692,6 +3702,17 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-binary" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b550db407b83ed53a4f76f888bfd7441b685abc2c086e20fb47781a286940506" +dependencies = [ + "binary-stream", + "serde", + "thiserror 1.0.69", +] + [[package]] name = "serde-untagged" version = "0.1.6" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index f917caa..64f0f9b 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -28,6 +28,7 @@ tauri-build = { version = "2.0.0", features = [] } tauri-plugin-shell = "2.0.0" serde = { version = "1", features = ["derive", "rc"] } serde_json = "1" +serde-binary = "0.5.0" rayon = "1.10.0" directories = "5.0.1" webbrowser = "1.0.2" diff --git a/src-tauri/src/downloads/download_agent.rs b/src-tauri/src/downloads/download_agent.rs index 07e7f7c..99d8217 100644 --- a/src-tauri/src/downloads/download_agent.rs +++ b/src-tauri/src/downloads/download_agent.rs @@ -31,13 +31,12 @@ pub struct GameDownloadAgent { pub id: String, pub version: String, pub control_flag: DownloadThreadControl, - pub base_dir: String, contexts: Vec, completed_contexts: Mutex>, pub manifest: Mutex>, pub progress: Arc, sender: Sender, - stored_manifest: StoredManifest + pub stored_manifest: StoredManifest, } #[derive(Debug)] @@ -93,14 +92,14 @@ impl GameDownloadAgent { let base_dir_path = Path::new(&base_dir); let data_base_dir_path = base_dir_path.join(id.clone()); - let stored_manifest = StoredManifest::generate(id.clone(), version.clone(), data_base_dir_path.clone()); + let stored_manifest = + StoredManifest::generate(id.clone(), version.clone(), data_base_dir_path.clone()); Self { id, version, control_flag, manifest: Mutex::new(None), - base_dir: data_base_dir_path.to_str().unwrap().to_owned(), contexts: Vec::new(), completed_contexts: Mutex::new(Vec::new()), progress: Arc::new(ProgressObject::new(0, 0, sender.clone())), @@ -217,13 +216,15 @@ impl GameDownloadAgent { let game_id = self.id.clone(); let mut contexts = Vec::new(); - let base_path = Path::new(&self.base_dir); + let base_path = Path::new(&self.stored_manifest.base_path); create_dir_all(base_path).unwrap(); *self.completed_contexts.lock().unwrap() = self.stored_manifest.get_completed_contexts(); - info!("Completed contexts: {:?}", *self.completed_contexts.lock().unwrap()); - + info!( + "Completed contexts: {:?}", + *self.completed_contexts.lock().unwrap() + ); for (raw_path, chunk) in manifest { let path = base_path.join(Path::new(&raw_path)); @@ -279,7 +280,6 @@ impl GameDownloadAgent { let progress_handle = ProgressHandle::new(progress, self.progress.clone()); // If we've done this one already, skip it if completed_lock.contains(&index) { - info!("Skipping index {}", index); progress_handle.add(context.length); continue; } @@ -308,7 +308,7 @@ impl GameDownloadAgent { let completed_lock_len = { let mut completed_lock = self.completed_contexts.lock().unwrap(); let newly_completed_lock = completed_indexes.lock().unwrap(); - + completed_lock.extend(newly_completed_lock.iter()); completed_lock.len() @@ -317,7 +317,8 @@ impl GameDownloadAgent { // If we're not out of contexts, we're not done, so we don't fire completed if completed_lock_len != self.contexts.len() { info!("da for {} exited without completing", self.id.clone()); - self.stored_manifest.set_completed_contexts(&self.completed_contexts); + self.stored_manifest + .set_completed_contexts(&self.completed_contexts); info!("Setting completed contexts"); self.stored_manifest.write(); info!("Wrote completed contexts"); diff --git a/src-tauri/src/downloads/download_manager_builder.rs b/src-tauri/src/downloads/download_manager_builder.rs index c24bbe3..9d2ab9d 100644 --- a/src-tauri/src/downloads/download_manager_builder.rs +++ b/src-tauri/src/downloads/download_manager_builder.rs @@ -260,7 +260,7 @@ impl DownloadManagerBuilder { let download_agent_lock = download_agent.lock().unwrap(); let version = download_agent_lock.version.clone(); - let install_dir = download_agent_lock.base_dir.clone(); + let install_dir = download_agent_lock.stored_manifest.base_path.clone().to_string_lossy().to_string(); drop(download_agent_lock); diff --git a/src-tauri/src/downloads/stored_manifest.rs b/src-tauri/src/downloads/stored_manifest.rs index 27b7ba7..cd4006d 100644 --- a/src-tauri/src/downloads/stored_manifest.rs +++ b/src-tauri/src/downloads/stored_manifest.rs @@ -1,16 +1,25 @@ -use std::{default, fs::File, io::{Read, Write}, path::{Path, PathBuf}, sync::Mutex}; +use std::{ + default, + fs::File, + io::{Read, Write}, + path::{Path, PathBuf}, + sync::Mutex, +}; use log::{error, info}; use serde::{Deserialize, Serialize}; +use serde_binary::binary_stream::Endian; #[derive(Serialize, Deserialize, Debug)] pub struct StoredManifest { game_id: String, game_version: String, pub completed_contexts: Mutex>, - base_path: PathBuf + pub base_path: PathBuf, } +static DROP_DATA_PATH: &str = ".dropdata"; + impl StoredManifest { pub fn new(game_id: String, game_version: String, base_path: PathBuf) -> Self { Self { @@ -21,39 +30,46 @@ impl StoredManifest { } } pub fn generate(game_id: String, game_version: String, base_path: PathBuf) -> Self { - let mut file = match File::open(base_path.join("manifest.json")) { + let mut file = match File::open(base_path.join(DROP_DATA_PATH)) { Ok(file) => file, Err(_) => return StoredManifest::new(game_id, game_version, base_path), }; - let mut s = String::new(); - match file.read_to_string(&mut s) { - Ok(_) => {}, - Err(e) => { error!("{}", e); return StoredManifest::new(game_id, game_version, base_path) }, + let mut s = Vec::new(); + match file.read_to_end(&mut s) { + Ok(_) => {} + Err(e) => { + error!("{}", e); + return StoredManifest::new(game_id, game_version, base_path); + } }; - info!("Contexts string: {}", s); - let manifest = match serde_json::from_str::(&s) { + let manifest = match serde_binary::from_vec::(s, Endian::Little) { Ok(manifest) => manifest, - Err(e) => { error!("{}", e); StoredManifest::new(game_id, game_version, base_path) }, + Err(e) => { + error!("{}", e); + StoredManifest::new(game_id, game_version, base_path) + } }; - info!("Completed manifest: {:?}", manifest); return manifest; } pub fn write(&self) { - let manifest_json = match serde_json::to_string(&self) { + let manifest_raw = match serde_binary::to_vec(&self, Endian::Little) { Ok(json) => json, Err(_) => return, }; - let mut file = match File::create(self.base_path.join("manifest.json")) { + let mut file = match File::create(self.base_path.join(DROP_DATA_PATH)) { Ok(file) => file, - Err(e) => { error!("{}", e); return; }, + Err(e) => { + error!("{}", e); + return; + } }; - match file.write_all(manifest_json.as_bytes()) { - Ok(_) => {}, + match file.write_all(&manifest_raw) { + Ok(_) => {} Err(e) => error!("{}", e), }; } @@ -63,4 +79,4 @@ impl StoredManifest { pub fn get_completed_contexts(&self) -> Vec { self.completed_contexts.lock().unwrap().clone() } -} \ No newline at end of file +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 5ed468a..f483cec 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -25,6 +25,7 @@ use library::{fetch_game, fetch_game_status, fetch_game_verion_options, fetch_li use log::{debug, info, LevelFilter}; use log4rs::append::console::ConsoleAppender; use log4rs::append::file::FileAppender; +use log4rs::append::rolling_file::RollingFileAppender; use log4rs::config::{Appender, Root}; use log4rs::encode::pattern::PatternEncoder; use log4rs::Config; diff --git a/src-tauri/src/process/process_manager.rs b/src-tauri/src/process/process_manager.rs index 8c03590..9da6de9 100644 --- a/src-tauri/src/process/process_manager.rs +++ b/src-tauri/src/process/process_manager.rs @@ -101,16 +101,18 @@ impl ProcessManager { let current_time = chrono::offset::Local::now(); let mut log_file = OpenOptions::new() + .truncate(true) .append(true) .read(true) .create(true) - .open(self.log_output_dir.join(format!( - "{}-{}.log", - game_id, - current_time.timestamp() - ))) + .open( + self.log_output_dir + .join(format!("{}-{}.log", game_id, current_time.timestamp())), + ) .map_err(|v| v.to_string())?; + log_file.write(&Vec::new()).unwrap(); + writeln!( log_file, "Drop: launching {} with args {:?} in {}",