add a subcommand to describe .one archives
This commit is contained in:
parent
ccc06c81d1
commit
202f6cd640
|
@ -18,7 +18,8 @@ struct Args {
|
|||
#[derive(FromArgs)]
|
||||
#[argh(subcommand)]
|
||||
enum Action {
|
||||
ExtractFile(ExtractFile)
|
||||
ExtractFile(ExtractFile),
|
||||
DescribeFile(DescribeFile),
|
||||
}
|
||||
|
||||
/// Unpack and decompress the files inside a .one archive.
|
||||
|
@ -30,14 +31,23 @@ struct ExtractFile {
|
|||
file: PathBuf,
|
||||
}
|
||||
|
||||
/// Describe the metadata of a .one archive.
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "tf")]
|
||||
struct DescribeFile {
|
||||
/// path to the .one file
|
||||
#[argh(positional)]
|
||||
file: PathBuf,
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let args: Args = argh::from_env();
|
||||
match args.action {
|
||||
Action::ExtractFile(ex) => {
|
||||
let mut infile = File::open(&ex.file)?;
|
||||
Action::ExtractFile(subcmd) => {
|
||||
let mut infile = File::open(&subcmd.file)?;
|
||||
let archive: JodOne = infile.read_le()?;
|
||||
let entries = archive.unpack();
|
||||
let dir = PathBuf::from(format!("{}.d", ex.file.to_string_lossy()));
|
||||
let dir = PathBuf::from(format!("{}.d", subcmd.file.to_string_lossy()));
|
||||
for (name, data) in entries {
|
||||
let full_path = dir.join(name);
|
||||
if let Some(path) = full_path.parent() {
|
||||
|
@ -46,6 +56,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
File::create(full_path)?.write_all(&data)?;
|
||||
}
|
||||
}
|
||||
Action::DescribeFile(subcmd) => {
|
||||
let mut infile = File::open(&subcmd.file)?;
|
||||
let archive: JodOne = infile.read_le()?;
|
||||
println!("{:?}", archive);
|
||||
for entry in archive.entries {
|
||||
println!("{:?}", entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use binread::{FilePtr, NullString};
|
||||
use prs_rust::prs;
|
||||
use std::ffi::OsString;
|
||||
use std::fmt::Formatter;
|
||||
use std::path::PathBuf;
|
||||
|
||||
|
@ -46,7 +45,7 @@ pub struct JodOneEntry {
|
|||
pub _unknown1: u32,
|
||||
pub id: u32,
|
||||
pub size_cmp: u32,
|
||||
pub _unknown2: u32,
|
||||
pub is_compressed: u32,
|
||||
pub size_dec: u32,
|
||||
pub id_again: u32,
|
||||
#[br(count = size_cmp)]
|
||||
|
@ -57,14 +56,38 @@ pub struct JodOneEntry {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for JodOne {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "JodOne{{_unknown1: 0x{:x}, category: {}, count: {}, ..}}", self._unknown1, self.category, self.count)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for JodOneEntry {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "JodOneEntry{{id: {}, name: {:?}, size_cmp: {}, size_dec: {}, ..}}", self.id, self.name.to_string(), self.size_cmp, self.size_dec)
|
||||
write!(
|
||||
f,
|
||||
"JodOneEntry{{_unknown1: 0x{:x}, id: {}, is_compressed: {}, name: {:?}, size_cmp: {}, size_dec: {}, ..}}",
|
||||
self._unknown1, self.id, self.is_compressed != 0, self.name.to_string(), self.size_cmp, self.size_dec,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl JodOne {
|
||||
pub fn pack(inputs: impl Iterator<Item = (PathBuf, Vec<u8>)>, category: Option<&str>) -> Self {
|
||||
let mut entries = Vec::new();
|
||||
for (id, (path, data)) in inputs.enumerate() {
|
||||
|
||||
entries.push(JodOneEntry {
|
||||
_unknown1: 0,
|
||||
id: id as u32,
|
||||
size_cmp: data.len() as u32,
|
||||
is_compressed: 0,
|
||||
size_dec: 0,
|
||||
id_again: id as u32,
|
||||
data: FilePtr { ptr: 0, value: Some(data) },
|
||||
name: path.to_string_lossy().replace(std::path::MAIN_SEPARATOR, "\\"),
|
||||
})
|
||||
}
|
||||
JodOne {
|
||||
_unknown1: 0xCC,
|
||||
category: category.unwrap_or("Default").to_string(),
|
||||
|
|
Loading…
Reference in New Issue