From be22a31ec409eb7a2a1ffdfbc95f0755a5b9700e Mon Sep 17 00:00:00 2001 From: Griatch Date: Sat, 11 May 2013 16:09:26 +0200 Subject: [PATCH] Made it possible to "take" over puppeting from one's own stale sessions. Fixed a nasty bug in swap_typeclass. --- src/commands/default/player.py | 24 +++++++++++++++----- src/locks/lockhandler.py | 1 + src/typeclasses/models.py | 41 +++++++++------------------------- 3 files changed, 30 insertions(+), 36 deletions(-) diff --git a/src/commands/default/player.py b/src/commands/default/player.py index fb8649c052..7ef3947906 100644 --- a/src/commands/default/player.py +++ b/src/commands/default/player.py @@ -71,6 +71,7 @@ class CmdOOCLook(MuxPlayerCommand): # get all our characters and sessions characters = player.db._playable_characters sessions = player.get_all_sessions() + is_su = player.is_superuser # text shown when looking in the ooc area string = "Account {g%s{n (you are Out-of-Character)" % (player.key) @@ -83,15 +84,22 @@ class CmdOOCLook(MuxPlayerCommand): string += "\n %s %s" % (sessid == csessid and "{w%s{n" % (isess + 1) or (isess + 1), addr) string += "\n\n {whelp{n - more commands" string += "\n {wooc {n - talk on public channel" - if len(characters) < MAX_NR_CHARACTERS: + + if is_su or len(characters) < MAX_NR_CHARACTERS: if not characters: string += "\n\n You don't have any character yet. See {whelp @charcreate{n for creating one." else: - string += "\n {w@charcreate [=description]{n - create new character (max %i)" % MAX_NR_CHARACTERS + string += "\n {w@charcreate [=description]{n - create new character" + if characters: + string_s_ending = len(characters) > 1 and "s" or "" string += "\n {w@ic {n - enter the game ({w@ooc{n to get back here)" - string += "\n\nAvailable character%s%s:" % (len(characters) > 1 and "s" or "", + if is_su: + string += "\n\nAvailable character%s (%i/unlimited):" % (string_s_ending, len(characters)) + else: + string += "\n\nAvailable character%s%s:" % (string_s_ending, MAX_NR_CHARACTERS > 1 and " (%i/%i)" % (len(characters), MAX_NR_CHARACTERS) or "") + for char in characters: csessid = char.sessid if csessid: @@ -153,7 +161,9 @@ class CmdCharCreate(MuxPlayerCommand): return key = self.lhs desc = self.rhs - if player.db._playable_characters and len(player.db._playable_characters) >= MAX_NR_CHARACTERS: + if not player.is_superuser and \ + (player.db._playable_characters and + len(player.db._playable_characters) >= MAX_NR_CHARACTERS): self.msg("You may only create a maximum of %i characters." % MAX_NR_CHARACTERS) return # create the character @@ -227,8 +237,10 @@ class CmdIC(MuxPlayerCommand): if new_character.player: # may not puppet an already puppeted character if new_character.sessid and new_character.player == player: - self.msg("{RYou already act as {c%s{n in another session." % new_character.name) - return + # as a safeguard we allow "taking over chars from your own sessions. + player.msg("{c%s{n{R is now acted from another of your sessions.{n" % (new_character.name), sessid=new_character.sessid) + player.unpuppet_object(new_character.sessid) + self.msg("Taking over {c%s{n from another of your sessions." % new_character.name) elif new_character.player != player and new_character.player.is_connected: self.msg("{c%s{r is already acted by another player.{n" % new_character.name) return diff --git a/src/locks/lockhandler.py b/src/locks/lockhandler.py index d43d205702..d11eadc6d8 100644 --- a/src/locks/lockhandler.py +++ b/src/locks/lockhandler.py @@ -259,6 +259,7 @@ class LockHandler(object): get_player method (this sits on serversessions, in some rare cases where a check is done before the login process has yet been fully finalized) """ + #print "_superuser_character:", hasattr(obj, "get_attribute") and obj.get_attribute("_superuser_character") self.lock_bypass = (hasattr(obj, "is_superuser") and obj.is_superuser or ((hasattr(obj, "get_attribute") and obj.get_attribute("_superuser_character")) and ((hasattr(obj, "player") and hasattr(obj.player, "is_superuser") and obj.player.is_superuser) diff --git a/src/typeclasses/models.py b/src/typeclasses/models.py index 657124e4af..889fba81a8 100644 --- a/src/typeclasses/models.py +++ b/src/typeclasses/models.py @@ -673,6 +673,7 @@ class TypedObject(SharedMemoryModel): # try to import and analyze the result typeclass = _GA(self, "_path_import")(tpath) + #print "typeclass:",typeclass,tpath if callable(typeclass): # we succeeded to import. Cache and return. _SA(self, "typeclass_path", tpath) @@ -751,27 +752,6 @@ class TypedObject(SharedMemoryModel): _SA(self, "typeclass_last_errmsg", message.strip()) return - #infochan = None - #cmessage = message - #try: - # from src.comms.models import Channel - # infochan = settings.CHANNEL_MUDINFO - # infochan = Channel.objects.get_channel(infochan[0]) - # if infochan: - # cname = infochan.key - # cmessage = "\n".join(["[%s]: %s" % (cname, line) for line in message.split('\n') if line]) - # cmessage = cmessage.strip() - # infochan.msg(cmessage) - # else: - # # no mudinfo channel is found. Log instead. - # cmessage = "\n".join(["[NO MUDINFO CHANNEL]: %s" % line for line in message.split('\n')]) - # logger.log_errmsg(cmessage) - #except Exception: - # if ServerConfig.objects.conf("server_starting_mode"): - # print cmessage - # else: - # logger.log_trace(cmessage) - def _get_default_typeclass(self, cache=False, silent=False, save=False): """ This is called when a typeclass fails to @@ -882,7 +862,7 @@ class TypedObject(SharedMemoryModel): """ if callable(new_typeclass): # this is an actual class object - build the path - cls = new_typeclass.__class__ + cls = new_typeclass new_typeclass = "%s.%s" % (cls.__module__, cls.__name__) else: new_typeclass = "%s" % to_str(new_typeclass) @@ -894,6 +874,7 @@ class TypedObject(SharedMemoryModel): # this will automatically use a default class if # there is an error with the given typeclass. new_typeclass = self.typeclass + print new_typeclass if self.typeclass_path != new_typeclass.path and no_default: # something went wrong; the default was loaded instead, # and we don't allow that; instead we return to previous. @@ -937,8 +918,8 @@ class TypedObject(SharedMemoryModel): attribute_name: (str) The attribute's name. """ if not get_attr_cache(self, attribute_name): - attrib_obj = _GA(self, "_attribute_class").objects.filter(db_obj=self).filter( - db_key__iexact=attribute_name) + attrib_obj = _GA(self, "_attribute_class").objects.filter( + db_obj=self, db_key__iexact=attribute_name) if attrib_obj: set_attr_cache(self, attribute_name, attrib_obj[0]) else: @@ -963,7 +944,7 @@ class TypedObject(SharedMemoryModel): attrclass = _GA(self, "_attribute_class") # check if attribute already exists. attrib_obj = attrclass.objects.filter( - db_obj=self).filter(db_key__iexact=attribute_name) + db_obj=self, db_key__iexact=attribute_name) if attrib_obj: # use old attribute attrib_obj = attrib_obj[0] @@ -990,7 +971,7 @@ class TypedObject(SharedMemoryModel): attrib_obj = get_attr_cache(self, attribute_name) if not attrib_obj: attrib_obj = _GA(self, "_attribute_class").objects.filter( - db_obj=self).filter(db_key__iexact=attribute_name) + db_obj=self, db_key__iexact=attribute_name) if not attrib_obj: return default set_attr_cache(self, attribute_name, attrib_obj[0]) #query is first evaluated here @@ -1009,7 +990,7 @@ class TypedObject(SharedMemoryModel): attrib_obj = get_attr_cache(self, attribute_name) if not attrib_obj: attrib_obj = _GA(self, "_attribute_class").objects.filter( - db_obj=self).filter(db_key__iexact=attribute_name) + db_obj=self, db_key__iexact=attribute_name) if not attrib_obj: return default set_attr_cache(self, attribute_name, attrib_obj[0]) #query is first evaluated here @@ -1026,7 +1007,7 @@ class TypedObject(SharedMemoryModel): attrib_obj = get_attr_cache(self, attribute_name) if not attrib_obj: attrib_obj = _GA(self, "_attribute_class").objects.filter( - db_obj=self).filter(db_key__iexact=attribute_name) + db_obj=self, db_key__iexact=attribute_name) if not attrib_obj: raise AttributeError set_attr_cache(self, attribute_name, attrib_obj[0]) #query is first evaluated here @@ -1046,7 +1027,7 @@ class TypedObject(SharedMemoryModel): else: try: _GA(self, "_attribute_class").objects.filter( - db_obj=self).filter(db_key__iexact=attribute_name)[0].delete() + db_obj=self, db_key__iexact=attribute_name)[0].delete() except IndexError: pass @@ -1064,7 +1045,7 @@ class TypedObject(SharedMemoryModel): else: try: _GA(self, "_attribute_class").objects.filter( - db_obj=self).filter(db_key__iexact=attribute_name)[0].delete() + db_obj=self, db_key__iexact=attribute_name)[0].delete() except IndexError: pass raise AttributeError