happyleavesaoc / aoc-mgz

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

DE version 25.22 fails on header parse #73

Closed Namek closed 2 years ago

Namek commented 2 years ago

Fast reader crashes at this line: https://github.com/happyleavesaoc/aoc-mgz/blob/77216bce4ebc2799aab5c6921a37fce23991ce8a/mgz/fast/header.py#L323

MP_Replay_v101.101.58259.0_2022.02.01_214243_2.zip

happyleavesaoc commented 2 years ago

Hi @Namek fast reader does not yet support 25.22

Namek commented 2 years ago

but does something? I try with Summary and it fails too.

Namek commented 2 years ago

The recording comes from another player. I just created a single player recordings on my machine and the Summary goes through that part successfully. It only fails in the parse_metadata on the raise RuntimeError("don't know how to parse ai").

I tried single player both on English and Polish but I still have a slight suspicion on the language.

Namek commented 2 years ago

JUST FYI:


from mgz.model import parse_match
from mgz.summary import Summary

def get_match_info(data):
    try:
        # some files seems broken for this library when using the `Summary`.
        m = parse_match(data)
        players = [dict(name=p.name, user_id=p.profile_id, number=p.number,
                        civilization=p.civilization) for p in m.players]

        return dict(
            map_name=m.map.name,
            game_version=f"{m.version.name} {m.version.value}",
            game_map_type=m.type,
            players=players,
            teams=m.teams,
            completed=False,
            start_time_seconds=int(m.actions[0].timestamp.seconds),
            duration_seconds=m.duration.seconds,
        )
    except RuntimeError:
        # the `parse_match` method doesn't work for restored recordings, thus, let's try with the `Summary`.
        data.seek(0)
        s = Summary(data)

        return dict(
            map_name=s.get_map()['name'],
            game_version=" ".join(str(x) for x in s.get_version()),
            game_map_type=s.get_settings()['type'][1],
            players=s.get_players(),
            teams=s.get_teams(),
            completed=s.get_completed(),
            start_time_seconds=int(s.get_start_time()/1000),
            duration_seconds=int(s.get_duration()/1000),
        )

This is what I need from recordings. It's basically header information.

happyleavesaoc commented 2 years ago

Ok, I confirmed it's failing to parse the DE header (in both fast and full). There's an unknown condition that introduces an extra array of bytes. It could be the use of a custom map, but I need more evidence.

happyleavesaoc commented 2 years ago

Tested a few custom maps, that was not the issue. Were any unusual settings used for that match?

Namek commented 2 years ago

the map from the recording is supposed to be "ANT - Arabia" from the mod Ant League 2022 Spring Edition - Mappack. I think it comes from the KtsOTD mappack

Namek commented 2 years ago

of anything special: players are supposed to use the "hidden civ" setting when hosting

happyleavesaoc commented 2 years ago

I am testing a fix for this.

happyleavesaoc commented 2 years ago

Please try the latest commit on master. I was able to parse the attached match:

Path        namek.aoe2record
Duration    00:33:39
Completed   True
Restored    False
Postgame    False
Objects     True
Version     DE (VER 9.4, 25.22, 5, 58259)
Dataset     Definitive Edition None
File Hash   9aa4db397aba6fb93cf093b4b1e9625197a9b36f
Match Hash  43c13fc932f42c78e4a08f01aa9a1528172df7e3
Encoding    utf-8
Language    en
Map         ANT - Arabia (-385897673)
Namek commented 2 years ago

@happyleavesaoc Somehow I have the same issue in the exact same place.

EDIT: OK, I got an error on my side. This finally reads the file with the Summary method.