예제 #1
0
파일: server.py 프로젝트: satyaog/diplomacy
    def _process_game(self, server_game):
        """ Process given game and send relevant notifications.

            :param server_game: server game to process
            :return: A boolean indicating if we must stop game.
            :type server_game: ServerGame
        """
        LOGGER.debug('Processing game %s (status %s).', server_game.game_id,
                     server_game.status)
        previous_phase_data, current_phase_data, kicked_powers = server_game.process(
        )
        self.save_game(server_game)

        if previous_phase_data is None and kicked_powers is None:
            # Game must be unscheduled immediately.
            return True

        notifier = Notifier(self)

        if kicked_powers:
            # Game was not processed because of kicked powers.
            # We notify those kicked powers and game must be unscheduled immediately.
            kicked_addresses = [(power_name, token)
                                for (power_name,
                                     tokens) in kicked_powers.items()
                                for token in tokens]
            # Notify kicked players.
            notifier.notify_game_addresses(
                server_game.game_id,
                kicked_addresses,
                notifications.PowersControllers,
                powers=server_game.get_controllers(),
                timestamps=server_game.get_controllers_timestamps())
            return True

        # Game was processed normally.
        # Send game updates to powers, observers and omniscient observers.
        yield notifier.notify_game_processed(server_game, previous_phase_data,
                                             current_phase_data)

        # If game is completed, we must close associated DAIDE port.
        if server_game.is_game_done:
            self.stop_daide_server(server_game.game_id)

        # Game must be stopped if not active.
        return not server_game.is_game_active
예제 #2
0
 def start_game(self, server_game):
     """ Start given server game.
         :param server_game: server game
         :type server_game: ServerGame
     """
     server_game.set_status(strings.ACTIVE)
     self.schedule_game(server_game)
     Notifier(self).notify_game_status(server_game)
예제 #3
0
 def stop_game_if_needed(self, server_game):
     """ Stop game if it has not required number of controlled powers. Notify game if status changed.
         :param server_game: game to check
         :param server_game: game
         :type server_game: ServerGame
     """
     if server_game.is_game_active and (
             server_game.count_controlled_powers() < server_game.get_expected_controls_count()):
         server_game.set_status(strings.FORMING)
         self.unschedule_game(server_game)
         Notifier(self).notify_game_status(server_game)
예제 #4
0
def transfer_special_tokens(server_game,
                            server,
                            username,
                            grade_update,
                            from_observation=True):
    """ Transfer tokens of given username from an observation role to the opposite in given
        server game, and notify all user tokens about observation role update with given grade update.
        This method is used in request manager on_set_grade().

        :param server_game: server game in which tokens roles must be changed.
        :param server: server from which notifications will be sent.
        :param username: name of user whom tokens will be transferred. Only user tokens registered in
            server games as observer tokens or omniscient tokens will be updated.
        :param grade_update: type of upgrading.
            Possibles values in strings.ALL_GRADE_UPDATES (PROMOTE or DEMOTE).
        :param from_observation: indicate transfer direction.
            If True, we expect to transfer role from observer to omniscient.
            If False, we expect to transfer role from omniscient to observer.
        :type server_game: diplomacy.server.server_game.ServerGame
        :type server: diplomacy.Server
    """
    if from_observation:
        old_role = strings.OBSERVER_TYPE
        new_role = strings.OMNISCIENT_TYPE
        token_filter = server_game.has_observer_token
    else:
        old_role = strings.OMNISCIENT_TYPE
        new_role = strings.OBSERVER_TYPE
        token_filter = server_game.has_omniscient_token

    connected_user_tokens = [
        user_token for user_token in server.users.get_tokens(username)
        if token_filter(user_token)
    ]

    if connected_user_tokens:

        # Update observer level for each connected user token.
        for user_token in connected_user_tokens:
            server_game.transfer_special_token(user_token)

        addresses = [(old_role, user_token)
                     for user_token in connected_user_tokens]
        Notifier(server).notify_game_addresses(server_game.game_id,
                                               addresses,
                                               notifications.OmniscientUpdated,
                                               grade_update=grade_update,
                                               game=server_game.cast(
                                                   new_role, username))