info

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jan 26, 2025 License: GPL-3.0 Imports: 7 Imported by: 1

Documentation

Overview

Package info defines binary structures and constants used by the MPQ format

Index

Constants

View Source
const (
	HashTerminator uint32 = 0xFFFFFFFF
	HashRemoved    uint32 = 0xFFFFFFFE
)

Special block indices

View Source
const (
	MaxHeaderSize = 0x17FF
	Header0Size   = 24
	Header1Size   = 12
	Header2Size   = 24
	Header3Size   = 140
)
View Source
const BetTableHeaderSize = 76
View Source
const BlockTableEntrySize = 16
View Source
const (
	ExtTableHeaderSize = 12
)
View Source
const HashTableEntrySize = 16

The bytes needed to store a HashTableEntry in binary format

View Source
const HetTableHeaderSize = 32
View Source
const MaxUserDataSize = 0x17FF

Variables

View Source
var (
	UserDataSignature   = [4]byte{'M', 'P', 'Q', 0x1B}
	HeaderDataSignature = [4]byte{'M', 'P', 'Q', 0x1A}

	HetTableSignature = [4]byte{'H', 'E', 'T', 0x1A}
	BetTableSignature = [4]byte{'B', 'E', 'T', 0x1A}
)

Functions

func BetTableMergeHashValue

func BetTableMergeHashValue(bet_table_header *BetTableHeader, name_hash_1 uint8, name_hash_2 uint64) (name_hash_64 uint64)

BetTableMergeHashValue reconstitutes the adjusted hash lookup value from name hashes 1 and 2

func BlockTablePos

func BlockTablePos(header *Header) (pos uint64)

func HashTablePos

func HashTablePos(header *Header) (pos uint64)

func HetTableIndexBitLength

func HetTableIndexBitLength(het_table_header *HetTableHeader) (bit_length uint8)

Returns the size of a single packed index, in bits

func HetTableIndicesBitLength

func HetTableIndicesBitLength(het_table_header *HetTableHeader) (bit_length uint64)

Returns the number of bits needed to hold all packed indices in HET table

func HetTableIndicesSize

func HetTableIndicesSize(het_table_header *HetTableHeader) (size uint64)

Returns the number of bytes needed to hold all packed indices in HET table

func HetTableLookupValue

func HetTableLookupValue(het_table_header *HetTableHeader, in_hash_value uint64) (hash_value uint64)

Returns the Jenkins hash, but truncated to the required length, with the maximum allowed bit set to true. this allows the name_hash_1 value to always be non-zero in the HET table, a name_hash_1 zero would signify that there is no data

func LogicalSectorSize

func LogicalSectorSize(header *Header) int

func ReadBetTableHeader

func ReadBetTableHeader(reader io.Reader, bet_table_header *BetTableHeader) (err error)

func ReadBlockTableEntry

func ReadBlockTableEntry(reader io.Reader, block_table_entry *BlockTableEntry) error

Read a BlockTableEntry from a Reader in binary

func ReadExtTableHeader

func ReadExtTableHeader(reader io.Reader, ext_table_header *ExtTableHeader) (err error)

func ReadHashTableEntry

func ReadHashTableEntry(reader io.Reader, hash_table_entry *HashTableEntry) error

Read a HashTableEntry from a Reader in binary

func ReadHeader

func ReadHeader(reader io.Reader, header *Header) (err error)

func ReadHetTableHeader

func ReadHetTableHeader(reader io.Reader, het_table_header *HetTableHeader) (err error)

func ReadUserData

func ReadUserData(reader io.Reader, user_data *UserData) (err error)

Types

type BetTableEntry

type BetTableEntry struct {
	// Offset of the beginning of the file, relative to the beginning of the archive.
	Position uint64
	// Compressed file size
	BlockSize uint64
	// Only valid if the block is a file; otherwise meaningless, and should be 0.
	// If the file is compressed, this is the size of the uncompressed file data.
	FileSize uint64
	// Flags for the file
	FlagsIndex uint32
}

type BetTableHeader

