mpq

package module
v0.0.0-...-d3cdc0b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 30, 2023 License: Apache-2.0 Imports: 7 Imported by: 7

README

mpq

Build Status Go Reference Go Report Card codecov

Package mpq is a decoder/parser of Blizzard's MPQ archive file format.

This is not a full MPQ implementation. It is primarily intended to parse StarCraft II replay files (*.SC2Replay), but that is fully supported.

Usage

Usage is simple. Opening an MPQ archive file:

m, err := mpq.NewFromFile("myreplay.SC2Replay")
if err != nil {
	// Handle error
	return
}
defer m.Close()

Getting a named file from the archive:

// Access a file inside the MPQ archive.
// Usually there is a file called "(listfile)" containing the list of other files:
if data, err := m.FileByName("(listfile)"); err == nil {
	fmt.Println("Files inside archive:")
	fmt.Println(string(data))
} else {
	// handle error
}

If you already have the MPQ data in memory:

mpqdata := []byte{} // MPQ data in memory
m, err := mpq.New(bytes.NewReader(mpqdata)))

Information sources

Example projects using this

License

Open-sourced under the Apache License 2.0.

Documentation

Overview

Package mpq is a decoder/parser of Blizzard's MPQ archive file format.

This is not a full MPQ implementation. It is primarily intended to parse StarCraft II replay files (*.SC2Replay), but that is fully supported.

Usage

Usage is simple. Opening an MPQ archive file:

m, err := mpq.NewFromFile("myreplay.SC2Replay")
if err != nil {
	// Handle error
	return
}
defer m.Close()

Getting a named file from the archive:

// Access a file inside the MPQ archive.
// Usually there is a file called "(listfile)" containing the list of other files:
if data, err := m.FileByName("(listfile)"); err == nil {
	fmt.Println("Files inside archive:")
	fmt.Println(string(data))
} else {
	// handle error
}

If you already have the MPQ data in memory:

mpqdata := []byte{} // MPQ data in memory
m, err := mpq.New(bytes.NewReader(mpqdata)))

Information sources

The_MoPaQ_Archive_Format: http://wiki.devklog.net/index.php?title=The_MoPaQ_Archive_Format

MPQ on wikipedia: http://en.wikipedia.org/wiki/MPQ

Zezula MPQ description: http://www.zezula.net/mpq.html

Stormlib: https://github.com/ladislav-zezula/StormLib

Libmpq project: https://github.com/ge0rg/libmpq (old: https://libmpq.org/)

MPQ parser of the Scelight project: https://github.com/icza/scelight/tree/master/src-app-libs/hu/belicza/andras/mpq

Format of the "(attributes)" meta attributes file: https://github.com/stormlib/StormLib/blob/3a926f0228c68d7d91cf3946624d7859976440ec/src/SFileAttributes.cpp

int version: Version of the (attributes) file. Must be 100 (0x64)
int flags: flags telling what is contained in the "(attributes)"
    MPQ_ATTRIBUTE_CRC32         0x00000001  The "(attributes)" contains CRC32 for each file
    MPQ_ATTRIBUTE_FILETIME      0x00000002  The "(attributes)" contains file time for each file
    MPQ_ATTRIBUTE_MD5           0x00000004  The "(attributes)" contains MD5 for each file
    MPQ_ATTRIBUTE_PATCH_BIT     0x00000008  The "(attributes)" contains a patch bit for each file
    MPQ_ATTRIBUTE_ALL           0x0000000F  Summary mask

If has CRC32: int * BlockTableSize

If has FILETIME: long * BlockTableSize

If has MD5: MD5SIZE * BlockTableSize

If has PATCH_BIT: enough bytes to hold BlockTableSize bits

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidArchive indicates an invalid MPQ archive
	ErrInvalidArchive = errors.New("Invalid MPQ Archive")
)

Functions

func FileNameHash

func FileNameHash(name string) (h1, h2, h3 uint32)

FileNameHash returns different hashes of the file name, exactly the ones that are needed by MPQ.FileByHash().

Types

type MPQ

type MPQ struct {
	// contains filtered or unexported fields
}

MPQ describes an MPQ archive and provides access to its content.

func New

func New(input io.ReadSeeker) (*MPQ, error)

New returns a new MPQ using the specified io.ReadSeeker as the input source. This can be used to create an MPQ out of a []byte with the help of bytes.NewReader(b []byte). The returned MPQ must be closed with the Close method! ErrInvalidArchive is returned if input is not a valid MPQ archive.

func NewFromFile

func NewFromFile(name string) (*MPQ, error)

NewFromFile returns a new MPQ using a file specified by its name as the input. The returned MPQ must be closed with the Close method! ErrInvalidArchive is returned if file exists and can be read, but is not a valid MPQ archive.

func (*MPQ) Close

func (m *MPQ) Close() error

Close closes the MPQ and its resources.

func (*MPQ) FileByHash

func (m *MPQ) FileByHash(h1, h2, h3 uint32) ([]byte, error)

FileByHash returns the content of a file specified by hashes of its name from the archive. The required hashes of a name can be acquired using the FileNameHash() function.

nil slice and nil error is returned if the file cannot be found. ErrInvalidArchive is returned if the file exists but the storing method of the file is not supported/implemented or some error occurs.

func (*MPQ) FileByName

func (m *MPQ) FileByName(name string) ([]byte, error)

FileByName returns the content of a file specified by its name from the archive.

nil slice and nil error is returned if the file cannot be found. ErrInvalidArchive is returned if the file exists but the storing method of the file is not supported/implemented or some error occurs.

Implementation note: this method returns:

MPQ.FileByHash(FileNameHash(name))

If you need to call this frequently, it's profitable to store the hashes returned by FileNameHash(), and call MPQ.FileByHash() directly passing the stored hashes.

func (*MPQ) FilesCount

func (m *MPQ) FilesCount() uint32

FilesCount returns the number of files in the archive.

func (*MPQ) Input

func (m *MPQ) Input() io.ReadSeeker

Input returns the input source of the MPQ content. A non-nil result is returned even if the MPQ is constructed from a file.

func (*MPQ) SrcFile

func (m *MPQ) SrcFile() *os.File

SrcFile returns the optional source file of the MPQ. Returns nil if the MPQ was not constructed from a file.

func (*MPQ) UserData

func (m *MPQ) UserData() []byte

UserData returns the optional data that precedes the MPQ header.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL