happyleavesaoc / aoc-mgz

Age of Empires II recorded game parsing and summarization in Python 3.
MIT License
197 stars 41 forks source link

Error: unpack requires a buffer of 8 bytes #75

Closed jrhomburger closed 2 years ago

jrhomburger commented 2 years ago

Having an issue with the byte unpacking here:

with open(game_file_path, 'rb') as data:
    s = Summary(data)
    s.get_map()
    s.get_platform()
    match = parse_match(data)

Any thoughts? Wondering if its a version change but I tried recs from Feb. 2 and still got this issue.

Stack trace:

error                                     Traceback (most recent call last)
c:\python39\lib\site-packages\mgz\fast\header.py in parse(data)
    454     try:
--> 455         header = decompress(data)
    456         version, game, save, log = parse_version(header, data)

c:\python39\lib\site-packages\mgz\fast\header.py in decompress(data)
    409     prefix_size = 8
--> 410     header_len, _ = unpack('<II', data)
    411     zlib_header = data.read(header_len - prefix_size)

c:\python39\lib\site-packages\mgz\fast\header.py in unpack(fmt, data)
     32     """Unpack bytes according to format string."""
---> 33     output = struct.unpack(fmt, data.read(struct.calcsize(fmt)))
     34     if len(output) == 1:

error: unpack requires a buffer of 8 bytes

During handling of the above exception, another exception occurred:

RuntimeError                              Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_4256/3714053892.py in <module>
      6     s.get_map()
      7     s.get_platform()
----> 8     match = parse_match(data)

c:\python39\lib\site-packages\mgz\model\__init__.py in parse_match(handle)
     91     """
     92 
---> 93     data = parse(handle)
     94     body_pos = handle.tell() - 4 # log version
     95     consts = get_consts()

c:\python39\lib\site-packages\mgz\fast\header.py in parse(data)
    465         lobby = parse_lobby(header, version, save)
    466     except (struct.error, zlib.error, AssertionError, MemoryError):
--> 467         raise RuntimeError("could not parse")
    468     return dict(
    469         version=version,

RuntimeError: could not parse
happyleavesaoc commented 2 years ago

You're mixing two different modes. You don't need parse_match if you're already using Summary.

jrhomburger commented 2 years ago

Thanks - then which commands with the s object would I use to extract a record of the first move? I see the playback module, but is there an example of how to connect that to the game?

Thanks for your help.

happyleavesaoc commented 2 years ago

Summary won't directly expose actions (since it's summary). You can either access the private variable _actions (like s._actions) or use the full parser directly.

happyleavesaoc commented 2 years ago

Playback is not compatible with DE.

jrhomburger commented 2 years ago

Thanks - so each iteration of parse_stream is it's own action and s._actions is a list of parsed non-sync actions. This is very helpful. Thank you for the project and response!