mirror of
https://github.com/redstrate/Physis.git
synced 2025-04-20 03:37:47 +00:00
Add DatHeader so we can read gear sets without libxivdat
This is limited to just that one dat type for now, but we can expand it as we add more parsers.
This commit is contained in:
parent
ed7618a5fa
commit
b61c3383b3
8 changed files with 131 additions and 71 deletions
Binary file not shown.
26
src/dat.rs
Normal file
26
src/dat.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
use binrw::binrw;
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
#[brw(little)]
|
||||
pub enum DatFileType {
|
||||
/// GEARSET.DAT
|
||||
#[brw(magic = 0x006d0005u32)]
|
||||
Gearset,
|
||||
}
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
#[brw(little)]
|
||||
pub struct DatHeader {
|
||||
pub file_type: DatFileType,
|
||||
pub max_size: u32,
|
||||
#[brw(pad_after = 4)] // empty bytes
|
||||
pub content_size: u32,
|
||||
#[br(temp)]
|
||||
#[bw(calc = 0xFF)]
|
||||
end_of_header: u8,
|
||||
}
|
|
@ -8,7 +8,6 @@ use std::path::PathBuf;
|
|||
|
||||
use tracing::{debug, warn};
|
||||
|
||||
use crate::sqpack::{IndexEntry, SqPackData, SqPackIndex};
|
||||
use crate::ByteBuffer;
|
||||
use crate::common::{Language, Platform, read_version};
|
||||
use crate::exd::EXD;
|
||||
|
@ -16,6 +15,7 @@ use crate::exh::EXH;
|
|||
use crate::exl::EXL;
|
||||
use crate::patch::{PatchError, ZiPatch};
|
||||
use crate::repository::{Category, Repository, string_to_category};
|
||||
use crate::sqpack::{IndexEntry, SqPackData, SqPackIndex};
|
||||
|
||||
/// Framework for operating on game data.
|
||||
pub struct GameData {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
use crate::ByteBuffer;
|
||||
use crate::dat::DatHeader;
|
||||
use crate::equipment::Slot;
|
||||
use binrw::NullString;
|
||||
use binrw::binrw;
|
||||
|
@ -9,6 +10,7 @@ use binrw::{BinRead, BinWrite};
|
|||
use std::collections::HashMap;
|
||||
use std::io::BufWriter;
|
||||
use std::io::Cursor;
|
||||
use std::io::Read;
|
||||
|
||||
// FIXME: unclear what this is
|
||||
const UNKNOWN_FLAG: u32 = 1_000_000;
|
||||
|
@ -223,8 +225,16 @@ const GEARSET_KEY: u8 = 0x73;
|
|||
impl GearSets {
|
||||
/// Parses existing gearsets data.
|
||||
pub fn from_existing(buffer: &[u8]) -> Option<GearSets> {
|
||||
let mut cursor = Cursor::new(buffer);
|
||||
|
||||
let header = DatHeader::read(&mut cursor).ok()?;
|
||||
|
||||
let mut buffer = vec![0; header.content_size as usize - 1];
|
||||
cursor.read_exact(&mut buffer).ok()?;
|
||||
|
||||
let decoded = buffer.iter().map(|x| *x ^ GEARSET_KEY).collect::<Vec<_>>();
|
||||
let mut cursor = Cursor::new(decoded);
|
||||
|
||||
GearSets::read(&mut cursor).ok()
|
||||
}
|
||||
|
||||
|
@ -232,15 +242,33 @@ impl GearSets {
|
|||
pub fn write_to_buffer(&self) -> Option<ByteBuffer> {
|
||||
let mut buffer = ByteBuffer::new();
|
||||
|
||||
// header
|
||||
{
|
||||
let cursor = Cursor::new(&mut buffer);
|
||||
let mut writer = BufWriter::new(cursor);
|
||||
let mut cursor = Cursor::new(&mut buffer);
|
||||
|
||||
self.write_le(&mut writer).ok()?;
|
||||
let header = DatHeader {
|
||||
file_type: crate::dat::DatFileType::Gearset,
|
||||
max_size: 45205,
|
||||
content_size: 45205,
|
||||
};
|
||||
header.write_le(&mut cursor).ok()?
|
||||
}
|
||||
|
||||
let encoded = buffer.iter().map(|x| *x ^ GEARSET_KEY).collect::<Vec<_>>();
|
||||
Some(encoded)
|
||||
// buffer contents encoded
|
||||
{
|
||||
let mut cursor = Cursor::new(ByteBuffer::new());
|
||||
self.write_le(&mut cursor).ok()?;
|
||||
|
||||
buffer.extend_from_slice(
|
||||
&cursor
|
||||
.into_inner()
|
||||
.iter()
|
||||
.map(|x| *x ^ GEARSET_KEY)
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
|
||||
Some(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -152,3 +152,6 @@ pub mod existing_dirs;
|
|||
pub mod patchlist;
|
||||
|
||||
mod bcn;
|
||||
|
||||
/// Reading the binary .dat files in the user folder (e.g. GEARSET.dat)
|
||||
pub mod dat;
|
||||
|
|
|
@ -46,17 +46,17 @@ struct TextureLodBlock {
|
|||
}
|
||||
|
||||
pub trait AnyNumberType<'a>:
|
||||
BinRead<Args<'a> = ()> + BinWrite<Args<'a> = ()> + std::ops::AddAssign + Copy + Default + 'static
|
||||
BinRead<Args<'a> = ()> + BinWrite<Args<'a> = ()> + std::ops::AddAssign + Copy + Default + 'static
|
||||
{
|
||||
}
|
||||
|
||||
impl<'a, T> AnyNumberType<'a> for T where
|
||||
T: BinRead<Args<'a> = ()>
|
||||
+ BinWrite<Args<'a> = ()>
|
||||
+ std::ops::AddAssign
|
||||
+ Copy
|
||||
+ Default
|
||||
+ 'static
|
||||
T: BinRead<Args<'a> = ()>
|
||||
+ BinWrite<Args<'a> = ()>
|
||||
+ std::ops::AddAssign
|
||||
+ Copy
|
||||
+ Default
|
||||
+ 'static
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ mod db;
|
|||
pub use db::SqPackDatabase;
|
||||
|
||||
mod index;
|
||||
pub use index::{SqPackIndex, IndexEntry};
|
||||
pub use index::{IndexEntry, SqPackIndex};
|
||||
|
||||
/// The type of this SqPack file.
|
||||
#[binrw]
|
||||
|
@ -57,7 +57,10 @@ pub(crate) struct SqPackHeader {
|
|||
sha1_hash: [u8; 20],
|
||||
}
|
||||
|
||||
pub(crate) fn read_data_block<T: Read + Seek>(mut buf: T, starting_position: u64) -> Option<Vec<u8>> {
|
||||
pub(crate) fn read_data_block<T: Read + Seek>(
|
||||
mut buf: T,
|
||||
starting_position: u64,
|
||||
) -> Option<Vec<u8>> {
|
||||
buf.seek(SeekFrom::Start(starting_position)).ok()?;
|
||||
|
||||
let block_header = BlockHeader::read(&mut buf).unwrap();
|
||||
|
|
Loading…
Add table
Reference in a new issue