def get_game(replay_path): stdout = get_stdout(['--initdata', '--json', replay_path]) stdout.next() init = json.loads(stdout.next()) game_mode = init['m_syncLobbyState']['m_gameDescription']['m_gameOptions'][ 'm_ammId'] if game_mode != game_modes.storm_league: return None archive = mpyq.MPQArchive(replay_path) lobby = archive.read_file('replay.server.battlelobby') stdout = get_stdout(['--details', '--json', replay_path]) details = json.loads(stdout.next()) players = [ Player( name=d['m_name'], hero=d['m_hero'], team=d['m_teamId'], party=get_party(lobby, d['m_name']), did_win=d['m_result'] == 1, ) for d in details['m_playerList'] ] (map, started_at) = get_map_and_datetime(replay_path) if started_at is None: started_at = get_creation_time(replay_path) return SerializedGame(players=players, map=map, started_at=started_at)
def read_replay(replay_file): #TODO: player match stats - df with end of match statistics for each player for each match archive = mpyq.MPQArchive(replay_file) # Read the protocol header, this can be read with any protocol contents = archive.header['user_data_header']['content'] header = protocol29406.decode_replay_header(contents) baseBuild = header['m_version']['m_baseBuild'] if baseBuild < 43905: raise NotImplementedError("File too old, build: {}".format(baseBuild)) try: protocol = importlib.import_module('heroprotocol.protocol%s' % (baseBuild,)) #protocol = __import__('heroprotocol.protocol%s' % (baseBuild,)) except ImportError: print 'Unsupported base build: %d' % baseBuild #initdata contents = archive.read_file('replay.initData') initdata = protocol.decode_replay_initdata(contents) game_mode, random_seed = read_initdata(initdata) assert game_mode != "Versus AI" and game_mode != "Brawl", "AI matches and brawls not supported" #details contents = archive.read_file('replay.details') details = protocol.decode_replay_details(contents) matchTimeLocal, matchTimeUTC, map_title, players = read_details(details) #tracker events contents = archive.read_file('replay.tracker.events') tracker_events = protocol.decode_replay_tracker_events(contents) player_inits, xp_stats, deaths, structure_deaths = read_tracker_events(tracker_events) players = pd.merge(pd.DataFrame(players), pd.DataFrame(player_inits), on = "ToonHandle") matchId = "".join(map(str, sorted(players["BattleNetId"]))) + str(random_seed) #TODO: Make sure that this is hotsapi compatible matchId = str(uuid.uuid3(uuid.NAMESPACE_OID, matchId))#hashlib.md5(matchId.encode("utf-8"))) players.drop(columns = "BattleNetId", inplace = True) #TODO: find a better way to do this winner = players[players["Result"] == 1]["Team"].iloc[0] match = {"MatchId": matchId, "LocalTime": matchTimeLocal, "UTCTime": matchTimeUTC, "Map": map_title, "Mode": game_mode, "Winner": winner} xp_stats = pd.DataFrame(xp_stats) deaths = pd.DataFrame(deaths) return players, match, xp_stats, deaths, structure_deaths
def read_and_decode(filename, do_attributes=1, do_initdata=1): global initdata, details, attributes, lobby_data archive = mpyq.MPQArchive(filename) header = protocol29406.decode_replay_header( archive.header['user_data_header']['content']) baseBuild = header['m_version']['m_baseBuild'] protocol = import_module('heroprotocol.protocol%s' % baseBuild, ) details = protocol.decode_replay_details( archive.read_file('replay.details')) lobby_data = archive.read_file( 'replay.server.battlelobby') #loby_data is not decoded file content if do_initdata: # for game type initdata = protocol.decode_replay_initdata( archive.read_file('replay.initData')) if do_attributes: # for hero level attributes = protocol.decode_replay_attributes_events( archive.read_file('replay.attributes.events'))
import heroprotocol, sys, os, os.path, pprint from heroprotocol.mpyq import mpyq sys.path.append(os.path.join(os.getcwd(), "heroprotocol")) from heroprotocol import protocol29406 archive = mpyq.MPQArchive(sys.argv[-1]) contents = archive.header['user_data_header']['content'] header = protocol29406.decode_replay_header(contents) baseBuild = header['m_version']['m_baseBuild'] try: protocol = __import__('protocol%s' % (baseBuild,)) except: print >> sys.stderr, 'Unsupported base build: %d' % baseBuild sys.exit(1) message_events = protocol.decode_replay_message_events(archive.read_file('replay.message.events')) for message in message_events: if 'm_string' in message: print(message['m_string'])
parser.add_argument("--header", help="print protocol header", action="store_true") parser.add_argument("--details", help="print protocol details", action="store_true") parser.add_argument("--initdata", help="print protocol initdata", action="store_true") parser.add_argument("--stats", help="print stats", action="store_true") parser.add_argument("--json", help="protocol information is printed in json format.", action="store_true") args = parser.parse_args() archive = mpyq.MPQArchive(args.replay_file) logger = EventLogger() logger.args = args # Read the protocol header, this can be read with any protocol contents = archive.header['user_data_header']['content'] header = protocol29406.decode_replay_header(contents) if args.header: logger.log(sys.stdout, header) # The header's baseBuild determines which protocol to use baseBuild = header['m_version']['m_baseBuild'] try: protocolVersion = 'protocol%s' % (baseBuild, ) _temp = __import__('heroprotocol', globals(), locals(),
help='Name of the Team 2', default=None) parser.add_argument('-e', '--event', help='Name of the eSport event', default=None) parser.add_argument('-s', '--stage', help='Stage of the event', default=None) args = parser.parse_args() print "Processing: %s" % (args.replay_path) replayData = None replay = mpyq.MPQArchive(args.replay_path) replayData = processEvents(protocol, replay, args.team1, args.team2, args.event, args.stage) if (args.output_dir): if not path.exists( args.output_dir): # check if the provided path exists print 'Error - Path %s does not exist' % (args.output_dir) exit(0) output_path = args.output_dir else: # If the parameter is not provided then assume the output is the same folder this script resides output_path = path.dirname(path.abspath(__file__)) if (args.dump_all):