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:
parent
3273070cef
commit
d3918c1382
2 changed files with 44 additions and 39 deletions
43
src/exd.rs
43
src/exd.rs
|
@ -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,
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Add table
Reference in a new issue