def createPlayer(pid, pdata, attributes): # make sure to strip the clan tag out of the name # in newer replays, the clan tag can be separated from the # player name with a <sp/> symbol. It should also be stripped. name = pdata.name.split("]", 1)[-1].split(">", 1)[-1] player = Player(pid, name) # In some beta patches attribute information is missing # Just assign them to team 2 to keep the issue from being fatal team_number = int(attributes.get('Teams'+self.type, "Team 2")[5:]) # team_number = pdata.team+1 if not team_number in self.team: self.team[team_number] = Team(team_number) self.teams.append(self.team[team_number]) # Maintain order in case people depended on it self.teams.sort(key=lambda t: t.number) self.team[team_number].players.append(player) player.team = self.team[team_number] # Do basic win/loss processing from details data if pdata.result == 1: player.team.result = "Win" self.winner = player.team elif pdata.result == 2: player.team.result = "Loss" else: player.team.result = None player.pick_race = attributes.get('Race','Unknown') player.play_race = LOCALIZED_RACES.get(pdata.race, pdata.race) player.difficulty = attributes.get('Difficulty','Unknown') player.is_human = (attributes.get('Controller','Computer') == 'User') player.uid = pdata.bnet.uid player.subregion = pdata.bnet.subregion player.gateway = GATEWAY_LOOKUP[pdata.bnet.gateway] player.handicap = pdata.handicap player.color = utils.Color(**pdata.color._asdict()) return player
def createPlayer(pid, pdata, attributes): # make sure to strip the clan tag out of the name # in newer replays, the clan tag can be separated from the # player name with a <sp/> symbol. It should also be stripped. name = pdata.name.split("]", 1)[-1].split(">", 1)[-1] player = Player(pid, name) # In some beta patches attribute information is missing # Just assign them to team 2 to keep the issue from being fatal team_number = int( attributes.get('Teams' + self.type, "Team 2")[5:]) if not team_number in self.team: self.team[team_number] = Team(team_number) self.teams.append(self.team[team_number]) self.team[team_number].players.append(player) player.team = self.team[team_number] # Do basic win/loss processing from details data if pdata.result == 1: player.team.result = "Win" self.winner = player.team elif pdata.result == 2: player.team.result = "Loss" else: player.team.result = None player.pick_race = attributes.get('Race', 'Unknown') player.play_race = LOCALIZED_RACES.get(pdata.race, pdata.race) player.difficulty = attributes.get('Difficulty', 'Unknown') player.is_human = (attributes.get('Controller', 'Computer') == 'User') player.uid = pdata.bnet.uid player.subregion = pdata.bnet.subregion player.gateway = GATEWAY_LOOKUP[pdata.bnet.gateway] player.handicap = pdata.handicap player.color = utils.Color(**pdata.color._asdict()) return player
def load_players(self): #If we don't at least have details and attributes_events we can go no further if 'replay.details' not in self.raw_data: return if 'replay.attributes.events' not in self.raw_data: return # Create and add the players based on attribute and details information player_index, obs_index, default_region = 0, 1, '' player_data = self.raw_data['replay.details'].players for pid, attributes in sorted(self.attributes.iteritems()): # We've already processed the global attributes if pid == 16: continue # Open Slots are skipped because it doesn't seem useful to store # an "Open" player to fill a spot that would otherwise be empty. if attributes['Player Type'] == 'Open': continue # Get the player data from the details file, increment the index to # Keep track of which player we are processing pdata = player_data[player_index] player_index += 1 # If this is a human player, push back the initial observer index in # the list of all human players we gathered from the initdata file. if attributes['Player Type'] == 'Human': obs_index += 1 # Create the player using the current pid and the player name from # The details file. This works because players are stored in order # of pid inside of the details file. Attributes and Details must be # processed together because Details doesn't index players by or # store their player ids; Attributes can provide that information # and allow for accurate pid mapping even with computers, observers, # and open open slots. # # General information re: each player comes from the following files # * replay.initData # * replay.details # * replay.attribute.events # # TODO: recognize current locale and use that instead of western # TODO: fill in the LOCALIZED_RACES table player = Player(pid,pdata.name) # Cross reference the player and team lookups team_number = attributes['Teams'+self.type] if not team_number in self.team: self.team[team_number] = Team(team_number) self.teams.append(self.team[team_number]) self.team[team_number].players.append(player) player.team = self.team[team_number] # Do basic win/loss processing from details data if pdata.result == 1: player.team.result = "Win" self.winner = player.team elif pdata.result == 2: player.team.result = "Loss" player.pick_race = attributes['Race'] player.play_race = LOCALIZED_RACES.get(pdata.race, pdata.race) player.difficulty = attributes['Difficulty'] player.is_human = (attributes['Player Type'] == 'Human') player.uid = pdata.bnet.uid player.subregion = pdata.bnet.subregion player.handicap = pdata.handicap # We need initData for the gateway portion of the url! if 'replay.initData' in self.raw_data and self.gateway: player.gateway = self.gateway if player.is_human and player.subregion: player.region = REGIONS[self.gateway][player.subregion] default_region = player.region # Conversion instructions to the new color object: # color_rgba is the color object itself # color_hex is color.hex # color is str(color) player.color = utils.Color(**pdata.color._asdict()) # Each player can be referenced in a number of different ways, # primarily for convenience of access in any given situation. self.people.append(player) self.players.append(player) self.player[pid] = player self.person[pid] = player #Create an store an ordered lineup string for team in self.teams: team.lineup = sorted(player.play_race[0].upper() for player in team) if 'replay.initData' in self.raw_data: # Assign the default region to computer players for consistency # We know there will be a default region because there must be # at least 1 human player or we wouldn't have a self. for player in self.players: if not player.is_human: player.region = default_region # Create observers out of the leftover names gathered from initData all_players = [p.name for p in self.players] all_people = self.raw_data['replay.initData'].player_names for obs_name in all_people: if obs_name in all_players: continue observer = Observer(obs_index,obs_name) observer.gateway = self.gateway self.observers.append(observer) self.people.append(observer) self.person[obs_index] = observer obs_index += 1 # Miscellaneous people processing self.humans = filter(lambda p: p.is_human, self.people) if 'replay.message.events' in self.raw_data: # Figure out recorder self.packets = self.raw_data['replay.message.events'].packets packet_senders = map(lambda p: p.pid, self.packets) human_pids = map(lambda p: p.pid, self.humans) recorders = list(set(human_pids) - set(packet_senders)) if len(recorders) == 1: self.recorder = self.person[recorders[0]] self.recorder.recorder = True else: raise ValueError("Get Recorder algorithm is broken!") player_names = sorted(map(lambda p: p.name, self.people)) hash_input = self.gateway+":"+','.join(player_names) self.people_hash = hashlib.sha256(hash_input).hexdigest()