Moved login and disconnect from session-level to sessionhandler level to make the process cleaner with hooks rather than direct calls.
This commit is contained in:
parent
261363bae7
commit
25505d69a6
7 changed files with 109 additions and 70 deletions
|
|
@ -118,14 +118,12 @@ class Command(object):
|
||||||
# used by the help system to group commands in lists.
|
# used by the help system to group commands in lists.
|
||||||
help_category = "general"
|
help_category = "general"
|
||||||
|
|
||||||
# this normally does not need to be changed. It allows to turn off
|
# This allows to turn off auto-help entry creation for individual commands.
|
||||||
# auto-help entry creation for individual commands.
|
|
||||||
auto_help = True
|
auto_help = True
|
||||||
# There is also the property 'obj'. This gets set by the system
|
# auto-set (by Evennia on command instantiation) are:
|
||||||
# on the fly to tie this particular command to a certain in-game entity.
|
# obj - which object this command is defined on
|
||||||
# self.obj should NOT be defined here since it will not be overwritten
|
# sessid - which session-id (if any) is responsible for triggering this command
|
||||||
# if it already exists.
|
#
|
||||||
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"the lockhandler works the same as for objects."
|
"the lockhandler works the same as for objects."
|
||||||
|
|
@ -190,6 +188,29 @@ class Command(object):
|
||||||
"""
|
"""
|
||||||
return self.lockhandler.check(srcobj, access_type, default=default)
|
return self.lockhandler.check(srcobj, access_type, default=default)
|
||||||
|
|
||||||
|
def msg(self, msg="", data=None, from_obj=None, to_obj=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
|
||||||
|
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
|
||||||
|
to_obj.msg(msg, from_obj=from_obj, data=data, sessid=sessid)
|
||||||
|
|
||||||
# Common Command hooks
|
# Common Command hooks
|
||||||
|
|
||||||
def at_pre_cmd(self):
|
def at_pre_cmd(self):
|
||||||
|
|
|
||||||
|
|
@ -388,7 +388,11 @@ class CmdQuit(MuxCommand):
|
||||||
Usage:
|
Usage:
|
||||||
@quit
|
@quit
|
||||||
|
|
||||||
Gracefully disconnect from the game.
|
Switch:
|
||||||
|
all - disconnect all connected sessions
|
||||||
|
|
||||||
|
Gracefully disconnect your current session from the
|
||||||
|
game. Use the /all switch to disconnect from all sessions.
|
||||||
"""
|
"""
|
||||||
key = "@quit"
|
key = "@quit"
|
||||||
locks = "cmd:all()"
|
locks = "cmd:all()"
|
||||||
|
|
@ -400,10 +404,20 @@ class CmdQuit(MuxCommand):
|
||||||
else:
|
else:
|
||||||
player = self.caller
|
player = self.caller
|
||||||
|
|
||||||
player.msg("{RQuitting{n. Hope to see you soon again.", sessid=self.sessid)
|
if 'all' in self.switches:
|
||||||
player.disconnect_session_from_player(self.sessid)
|
player.msg("{RQuitting{n all sessions. Hope to see you soon again.", sessid=self.sessid)
|
||||||
#for session in self.caller.sessions:
|
for session in player.get_all_sessions():
|
||||||
# session.session_disconnect()
|
player.disconnect_session_from_player(session.sessid)
|
||||||
|
else:
|
||||||
|
nsess = len(player.get_all_sessions())
|
||||||
|
if nsess == 2:
|
||||||
|
player.msg("{RQuitting{n. One session is still connected.", sessid=self.sessid)
|
||||||
|
elif nsess > 2:
|
||||||
|
player.msg("{RQuitting{n. %i session are still connected." % (nsess-1), sessid=self.sessid)
|
||||||
|
else:
|
||||||
|
# we are quitting the last available session
|
||||||
|
player.msg("{RQuitting{n. Hope to see you soon again.", sessid=self.sessid)
|
||||||
|
player.disconnect_session_from_player(self.sessid)
|
||||||
|
|
||||||
class CmdWho(MuxCommand):
|
class CmdWho(MuxCommand):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ class CmdUnconnectedConnect(MuxCommand):
|
||||||
# at_pre_login()
|
# at_pre_login()
|
||||||
# player.at_post_login() - calls look if no character is set
|
# player.at_post_login() - calls look if no character is set
|
||||||
# character.at_post_login() - this calls look command by default
|
# character.at_post_login() - this calls look command by default
|
||||||
session.session_login(player)
|
session.sessionhandler.login(session, player)
|
||||||
|
|
||||||
class CmdUnconnectedCreate(MuxCommand):
|
class CmdUnconnectedCreate(MuxCommand):
|
||||||
"""
|
"""
|
||||||
|
|
@ -224,8 +224,8 @@ class CmdUnconnectedQuit(MuxCommand):
|
||||||
def func(self):
|
def func(self):
|
||||||
"Simply close the connection."
|
"Simply close the connection."
|
||||||
session = self.caller
|
session = self.caller
|
||||||
session.msg("Good bye! Disconnecting ...")
|
#session.msg("Good bye! Disconnecting ...")
|
||||||
session.session_disconnect()
|
session.sessionhandler.disconnect(session, "Good bye! Disconnecting ...")
|
||||||
|
|
||||||
class CmdUnconnectedLook(MuxCommand):
|
class CmdUnconnectedLook(MuxCommand):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -584,7 +584,6 @@ class ObjectDB(TypedObject):
|
||||||
if ostring in (_ME, _SELF, '*' + _ME, '*' + _SELF):
|
if ostring in (_ME, _SELF, '*' + _ME, '*' + _SELF):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
if use_nicks:
|
if use_nicks:
|
||||||
nick = None
|
nick = None
|
||||||
nicktype = "object"
|
nicktype = "object"
|
||||||
|
|
@ -670,7 +669,7 @@ class ObjectDB(TypedObject):
|
||||||
break
|
break
|
||||||
return cmdhandler.cmdhandler(_GA(self, "typeclass"), raw_string, sessid=sessid)
|
return cmdhandler.cmdhandler(_GA(self, "typeclass"), raw_string, sessid=sessid)
|
||||||
|
|
||||||
def msg(self, message, from_obj=None, data=None):
|
def msg(self, msg=None, from_obj=None, data=None, sessid=0):
|
||||||
"""
|
"""
|
||||||
Emits something to a session attached to the object.
|
Emits something to a session attached to the object.
|
||||||
|
|
||||||
|
|
@ -678,10 +677,14 @@ class ObjectDB(TypedObject):
|
||||||
from_obj (obj): object that is sending.
|
from_obj (obj): object that is sending.
|
||||||
data (object): an optional data object that may or may not
|
data (object): an optional data object that may or may not
|
||||||
be used by the protocol.
|
be used by the protocol.
|
||||||
|
sessid (int): sessid to relay to, if any.
|
||||||
|
If set to 0 (default), use self.sessid automatically
|
||||||
|
If None, echo to all connected sessions
|
||||||
"""
|
"""
|
||||||
if _GA(self, 'player'):
|
if _GA(self, 'player'):
|
||||||
# note that we must call the player *typeclass'* msg(), otherwise one couldn't overload it.
|
# note that we must call the player *typeclass'* msg(), otherwise one couldn't overload it.
|
||||||
_GA(_GA(self, 'player'), "typeclass").msg(message, from_obj=from_obj, data=data, sessid=_GA(self, "sessid"))
|
_GA(_GA(self, 'player'), "typeclass").msg(msg, from_obj=from_obj, data=data,
|
||||||
|
sessid=(sessid==0 and _GA(self, "sessid") or sessid or None))
|
||||||
|
|
||||||
def emit_to(self, message, from_obj=None, data=None):
|
def emit_to(self, message, from_obj=None, data=None):
|
||||||
"Deprecated. Alias for msg"
|
"Deprecated. Alias for msg"
|
||||||
|
|
|
||||||
|
|
@ -423,16 +423,23 @@ class PlayerDB(TypedObject):
|
||||||
# a non-character session; this goes to player directly
|
# a non-character session; this goes to player directly
|
||||||
_GA(self, "execute_cmd")(ingoing_string, sessid=sessid)
|
_GA(self, "execute_cmd")(ingoing_string, sessid=sessid)
|
||||||
|
|
||||||
def disconnect_session_from_player(self, sessid):
|
def get_session_from_sessid(self, sessid):
|
||||||
"""
|
"""
|
||||||
Access method for disconnecting a given session from the player.
|
Get the session object from sessid. If session with sessid is not
|
||||||
|
connected to this player, return None.
|
||||||
"""
|
"""
|
||||||
global _SESSIONS
|
global _SESSIONS
|
||||||
if not _SESSIONS:
|
if not _SESSIONS:
|
||||||
from src.server.sessionhandler import SESSIONS as _SESSIONS
|
from src.server.sessionhandler import SESSIONS as _SESSIONS
|
||||||
_SESSIONS.disconnect(sessid=sessid)
|
return _SESSIONS.sessions_from_player(self, sessid=sessid)
|
||||||
|
|
||||||
|
|
||||||
|
def disconnect_session_from_player(self, sessid):
|
||||||
|
"""
|
||||||
|
Access method for disconnecting a given session from the player.
|
||||||
|
"""
|
||||||
|
session = self.get_session_from_sessid(sessid)
|
||||||
|
if session:
|
||||||
|
session.sessionhandler.disconnect(session)
|
||||||
|
|
||||||
def connect_session_to_character(self, sessid, character, force=False):
|
def connect_session_to_character(self, sessid, character, force=False):
|
||||||
"""
|
"""
|
||||||
|
|
@ -502,7 +509,6 @@ class PlayerDB(TypedObject):
|
||||||
"""
|
"""
|
||||||
char = _GA(self, "get_character")(sessid=sessid, return_dbobj=True)
|
char = _GA(self, "get_character")(sessid=sessid, return_dbobj=True)
|
||||||
if not char:
|
if not char:
|
||||||
print "No reconnecting character found"
|
|
||||||
return
|
return
|
||||||
self.connect_session_to_character(sessid, char, force=True)
|
self.connect_session_to_character(sessid, char, force=True)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,23 +59,12 @@ class ServerSession(Session):
|
||||||
else:
|
else:
|
||||||
self.player.reconnect_session_to_character(self.sessid)
|
self.player.reconnect_session_to_character(self.sessid)
|
||||||
|
|
||||||
def session_login(self, player):
|
def at_login(self, player):
|
||||||
"""
|
"""
|
||||||
Startup mechanisms that need to run at login. This is called
|
Hook called by sessionhandler when the session becomes authenticated.
|
||||||
by the login command (which need to have handled authentication
|
|
||||||
already before calling this method)
|
|
||||||
|
|
||||||
player - the connected player
|
player - the player associated with the session
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# we have to check this first before uid has been assigned
|
|
||||||
# this session.
|
|
||||||
|
|
||||||
if not self.sessionhandler.sessions_from_player(player):
|
|
||||||
player.is_connected = True
|
|
||||||
|
|
||||||
# actually do the login by assigning session data
|
|
||||||
|
|
||||||
self.player = player
|
self.player = player
|
||||||
self.user = player.user
|
self.user = player.user
|
||||||
self.uid = self.user.id
|
self.uid = self.user.id
|
||||||
|
|
@ -87,31 +76,9 @@ class ServerSession(Session):
|
||||||
self.user.last_login = datetime.now()
|
self.user.last_login = datetime.now()
|
||||||
self.user.save()
|
self.user.save()
|
||||||
|
|
||||||
# player init
|
def at_disconnect(self):
|
||||||
player.at_init()
|
|
||||||
|
|
||||||
# Check if this is the first time the *player* logs in
|
|
||||||
if player.db.FIRST_LOGIN:
|
|
||||||
player.at_first_login()
|
|
||||||
del player.db.FIRST_LOGIN
|
|
||||||
|
|
||||||
player.at_pre_login()
|
|
||||||
|
|
||||||
self.log(_('Logged in: %(self)s') % {'self': self})
|
|
||||||
|
|
||||||
# start (persistent) scripts on this object
|
|
||||||
#ScriptDB.objects.validate(obj=self.player.character)
|
|
||||||
|
|
||||||
#add session to connected list
|
|
||||||
self.sessionhandler.login(self)
|
|
||||||
|
|
||||||
player.at_post_login()
|
|
||||||
|
|
||||||
def session_disconnect(self):
|
|
||||||
"""
|
"""
|
||||||
Clean up the session, removing it from the game and doing some
|
Hook called by sessionhandler when disconnecting this session.
|
||||||
accounting. This method is used also for non-loggedin
|
|
||||||
accounts.
|
|
||||||
"""
|
"""
|
||||||
if self.logged_in:
|
if self.logged_in:
|
||||||
sessid = self.sessid
|
sessid = self.sessid
|
||||||
|
|
@ -123,8 +90,9 @@ class ServerSession(Session):
|
||||||
uaccount.save()
|
uaccount.save()
|
||||||
self.logged_in = False
|
self.logged_in = False
|
||||||
if not self.sessionhandler.sessions_from_player(player):
|
if not self.sessionhandler.sessions_from_player(player):
|
||||||
|
# no more sessions connected to this player
|
||||||
player.is_connected = False
|
player.is_connected = False
|
||||||
self.sessionhandler.disconnect(self)
|
|
||||||
|
|
||||||
def get_player(self):
|
def get_player(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -268,12 +236,12 @@ class ServerSession(Session):
|
||||||
|
|
||||||
# easy-access functions
|
# easy-access functions
|
||||||
|
|
||||||
def login(self, player):
|
#def login(self, player):
|
||||||
"alias for at_login"
|
# "alias for at_login"
|
||||||
self.session_login(player)
|
# self.session_login(player)
|
||||||
def disconnect(self):
|
#def disconnect(self):
|
||||||
"alias for session_disconnect"
|
# "alias for session_disconnect"
|
||||||
self.session_disconnect()
|
# self.session_disconnect()
|
||||||
def msg(self, string='', data=None):
|
def msg(self, string='', data=None):
|
||||||
"alias for at_data_out"
|
"alias for at_data_out"
|
||||||
self.data_out(string, data=data)
|
self.data_out(string, data=data)
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,7 @@ class ServerSessionHandler(SessionHandler):
|
||||||
"""
|
"""
|
||||||
session = self.sessions.get(session.sessid, None)
|
session = self.sessions.get(session.sessid, None)
|
||||||
if session:
|
if session:
|
||||||
|
session.at_disconnect()
|
||||||
sessid = session.sessid
|
sessid = session.sessid
|
||||||
del self.sessions[sessid]
|
del self.sessions[sessid]
|
||||||
# inform portal that session should be closed.
|
# inform portal that session should be closed.
|
||||||
|
|
@ -206,7 +207,7 @@ class ServerSessionHandler(SessionHandler):
|
||||||
operation=SDISCONN,
|
operation=SDISCONN,
|
||||||
data=reason)
|
data=reason)
|
||||||
|
|
||||||
def login(self, session):
|
def login(self, session, player):
|
||||||
"""
|
"""
|
||||||
Log in the previously unloggedin session and the player we by
|
Log in the previously unloggedin session and the player we by
|
||||||
now should know is connected to it. After this point we
|
now should know is connected to it. After this point we
|
||||||
|
|
@ -214,15 +215,41 @@ class ServerSessionHandler(SessionHandler):
|
||||||
"""
|
"""
|
||||||
# prep the session with player/user info
|
# prep the session with player/user info
|
||||||
|
|
||||||
|
# we have to check this first before uid has been assigned
|
||||||
|
# this session.
|
||||||
|
|
||||||
|
if not self.sessions_from_player(player):
|
||||||
|
player.is_connected = True
|
||||||
|
|
||||||
|
# sets up and assigns all properties on the session
|
||||||
|
session.at_login(player)
|
||||||
|
|
||||||
|
# player init
|
||||||
|
player.at_init()
|
||||||
|
|
||||||
|
# Check if this is the first time the *player* logs in
|
||||||
|
if player.db.FIRST_LOGIN:
|
||||||
|
player.at_first_login()
|
||||||
|
del player.db.FIRST_LOGIN
|
||||||
|
|
||||||
|
player.at_pre_login()
|
||||||
|
|
||||||
|
session.log(_('Logged in: %(self)s') % {'self': self})
|
||||||
|
|
||||||
|
# start (persistent) scripts on this object
|
||||||
|
#ScriptDB.objects.validate(obj=self.player.character)
|
||||||
|
|
||||||
if MULTISESSION_MODE == 0:
|
if MULTISESSION_MODE == 0:
|
||||||
# disconnect all previous sessions.
|
# disconnect all previous sessions.
|
||||||
self.disconnect_duplicate_sessions(session)
|
self.disconnect_duplicate_sessions(session)
|
||||||
|
|
||||||
session.logged_in = True
|
session.logged_in = True
|
||||||
# sync the portal to this session
|
# sync the portal to the session
|
||||||
sessdata = session.get_sync_data()
|
sessdata = session.get_sync_data()
|
||||||
self.server.amp_protocol.call_remote_PortalAdmin(session.sessid,
|
self.server.amp_protocol.call_remote_PortalAdmin(session.sessid,
|
||||||
operation=SLOGIN,
|
operation=SLOGIN,
|
||||||
data=sessdata)
|
data=sessdata)
|
||||||
|
player.at_post_login()
|
||||||
|
|
||||||
def all_sessions_portal_sync(self):
|
def all_sessions_portal_sync(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue