After the rework of the many-char mode, mode 0 now works stably and auto-logins correctly it seems.

This commit is contained in:
Griatch 2013-04-09 17:11:34 +02:00
parent 26ced2cb90
commit 1e07b8ca34
8 changed files with 29 additions and 171 deletions

View file

@ -464,7 +464,7 @@ class CmdWho(MuxCommand):
delta_cmd = time.time() - session.cmd_last_visible delta_cmd = time.time() - session.cmd_last_visible
delta_conn = time.time() - session.conn_time delta_conn = time.time() - session.conn_time
plr_pobject = session.get_character() plr_pobject = session.get_puppet()
if not plr_pobject: if not plr_pobject:
plr_pobject = session.get_player() plr_pobject = session.get_player()
show_session_data = False show_session_data = False
@ -562,7 +562,7 @@ class CmdSessions(MuxCommand):
table = [["sessid"], ["host"], ["character"], ["location"]] table = [["sessid"], ["host"], ["character"], ["location"]]
for sess in sorted(sessions, key=lambda x:x.sessid): for sess in sorted(sessions, key=lambda x:x.sessid):
sessid = sess.sessid sessid = sess.sessid
char = player.get_character(sessid) char = player.get_puppet(sessid)
table[0].append(str(sess.sessid)) table[0].append(str(sess.sessid))
table[1].append(str(sess.address[0])) table[1].append(str(sess.address[0]))
table[2].append(char and str(char) or "None") table[2].append(char and str(char) or "None")
@ -750,7 +750,7 @@ class CmdColorTest(MuxCommand):
string = "ANSI colors:" string = "ANSI colors:"
for row in table: for row in table:
string += "\n" + "".join(row) string += "\n" + "".join(row)
print string #print string
self.caller.msg(string) self.caller.msg(string)
self.caller.msg("{{X and %%cx are black-on-black)") self.caller.msg("{{X and %%cx are black-on-black)")
elif self.args == "xterm256": elif self.args == "xterm256":
@ -939,7 +939,7 @@ class CmdIC(MuxCommandOOC):
def func(self): def func(self):
""" """
Simple puppet method Main puppet method
""" """
player = self.caller player = self.caller
sessid = self.sessid sessid = self.sessid
@ -977,7 +977,7 @@ class CmdIC(MuxCommandOOC):
return return
if player.puppet_object(sessid, new_character): if player.puppet_object(sessid, new_character):
self.msg("\n{gYou become {c%s{n.\n" % new_character.name) self.msg("\n{gYou become {c%s{n.\n" % new_character.name)
player.db._last_puppet = old_character player.db._last_puppet = new_character
if not new_character.location: if not new_character.location:
# this might be due to being hidden away at logout; check # this might be due to being hidden away at logout; check
loc = new_character.db.prelogout_location loc = new_character.db.prelogout_location

View file

@ -198,6 +198,8 @@ class CmdUnconnectedCreate(MuxCommand):
# If no description is set, set a default description # If no description is set, set a default description
if not new_character.db.desc: if not new_character.db.desc:
new_character.db.desc = "This is a Player." new_character.db.desc = "This is a Player."
# We need to set this to have @ic auto-connect to this character
new_player.db._last_puppet = new_character
# tell the caller everything went well. # tell the caller everything went well.
string = "A new account '%s' was created. Welcome!" string = "A new account '%s' was created. Welcome!"

View file

