Miscellaneous changes #266

Merged
lucas merged 49 commits from feat/misc into master 2025-07-02 16:25:44 +02:00
2 changed files with 38 additions and 15 deletions
Showing only changes of commit 2c51ab1fcc - Show all commits

View file

@ -44,10 +44,10 @@ impl<T: FromBinary> FromBinary for Vec<T> {
pub mod sync { pub mod sync {
use std::ffi::CStr; use std::ffi::CStr;
use std::io::{self, Read, Seek, SeekFrom}; use std::io::{self, Read, Seek, SeekFrom, Write};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use color_eyre::eyre::WrapErr; use color_eyre::eyre::{self, WrapErr};
use color_eyre::{Help, Report, Result, SectionExt}; use color_eyre::{Help, Report, Result, SectionExt};
macro_rules! make_read { macro_rules! make_read {
@ -123,7 +123,7 @@ pub mod sync {
}; };
} }
pub trait ReadExt: ReadBytesExt + Seek { pub trait ReadExt: Read + Seek {
fn read_u8(&mut self) -> io::Result<u8> { fn read_u8(&mut self) -> io::Result<u8> {
ReadBytesExt::read_u8(self) ReadBytesExt::read_u8(self)
} }
@ -131,7 +131,6 @@ pub mod sync {
make_read!(read_u32, read_u32_le, u32); make_read!(read_u32, read_u32_le, u32);
make_read!(read_u64, read_u64_le, u64); make_read!(read_u64, read_u64_le, u64);
make_skip!(skip_u8, read_u8, u8);
make_skip!(skip_u32, read_u32, u32); make_skip!(skip_u32, read_u32, u32);
// Implementation based on https://en.wikipedia.com/wiki/LEB128 // Implementation based on https://en.wikipedia.com/wiki/LEB128
@ -181,9 +180,17 @@ pub mod sync {
res res
} }
} }
fn read_bool(&mut self) -> Result<bool> {
match ReadExt::read_u8(self)? {
0 => Ok(false),
1 => Ok(true),
v => eyre::bail!("Invalid value for boolean '{}'", v),
}
}
} }
pub trait WriteExt: WriteBytesExt + Seek { pub trait WriteExt: Write + Seek {
fn write_u8(&mut self, val: u8) -> io::Result<()> { fn write_u8(&mut self, val: u8) -> io::Result<()> {
WriteBytesExt::write_u8(self, val) WriteBytesExt::write_u8(self, val)
} }
@ -191,6 +198,10 @@ pub mod sync {
make_write!(write_u32, write_u32_le, u32); make_write!(write_u32, write_u32_le, u32);
make_write!(write_u64, write_u64_le, u64); make_write!(write_u64, write_u64_le, u64);
fn write_bool(&mut self, val: bool) -> io::Result<()> {
WriteBytesExt::write_u8(self, if val { 1 } else { 0 })
}
fn write_padding(&mut self) -> io::Result<usize> { fn write_padding(&mut self) -> io::Result<usize> {
let pos = self.stream_position()?; let pos = self.stream_position()?;
let size = 16 - (pos % 16) as usize; let size = 16 - (pos % 16) as usize;
@ -207,8 +218,8 @@ pub mod sync {
} }
} }
impl<R: ReadBytesExt + Seek + ?Sized> ReadExt for R {} impl<R: Read + Seek + ?Sized> ReadExt for R {}
impl<W: WriteBytesExt + Seek + ?Sized> WriteExt for W {} impl<W: Write + Seek + ?Sized> WriteExt for W {}
pub(crate) fn _read_up_to<R>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> pub(crate) fn _read_up_to<R>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize>
where where

View file

@ -15,17 +15,18 @@ use super::filetype::BundleFileType;
#[derive(Debug)] #[derive(Debug)]
struct BundleFileHeader { struct BundleFileHeader {
variant: u32, variant: u32,
unknown_1: u8, external: bool,
size: usize, size: usize,
unknown_1: u8,
len_data_file_name: usize, len_data_file_name: usize,
} }
#[derive(Clone, Debug)] #[derive(Clone)]
pub struct BundleFileVariant { pub struct BundleFileVariant {
property: u32, property: u32,
data: Vec<u8>, data: Vec<u8>,
data_file_name: Option<String>, data_file_name: Option<String>,
// Seems to be related to whether there is a data path. external: bool,
unknown_1: u8, unknown_1: u8,
} }
@ -39,6 +40,7 @@ impl BundleFileVariant {
property: 0, property: 0,
data: Vec::new(), data: Vec::new(),
data_file_name: None, data_file_name: None,
external: false,
unknown_1: 0, unknown_1: 0,
} }
} }
@ -63,21 +65,30 @@ impl BundleFileVariant {
self.data_file_name.as_ref() self.data_file_name.as_ref()
} }
pub fn external(&self) -> bool {
self.external
}
pub fn unknown_1(&self) -> u8 {
self.unknown_1
}
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
fn read_header<R>(r: &mut R) -> Result<BundleFileHeader> fn read_header<R>(r: &mut R) -> Result<BundleFileHeader>
where where
R: Read + Seek, R: Read + Seek,
{ {
let variant = r.read_u32()?; let variant = r.read_u32()?;
let unknown_1 = r.read_u8()?; let external = r.read_bool()?;
let size = r.read_u32()? as usize; let size = r.read_u32()? as usize;
r.skip_u8(1)?; let unknown_1 = r.read_u8()?;
let len_data_file_name = r.read_u32()? as usize; let len_data_file_name = r.read_u32()? as usize;
Ok(BundleFileHeader { Ok(BundleFileHeader {
size, size,
unknown_1, external,
variant, variant,
unknown_1,
len_data_file_name, len_data_file_name,
}) })
} }
@ -88,7 +99,7 @@ impl BundleFileVariant {
W: Write + Seek, W: Write + Seek,
{ {
w.write_u32(self.property)?; w.write_u32(self.property)?;
w.write_u8(self.unknown_1)?; w.write_bool(self.external)?;
let len_data_file_name = self.data_file_name.as_ref().map(|s| s.len()).unwrap_or(0); let len_data_file_name = self.data_file_name.as_ref().map(|s| s.len()).unwrap_or(0);
@ -216,6 +227,7 @@ impl BundleFile {
property: header.variant, property: header.variant,
data, data,
data_file_name, data_file_name,
external: header.external,
unknown_1: header.unknown_1, unknown_1: header.unknown_1,
}; };
@ -243,7 +255,7 @@ impl BundleFile {
for variant in self.variants.iter() { for variant in self.variants.iter() {
w.write_u32(variant.property())?; w.write_u32(variant.property())?;
w.write_u8(variant.unknown_1)?; w.write_bool(variant.external)?;
let len_data_file_name = variant.data_file_name().map(|s| s.len()).unwrap_or(0); let len_data_file_name = variant.data_file_name().map(|s| s.len()).unwrap_or(0);