Compare commits

..

13 commits

Author SHA1 Message Date
805fe53914
Only use texture files for texture-meta command
All checks were successful
build/linux Build for the target platform: linux
lint/clippy Checking for common mistakes and opportunities for code improvement
build/msvc Build for the target platform: msvc
2025-04-22 22:54:51 +02:00
6bb938fa97
Use macro to generate file type enum and impls
Due to the large amount of variants, and the different kind of values
connected to each variant (hash, extension name) being scattered
across the various `impl` blocks, the file became rather convoluted.

While I don't generally like the indirection of macros or meta
programming, it's not that bad with Rust, thanks to Rust Analyzer being
able to attach diagnostics to the source inside the macro definition,
and the ability to generate the macro's output for validation.

Therefore, the new macro allows putting all data used for this enum
definition into a single block.
2025-04-22 22:54:50 +02:00
40b0411330
sdk: Remove unused function 2025-04-22 22:54:49 +02:00
ba1b3c4323
dtmt: Fix file injection
I ended up wrapping the raw data in a `BundleFile` twice.
I also made '--compile' the default, as it should be much less often
that raw data needs to be inserted. Even files that are essentially raw
binary blobs, like `.wwise_event`, still have some custom fields that
need to be accounted for.
2025-04-22 22:54:48 +02:00
bb86584262
Add cmdline to tracing output
Can come in handy when other people report problems and show the error
message or full log, but not the command line.

Setting that span to `level = "error"` ensures that it won't be disabled
by level filters.
2025-04-22 22:54:47 +02:00
51055040c0
Refactor code for file injection 2025-04-22 22:54:46 +02:00
c137cfb90d
Implement more texture formats
The second compression method found in the game's code seems to be Zlib,
but it doesn't seem to be used in the game files. What does get used is
a compression type of `0`, which appears to be uncompressed data.

For DDS formats, all the ones that are currently used by in the game
files can be emitted as is. Though for some of them, other tools might
not be able to display them.
2025-04-22 22:54:45 +02:00
634fc310ee
sdk: Implement decompiling streamed mipmaps
For now, we only extract the largest mipmap.
2025-04-22 22:48:34 +02:00
aeed53bf88
Reverse DDSImage::load
Decompiling the game binary shows a rather elaborate algorithm to load
DDS images from binary. Though comparing it to Microsoft's documentation
on DDS, most of it seems to be pretty standard handling.

However, we don't actually need all of it. The part about calculating
pitch and reading blocks only accesses a subset of the `ImageFormat`
struct, so we can strip our implementation to just that.
2025-04-22 22:40:21 +02:00
5e19d5cb34
sdk: Add decompiled SJSON texture file
In addition to the actual image file, also write a `.texture` engine
file.
2025-04-22 22:40:20 +02:00
6926dabbab
sdk: Add dictionary group for texture categories 2025-04-22 22:40:18 +02:00
66d1e375b9
dtmt: Add option to compile file when injecting 2025-04-22 22:38:30 +02:00
3cb6687855
feat(sdk): Implement partial texture decompilation 2025-04-22 22:38:26 +02:00
5 changed files with 83 additions and 111 deletions

View file

@ -3,7 +3,8 @@
"extends": [
"config:recommended",
":combinePatchMinorReleases",
":enableVulnerabilityAlerts"
":enableVulnerabilityAlerts",
":rebaseStalePrs"
],
"prConcurrentLimit": 10,
"branchPrefix": "renovate/",

168
Cargo.lock generated
View file

