def test_prepare(
        self, mock_config, mock_path, mock_sys, mock_load_plugins
    ):
        mock_factory = Mock()

        mock_path.child.return_value = Mock(path='test child')
        mock_config.return_value = Mock(
            plugin_path='test path',
            config={
                'initial_plugins': 'test initial plugins'
            }
        )

        pm = PluginManager(mock_factory)
        pm.prepare()

        mock_path.child.assert_called_with('test path')
        mock_sys.path.append.assert_called_with('test child')
        self.assertEqual(mock_load_plugins.call_count, 2)
        mock_load_plugins.assert_has_calls(
            [
                call(
                    [
                        'core.admin_commands_plugin',
                        'core.colored_names',
                        'core.command_plugin',
                        'core.player_manager_plugin',
                        'core.starbound_config_manager'
                    ]
                ),
                call('test initial plugins')
            ]
        )
Beispiel #2
0
    def test_prepare(self, mock_config, mock_path, mock_sys,
                     mock_load_plugins):
        mock_factory = Mock()

        mock_path.child.return_value = Mock(path='test child')
        mock_config.return_value = Mock(
            plugin_path='test path',
            config={'initial_plugins': 'test initial plugins'})

        pm = PluginManager(mock_factory)
        pm.prepare()

        mock_path.child.assert_called_with('test path')
        mock_sys.path.append.assert_called_with('test child')
        self.assertEqual(mock_load_plugins.call_count, 2)
        mock_load_plugins.assert_has_calls([
            call([
                'core.admin_commands_plugin', 'core.colored_names',
                'core.command_plugin', 'core.player_manager_plugin',
                'core.starbound_config_manager'
            ]),
            call('test initial plugins')
        ])
Beispiel #3
0
class StarryPyServerFactory(ServerFactory):
    """
    Factory which creates `StarryPyServerProtocol` instances.
    """
    protocol = StarryPyServerProtocol

    def __init__(self):
        """
        Initializes persistent objects and prepares a list of connected
        protocols.
        """
        self.config = ConfigurationManager()
        self.protocol.factory = self
        self.protocols = {}
        self.plugin_manager = PluginManager(factory=self)
        try:
            self.plugin_manager.prepare()
        except FatalPluginError:
            logger.critical('Shutting Down.')
            sys.exit()
        self.reaper = LoopingCall(self.reap_dead_protocols)
        self.reaper.start(self.config.reap_time)
        logger.debug(
            'Factory created, endpoint of port %d', self.config.bind_port
        )

    def stopFactory(self):
        """
        Called when the factory is stopped. Saves the configuration.
        :return: None
        """

        self.config.save()
        self.plugin_manager.die()

    def broadcast(self, text, name=''):
        """
        Convenience method to send a broadcasted message to all clients on the
        server.

        :param text: Message text
        :param name: The name to prepend before the message, format is <name>
        :return: None
        """
        for p in self.protocols.itervalues():
            try:
                p.send_chat_message(text)
            except:
                logger.exception('Exception in broadcast.')

    def broadcast_planet(self, text, planet, name=''):
        """
        Convenience method to send a broadcasted message to all clients on the
        current planet (and ships orbiting it).

        :param text: Message text
        :param planet: The planet to send the message to
        :param name: The name to prepend before the message, format is <name>,
         not prepended when empty
        :return: None
        """
        for p in self.protocols.itervalues():
            if p.player.planet == planet:
                try:
                    p.send_chat_message(text)
                except:
                    logger.exception('Exception in broadcast.')

    def buildProtocol(self, address):
        """
        Builds the protocol to a given address.

        :rtype : Protocol
        """
        logger.vdebug('Building protocol to address %s', address)
        p = ServerFactory.buildProtocol(self, address)
        return p

    def reap_dead_protocols(self):
        logger.vdebug('Reaping dead connections.')
        count = 0
        start_time = datetime.datetime.now()
        for protocol in self.protocols.itervalues():
            total_seconds = (
                protocol
                .client_protocol
                .packet_stream
                .last_received_timestamp -
                start_time
            ).total_seconds()
            if total_seconds > self.config.reap_time:
                logger.debug(
                    'Reaping protocol %s. Reason: Server protocol timeout.',
                    protocol.id
                )
                protocol.connectionLost()
                count += 1
                continue
            if (
                    protocol.client_protocol is not None and
                    total_seconds > self.config.reap_time
            ):
                protocol.connectionLost()
                logger.debug(
                    'Reaping protocol %s. Reason: Client protocol timeout.',
                    protocol.id
                )
                count += 1
        if count == 1:
            logger.info('1 connection reaped.')
        elif count > 1:
            logger.info('%d connections reaped.')
        else:
            logger.vdebug('No connections reaped.')