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.
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.
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.
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.
Fatshark has a few weird string fields, where they provide a length
field, but then sometimes write a shorter, NUL-terminated string into
that same field and adding padding up to the "advertised" length.
To properly read those strings, we can't rely on just the length field
anymore, but need to check for a NUL, too.
Ideally, I would prefer the usual split per logging level, but that
seems to be somewhat complex with `tracing_subscriber`, so this simply
switches everything over to stderr, so that some of the experiment
commands can write results to stdout.
lint/clippy Checking for common mistakes and opportunities for code improvement
build/msvc Build for the target platform: msvc
build/linux Build for the target platform: linux
For most of the game files, we don't know the actual name, only the hash
of that name. To still allow building bundles that contain files with
that name (e.g. to override a game file with a custom one), there needs
to be a way to tell DTMT to name a file such that its hash is the same
as the one in the game.
The initial idea was to just expect the file name on disk to be the
hash, but that wouldn't allow for arbitrary folder structures anymore.
So instead, there is now a new, optional setting in `dtmt.cfg`, where
the modder can map a file path to an override name.
lint/clippy Checking for common mistakes and opportunities for code improvement
build/msvc Build for the target platform: msvc
build/linux Build for the target platform: linux
* master:
dtmm: Fix writing Nexus image to disk
dtmm: Fix importing from `.mod` file
ci: Combine Dockerfiles into multi-stage build
ci: Rework MSVC image building
ci: Fix base pipeline
ci: Improve caching setup for image building
ci: Create build artifacts for commits on master
ci: Fix undefined variable
Add changelog entry
dtmm: Fetch mod image from Nexus
lint/clippy Checking for common mistakes and opportunities for code improvement
build/msvc Build for the target platform: msvc
build/linux Build for the target platform: linux
When importing an archive file downloaded from Nexus, the file name does
include a version field. But, presumably for compatibility reasons,
Nexus replaces special characters with `-`, so that this field doesn't
match common schemes like `1.0.0`.
So instead we use the also included update timestamp to find the
corresponding file info from Nexus and use the version data from that.
Closes#131.
Non-bundled mods come without a `dtmt.cfg`, and therefore without a
version number. But we need a version number at import to compare to
for the Nexus update check.