type BetTableHeader struct {
	// Size of the entire BET table, including the header (in bytes)
	TableSize uint32
	// Number of entries in the BET table. Must match HET_TABLE_HEADER::dwEntryCount
	EntryCount uint32
	Unknown08  uint32
	// Size of one table entry (in bits)
	TableEntrySize uint32
	// Bit index of the file position (within the entry record)
	BitIndex_FilePos uint32
	// Bit index of the file size (within the entry record)
	BitIndex_FileSize uint32
	// Bit index of the compressed size (within the entry record)
	BitIndex_CompressedSize uint32
	// Bit index of the flag index (within the entry record)
	BitIndex_FlagIndex uint32
	// Bit index of the ??? (within the entry record)
	BitIndex_Unknown uint32
	// Bit size of file position (in the entry record)
	BitCount_FilePos uint32
	// Bit size of file size (in the entry record)
	BitCount_FileSize uint32
	// Bit size of compressed file size (in the entry record)
	BitCount_CompressedSize uint32
	// Bit size of flags index (in the entry record)
	BitCount_FlagIndex uint32
	// Bit size of ??? (in the entry record)
	BitCount_Unknown uint32
	// Total bit size of the NameHash2
	BitTotal_NameHash2 uint32
	// Extra bits in the NameHash2
	BitExtra_NameHash2 uint32
	// Effective size of NameHash2 (in bits)
	BitCount_NameHash2 uint32
	// Size of NameHash2 table, in bytes
	NameHashArraySize uint32
	// Number of flags in the following array
	FlagCount uint32
}

type BlockTableEntry

type BlockTableEntry struct {
	// Offset of the beginning of the file, relative to the beginning of the archive.
	Position uint32
	// Compressed file size
	BlockSize uint32
	// Only valid if the block is a file; otherwise meaningless, and should be 0.
	// If the file is compressed, this is the size of the uncompressed file data.
	FileSize uint32
	// Flags for the file
	Flags FileFlag
}

type ExtTableHeader

type ExtTableHeader struct {
	// 'HET\x1A' or 'BET\x1A'
	Signature [4]byte
	// Version. Seems to be always 1
	Version uint32
	// Size of the contained table
	Size uint32
}

type FileCompression

type FileCompression uint8

type FileFlag

type FileFlag uint32
const (
	FileImplode      FileFlag = 0x00000100 // Implode method (By PKWARE Data Compression Library)
	FileCompress     FileFlag = 0x00000200 // Compress methods (By multiple methods)
	FileEncrypted    FileFlag = 0x00010000 // Indicates an encrypted file
	FileKey_v2       FileFlag = 0x00020000 // Indicates an encrypted file with key v2
	FilePatchFile    FileFlag = 0x00100000 // The file is a patch file. Raw file data begin with TPatchInfo structure
	FileSingleUnit   FileFlag = 0x01000000 // File is stored as a single unit, rather than split into sectors (Thx, Quantam)
	FileDeleteMarker FileFlag = 0x02000000 // File is a deletion marker. Used in MPQ patches, indicating that the file no longer exists.
	FileSectorCRC    FileFlag = 0x04000000 // File has checksums for each sector. Ignored if file is not compressed or imploded.
	FileSignature    FileFlag = 0x10000000 // Present on STANDARD.SNP\(signature). The only occurence ever observed
	FileExists       FileFlag = 0x80000000 // Set if file exists, reset when the file was deleted
	FileCompressMask FileFlag = 0x0000FF00 // Mask for a file being compressed
	FileFixKey       FileFlag = 0x00020000 // Obsolete, do not use
)

func (FileFlag) String

func (flag FileFlag) String() string

type HashTableEntry

type HashTableEntry struct {
	// The hash of the file path, using method A.
	Name1 uint32
	// The hash of the file path, using method B.
	Name2 uint32
	// The language of the file. This is a Windows LANGID data type, and uses the same values.
	// 0 indicates the default language (American English), or that the file is language-neutral.
	Locale uint16
	// The platform the file is used for. 0 indicates the default platform.
	// No other values have been observed.
	Platform uint8
	Reserved uint8
	// If the hash table entry is valid, this is the index into the block table of the file.
	// Otherwise, one of the following two values:
	//  - FFFFFFFFh: Hash table entry is empty, and has always been empty.
	//               Terminates searches for a given file.
	//  - FFFFFFFEh: Hash table entry is empty, but was valid at some point (a deleted file).
	//               Does not terminate searches for a given file.
	BlockIndex uint32
}
type Header struct {
	Header0
	Header1
	Header2
	Header3
}

