Example #1
0
 def get_map(self):
     """Get map."""
     if not self._cache['map']:
         self._cache['map'], self._cache['encoding'], self._cache[
             'language'] = get_map_data(
                 self._header.scenario.game_settings.map_id,
                 self._header.scenario.messages.instructions,
                 self._header.map_info.size_x, self._header.de is not None,
                 self._header.map_info.tile)
     return self._cache['map']
Example #2
0
 def get_map(self):
     """Get map."""
     if not self._cache['map']:
         self._cache['map'], self._cache['encoding'], self._cache['language'] = get_map_data(
             self._header.scenario.game_settings.map_id,
             self._header.scenario.messages.instructions,
             self._header.map_info.size_x,
             self._header.version,
             self.get_dataset()['id'],
             self._header.map_info.tile,
             de_seed=self._header.lobby.de.map_seed if self._header.lobby.de else None
         )
     return self._cache['map']
Example #3
0
 def get_map(self):
     """Get map."""
     tiles = tiles = [(tile.terrain_type, tile.elevation)
                      for tile in self._header.map_info.tile]
     if not self._cache['map']:
         self._cache['map'], self._cache['encoding'], self._cache[
             'language'] = get_map_data(
                 self._header.scenario.game_settings.map_id,
                 self._header.scenario.messages.instructions,
                 self._header.map_info.size_x,
                 self._header.version,
                 self.get_dataset()['id'],
                 self.reference,
                 tiles,
                 de_seed=self._header.lobby.de.map_seed
                 if self._header.lobby.de else None)
     return self._cache['map']
Example #4
0
def parse_match(handle):
    """Parse a match.

    This is one big function because the dependency graph between
    the variables is dense.
    """

    data = parse(handle)
    consts = get_consts()

    dataset_id, dataset = get_dataset(data['version'], data['mod'])
    # self._header.hd.selected_map_id if self._header.hd else self._header.scenario.game_settings.map_id
    map_data, encoding, language = get_map_data(
        data['hd']['map_id']
        if data['version'] is Version.HD else data['scenario']['map_id'],
        data['scenario']['instructions'],
        data['map']['dimension'],
        data['version'],
        dataset_id,
        dataset,
        data['map']['tiles'],
        de_seed=data['lobby']['seed'])

    # Handle DE-specific data
    if data['de']:
        de_players = {
            player['number']: player
            for player in data['de']['players']
        }
        lobby = data['de']['lobby']
        guid = data['de']['guid']
    else:
        de_players = dict()
        lobby = None
        guid = None

    # Parse gaia objects
    gaia = [
        Object(dataset['objects'].get(str(obj['object_id'])),
               obj['instance_id'],
               Position(obj['position']['x'], obj['position']['y']))
        for obj in data['players'][0]['objects']
    ]

    inputs = Inputs({o.instance_id: o.name for o in gaia})

    # Parse players
    players = dict()
    allies = dict()
    for player in data['players'][1:]:
        allies[player['number']] = set([player['number']])
        for i, stance in enumerate(player['diplomacy']):
            if stance == 2:
                allies[player['number']].add(i)
        de_player = de_players.get(player['number'])
        if de_player:
            player.update(de_player)
        pos_x = None
        pos_y = None
        for obj in player['objects']:
            if obj['object_id'] in TC_IDS:
                pos_x = obj['position']['x']
                pos_y = obj['position']['y']
        players[player['number']] = Player(
            player['color_id'] + 1, player['name'].decode(encoding),
            consts['player_colors'][str(player['color_id'])],
            dataset['civilizations'][str(player['civilization_id'])]['name'],
            Position(pos_x, pos_y), [
                Object(dataset['objects'].get(str(obj['object_id'])),
                       obj['instance_id'],
                       Position(obj['position']['x'], obj['position']['y']))
                for obj in player['objects']
            ], player.get('profile_id'))

    # Assign teams
    team_ids = set([frozenset(s) for s in allies.values()])
    teams = []
    for team in team_ids:
        t = [players[x] for x in team]
        for x in team:
            players[x].team = t
        teams.append(t)

    # Compute diplomacy
    diplomacy_type = get_diplomacy_type(teams, players)

    # Extract lobby chat
    pd = [dict(name=p.name, number=n) for n, p in players.items()]
    chats = []
    for c in data['lobby']['chat']:
        chat = parse_chat(c, encoding, 0, pd, diplomacy_type, 'lobby')
        if chat['player_number'] not in players:
            continue
        chats.append(
            Chat(timedelta(milliseconds=chat['timestamp']), chat['message'],
                 players[chat['player_number']]))
        inputs.add_chat(chats[-1])

    # Parse player actions
    fast.meta(handle)
    timestamp = 0
    resigned = []
    actions = []
    viewlocks = []
    last_viewlock = None
    while True:
        try:
            op_type, op_data = fast.operation(handle)
            if op_type is fast.Operation.SYNC:
                timestamp += op_data[0]
            elif op_type is fast.Operation.VIEWLOCK:
                if op_data == last_viewlock:
                    continue
                viewlock = Viewlock(timedelta(milliseconds=timestamp),
                                    Position(*op_data),
                                    players[data['metadata']['owner_id']])
                viewlocks.append(viewlock)
                last_viewlock = op_data
            elif op_type is fast.Operation.CHAT:
                chat = parse_chat(op_data, encoding, timestamp, pd,
                                  diplomacy_type, 'game')
                if chat['type'] == ChatEnum.MESSAGE:
                    chats.append(
                        Chat(timedelta(milliseconds=chat['timestamp']),
                             chat['message'], players[chat['player_number']]))
                    inputs.add_chat(chats[-1])
            elif op_type is fast.Operation.ACTION:
                action_type, action_data = op_data
                action = Action(timedelta(milliseconds=timestamp), action_type,
                                action_data)
                if action_type is fast.Action.RESIGN:
                    resigned.append(players[action_data['player_id']])
                if 'player_id' in action_data:
                    action.player = players[action_data['player_id']]
                    del action.payload['player_id']
                enrich_action(action, action_data, dataset, consts)
                actions.append(action)
                inputs.add_action(action)
        except EOFError:
            break

    # Compute winner(s)
    for team in teams:
        winner = not any([player for player in team if player in resigned])
        for player in team:
            player.winner = winner

    return Match(
        list(players.values()), teams, gaia,
        Map(map_data['name'], map_data['dimension'],
            consts['map_sizes'][str(map_data['dimension'])],
            map_data['custom'], map_data['seed'], [
                Tile(tile['terrain_id'], tile['elevation'],
                     Position(tile['x'], tile['y']))
                for tile in map_data['tiles']
            ]),
        File(codecs.lookup(encoding), language,
             players[data['metadata']['owner_id']], viewlocks),
        consts['speeds'][str(int(round(data['metadata']['speed'], 2) * 100))],
        data['metadata']['cheats'], data['lobby']['lock_teams'],
        data['lobby']['population'], chats, guid, lobby,
        dataset['dataset']['name'],
        consts['game_types'][str(data['lobby']['game_type_id'])],
        consts['map_reveal_choices'][str(data['lobby']['reveal_map_id'])],
        timedelta(milliseconds=timestamp), diplomacy_type, data['version'],
        actions, inputs.inputs)