From 3215670ae0cf7653f750d87ee4dfe17d813e49d2 Mon Sep 17 00:00:00 2001 From: Lucas Schwiderski Date: Tue, 26 Apr 2022 11:43:15 +0200 Subject: [PATCH] feat: Iterate over a directory of banks Wwise actually provides a directory that may contain multiple sound banks, rather than just the path to a single file. --- Cargo.lock | 7 +++++ Cargo.toml | 1 + src/main.rs | 74 ++++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 67 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fe2d0e0..f70568e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "anyhow" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" + [[package]] name = "bitflags" version = "1.3.2" @@ -96,5 +102,6 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" name = "wwise_fix" version = "0.1.0" dependencies = [ + "anyhow", "tempfile", ] diff --git a/Cargo.toml b/Cargo.toml index 860cf12..ca5f7b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +anyhow = "1.0.57" tempfile = "3.3.0" diff --git a/src/main.rs b/src/main.rs index 607c6b9..e7e353b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,14 @@ +use anyhow::bail; +use anyhow::Context; +use anyhow::Result; use tempfile::NamedTempFile; +use std::env; +use std::ffi::{OsStr, OsString}; +use std::fs; use std::fs::File; use std::io::{self, Read, Seek, SeekFrom, Write}; -use std::{env, fs}; +use std::path::Path; // Offset within the bank file to the version number within the BKHD section. // TODO: Check if this may change. @@ -10,38 +16,76 @@ const OFFSET_VERSION_NUMBER: u64 = 52; // Retrieved by philipdestroyer by inspecting the game's sound banks in memory at runtime. const BANK_VERSION: [u8; 4] = [0x28, 0xbc, 0x11, 0x92]; -fn main() { - let path = env::args().nth(1).expect("Path to sound bank required"); - +fn fix_file

(path: P) -> Result<()> +where + P: AsRef, +{ let tmp_path = { - let mut f = File::open(&path).expect("failed to open sound bank file"); - let mut tmp = NamedTempFile::new().expect("failed to open temporary file"); + let mut f = File::open(&path).with_context(|| "failed to open sound bank file")?; + let mut tmp = NamedTempFile::new().with_context(|| "failed to open temporary file")?; // Copy everything until the version number io::copy( &mut std::io::Read::by_ref(&mut f).take(OFFSET_VERSION_NUMBER), &mut tmp, ) - .expect("failed to copy to tempfile"); + .with_context(|| "failed to copy to tempfile")?; // Write the hard coded version number - tmp.write(&BANK_VERSION).expect("failed to write version number"); + tmp.write(&BANK_VERSION) + .with_context(|| "failed to write version number")?; // Copy the rest of the file f.seek(SeekFrom::Start(OFFSET_VERSION_NUMBER + 4)) - .expect("failed to skip to rest of content"); - io::copy(&mut f, &mut tmp).expect("failed to copy to tempfile"); + .with_context(|| "failed to skip to rest of content")?; + io::copy(&mut f, &mut tmp).with_context(|| "failed to copy to tempfile")?; tmp.into_temp_path() }; if let Err(err) = fs::rename(&tmp_path, &path) { - let tmp_path = tmp_path.keep().expect("failed to persist temporary file"); - eprintln!( - "failed to rename temporary file to override the sound bank {}.\n\ - Please manually copy the file from {} to {}", + let tmp_path = tmp_path + .keep() + .with_context(|| "failed to persist temporary file")?; + bail!( + "failed to rename temporary file to override the sound bank: {}!\n\ + Please manually copy the file from {} to {}.", err, tmp_path.display(), - path + path.as_ref().display() ); } + + Ok(()) +} + +fn main() -> Result<()> { + let dir = env::args() + .nth(1) + .expect("Please specify a directory containing .wwise_bank files"); + + let mut results = Vec::new(); + + for entry in fs::read_dir(dir)? { + let entry = entry?; + let path = entry.path(); + + if path.is_file() && path.extension().and_then(OsStr::to_str) == Some("wwise_bank") { + let res = fix_file(&path); + results.push((path, res)); + } + } + + for (path, res) in results.iter() { + let name = path + .file_name() + .map(OsStr::to_os_string) + .unwrap_or_else(|| OsString::from("..")); + + match res { + Ok(_) => println!("Fixed: {}", name.to_string_lossy()), + Err(err) => eprintln!("Failed: {}. Error: {}", name.to_string_lossy(), err), + } + } + + Ok(()) }