Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
ByteZ1337 committed Apr 22, 2024
1 parent d1f6a96 commit 27a1a6f
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 26 deletions.
12 changes: 6 additions & 6 deletions src/command/pack.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use std::ffi::OsStr;
use std::path::PathBuf;
use anyhow::Context;

use anyhow::Context;
use walkdir::WalkDir;

use crate::{crypto, I18nCompatMode, NewArgs};
use crate::command::AssetMetadata;
use crate::crypto;

pub fn pack(args: &NewArgs, input: &Option<PathBuf>, output: &PathBuf, locale_mode: &I18nCompatMode) -> anyhow::Result<()> {
pub fn pack(art_key: &String, input: &Option<PathBuf>, output: &PathBuf) -> anyhow::Result<()> {
let input = find_input(input);
if let Err(e) = input {
anyhow::bail!("Error while finding input: {}", e);
Expand All @@ -17,7 +17,7 @@ pub fn pack(args: &NewArgs, input: &Option<PathBuf>, output: &PathBuf, locale_mo
match extension {
Some(ext) => {
if ext == OsStr::new("dat") || ext == OsStr::new("txt") {
pack_dat(args, &input.unwrap(), output, locale_mode)
pack_dat(art_key, &input.unwrap(), output)
} else {
anyhow::bail!("Output file has an invalid extension. (Use .dat or .txt)");
}
Expand Down Expand Up @@ -62,7 +62,7 @@ fn find_input(input: &Option<PathBuf>) -> anyhow::Result<PathBuf> {
}
}

fn pack_dat(args: &NewArgs, input: &PathBuf, output: &PathBuf, _locale_mode: &I18nCompatMode) -> anyhow::Result<()> {
fn pack_dat(art_key: &String, input: &PathBuf, output: &PathBuf) -> anyhow::Result<()> {
let mut assets: Vec<AssetMetadata> = Vec::new();
let mut asset_bytes: Vec<u8> = Vec::new();

Expand Down Expand Up @@ -100,7 +100,7 @@ fn pack_dat(args: &NewArgs, input: &PathBuf, output: &PathBuf, _locale_mode: &I1
out.append(&mut asset_bytes);

println!("Encrypting assets...");
let key = args.art_key.clone().unwrap();
let key = art_key.clone();
let enc_key = crypto::to_key_array(key.as_str());
let enc_key = enc_key.as_slice();
crypto::encrypt(enc_key, out.as_mut_slice());
Expand Down
38 changes: 27 additions & 11 deletions src/command/unpack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ use binrw::io::BufReader;

use crate::{crypto, NewArgs};
use crate::command::ArtHeader;
use crate::read_ext::ReadExt;
use crate::io_ext::ReadExt;
use crate::unity::AssetsFile;

pub fn unpack(args: &NewArgs, input: &PathBuf, output: &PathBuf) -> anyhow::Result<()> {
let extension = input.extension();
match extension {
Some(ext) => {
if ext == OsStr::new("dat") || ext == OsStr::new("txt") {
unpack_dat(args, input, output)
unpack_dat(args, input, output)?;
} else if ext == OsStr::new("assets") {
unpack_assets(args, input, output)
unpack_assets(args, input, output)?;
} else {
anyhow::bail!("Input file has an invalid extension. (Supported: .dat, .assets)");
}
Expand All @@ -28,6 +28,8 @@ pub fn unpack(args: &NewArgs, input: &PathBuf, output: &PathBuf) -> anyhow::Resu
anyhow::bail!("Input file has no extension. (Supported: .dat, .assets)");
}
}

Ok(())
}

pub fn unpack_dat(args: &NewArgs, input: &PathBuf, output: &PathBuf) -> anyhow::Result<()> {
Expand All @@ -38,8 +40,8 @@ pub fn unpack_dat(args: &NewArgs, input: &PathBuf, output: &PathBuf) -> anyhow::
// key can be unwrapped safely here
let key = args.art_key.clone().unwrap();
let enc_key = crypto::to_key_array(key.as_str());
let enc_key = enc_key.as_slice();
crypto::decrypt(enc_key, data.as_mut_slice());
let enc_key_slice = enc_key.as_slice();
crypto::decrypt(enc_key_slice, data.as_mut_slice());

// Read header string
let len = u16::from_le_bytes([data[0], data[1]]) as usize;
Expand Down Expand Up @@ -76,8 +78,15 @@ pub fn unpack_dat(args: &NewArgs, input: &PathBuf, output: &PathBuf) -> anyhow::
Ok(())
}

pub fn unpack_assets(args: &NewArgs, input: &PathBuf, output: &PathBuf) -> anyhow::Result<()> {
let input = File::open(input)
pub struct RepackInfo {
pub assets: AssetsFile,
pub art_path_id: i64,
pub art_key: String,
pub original_assets: PathBuf,
}

pub fn unpack_assets(args: &NewArgs, input_path: &PathBuf, output: &PathBuf) -> anyhow::Result<RepackInfo> {
let input = File::open(input_path)
.context("Failed to open input file")?;
let mut input = BufReader::new(input);
let assets = AssetsFile::read(&mut input)
Expand All @@ -86,11 +95,12 @@ pub fn unpack_assets(args: &NewArgs, input: &PathBuf, output: &PathBuf) -> anyho
.context("Failed to resolve object classes")?;

let mut art_file: Option<PathBuf> = None;
let mut art_path_id: Option<i64> = None;
for obj in objects {
if obj.class_id == 49 { // text asset
input.seek(SeekFrom::Start(assets.header.offset_first_file + obj.byte_start))
.context("Failed to seek to object")?;
let name = input.read_dyn_string(&assets.header.endianness, i32::BITS)
let name = input.read_dyn_string(&assets.header.endianness)
.context("Failed to read object name")?;

if name == "Art.dat" {
Expand All @@ -110,8 +120,9 @@ pub fn unpack_assets(args: &NewArgs, input: &PathBuf, output: &PathBuf) -> anyho

std::io::copy(&mut temp_reader, &mut temp_writer)
.context("Failed to copy object data")?;

art_file = Some(temp);
art_path_id = Some(obj.path_id);
break;
}
}
Expand All @@ -123,9 +134,14 @@ pub fn unpack_assets(args: &NewArgs, input: &PathBuf, output: &PathBuf) -> anyho
if let Err(e) = std::fs::remove_file(art_file) {
eprintln!("Failed to remove temporary file: {}", e);
}
// Any unwraps here are safe because None values would've resulted in earlier bail
Ok(RepackInfo {
assets,
art_path_id: art_path_id.unwrap(),
art_key: args.art_key.clone().unwrap(),
original_assets: input_path.clone(),
})
} else {
anyhow::bail!("Failed to find Art.dat object in assets file");
}

Ok(())
}
11 changes: 4 additions & 7 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use clap_derive::{Parser, Subcommand, ValueEnum};
use crate::command::{pack, patch, unpack};

mod crypto;
mod read_ext;
mod io_ext;
mod command;
mod unity;

Expand Down Expand Up @@ -57,10 +57,6 @@ enum Command {
/// Output file. Make sure to use the .dat or .txt extension.
#[arg(short, long, default_value = "Art-modded.dat")]
output: PathBuf,

/// How should the tool handle localized assets.
#[arg(long, default_value = "none")]
i18n: I18nCompatMode,
},
/// Unpack assets from an Art.dat or unity asset bundle.
Unpack {
Expand Down Expand Up @@ -108,8 +104,9 @@ fn main() {
}

let res = match &args.command {
Command::Pack { input, output, i18n } => {
pack::pack(&args, input, output, i18n)
Command::Pack { input, output } => {
// unwrap is safe here
pack::pack(&args.art_key.unwrap(), input, output)
}
Command::Unpack { input, output } => {
unpack::unpack(&args, input, output)
Expand Down
4 changes: 2 additions & 2 deletions src/unity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub mod util;
#[derive(Debug, PartialEq)]
pub struct AssetsFile {
#[brw(big)]
pub header: AssetFileHeader,
pub header: AssetsFileHeader,
#[brw(is_little = header.endianness == Endian::Little)]
pub content: AssetsFileContent,
}
Expand Down Expand Up @@ -38,7 +38,7 @@ impl AssetsFile {
#[binrw]
#[brw(big)]
#[derive(Debug, PartialEq)]
pub struct AssetFileHeader {
pub struct AssetsFileHeader {
#[br(assert(version == 22))]
#[brw(pad_before = 8, pad_after = 4)]
pub version: u32,
Expand Down

0 comments on commit 27a1a6f

Please sign in to comment.