Example #1
0
    def update_defaults(self):
        """
        We make sure to store the most important object defaults here, so
        we can catch if they change and update them on-objects automatically.
        This allows for changing default cmdset locations and default
        typeclasses in the settings file and have them auto-update all
        already existing objects.
        """
        # setting names
        settings_names = (
            "CMDSET_CHARACTER",
            "CMDSET_PLAYER",
            "BASE_PLAYER_TYPECLASS",
            "BASE_OBJECT_TYPECLASS",
            "BASE_CHARACTER_TYPECLASS",
            "BASE_ROOM_TYPECLASS",
            "BASE_EXIT_TYPECLASS",
            "BASE_SCRIPT_TYPECLASS",
            "BASE_CHANNEL_TYPECLASS",
        )
        # get previous and current settings so they can be compared
        settings_compare = zip(
            [ServerConfig.objects.conf(name) for name in settings_names],
            [settings.__getattr__(name) for name in settings_names],
        )
        mismatches = [i for i, tup in enumerate(settings_compare) if tup[0] and tup[1] and tup[0] != tup[1]]
        if len(mismatches):  # can't use any() since mismatches may be [0] which reads as False for any()
            # we have a changed default. Import relevant objects and
            # run the update
            from evennia.objects.models import ObjectDB
            from evennia.comms.models import ChannelDB

            # from evennia.players.models import PlayerDB
            for i, prev, curr in ((i, tup[0], tup[1]) for i, tup in enumerate(settings_compare) if i in mismatches):
                # update the database
                print(
                    " %s:\n '%s' changed to '%s'. Updating unchanged entries in database ..."
                    % (settings_names[i], prev, curr)
                )
                if i == 0:
                    ObjectDB.objects.filter(db_cmdset_storage__exact=prev).update(db_cmdset_storage=curr)
                if i == 1:
                    PlayerDB.objects.filter(db_cmdset_storage__exact=prev).update(db_cmdset_storage=curr)
                if i == 2:
                    PlayerDB.objects.filter(db_typeclass_path__exact=prev).update(db_typeclass_path=curr)
                if i in (3, 4, 5, 6):
                    ObjectDB.objects.filter(db_typeclass_path__exact=prev).update(db_typeclass_path=curr)
                if i == 7:
                    ScriptDB.objects.filter(db_typeclass_path__exact=prev).update(db_typeclass_path=curr)
                if i == 8:
                    ChannelDB.objects.filter(db_typeclass_path__exact=prev).update(db_typeclass_path=curr)
                # store the new default and clean caches
                ServerConfig.objects.conf(settings_names[i], curr)
                ObjectDB.flush_instance_cache()
                PlayerDB.flush_instance_cache()
                ScriptDB.flush_instance_cache()
                ChannelDB.flush_instance_cache()
        # if this is the first start we might not have a "previous"
        # setup saved. Store it now.
        [ServerConfig.objects.conf(settings_names[i], tup[1]) for i, tup in enumerate(settings_compare) if not tup[0]]
