1
Fork 0
mirror of https://github.com/redstrate/Physis.git synced 2025-07-19 23:37:46 +00:00

Port the useful Excel API from SqPackResource to Resource

This commit is contained in:
Joshua Goins 2025-07-08 21:44:51 -04:00
parent 81fff744f2
commit c2eb47cca0
3 changed files with 55 additions and 70 deletions

View file

@ -2,7 +2,7 @@
// SPDX-License-Identifier: GPL-3.0-or-later
use physis::common::Platform;
use physis::resource::SqPackResource;
use physis::resource::{Resource, SqPackResource};
use std::env;
use std::fs::File;
use std::io::Write;
@ -24,7 +24,7 @@ fn main() {
let mut game_data = SqPackResource::from_existing(Platform::Win32, game_dir);
// Extract said file:
let Some(game_file) = game_data.extract(file_path) else {
let Some(game_file) = game_data.read(file_path) else {
println!("File {} not found!", file_path);
return;
};

View file

@ -7,7 +7,7 @@ pub use sqpack::SqPackResource;
mod unpacked;
pub use unpacked::UnpackedResource;
use crate::ByteBuffer;
use crate::{ByteBuffer, common::Language, exd::EXD, exh::EXH, exl::EXL};
/// Represents a source of files for reading.
/// This abstracts away some of the nitty-gritty of where files come from. These could be coming from a compressed archive like SqPack, unpacked files on disk, or even a network.
@ -46,3 +46,54 @@ pub trait Resource {
/// ```
fn exists(&mut self, path: &str) -> bool;
}
/// Read an excel sheet by name (e.g. "Achievement")
pub fn read_excel_sheet_header<T: Resource>(resource: &mut T, name: &str) -> Option<EXH> {
let root_exl_file = resource.read("exd/root.exl")?;
let root_exl = EXL::from_existing(&root_exl_file)?;
for (row, _) in root_exl.entries {
if row == name {
let new_filename = name.to_lowercase();
let path = format!("exd/{new_filename}.exh");
return EXH::from_existing(&resource.read(&path)?);
}
}
None
}
/// Returns all known sheet names listed in the root list
pub fn get_all_sheet_names<T: Resource>(resource: &mut T) -> Option<Vec<String>> {
let root_exl_file = resource.read("exd/root.exl")?;
let root_exl = EXL::from_existing(&root_exl_file)?;
let mut names = vec![];
for (row, _) in root_exl.entries {
names.push(row);
}
Some(names)
}
/// Read an excel sheet
pub fn read_excel_sheet<T: Resource>(
resource: &mut T,
name: &str,
exh: &EXH,
language: Language,
page: usize,
) -> Option<EXD> {
let exd_path = format!(
"exd/{}",
EXD::calculate_filename(name, language, &exh.pages[page])
);
let exd_file = resource.read(&exd_path)?;
EXD::from_existing(exh, &exd_file)
}

View file

@ -6,10 +6,7 @@ use std::{
use crate::{
ByteBuffer,
common::{Language, Platform, read_version},
exd::EXD,
exh::EXH,
exl::EXL,
common::{Platform, read_version},
patch::{PatchError, ZiPatch},
repository::{Category, Repository, string_to_category},
sqpack::{IndexEntry, SqPackData, SqPackIndex},
@ -118,18 +115,6 @@ impl SqPackResource {
SqPackData::from_existing(dat_path.to_str()?)
}
pub fn extract(&mut self, path: &str) -> Option<ByteBuffer> {
let slice = self.find_entry(path);
match slice {
Some((entry, chunk)) => {
let mut dat_file = self.get_dat_file(path, chunk, entry.data_file_id.into())?;
dat_file.read_from_offset(entry.offset)
}
None => None,
}
}
/// Finds the offset inside of the DAT file for `path`.
pub fn find_offset(&mut self, path: &str) -> Option<u64> {
let slice = self.find_entry(path);
@ -188,57 +173,6 @@ impl SqPackResource {
Some(index_filenames)
}
/// Read an excel sheet by name (e.g. "Achievement")
pub fn read_excel_sheet_header(&mut self, name: &str) -> Option<EXH> {
let root_exl_file = self.extract("exd/root.exl")?;
let root_exl = EXL::from_existing(&root_exl_file)?;
for (row, _) in root_exl.entries {
if row == name {
let new_filename = name.to_lowercase();
let path = format!("exd/{new_filename}.exh");
return EXH::from_existing(&self.extract(&path)?);
}
}
None
}
/// Returns all known sheet names listed in the root list
pub fn get_all_sheet_names(&mut self) -> Option<Vec<String>> {
let root_exl_file = self.extract("exd/root.exl")?;
let root_exl = EXL::from_existing(&root_exl_file)?;
let mut names = vec![];
for (row, _) in root_exl.entries {
names.push(row);
}
Some(names)
}
/// Read an excel sheet
pub fn read_excel_sheet(
&mut self,
name: &str,
exh: &EXH,
language: Language,
page: usize,
) -> Option<EXD> {
let exd_path = format!(
"exd/{}",
EXD::calculate_filename(name, language, &exh.pages[page])
);
let exd_file = self.extract(&exd_path)?;
EXD::from_existing(exh, &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.
pub fn apply_patch(&self, patch_path: &str) -> Result<(), PatchError> {
ZiPatch::apply(&self.game_directory, patch_path)