@ -817,8 +817,6 @@ class Character(Object):
""" """
This recovers the character again after having been "stoved away" at the unpuppet This recovers the character again after having been "stoved away" at the unpuppet
""" """
print "object at_pre_puppet", self, player
if self.db.prelogout_location: if self.db.prelogout_location:
# try to recover # try to recover
self.location = self.db.prelogout_location self.location = self.db.prelogout_location
@ -831,18 +829,11 @@ class Character(Object):
self.location.msg_contents("%s has entered the game." % self.name, exclude=[self]) self.location.msg_contents("%s has entered the game." % self.name, exclude=[self])
self.location.at_object_receive(self, self.location) self.location.at_object_receive(self, self.location)
def at_post_puppet(self):
"Once puppeting is complete, make sure to view the location."
# call look
print "object at_post_puppet", self
self.execute_cmd("look")
def at_post_unpuppet(self, player): def at_post_unpuppet(self, player):
""" """
We stove away the character when the player goes ooc/logs off, otherwise the character object will We stove away the character when the player goes ooc/logs off, otherwise the character object will
remain in the room also after the player logged off ("headless", so to say). remain in the room also after the player logged off ("headless", so to say).
""" """
print "at_post_unpuppet", player
if self.location: # have to check, in case of multiple connections closing if self.location: # have to check, in case of multiple connections closing
self.location.msg_contents("%s has left the game." % self.name, exclude=[self]) self.location.msg_contents("%s has left the game." % self.name, exclude=[self])
self.db.prelogout_location = self.location self.db.prelogout_location = self.location

View file