Example #2
0
    def shutdown(self, mode=None, _reactor_stopping=False):
        """
        Shuts down the server from inside it.

        mode - sets the server restart mode.
               'reload' - server restarts, no "persistent" scripts
                          are stopped, at_reload hooks called.
               'reset' - server restarts, non-persistent scripts stopped,
                         at_shutdown hooks called but sessions will not
                         be disconnected.
               'shutdown' - like reset, but server will not auto-restart.
               None - keep currently set flag from flag file.
        _reactor_stopping - this is set if server is stopped by a kill
                            command OR this method was already called
                             once - in both cases the reactor is
                             dead/stopping already.
        """
        if _reactor_stopping and hasattr(self, "shutdown_complete"):
            # this means we have already passed through this method
            # once; we don't need to run the shutdown procedure again.
            defer.returnValue(None)

        mode = self.set_restart_mode(mode)

        from evennia.objects.models import ObjectDB
        #from evennia.players.models import PlayerDB
        from evennia.server.models import ServerConfig

        if mode == 'reload':
            # call restart hooks
            ServerConfig.objects.conf("server_restart_mode", "reload")
            yield [o.at_server_reload() for o in ObjectDB.get_all_cached_instances()]
            yield [p.at_server_reload() for p in PlayerDB.get_all_cached_instances()]
            yield [(s.pause(manual_pause=False), s.at_server_reload()) for s in ScriptDB.get_all_cached_instances() if s.is_active]
            yield self.sessions.all_sessions_portal_sync()
            self.at_server_reload_stop()
            # only save monitor state on reload, not on shutdown/reset
            from evennia.scripts.monitorhandler import MONITOR_HANDLER
            MONITOR_HANDLER.save()
        else:
            if mode == 'reset':
                # like shutdown but don't unset the is_connected flag and don't disconnect sessions
                yield [o.at_server_shutdown() for o in ObjectDB.get_all_cached_instances()]
                yield [p.at_server_shutdown() for p in PlayerDB.get_all_cached_instances()]
                if self.amp_protocol:
                    yield self.sessions.all_sessions_portal_sync()
            else:  # shutdown
                yield [_SA(p, "is_connected", False) for p in PlayerDB.get_all_cached_instances()]
                yield [o.at_server_shutdown() for o in ObjectDB.get_all_cached_instances()]
                yield [(p.unpuppet_all(), p.at_server_shutdown())
                                       for p in PlayerDB.get_all_cached_instances()]
                yield ObjectDB.objects.clear_all_sessids()
            yield [(s.pause(manual_pause=False), s.at_server_shutdown()) for s in ScriptDB.get_all_cached_instances()]
            ServerConfig.objects.conf("server_restart_mode", "reset")
            self.at_server_cold_stop()

        # tickerhandler state should always be saved.
        from evennia.scripts.tickerhandler import TICKER_HANDLER
        TICKER_HANDLER.save()

        # always called, also for a reload
        self.at_server_stop()

        # if _reactor_stopping is true, reactor does not need to
        # be stopped again.
        if os.name == 'nt' and os.path.exists(SERVER_PIDFILE):
            # for Windows we need to remove pid files manually
            os.remove(SERVER_PIDFILE)
        if not _reactor_stopping:
            # this will also send a reactor.stop signal, so we set a
            # flag to avoid loops.
            self.shutdown_complete = True
            # kill the server
            reactor.callLater(0, reactor.stop)
Example #3
0
 def update_defaults(self):
     """
     We make sure to store the most important object defaults here, so
     we can catch if they change and update them on-objects automatically.
     This allows for changing default cmdset locations and default
     typeclasses in the settings file and have them auto-update all
     already existing objects.
     """
     # setting names
     settings_names = ("CMDSET_CHARACTER", "CMDSET_PLAYER",
                       "BASE_PLAYER_TYPECLASS", "BASE_OBJECT_TYPECLASS",
                       "BASE_CHARACTER_TYPECLASS", "BASE_ROOM_TYPECLASS",
                       "BASE_EXIT_TYPECLASS", "BASE_SCRIPT_TYPECLASS",
                       "BASE_CHANNEL_TYPECLASS")
     # get previous and current settings so they can be compared
     settings_compare = zip(
         [ServerConfig.objects.conf(name) for name in settings_names],
         [settings.__getattr__(name) for name in settings_names])
     mismatches = [
         i for i, tup in enumerate(settings_compare)
         if tup[0] and tup[1] and tup[0] != tup[1]
     ]
     if len(
             mismatches
     ):  # can't use any() since mismatches may be [0] which reads as False for any()
         # we have a changed default. Import relevant objects and
         # run the update
         from evennia.objects.models import ObjectDB
         from evennia.comms.models import ChannelDB
         #from evennia.players.models import PlayerDB
         for i, prev, curr in ((i, tup[0], tup[1])
                               for i, tup in enumerate(settings_compare)
                               if i in mismatches):
             # update the database
             print(
                 " %s:\n '%s' changed to '%s'. Updating unchanged entries in database ..."
                 % (settings_names[i], prev, curr))
             if i == 0:
                 ObjectDB.objects.filter(
                     db_cmdset_storage__exact=prev).update(
                         db_cmdset_storage=curr)
             if i == 1:
                 PlayerDB.objects.filter(
                     db_cmdset_storage__exact=prev).update(
                         db_cmdset_storage=curr)
             if i == 2:
                 PlayerDB.objects.filter(
                     db_typeclass_path__exact=prev).update(
                         db_typeclass_path=curr)
             if i in (3, 4, 5, 6):
                 ObjectDB.objects.filter(
                     db_typeclass_path__exact=prev).update(
                         db_typeclass_path=curr)
             if i == 7:
                 ScriptDB.objects.filter(
                     db_typeclass_path__exact=prev).update(
                         db_typeclass_path=curr)
             if i == 8:
                 ChannelDB.objects.filter(
                     db_typeclass_path__exact=prev).update(
                         db_typeclass_path=curr)
             # store the new default and clean caches
             ServerConfig.objects.conf(settings_names[i], curr)
             ObjectDB.flush_instance_cache()
             PlayerDB.flush_instance_cache()
             ScriptDB.flush_instance_cache()
             ChannelDB.flush_instance_cache()
     # if this is the first start we might not have a "previous"
     # setup saved. Store it now.
     [
         ServerConfig.objects.conf(settings_names[i], tup[1])
         for i, tup in enumerate(settings_compare) if not tup[0]
     ]
