wow-mpq
A high-performance, safe Rust implementation of the MPQ (Mo'PaQ) archive format used by World of Warcraft and other Blizzard Entertainment games.
Status
Production Ready - Feature-complete MPQ implementation with 100% StormLib bidirectional compatibility
Overview
MPQ archives are used by World of Warcraft (versions 1.x through 5.x) to store game assets including models, textures, sounds, and data files. This crate provides a pure Rust implementation for reading, creating, and managing MPQ archives with comprehensive support for all format versions and features.
Features
- Complete Archive Reading - All MPQ versions (v1-v4) with full feature coverage
- Archive Creation - Build new archives with full control over format and compression
- Archive Modification - Add, remove, and rename files with automatic listfile/attributes updates
- Archive Rebuilding - Comprehensive rebuild with format upgrades and optimization
- All Compression Algorithms - Zlib, BZip2, LZMA, Sparse, ADPCM, PKWare, Huffman
- Full Cryptography - File encryption/decryption, signature verification and generation
- Patch Chain Support - Complete World of Warcraft patch archive management
- Binary Patch Files - PTCH format support with COPY and BSD0 (bsdiff40) patch types
- Advanced Tables - HET/BET tables for v3+ archives with optimal compression
- StormLib Compatibility - 100% bidirectional compatibility with the reference implementation
- High Performance - Efficient I/O, zero-copy where possible, comprehensive benchmarks
- Parallel Processing - Multi-threaded extraction and validation for better performance
Installation
Add to your Cargo.toml:
[]
= "0.3.0"
Or use cargo add:
Quick Start
use ;
// Read an existing archive
let mut archive = open?;
// List all files
for entry in archive.list?
// Extract a file
let data = archive.read_file?;
// Create a new archive
new
.add_file_data
.version
.build?;
// Modify an existing archive
let mut mutable = open?;
mutable.add_file_data?;
mutable.remove_file?;
mutable.rename_file?;
mutable.flush?; // Save all changes
Supported Versions
- Classic (1.12.1) - Full support including patch archives
- The Burning Crusade (2.4.3) - Full support with v2 features
- Wrath of the Lich King (3.3.5a) - Full support with LZMA compression
- Cataclysm (4.3.4) - Full support with HET/BET tables
- Mists of Pandaria (5.4.8) - Full support with v4 format
Advanced Features
Patch Chain Support
Handle World of Warcraft's patch archive system with automatic priority-based file resolution and binary patch application (PTCH format):
use PatchChain;
let mut chain = new;
chain.add_archive?; // Base priority
chain.add_archive?; // Patch priority
chain.add_archive?; // Higher priority
// Automatically gets the highest priority version
// If patch archives contain PTCH files, they are automatically applied
let data = chain.read_file?;
Patch File Support (Cataclysm+)
Starting with Cataclysm (4.x), WoW introduced binary patch files (PTCH format) in update archives. These files cannot be extracted directly - they must be applied to base files. This crate handles patch files automatically:
- COPY Patches - Simple file replacement
- BSD0 Patches - Binary diff using bsdiff40 algorithm
- Automatic Application - PatchChain detects and applies patches transparently
- MD5 Verification - Validates patch integrity before and after application
// Example: Cataclysm terrain file with patches
let mut chain = new;
chain.add_archive?;
chain.add_archive?;
chain.add_archive?;
// If Azeroth_30_30.adt exists as a patch file in updates,
// it will be automatically applied to the base file
let adt_data = chain.read_file?;
CLI Usage
The mpq extract command supports patch chains via the --patch flag:
# Extract files with patch chain
# Extract specific file from Cataclysm with patches
Archive Rebuilding
Optimize and upgrade archives with comprehensive rebuild options:
use ;
let options = new
.target_version // Upgrade to v4
.compression // Change compression
.remove_signatures // Strip signatures
.progress_callback;
rebuild_archive?;
Digital Signatures
Verify and generate archive signatures for integrity protection:
use ;
// Verify existing signatures
let archive = open?;
match archive.verify_signature?
// Generate new weak signature
let archive_data = read?;
let sig_info = new_weak;
let signature = generate_weak_signature?;
Debug Utilities
The crate includes debug utilities for analyzing MPQ archives (requires
debug-utils feature):
use ;
// Enable the feature in Cargo.toml:
// wow-mpq = { version = "0.3.0", features = ["debug-utils"] }
let mut archive = open?;
// Dump archive structure and metadata
dump_archive_structure?;
// Analyze compression methods used
analyze_compression_methods?;
// Dump table contents (hash table, block table)
dump_hash_table?;
dump_block_table?;
// Trace file extraction with detailed debugging
let config = ExtractionTraceConfig ;
trace_file_extraction?
// Create hex dumps of binary data
let data = archive.read_file?;
let hex_config = default;
println!;
Run the debug example to analyze any MPQ archive:
# Basic analysis
# Trace specific file extraction
# Show detailed table dumps
SHOW_TABLES=1
Performance
The crate includes comprehensive benchmarks showing excellent performance:
- Archive Creation: ~50-100 MB/s depending on compression
- File Extraction: ~200-500 MB/s for uncompressed files
- Hash Calculation: ~1-2 billion hashes/second
- Compression: Varies by algorithm (Zlib: ~50MB/s, LZMA: ~10MB/s)
Examples
The crate includes numerous examples demonstrating real-world usage:
create_archive- Basic archive creationpatch_chain_demo- Working with WoW patch archiveswotlk_patch_chain_demo- Complete WotLK patch handlingpatch_analysis- Analyze patch archive contentssignature_demo- Digital signature generation and verificationdebug_archive- Debug utilities for analyzing MPQ internals- And many more...
Run examples with:
Limitations
While achieving 100% StormLib compatibility for core functionality, the following performance and specialized features are not implemented:
- Memory-mapped I/O - Standard I/O only (sufficient for most use cases)
- Streaming API - No chunked reading for very large files
- Protected Archives - Copy-protected MPQ support (rarely used)
- Strong Signature Generation - Requires private key not publicly available
- Archive Compacting - Use rebuild instead for optimization
- Async I/O - Synchronous operations only
Compatibility Notes
Blizzard Archives
Blizzard's MPQ implementation has some quirks that this library handles gracefully:
- Attributes File Size: All official Blizzard MPQs have attributes files that are exactly 28 bytes larger than the specification. This library detects and handles this discrepancy automatically.
- Path Separators: MPQ archives use backslashes (
\) as path separators. While this library accepts forward slashes for convenience, they are automatically converted to backslashes internally.
License
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.