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

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

  1. Python 3.7+
  2. 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:

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:

  1. basic_operations.py - Demonstrates all basic operations
  2. extract_all.py - Extract all files from an archive
  3. create_archive.py - Create an archive from a directory
  4. list_files.py - List and analyze archive contents

Run an example:

cd examples
python3 basic_operations.py

API Overview

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:

  1. stormlib.py: Defines ctypes function signatures and provides low-level wrappers
  2. init.py: Exports high-level classes (MPQArchive, MPQFile)
  3. 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:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. 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

Support


Made with by the Python community for game developers and modders