I am a fan of the outmoded game Age of Empires II(AoE). I want to write a parser of AoE game record(.mgx files) using Python.
I did some searching on GitHub and found little projects on this, the most useful one is aoc-mgx-format which provide some details of .mgx game record files.
Here is the problem:
according to the reference, structure of a .mgx file is like:
| header_len(4byte int) | next_pos(4byte int) | header_data | ... ... |
The hex data's byte order in mgx format is little endian.
header_len
stores data length of the Header part(header_len
+ next_post
+ header_data
)
header_data
stores useful imformation i need, but its compressed with zlib
I tried to decompress data in header_data
with zlib module like this:
import struct
import zlib
with open('test.mgx', "rb") as fp:
# read the header_len bytes and covert it to a int reprents length of Header part
header_len = struct.unpack("<i", fp.read(4))[0]
# read next_pos (this is not important for me)
next_pos = struct.unpack("<i", fp.read(4))[0]
# then I can get data length of header_data part(compressed with zlib)
header_data_len = header_len - 8
compressed_data = fp.read(header_data_len)[::-1] # need to be reversed because byte order is little endian?
try:
zlib.decompress(compressed_data)
print "can be decompressed!"
except zlib.error as e:
print e.message
but I got this after running the program:
Error -3 while decompressing data: incorrect header check
PS: Sample .mgx files can be found here: https://github.com/stefan-kolb/aoc-mgx-format/tree/master/parser/recs
"<i"
instead of just"i"
in yourunpack
calls. (And besides, I'll bet your computer is natively little-endian anyway.) – Bottomless[::-1]
, that fixes that error, and instead gives you the correct error -3, complaining that EC BD doesn't look like a valid compression method. Since you're usually going to see 79 9C or 79 DA at the start of a valid zlib compressed blob, it may be worth scanning the file for those bytes… – Bottomlesszlib.decompress(compressed_data, -zlib.MAX_WBITS)
will work – Hoodecompress
method too. That's even simpler. :) – Bottomless