Example #4
0
    def shutdown(self, mode=None, _reactor_stopping=False):
        """
        Shuts down the server from inside it.

        mode - sets the server restart mode.
               'reload' - server restarts, no "persistent" scripts
                          are stopped, at_reload hooks called.
               'reset' - server restarts, non-persistent scripts stopped,
                         at_shutdown hooks called but sessions will not
                         be disconnected.
               'shutdown' - like reset, but server will not auto-restart.
               None - keep currently set flag from flag file.
        _reactor_stopping - this is set if server is stopped by a kill
                            command OR this method was already called
                             once - in both cases the reactor is
                             dead/stopping already.
        """
        if _reactor_stopping and hasattr(self, "shutdown_complete"):
            # this means we have already passed through this method
            # once; we don't need to run the shutdown procedure again.
            defer.returnValue(None)

        mode = self.getset_restart_mode(mode)

        from evennia.objects.models import ObjectDB
        #from evennia.players.models import PlayerDB
        from evennia.server.models import ServerConfig
        from evennia.utils import gametime as _GAMETIME_MODULE

        if mode == 'reload':
            # call restart hooks
            ServerConfig.objects.conf("server_restart_mode", "reload")
            yield [
                o.at_server_reload()
                for o in ObjectDB.get_all_cached_instances()
            ]
            yield [
                p.at_server_reload()
                for p in PlayerDB.get_all_cached_instances()
            ]
            yield [(s.pause(manual_pause=False), s.at_server_reload())
                   for s in ScriptDB.get_all_cached_instances() if s.is_active]
            yield self.sessions.all_sessions_portal_sync()
            self.at_server_reload_stop()
            # only save monitor state on reload, not on shutdown/reset
            from evennia.scripts.monitorhandler import MONITOR_HANDLER
            MONITOR_HANDLER.save()
        else:
            if mode == 'reset':
                # like shutdown but don't unset the is_connected flag and don't disconnect sessions
                yield [
                    o.at_server_shutdown()
                    for o in ObjectDB.get_all_cached_instances()
                ]
                yield [
                    p.at_server_shutdown()
                    for p in PlayerDB.get_all_cached_instances()
                ]
                if self.amp_protocol:
                    yield self.sessions.all_sessions_portal_sync()
            else:  # shutdown
                yield [
                    _SA(p, "is_connected", False)
                    for p in PlayerDB.get_all_cached_instances()
                ]
                yield [
                    o.at_server_shutdown()
                    for o in ObjectDB.get_all_cached_instances()
                ]
                yield [(p.unpuppet_all(), p.at_server_shutdown())
                       for p in PlayerDB.get_all_cached_instances()]
                yield ObjectDB.objects.clear_all_sessids()
            yield [(s.pause(manual_pause=False), s.at_server_shutdown())
                   for s in ScriptDB.get_all_cached_instances()]
            ServerConfig.objects.conf("server_restart_mode", "reset")
            self.at_server_cold_stop()

        # tickerhandler state should always be saved.
        from evennia.scripts.tickerhandler import TICKER_HANDLER
        TICKER_HANDLER.save()

        # always called, also for a reload
        self.at_server_stop()

        if os.name == 'nt' and os.path.exists(SERVER_PIDFILE):
            # for Windows we need to remove pid files manually
            os.remove(SERVER_PIDFILE)

        if hasattr(self, "web_root"):  # not set very first start
            yield self.web_root.empty_threadpool()

        if not _reactor_stopping:
            # kill the server
            self.shutdown_complete = True
            reactor.callLater(1, reactor.stop)

        # we make sure the proper gametime is saved as late as possible
        ServerConfig.objects.conf("runtime", _GAMETIME_MODULE.runtime())
