Exemplo n.º 1
0
def replay():
    match_id = request.args.get('match_id')
    profile_id = request.args.get('profile_id')

    url = 'https://aoe.ms/replay/?gameId={}&profileId={}'.format(match_id, profile_id)

    try:
        filename = aoeapi.download_rec(url, 'recs')
    except aoeapi.AoeApiError:
        print('could not download valid rec: ', match_id, ' - ', profile_id)
        abort(404)
        return
    except RuntimeError:
        print('could not download valid rec: ', match_id, ' - ', profile_id)
        abort(404)
        return

    print('recs/' + filename)

    start = time.time()
    with open('recs/' + filename, 'rb') as handle:
        data = handle.read()

    handle = io.BytesIO(data)
    summary = mgz.summary.Summary(handle, None)

    end = time.time()
    print('process', end - start, 's')

    os.remove('recs/' + filename)

    map = summary.get_map()
    del map['tiles']

    return json.dumps({
        "players": summary.get_players(),
        "completed": summary.get_completed(),
        "chat": summary.get_chat(),
        "dataset": summary.get_dataset(),
        "diplomacy": summary.get_diplomacy(),
        "duration": summary.get_duration(),
        "encoding": summary.get_encoding(),
        "file_hash": summary.get_file_hash(),
        "language": summary.get_language(),
        "mirror": summary.get_mirror(),
        "owner": summary.get_owner(),
        "platform": summary.get_platform(),
        "postgame": summary.get_postgame(), # null
        "teams": summary.get_teams(),
        "start_time": summary.get_start_time(), # 0
        "restored": summary.get_restored(),
        "ratings": summary.get_ratings(), # empty
        "profile_ids": summary.get_profile_ids(),
        "map": map,
    }, default=str)
Exemplo n.º 2
0
def won():
    match_id = request.args.get('match_id')

    try:
        match = aoeapi.get_match(match_id)
    except aoeapi.AoeApiError:
        raise RuntimeError('could not get match')

    players = match['players']
    # print(json.dumps(match['players2']))

    for player in players:
        if not player['url']:
            continue
        try:
            start = time.time()
            filename = aoeapi.download_rec(player['url'], 'recs')
            end = time.time()
            # print('download', end - start, 's')
        except aoeapi.AoeApiError:
            # raise RuntimeError("could not download valid rec: %s", match_id)
            print('error')
            continue
        except RuntimeError:
            raise RuntimeError("could not download valid rec: %s", match_id)
            print('error')
            continue

        print('recs/' + filename)

        start = time.time()
        with open('recs/' + filename, 'rb') as handle:
            data = handle.read()

        handle = io.BytesIO(data)
        summary = mgz.summary.Summary(handle, None)

        end = time.time()
        print('process', end - start, 's')

        # print('--- BREAK')

        # for player2 in summary.get_players():
        #     print(player2['name'] + ': ' + str(player2['winner']))

        os.remove('recs/' + filename)

        return jsonify({
            "players": summary.get_players(),
            "completed": summary.get_completed(),
            "chat": summary.get_chat(),
            "dataset": summary.get_dataset(),
            "diplomacy": summary.get_diplomacy(),
            "duration": summary.get_duration(),
            "encoding": summary.get_encoding(),
            "file_hash": summary.get_file_hash(),
            "language": summary.get_language(),
            "mirror": summary.get_mirror(),
            "owner": summary.get_owner(),
            "platform": summary.get_platform(),
            "postgame": summary.get_postgame(),  # null
            "teams": summary.get_teams(),
            "start_time": summary.get_start_time(),  # 0
            "restored": summary.get_restored(),
            "ratings": summary.get_ratings(),  # empty
            "profile_ids": summary.get_profile_ids(),
        })

        # print(json.dumps(summary.get_hash())) # non serializable
        # print(json.dumps(summary.get_header())) # non serializable
        # print(json.dumps(summary.get_version())) # non serializable

        # print(json.dumps(summary.get_objects())) #80KB
        # print(json.dumps(summary.get_map())) # 2.1MB

        # print('get_completed', summary.get_completed())
        # print('get_chat', summary.get_chat())
        # print('get_objects', summary.get_objects())
        # print('get_hash', summary.get_hash())
        # print('get_map', summary.get_map())
        # print('get_dataset', summary.get_dataset())
        # print('get_diplomacy', summary.get_diplomacy())
        # print('get_duration', summary.get_duration())
        # print('get_encoding', summary.get_encoding())
        # print('get_file_hash', summary.get_file_hash())
        # print('get_header', summary.get_header())
        # print('get_version', summary.get_version())
        # print('get_language', summary.get_language())
        # print('get_mirror', summary.get_mirror())
        # print('get_owner', summary.get_owner())
        # print('get_platform', summary.get_platform())
        # print('get_postgame', summary.get_postgame())
        # print('get_teams', summary.get_teams())
        # print('get_start_time', summary.get_start_time())
        # print('get_restored', summary.get_restored())
        # print('get_ratings', summary.get_ratings())
        # print('get_profile_ids', summary.get_profile_ids())

    abort(404)