@ -233,7 +233,7 @@ version = "0.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f"
dependencies = [
"bitflags 2.9.1",
"bitflags 2.9.0",
"cexpr",
"clang-sys",
"itertools",
@ -253,7 +253,7 @@ version = "0.71.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3"
dependencies = [
"bitflags 2.9.1",
"bitflags 2.9.0",
"cexpr",
"clang-sys",
"itertools",
@ -275,9 +275,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.9.1"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
[[package]]
name = "bitmaps"
@ -426,9 +426,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.39"
version = "4.5.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f"
checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071"
dependencies = [
"clap_builder",
"clap_derive",
@ -436,9 +436,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.39"
version = "4.5.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51"
checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2"
dependencies = [
"anstream",
"anstyle",
@ -686,6 +686,12 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "crypto-common"
version = "0.1.6"
@ -698,9 +704,9 @@ dependencies = [
[[package]]
name = "csv-async"
version = "1.3.1"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "888dbb0f640d2c4c04e50f933885c7e9c95995d93cec90aba8735b4c610f26f1"
checksum = "d37fe5b0d07f4a8260ce1e9a81413e88f459af0f2dfc55c15e96868a2f99c0f0"
dependencies = [
"cfg-if",
"csv-core",
@ -911,7 +917,7 @@ dependencies = [
"ansi-parser",
"async-recursion",
"bincode",
"bitflags 2.9.1",
"bitflags 2.9.0",
"clap",
"color-eyre",
"colors-transform",
@ -1112,14 +1118,13 @@ dependencies = [
[[package]]
name = "flate2"
version = "1.1.1"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
checksum = "9c0596c1eac1f9e04ed902702e9878208b336edc9d6fddc8a48387349bab3666"
dependencies = [
"crc32fast",
"libz-rs-sys",
"libz-sys",
"miniz_oxide 0.8.8",
"miniz_oxide 0.8.0",
]
[[package]]
@ -1743,28 +1748,22 @@ dependencies = [
[[package]]
name = "hyper-util"
version = "0.1.13"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8"
checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2"
dependencies = [
"base64 0.22.1",
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"http",
"http-body",
"hyper",
"ipnet",
"libc",
"percent-encoding",
"pin-project-lite",
"socket2",
"system-configuration",
"tokio",
"tower-service",
"tracing",
"windows-registry",
]
[[package]]
@ -1957,7 +1956,7 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3"
dependencies = [
"bitflags 2.9.1",
"bitflags 2.9.0",
"inotify-sys",
"libc",
]
@ -2021,16 +2020,6 @@ version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]]
name = "iri-string"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2"
dependencies = [
"memchr",
"serde",
]
[[package]]
name = "is-docker"
version = "0.2.0"
@ -2185,7 +2174,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
dependencies = [
"cfg-if",
"windows-targets 0.48.5",
"windows-targets 0.52.6",
]
[[package]]
@ -2194,25 +2183,16 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags 2.9.1",
"bitflags 2.9.0",
"libc",
"redox_syscall",
]
[[package]]
name = "libz-rs-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6489ca9bd760fe9642d7644e827b0c9add07df89857b0416ee15c1cc1a3b8c5a"
dependencies = [
"zlib-rs",
]
[[package]]
name = "libz-sys"
version = "1.1.21"
version = "1.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df9b68e50e6e0b26f672573834882eb57759f6db9b3be2ea3c35c91188bb4eaa"
checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9"
dependencies = [
"cc",
"pkg-config",
@ -2334,9 +2314,9 @@ dependencies = [
[[package]]
name = "minijinja"
version = "2.10.2"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd72e8b4e42274540edabec853f607c015c73436159b06c39c7af85a20433155"
checksum = "98642a6dfca91122779a307b77cd07a4aa951fbe32232aaf5bad9febc66be754"
dependencies = [
"serde",
]
@ -2359,9 +2339,9 @@ dependencies = [
[[package]]
name = "miniz_oxide"
version = "0.8.8"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
dependencies = [
"adler2",
]
@ -2477,7 +2457,7 @@ version = "8.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943"
dependencies = [
"bitflags 2.9.1",
"bitflags 2.9.0",
"filetime",
"fsevent-sys",
"inotify",
@ -2591,7 +2571,7 @@ version = "0.10.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1"
dependencies = [
"bitflags 2.9.1",
"bitflags 2.9.0",
"cfg-if",
"foreign-types",
"libc",
@ -3029,7 +3009,7 @@ version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
dependencies = [
"bitflags 2.9.1",
"bitflags 2.9.0",
]
[[package]]
@ -3089,14 +3069,15 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "reqwest"
version = "0.12.18"
version = "0.12.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e98ff6b0dbbe4d5a37318f433d4fc82babd21631f194d370409ceb2e40b2f0b5"
checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"
dependencies = [
"base64 0.22.1",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
@ -3113,20 +3094,21 @@ dependencies = [
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls-pki-types",
"rustls-pemfile",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"system-configuration",
"tokio",
"tokio-native-tls",
"tower",
"tower-http",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"windows-registry",
]
[[package]]
@ -3219,7 +3201,7 @@ version = "0.38.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
dependencies = [
"bitflags 2.9.1",
"bitflags 2.9.0",
"errno",
"libc",
"linux-raw-sys 0.4.14",
@ -3232,7 +3214,7 @@ version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf"
dependencies = [
"bitflags 2.9.1",
"bitflags 2.9.0",
"errno",
"libc",
"linux-raw-sys 0.9.4",
@ -3253,14 +3235,21 @@ dependencies = [
]
[[package]]
name = "rustls-pki-types"
version = "1.12.0"
name = "rustls-pemfile"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425"
dependencies = [
"zeroize",
"base64 0.22.1",
"rustls-pki-types",
]
[[package]]
name = "rustls-pki-types"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0"
[[package]]
name = "rustls-webpki"
version = "0.102.6"
@ -3359,7 +3348,7 @@ name = "sdk"
version = "0.3.0"
dependencies = [
"async-recursion",
"bitflags 2.9.1",
"bitflags 2.9.0",
"byteorder",
"color-eyre",
"csv-async",
@ -3390,7 +3379,7 @@ version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags 2.9.1",
"bitflags 2.9.0",
"core-foundation",
"core-foundation-sys",
"libc",
@ -3730,11 +3719,11 @@ dependencies = [
[[package]]
name = "system-configuration"
version = "0.6.1"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
checksum = "658bc6ee10a9b4fcf576e9b0819d95ec16f4d2c02d39fd83ac1c8789785c4a42"
dependencies = [
"bitflags 2.9.1",
"bitflags 2.9.0",
"core-foundation",
"system-configuration-sys",
]
@ -3770,9 +3759,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
[[package]]
name = "tempfile"
version = "3.20.0"
version = "3.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
dependencies = [
"fastrand",
"getrandom 0.3.2",
@ -3910,9 +3899,9 @@ dependencies = [
[[package]]
name = "tokio"
version = "1.45.1"
version = "1.44.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48"
dependencies = [
"backtrace",
"bytes",
@ -4051,24 +4040,6 @@ dependencies = [
"tower-service",
]
[[package]]
name = "tower-http"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fdb0c213ca27a9f57ab69ddb290fd80d970922355b83ae380b395d3986b8a2e"
dependencies = [
"bitflags 2.9.1",
"bytes",
"futures-util",
"http",
"http-body",
"iri-string",
"pin-project-lite",
"tower",
"tower-layer",
"tower-service",
]
[[package]]
name = "tower-layer"
version = "0.3.3"
@ -4621,7 +4592,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
"windows-sys 0.48.0",
"windows-sys 0.59.0",
]
[[package]]
@ -4929,7 +4900,7 @@ version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags 2.9.1",
"bitflags 2.9.0",
]
[[package]]
@ -5043,13 +5014,14 @@ dependencies = [
[[package]]
name = "zip"
version = "3.0.0"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12598812502ed0105f607f941c386f43d441e00148fce9dec3ca5ffb0bde9308"
checksum = "1dcb24d0152526ae49b9b96c1dcf71850ca1e0b882e4e28ed898a93c41334744"
dependencies = [
"arbitrary",
"bzip2",
"crc32fast",
"crossbeam-utils",
"flate2",
"indexmap",
"memchr",
@ -5058,12 +5030,6 @@ dependencies = [
"zstd",
]
[[package]]
name = "zlib-rs"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "868b928d7949e09af2f6086dfc1e01936064cc7a819253bce650d4e2a2d63ba8"
[[package]]
name = "zopfli"
version = "0.8.1"

View file

@ -60,7 +60,7 @@ tracing = { version = "0.1.37", features = ["async-await"] }
tracing-error = "0.2.0"
tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
usvg = "0.25.0"
zip = { version = "3.0.0", default-features = false, features = ["deflate", "bzip2", "zstd", "time"] }
zip = { version = "2.1.3", default-features = false, features = ["deflate", "bzip2", "zstd", "time"] }
[profile.dev.package.backtrace]
opt-level = 3

View file

@ -5,6 +5,7 @@ use clap::{value_parser, Arg, ArgAction, ArgMatches, Command};
use color_eyre::eyre::{self, Context, OptionExt, Result};
use color_eyre::Help;
use path_slash::PathBufExt as _;
use sdk::filetype::texture;
use sdk::murmur::IdString64;
use sdk::{Bundle, BundleFile, BundleFileType};
use tokio::fs;
@ -110,15 +111,20 @@ async fn compile_file(
let file_data = fs::read(&path)
.await
.wrap_err_with(|| format!("Failed to read file '{}'", path.display()))?;
let _sjson = String::from_utf8(file_data)
let sjson = String::from_utf8(file_data)
.wrap_err_with(|| format!("Invalid UTF8 data in '{}'", path.display()))?;
let _root = path.parent().ok_or_eyre("File path has no parent")?;
let root = path.parent().ok_or_eyre("File path has no parent")?;
eyre::bail!(
match file_type {
BundleFileType::Texture => texture::compile(name.into(), sjson, root)
.await
.wrap_err_with(|| format!("Failed to compile file as texture: {}", path.display())),
_ => eyre::bail!(
"Compilation for type '{}' is not implemented, yet",
file_type
)
),
}
}
#[tracing::instrument(

View file

@ -1,5 +1,4 @@
use color_eyre::eyre;
use color_eyre::Result;
use color_eyre::{eyre, Result};
use serde::Serialize;
use crate::murmur::Murmur64;