Example #5
0
    def shutdown(self, mode=None, _reactor_stopping=False):
        """
        Shuts down the server from inside it.

        mode - sets the server restart mode.
               'reload' - server restarts, no "persistent" scripts
                          are stopped, at_reload hooks called.
               'reset' - server restarts, non-persistent scripts stopped,
                         at_shutdown hooks called but sessions will not
                         be disconnected.
               'shutdown' - like reset, but server will not auto-restart.
               None - keep currently set flag from flag file.
        _reactor_stopping - this is set if server is stopped by a kill
                            command OR this method was already called
                             once - in both cases the reactor is
                             dead/stopping already.
        """
        if _reactor_stopping and hasattr(self, "shutdown_complete"):
            # this means we have already passed through this method
            # once; we don't need to run the shutdown procedure again.
            defer.returnValue(None)

        mode = self.set_restart_mode(mode)

        from evennia.objects.models import ObjectDB
        #from evennia.players.models import PlayerDB
        from evennia.server.models import ServerConfig

        if mode == 'reload':
            # call restart hooks
            ServerConfig.objects.conf("server_restart_mode", "reload")
            yield [
                o.at_server_reload()
                for o in ObjectDB.get_all_cached_instances()
            ]
            yield [
                p.at_server_reload()
                for p in PlayerDB.get_all_cached_instances()
            ]
            yield [(s.pause(), s.at_server_reload())
                   for s in ScriptDB.get_all_cached_instances()]
            yield self.sessions.all_sessions_portal_sync()
            self.at_server_reload_stop()
            # only save OOB state on reload, not on shutdown/reset
            from evennia.server.oobhandler import OOB_HANDLER
            OOB_HANDLER.save()
        else:
            if mode == 'reset':
                # like shutdown but don't unset the is_connected flag and don't disconnect sessions
                yield [
                    o.at_server_shutdown()
                    for o in ObjectDB.get_all_cached_instances()
                ]
                yield [
                    p.at_server_shutdown()
                    for p in PlayerDB.get_all_cached_instances()
                ]
                if self.amp_protocol:
                    yield self.sessions.all_sessions_portal_sync()
            else:  # shutdown
                yield [
                    _SA(p, "is_connected", False)
                    for p in PlayerDB.get_all_cached_instances()
                ]
                yield [
                    o.at_server_shutdown()
                    for o in ObjectDB.get_all_cached_instances()
                ]
                yield [(p.unpuppet_all(), p.at_server_shutdown())
                       for p in PlayerDB.get_all_cached_instances()]
                yield ObjectDB.objects.clear_all_sessids()
            yield [(s.pause(), s.at_server_reload())
                   for s in ScriptDB.get_all_cached_instances()]
            ServerConfig.objects.conf("server_restart_mode", "reset")
            self.at_server_cold_stop()

        # tickerhandler state should always be saved.
        from evennia.scripts.tickerhandler import TICKER_HANDLER
        TICKER_HANDLER.save()

        # always called, also for a reload
        self.at_server_stop()

        # if _reactor_stopping is true, reactor does not need to
        # be stopped again.
        if os.name == 'nt' and os.path.exists(SERVER_PIDFILE):
            # for Windows we need to remove pid files manually
            os.remove(SERVER_PIDFILE)
        if not _reactor_stopping:
            # this will also send a reactor.stop signal, so we set a
            # flag to avoid loops.
            self.shutdown_complete = True
            # kill the server
            reactor.callLater(0, reactor.stop)