From 29e313492fc2cddf2bd5db4aa1080c10eb66e20c Mon Sep 17 00:00:00 2001 From: Griatch Date: Mon, 11 Mar 2013 01:32:17 +0100 Subject: [PATCH] Added more session info to ooclook. Working on a bug that causes superuser to not be recognized now and then - this seems to be related to character.player returning None. This revision contains some printout debug messages since that bug is not yet fixed. --- src/commands/command.py | 25 ++++++++++++++--------- src/commands/default/general.py | 32 ++++++++++++++++++++---------- src/commands/default/muxcommand.py | 2 +- src/locks/lockhandler.py | 15 +++++++++++--- src/players/models.py | 4 +--- src/settings_default.py | 2 +- 6 files changed, 53 insertions(+), 27 deletions(-) diff --git a/src/commands/command.py b/src/commands/command.py index f4b7e8caaa..13988352dd 100644 --- a/src/commands/command.py +++ b/src/commands/command.py @@ -188,27 +188,34 @@ class Command(object): """ return self.lockhandler.check(srcobj, access_type, default=default) - def msg(self, msg="", data=None, from_obj=None, to_obj=None, all_sessions=False): + def msg(self, msg="", to_obj=None, from_obj=None, data=None, sessid=None, all_sessions=False): """ This is a shortcut instad of calling msg() directly on an object - it will - determine - detect if caller is an Object or a Player and also appends self.sessid automatically. msg - text string of message to send - data - optional dictionary of data - from_obj - source of message. Defaults to self.caller. to_obj - target object of message. Defaults to self.caller + from_obj - source of message. Defaults to to_obj + data - optional dictionary of data + sessid - supply data only to a unique sessid (normally not used - this is only potentially useful if + to_obj is a Player object different from self.caller or self.caller.player) all_sessions (bool) - default is to send only to the session connected to the target object """ from_obj = from_obj or self.caller to_obj = to_obj or from_obj - if hasattr(to_obj, "sessid"): - sessid = all_sessions and None or to_obj.sessid - else: - sessid = None + if not sessid: + if hasattr(to_obj, "sessid"): + # this is the case when to_obj is e.g. a Character + sessid = all_sessions and None or to_obj.sessid + elif to_obj == self.caller: + # this is the case if to_obj is the calling Player + sessid = all_sessions and None or self.sessid + else: + # if to_obj is a different Player, all their sessions + # will be notified unless sessid was given specifically + sessid = None to_obj.msg(msg, from_obj=from_obj, data=data, sessid=sessid) # Common Command hooks diff --git a/src/commands/default/general.py b/src/commands/default/general.py index 988caff413..be0f5900a6 100644 --- a/src/commands/default/general.py +++ b/src/commands/default/general.py @@ -769,6 +769,12 @@ class CmdColorTest(MuxCommand): #------------------------------------------------------------ # OOC commands +# +# Note that in commands inheriting from MuxCommandOOC, +# self.caller is always the Player object, not the Character. +# A property self.character can be used to access the +# connecter character (this can be None if no character is +# currently controlled by the Player). #------------------------------------------------------------ class CmdOOCLook(MuxCommandOOC, CmdLook): @@ -809,24 +815,33 @@ class CmdOOCLook(MuxCommandOOC, CmdLook): # caller is always a player at this point. player = self.caller sessid = self.sessid - # get all our characters + # get all our characters and sessions characters = player.db._playable_characters - string = "You are logged in as {g%s{n." % player.key - string += "\nUse {w@ic {n to enter the game, {w@occ{n to get back here." + sessions = player.get_all_sessions() + + sessidstr = sessid and "(session id %i)" % sessid or "" + string = "You are logged in as {g%s{n%s." % (player.key, sessidstr) + + string += "\n\nSession(s) connected:" + for sess in sessions: + csessid = sess.sessid + string += "\n %s %s" % (sessid == csessid and "{w%i{n" % csessid or csessid, sess.address) + string += "\n\nUse {w@ic {n to enter the game, {w@occ{n to get back here." if characters: string += "\n\nAvailable character%s:" % (len(characters) > 1 and "s" or "") for char in characters: csessid = char.sessid if csessid: # character is already puppeted - if player.get_session(csessid): - string += "\n - {G%s{n (played by you in another session)" % char.key + sess = player.get_session(csessid) + if sess: + string += "\n - {G%s{n (played by you from session with id %i)" % (char.key, sess.sessid) else: string += "\n - {R%s{n (played by someone else)" % char.key else: # character is "free to puppet" string += "\n - %s" % char.key - player.msg(string) + self.msg(string) def func(self): "implement the ooc look command" @@ -957,7 +972,7 @@ class CmdIC(MuxCommandOOC): class CmdOOC(MuxCommandOOC): """ - @ooc - go ooc + go ooc Usage: @ooc @@ -977,9 +992,6 @@ class CmdOOC(MuxCommandOOC): caller = self.caller - if utils.inherits_from(caller, "src.objects.objects.Object"): - caller = self.caller.player - old_char = caller.get_character(sessid=self.sessid) if not old_char: string = "You are already OOC." diff --git a/src/commands/default/muxcommand.py b/src/commands/default/muxcommand.py index d4adb1ab39..29a8906a98 100644 --- a/src/commands/default/muxcommand.py +++ b/src/commands/default/muxcommand.py @@ -175,7 +175,7 @@ class MuxCommandOOC(MuxCommand): This class makes sure that caller is always a Player object, while creating a new property "character" that is set only if a - character is actually attached to the Player. + character is actually attached to this Player and Session. """ def parse(self): """ diff --git a/src/locks/lockhandler.py b/src/locks/lockhandler.py index dfb98ecd38..949bccd489 100644 --- a/src/locks/lockhandler.py +++ b/src/locks/lockhandler.py @@ -170,12 +170,21 @@ class LockHandler(object): self.log_obj = None self.reset_flag = False self._cache_locks(self.obj.lock_storage) - # 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). + # we handle bypass checks already here for efficiency. We need to grant access to superusers. + # We need to check both directly on the object (players), through obj.player and using the + # 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) self.lock_bypass = ((hasattr(obj, "is_superuser") and obj.is_superuser) or (hasattr(obj, "player") and hasattr(obj.player, "is_superuser") and obj.player.is_superuser) or (hasattr(obj, "get_player") and (not obj.get_player() or obj.get_player().is_superuser))) + if obj.key == "Griatch": + print "SETTING lock_bypass:", obj, self.lock_bypass, "<-", + print (hasattr(obj, "is_superuser") and obj.is_superuser), + print (hasattr(obj, "player") and hasattr(obj.player, "is_superuser") and obj.player.is_superuser), + print (hasattr(obj, "get_player") and (not obj.get_player() or obj.get_player().is_superuser)), + if hasattr(obj, "player"): + print obj.player and obj.player.is_superuser + def __str__(self): return ";".join(self.locks[key][2] for key in sorted(self.locks)) diff --git a/src/players/models.py b/src/players/models.py index bab020473d..4239768b55 100644 --- a/src/players/models.py +++ b/src/players/models.py @@ -390,9 +390,7 @@ class PlayerDB(TypedObject): pass outgoing_string = utils.to_str(outgoing_string, force_string=True) - session = None - if sessid: - session = _GA(self, "get_session")(sessid) + session = sessid and _GA(self, "get_session")(sessid) or None if session: char = _GA(self, "get_character")(sessid=sessid) if char and not char.at_msg_receive(outgoing_string, from_obj=from_obj, data=data): diff --git a/src/settings_default.py b/src/settings_default.py index fb83919335..fe2ee25e6e 100644 --- a/src/settings_default.py +++ b/src/settings_default.py @@ -63,7 +63,7 @@ SSL_PORTS = [4001] # Interface addresses to listen to. If 0.0.0.0, listen to all. SSL_INTERFACES = ['0.0.0.0'] # Multisession modes allow a player (=account) to connect to the game simultaneously -# with multiple clients in various ways according to the set mode: +# with multiple clients (=sessions) in various ways according to the set mode: # 0 - no multisession - when a new session is connected, the old one is disconnected # 1 - multiple sessions, one player, one character, each session getting the same data # 2 - multiple sessions, one player, each session controlling different characters