mpq

package
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Jan 15, 2023 License: GPL-3.0 Imports: 18 Imported by: 0

Documentation

Overview

Package mpq allows the reading of compressed data from MPQ archives.

   Based on http://www.zezula.net/en/mpq/mpqformat.html
   Cryptographic functions taken from https://github.com/aphistic/go.Zamara

   TODO: - support table encryption
		 - implement test files for MPQ versions 1-4
		 - be memory efficient

Index

Constants

View Source
const (
	MPQ_HASH_TABLE_INDEX = 0x000
	MPQ_HASH_NAME_A      = 0x100
	MPQ_HASH_NAME_B      = 0x200
	MPQ_HASH_FILE_KEY    = 0x300
	MPQ_HASH_KEY2_MIX    = 0x400

	MPQNeutral    = 0
	MPQChinese    = 0x404
	MPQCzech      = 0x405
	MPQGerman     = 0x407
	MPQEnglish    = 0x409
	MPQSpanish    = 0x40a
	MPQFrench     = 0x40c
	MPQItalian    = 0x410
	MPQJapanese   = 0x411
	MPQKorean     = 0x412
	MPQDutch      = 0x413
	MPQPolish     = 0x415
	MPQPortuguese = 0x416
	MPQRusssian   = 0x419
	MPQEnglishUK  = 0x809
)
View Source
const (
	MPQ_HEADER_DATA = "MPQ\x1A"
	MPQ_USER_DATA   = "MPQ\x1B"

	SectorSize = 512

	MD5_ListSize = 6

	MD5_BlockTable int = iota
	MD5_HashTable
	MD5_HiBlockTable
	MD5_BETTable
	MD5_HETTable
	MD5_MPQHeader
)
View Source
const Size = 4

The size of an Adler-32 checksum in bytes.

Variables

View Source
var CompressionTable = map[CompressionType]*dcEntry{
	MPQ_COMPRESSION_HUFFMANN:     {"Huffman trees", dcHuff},
	MPQ_COMPRESSION_ZLIB:         {"zlib", dcZlib},
	MPQ_COMPRESSION_PKWARE:       {"PKWARE", dcl},
	MPQ_COMPRESSION_BZIP2:        {"bzip2", dcBzip2},
	MPQ_COMPRESSION_ADPCM_MONO:   {"wave (mono)", dcADPCMMono},
	MPQ_COMPRESSION_ADPCM_STEREO: {"wave (stereo)", dcADPCMStereo},
	MPQ_COMPRESSION_SPARSE:       {"Sparse", sparse.Decompress},
}
View Source
var Patterns = []string{

	"backup.MPQ",
	"base.MPQ",
	"dbc.MPQ",
	"fonts.MPQ",
	"interface.MPQ",
	"misc.MPQ",
	"model.MPQ",
	"patch.MPQ",
	"patch-2.MPQ",
	"sound.MPQ",
	"speech.MPQ",
	"terrain.MPQ",
	"texture.MPQ",
	"wmo.MPQ",

	"common.MPQ",
	"common-2.MPQ",
	"expansion.MPQ",
	"lichking.MPQ",
	"*/locale-*.MPQ",
	"*/speech-*.MPQ",
	"*/expansion-locale-*.MPQ",
	"*/lichking-locale-*.MPQ",
	"*/expansion-speech-*.MPQ",
	"*/lichking-speech-*.MPQ",
	"*/patch-*.MPQ",
	"patch.MPQ",
	"patch-*.MPQ",
}

Functions

func DecompressBlock

func DecompressBlock(version int, fl CompressionType, content []byte) ([]byte, error)

func GetFiles

func GetFiles(basepath string) ([]string, error)

Types

type BlockEntry

type BlockEntry struct {
	FileOffset     uint64
	CompressedSize uint32
	Size           uint32
	Flags          BlockFlags
}

func (*BlockEntry) Match

func (m *BlockEntry) Match(flag BlockFlags) bool

type BlockFlags

type BlockFlags uint32
const (
	BlockPKZIP        BlockFlags = 0x00000100 // File is compressed using PKWARE Data compression library
	BlockCompress     BlockFlags = 0x00000200 // File is compressed using combination of compression methods
	BlockEncrypted    BlockFlags = 0x00010000 // The file is encrypted
	BlockFixKey       BlockFlags = 0x00020000 // The decryption key for the file is altered according to the position of the file in the archive
	BlockPatchFile    BlockFlags = 0x00100000 // The file contains incremental patch for an existing file in base MPQ
	BlockSingleUnit   BlockFlags = 0x01000000 // Instead of being divided to BlockFlags = 0x1000-bytes blocks, the file is stored as single unit
	BlockDeleteMarker BlockFlags = 0x02000000 // File is a deletion marker, indicating that the file no longer exists. This is used to allow patch archives to delete files present in lower-priority archives in the search chain. The file usually has length of 0 or 1 byte and its name is a hash
	BlockSectorCRC    BlockFlags = 0x04000000 // File has checksums for each sector (explained in the File Data section). Ignored if file is not compressed or imploded.
	BlockExists       BlockFlags = 0x80000000 // Set if file exists, reset when the file was deleted
)

func (BlockFlags) String

func (bf BlockFlags) String() string

type CompressionType

