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)
# 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'] 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(),
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
def _add_match( # pylint: disable=too-many-branches self, summary, played, match_hash, user_data, series_name=None, series_id=None, platform_id=None, platform_match_id=None, ladder=None ): """Add a match.""" try: postgame = summary.get_postgame() duration = summary.get_duration() except RuntimeError: LOGGER.error("[m] failed to get duration") return False rated = False from_voobly, ladder_name, rated, _ = summary.get_ladder() if ladder: rated = True if not ladder: ladder = ladder_name if from_voobly and not platform_id: platform_id = PLATFORM_VOOBLY settings = summary.get_settings() map_data = summary.get_map() completed = summary.get_completed() restored, _ = summary.get_restored() has_postgame = bool(postgame) major_version, minor_version = summary.get_version() dataset_data = summary.get_dataset() teams = summary.get_teams() diplomacy = summary.get_diplomacy() players = list(summary.get_players()) mirror = summary.get_mirror() log_id = match_hash[:LOG_ID_LENGTH] if platform_match_id: log_id += ':{}'.format(platform_match_id) if restored: LOGGER.error("[m:%s] is restored game", log_id) return False if not completed: LOGGER.error("[m:%s] was not completed", log_id) return False if user_data and len(players) != len(user_data): LOGGER.error("[m:%s] has mismatched user data", log_id) return False if platform_id: try: if platform_id in VOOBLY_PLATFORMS: ladder_id = voobly.lookup_ladder_id(ladder) else: ladder_id = 1 # fix.. ladder = self._get_unique( Ladder, keys=['id', 'platform_id'], id=ladder_id, platform_id=platform_id, name=ladder ) except ValueError: ladder_id = None else: ladder_id = None 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 series, tournament, event, event_map_id = self._handle_series(series_id, series_name, map_data, log_id) if series: played = series.played match = self._get_unique( Match, ['hash', 'platform_match_id'], platform_match_id=platform_match_id, platform_id=platform_id, played=played, hash=match_hash, series=series, tournament=tournament, event=event, version=major_version, minor_version=minor_version, dataset=dataset, dataset_version=dataset_data['version'], ladder_id=ladder_id, rated=rated, builtin_map_id=map_data['id'], event_map_id=event_map_id, map_size_id=map_data['dimension'], map_name=map_data['name'], 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'], 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'], 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 ) 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'] self._get_unique( Team, ['match', 'team_id'], winner=(team_id == winning_team_id), match=match, team_id=team_id ) player = self._get_unique( Player, ['match_id', 'number'], civilization_id=int(data['civilization']), team_id=team_id, match_id=match.id, dataset=dataset, platform_id=platform_id, 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'], 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'] ) if match.platform_id == PLATFORM_VOOBLY and not user_data: self._guess_match_user(player, data['name']) match.winning_team_id = winning_team_id return match