我是一个过时的游戏帝国时代2(AoE)的球迷。我想用Python编写一个AoE游戏记录(.mgx文件)的解析器。在
我在GitHub上做了一些搜索,找到了一些关于这个的小项目,最有用的是提供some details of .mgx game record files的aoc-mgx-format。在
问题是:
根据参考文献,.mgx文件的结构如下:
| header_len(4byte int) | next_pos(4byte int) | header_data | ... ... |
mgx格式的十六进制数据的字节顺序是LIGHT endian。在
标题长度存储标题部分的数据长度(标题长度+下一篇文章+标题数据)
header_data存储我需要的有用信息,但它是用zlib压缩的
我尝试用zlib模块解压缩头_数据中的数据,如下所示:
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
但我在运行程序后得到了这个:
Error -3 while decompressing data: incorrect header check
可以在这里找到sample.mgx文件:https://github.com/stefan-kolb/aoc-mgx-format/tree/master/parser/recs
您的第一个问题是不应该反转数据;只需去掉
[::-1]
。在但是如果你这样做,你得到的不是错误-3,而是另一个错误-3,通常是关于一个未知的压缩方法。在
问题是这是一个无头的zlib数据,很像gzip使用的数据。理论上,这意味着有关压缩方法、窗口、start dict等的信息必须在文件中的其他地方提供(在gzip中,是通过gzip头中的信息提供的)。但在实践中,每个人都使用deflate with the max window size and no start dict,所以如果我在为游戏设计一个紧凑的格式,那时候每个字节都是计数的,我只需要硬编码。(在现代,这在RFC中被标准化为“压缩数据格式”,但90年代的大多数PC游戏并没有按照RFC设计……)
所以:
所以,它不仅被解压,看起来像是一个版本,而且…我猜任何东西看起来都像一个未知常数,但它在规范中是相同的未知常数,所以我认为我们很好。在
正如^{} 文档所解释的,
MAX_WBITS
是默认的/最常见的窗口大小(也是通常称为“zlib deflate”而不是“zlib”使用的唯一大小),传递负值意味着头被抑制;其他参数可以保留为默认值。在另请参见this answer、
zlib
文档中的Advanced Functions部分和RFC 1951。(感谢OP找到链接。)老了,但下面是我所做的一个例子:
希望它能帮助未来的程序员:)
顺便说一句,我正打算写一本这样的图书馆。在
相关问题 更多 >
编程相关推荐