diff --git a/src/locks/lockhandler.py b/src/locks/lockhandler.py index 8fc4b035e5..76372c5a6f 100644 --- a/src/locks/lockhandler.py +++ b/src/locks/lockhandler.py @@ -168,7 +168,7 @@ class LockHandler(object): self.no_errors = True self.reset_flag = False self._cache_locks(self.obj.lock_storage) - # we handle most bypass checks already here. We need to grant access to superusers and + # we handle bypass checks already here for efficiency. We need to grant access to superusers and # to protocol instances where the superuser status cannot be determined (can happen at # some rare cases during login). self.lock_bypass = ((hasattr(obj, "is_superuser") and obj.is_superuser) @@ -306,6 +306,7 @@ class LockHandler(object): "Remove all locks" self.locks = {} self.lock_storage = "" + def reset(self): """ Set the reset flag, so the the lock will be re-cached at next checking. @@ -346,13 +347,18 @@ class LockHandler(object): self._cache_locks(self.obj.lock_storage) self.reset_flag = False - # check if the lock should be bypassed (e.g. superuser status) try: + # check if the lock should be bypassed (e.g. superuser status) if accessing_obj.locks.lock_bypass and not no_superuser_bypass: return True except AttributeError: - pass + # happens before session is initiated. + if not no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser) + or (hasattr(accessing_obj, 'player') and hasattr(accessing_obj.player, 'is_superuser') and accessing_obj.player.is_superuser) + or (hasattr(accessing_obj, 'get_player') and (not accessing_obj.get_player() or accessing_obj.get_player().is_superuser))): + return True + # no superuser or bypass -> normal lock operation if access_type in self.locks: # we have a lock, test it. evalstring, func_tup, raw_string = self.locks[access_type] @@ -377,8 +383,8 @@ class LockHandler(object): except AttributeError: if no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser) or (hasattr(accessing_obj, 'player') and hasattr(accessing_obj.player, 'is_superuser') and accessing_obj.player.is_superuser) - or (hasattr(accessing_obj, 'get_player') and (accessing_obj.get_player()==None or accessing_obj.get_player().is_superuser))): - return True + or (hasattr(accessing_obj, 'get_player') and (not accessing_obj.get_player() or accessing_obj.get_player().is_superuser))): + return True locks = self. _parse_lockstring(lockstring) for access_type in locks: diff --git a/src/players/models.py b/src/players/models.py index b30c20472f..59f7b47598 100644 --- a/src/players/models.py +++ b/src/players/models.py @@ -257,10 +257,10 @@ class PlayerDB(TypedObject): # def __str__(self): - return smart_str("%s(player %i)" % (self.name, self.dbid)) + return smart_str("%s(player %s)" % (self.name, self.dbid)) def __unicode__(self): - return u"%s(player#%i)" % (self.name, self.dbid) + return u"%s(player#%s)" % (self.name, self.dbid) # this is required to properly handle attributes and typeclass loading _typeclass_paths = settings.PLAYER_TYPECLASS_PATHS diff --git a/src/server/initial_setup.py b/src/server/initial_setup.py index 2859780bc7..1a3c3f6234 100644 --- a/src/server/initial_setup.py +++ b/src/server/initial_setup.py @@ -189,7 +189,7 @@ def at_initial_setup(): """ Custom hook for users to overload some or all parts of the initial setup. Called very last in the sequence. It tries to import and - run a module settings.AT_INITIAL_SETUP_HOOK_MODULE and will fail + srun a module settings.AT_INITIAL_SETUP_HOOK_MODULE and will fail silently if this does not exist or fails to load. """ modname = settings.AT_INITIAL_SETUP_HOOK_MODULE @@ -203,6 +203,17 @@ def at_initial_setup(): if mod.__dict__.get("at_initial_setup", None): mod.at_initial_setup() +def reset_server(): + """ + We end the initialization by resetting the server. This + makes sure the first login is the same as all the following + ones, particularly it cleans all caches for the special objects. + It also checks so the warm-reset mechanism works as it should. + """ + from src.server.sessionhandler import SESSIONS + print _(" Initial setup finished. Resetting/Reloading Server.") + SESSIONS.server.shutdown(mode='reset') + def handle_setup(last_step): """ Main logic for the module. It allows for restarting @@ -227,12 +238,13 @@ def handle_setup(last_step): start_game_time, create_admin_media_links, import_MUX_help_files, - at_initial_setup] + at_initial_setup, + reset_server] if not settings.IMPORT_MUX_HELP: # skip importing of the MUX helpfiles, they are # not interesting except for developers. - del setup_queue[-2] + del setup_queue[-3] #print " Initial setup: %s steps." % (len(setup_queue)) @@ -256,13 +268,10 @@ def handle_setup(last_step): profile.delete() elif last_step + num == 3: from src.comms.models import Channel, PlayerChannelConnection - for chan in Channel.objects.all(): chan.delete() for conn in PlayerChannelConnection.objects.all(): conn.delete() - - raise ServerConfig.objects.conf("last_initial_setup_step", last_step + num + 1) # We got through the entire list. Set last_step to -1 so we don't diff --git a/src/utils/ansi.py b/src/utils/ansi.py index dffb5dbe00..24f6f8b18c 100644 --- a/src/utils/ansi.py +++ b/src/utils/ansi.py @@ -123,10 +123,10 @@ class ANSIParser(object): # xterm256 {123, %c134, self.xterm256_map = [ - (r'(?