@ -384,7 +384,7 @@ class PlayerDB(TypedObject):
(connection happens automatically in the sessionhandler) (connection happens automatically in the sessionhandler)
""" """
# this should only be one value, loop just to make sure to clean everything # this should only be one value, loop just to make sure to clean everything
sessions = (session for session in self.get_all_sessions(sessid) if session.sessid == sessid) sessions = (session for session in self.get_all_sessions() if session.sessid == sessid)
for session in sessions: for session in sessions:
# this will also trigger unpuppeting # this will also trigger unpuppeting
session.sessionhandler.disconnect(session) session.sessionhandler.disconnect(session)
@ -486,148 +486,8 @@ class PlayerDB(TypedObject):
return puppets return puppets
return [puppet.typeclass for puppet in puppets] return [puppet.typeclass for puppet in puppets]
def has_puppet(self, obj):
"""
Checks of this player currently puppets this object or not
"""
return obj in self.get_all_puppets()
# def connect_session_to_character(self, sessid, character, force=False, call_hooks=True): # utility methods
# """
# Connect the given session to a character through this player.
# Note that this assumes the character has previously been
# linked to the player using self.connect_character().
#
# force - drop existing connection to other character
# call_hooks - call puppet/unpuppet hooks. This is not wanted e.g. if
# server is reloading
#
# Returns True if connection was successful, False otherwise
# """
# # first check if we already have a character tied to this session
# char = _GA(self, "get_character")(sessid=sessid, return_dbobj=True)
# if char:
# if force and char != character:
# _GA(self, "disconnect_session_from_character")(sessid)
# else:
# return
# # pre-puppet hook
# if call_hooks:
# # if e.g. server reloads we don't want to call any hooks anew
# _GA(character.typeclass, "at_pre_puppet")(self.typeclass)
# # do the connection
# character.sessid = sessid
# # update cache
# cache = get_prop_cache(self, "_characters") or {}
# cache[sessid] = character
# set_prop_cache(self, "_characters", cache)
# # start/validate (persistent) scripts on this object
# ScriptDB.objects.validate(obj=character)
# # post-puppet hook
# if call_hooks:
# _GA(character.typeclass, "at_post_puppet")()
# return True
#
# def disconnect_session_from_character(self, sessid):
# """
# Disconnect a session from the characterm (still keeping the
# connection to the Player)
# returns the newly disconnected character, if it existed
# """
# print "player disconnect_session_from_character", sessid
# if not sessid:
# return
# char = _GA(self, "get_character")(sessid=sessid, return_dbobj=True)
# print char
# if char:
# # call hook before disconnecting
# _GA(char.typeclass, "at_pre_unpuppet")()
# del char.sessid
# # update cache
# cache = get_prop_cache(self, "_characters") or {}
# if sessid in cache:
# del cache[sessid]
# set_prop_cache(self, "_characters", cache)
# # call post-unpuppet hook
# _GA(char.typeclass, "at_post_unpuppet")(self.typeclass)
# print "... leaving player disconnect_session_from_character", sessid
# return char
#
# def server_reconnect_session_to_character(self, sessid):
# """
# Auto-re-connect a session to a character. This is called by the sessionhandler
# during a server reload. It goes through the characters stored in this player's
# db_objs many2many fields and checks if any of those has the given sessid
# stored on themselves - if so they connect them. This should ONLY be called
# automatically by sessionhandler after a reload - after a portal shutdown
# the portal sessids will be out of sync with whatever is stored on character
# objects which could lead to a session being linked to the wrong character.
# """
# char = _GA(self, "get_character")(sessid=sessid, return_dbobj=True)
# if not char:
# return
# _GA(self, "connect_session_to_character")(sessid, char, force=True, call_hooks=False)
# def get_all_characters(self):
# """
# Readability-wrapper for getting all characters
# """
# return _GA(self, "get_character")(sessid=None, character=None)
#
# def get_all_connected_characters(self):
# """
# Return all characters with an active session connected
# to them through this player
# """
# chars = make_iter(_GA(self, "get_character")(sessid=None, character=None))
# sessids = [sess.sessid for sess in _GA(self, "get_all_sessions")()]
# return [char for char in chars if char.sessid in sessids]
# def connect_character(self, character, sessid=None):
# """
# Use the Player to connect a Character to the Player. Note that
# we don't do any access checks at this point. If the
# game was fully restarted (including the Portal), this must be
# used, since sessids will have changed as players reconnect.
#
# if sessid is given, also connect the sessid to the character directly.
# """
# # first disconnect any other character from this session
# char = character.dbobj
# _GA(self, "disconnect_character")(char)
# char.player = self
# _GA(self, "db_objs").add(char)
# _GA(self, "save")()
# if sessid:
# return _GA(self, "connect_session_to_character")(sessid=sessid, character=char)
# return True
#
# def disconnect_character(self, character):
# """
# Disconnect a character from this player, either based
# on sessid or by giving the character object directly
#
# Returns newly disconnected character.
# """
# if not character:
# return
# char = _GA(self, "get_character")(character=character, return_dbobj=True)
# if char:
# err = _GA(self, "disconnect_session_from_character")(char.sessid)
# _GA(self, "db_objs").remove(char)
# del char.player
# self.save()
# # clear cache
# cache = get_prop_cache(self, "_characters") or {}
# [cache.pop(sessid) for sessid,stored_char in cache.items() if stored_char==char]
# set_prop_cache(self, "_characters", cache)
# return char
#
# def disconnect_all_characters(self):
# for char in self.db_objs.all():
# _GA(self, "disconnect_character")(char)
def delete(self, *args, **kwargs): def delete(self, *args, **kwargs):
@ -651,9 +511,6 @@ class PlayerDB(TypedObject):
except AssertionError: except AssertionError:
# this means deleting the user already cleared out the Player object. # this means deleting the user already cleared out the Player object.
pass pass
#
# Execution/action methods
#
def execute_cmd(self, raw_string, sessid=None): def execute_cmd(self, raw_string, sessid=None):
""" """
@ -671,6 +528,11 @@ class PlayerDB(TypedObject):
if nick.db_nick in raw_list: if nick.db_nick in raw_list:
raw_string = raw_string.replace(nick.db_nick, nick.db_real, 1) raw_string = raw_string.replace(nick.db_nick, nick.db_real, 1)
break break
if not sessid and _MULTISESSION_MODE in (0, 1):
# in this case, we should either have only one sessid, or the sessid
# should not matter (since the return goes to all of them we can just
# use the first one as the source)
sessid = self.get_all_sessions()[0].sessid
return cmdhandler.cmdhandler(self.typeclass, raw_string, sessid=sessid) return cmdhandler.cmdhandler(self.typeclass, raw_string, sessid=sessid)
def search(self, ostring, return_character=False, **kwargs): def search(self, ostring, return_character=False, **kwargs):

View file

