|
|
1 month ago | |
|---|---|---|
| .github | 1 month ago | |
| examples | 1 month ago | |
| pystorm | 1 month ago | |
| .gitignore | 1 month ago | |
| ASSET_EXTRACTION.md | 1 month ago | |
| BUILD.md | 1 month ago | |
| CONTRIBUTING.md | 1 month ago | |
| LICENSE | 1 month ago | |
| MANIFEST.in | 1 month ago | |
| MPQ_INSPECTOR_README.md | 1 month ago | |
| README.md | 1 month ago | |
| STARCRAFT_ASSETS.md | 1 month ago | |
| TESTING.md | 1 month ago | |
| VERIFICATION.md | 1 month ago | |
| build_stormlib.py | 1 month ago | |
| create_sample_mpq.py | 1 month ago | |
| debug_starcraft.py | 1 month ago | |
| demo_assets.py | 1 month ago | |
| example_game_engine.py | 1 month ago | |
| extract_starcraft_assets.py | 1 month ago | |
| install.sh | 1 month ago | |
| mpq_inspector.py | 1 month ago | |
| pyproject.toml | 1 month ago | |
| setup.py | 1 month ago | |
| test_gui.py | 1 month ago | |
README.md
PyStorm - Python Bindings for StormLib
PyStorm provides Python bindings for StormLib, a library for reading and writing MPQ (MoPaQ) archives used by Blizzard Entertainment games.
Features
- Read MPQ archives: Open and extract files from MPQ archives
- Write MPQ archives: Create new archives and add files
- Modify archives: Add, remove, and rename files in existing archives
- File search: Find files in archives using wildcards
- Archive verification: Verify archive integrity
- High-level and low-level APIs: Choose the interface that suits your needs
- Cross-platform: Works on Windows, Linux, and macOS
- 🎮 Asset Extraction: Tools for extracting and organizing game assets
- 🖼️ GUI Inspector: Visual MPQ archive browser
Quick Links
- 📦 Asset Extraction Guide - Extract & organize MPQ assets
- 📖 StarCraft Assets Guide - File format documentation
- 🖼️ MPQ Inspector - GUI tool documentation
- 🧪 Testing Guide - Testing and debugging
Requirements
- Python 3.7 or higher
- StormLib shared library (libstorm.so, StormLib.dll, or libstorm.dylib)
Installation
1. Install StormLib
First, you need to install the StormLib C library:
Linux/macOS
# Clone the repository
git clone https://github.com/ladislav-zezula/StormLib.git
cd StormLib
# Build and install
mkdir build && cd build
cmake ..
make
sudo make install
# Update library cache (Linux)
sudo ldconfig
Windows
Download pre-built binaries from the StormLib releases or build from source using Visual Studio.
2. Install PyStorm
pip install pystorm
Or install from source:
git clone https://github.com/enne2/pystorm.git
cd pystorm
pip install -e .
Quick Start
High-Level API (Recommended)
from pystorm import MPQArchive
# Open an existing archive
with MPQArchive("example.mpq") as archive:
# Check if a file exists
if archive.has_file("path/to/file.txt"):
# Read a file
with archive.open_file("path/to/file.txt") as mpq_file:
content = mpq_file.read()
print(content.decode('utf-8'))
# Extract a file
archive.extract_file("path/to/file.txt", "output.txt")
# List all files
files = archive.find_files("*")
for file_info in files:
print(f"{file_info['name']}: {file_info['size']} bytes")
# Create a new archive
with MPQArchive("new_archive.mpq", flags=MPQ_CREATE_ARCHIVE_V2) as archive:
# Add a file
archive.add_file("local_file.txt", "archived_name.txt")
# Remove a file
archive.remove_file("old_file.txt")
# Rename a file
archive.rename_file("old_name.txt", "new_name.txt")
# Flush changes to disk
archive.flush()
Low-Level API
from pystorm import (
SFileOpenArchive, SFileCloseArchive, SFileOpenFileEx,
SFileReadFile, SFileCloseFile, SFileGetFileSize,
SFILE_OPEN_FROM_MPQ
)
# Open archive
archive_handle = SFileOpenArchive("example.mpq")
try:
# Open file
file_handle = SFileOpenFileEx(archive_handle, "file.txt", SFILE_OPEN_FROM_MPQ)
try:
# Get file size
file_size = SFileGetFileSize(file_handle)
# Read file
data = SFileReadFile(file_handle, file_size)
print(data.decode('utf-8'))
finally:
SFileCloseFile(file_handle)
finally:
SFileCloseArchive(archive_handle)
API Reference
MPQArchive Class
High-level wrapper for MPQ archive operations.
Methods
__init__(path, flags=0, priority=0): Open an MPQ archiveclose(): Close the archivehas_file(filename): Check if a file existsopen_file(filename, search_scope=SFILE_OPEN_FROM_MPQ): Open a fileextract_file(filename, output_path, search_scope=SFILE_OPEN_FROM_MPQ): Extract a fileadd_file(local_path, archived_name, flags=MPQ_FILE_COMPRESS, compression=MPQ_COMPRESSION_ZLIB): Add a fileremove_file(filename, search_scope=SFILE_OPEN_FROM_MPQ): Remove a filerename_file(old_name, new_name): Rename a filefind_files(mask="*"): Find files matching a patternflush(): Flush changes to diskcompact(listfile=None): Compact the archiveverify(): Verify archive integrity
MPQFile Class
High-level wrapper for file operations within an MPQ archive.
Methods
__init__(archive, filename, search_scope=SFILE_OPEN_FROM_MPQ): Open a fileclose(): Close the fileget_size(): Get file sizeread(size=None): Read data from the fileseek(offset, whence=FILE_BEGIN): Seek to a position
Constants
Open Flags
MPQ_OPEN_NO_LISTFILE: Don't load the listfileMPQ_OPEN_NO_ATTRIBUTES: Don't load attributesMPQ_OPEN_READ_ONLY: Open in read-only mode
Create Flags
MPQ_CREATE_LISTFILE: Create with listfileMPQ_CREATE_ATTRIBUTES: Create with attributesMPQ_CREATE_ARCHIVE_V1: Create version 1 archive (max 4GB)MPQ_CREATE_ARCHIVE_V2: Create version 2 archiveMPQ_CREATE_ARCHIVE_V3: Create version 3 archiveMPQ_CREATE_ARCHIVE_V4: Create version 4 archive
File Flags
MPQ_FILE_COMPRESS: Compress the fileMPQ_FILE_ENCRYPTED: Encrypt the fileMPQ_FILE_FIX_KEY: Use fixed encryption keyMPQ_FILE_SINGLE_UNIT: Store as single unitMPQ_FILE_DELETE_MARKER: File is marked for deletionMPQ_FILE_SECTOR_CRC: File has sector CRCs
Compression Types
MPQ_COMPRESSION_HUFFMANN: Huffman compressionMPQ_COMPRESSION_ZLIB: ZLIB compressionMPQ_COMPRESSION_PKWARE: PKWARE compressionMPQ_COMPRESSION_BZIP2: BZIP2 compressionMPQ_COMPRESSION_SPARSE: Sparse compressionMPQ_COMPRESSION_ADPCM_MONO: ADPCM mono compressionMPQ_COMPRESSION_ADPCM_STEREO: ADPCM stereo compressionMPQ_COMPRESSION_LZMA: LZMA compression
Tools Included
🎮 Asset Extraction Tool
Extract and organize game assets for engine development:
python extract_starcraft_assets.py
Automatically categorizes files into:
audio/- Sound effects, musicgraphics/- Sprites, imagesvideo/- Cinematicsdata/- Game data tables- And more...
See ASSET_EXTRACTION.md for complete guide.
🖼️ MPQ Inspector (GUI)
Visual MPQ archive browser with tkinter:
python mpq_inspector.py
Features:
- Browse and open MPQ archives visually
- View file listings with compression details
- Extract individual files or entire archives
- Verify archive integrity
- File information viewer
See MPQ_INSPECTOR_README.md for full documentation.
📊 Asset Demo Tool
Explore and analyze extracted assets:
python demo_assets.py
Features:
- List assets by category
- Analyze audio/graphics files
- Search functionality
- Interactive menu
Examples
More examples can be found in the examples/ directory.
Extract All Files from an Archive
from pystorm import MPQArchive
from pathlib import Path
def extract_all(archive_path, output_dir):
output_dir = Path(output_dir)
output_dir.mkdir(parents=True, exist_ok=True)
with MPQArchive(archive_path) as archive:
files = archive.find_files("*")
for file_info in files:
filename = file_info['name']
output_path = output_dir / filename
output_path.parent.mkdir(parents=True, exist_ok=True)
try:
archive.extract_file(filename, str(output_path))
print(f"Extracted: {filename}")
except Exception as e:
print(f"Failed to extract {filename}: {e}")
extract_all("game.mpq", "extracted_files")
Create an Archive from a Directory
from pystorm import MPQArchive, MPQ_CREATE_ARCHIVE_V2, MPQ_FILE_COMPRESS
from pathlib import Path
def create_archive_from_dir(source_dir, archive_path):
source_dir = Path(source_dir)
with MPQArchive(archive_path, flags=MPQ_CREATE_ARCHIVE_V2) as archive:
for file_path in source_dir.rglob("*"):
if file_path.is_file():
# Get relative path for archived name
archived_name = str(file_path.relative_to(source_dir))
# Replace backslashes with forward slashes
archived_name = archived_name.replace("\\", "/")
archive.add_file(str(file_path), archived_name)
print(f"Added: {archived_name}")
archive.flush()
create_archive_from_dir("my_files", "output.mpq")
Verify Archive Integrity
from pystorm import MPQArchive
with MPQArchive("example.mpq") as archive:
result = archive.verify()
if result == 0:
print("Archive is valid!")
else:
print(f"Archive verification failed with code: {result}")
Troubleshooting
Library Not Found Error
If you get an error about not finding the StormLib library:
- Make sure StormLib is installed on your system
- Check that the library is in your system's library path
- On Linux, try running
sudo ldconfigafter installation - Alternatively, copy the library file to the
pystormpackage directory
Permission Errors
Some operations (like creating or modifying archives) require write permissions. Make sure you have the necessary permissions for the files and directories you're working with.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Credits
- StormLib: Created and maintained by Ladislav Zezula
- PyStorm: Python bindings by Matteo Benedetto