Esempio n. 1
0
        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
Esempio n. 2
0
        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
Esempio n. 3
0
    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()