def parse_files(abs_path, spell_check, playlist_filter, single_player): temp_output_dir = abs_path + "/TempJSON/" replay_dir = abs_path print("Engine: verifying temp directory") sys.stdout.flush() print("Engine: parsing folder: " + replay_dir) for replay_file in get_files(replay_dir): print("Engine: Analyzing replay: " + replay_file) sys.stdout.flush() _json = carball.decompile_replay(replay_dir + "/" + replay_file, output_path=temp_output_dir + 'decompiled_replay.json', overwrite=True) game = Game() game.initialize(loaded_json=_json) analysis = AnalysisManager(game) analysis.create_analysis() raw_json = MessageToJson(analysis.protobuf_game) data = json.loads(raw_json) f = open(temp_output_dir + "lastfile.json", "w+") f.write(raw_json) f.close() print("Engine: sending data from " + replay_file + " to Builder") sys.stdout.flush() Builder(data, spell_check, playlist_filter, single_player)
def processReplays(self, replay, outputfile): self.outputfile = outputfile _json = carball.decompile_replay(replay) game = Game() player = Player() # Initialize and perform default analysis game.initialize(loaded_json=_json) analysis = AnalysisManager(game) analysis.create_analysis() # Get protobuf data to analyze proto_game = analysis.get_protobuf_data() # Readability self.meta = proto_game.game_metadata self.team = proto_game.teams self.players = proto_game.players self.getMetaInfo() self.getPlayerInfo() self.getTeamInfo() self.outputJSON()
def analyze_replay_file(replay_path: str, output_path: str, overwrite=True, controls: ControlsCreator = None, sanity_check: SanityChecker = 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) :return: AnalysisManager of game with analysis. """ _json = decompile_replay(replay_path, output_path, overwrite=overwrite) game = Game(loaded_json=_json) # get_controls(game) # TODO: enable and optimise. if controls is not None: controls.get_controls(game) if sanity_check is not None: sanity_check.check_game(game) analysis = AnalysisManager(game) analysis.create_analysis() return analysis
def write_replay_to_disk(analysis_manager: AnalysisManager, parsed_data_path: str): # Temp write file to the original filename location if not os.path.isdir(os.path.dirname(parsed_data_path)): os.makedirs(os.path.dirname(parsed_data_path)) with open(parsed_data_path + '.pts', 'wb') as fo: analysis_manager.write_proto_out_to_file(fo) with gzip.open(parsed_data_path + '.gzip', 'wb') as fo: analysis_manager.write_pandas_out_to_file(fo)
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 = [] total = 0 duplicates = 0 previous_frame = None 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"] = [ velocity_scaler(NaN_fixer(row["ball"]["vel_x"])), velocity_scaler(NaN_fixer(row["ball"]["vel_y"])), velocity_scaler(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)) if previous_frame != None: if duplicateFrameCheck(frame, previous_frame): total += 1 duplicates += 1 continue previous_frame = frame frames.append(frame) total += 1 return frames
def test(analysis: AnalysisManager): assert (analysis.get_protobuf_data() is not None) assert (not analysis.get_protobuf_data().game_metadata.is_invalid_analysis) for player in analysis.get_protobuf_data().players: ratio = (player.stats.positional_tendencies.time_in_front_ball + player.stats.positional_tendencies.time_behind_ball) / player.time_in_game assert (ratio > 0.99) assert (player.stats.positional_tendencies.time_in_front_ball > 0) assert (player.stats.positional_tendencies.time_behind_ball > 0) assert (player.time_in_game > 0) assert (player.stats.speed.time_at_slow_speed > 0) assert (player.stats.boost.average_boost_level > 0)
def test(analysis: AnalysisManager): local.assertIsNotNone(analysis.get_protobuf_data()) local.assertEqual(False, analysis.get_protobuf_data().game_metadata.is_invalid_analysis) for player in analysis.get_protobuf_data().players: ratio = (player.stats.positional_tendencies.time_in_front_ball + player.stats.positional_tendencies.time_behind_ball) / player.time_in_game local.assertEqual(True, ratio > 0.99) local.assertGreater(player.stats.positional_tendencies.time_in_front_ball, 0) local.assertGreater(player.stats.positional_tendencies.time_behind_ball, 0) local.assertGreater(player.time_in_game, 0) local.assertGreater(player.stats.speed.time_at_slow_speed, 0) local.assertGreater(player.stats.boost.average_boost_level, 0)
def convert_replay(replay_path: str, out_folder: str) -> Dict: ''' Parses the replay file intro proto and pandas. Returns a dictionary with keys ['proto', 'pandas'] with the paths to each file. ''' id = os.path.splitext(os.path.basename(replay_path))[0] proto_path = os.path.join(out_folder, '{}.pts'.format(id)) pandas_path = os.path.join(out_folder, '{}.gzip'.format(id)) temp_path = tempfile.mktemp(suffix='.json') _json = carball.decompile_replay(replay_path, temp_path) game = Game() game.initialize(loaded_json=_json) analysis = AnalysisManager(game) analysis.create_analysis() with open(proto_path, 'wb') as f: analysis.write_proto_out_to_file(f) with open(pandas_path, 'wb') as f: analysis.write_pandas_out_to_file(f) return {'proto': proto_path, 'pandas': pandas_path}
def test(analysis: AnalysisManager): assert (analysis.get_protobuf_data() is not None) assert(not analysis.get_protobuf_data().game_metadata.is_invalid_analysis) for player in analysis.get_protobuf_data().players: ratio = (player.stats.positional_tendencies.time_in_front_ball + player.stats.positional_tendencies.time_behind_ball) / player.time_in_game assert ratio > 0.99 # local.assertGreater(player.stats.positional_tendencies.time_in_front_ball, 0) # local.assertGreater(player.stats.positional_tendencies.time_behind_ball, 0) assert (player.time_in_game > 0) assert(player.stats.speed.time_at_slow_speed > 0) assert(player.stats.boost.average_boost_level > 0) assert(player.stats.boost.wasted_collection > -1) json = analysis.get_json_data() assert len(json['players']) > 0
def test(analysis: AnalysisManager): proto_game = analysis.get_protobuf_data() assert proto_game.game_metadata.goals[0].extra_mode_info.pre_items assert not proto_game.game_metadata.goals[ 1].extra_mode_info.pre_items assert proto_game.game_metadata.goals[2].extra_mode_info.pre_items
def test(analysis: AnalysisManager): proto_game = analysis.get_protobuf_data() assertions = unittest.TestCase('__init__') dropshot_ball_proto = proto_game.game_stats.ball_stats.extra_mode assert dropshot_ball_proto.dropshot_phase_stats[0].phase == 0 assertions.assertAlmostEqual( dropshot_ball_proto.dropshot_phase_stats[0].average, 3.72452275, 5) assertions.assertAlmostEqual( dropshot_ball_proto.dropshot_phase_stats[0].max, 6.9999535, 5) assertions.assertAlmostEqual( dropshot_ball_proto.dropshot_phase_stats[0].total, 7.4490455, 5) assert dropshot_ball_proto.dropshot_phase_stats[1].phase == 1 assertions.assertAlmostEqual( dropshot_ball_proto.dropshot_phase_stats[1].average, 0.1, 5) assertions.assertAlmostEqual( dropshot_ball_proto.dropshot_phase_stats[1].max, 0.1, 5) assertions.assertAlmostEqual( dropshot_ball_proto.dropshot_phase_stats[1].total, 0.1, 5) assert dropshot_ball_proto.dropshot_phase_stats[2].phase == 2 assert dropshot_ball_proto.dropshot_phase_stats[2].average == 0 assert dropshot_ball_proto.dropshot_phase_stats[2].max == 0 assert dropshot_ball_proto.dropshot_phase_stats[2].total == 0 game_dropshot_stats = proto_game.game_stats.dropshot_stats assert len(game_dropshot_stats.damage_events[0].tiles) == 7
def test(analysis: AnalysisManager, boost_value): proto_game = analysis.get_protobuf_data() for index, player in enumerate(proto_game.players): boost = player.stats.boost case.assertAlmostEqual(boost.wasted_collection, boost_value[index], delta=2)
def test(analysis: AnalysisManager): proto_game = analysis.get_protobuf_data() player = proto_game.players[0] boost = player.stats.boost self.assertEqual(boost.num_large_boosts, 1) print(analysis)
def test(analysis: AnalysisManager, boost_value): proto_game = analysis.get_protobuf_data() player = proto_game.players[0] boost = player.stats.boost self.assertAlmostEqual(boost.boost_usage, boost_value, delta=9) # TODO: Figgure out a way to calculate boost in a more accurate manner print(analysis)
def test(analysis: AnalysisManager): proto_game = analysis.get_protobuf_data() kickoffs = proto_game.game_stats.kickoffs assert (len(kickoffs) == 6) first_player = proto_game.players[0].stats kickoff_stats = first_player.kickoff_stats assert kickoff_stats.num_time_first_touch == 1 assert kickoff_stats.num_time_go_to_ball == 1 assert kickoff_stats.num_time_boost == 1 assert kickoff_stats.num_time_cheat == 0 assert kickoff_stats.num_time_defend == 1 assert kickoff_stats.num_time_afk == 1 assert kickoff_stats.total_kickoffs == 6 assert 2 == ( kickoff_stats.total_kickoffs - (kickoff_stats.num_time_go_to_ball + kickoff_stats.num_time_boost + kickoff_stats.num_time_cheat + kickoff_stats.num_time_defend + kickoff_stats.num_time_afk)) second_player_stats = proto_game.players[1].stats.kickoff_stats assert second_player_stats.num_time_first_touch == 5 assert second_player_stats.num_time_go_to_ball == 6 for i in range(len(kickoffs)): kickoff = proto_game.game_stats.kickoff_stats[i] player = kickoff.touch.players[0] start_left = player.start_position.pos_x < 0 assert player.start_left == start_left
def test(analysis: AnalysisManager, boost_value): proto_game = analysis.get_protobuf_data() player = proto_game.players[0] boost = player.stats.boost print("Predicted usage: {}, actual: {}".format( boost.boost_usage, boost_value)) case.assertAlmostEqual(boost.boost_usage, boost_value, delta=1)
def test(analysis: AnalysisManager): proto_game = analysis.get_protobuf_data() fifties = proto_game.game_stats.fifty_fifties # Tuples are (starting frame, ending frame, # hits, # unique players) expected_tuples = [ (173, 177, 4, 2), (259, 261, 2, 2), (539, 540, 2, 2), (1212, 1214, 2, 2), (1676, 1679, 2, 2), (2261, 2265, 3, 2), (2634, 2636, 2, 2), (3172, 3174, 3, 2), (4132, 4134, 2, 2), (4774, 4776, 2, 2), (5124, 5127, 2, 2), (5224, 5226, 2, 2), (6260, 6262, 2, 2), (7495, 7496, 2, 2), (7916, 7921, 3, 2), (8203, 8207, 2, 2), (8855, 8857, 3, 2), (8906, 8909, 2, 2), (9291, 9294, 3, 2), (10257, 10259, 2, 2), ] assert (len(fifties) == len(expected_tuples)) for i in range(len(fifties)): fifty = fifties[i] fifty_tuple = (fifty.starting_frame, fifty.ending_frame, len(fifty.hits), len(fifty.players)) assert (fifty_tuple == expected_tuples[i])
def test(analysis: AnalysisManager, boost_value): proto_game = analysis.get_protobuf_data() player = proto_game.players[0] boost = player.stats.boost print("Predicted usage: {}, actual: {}".format( boost.boost_usage, boost_value)) assertNearlyEqual(case, boost.boost_usage, boost_value, percent=3)
def test(analysis: AnalysisManager, answer): proto_game = analysis.get_protobuf_data() hits = proto_game.game_stats.hits clear_counter = 0 for hit in hits: if hit.clear: clear_counter += 1
def test(analysis: AnalysisManager, boost_value): proto_game = analysis.get_protobuf_data() player = proto_game.players[0] boost = player.stats.boost self.assertEqual(boost.boost_usage, boost_value) print(analysis)
def test(analysis: AnalysisManager, dribbles, flicks): proto_game = analysis.get_protobuf_data() carries = proto_game.game_stats.ball_carries assert (len(carries) > 0) player = proto_game.players[0] assert (player.stats.ball_carries.total_carries == dribbles) assert (player.stats.ball_carries.total_flicks == flicks) assert (player.stats.ball_carries.total_carry_time > 0)
def test(analysis: AnalysisManager): proto_game = analysis.get_protobuf_data() player = proto_game.players[0] print(player) percent = 6 assert player.stats.ball_carries.total_carry_time == pytest.approx( 196, percent / 100)
def test(analysis: AnalysisManager): proto_game = analysis.get_protobuf_data() kickoffs = proto_game.game_stats.kickoffs assert (len(kickoffs) == 0) first_player = proto_game.players[0].stats kickoff_stats = first_player.kickoff_stats assert kickoff_stats.total_kickoffs == 0
def test(analysis: AnalysisManager, answer): proto_game = analysis.get_protobuf_data() hits = proto_game.game_stats.hits counter = 0 for hit in hits: if hit.save: counter += 1 self.assertEqual(counter, answer)
def test(analysis: AnalysisManager, boost_value): proto_game = analysis.get_protobuf_data() player = proto_game.players[0] boost = player.stats.boost self.assertAlmostEqual(boost.wasted_collection, boost_value, delta=1) # self.assertGreater(boost.average_boost_level, 0) print(analysis)
def test(analysis: AnalysisManager): proto_game = analysis.get_protobuf_data() self.assertTrue( proto_game.game_metadata.goals[0].extra_mode_info.pre_items) self.assertFalse( proto_game.game_metadata.goals[1].extra_mode_info.pre_items) self.assertTrue( proto_game.game_metadata.goals[2].extra_mode_info.pre_items)
def test(analysis: AnalysisManager, answer): proto_game = analysis.get_protobuf_data() hits = proto_game.game_stats.hits aerial_counter = 0 for hit in hits: if hit.aerial: aerial_counter += 1 assert (aerial_counter == answer)
def test(analysis: AnalysisManager): proto_game = analysis.get_protobuf_data() assert proto_game.game_metadata.goals[ 0].extra_mode_info.dropshot_tile.id == 89 assert proto_game.game_metadata.goals[ 0].extra_mode_info.phase_1_tiles == 0 assert proto_game.game_metadata.goals[ 0].extra_mode_info.phase_2_tiles == 1
def test(analysis: AnalysisManager, boost_value): proto_game = analysis.get_protobuf_data() for index, player in enumerate(proto_game.players): wasted_answer = boost_value[index] total_wasted = (wasted_answer[0] - (255 - wasted_answer[1])) / 256.0 * 100.0 boost = player.stats.boost case.assertAlmostEqual(boost.wasted_collection, total_wasted, delta=2)
def test(analysis: AnalysisManager): proto_game = analysis.get_protobuf_data() self.assertNotEqual( proto_game.game_stats.rumble_items[1].frame_number_use, -1) freeze_stats = next( filter(lambda x: x.item == BALL_FREEZE, proto_game.players[0].stats.rumble_stats.rumble_items)) self.assertEqual(freeze_stats.used, 1)