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::process::Command;
use std::sync::Arc; use std::sync::Arc;
use crate::murmur::{Dictionary, HashGroup, IdString64, Murmur32, Murmur64}; use crate::murmur::{Dictionary, HashGroup, IdString32, IdString64, Murmur32, Murmur64};
#[derive(Clone)] #[derive(Clone)]
pub struct CmdLine { 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 where
M: Into<Murmur32>, M: Into<Murmur32>,
{ {
let hash = hash.into(); let hash = hash.into();
if let Some(s) = self.lookup.lookup_short(hash, group) { if let Some(s) = self.lookup.lookup_short(hash, group) {
tracing::debug!(%hash, string = s, "Murmur32 lookup successful"); tracing::debug!(%hash, string = s, "Murmur32 lookup successful");
s.to_owned() s.to_string().into()
} else { } else {
tracing::debug!(%hash, "Murmur32 lookup failed"); 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::binary::sync::ReadExt;
use crate::bundle::file::{BundleFileVariant, UserFile}; use crate::bundle::file::{BundleFileVariant, UserFile};
use crate::murmur::HashGroup; use crate::murmur::{HashGroup, IdString32};
#[derive(Copy, Clone, PartialEq, Eq, Hash, serde::Serialize)] #[derive(Copy, Clone, PartialEq, Eq, Hash, serde::Serialize)]
#[serde(untagged)] #[serde(untagged)]
@ -26,7 +26,7 @@ impl Language {
} }
#[derive(serde::Serialize)] #[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> fn read_string<R>(r: R) -> Result<String>
where where
@ -42,7 +42,7 @@ where
impl Strings { impl Strings {
#[tracing::instrument(skip_all, fields(languages = variants.len()))] #[tracing::instrument(skip_all, fields(languages = variants.len()))]
pub fn from_variants(ctx: &crate::Context, variants: &Vec<BundleFileVariant>) -> Result<Self> { 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() { for (i, variant) in variants.iter().enumerate() {
let _span = tracing::trace_span!("variant {}", i); let _span = tracing::trace_span!("variant {}", i);

View file

@ -11,7 +11,7 @@ use tokio::fs;
use crate::binary::sync::{ReadExt, WriteExt}; use crate::binary::sync::{ReadExt, WriteExt};
use crate::bundle::file::UserFile; use crate::bundle::file::UserFile;
use crate::murmur::{IdString32, IdString64}; use crate::murmur::{HashGroup, IdString32, IdString64};
use crate::{BundleFile, BundleFileType, BundleFileVariant}; use crate::{BundleFile, BundleFileType, BundleFileVariant};
bitflags! { bitflags! {
@ -86,8 +86,12 @@ struct Texture {
} }
impl Texture { impl Texture {
#[tracing::instrument(skip(r, stream_r))] #[tracing::instrument(skip(ctx, r, stream_r))]
fn from_binary(mut r: impl Read + Seek, mut stream_r: Option<impl Read>) -> Result<Self> { 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`. // 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 // If this ever comes up in the game data, I'll have to reverse engineer the
// (de)compression algorithm through IDA. // (de)compression algorithm through IDA.
@ -187,7 +191,7 @@ impl Texture {
None None
}; };
let category = r.read_u32().map(IdString32::from)?; let category = ctx.lookup_hash_short(r.read_u32()?, HashGroup::TextureCategory);
Ok(Self { Ok(Self {
category, category,
@ -265,8 +269,9 @@ struct TextureDefinitionOutput {
category: String, 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( pub(crate) async fn decompile_data(
ctx: &crate::Context,
name: String, name: String,
data: impl AsRef<[u8]>, data: impl AsRef<[u8]>,
stream_file_name: Option<PathBuf>, stream_file_name: Option<PathBuf>,
@ -281,7 +286,7 @@ pub(crate) async fn decompile_data(
None 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); let files = texture.to_user_files(name);
Ok(files) Ok(files)
} }
@ -300,7 +305,7 @@ pub(crate) async fn decompile(
None => PathBuf::from("bundle").join(name), 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 { 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." "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()))] #[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, Filename,
Filetype, Filetype,
Strings, Strings,
TextureCategory,
Other, Other,
} }
impl HashGroup { impl HashGroup {
pub fn all() -> [Self; 3] { pub fn all() -> [Self; 5] {
[Self::Filename, Self::Filetype, Self::Other] [
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::Filename => write!(f, "filename"),
HashGroup::Filetype => write!(f, "filetype"), HashGroup::Filetype => write!(f, "filetype"),
HashGroup::Strings => write!(f, "strings"), HashGroup::Strings => write!(f, "strings"),
HashGroup::TextureCategory => write!(f, "texture-category"),
HashGroup::Other => write!(f, "other"), HashGroup::Other => write!(f, "other"),
} }
} }