1
Fork 0
mirror of https://github.com/redstrate/Physis.git synced 2025-04-20 03:37:47 +00:00

Actually use row ids in EXD files

I'm an idiot, these row ids are here for a reason and are important for actually
reading Excel sheets. The API has changed to a read_row() function that takes a
row id, and I'll improve it before release.
This commit is contained in:
Joshua Goins 2025-03-15 21:40:34 -04:00
parent 3273070cef
commit d3918c1382
2 changed files with 44 additions and 39 deletions

View file

@ -4,6 +4,7 @@
use std::io::{Cursor, Seek, SeekFrom}; use std::io::{Cursor, Seek, SeekFrom};
use binrw::binrw; use binrw::binrw;
use binrw::helpers::until_eof;
use binrw::{BinRead, Endian}; use binrw::{BinRead, Endian};
use crate::ByteSpan; use crate::ByteSpan;
@ -46,8 +47,8 @@ pub struct EXD {
#[br(count = header.index_size / core::mem::size_of::<ExcelDataOffset>() as u32)] #[br(count = header.index_size / core::mem::size_of::<ExcelDataOffset>() as u32)]
data_offsets: Vec<ExcelDataOffset>, data_offsets: Vec<ExcelDataOffset>,
#[brw(ignore)] #[br(seek_before = SeekFrom::Start(0), parse_with = until_eof)]
pub rows: Vec<ExcelRow>, data: Vec<u8>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -65,18 +66,21 @@ pub enum ColumnData {
UInt64(u64), UInt64(u64),
} }
#[derive(Debug)]
pub struct ExcelRow { pub struct ExcelRow {
pub data: Vec<ColumnData>, pub data: Vec<ColumnData>,
} }
impl EXD { impl EXD {
pub fn from_existing(exh: &EXH, buffer: ByteSpan) -> Option<EXD> { pub fn from_existing(buffer: ByteSpan) -> Option<EXD> {
let mut cursor = Cursor::new(buffer); EXD::read(&mut Cursor::new(&buffer)).ok()
let mut exd = EXD::read(&mut cursor).ok()?; }
for i in 0..exh.header.row_count { pub fn read_row(&self, exh: &EXH, id: u32) -> Option<Vec<ExcelRow>> {
for offset in &exd.data_offsets { let mut cursor = Cursor::new(&self.data);
if offset.row_id == i {
for offset in &self.data_offsets {
if offset.row_id == id {
cursor.seek(SeekFrom::Start(offset.offset.into())).ok()?; cursor.seek(SeekFrom::Start(offset.offset.into())).ok()?;
let row_header = ExcelDataRowHeader::read(&mut cursor).ok()?; let row_header = ExcelDataRowHeader::read(&mut cursor).ok()?;
@ -93,37 +97,38 @@ impl EXD {
.seek(SeekFrom::Start((row_offset + column.offset as u32).into())) .seek(SeekFrom::Start((row_offset + column.offset as u32).into()))
.ok()?; .ok()?;
subrow.data.push( subrow
Self::read_column(&mut cursor, exh, row_offset, column).unwrap(), .data
); .push(Self::read_column(&mut cursor, exh, row_offset, column).unwrap());
} }
Some(subrow) Some(subrow)
}; };
if row_header.row_count > 1 { return if row_header.row_count > 1 {
let mut rows = Vec::new();
for i in 0..row_header.row_count { for i in 0..row_header.row_count {
let subrow_offset = let subrow_offset =
header_offset + (i * exh.header.data_offset + 2 * (i + 1)) as u32; header_offset + (i * exh.header.data_offset + 2 * (i + 1)) as u32;
exd.rows.push(read_row(subrow_offset).unwrap()); rows.push(read_row(subrow_offset).unwrap());
} }
Some(rows)
} else { } else {
exd.rows.push(read_row(header_offset).unwrap()); Some(vec![read_row(header_offset).unwrap()])
} };
}
} }
} }
Some(exd) None
} }
fn read_data_raw<Z: BinRead<Args<'static> = ()>>(cursor: &mut Cursor<ByteSpan>) -> Option<Z> { fn read_data_raw<Z: BinRead<Args<'static> = ()>>(cursor: &mut Cursor<&Vec<u8>>) -> Option<Z> {
Z::read_options(cursor, Endian::Big, ()).ok() Z::read_options(cursor, Endian::Big, ()).ok()
} }
fn read_column( fn read_column(
cursor: &mut Cursor<ByteSpan>, cursor: &mut Cursor<&Vec<u8>>,
exh: &EXH, exh: &EXH,
row_offset: u32, row_offset: u32,
column: &ExcelColumnDefinition, column: &ExcelColumnDefinition,

View file

@ -291,7 +291,7 @@ impl GameData {
let exd_file = self.extract(&exd_path)?; let exd_file = self.extract(&exd_path)?;
EXD::from_existing(exh, &exd_file) EXD::from_existing(&exd_file)
} }
/// Applies the patch to game data and returns any errors it encounters. This function will not update the version in the GameData struct. /// Applies the patch to game data and returns any errors it encounters. This function will not update the version in the GameData struct.