mirror of
https://github.com/redstrate/Physis.git
synced 2025-07-20 07:47:45 +00:00
Port the useful Excel API from SqPackResource to Resource
This commit is contained in:
parent
81fff744f2
commit
c2eb47cca0
3 changed files with 55 additions and 70 deletions
|
@ -2,7 +2,7 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
use physis::common::Platform;
|
use physis::common::Platform;
|
||||||
use physis::resource::SqPackResource;
|
use physis::resource::{Resource, SqPackResource};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
@ -24,7 +24,7 @@ fn main() {
|
||||||
let mut game_data = SqPackResource::from_existing(Platform::Win32, game_dir);
|
let mut game_data = SqPackResource::from_existing(Platform::Win32, game_dir);
|
||||||
|
|
||||||
// Extract said file:
|
// 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);
|
println!("File {} not found!", file_path);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub use sqpack::SqPackResource;
|
||||||
mod unpacked;
|
mod unpacked;
|
||||||
pub use unpacked::UnpackedResource;
|
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.
|
/// 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.
|
/// 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;
|
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)
|
||||||
|
}
|
||||||
|
|
|
@ -6,10 +6,7 @@ use std::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ByteBuffer,
|
ByteBuffer,
|
||||||
common::{Language, Platform, read_version},
|
common::{Platform, read_version},
|
||||||
exd::EXD,
|
|
||||||
exh::EXH,
|
|
||||||
exl::EXL,
|
|
||||||
patch::{PatchError, ZiPatch},
|
patch::{PatchError, ZiPatch},
|
||||||
repository::{Category, Repository, string_to_category},
|
repository::{Category, Repository, string_to_category},
|
||||||
sqpack::{IndexEntry, SqPackData, SqPackIndex},
|
sqpack::{IndexEntry, SqPackData, SqPackIndex},
|
||||||
|
@ -118,18 +115,6 @@ impl SqPackResource {
|
||||||
SqPackData::from_existing(dat_path.to_str()?)
|
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`.
|
/// Finds the offset inside of the DAT file for `path`.
|
||||||
pub fn find_offset(&mut self, path: &str) -> Option<u64> {
|
pub fn find_offset(&mut self, path: &str) -> Option<u64> {
|
||||||
let slice = self.find_entry(path);
|
let slice = self.find_entry(path);
|
||||||
|
@ -188,57 +173,6 @@ impl SqPackResource {
|
||||||
Some(index_filenames)
|
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.
|
/// 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> {
|
pub fn apply_patch(&self, patch_path: &str) -> Result<(), PatchError> {
|
||||||
ZiPatch::apply(&self.game_directory, patch_path)
|
ZiPatch::apply(&self.game_directory, patch_path)
|
||||||
|
|
Loading…
Add table
Reference in a new issue