예제 #1
0
파일: server.py 프로젝트: elmerfud/StarryPy
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()
        self.plugin_manager.activate_plugins()

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

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

        :param text: Message text
        :param channel: Channel to broadcast on. 0 is global, 1 is planet.
        :param world: World
        :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.", exc_info=True)

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

        :rtype : Protocol
        """
        logger.debug("Building protocol to address %s", address)
        p = ServerFactory.buildProtocol(self, address)
        return p
예제 #2
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 = {}
        try:
            self.plugin_manager = PluginManager(factory=self)
        except FatalPluginError:
            logger.critical("Shutting Down.")
            sys.exit()
        self.reaper = LoopingCall(self.reap_dead_protocols)
        self.reaper.start(self.config.reap_time)

    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, channel=1, world='', name=''):
        """
        Convenience method to send a broadcasted message to all clients on the
        server.

        :param text: Message text
        :param channel: Channel to broadcast on. 0 is global, 1 is planet.
        :param world: World
        :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 prepanded 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
        """
        p = ServerFactory.buildProtocol(self, address)
        return p

    def reap_dead_protocols(self):
        count = 0
        start_time = datetime.datetime.now()
        for protocol in self.protocols.itervalues():
            if (
                    protocol.packet_stream.last_received_timestamp - start_time).total_seconds() > self.config.reap_time:
                protocol.connectionLost()
                count += 1
                continue
            if protocol.client_protocol is not None and (
                    protocol.client_protocol.packet_stream.last_received_timestamp - start_time).total_seconds() > self.config.reap_time:
                protocol.connectionLost()
                count += 1
        if count == 1:
            logger.info("1 connection reaped.")
        elif count > 1:
            logger.info("%d connections reaped.")
예제 #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.')
예제 #4
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 = {}
        try:
            self.plugin_manager = PluginManager(factory=self)
        except FatalPluginError:
            logger.critical("Shutting Down.")
            sys.exit()
        self.reaper = LoopingCall(self.reap_dead_protocols)
        self.reaper.start(self.config.reap_time)

    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, channel=1, world='', name=''):
        """
        Convenience method to send a broadcasted message to all clients on the
        server.

        :param text: Message text
        :param channel: Channel to broadcast on. 0 is global, 1 is planet.
        :param world: World
        :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 prepanded 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
        """
        p = ServerFactory.buildProtocol(self, address)
        return p

    def reap_dead_protocols(self):
        count = 0
        start_time = datetime.datetime.now()
        for protocol in self.protocols.itervalues():
            if (protocol.packet_stream.last_received_timestamp -
                    start_time).total_seconds() > self.config.reap_time:
                protocol.connectionLost()
                count += 1
                continue
            if protocol.client_protocol is not None and (
                    protocol.client_protocol.packet_stream.
                    last_received_timestamp -
                    start_time).total_seconds() > self.config.reap_time:
                protocol.connectionLost()
                count += 1
        if count == 1:
            logger.info("1 connection reaped.")
        elif count > 1:
            logger.info("%d connections reaped.")
예제 #5
0
 def change(newname):
     ConfigurationManager.save('prefix', '/opt/' + newname)