def analyse_replay(replay: str, output_path: str = None): json_ = None if output_path is not None: output_path_ = Path(output_path) if output_path_.is_file(): with timer('Loading previously decompiled replay'): with output_path_.open("r") as f: json_ = json.load(f) if json_ is None: with timer('Decompiling replay'): json_ = decompile_replay(replay, output_path=output_path) with timer('Parsing json'): json_parser_game = JsonParserGame() json_parser_game.initialize(loaded_json=json_) with timer('Creating protobuf game'): game = create_game(json_parser_game) # print(game) with timer('Creating full pandas DataFrame'): df = create_data_frame(json_parser_game) # print(df.memory_usage()) events = game.events # with timer('Getting old hits'): # # old hits # old_hit_frames = BaseHit.get_hits_from_game(json_parser_game, None, None, df, None) with timer('Getting hits'): # new hits get_hits(events, game, df) with timer('Calculating hit types'): calculate_hit_types(events.hits, game, df) with timer('Calculating pressures'): calculate_pressures(events, game, df) with timer("Calculating stats"): analysis = calculate_stats(events, game, df) return json_parser_game, game, df, events, analysis
def convert_json_to_game_frames(filename): with open(filename, encoding='utf-8', errors='ignore') as json_file: _json = json.load(json_file) game = Game() game.initialize(loaded_json=_json) analysis = AnalysisManager(game) analysis.create_analysis() x = ControlsCreator() x.get_controls(game) frames = [] for col, row in analysis.data_frame.iterrows(): frame = {} frame["GameState"] = {} frame["GameState"]["time"] = NaN_fixer(row["game"]["time"]) frame["GameState"]["seconds_remaining"] = NaN_fixer( row["game"]["seconds_remaining"]) frame["GameState"]["deltatime"] = NaN_fixer(row["game"]["delta"]) frame["GameState"]["ball"] = {} frame["GameState"]["ball"]["position"] = [ NaN_fixer(row["ball"]["pos_x"]), NaN_fixer(row["ball"]["pos_y"]), NaN_fixer(row["ball"]["pos_z"]) ] frame["GameState"]["ball"]["velocity"] = [ NaN_fixer(row["ball"]["vel_x"]), NaN_fixer(row["ball"]["vel_y"]), NaN_fixer(row["ball"]["vel_z"]) ] frame["GameState"]["ball"]["rotation"] = [ NaN_fixer(row["ball"]["rot_x"]), NaN_fixer(row["ball"]["rot_y"]), NaN_fixer(row["ball"]["rot_z"]) ] frame["PlayerData"] = [] for i in range(len(game.players)): frame["PlayerData"].append( getPlayerFrame(game.players[i], i, col, row)) frames.append(frame) return frames
def analyze_replay_file(replay_path: str, controls: ControlsCreator = None, sanity_check: SanityChecker = None, analysis_per_goal=False, logging_level=logging.NOTSET, calculate_intensive_events: bool = False, clean: bool = True): """ Decompile and analyze a replay file. :param replay_path: Path to replay file :param controls: Generate controls from the replay using our best guesses (ALPHA) :param sanity_check: Run sanity check to make sure we analyzed correctly (BETA) :param analysis_per_goal: Runs the analysis per a goal instead of the replay as a whole :param force_full_analysis: If True full analysis will be performed even if checks say it should not. :param logging_level: Sets the logging level globally across carball :param calculate_intensive_events: Indicates if expensive calculations should run to include additional stats. :param clean: Indicates if useless/invalid data should be found and removed. :return: AnalysisManager of game with analysis. """ if logging_level != logging.NOTSET: logging.getLogger('carball').setLevel(logging_level) _json = decompile_replay(replay_path) game = Game() game.initialize(loaded_json=_json) # get_controls(game) # TODO: enable and optimise. if sanity_check is not None: sanity_check.check_game(game) if analysis_per_goal: analysis = PerGoalAnalysis(game) else: analysis = AnalysisManager(game) analysis.create_analysis( calculate_intensive_events=calculate_intensive_events, clean=clean) if controls is not None: controls.get_controls(game) return analysis
def analyze_replay_file(replay_path: str, output_path: str = None, overwrite=True, controls: ControlsCreator = None, sanity_check: SanityChecker = None, analysis_per_goal=False, rattletrap_path: str = None): """ Decompile and analyze a replay file. :param replay_path: Path to replay file :param output_path: Path to write JSON :param overwrite: If to overwrite JSON (suggest True if speed is not an issue) :param controls: Generate controls from the replay using our best guesses (ALPHA) :param sanity_check: Run sanity check to make sure we analyzed correctly (BETA) :param analysis_per_goal: Runs the analysis per a goal instead of the replay as a whole :param rattletrap_path: Custom location for rattletrap executable. Path to folder. :param force_full_analysis: If True full analysis will be performed even if checks say it should not. :return: AnalysisManager of game with analysis. """ _json = decompile_replay(replay_path, output_path=output_path, overwrite=overwrite, rattletrap_path=rattletrap_path) game = Game() game.initialize(loaded_json=_json) # get_controls(game) # TODO: enable and optimise. if sanity_check is not None: sanity_check.check_game(game) if analysis_per_goal: analysis = PerGoalAnalysis(game) else: analysis = AnalysisManager(game) analysis.create_analysis() if controls is not None: controls.get_controls(game) return analysis
def perform_full_analysis(self, game: Game, proto_game: game_pb2.Game, player_map, data_frame, kickoff_frames): self.protobuf_games = [] # split up frames total_score = proto_game.game_metadata.score.team_0_score + proto_game.game_metadata.score.team_1_score print(total_score) for i in range(0, total_score): split_pandas = data_frame[data_frame.game.goal_number == i] new_proto = game_pb2.Game() for team in proto_game.teams: proto_team = new_proto.teams.add() proto_team.CopyFrom(team) for player in proto_game.players: proto_player = new_proto.players.add() proto_player.CopyFrom(player) new_proto.game_metadata.CopyFrom(proto_game.game_metadata) new_game = Game() new_game.players = game.players new_game.teams = game.teams new_game.frames = split_pandas super().perform_full_analysis(new_game, new_proto, player_map, split_pandas, kickoff_frames) self.protobuf_games.append(new_proto)
import carball from carball.json_parser.game import Game from carball.analysis.analysis_manager import AnalysisManager import sys import os import json _json_name = output_path = sys.argv[2] + '.tmp' _json = carball.decompile_replay(sys.argv[1], _json_name, overwrite=True) game = Game() game.initialize(loaded_json=_json) analysis = AnalysisManager(game) analysis.create_analysis(calculate_intensive_events=False) _output_tmp_name = sys.argv[2] + "-" + 'tmp' + ".json" with open(_output_tmp_name, 'w') as out: analysis.write_json_out_to_file(out) with open(_output_tmp_name) as tmp: data = json.load(tmp) time = data['gameMetadata']['time'] _output_name = sys.argv[2] + "-" + time + ".json" os.rename(_output_tmp_name, _output_name) if os.path.exists(_json_name): os.remove(_json_name) else:
def main(): parser = argparse.ArgumentParser( description='Rocket League replay parsing and analysis.') parser.add_argument( '-i', '--input', type=str, required=True, help= 'Path to replay file that will be analyzed. Carball expects a raw replay file unless ' '--skip-decompile is provided.') parser.add_argument( '--proto', type=str, required=False, help= 'The result of the analysis will be saved to this file in protocol buffers format.' ) parser.add_argument( '--json', type=str, required=False, help= 'The result of the analysis will be saved to this file in json file format. This is not ' 'the decompiled replay json from rattletrap.') parser.add_argument( '--gzip', type=str, required=False, help= 'The pandas data frame containing the replay frames will be saved to this file in a ' 'compressed gzip format.') parser.add_argument( '-sd', '--skip-decompile', action='store_true', default=False, help= 'If set, carball will treat the input file as a json file that Rattletrap outputs.' ) parser.add_argument( '-v', '--verbose', action='count', default=0, help= 'Set the logging level to INFO. To set the logging level to DEBUG use -vv.' ) parser.add_argument('-s', '--silent', action='store_true', default=False, help='Disable logging altogether.') args = parser.parse_args() if not args.proto and not args.json and not args.gzip: parser.error( 'at least one of the following arguments are required: --proto, --json, --gzip' ) log_level = logging.WARNING if args.verbose == 1: log_level = logging.INFO elif args.verbose >= 2: log_level = logging.DEBUG if args.silent: logging.basicConfig(handlers=[logging.NullHandler()]) else: logging.basicConfig(handlers=[logging.StreamHandler()], level=log_level) if args.skip_decompile: game = Game() game.initialize(loaded_json=args.input) manager = AnalysisManager(game) manager.create_analysis() else: manager = carball.analyze_replay_file(args.input) if args.proto: with open(args.proto, 'wb') as f: manager.write_proto_out_to_file(f) if args.json: proto_game = manager.get_protobuf_data() with open(args.json, 'w') as f: f.write(MessageToJson(proto_game)) if args.gzip: with gzip.open(args.gzip, 'wb') as f: manager.write_pandas_out_to_file(f)
def __init__(self, jsonObject, parser): self.jsonObject = jsonObject self.parser = parser if parser == 'rattletrap': self.game = Game().initialize(loaded_json=self.jsonObject)
def get_decompiled_replay(): game = Game( os.path.abspath('test/replays/516E50BF491D3ECE8D1E9FAD08C00F9B.json')) return game