99 lines
2.7 KiB
Rust
99 lines
2.7 KiB
Rust
#[macro_use] extern crate argh;
|
|
extern crate binread;
|
|
extern crate one_rust;
|
|
|
|
use std::fs::File;
|
|
use std::io::prelude::*;
|
|
use std::path::PathBuf;
|
|
use binread::prelude::*;
|
|
use one_rust::JodOne;
|
|
|
|
/// Unpack .one archives from NiGHTS: Journey of Dreams
|
|
#[derive(FromArgs)]
|
|
struct Args {
|
|
#[argh(subcommand)]
|
|
action: Action,
|
|
}
|
|
|
|
#[derive(FromArgs)]
|
|
#[argh(subcommand)]
|
|
enum Action {
|
|
ExtractFile(ExtractFile),
|
|
CreateFile(CreateFile),
|
|
DescribeFile(DescribeFile),
|
|
}
|
|
|
|
/// Unpack and decompress the files inside a .one archive.
|
|
#[derive(FromArgs)]
|
|
#[argh(subcommand, name = "xf")]
|
|
struct ExtractFile {
|
|
/// path to the .one file
|
|
#[argh(positional)]
|
|
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,
|
|
}
|
|
|
|
/// Create a .one archive from the given files.
|
|
#[derive(FromArgs)]
|
|
#[argh(subcommand, name = "cf")]
|
|
struct CreateFile {
|
|
/// path of the .one file to create
|
|
#[argh(positional)]
|
|
file: PathBuf,
|
|
/// paths of the files to pack into the archive
|
|
#[argh(positional)]
|
|
contents: Vec<PathBuf>,
|
|
}
|
|
|
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
let args: Args = argh::from_env();
|
|
match args.action {
|
|
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", subcmd.file.to_string_lossy()));
|
|
for (name, data) in entries {
|
|
let full_path = dir.join(name);
|
|
if let Some(path) = full_path.parent() {
|
|
std::fs::create_dir_all(path)?;
|
|
}
|
|
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);
|
|
}
|
|
}
|
|
Action::CreateFile(subcmd) => {
|
|
if subcmd.file.exists() {
|
|
return Err(format!("{:?} already exists, refusing to overwrite", subcmd.file).into());
|
|
}
|
|
|
|
let mut entries = Vec::new();
|
|
for path in subcmd.contents {
|
|
let mut data = Vec::new();
|
|
File::open(&path)?.read_to_end(&mut data)?;
|
|
entries.push((path, data));
|
|
}
|
|
|
|
let archive = JodOne::pack(entries, None);
|
|
let outfile = File::create(&subcmd.file)?;
|
|
archive.write(outfile)?;
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|