chore(stored manifest): swap file name and to binary encoding

This commit is contained in:
DecDuck
2024-12-24 12:52:40 +11:00
parent f09605aa7e
commit 694f2fd46e
7 changed files with 75 additions and 33 deletions

21
src-tauri/Cargo.lock generated
View File

@ -294,6 +294,15 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 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]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.3.2"
@ -969,6 +978,7 @@ dependencies = [
"rustbreak", "rustbreak",
"rustix", "rustix",
"serde", "serde",
"serde-binary",
"serde_json", "serde_json",
"tauri", "tauri",
"tauri-build", "tauri-build",
@ -3692,6 +3702,17 @@ dependencies = [
"serde_derive", "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]] [[package]]
name = "serde-untagged" name = "serde-untagged"
version = "0.1.6" version = "0.1.6"

View File

@ -28,6 +28,7 @@ tauri-build = { version = "2.0.0", features = [] }
tauri-plugin-shell = "2.0.0" tauri-plugin-shell = "2.0.0"
serde = { version = "1", features = ["derive", "rc"] } serde = { version = "1", features = ["derive", "rc"] }
serde_json = "1" serde_json = "1"
serde-binary = "0.5.0"
rayon = "1.10.0" rayon = "1.10.0"
directories = "5.0.1" directories = "5.0.1"
webbrowser = "1.0.2" webbrowser = "1.0.2"

View File

@ -31,13 +31,12 @@ pub struct GameDownloadAgent {
pub id: String, pub id: String,
pub version: String, pub version: String,
pub control_flag: DownloadThreadControl, pub control_flag: DownloadThreadControl,
pub base_dir: String,
contexts: Vec<DropDownloadContext>, contexts: Vec<DropDownloadContext>,
completed_contexts: Mutex<Vec<usize>>, completed_contexts: Mutex<Vec<usize>>,
pub manifest: Mutex<Option<DropManifest>>, pub manifest: Mutex<Option<DropManifest>>,
pub progress: Arc<ProgressObject>, pub progress: Arc<ProgressObject>,
sender: Sender<DownloadManagerSignal>, sender: Sender<DownloadManagerSignal>,
stored_manifest: StoredManifest pub stored_manifest: StoredManifest,
} }
#[derive(Debug)] #[derive(Debug)]
@ -93,14 +92,14 @@ impl GameDownloadAgent {
let base_dir_path = Path::new(&base_dir); let base_dir_path = Path::new(&base_dir);
let data_base_dir_path = base_dir_path.join(id.clone()); 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 { Self {
id, id,
version, version,
control_flag, control_flag,
manifest: Mutex::new(None), manifest: Mutex::new(None),
base_dir: data_base_dir_path.to_str().unwrap().to_owned(),
contexts: Vec::new(), contexts: Vec::new(),
completed_contexts: Mutex::new(Vec::new()), completed_contexts: Mutex::new(Vec::new()),
progress: Arc::new(ProgressObject::new(0, 0, sender.clone())), progress: Arc::new(ProgressObject::new(0, 0, sender.clone())),
@ -217,13 +216,15 @@ impl GameDownloadAgent {
let game_id = self.id.clone(); let game_id = self.id.clone();
let mut contexts = Vec::new(); 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(); create_dir_all(base_path).unwrap();
*self.completed_contexts.lock().unwrap() = self.stored_manifest.get_completed_contexts(); *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 { for (raw_path, chunk) in manifest {
let path = base_path.join(Path::new(&raw_path)); let path = base_path.join(Path::new(&raw_path));
@ -279,7 +280,6 @@ impl GameDownloadAgent {
let progress_handle = ProgressHandle::new(progress, self.progress.clone()); let progress_handle = ProgressHandle::new(progress, self.progress.clone());
// If we've done this one already, skip it // If we've done this one already, skip it
if completed_lock.contains(&index) { if completed_lock.contains(&index) {
info!("Skipping index {}", index);
progress_handle.add(context.length); progress_handle.add(context.length);
continue; continue;
} }
@ -317,7 +317,8 @@ impl GameDownloadAgent {
// If we're not out of contexts, we're not done, so we don't fire completed // If we're not out of contexts, we're not done, so we don't fire completed
if completed_lock_len != self.contexts.len() { if completed_lock_len != self.contexts.len() {
info!("da for {} exited without completing", self.id.clone()); 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"); info!("Setting completed contexts");
self.stored_manifest.write(); self.stored_manifest.write();
info!("Wrote completed contexts"); info!("Wrote completed contexts");

View File

@ -260,7 +260,7 @@ impl DownloadManagerBuilder {
let download_agent_lock = download_agent.lock().unwrap(); let download_agent_lock = download_agent.lock().unwrap();
let version = download_agent_lock.version.clone(); 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); drop(download_agent_lock);

View File

@ -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 log::{error, info};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_binary::binary_stream::Endian;
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct StoredManifest { pub struct StoredManifest {
game_id: String, game_id: String,
game_version: String, game_version: String,
pub completed_contexts: Mutex<Vec<usize>>, pub completed_contexts: Mutex<Vec<usize>>,
base_path: PathBuf pub base_path: PathBuf,
} }
static DROP_DATA_PATH: &str = ".dropdata";
impl StoredManifest { impl StoredManifest {
pub fn new(game_id: String, game_version: String, base_path: PathBuf) -> Self { pub fn new(game_id: String, game_version: String, base_path: PathBuf) -> Self {
Self { Self {
@ -21,39 +30,46 @@ impl StoredManifest {
} }
} }
pub fn generate(game_id: String, game_version: String, base_path: PathBuf) -> Self { 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, Ok(file) => file,
Err(_) => return StoredManifest::new(game_id, game_version, base_path), Err(_) => return StoredManifest::new(game_id, game_version, base_path),
}; };
let mut s = String::new(); let mut s = Vec::new();
match file.read_to_string(&mut s) { match file.read_to_end(&mut s) {
Ok(_) => {}, Ok(_) => {}
Err(e) => { error!("{}", e); return StoredManifest::new(game_id, game_version, base_path) }, Err(e) => {
error!("{}", e);
return StoredManifest::new(game_id, game_version, base_path);
}
}; };
info!("Contexts string: {}", s); let manifest = match serde_binary::from_vec::<StoredManifest>(s, Endian::Little) {
let manifest = match serde_json::from_str::<StoredManifest>(&s) {
Ok(manifest) => manifest, 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; return manifest;
} }
pub fn write(&self) { 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, Ok(json) => json,
Err(_) => return, 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, Ok(file) => file,
Err(e) => { error!("{}", e); return; }, Err(e) => {
error!("{}", e);
return;
}
}; };
match file.write_all(manifest_json.as_bytes()) { match file.write_all(&manifest_raw) {
Ok(_) => {}, Ok(_) => {}
Err(e) => error!("{}", e), Err(e) => error!("{}", e),
}; };
} }

View File

@ -25,6 +25,7 @@ use library::{fetch_game, fetch_game_status, fetch_game_verion_options, fetch_li
use log::{debug, info, LevelFilter}; use log::{debug, info, LevelFilter};
use log4rs::append::console::ConsoleAppender; use log4rs::append::console::ConsoleAppender;
use log4rs::append::file::FileAppender; use log4rs::append::file::FileAppender;
use log4rs::append::rolling_file::RollingFileAppender;
use log4rs::config::{Appender, Root}; use log4rs::config::{Appender, Root};
use log4rs::encode::pattern::PatternEncoder; use log4rs::encode::pattern::PatternEncoder;
use log4rs::Config; use log4rs::Config;

View File

@ -101,16 +101,18 @@ impl ProcessManager {
let current_time = chrono::offset::Local::now(); let current_time = chrono::offset::Local::now();
let mut log_file = OpenOptions::new() let mut log_file = OpenOptions::new()
.truncate(true)
.append(true) .append(true)
.read(true) .read(true)
.create(true) .create(true)
.open(self.log_output_dir.join(format!( .open(
"{}-{}.log", self.log_output_dir
game_id, .join(format!("{}-{}.log", game_id, current_time.timestamp())),
current_time.timestamp() )
)))
.map_err(|v| v.to_string())?; .map_err(|v| v.to_string())?;
log_file.write(&Vec::new()).unwrap();
writeln!( writeln!(
log_file, log_file,
"Drop: launching {} with args {:?} in {}", "Drop: launching {} with args {:?} in {}",