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.
This commit is contained in:
parent
fc788f85e2
commit
3215670ae0
3 changed files with 67 additions and 15 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -2,6 +2,12 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.57"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
|
@ -96,5 +102,6 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
name = "wwise_fix"
|
name = "wwise_fix"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,4 +6,5 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
anyhow = "1.0.57"
|
||||||
tempfile = "3.3.0"
|
tempfile = "3.3.0"
|
||||||
|
|
74
src/main.rs
74
src/main.rs
|
@ -1,8 +1,14 @@
|
||||||
|
use anyhow::bail;
|
||||||
|
use anyhow::Context;
|
||||||
|
use anyhow::Result;
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
use std::ffi::{OsStr, OsString};
|
||||||
|
use std::fs;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self, Read, Seek, SeekFrom, Write};
|
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.
|
// Offset within the bank file to the version number within the BKHD section.
|
||||||
// TODO: Check if this may change.
|
// 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.
|
// Retrieved by philipdestroyer by inspecting the game's sound banks in memory at runtime.
|
||||||
const BANK_VERSION: [u8; 4] = [0x28, 0xbc, 0x11, 0x92];
|
const BANK_VERSION: [u8; 4] = [0x28, 0xbc, 0x11, 0x92];
|
||||||
|
|
||||||
fn main() {
|
fn fix_file<P>(path: P) -> Result<()>
|
||||||
let path = env::args().nth(1).expect("Path to sound bank required");
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
let tmp_path = {
|
let tmp_path = {
|
||||||
let mut f = File::open(&path).expect("failed to open sound bank file");
|
let mut f = File::open(&path).with_context(|| "failed to open sound bank file")?;
|
||||||
let mut tmp = NamedTempFile::new().expect("failed to open temporary file");
|
let mut tmp = NamedTempFile::new().with_context(|| "failed to open temporary file")?;
|
||||||
|
|
||||||
// Copy everything until the version number
|
// Copy everything until the version number
|
||||||
io::copy(
|
io::copy(
|
||||||
&mut std::io::Read::by_ref(&mut f).take(OFFSET_VERSION_NUMBER),
|
&mut std::io::Read::by_ref(&mut f).take(OFFSET_VERSION_NUMBER),
|
||||||
&mut tmp,
|
&mut tmp,
|
||||||
)
|
)
|
||||||
.expect("failed to copy to tempfile");
|
.with_context(|| "failed to copy to tempfile")?;
|
||||||
|
|
||||||
// Write the hard coded version number
|
// 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
|
// Copy the rest of the file
|
||||||
f.seek(SeekFrom::Start(OFFSET_VERSION_NUMBER + 4))
|
f.seek(SeekFrom::Start(OFFSET_VERSION_NUMBER + 4))
|
||||||
.expect("failed to skip to rest of content");
|
.with_context(|| "failed to skip to rest of content")?;
|
||||||
io::copy(&mut f, &mut tmp).expect("failed to copy to tempfile");
|
io::copy(&mut f, &mut tmp).with_context(|| "failed to copy to tempfile")?;
|
||||||
tmp.into_temp_path()
|
tmp.into_temp_path()
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(err) = fs::rename(&tmp_path, &path) {
|
if let Err(err) = fs::rename(&tmp_path, &path) {
|
||||||
let tmp_path = tmp_path.keep().expect("failed to persist temporary file");
|
let tmp_path = tmp_path
|
||||||
eprintln!(
|
.keep()
|
||||||
"failed to rename temporary file to override the sound bank {}.\n\
|
.with_context(|| "failed to persist temporary file")?;
|
||||||
Please manually copy the file from {} to {}",
|
bail!(
|
||||||
|
"failed to rename temporary file to override the sound bank: {}!\n\
|
||||||
|
Please manually copy the file from {} to {}.",
|
||||||
err,
|
err,
|
||||||
tmp_path.display(),
|
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(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue