mirror of
https://github.com/Drop-OSS/drop-app.git
synced 2025-11-13 16:22:43 +10:00
chore(stored manifest): swap file name and to binary encoding
This commit is contained in:
21
src-tauri/Cargo.lock
generated
21
src-tauri/Cargo.lock
generated
@ -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"
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
@ -308,7 +308,7 @@ impl GameDownloadAgent {
|
|||||||
let completed_lock_len = {
|
let completed_lock_len = {
|
||||||
let mut completed_lock = self.completed_contexts.lock().unwrap();
|
let mut completed_lock = self.completed_contexts.lock().unwrap();
|
||||||
let newly_completed_lock = completed_indexes.lock().unwrap();
|
let newly_completed_lock = completed_indexes.lock().unwrap();
|
||||||
|
|
||||||
completed_lock.extend(newly_completed_lock.iter());
|
completed_lock.extend(newly_completed_lock.iter());
|
||||||
|
|
||||||
completed_lock.len()
|
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 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");
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
@ -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),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -63,4 +79,4 @@ impl StoredManifest {
|
|||||||
pub fn get_completed_contexts(&self) -> Vec<usize> {
|
pub fn get_completed_contexts(&self) -> Vec<usize> {
|
||||||
self.completed_contexts.lock().unwrap().clone()
|
self.completed_contexts.lock().unwrap().clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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 {}",
|
||||||
|
|||||||
Reference in New Issue
Block a user