Skip to content

HoldMyBeer-gg/rustydemon

Repository files navigation

Rusty Demon - Cross-Platform CASC Explorer

A fast, cross-platform explorer for CASC (Content-Addressable Storage Container) archives, written entirely in Rust.

Rusty Demon is the first tool of any kind, proprietary or open source, that can read the Steam-distribution CASC static container format used by Diablo IV. Neither CascLib nor the original TACTLib implementation handles the full Steam D4 layout (key-layout flags, zlib VFS roots, meta.dat / payload.dat distinction); rustydemon does. See Steam D4 Support below.

For personal and educational use only.

CI Rust Edition License Platforms Steam D4


UI Preview

rustydemon previewing a WoW M2 model

Three-panel layout: archive tree (left) · search results (centre) · file details with live 3D preview (right). Shown here previewing a WoW M2 character model.


Preview Plugins

About modal D4 .tex texture
About modal D4 texture preview
D4 .pow skill data WoW .m2 model
D4 power preview WoW M2 model preview

Features

  • Regedit-style global search - searches every entry in the archive manifest, not just the currently selected folder
  • File tree navigation - browse archives by folder with expand/collapse, Expand All / Collapse All
  • Pluggable preview panel - formats register themselves through a PreviewPlugin trait. Built-in plugins cover BLP textures (WoW), .tex BC textures (D4), .pow skill data (D4), .vid Bink Video 2 movies (D4), and a generic UTF-8 text fallback. Add a format by dropping one file into rustydemon/src/preview/.
  • Pluggable export buttons - each preview plugin can register its own export actions (e.g. Export As PNG for textures, Export As BK2 for movies). Raw export is always available as a fallback.
  • Deep search - optionally search inside container files via a parallel ContentSearcher plug-in interface (.pow D4 skill data supported out of the box).
  • Glob path search - search bar and CLI accept literal paths or glob patterns (*.wmo, textures/*.tex, **/cinematics/*.vid); matching is case-insensitive and **/ is auto-prepended for convenience.
  • Headless CLI exporter (rustydemon-cli) - batch-extract files from a local CASC install without launching the GUI. Supports path/glob/FDID selection, parallel workers, dry-run, flatten, and overwrite. See CLI below.
  • Auto product detection - reads .build.info so you never need to know internal product codes (fenris, wow, etc.)
  • Cross-platform - Windows · macOS · Linux · Steam Deck (touch-ready via egui)
  • Steam Diablo IV support - first-ever reader for the Steam-distribution static container format (no .build.info, no encoding file, location encoded directly in each EKey)
  • Diablo II: Resurrected support - reads D2R 3.1.2's TVFS-based layout, including the multi-storage Data/data + Data/ecache split and archive-style .index files, with an optional CDN fallback fetcher (behind the cdn cargo feature).

Steam D4 Support

Rusty Demon is, to the best of our knowledge, the first publicly-available tool, free, paid, or otherwise, that can open the Steam distribution of Diablo IV's CASC archives. The Steam build ships with a fundamentally different storage layout than the Battle.net client:

Battle.net D4 Steam D4
Manifest entry point .build.info Data/.build.config
Archive files data.NNN {chunk}/0x{archive}-{meta,payload}.dat
Location lookup *.idx index files Bits inside each EKey
Encoding table encoding file (none -CKey ≡ EKey)
VFS root wrapper BLTE Raw zlib (espec = z)
Data header 30-byte prefix None

Rustydemon auto-detects which layout is in use and picks the right backend. Point File → Open Game Directory… at either C:\Program Files (x86)\Diablo IV (Battle.net) or …/steamapps/common/Diablo IV (Steam) and it just works.

Neither CascLib nor the TACTLib StaticContainerHandler implements the full Steam D4 format: TACTLib's handler hard-codes a single data.{chunk}.{archive} path layout used only by Overwatch, ignores the 4th (flags) value in key-layout-*, and doesn't handle the zlib-compressed VFS root. Rustydemon's static_container module in rustydemon-lib is a clean-room implementation that verified all of these against a real Steam installation.


Quick Start

Prerequisites

Platform Requirement
All Rust stable toolchain (1.80+)
Linux / Steam Deck libgtk-3-dev (or equivalent) - see below
Windows / macOS Nothing extra; eframe bundles everything

Linux / Steam Deck system deps:

# Debian / Ubuntu / Kali
sudo apt install libgtk-3-dev libxcb-render0-dev libxcb-shape0-dev \
                 libxcb-xfixes0-dev libxkbcommon-dev libssl-dev

# Arch / Steam Deck
# Note: Just try to run rustydemon first. SteamOS probably has these already.
# If not, you'll have to `sudo steamos-readonly disable`, install, then 
# `sudo steamos-readonly enable` immediately after the install is done.
sudo pacman -S gtk3 libxcb xkbcommon openssl

# Fedora
sudo dnf install gtk3-devel libxcb-devel libxkbcommon-devel openssl-devel

Steam Deck (Desktop Mode): SteamOS has very limited space outside /home, so install Homebrew, rustup, and gcc to your SD card rather than the internal drive. Once Rust is available, install the Arch deps above via pacman and build normally. Game files live at /home/deck/.steam/steam/steamapps/common/<Game> - point File → Open Game Directory… there.

Build & Run

git clone https://github.com/jabberwock/rustydemon.git
cd rustydemon
cargo run --release -p rustydemon

The first build downloads and compiles all dependencies (~3–5 minutes). Subsequent builds are incremental and much faster.


Usage Guide

1 -Open a game directory

File → Open Game Directory… and select your game's installation root (the folder that contains .build.info for Battle.net installs, or Data/.build.config for Steam installs).

The product UID is detected automatically:

Game Detected as
World of Warcraft wow
Diablo IV fenris
Diablo II: Resurrected osi
Diablo III d3
Hearthstone hs
Heroes of the Storm hero
StarCraft II s2
Overwatch pro

2 -Load a listfile (optional but recommended)

Without a listfile, files are shown by hash only. With one, the full virtual path is resolved and the tree is populated.

File → Load Listfile… and pick a community listfile (CSV or plain text). A maintained listfile can be downloaded from the wowdev community listfile project.

3 -Search

Type a filename fragment in the search bar and press Enter or click Search. Results are drawn from the entire root manifest, every locale and content variant, so nothing is hidden behind an unexpanded folder.

The query can be a literal substring or a glob: *.wmo, textures/*.tex, **/cinematics/*.vid. Matching is case-insensitive, and **/ is auto-prepended unless the pattern already anchors at / or **/.

4 -Deep search (optional)

Check Deep search and click 🔍 Find All (Deep Search) to also search inside supported container files:

Format What is indexed
.pow D4 skill/power definitions, SF names, damage formulas
(more formats via the plug-in interface)

5 -Preview and export

Click any file in the tree or search results to load it into the preview panel.

  • BLP textures render inline
  • All other files show a hex dump of the first 256 bytes
  • Export As PNG saves a decoded BLP to disk via a native dialog

CLI

rustydemon-cli is a headless batch exporter for scripting and server-side extraction. The GUI binary remains the way to browse interactively.

cargo run --release -p rustydemon-cli -- \
    --archive "/home/deck/.steam/steam/steamapps/common/Diablo IV" \
    --path    "base/meta/Sound" \
    --output  ./out

Key flags:

Flag Purpose
-a, --archive <DIR> Game install root (Battle.net or Steam)
-p, --path <PATH> Literal folder, literal file, or glob (*.wmo, **/cinematics/*.vid)
--fdid <N> Extract a single WoW file by FileDataID (no listfile needed)
-l, --listfile <FILE> Listfile for WoW (required to resolve paths)
-o, --output <DIR> Host directory; created if missing
--flat Drop files into --output instead of mirroring virtual dirs
--dry-run Print matches without writing
--overwrite Replace existing files (default: skip)
-j, --parallel <N> Worker thread count (defaults to CPU cores)
-q, --quiet Suppress progress bar

D4 and other TVFS-based archives self-describe, so --listfile is not needed there. For WoW, pass either --listfile or --fdid.


Workspace Layout

rustydemon/
├── rustydemon-blp2/   BLP0/1/2 texture decoder (palette, DXT1/3/5, ARGB, JPEG)
├── rustydemon-lib/    CASC library (config, index, encoding, BLTE, root, search)
├── rustydemon-cli/    Headless batch exporter (clap + rayon)
└── rustydemon/        egui/eframe GUI application

Contributing

  1. Fork and create a feature branch
  2. cargo test --workspace must pass
  3. cargo fmt --all and cargo clippy --workspace -- -D warnings must be clean
  4. Open a PR - CI runs fmt, clippy, tests, and a RustSec security audit automatically

Listfile improvements and new deep-search plug-ins are especially welcome.


Acknowledgments

Built on the shoulders of the CASC reverse-engineering community:

  • CascLib by Ladislav Zezula - the C library for reading CASC archives and our primary reference for BLTE, encoding, root manifests, MNDX/MARR, and more.
  • CASC Explorer by the WoW-Tools team - the original .NET GUI for browsing CASC archives. Rusty Demon's UI takes cues from CASC Explorer's design.
  • TACTLib by the Overtools team - a C# CASC implementation whose TVFS and static-container work was a useful reference.
  • SereniaBLPLib by Xalcon - BLP texture parsing and DXT decompression in rustydemon-blp2 are derived from this MIT-licensed C# library (see rustydemon-blp2/CREDITS).
  • wowdev.wiki and the datamining community - for documenting CASC/TACT formats and maintaining the community listfiles.

License

Source licensed under AGPL-3.0 with the Commons Clause - free to read, build, and use for personal and educational purposes.

Commercial distribution (e.g. Steam store builds) is reserved to the maintainers under a separate proprietary license. See COMMERCIAL.md for the dual-licensing details and the contributor license grant that applies to pull requests.

Sponsor this project

 

Packages

 
 
 

Contributors