You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7.4 KiB
7.4 KiB
PyStorm - Python Bindings for StormLib
A comprehensive Python wrapper for StormLib, enabling Python developers to work with MPQ (MoPaQ) archives used by Blizzard Entertainment games.
Project Structure
pystorm/
├── pystorm/ # Main package
│ ├── __init__.py # Package initialization and exports
│ └── stormlib.py # Core bindings using ctypes
├── examples/ # Usage examples
│ ├── basic_operations.py # Basic MPQ operations
│ ├── extract_all.py # Extract all files from archive
│ ├── create_archive.py # Create archive from directory
│ └── list_files.py # List archive contents
├── README.md # User documentation
├── LICENSE # MIT License
├── setup.py # Setup script
├── pyproject.toml # Modern Python packaging config
├── MANIFEST.in # Package manifest
├── install.sh # Installation helper script
└── .gitignore # Git ignore rules
Features
Archive Operations
- ✅ Open existing MPQ archives
- ✅ Create new MPQ archives (v1-v4)
- ✅ Close and flush archives
- ✅ Compact archives
- ✅ Verify archive integrity
File Operations
- ✅ Read files from archives
- ✅ Extract files to disk
- ✅ Add files to archives
- ✅ Remove files from archives
- ✅ Rename files within archives
- ✅ Check file existence
- ✅ Search files with wildcards
Compression Support
- ✅ Huffman compression
- ✅ ZLIB compression
- ✅ PKWARE compression
- ✅ BZIP2 compression
- ✅ LZMA compression
- ✅ ADPCM compression
- ✅ Sparse compression
Installation
Prerequisites
- Python 3.7+
- StormLib C library
Quick Install (Linux/macOS)
# Clone the repository
git clone https://github.com/enne2/pystorm.git
cd pystorm
# Run the installation script (builds StormLib if needed)
chmod +x install.sh
./install.sh
Manual Installation
Step 1: Install StormLib
Linux:
git clone https://github.com/ladislav-zezula/StormLib.git
cd StormLib
mkdir build && cd build
cmake ..
make
sudo make install
sudo ldconfig
macOS:
brew install cmake
git clone https://github.com/ladislav-zezula/StormLib.git
cd StormLib
mkdir build && cd build
cmake ..
make
sudo make install
Windows:
- Download pre-built binaries from StormLib releases
- Or build using Visual Studio
Step 2: Install PyStorm
# From PyPI (when published)
pip install pystorm
# From source
git clone https://github.com/enne2/pystorm.git
cd pystorm
pip install -e .
Usage
Quick Start
from pystorm import MPQArchive
# Open and read a file
with MPQArchive("game.mpq") as archive:
with archive.open_file("data/config.txt") as mpq_file:
content = mpq_file.read()
print(content.decode('utf-8'))
Complete Examples
Check the examples/ directory for complete working examples:
- basic_operations.py - Demonstrates all basic operations
- extract_all.py - Extract all files from an archive
- create_archive.py - Create an archive from a directory
- list_files.py - List and analyze archive contents
Run an example:
cd examples
python3 basic_operations.py
API Overview
High-Level API (Recommended)
from pystorm import MPQArchive, MPQ_CREATE_ARCHIVE_V2, MPQ_FILE_COMPRESS
# Create/open archive
with MPQArchive("archive.mpq", flags=MPQ_CREATE_ARCHIVE_V2) as archive:
# Add file
archive.add_file("local.txt", "archived.txt", flags=MPQ_FILE_COMPRESS)
# Check file
if archive.has_file("archived.txt"):
# Read file
with archive.open_file("archived.txt") as f:
data = f.read()
# Extract file
archive.extract_file("archived.txt", "output.txt")
# List files
files = archive.find_files("*.txt")
# Remove file
archive.remove_file("old.txt")
# Rename file
archive.rename_file("old.txt", "new.txt")
# Flush changes
archive.flush()
Low-Level API
from pystorm import (
SFileOpenArchive, SFileCloseArchive,
SFileOpenFileEx, SFileReadFile, SFileCloseFile
)
# Direct ctypes interface
handle = SFileOpenArchive("archive.mpq")
# ... use handle ...
SFileCloseArchive(handle)
Development
Setting Up Development Environment
# Clone repository
git clone https://github.com/enne2/pystorm.git
cd pystorm
# Create virtual environment
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode
pip install -e ".[dev]"
Running Tests
pytest tests/
Code Formatting
black pystorm/
flake8 pystorm/
Architecture
PyStorm uses ctypes to interface with the StormLib C library:
- stormlib.py: Defines ctypes function signatures and provides low-level wrappers
- init.py: Exports high-level classes (
MPQArchive,MPQFile) - High-level classes: Provide Pythonic interface with context managers
Design Decisions
- ctypes over CFFI: Simpler setup, no compilation needed
- Context managers: Automatic resource cleanup
- Dual API: Low-level for power users, high-level for convenience
- Error handling: Exceptions for failures, not return codes
Platform Support
| Platform | Status | Notes |
|---|---|---|
| Linux | ✅ Tested | Ubuntu 20.04+, Debian, Fedora |
| macOS | ✅ Tested | macOS 10.15+ |
| Windows | ⚠️ Untested | Should work with StormLib.dll |
Compatibility
- Python: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12
- StormLib: Latest version from GitHub
- MPQ Format: v1, v2, v3, v4
Performance
PyStorm adds minimal overhead over native StormLib:
- Direct ctypes calls (no additional layers)
- Zero-copy where possible
- Efficient memory management
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
Known Issues
- Windows support is untested (help wanted!)
- Some advanced StormLib features not yet wrapped
- Archive creation requires careful error handling
Roadmap
- Complete Windows testing
- Add async/await support
- Wrap remaining StormLib functions
- Add comprehensive test suite
- Performance benchmarks
- Binary wheels for PyPI
License
MIT License - see LICENSE file for details.
This project is a wrapper for StormLib, which is also MIT licensed.
Credits
- StormLib: Ladislav Zezula - Original C library
- PyStorm: Matteo Benedetto - Python bindings
Links
Support
- GitHub Issues: Report bugs or request features
- Documentation: See README.md and examples/
- StormLib Issues: StormLib specific issues
Made with ❤️ by the Python community for game developers and modders