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)
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)
# 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(),
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