type CompressionType uint8
const (
	MPQ_COMPRESSION_HUFFMANN     CompressionType = 0x01 // Huffmann compression (used on WAVE files only)
	MPQ_COMPRESSION_ZLIB         CompressionType = 0x02 // ZLIB compression
	MPQ_COMPRESSION_PKWARE       CompressionType = 0x08 // PKWARE DCL compression
	MPQ_COMPRESSION_BZIP2        CompressionType = 0x10 // BZIP2 compression (added in Warcraft III)
	MPQ_COMPRESSION_SPARSE       CompressionType = 0x20 // Sparse compression (added in Starcraft 2)
	MPQ_COMPRESSION_ADPCM_MONO   CompressionType = 0x40 // IMA ADPCM compression (mono)
	MPQ_COMPRESSION_ADPCM_STEREO CompressionType = 0x80 // IMA ADPCM compression (stereo)

)

func (CompressionType) String

func (c CompressionType) String() string

type Decompressor

type Decompressor func([]byte) ([]byte, error)

type File

type File struct {
	Name      string
	Hash      *HashEntry
	Block     *BlockEntry
	Reader    io.ReadSeeker
	Multipart bool
	Volume    *MPQ
}

func (*File) Close

func (f *File) Close() error

func (*File) CompressedSize

func (f *File) CompressedSize() int64

func (*File) GetBlockSize

func (f *File) GetBlockSize() int

func (*File) GetFileOffset

func (f *File) GetFileOffset() int64

func (*File) IsCompressed

func (f *File) IsCompressed() bool

func (*File) ReadBlock

func (f *File) ReadBlock() ([]byte, error)

type FileCorruptionError

type FileCorruptionError struct {
	Filename        string
	CorruptionError error
}

func (FileCorruptionError) Error

func (fce FileCorruptionError) Error() string

type FileWasDeletedError

type FileWasDeletedError string

func (FileWasDeletedError) Error

func (fwde FileWasDeletedError) Error() string

type HashEntry

type HashEntry struct {
	ID_A, ID_B uint32

	Locale   uint16
	Platform uint16

	BlockIndex uint32
}
type Header struct {
	ArchiveOffset int64

	Type        uint32
	HeaderSize  uint32
	ArchiveSize uint32

	FormatVersion uint16
	BlockSize     uint16

	HashTableOffset  uint32
	BlockTableOffset uint32

	HashTableSize  uint32
	BlockTableSize uint32

	//-- MPQ HEADER v 2 -------------------------------------------
	HiBlockTableOffset uint64
	HashTableOffsetHi  uint16
	BlockTableOffsetHi uint16

	//-- MPQ HEADER v 3 -------------------------------------------
	ArchiveSize64    uint64
	BETTableOffset64 uint64
	HETTableOffset64 uint64

	//-- MPQ HEADER v 4 -------------------------------------------
	HashTableSize64    uint64
	BlockTableSize64   uint64
	HiBlockTableSize64 uint64
	HETTableSize64     uint64
	BETTableSize64     uint64
	RawChunkSize       uint32

	MD5 [][]byte
}

type MPQ

type MPQ struct {
	Path       string
	Header     *Header
	UserData   *UserData
	File       io.ReadSeeker
	GuardFile  sync.Mutex
	HashTable  []*HashEntry
	BlockTable []*BlockEntry
}

func Decode

func Decode(i io.ReadSeeker) (*MPQ, error)

func Open

func Open(filename string) (*MPQ, error)

func (*MPQ) BlockSize

func (m *MPQ) BlockSize() int

func (*MPQ) Close

func (m *MPQ) Close() error

func (*MPQ) GetBlockTableOffset

func (m *MPQ) GetBlockTableOffset() int64

TODO: add high 16 bits for version 2

func (*MPQ) GetBlockTableSize

func (m *MPQ) GetBlockTableSize() int

func (*MPQ) GetHashTableOffset

func (m *MPQ) GetHashTableOffset() int64

func (*MPQ) GetHashTableSize

func (m *MPQ) GetHashTableSize() int

func (*MPQ) ListFiles

func (m *MPQ) ListFiles() []string

func (*MPQ) OpenFile

func (m *MPQ) OpenFile(name string) (*File, error)

func (*MPQ) Query

func (m *MPQ) Query(n string) (*HashEntry, error)

func (*MPQ) ReadBlockTable

func (m *MPQ) ReadBlockTable()

func (*MPQ) ReadHashTable

func (m *MPQ) ReadHashTable()

func (*MPQ) ReadHeaderData

func (m *MPQ) ReadHeaderData() error

func (*MPQ) ReadUserData

func (m *MPQ) ReadUserData()

func (*MPQ) Version

func (m *MPQ) Version() int

type Pool

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

Pool pre-loads multiple MPQ archive headers, allowing fast, concurrent access of archive files

func OpenPool

func OpenPool(names []string) (*Pool, error)

OpenPool opens a Pool using a slice of MPQ file paths

func (*Pool) ListFiles

func (p *Pool) ListFiles() []string

func (*Pool) OpenFile

func (p *Pool) OpenFile(name string) (*File, error)

type UserData

type UserData struct {
	Size         uint32
	HeaderOffset uint32
	HeaderSize   uint32
}

Jump to

Keyboard shortcuts

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