@ -292,7 +292,6 @@ class Player(TypeClass):
Only called once, the very first Only called once, the very first
time the user logs in. time the user logs in.
""" """
print "player at_first_login", self
pass pass
def at_pre_login(self): def at_pre_login(self):
@ -300,7 +299,6 @@ class Player(TypeClass):
Called every time the user logs in, just before the actual Called every time the user logs in, just before the actual
login-state is set. login-state is set.
""" """
print "player at_pre_login", self
pass pass
def _send_to_connect_channel(self, message): def _send_to_connect_channel(self, message):
@ -324,19 +322,21 @@ class Player(TypeClass):
them loose. This is called before an eventual Character's them loose. This is called before an eventual Character's
at_post_login hook. at_post_login hook.
""" """
print "player at_post_login", self
self._send_to_connect_channel("{G%s connected{n" % self.key) self._send_to_connect_channel("{G%s connected{n" % self.key)
if _MULTISESSION_MODE in (0, 1):
if _MULTISESSION_MODE == 2: # in these modes we should have only one character available. We
# Character.at_post_login also looks around. Only use # try to auto-connect to it by calling the @ic command
# this as a backup when logging in without a character # (this relies on player.db._last_puppet being set)
self.execute_cmd("@ic")
elif _MULTISESSION_MODE == 2:
# In this mode we by default end up at a character selection
# screen. We execute look on the player.
self.execute_cmd("look") self.execute_cmd("look")
def at_disconnect(self, reason=None): def at_disconnect(self, reason=None):
""" """
Called just before user is disconnected. Called just before user is disconnected.
""" """
print "player at_disconnect", self
reason = reason and "(%s)" % reason or "" reason = reason and "(%s)" % reason or ""
self._send_to_connect_channel("{R%s disconnected %s{n" % (self.key, reason)) self._send_to_connect_channel("{R%s disconnected %s{n" % (self.key, reason))

View file

@ -61,7 +61,8 @@ def create_objects():
god_character.save() god_character.save()
god_character.set_attribute("_superuser_character", True) god_character.set_attribute("_superuser_character", True)
god_character.set_attribute("_first_login", True) god_player.set_attribute("_first_login", True)
god_player.set_attribute("_last_puppet", god_character)
# Limbo is the default "nowhere" starting room # Limbo is the default "nowhere" starting room

View file

@ -43,6 +43,10 @@ class ServerSession(Session):
through their session. through their session.
""" """
def __init__(self):
"Initiate to avoid AttributeErrors down the line"
self.puppet = None
def at_sync(self): def at_sync(self):
""" """
This is called whenever a session has been resynced with the portal. This is called whenever a session has been resynced with the portal.
@ -62,7 +66,7 @@ class ServerSession(Session):
self.cmdset_storage = [settings.CMDSET_UNLOGGEDIN] self.cmdset_storage = [settings.CMDSET_UNLOGGEDIN]
self.cmdset.update(init_mode=True) self.cmdset.update(init_mode=True)
elif self.puid: elif self.puid:
self.puppet = None # reconnect puppet (puid is only set if we are coming back from a server reload)
obj = _ObjectDB.objects.get(id=self.puid) obj = _ObjectDB.objects.get(id=self.puid)
self.player.puppet_object(self.sessid, obj, normal_mode=False) self.player.puppet_object(self.sessid, obj, normal_mode=False)
@ -92,7 +96,6 @@ class ServerSession(Session):
if self.logged_in: if self.logged_in:
sessid = self.sessid sessid = self.sessid
player = self.player player = self.player
print "session at_disconnect", self
_GA(player.dbobj, "unpuppet_object")(sessid) _GA(player.dbobj, "unpuppet_object")(sessid)
uaccount = _GA(player.dbobj, "user") uaccount = _GA(player.dbobj, "user")
uaccount.last_login = datetime.now() uaccount.last_login = datetime.now()

View file

@ -212,7 +212,6 @@ class ServerSessionHandler(SessionHandler):
now should know is connected to it. After this point we now should know is connected to it. After this point we
assume the session to be logged in one way or another. assume the session to be logged in one way or another.
""" """
# prep the session with player/user info
# we have to check this first before uid has been assigned # we have to check this first before uid has been assigned
# this session. # this session.