MPQ file header

type Header0

type Header0 struct {
	// Size of MPQ archive
	// This field is deprecated in the Burning Crusade MoPaQ format, and the size of the archive
	// is calculated as the size from the beginning of the archive to the end of the hash table,
	// block table, or extended block table (whichever is largest).
	ArchiveSize uint32
	// 0 = Format 1 (up to The Burning Crusade)
	// 1 = Format 2 (The Burning Crusade and newer)
	// 2 = Format 3 (WoW - Cataclysm beta or newer)
	// 3 = Format 4 (WoW - Cataclysm beta or newer)
	Version uint16
	// Power of two exponent specifying the number of 512-byte disk sectors in each logical sector
	// in the archive. The size of each logical sector in the archive is 512 * 2^wBlockSize.
	SectorSize uint16
	// Offset to the beginning of the hash table, relative to the beginning of the archive.
	HashTablePos uint32
	// Offset to the beginning of the block table, relative to the beginning of the archive.
	BlockTablePos uint32
	// Number of entries in the hash table. Must be a power of two, and must be less than 2^16 for
	// the original MoPaQ format, or less than 2^20 for the Burning Crusade format.
	HashTableSize uint32
	// Number of entries in the block table
	BlockTableSize uint32
}

type Header1

type Header1 struct {
	// Offset to the beginning of array of 16-bit high parts of file offsets.
	HiBlockTablePos64 uint64
	// High 16 bits of the hash table offset for large archives.
	HashTablePosHi uint16
	// High 16 bits of the block table offset for large archives.
	BlockTablePosHi uint16
}

type Header2

type Header2 struct {
	// 64-bit version of the archive size
	ArchiveSize64 uint64
	// 64-bit position of the BET table
	BetTablePos64 uint64
	// 64-bit position of the HET table
	HetTablePos64 uint64
}

type Header3

type Header3 struct {
	// Compressed size of the hash table
	HashTableSize64 uint64
	// Compressed size of the block table
	BlockTableSize64 uint64
	// Compressed size of the hi-block table
	HiBlockTableSize64 uint64
	// Compressed size of the HET block
	HetTableSize64 uint64
	// Compressed size of the BET block
	BetTableSize64 uint64
	// Size of raw data chunk to calculate MD5.
	// MD5 of each data chunk follows the raw file data.
	RawChunkSize uint32
	// Array of MD5's
	// MD5 of the block table before decryption
	MD5_BlockTable [md5.Size]byte
	// MD5 of the hash table before decryption
	MD5_HashTable [md5.Size]byte
	// MD5 of the hi-block table
	MD5_HiBlockTable [md5.Size]byte
	// MD5 of the BET table before decryption
	MD5_BetTable [md5.Size]byte
	// MD5 of the HET table before decryption
	MD5_HetTable [md5.Size]byte
	// MD5 of the MPQ header from signature to (including) MD5_HetTable
	MD5_MpqHeader [md5.Size]byte
}

type HetTableHeader

type HetTableHeader struct {
	// Size of the entire HET table, including HetTableHeader (in bytes)
	TableSize uint32
	// Number of occupied entries in the HET table
	UsedEntryCount uint32
	// Total number of entries in the HET table
	TotalEntryCount uint32
	// Size of the name hash entry (in bits)
	NameHashBitSize uint32
	// Total size of file index (in bits)
	IndexSizeTotal uint32
	// Extra bits in the file index
	IndexSizeExtra uint32
	// Effective size of the file index (in bits)
	IndexSize uint32
	// Size of the block index subtable (in bytes)
	IndexTableSize uint32
}

The header occupies the very beginning of the encrypted data block immediately following the ExtTableHeader

type UserData

type UserData struct {
	UserDataPrefix
}

type UserDataPrefix

type UserDataPrefix struct {
	// Offset of the MPQ header, relative to the begin of this header
	HeaderOffset uint32
	// Appears to be size of user data header (Starcraft II maps)
	UserDataHeader uint32
}

Jump to

Keyboard shortcuts

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