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

View File

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

View File

@ -31,13 +31,12 @@ pub struct GameDownloadAgent {
pub id: String,
pub version: String,
pub control_flag: DownloadThreadControl,
pub base_dir: String,
contexts: Vec<DropDownloadContext>,
completed_contexts: Mutex<Vec<usize>>,
pub manifest: Mutex<Option<DropManifest>>,
pub progress: Arc<ProgressObject>,
sender: Sender<DownloadManagerSignal>,
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;
}
@ -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");

View File

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

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 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<Vec<usize>>,
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::<StoredManifest>(&s) {
let manifest = match serde_binary::from_vec::<StoredManifest>(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),
};
}

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

View File

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