Updated more of server/ to google docstrings as per #709.
This commit is contained in:
parent
57b2396af7
commit
00b5309295
3 changed files with 251 additions and 64 deletions
|
|
@ -60,12 +60,13 @@ class ServerSession(Session):
|
||||||
|
|
||||||
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
|
||||||
At this point all relevant attributes have already been set and
|
portal. At this point all relevant attributes have already
|
||||||
self.player been assigned (if applicable).
|
been set and self.player been assigned (if applicable).
|
||||||
|
|
||||||
|
Since this is often called after a server restart we need to
|
||||||
|
set up the session as it was.
|
||||||
|
|
||||||
Since this is often called after a server restart we need to set up
|
|
||||||
the session as it was.
|
|
||||||
"""
|
"""
|
||||||
global _ObjectDB
|
global _ObjectDB
|
||||||
if not _ObjectDB:
|
if not _ObjectDB:
|
||||||
|
|
@ -94,7 +95,9 @@ class ServerSession(Session):
|
||||||
"""
|
"""
|
||||||
Hook called by sessionhandler when the session becomes authenticated.
|
Hook called by sessionhandler when the session becomes authenticated.
|
||||||
|
|
||||||
player - the player associated with the session
|
Args:
|
||||||
|
player (Player): The player associated with the session.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.player = player
|
self.player = player
|
||||||
self.uid = self.player.id
|
self.uid = self.player.id
|
||||||
|
|
@ -115,6 +118,7 @@ class ServerSession(Session):
|
||||||
def at_disconnect(self):
|
def at_disconnect(self):
|
||||||
"""
|
"""
|
||||||
Hook called by sessionhandler when disconnecting this session.
|
Hook called by sessionhandler when disconnecting this session.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.logged_in:
|
if self.logged_in:
|
||||||
sessid = self.sessid
|
sessid = self.sessid
|
||||||
|
|
@ -136,21 +140,32 @@ class ServerSession(Session):
|
||||||
def get_player(self):
|
def get_player(self):
|
||||||
"""
|
"""
|
||||||
Get the player associated with this session
|
Get the player associated with this session
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
player (Player): The associated Player.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.logged_in and self.player
|
return self.logged_in and self.player
|
||||||
|
|
||||||
def get_puppet(self):
|
def get_puppet(self):
|
||||||
"""
|
"""
|
||||||
Returns the in-game character associated with this session.
|
Get the in-game character associated with this session.
|
||||||
This returns the typeclass of the object.
|
|
||||||
|
Returns:
|
||||||
|
puppet (Object): The puppeted object, if any.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.logged_in and self.puppet
|
return self.logged_in and self.puppet
|
||||||
get_character = get_puppet
|
get_character = get_puppet
|
||||||
|
|
||||||
def get_puppet_or_player(self):
|
def get_puppet_or_player(self):
|
||||||
"""
|
"""
|
||||||
Returns session if not logged in; puppet if one exists,
|
Get puppet or player.
|
||||||
otherwise return the player.
|
|
||||||
|
Returns:
|
||||||
|
controller (Object or Player): The puppet if one exists,
|
||||||
|
otherwise return the player.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.logged_in:
|
if self.logged_in:
|
||||||
return self.puppet if self.puppet else self.player
|
return self.puppet if self.puppet else self.player
|
||||||
|
|
@ -159,6 +174,12 @@ class ServerSession(Session):
|
||||||
def log(self, message, channel=True):
|
def log(self, message, channel=True):
|
||||||
"""
|
"""
|
||||||
Emits session info to the appropriate outputs and info channels.
|
Emits session info to the appropriate outputs and info channels.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
message (str): The message to log.
|
||||||
|
channel (bool, optional): Log to the CHANNEL_CONNECTINFO channel
|
||||||
|
in addition to the server log.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if channel:
|
if channel:
|
||||||
try:
|
try:
|
||||||
|
|
@ -173,7 +194,8 @@ class ServerSession(Session):
|
||||||
"""
|
"""
|
||||||
Return eventual eventual width and height reported by the
|
Return eventual eventual width and height reported by the
|
||||||
client. Note that this currently only deals with a single
|
client. Note that this currently only deals with a single
|
||||||
client window (windowID==0) as in traditional telnet session
|
client window (windowID==0) as in a traditional telnet session.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
flags = self.protocol_flags
|
flags = self.protocol_flags
|
||||||
width = flags.get('SCREENWIDTH', {}).get(0, settings.CLIENT_DEFAULT_WIDTH)
|
width = flags.get('SCREENWIDTH', {}).get(0, settings.CLIENT_DEFAULT_WIDTH)
|
||||||
|
|
@ -182,8 +204,9 @@ class ServerSession(Session):
|
||||||
|
|
||||||
def update_session_counters(self, idle=False):
|
def update_session_counters(self, idle=False):
|
||||||
"""
|
"""
|
||||||
Hit this when the user enters a command in order to update idle timers
|
Hit this when the user enters a command in order to update
|
||||||
and command counters.
|
idle timers and command counters.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# Store the timestamp of the user's last command.
|
# Store the timestamp of the user's last command.
|
||||||
if not idle:
|
if not idle:
|
||||||
|
|
@ -194,12 +217,16 @@ class ServerSession(Session):
|
||||||
|
|
||||||
def data_in(self, text=None, **kwargs):
|
def data_in(self, text=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Send User->Evennia. This will in effect
|
Send data User->Evennia. This will in effect execute a command
|
||||||
execute a command string on the server.
|
string on the server.
|
||||||
|
|
||||||
Note that oob data is already sent to the
|
Note that oob data is already sent separately to the
|
||||||
oobhandler at this point.
|
oobhandler at this point.
|
||||||
|
|
||||||
|
Kwargs:
|
||||||
|
text (str): A text to relay
|
||||||
|
kwargs (any): Other parameters from the protocol.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
#explicitly check for None since text can be an empty string, which is
|
#explicitly check for None since text can be an empty string, which is
|
||||||
#also valid
|
#also valid
|
||||||
|
|
@ -227,6 +254,11 @@ class ServerSession(Session):
|
||||||
def data_out(self, text=None, **kwargs):
|
def data_out(self, text=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Send Evennia -> User
|
Send Evennia -> User
|
||||||
|
|
||||||
|
Kwargs:
|
||||||
|
text (str): A text to relay
|
||||||
|
kwargs (any): Other parameters to the protocol.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
text = text if text else ""
|
text = text if text else ""
|
||||||
if _INLINEFUNC_ENABLED and not "raw" in kwargs:
|
if _INLINEFUNC_ENABLED and not "raw" in kwargs:
|
||||||
|
|
@ -244,12 +276,14 @@ class ServerSession(Session):
|
||||||
msg = data_out
|
msg = data_out
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
|
"Handle session comparisons"
|
||||||
return self.address == other.address
|
return self.address == other.address
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""
|
"""
|
||||||
String representation of the user session class. We use
|
String representation of the user session class. We use
|
||||||
this a lot in the server logs.
|
this a lot in the server logs.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
symbol = ""
|
symbol = ""
|
||||||
if self.logged_in and hasattr(self, "player") and self.player:
|
if self.logged_in and hasattr(self, "player") and self.player:
|
||||||
|
|
@ -264,15 +298,16 @@ class ServerSession(Session):
|
||||||
return "%s%s@%s" % (self.uname, symbol, address)
|
return "%s%s@%s" % (self.uname, symbol, address)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
"""
|
"Unicode representation"
|
||||||
Unicode representation
|
|
||||||
"""
|
|
||||||
return u"%s" % str(self)
|
return u"%s" % str(self)
|
||||||
|
|
||||||
# Dummy API hooks for use during non-loggedin operation
|
# Dummy API hooks for use during non-loggedin operation
|
||||||
|
|
||||||
def at_cmdset_get(self, **kwargs):
|
def at_cmdset_get(self, **kwargs):
|
||||||
"dummy hook all objects with cmdsets need to have"
|
"""
|
||||||
|
A dummy hook all objects with cmdsets need to have
|
||||||
|
"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Mock db/ndb properties for allowing easy storage on the session
|
# Mock db/ndb properties for allowing easy storage on the session
|
||||||
|
|
@ -286,6 +321,7 @@ class ServerSession(Session):
|
||||||
to this is guaranteed to be cleared when a server is shutdown.
|
to this is guaranteed to be cleared when a server is shutdown.
|
||||||
Syntax is same as for the _get_db_holder() method and
|
Syntax is same as for the _get_db_holder() method and
|
||||||
property, e.g. obj.ndb.attr = value etc.
|
property, e.g. obj.ndb.attr = value etc.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return self._ndb_holder
|
return self._ndb_holder
|
||||||
|
|
@ -307,7 +343,13 @@ class ServerSession(Session):
|
||||||
|
|
||||||
#@ndb.setter
|
#@ndb.setter
|
||||||
def ndb_set(self, value):
|
def ndb_set(self, value):
|
||||||
"Stop accidentally replacing the db object"
|
"""
|
||||||
|
Stop accidentally replacing the db object
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value (any): A value to store in the ndb.
|
||||||
|
|
||||||
|
"""
|
||||||
string = "Cannot assign directly to ndb object! "
|
string = "Cannot assign directly to ndb object! "
|
||||||
string = "Use ndb.attr=value instead."
|
string = "Use ndb.attr=value instead."
|
||||||
raise Exception(string)
|
raise Exception(string)
|
||||||
|
|
@ -322,5 +364,5 @@ class ServerSession(Session):
|
||||||
# Mock access method for the session (there is no lock info
|
# Mock access method for the session (there is no lock info
|
||||||
# at this stage, so we just present a uniform API)
|
# at this stage, so we just present a uniform API)
|
||||||
def access(self, *args, **kwargs):
|
def access(self, *args, **kwargs):
|
||||||
"Dummy method."
|
"Dummy method to mimic the logged-in API."
|
||||||
return True
|
return True
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"""
|
"""
|
||||||
This defines a generic session class. All connection instances (both
|
This module defines a generic session class. All connection instances
|
||||||
on Portal and Server side) should inherit from this class.
|
(both on Portal and Server side) should inherit from this class.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -18,13 +18,13 @@ class Session(object):
|
||||||
|
|
||||||
Each connection will see two session instances created:
|
Each connection will see two session instances created:
|
||||||
|
|
||||||
1) A Portal session. This is customized for the respective connection
|
1. A Portal session. This is customized for the respective connection
|
||||||
protocols that Evennia supports, like Telnet, SSH etc. The Portal
|
protocols that Evennia supports, like Telnet, SSH etc. The Portal
|
||||||
session must call init_session() as part of its initialization. The
|
session must call init_session() as part of its initialization. The
|
||||||
respective hook methods should be connected to the methods unique
|
respective hook methods should be connected to the methods unique
|
||||||
for the respective protocol so that there is a unified interface
|
for the respective protocol so that there is a unified interface
|
||||||
to Evennia.
|
to Evennia.
|
||||||
2) A Server session. This is the same for all connected players,
|
2. A Server session. This is the same for all connected players,
|
||||||
regardless of how they connect.
|
regardless of how they connect.
|
||||||
|
|
||||||
The Portal and Server have their own respective sessionhandlers. These
|
The Portal and Server have their own respective sessionhandlers. These
|
||||||
|
|
@ -44,9 +44,14 @@ class Session(object):
|
||||||
"""
|
"""
|
||||||
Initialize the Session. This should be called by the protocol when
|
Initialize the Session. This should be called by the protocol when
|
||||||
a new session is established.
|
a new session is established.
|
||||||
protocol_key - telnet, ssh, ssl or web
|
|
||||||
address - client address
|
Args:
|
||||||
sessionhandler - reference to the sessionhandler instance
|
protocol_key (str): By default, one of 'telnet', 'ssh',
|
||||||
|
'ssl' or 'web'.
|
||||||
|
address (str): Client address.
|
||||||
|
sessionhandler (SessionHandler): Reference to the
|
||||||
|
main sessionhandler instance.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# This is currently 'telnet', 'ssh', 'ssl' or 'web'
|
# This is currently 'telnet', 'ssh', 'ssl' or 'web'
|
||||||
self.protocol_key = protocol_key
|
self.protocol_key = protocol_key
|
||||||
|
|
@ -85,15 +90,24 @@ class Session(object):
|
||||||
|
|
||||||
def get_sync_data(self):
|
def get_sync_data(self):
|
||||||
"""
|
"""
|
||||||
Return all data relevant to sync the session
|
Get all data relevant to sync the session.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
syncdata (dict): All syncdata values, based on
|
||||||
|
the keys given by self._attrs_to_sync.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return dict((key, value) for key, value in self.__dict__.items()
|
return dict((key, value) for key, value in self.__dict__.items()
|
||||||
if key in self._attrs_to_sync)
|
if key in self._attrs_to_sync)
|
||||||
|
|
||||||
def load_sync_data(self, sessdata):
|
def load_sync_data(self, sessdata):
|
||||||
"""
|
"""
|
||||||
Takes a session dictionary, as created by get_sync_data,
|
Takes a session dictionary, as created by get_sync_data, and
|
||||||
and loads it into the correct properties of the session.
|
loads it into the correct properties of the session.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sessdata (dict): Session data dictionary.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
for propname, value in sessdata.items():
|
for propname, value in sessdata.items():
|
||||||
setattr(self, propname, value)
|
setattr(self, propname, value)
|
||||||
|
|
@ -103,6 +117,7 @@ class Session(object):
|
||||||
Called after a session has been fully synced (including
|
Called after a session has been fully synced (including
|
||||||
secondary operations such as setting self.player based
|
secondary operations such as setting self.player based
|
||||||
on uid etc).
|
on uid etc).
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
@ -112,19 +127,33 @@ class Session(object):
|
||||||
"""
|
"""
|
||||||
generic hook called from the outside to disconnect this session
|
generic hook called from the outside to disconnect this session
|
||||||
should be connected to the protocols actual disconnect mechanism.
|
should be connected to the protocols actual disconnect mechanism.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
reason (str): Eventual text motivating the disconnect.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def data_out(self, text=None, **kwargs):
|
def data_out(self, text=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
generic hook for sending data out through the protocol. Server
|
Generic hook for sending data out through the protocol. Server
|
||||||
protocols can use this right away. Portal sessions
|
protocols can use this right away. Portal sessions
|
||||||
should overload this to format/handle the outgoing data as needed.
|
should overload this to format/handle the outgoing data as needed.
|
||||||
|
|
||||||
|
Kwargs:
|
||||||
|
text (str): Text data
|
||||||
|
kwargs (any): Other data to the protocol.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def data_in(self, text=None, **kwargs):
|
def data_in(self, text=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
hook for protocols to send incoming data to the engine.
|
Hook for protocols to send incoming data to the engine.
|
||||||
|
|
||||||
|
Kwargs:
|
||||||
|
text (str): Text data
|
||||||
|
kwargs (any): Other data from the protocol.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,11 @@ This module defines handlers for storing sessions when handles
|
||||||
sessions of users connecting to the server.
|
sessions of users connecting to the server.
|
||||||
|
|
||||||
There are two similar but separate stores of sessions:
|
There are two similar but separate stores of sessions:
|
||||||
ServerSessionHandler - this stores generic game sessions
|
|
||||||
|
- ServerSessionHandler - this stores generic game sessions
|
||||||
for the game. These sessions has no knowledge about
|
for the game. These sessions has no knowledge about
|
||||||
how they are connected to the world.
|
how they are connected to the world.
|
||||||
PortalSessionHandler - this stores sessions created by
|
- PortalSessionHandler - this stores sessions created by
|
||||||
twisted protocols. These are dumb connectors that
|
twisted protocols. These are dumb connectors that
|
||||||
handle network communication but holds no game info.
|
handle network communication but holds no game info.
|
||||||
|
|
||||||
|
|
@ -53,7 +54,10 @@ _MAX_SERVER_COMMANDS_PER_SECOND = 100.0
|
||||||
_MAX_SESSION_COMMANDS_PER_SECOND = 5.0
|
_MAX_SESSION_COMMANDS_PER_SECOND = 5.0
|
||||||
|
|
||||||
def delayed_import():
|
def delayed_import():
|
||||||
"Helper method for delayed import of all needed entities"
|
"""
|
||||||
|
Helper method for delayed import of all needed entities.
|
||||||
|
|
||||||
|
"""
|
||||||
global _ServerSession, _PlayerDB, _ServerConfig, _ScriptDB
|
global _ServerSession, _PlayerDB, _ServerConfig, _ScriptDB
|
||||||
if not _ServerSession:
|
if not _ServerSession:
|
||||||
# we allow optional arbitrary serversession class for overloading
|
# we allow optional arbitrary serversession class for overloading
|
||||||
|
|
@ -76,16 +80,26 @@ def delayed_import():
|
||||||
class SessionHandler(object):
|
class SessionHandler(object):
|
||||||
"""
|
"""
|
||||||
This handler holds a stack of sessions.
|
This handler holds a stack of sessions.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""
|
"""
|
||||||
Init the handler.
|
Init the handler.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.sessions = {}
|
self.sessions = {}
|
||||||
|
|
||||||
def get_sessions(self, include_unloggedin=False):
|
def get_sessions(self, include_unloggedin=False):
|
||||||
"""
|
"""
|
||||||
Returns the connected session objects.
|
Returns the connected session objects.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
include_unloggedin (bool, optional): Also list Sessions
|
||||||
|
that have not yet authenticated.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
sessions (list): A list of `Session` objects.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if include_unloggedin:
|
if include_unloggedin:
|
||||||
return self.sessions.values()
|
return self.sessions.values()
|
||||||
|
|
@ -94,7 +108,14 @@ class SessionHandler(object):
|
||||||
|
|
||||||
def get_session(self, sessid):
|
def get_session(self, sessid):
|
||||||
"""
|
"""
|
||||||
Get session by sessid
|
Get session by sessid.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sessid (int): Session id.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
session (Session): A `Session` object, if found.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.sessions.get(sessid, None)
|
return self.sessions.get(sessid, None)
|
||||||
|
|
||||||
|
|
@ -102,6 +123,10 @@ class SessionHandler(object):
|
||||||
"""
|
"""
|
||||||
Create a dictionary of sessdata dicts representing all
|
Create a dictionary of sessdata dicts representing all
|
||||||
sessions in store.
|
sessions in store.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
syncdata (dict): A dict of sync data.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return dict((sessid, sess.get_sync_data()) for sessid, sess in self.sessions.items())
|
return dict((sessid, sess.get_sync_data()) for sessid, sess in self.sessions.items())
|
||||||
|
|
||||||
|
|
@ -128,26 +153,29 @@ class ServerSessionHandler(SessionHandler):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""
|
"""
|
||||||
Init the handler.
|
Init the handler.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.sessions = {}
|
self.sessions = {}
|
||||||
self.server = None
|
self.server = None
|
||||||
self.server_data = {"servername": _SERVERNAME}
|
self.server_data = {"servername": _SERVERNAME}
|
||||||
|
|
||||||
def portal_connect(self, portalsession):
|
def portal_connect(self, portalsessiondata):
|
||||||
"""
|
"""
|
||||||
Called by Portal when a new session has connected.
|
Called by Portal when a new session has connected.
|
||||||
Creates a new, unlogged-in game session.
|
Creates a new, unlogged-in game session.
|
||||||
|
|
||||||
portalsession is a dictionary of all property:value keys
|
Args:
|
||||||
defining the session and which is marked to
|
portalsessiondata (dict): a dictionary of all property:value
|
||||||
be synced.
|
keys defining the session and which is marked to be
|
||||||
|
synced.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
delayed_import()
|
delayed_import()
|
||||||
global _ServerSession, _PlayerDB, _ScriptDB
|
global _ServerSession, _PlayerDB, _ScriptDB
|
||||||
|
|
||||||
sess = _ServerSession()
|
sess = _ServerSession()
|
||||||
sess.sessionhandler = self
|
sess.sessionhandler = self
|
||||||
sess.load_sync_data(portalsession)
|
sess.load_sync_data(portalsessiondata)
|
||||||
if sess.logged_in and sess.uid:
|
if sess.logged_in and sess.uid:
|
||||||
# this can happen in the case of auto-authenticating
|
# this can happen in the case of auto-authenticating
|
||||||
# protocols like SSH
|
# protocols like SSH
|
||||||
|
|
@ -162,6 +190,12 @@ class ServerSessionHandler(SessionHandler):
|
||||||
"""
|
"""
|
||||||
Called by Portal when it wants to update a single session (e.g.
|
Called by Portal when it wants to update a single session (e.g.
|
||||||
because of all negotiation protocols have finally replied)
|
because of all negotiation protocols have finally replied)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
portalsessiondata (dict): a dictionary of all property:value
|
||||||
|
keys defining the session and which is marked to be
|
||||||
|
synced.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
sessid = portalsessiondata.get("sessid")
|
sessid = portalsessiondata.get("sessid")
|
||||||
session = self.sessions.get(sessid)
|
session = self.sessions.get(sessid)
|
||||||
|
|
@ -177,20 +211,26 @@ class ServerSessionHandler(SessionHandler):
|
||||||
"""
|
"""
|
||||||
Called by Portal when portal reports a closing of a session
|
Called by Portal when portal reports a closing of a session
|
||||||
from the portal side.
|
from the portal side.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sessid (int): Session id.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
session = self.sessions.get(sessid, None)
|
session = self.sessions.get(sessid, None)
|
||||||
if not session:
|
if not session:
|
||||||
return
|
return
|
||||||
self.disconnect(session)
|
self.disconnect(session)
|
||||||
|
|
||||||
def portal_sessions_sync(self, portalsessions):
|
def portal_sessions_sync(self, portalsessionsdata):
|
||||||
"""
|
"""
|
||||||
Syncing all session ids of the portal with the ones of the
|
Syncing all session ids of the portal with the ones of the
|
||||||
server. This is instantiated by the portal when reconnecting.
|
server. This is instantiated by the portal when reconnecting.
|
||||||
|
|
||||||
portalsessions is a dictionary {sessid: {property:value},...} defining
|
Args:
|
||||||
each session and the properties in it which should
|
portalsessionsdata (dict): A dictionary
|
||||||
be synced.
|
`{sessid: {property:value},...}` defining each session and
|
||||||
|
the properties in it which should be synced.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
delayed_import()
|
delayed_import()
|
||||||
global _ServerSession, _PlayerDB, _ServerConfig, _ScriptDB
|
global _ServerSession, _PlayerDB, _ServerConfig, _ScriptDB
|
||||||
|
|
@ -200,7 +240,7 @@ class ServerSessionHandler(SessionHandler):
|
||||||
# lingering references.
|
# lingering references.
|
||||||
del sess
|
del sess
|
||||||
|
|
||||||
for sessid, sessdict in portalsessions.items():
|
for sessid, sessdict in portalsessionsdata.items():
|
||||||
sess = _ServerSession()
|
sess = _ServerSession()
|
||||||
sess.sessionhandler = self
|
sess.sessionhandler = self
|
||||||
sess.load_sync_data(sessdict)
|
sess.load_sync_data(sessdict)
|
||||||
|
|
@ -221,14 +261,26 @@ class ServerSessionHandler(SessionHandler):
|
||||||
|
|
||||||
def start_bot_session(self, protocol_path, configdict):
|
def start_bot_session(self, protocol_path, configdict):
|
||||||
"""
|
"""
|
||||||
This method allows the server-side to force the Portal to create
|
This method allows the server-side to force the Portal to
|
||||||
a new bot session using the protocol specified by protocol_path,
|
create a new bot session.
|
||||||
which should be the full python path to the class, including the
|
|
||||||
class name, like "evennia.server.portal.irc.IRCClient".
|
Args:
|
||||||
The new session will use the supplied player-bot uid to
|
protocol_path (str): The full python path to the bot's
|
||||||
initiate an already logged-in connection. The Portal will
|
class.
|
||||||
treat this as a normal connection and henceforth so will the
|
configdict (dict): This dict will be used to configure
|
||||||
Server.
|
the bot (this depends on the bot protocol).
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
start_bot_session("evennia.server.portal.irc.IRCClient",
|
||||||
|
{"uid":1, "botname":"evbot", "channel":"#evennia",
|
||||||
|
"network:"irc.freenode.net", "port": 6667})
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
The new session will use the supplied player-bot uid to
|
||||||
|
initiate an already logged-in connection. The Portal will
|
||||||
|
treat this as a normal connection and henceforth so will
|
||||||
|
the Server.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
data = {"protocol_path":protocol_path,
|
data = {"protocol_path":protocol_path,
|
||||||
"config":configdict}
|
"config":configdict}
|
||||||
|
|
@ -239,6 +291,7 @@ class ServerSessionHandler(SessionHandler):
|
||||||
def portal_shutdown(self):
|
def portal_shutdown(self):
|
||||||
"""
|
"""
|
||||||
Called by server when shutting down the portal.
|
Called by server when shutting down the portal.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.server.amp_protocol.call_remote_PortalAdmin(0,
|
self.server.amp_protocol.call_remote_PortalAdmin(0,
|
||||||
operation=SSHUTD,
|
operation=SSHUTD,
|
||||||
|
|
@ -247,11 +300,15 @@ class ServerSessionHandler(SessionHandler):
|
||||||
def login(self, session, player, testmode=False):
|
def login(self, session, player, testmode=False):
|
||||||
"""
|
"""
|
||||||
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 assume
|
||||||
assume the session to be logged in one way or another.
|
the session to be logged in one way or another.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
session (Session): The Session to authenticate.
|
||||||
|
player (Player): The Player identified as associated with this Session.
|
||||||
|
testmode (bool, optional): This is used by unittesting for
|
||||||
|
faking login without any AMP being actually active.
|
||||||
|
|
||||||
testmode - this is used by unittesting for faking login without
|
|
||||||
any AMP being actually active
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# we have to check this first before uid has been assigned
|
# we have to check this first before uid has been assigned
|
||||||
|
|
@ -295,6 +352,11 @@ class ServerSessionHandler(SessionHandler):
|
||||||
"""
|
"""
|
||||||
Called from server side to remove session and inform portal
|
Called from server side to remove session and inform portal
|
||||||
of this fact.
|
of this fact.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
session (Session): The Session to disconnect.
|
||||||
|
reason (str, optional): A motivation for the disconnect.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
session = self.sessions.get(session.sessid)
|
session = self.sessions.get(session.sessid)
|
||||||
if not session:
|
if not session:
|
||||||
|
|
@ -319,6 +381,7 @@ class ServerSessionHandler(SessionHandler):
|
||||||
"""
|
"""
|
||||||
This is called by the server when it reboots. It syncs all session data
|
This is called by the server when it reboots. It syncs all session data
|
||||||
to the portal. Returns a deferred!
|
to the portal. Returns a deferred!
|
||||||
|
|
||||||
"""
|
"""
|
||||||
sessdata = self.get_all_sync_data()
|
sessdata = self.get_all_sync_data()
|
||||||
return self.server.amp_protocol.call_remote_PortalAdmin(0,
|
return self.server.amp_protocol.call_remote_PortalAdmin(0,
|
||||||
|
|
@ -328,6 +391,10 @@ class ServerSessionHandler(SessionHandler):
|
||||||
def disconnect_all_sessions(self, reason="You have been disconnected."):
|
def disconnect_all_sessions(self, reason="You have been disconnected."):
|
||||||
"""
|
"""
|
||||||
Cleanly disconnect all of the connected sessions.
|
Cleanly disconnect all of the connected sessions.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
reason (str, optional): The reason for the disconnection.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for session in self.sessions:
|
for session in self.sessions:
|
||||||
|
|
@ -341,6 +408,11 @@ class ServerSessionHandler(SessionHandler):
|
||||||
reason=_("Logged in from elsewhere. Disconnecting.")):
|
reason=_("Logged in from elsewhere. Disconnecting.")):
|
||||||
"""
|
"""
|
||||||
Disconnects any existing sessions with the same user.
|
Disconnects any existing sessions with the same user.
|
||||||
|
|
||||||
|
args:
|
||||||
|
curr_session (Session): Disconnect all Sessions matching this one.
|
||||||
|
reason (str, optional): A motivation for disconnecting.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
uid = curr_session.uid
|
uid = curr_session.uid
|
||||||
doublet_sessions = [sess for sess in self.sessions.values()
|
doublet_sessions = [sess for sess in self.sessions.values()
|
||||||
|
|
@ -352,8 +424,9 @@ class ServerSessionHandler(SessionHandler):
|
||||||
|
|
||||||
def validate_sessions(self):
|
def validate_sessions(self):
|
||||||
"""
|
"""
|
||||||
Check all currently connected sessions (logged in and not)
|
Check all currently connected sessions (logged in and not) and
|
||||||
and see if any are dead or idle
|
see if any are dead or idle.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
tcurr = time()
|
tcurr = time()
|
||||||
reason = _("Idle timeout exceeded, disconnecting.")
|
reason = _("Idle timeout exceeded, disconnecting.")
|
||||||
|
|
@ -387,7 +460,14 @@ class ServerSessionHandler(SessionHandler):
|
||||||
|
|
||||||
def session_from_sessid(self, sessid):
|
def session_from_sessid(self, sessid):
|
||||||
"""
|
"""
|
||||||
Return session based on sessid, or None if not found
|
Get session based on sessid, or None if not found
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sessid (int or list): Session id(s)
|
||||||
|
|
||||||
|
Return:
|
||||||
|
sessions (Session or list): Session(s) found.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if is_iter(sessid):
|
if is_iter(sessid):
|
||||||
return [self.sessions.get(sid) for sid in sessid if sid in self.sessions]
|
return [self.sessions.get(sid) for sid in sessid if sid in self.sessions]
|
||||||
|
|
@ -395,7 +475,16 @@ class ServerSessionHandler(SessionHandler):
|
||||||
|
|
||||||
def session_from_player(self, player, sessid):
|
def session_from_player(self, player, sessid):
|
||||||
"""
|
"""
|
||||||
Given a player and a session id, return the actual session object
|
Given a player and a session id, return the actual session
|
||||||
|
object.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
player (Player): The Player to get the Session from.
|
||||||
|
sessid (int or list): Session id(s).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
sessions (Session or list): Session(s) found.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if is_iter(sessid):
|
if is_iter(sessid):
|
||||||
sessions = [self.sessions.get(sid) for sid in sessid]
|
sessions = [self.sessions.get(sid) for sid in sessid]
|
||||||
|
|
@ -407,6 +496,13 @@ class ServerSessionHandler(SessionHandler):
|
||||||
def sessions_from_player(self, player):
|
def sessions_from_player(self, player):
|
||||||
"""
|
"""
|
||||||
Given a player, return all matching sessions.
|
Given a player, return all matching sessions.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
player (Player): Player to get sessions from.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
sessions (list): All Sessions associated with this player.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
uid = player.uid
|
uid = player.uid
|
||||||
return [session for session in self.sessions.values() if session.logged_in and session.uid == uid]
|
return [session for session in self.sessions.values() if session.logged_in and session.uid == uid]
|
||||||
|
|
@ -414,6 +510,14 @@ class ServerSessionHandler(SessionHandler):
|
||||||
def sessions_from_puppet(self, puppet):
|
def sessions_from_puppet(self, puppet):
|
||||||
"""
|
"""
|
||||||
Given a puppeted object, return all controlling sessions.
|
Given a puppeted object, return all controlling sessions.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
puppet (Object): Object puppeted
|
||||||
|
|
||||||
|
Returns.
|
||||||
|
sessions (Session or list): Can be more than one of Object is controlled by
|
||||||
|
more than one Session (MULTISESSION_MODE > 1).
|
||||||
|
|
||||||
"""
|
"""
|
||||||
sessid = puppet.sessid.get()
|
sessid = puppet.sessid.get()
|
||||||
if is_iter(sessid):
|
if is_iter(sessid):
|
||||||
|
|
@ -424,6 +528,10 @@ class ServerSessionHandler(SessionHandler):
|
||||||
def announce_all(self, message):
|
def announce_all(self, message):
|
||||||
"""
|
"""
|
||||||
Send message to all connected sessions
|
Send message to all connected sessions
|
||||||
|
|
||||||
|
Args:
|
||||||
|
message (str): Message to send.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
for sess in self.sessions.values():
|
for sess in self.sessions.values():
|
||||||
self.data_out(sess, message)
|
self.data_out(sess, message)
|
||||||
|
|
@ -482,6 +590,14 @@ class ServerSessionHandler(SessionHandler):
|
||||||
"""
|
"""
|
||||||
Data Portal -> Server.
|
Data Portal -> Server.
|
||||||
We also intercept OOB communication here.
|
We also intercept OOB communication here.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sessid (int): Session id.
|
||||||
|
|
||||||
|
Kwargs:
|
||||||
|
text (str): Text from protocol.
|
||||||
|
kwargs (any): Other data from protocol.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
session = self.sessions.get(sessid, None)
|
session = self.sessions.get(sessid, None)
|
||||||
if session:
|
if session:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue