sdk: Add dictionary group for texture categories

This commit is contained in:
Lucas Schwiderski 2023-10-06 10:01:18 +02:00
parent 126d3c743d
commit 0e2f0d4409
Signed by: lucas
GPG key ID: AA12679AAA6DF4D8
4 changed files with 30 additions and 17 deletions

View file

@ -3,7 +3,7 @@ use std::path::PathBuf;
use std::process::Command;
use std::sync::Arc;
use crate::murmur::{Dictionary, HashGroup, IdString64, Murmur32, Murmur64};
use crate::murmur::{Dictionary, HashGroup, IdString32, IdString64, Murmur32, Murmur64};
#[derive(Clone)]
pub struct CmdLine {
@ -87,17 +87,17 @@ impl Context {
}
}
pub fn lookup_hash_short<M>(&self, hash: M, group: HashGroup) -> String
pub fn lookup_hash_short<M>(&self, hash: M, group: HashGroup) -> IdString32
where
M: Into<Murmur32>,
{
let hash = hash.into();
if let Some(s) = self.lookup.lookup_short(hash, group) {
tracing::debug!(%hash, string = s, "Murmur32 lookup successful");
s.to_owned()
s.to_string().into()
} else {
tracing::debug!(%hash, "Murmur32 lookup failed");
format!("{hash:08X}")
hash.into()
}
}
}

View file

@ -5,7 +5,7 @@ use color_eyre::{Report, Result};
use crate::binary::sync::ReadExt;
use crate::bundle::file::{BundleFileVariant, UserFile};
use crate::murmur::HashGroup;
use crate::murmur::{HashGroup, IdString32};
#[derive(Copy, Clone, PartialEq, Eq, Hash, serde::Serialize)]
#[serde(untagged)]
@ -26,7 +26,7 @@ impl Language {
}
#[derive(serde::Serialize)]
pub struct Strings(HashMap<String, HashMap<Language, String>>);
pub struct Strings(HashMap<IdString32, HashMap<Language, String>>);
fn read_string<R>(r: R) -> Result<String>
where
@ -42,7 +42,7 @@ where
impl Strings {
#[tracing::instrument(skip_all, fields(languages = variants.len()))]
pub fn from_variants(ctx: &crate::Context, variants: &Vec<BundleFileVariant>) -> Result<Self> {
let mut map: HashMap<String, HashMap<Language, String>> = HashMap::new();
let mut map: HashMap<IdString32, HashMap<Language, String>> = HashMap::new();
for (i, variant) in variants.iter().enumerate() {
let _span = tracing::trace_span!("variant {}", i);

View file

@ -11,7 +11,7 @@ use tokio::fs;
use crate::binary::sync::{ReadExt, WriteExt};
use crate::bundle::file::UserFile;
use crate::murmur::{IdString32, IdString64};
use crate::murmur::{HashGroup, IdString32, IdString64};
use crate::{BundleFile, BundleFileType, BundleFileVariant};
bitflags! {
@ -86,8 +86,12 @@ struct Texture {
}
impl Texture {
#[tracing::instrument(skip(r, stream_r))]
fn from_binary(mut r: impl Read + Seek, mut stream_r: Option<impl Read>) -> Result<Self> {
#[tracing::instrument(skip(ctx, r, stream_r))]
fn from_binary(
ctx: &crate::Context,
mut r: impl Read + Seek,
mut stream_r: Option<impl Read>,
) -> Result<Self> {
// Looking at the executable in IDA, there is one other valid value: `2`.
// If this ever comes up in the game data, I'll have to reverse engineer the
// (de)compression algorithm through IDA.
@ -187,7 +191,7 @@ impl Texture {
None
};
let category = r.read_u32().map(IdString32::from)?;
let category = ctx.lookup_hash_short(r.read_u32()?, HashGroup::TextureCategory);
Ok(Self {
category,
@ -265,8 +269,9 @@ struct TextureDefinitionOutput {
category: String,
}
#[tracing::instrument(skip(data), fields(buf_len = data.as_ref().len()))]
#[tracing::instrument(skip(ctx, data), fields(buf_len = data.as_ref().len()))]
pub(crate) async fn decompile_data(
ctx: &crate::Context,
name: String,
data: impl AsRef<[u8]>,
stream_file_name: Option<PathBuf>,
@ -281,7 +286,7 @@ pub(crate) async fn decompile_data(
None
};
let texture = Texture::from_binary(&mut r, stream_r.as_mut())?;
let texture = Texture::from_binary(ctx, &mut r, stream_r.as_mut())?;
let files = texture.to_user_files(name);
Ok(files)
}
@ -300,7 +305,7 @@ pub(crate) async fn decompile(
None => PathBuf::from("bundle").join(name),
});
return decompile_data(name, variant.data(), stream_file_name).await;
return decompile_data(ctx, name, variant.data(), stream_file_name).await;
}
let Some(file_name) = variant.data_file_name() else {
@ -323,7 +328,7 @@ pub(crate) async fn decompile(
"Provide a game directory in the config file or make sure the `data` directory is next to the provided bundle."
})?;
decompile_data(name, &data, None).await
decompile_data(ctx, name, &data, None).await
}
#[tracing::instrument(skip(sjson, name), fields(sjson_len = sjson.as_ref().len(), name = %name.display()))]

View file

@ -12,12 +12,19 @@ pub enum HashGroup {
Filename,
Filetype,
Strings,
TextureCategory,
Other,
}
impl HashGroup {
pub fn all() -> [Self; 3] {
[Self::Filename, Self::Filetype, Self::Other]
pub fn all() -> [Self; 5] {
[
Self::Filename,
Self::Filetype,
Self::Strings,
Self::TextureCategory,
Self::Other,
]
}
}
@ -27,6 +34,7 @@ impl std::fmt::Display for HashGroup {
HashGroup::Filename => write!(f, "filename"),
HashGroup::Filetype => write!(f, "filetype"),
HashGroup::Strings => write!(f, "strings"),
HashGroup::TextureCategory => write!(f, "texture-category"),
HashGroup::Other => write!(f, "other"),
}
}