write a metadata to uncompressed pak

This commit is contained in:
2025-07-28 18:45:11 +08:00
parent 6bd30c682d
commit c64a9a8fbb
5 changed files with 100 additions and 2 deletions

26
Cargo.lock generated
View File

@@ -616,6 +616,12 @@ dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "jobserver"
version = "0.1.33"
@@ -718,6 +724,8 @@ dependencies = [
"rayon",
"re-tex",
"ree-pak-core",
"serde",
"serde_json",
]
[[package]]
@@ -1183,6 +1191,12 @@ version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "scopeguard"
version = "1.2.0"
@@ -1209,6 +1223,18 @@ dependencies = [
"syn 2.0.104",
]
[[package]]
name = "serde_json"
version = "1.0.141"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]]
name = "serde_spanned"
version = "0.6.9"

View File

@@ -18,3 +18,5 @@ rayon = "1.10"
parking_lot = "0.12"
colored = "3.0"
fs-err = "3.1.1"
serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.141"

View File

@@ -24,7 +24,7 @@ use ree_pak_core::{
write::FileOptions,
};
use crate::{chunk::ChunkName, util::human_bytes};
use crate::{chunk::ChunkName, metadata::PakMetadata, util::human_bytes};
const FILE_NAME_LIST: &[u8] = include_bytes!("../assets/MHWs_STM_Release.list.zst");
const AUTO_CHUNK_SELECTION_SIZE_THRESHOLD: usize = 50 * 1024 * 1024; // 50MB
@@ -111,7 +111,15 @@ impl App {
.truncate(true)
.write(true)
.open(output_path)?;
let pak_writer = ree_pak_core::write::PakWriter::new(out_file, entries.len() as u64);
let mut pak_writer = ree_pak_core::write::PakWriter::new(out_file, entries.len() as u64);
// write metadata
let metadata = PakMetadata {
version: 1,
is_uncompressed_patch: true,
};
metadata.write_to_pak(&mut pak_writer)?;
let pak_writer_mtx = Arc::new(Mutex::new(pak_writer));
let bar = ProgressBar::new(entries.len() as u64);

View File

@@ -1,5 +1,6 @@
mod app;
mod chunk;
mod metadata;
mod util;
use colored::Colorize;

61
src/metadata.rs Normal file
View File

@@ -0,0 +1,61 @@
//! Extended metadata for generated pak files.
use std::io::{self, Read, Write};
use ree_pak_core::{
filename::{FileNameExt, FileNameFull},
pak::PakArchive,
read::archive::PakArchiveReader,
write::{FileOptions, PakWriter},
};
use serde::{Deserialize, Serialize};
const METADATA_KEY: &str = "__TEX_DECOMPRESSOR_METADATA__";
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PakMetadata {
pub version: u32,
pub is_uncompressed_patch: bool,
}
impl PakMetadata {
pub fn from_pak_archive<R>(
reader: R,
pak_archive: &PakArchive,
) -> color_eyre::Result<Option<Self>>
where
R: io::Read + io::Seek,
{
let key_name = FileNameFull::new(METADATA_KEY);
let entry = pak_archive
.entries()
.iter()
.find(|entry| entry.hash() == key_name.hash_mixed());
if let Some(entry) = entry {
// read file
let mut archive_reader = PakArchiveReader::new(reader, pak_archive);
let mut entry_reader = archive_reader.owned_entry_reader(entry.clone())?;
let mut buf = Vec::new();
entry_reader.read_to_end(&mut buf)?;
let metadata = serde_json::from_slice(&buf)?;
Ok(Some(metadata))
} else {
Ok(None)
}
}
pub fn write_to_pak<W>(&self, pak_writer: &mut PakWriter<W>) -> color_eyre::Result<()>
where
W: io::Write + io::Seek,
{
let json_str = serde_json::to_string(self)?;
let json_bytes = json_str.as_bytes();
pak_writer.start_file(METADATA_KEY, FileOptions::default())?;
pak_writer.write_all(json_bytes)?;
Ok(())
}
}