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
- Variables
- func DecompressBlock(version int, fl CompressionType, content []byte) ([]byte, error)
- func GetFiles(basepath string) ([]string, error)
- type BlockEntry
- type BlockFlags
- type CompressionType
- type Decompressor
- type File
- type FileCorruptionError
- type FileWasDeletedError
- type HashEntry
- type Header
- type MPQ
- func (m *MPQ) BlockSize() int
- func (m *MPQ) Close() error
- func (m *MPQ) GetBlockTableOffset() int64
- func (m *MPQ) GetBlockTableSize() int
- func (m *MPQ) GetHashTableOffset() int64
- func (m *MPQ) GetHashTableSize() int
- func (m *MPQ) ListFiles() []string
- func (m *MPQ) OpenFile(name string) (*File, error)
- func (m *MPQ) Query(n string) (*HashEntry, error)
- func (m *MPQ) ReadBlockTable()
- func (m *MPQ) ReadHashTable()
- func (m *MPQ) ReadHeaderData() error
- func (m *MPQ) ReadUserData()
- func (m *MPQ) Version() int
- type Pool
- type UserData
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 CompressionOrder = []CompressionType{ MPQ_COMPRESSION_HUFFMANN, MPQ_COMPRESSION_ZLIB, MPQ_COMPRESSION_PKWARE, MPQ_COMPRESSION_BZIP2, MPQ_COMPRESSION_ADPCM_MONO, MPQ_COMPRESSION_ADPCM_STEREO, MPQ_COMPRESSION_SPARSE, }
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)
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 File ¶
type File struct { Name string Hash *HashEntry Block *BlockEntry Reader io.ReadSeeker Multipart bool Volume *MPQ }
func (*File) CompressedSize ¶
func (*File) GetBlockSize ¶
func (*File) GetFileOffset ¶
func (*File) IsCompressed ¶
type FileCorruptionError ¶
func (FileCorruptionError) Error ¶
func (fce FileCorruptionError) Error() string
type FileWasDeletedError ¶
type FileWasDeletedError string
func (FileWasDeletedError) Error ¶
func (fwde FileWasDeletedError) Error() string
type Header ¶
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 (*MPQ) GetBlockTableOffset ¶
TODO: add high 16 bits for version 2
func (*MPQ) GetBlockTableSize ¶
func (*MPQ) GetHashTableOffset ¶
func (*MPQ) GetHashTableSize ¶
func (*MPQ) ReadBlockTable ¶
func (m *MPQ) ReadBlockTable()
func (*MPQ) ReadHashTable ¶
func (m *MPQ) ReadHashTable()
func (*MPQ) ReadHeaderData ¶
func (*MPQ) ReadUserData ¶
func (m *MPQ) ReadUserData()
Click to show internal directories.
Click to hide internal directories.