Exemplo n.º 3
0
# end = time.time()
# print('process', end - start, 's')

os.remove('recs/' + filename)

map = summary.get_map()
del map['tiles']

sys.stdout = old_stdout
print(
    json.dumps(
        {
            "players": summary.get_players(),
            "completed": summary.get_completed(),
            "chat": summary.get_chat(),
            "dataset": summary.get_dataset(),
            "diplomacy": summary.get_diplomacy(),
            "duration": summary.get_duration(),
            "encoding": summary.get_encoding(),
            "file_hash": summary.get_file_hash(),
            "language": summary.get_language(),
            "mirror": summary.get_mirror(),
            "owner": summary.get_owner(),
            "platform": summary.get_platform(),
            "postgame": summary.get_postgame(),  # null
            "teams": summary.get_teams(),
            "start_time": summary.get_start_time(),  # 0
            "restored": summary.get_restored(),
            "ratings": summary.get_ratings(),  # empty
            "profile_ids": summary.get_profile_ids(),
Exemplo n.º 4
0
    def _add_match(  # pylint: disable=too-many-branches, too-many-return-statements
            self,
            summary,
            played,
            match_hash,
            user_data,
            series_name=None,
            series_id=None,
            platform_id=None,
            platform_match_id=None,
            platform_metadata=None,
            ladder=None,
            build=None):
        """Add a match."""
        try:
            duration = summary.get_duration()
        except RuntimeError:
            LOGGER.error("[m] failed to get duration")
            return False, 'Failed to get duration'

        log_id = match_hash[:LOG_ID_LENGTH]
        platform_data = summary.get_platform()
        rated, ladder_id, platform_id, platform_match_id = merge_platform_attributes(
            ladder, platform_id, platform_match_id, platform_data,
            self.platforms)

        settings = summary.get_settings()
        try:
            map_data = summary.get_map()
        except ValueError:
            LOGGER.error("[m:%s] has an invalid map", log_id)
            return False, 'Invalid map'
        completed = summary.get_completed()
        restored, _ = summary.get_restored()
        has_postgame = summary.has_achievements()
        version_id, game_version, save_version, log_version = summary.get_version(
        )
        try:
            dataset_data = summary.get_dataset()
        except ValueError:
            LOGGER.error("[m:%s] dataset inconclusive", log_id)
            return False, 'Inconclusive dataset'

        teams = summary.get_teams()
        diplomacy = summary.get_diplomacy()
        players = list(summary.get_players())
        mirror = summary.get_mirror()
        if platform_match_id:
            log_id += ':{}'.format(platform_match_id)

        if restored:
            LOGGER.error("[m:%s] is restored game", log_id)
            return False, 'Restored matches not supported'

        if not completed:
            LOGGER.error("[m:%s] was not completed", log_id)
            return False, 'Incomplete matches not supported'

        if user_data and len(players) != len(user_data):
            LOGGER.error("[m:%s] has mismatched user data", log_id)
            return False, 'Mismatched user data'

        if has_transposition(user_data, players):
            LOGGER.error("[m:%s] has mismatched user data (transposition)",
                         log_id)
            return False, 'Transposed user data'

        try:
            dataset = self.session.query(Dataset).filter_by(
                id=dataset_data['id']).one()
        except NoResultFound:
            LOGGER.error("[m:%s] dataset not supported: userpatch id: %s (%s)",
                         log_id, dataset_data['id'], dataset_data['name'])
            return False, 'Dataset not supported'

        series, tournament, event, event_map_id = self._handle_series(
            series_id, series_name, map_data, log_id)

        objects = summary.get_objects()
        try:
            compressed_objects = compress_objects(objects['objects'])
        except struct.error:
            return False, "bad object parsing"

        match = get_unique(
            self.session,
            Match, ['hash', 'platform_match_id'],
            platform_match_id=platform_match_id,
            platform_id=platform_id,
            platform_metadata=platform_metadata,
            played=played,
            hash=match_hash,
            series=series,
            tournament=tournament,
            event=event,
            version_id=version_id.value,
            game_version=game_version,
            save_version=round(save_version, 2),
            log_version=log_version,
            build=build,
            dataset=dataset,
            dataset_version=dataset_data['version'],
            ladder_id=ladder_id,
            rated=rated,
            lobby_name=platform_data['lobby_name'],
            objects=compressed_objects,
            builtin_map_id=map_data['id'],
            event_map_id=event_map_id,
            map_size_id=map_data['dimension'],
            map_name=map_data['name'],
            map_tiles=compress_tiles(map_data['tiles']),
            rms_seed=map_data['seed'],
            rms_zr=map_data['zr'],
            rms_custom=map_data['custom'],
            guard_state=map_data['modes']['guard_state'],
            direct_placement=map_data['modes']['direct_placement'],
            effect_quantity=map_data['modes']['effect_quantity'],
            fixed_positions=map_data['modes']['fixed_positions'],
            water_percent=map_data['water'],
            duration=timedelta(milliseconds=duration),
            completed=completed,
            restored=restored,
            postgame=has_postgame,
            type_id=settings['type'][0],
            difficulty_id=settings['difficulty'][0],
            population_limit=settings['population_limit'],
            map_reveal_choice_id=settings['map_reveal_choice'][0],
            speed_id=settings['speed'][0],
            cheats=settings['cheats'],
            lock_teams=settings['lock_teams'],
            treaty_length=settings['treaty_length'],
            starting_resources_id=settings['starting_resources'][0],
            starting_age_id=settings['starting_age'][0],
            victory_condition_id=settings['victory_condition'][0],
            team_together=settings['team_together'],
            all_technologies=settings['all_technologies'],
            lock_speed=settings['lock_speed'],
            multiqueue=settings['multiqueue'],
            diplomacy_type=diplomacy['type'],
            team_size=diplomacy.get('team_size'),
            mirror=mirror,
            starting_town_centers=objects.get('tcs'),
            starting_walls=objects.get('stone_walls'),
            starting_palisades=objects.get('palisade_walls'))

        winning_team_id = None
        for data in players:
            team_id = None
            for i, team in enumerate(teams):
                if data['number'] in team:
                    team_id = i
            if data['winner']:
                winning_team_id = team_id
            feudal_time = data['achievements']['technology']['feudal_time']
            castle_time = data['achievements']['technology']['castle_time']
            imperial_time = data['achievements']['technology']['imperial_time']
            try:
                get_unique(self.session,
                           Team, ['match', 'team_id'],
                           winner=(team_id == winning_team_id),
                           match=match,
                           team_id=team_id)
                if data['user_id']:
                    get_unique(self.session,
                               User, ['id', 'platform_id'],
                               id=str(data['user_id']),
                               platform_id=platform_id)
                player = get_unique(
                    self.session,
                    Player, ['match_id', 'number'],
                    civilization_id=int(data['civilization']),
                    team_id=team_id,
                    match_id=match.id,
                    dataset=dataset,
                    platform_id=platform_id,
                    user_id=data['user_id'],
                    user_name=data['name'] if data['user_id'] else None,
                    human=data['human'],
                    name=data['name'],
                    number=data['number'],
                    color_id=data['color_id'],
                    start_x=data['position'][0],
                    start_y=data['position'][1],
                    winner=data['winner'],
                    mvp=data['mvp'],
                    cheater=data['cheater'],
                    score=data['score'],
                    rate_snapshot=data['rate_snapshot'],
                    military_score=data['achievements']['military']['score'],
                    units_killed=data['achievements']['military']
                    ['units_killed'],
                    hit_points_killed=data['achievements']['military']
                    ['hit_points_killed'],
                    units_lost=data['achievements']['military']['units_lost'],
                    buildings_razed=data['achievements']['military']
                    ['buildings_razed'],
                    hit_points_razed=data['achievements']['military']
                    ['hit_points_razed'],
                    buildings_lost=data['achievements']['military']
                    ['buildings_lost'],
                    units_converted=data['achievements']['military']
                    ['units_converted'],
                    economy_score=data['achievements']['economy']['score'],
                    food_collected=data['achievements']['economy']
                    ['food_collected'],
                    wood_collected=data['achievements']['economy']
                    ['wood_collected'],
                    stone_collected=data['achievements']['economy']
                    ['stone_collected'],
                    gold_collected=data['achievements']['economy']
                    ['gold_collected'],
                    tribute_sent=data['achievements']['economy']
                    ['tribute_sent'],
                    tribute_received=data['achievements']['economy']
                    ['tribute_received'],
                    trade_gold=data['achievements']['economy']['trade_gold'],
                    relic_gold=data['achievements']['economy']['relic_gold'],
                    technology_score=data['achievements']['technology']
                    ['score'],
                    feudal_time=timedelta(
                        seconds=feudal_time) if feudal_time else None,
                    castle_time=timedelta(
                        seconds=castle_time) if castle_time else None,
                    imperial_time=timedelta(
                        seconds=imperial_time) if imperial_time else None,
                    explored_percent=data['achievements']['technology']
                    ['explored_percent'],
                    research_count=data['achievements']['technology']
                    ['research_count'],
                    research_percent=data['achievements']['technology']
                    ['research_percent'],
                    society_score=data['achievements']['society']['score'],
                    total_wonders=data['achievements']['society']
                    ['total_wonders'],
                    total_castles=data['achievements']['society']
                    ['total_castles'],
                    total_relics=data['achievements']['society']
                    ['total_relics'],
                    villager_high=data['achievements']['society']
                    ['villager_high'])
            except RuntimeError:
                LOGGER.warning(
                    "[m:%s] failed to insert players (probably bad civ id: %d)",
                    log_id, data['civilization'])
                return False, 'Failed to load players'

            if match.platform_id in [PLATFORM_VOOBLY, PLATFORM_IGZ
                                     ] and not user_data and player.human:
                self._guess_match_user(player, data['name'], match.platform_id)

        match.winning_team_id = winning_team_id
        success, attrs = save_extraction(self.session, summary, ladder_id,
                                         match.id, dataset_data['id'], log_id)
        if success:
            match.has_playback = True
            match.state_reader_version = attrs['version']
            match.state_reader_interval = attrs['interval']
            match.state_reader_runtime = attrs['runtime']

        save_chat(self.session, summary.get_chat(), match.id)
        return match, None