Reworked most of the system to use sessions directly instead of sessids by the introduction of on-object sessionhandlers. No debugging done yet.
This commit is contained in:
parent
556a0cc332
commit
709f5ff5b3
5 changed files with 234 additions and 259 deletions
|
|
@ -138,8 +138,7 @@ class ErrorReported(Exception):
|
||||||
# Helper function
|
# Helper function
|
||||||
|
|
||||||
@inlineCallbacks
|
@inlineCallbacks
|
||||||
def get_and_merge_cmdsets(caller, session, player, obj,
|
def get_and_merge_cmdsets(caller, session, player, obj, callertype):
|
||||||
callertype, sessid=None):
|
|
||||||
"""
|
"""
|
||||||
Gather all relevant cmdsets and merge them.
|
Gather all relevant cmdsets and merge them.
|
||||||
|
|
||||||
|
|
@ -154,7 +153,6 @@ def get_and_merge_cmdsets(caller, session, player, obj,
|
||||||
obj (Object or None): The Object associated with caller, if any.
|
obj (Object or None): The Object associated with caller, if any.
|
||||||
callertype (str): This identifies caller as either "player", "object" or "session"
|
callertype (str): This identifies caller as either "player", "object" or "session"
|
||||||
to avoid having to do this check internally.
|
to avoid having to do this check internally.
|
||||||
sessid (int, optional): Session ID. This is not used at the moment.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
cmdset (Deferred): This deferred fires with the merged cmdset
|
cmdset (Deferred): This deferred fires with the merged cmdset
|
||||||
|
|
@ -335,7 +333,7 @@ def get_and_merge_cmdsets(caller, session, player, obj,
|
||||||
|
|
||||||
|
|
||||||
@inlineCallbacks
|
@inlineCallbacks
|
||||||
def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sessid=None, **kwargs):
|
def cmdhandler(called_by, raw_string, _testing=False, callertype="session", session=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
This is the main mechanism that handles any string sent to the engine.
|
This is the main mechanism that handles any string sent to the engine.
|
||||||
|
|
||||||
|
|
@ -355,7 +353,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
||||||
cmdset and the Objects and so on. Merge order is the same
|
cmdset and the Objects and so on. Merge order is the same
|
||||||
order, so that Object cmdsets are merged in last, giving them
|
order, so that Object cmdsets are merged in last, giving them
|
||||||
precendence for same-name and same-prio commands.
|
precendence for same-name and same-prio commands.
|
||||||
sessid (int, optional): Relevant if callertype is "player" - the session id will help
|
session (int, optional): Relevant if callertype is "player" - the session will help
|
||||||
retrieve the correct cmdsets from puppeted objects.
|
retrieve the correct cmdsets from puppeted objects.
|
||||||
|
|
||||||
Kwargs:
|
Kwargs:
|
||||||
|
|
@ -398,7 +396,6 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
||||||
cmd.cmdstring = cmdname
|
cmd.cmdstring = cmdname
|
||||||
cmd.args = args
|
cmd.args = args
|
||||||
cmd.cmdset = cmdset
|
cmd.cmdset = cmdset
|
||||||
cmd.sessid = session.sessid if session else sessid
|
|
||||||
cmd.session = session
|
cmd.session = session
|
||||||
cmd.player = player
|
cmd.player = player
|
||||||
cmd.raw_string = unformatted_raw_string
|
cmd.raw_string = unformatted_raw_string
|
||||||
|
|
@ -460,17 +457,15 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
||||||
|
|
||||||
raw_string = to_unicode(raw_string, force_string=True)
|
raw_string = to_unicode(raw_string, force_string=True)
|
||||||
|
|
||||||
session, player, obj = None, None, None
|
session, player, obj = session, None, None
|
||||||
if callertype == "session":
|
if callertype == "session":
|
||||||
session = called_by
|
session = called_by
|
||||||
player = session.player
|
player = session.player
|
||||||
if player:
|
obj = session.puppet
|
||||||
obj = yield player.get_puppet(session.sessid)
|
|
||||||
elif callertype == "player":
|
elif callertype == "player":
|
||||||
player = called_by
|
player = called_by
|
||||||
if sessid:
|
if session:
|
||||||
session = player.get_session(sessid)
|
obj = yield session.puppet
|
||||||
obj = yield player.get_puppet(sessid)
|
|
||||||
elif callertype == "object":
|
elif callertype == "object":
|
||||||
obj = called_by
|
obj = called_by
|
||||||
else:
|
else:
|
||||||
|
|
@ -486,7 +481,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
||||||
try: # catch special-type commands
|
try: # catch special-type commands
|
||||||
|
|
||||||
cmdset = yield get_and_merge_cmdsets(caller, session, player, obj,
|
cmdset = yield get_and_merge_cmdsets(caller, session, player, obj,
|
||||||
callertype, sessid)
|
callertype)
|
||||||
if not cmdset:
|
if not cmdset:
|
||||||
# this is bad and shouldn't happen.
|
# this is bad and shouldn't happen.
|
||||||
raise NoCmdSets
|
raise NoCmdSets
|
||||||
|
|
@ -553,7 +548,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
||||||
if syscmd:
|
if syscmd:
|
||||||
# replace system command with custom version
|
# replace system command with custom version
|
||||||
cmd = syscmd
|
cmd = syscmd
|
||||||
cmd.sessid = session.sessid if session else None
|
cmd.session = session
|
||||||
sysarg = "%s:%s" % (cmdname, args)
|
sysarg = "%s:%s" % (cmdname, args)
|
||||||
raise ExecSystemCommand(cmd, sysarg)
|
raise ExecSystemCommand(cmd, sysarg)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ _SESSID_MAX = 16 if _MULTISESSION_MODE in (1, 3) else 1
|
||||||
|
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
class SessidHandler(object):
|
class ObjectSessionHandler(object):
|
||||||
"""
|
"""
|
||||||
Handles the get/setting of the sessid
|
Handles the get/setting of the sessid
|
||||||
comma-separated integer field
|
comma-separated integer field
|
||||||
|
|
@ -52,50 +52,86 @@ class SessidHandler(object):
|
||||||
self._recache()
|
self._recache()
|
||||||
|
|
||||||
def _recache(self):
|
def _recache(self):
|
||||||
self._cache = list(set(int(val) for val in (self.obj.db_sessid or "").split(",") if val))
|
self._sessid_cache = list(set(int(val) for val in (self.obj.db_sessid or "").split(",") if val))
|
||||||
|
|
||||||
def get(self):
|
def get(self, sessid=None):
|
||||||
"""
|
"""
|
||||||
Get the session ids.
|
Get the sessions linked to this Object.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sessid (int, optional): A specific session id.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
session (list): A cached list of one or more session ids.
|
sessions (list): The sessions connected to this object. If `sessid` is given,
|
||||||
|
this is a list of one (or zero) elements.
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
Aliased to `self.all()`.
|
Aliased to `self.all()`.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self._cache
|
global _SESSIONS
|
||||||
all = get # alias
|
if not _SESSIONS:
|
||||||
|
from evennia.server.sessionhandler import SESSIONS as _SESSIONS
|
||||||
|
if sessid:
|
||||||
|
return [_SESSIONS[sessid]] if sessid in self._sessid_cache and sessid in _SESSIONS else []
|
||||||
|
else:
|
||||||
|
return [_SESSIONS[sessid] for sessid in self._sessid_cache if sessid in _SESSIONS]
|
||||||
|
|
||||||
def add(self, sessid):
|
def all(self):
|
||||||
"""
|
"""
|
||||||
Add sessid to handler.
|
Alias to get(), returning all sessions.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
sessions (list): All sessions.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self.get()
|
||||||
|
|
||||||
|
def add(self, session):
|
||||||
|
"""
|
||||||
|
Add session to handler.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
sessid (int): Session id to add.
|
session (Session or int): Session or session id to add.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
We will only add a session/sessid if this actually also exists
|
||||||
|
in the the core sessionhandler.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
_cache = self._cache
|
global _SESSIONS
|
||||||
if sessid not in _cache:
|
if not _SESSIONS:
|
||||||
if len(_cache) >= _SESSID_MAX:
|
from evennia.server.sessionhandler import SESSIONS as _SESSIONS
|
||||||
|
try:
|
||||||
|
sessid = session.sessid
|
||||||
|
except AttributeError:
|
||||||
|
sessid = session
|
||||||
|
|
||||||
|
sessid_cache = self._sessid_cache
|
||||||
|
if sessid in _SESSIONS and sessid not in sessid_cache:
|
||||||
|
if len(sessid_cache) >= _SESSID_MAX:
|
||||||
return
|
return
|
||||||
_cache.append(sessid)
|
sessid_cache.append(sessid)
|
||||||
self.obj.db_sessid = ",".join(str(val) for val in _cache)
|
self.obj.db_sessid = ",".join(str(val) for val in sessid_cache)
|
||||||
self.obj.save(update_fields=["db_sessid"])
|
self.obj.save(update_fields=["db_sessid"])
|
||||||
|
|
||||||
def remove(self, sessid):
|
def remove(self, session):
|
||||||
"""
|
"""
|
||||||
Remove sessid from handler.
|
Remove session from handler.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
sessid (int): Session id to remove.
|
sessid (Session or int): Session or session id to remove.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
_cache = self._cache
|
try:
|
||||||
if sessid in _cache:
|
sessid = session.sessid
|
||||||
_cache.remove(sessid)
|
except AttributeError:
|
||||||
self.obj.db_sessid = ",".join(str(val) for val in _cache)
|
sessid = session
|
||||||
|
|
||||||
|
sessid_cache = self._sessid_cache
|
||||||
|
if sessid in sessid_cache:
|
||||||
|
sessid_cache.remove(sessid)
|
||||||
|
self.obj.db_sessid = ",".join(str(val) for val in sessid_cache)
|
||||||
self.obj.save(update_fields=["db_sessid"])
|
self.obj.save(update_fields=["db_sessid"])
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
|
|
@ -103,7 +139,7 @@ class SessidHandler(object):
|
||||||
Clear all handled sessids.
|
Clear all handled sessids.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self._cache = []
|
self._sessid_cache = []
|
||||||
self.obj.db_sessid = None
|
self.obj.db_sessid = None
|
||||||
self.obj.save(update_fields=["db_sessid"])
|
self.obj.save(update_fields=["db_sessid"])
|
||||||
|
|
||||||
|
|
@ -152,19 +188,8 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
||||||
return NickHandler(self)
|
return NickHandler(self)
|
||||||
|
|
||||||
@lazy_property
|
@lazy_property
|
||||||
def sessid(self):
|
|
||||||
return SessidHandler(self)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def sessions(self):
|
def sessions(self):
|
||||||
"""
|
return ObjectSessionHandler(self)
|
||||||
Retrieve sessions connected to this object.
|
|
||||||
|
|
||||||
"""
|
|
||||||
# if the player is not connected, this will simply be an empty list.
|
|
||||||
if self.db_player:
|
|
||||||
return self.db_player.get_all_sessions()
|
|
||||||
return []
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def has_player(self):
|
def has_player(self):
|
||||||
|
|
@ -372,7 +397,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
||||||
return results
|
return results
|
||||||
return _AT_SEARCH_RESULT(results, self, query=searchdata)
|
return _AT_SEARCH_RESULT(results, self, query=searchdata)
|
||||||
|
|
||||||
def execute_cmd(self, raw_string, sessid=None, **kwargs):
|
def execute_cmd(self, raw_string, session=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Do something as this object. This method is a copy of the
|
Do something as this object. This method is a copy of the
|
||||||
`execute_cmd` method on the session. This is never called
|
`execute_cmd` method on the session. This is never called
|
||||||
|
|
@ -382,7 +407,8 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
raw_string (string): Raw command input
|
raw_string (string): Raw command input
|
||||||
sessid (int, optional): Session id to return results to
|
session (Session, optional): Session to
|
||||||
|
return results to
|
||||||
|
|
||||||
Kwargs:
|
Kwargs:
|
||||||
Other keyword arguments will be added to the found command
|
Other keyword arguments will be added to the found command
|
||||||
|
|
@ -407,10 +433,10 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
||||||
raw_string = to_unicode(raw_string)
|
raw_string = to_unicode(raw_string)
|
||||||
raw_string = self.nicks.nickreplace(raw_string,
|
raw_string = self.nicks.nickreplace(raw_string,
|
||||||
categories=("inputline", "channel"), include_player=True)
|
categories=("inputline", "channel"), include_player=True)
|
||||||
return cmdhandler.cmdhandler(self, raw_string, callertype="object", sessid=sessid, **kwargs)
|
return cmdhandler.cmdhandler(self, raw_string, callertype="object", session=session, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def msg(self, text=None, from_obj=None, sessid=0, **kwargs):
|
def msg(self, text=None, from_obj=None, session=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Emits something to a session attached to the object.
|
Emits something to a session attached to the object.
|
||||||
|
|
||||||
|
|
@ -418,17 +444,19 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
||||||
text (str, optional): The message to send
|
text (str, optional): The message to send
|
||||||
from_obj (obj, optional): object that is sending. If
|
from_obj (obj, optional): object that is sending. If
|
||||||
given, at_msg_send will be called
|
given, at_msg_send will be called
|
||||||
sessid (int or list, optional): sessid or list of
|
session (Session or list, optional): Session or list of
|
||||||
sessids to relay to, if any. If set, will
|
Sessions to relay data to, if any. If set, will
|
||||||
force send regardless of MULTISESSION_MODE.
|
force send to these sessions. If unset, who receives the
|
||||||
|
message depends on the MULTISESSION_MODE.
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
`at_msg_receive` will be called on this Object.
|
`at_msg_receive` will be called on this Object.
|
||||||
All extra kwargs will be passed on to the protocol.
|
All extra kwargs will be passed on to the protocol.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
text = to_str(text, force_string=True) if text != None else ""
|
text = to_str(text, force_string=True) if text != None else ""
|
||||||
|
# try send hooks
|
||||||
if from_obj:
|
if from_obj:
|
||||||
# call hook
|
|
||||||
try:
|
try:
|
||||||
from_obj.at_msg_send(text=text, to_obj=self, **kwargs)
|
from_obj.at_msg_send(text=text, to_obj=self, **kwargs)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
@ -440,18 +468,10 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
|
|
||||||
# session relay
|
# relay to session(s)
|
||||||
kwargs['_nomulti'] = kwargs.get('_nomulti', True)
|
sessions = make_iter(session) if session else self.sessions.all()
|
||||||
|
for session in sessions:
|
||||||
if self.player:
|
session.msg(text=text, **kwargs)
|
||||||
# for there to be a session there must be a Player.
|
|
||||||
if sessid:
|
|
||||||
sessions = make_iter(self.player.get_session(sessid))
|
|
||||||
else:
|
|
||||||
# Send to all sessions connected to this object
|
|
||||||
sessions = [self.player.get_session(sessid) for sessid in self.sessid.get()]
|
|
||||||
if sessions:
|
|
||||||
sessions[0].msg(text=text, session=sessions, **kwargs)
|
|
||||||
|
|
||||||
def for_contents(self, func, exclude=None, **kwargs):
|
def for_contents(self, func, exclude=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|
@ -756,8 +776,8 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
||||||
# no need to disconnect, Player just jumps to OOC mode.
|
# no need to disconnect, Player just jumps to OOC mode.
|
||||||
# sever the connection (important!)
|
# sever the connection (important!)
|
||||||
if self.player:
|
if self.player:
|
||||||
for sessid in self.sessid.all():
|
for session in self.sessions.all():
|
||||||
self.player.unpuppet_object(sessid)
|
self.player.unpuppet_object(session)
|
||||||
self.player = None
|
self.player = None
|
||||||
|
|
||||||
for script in _ScriptDB.objects.get_all_scripts_on_obj(self):
|
for script in _ScriptDB.objects.get_all_scripts_on_obj(self):
|
||||||
|
|
@ -964,14 +984,14 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def at_pre_puppet(self, player, sessid=None):
|
def at_pre_puppet(self, player, session=None):
|
||||||
"""
|
"""
|
||||||
Called just before a Player connects to this object to puppet
|
Called just before a Player connects to this object to puppet
|
||||||
it.
|
it.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
player (Player): This is the connecting player.
|
player (Player): This is the connecting player.
|
||||||
sessid (int): Session id controlling the connection.
|
session (Session): Session controlling the connection.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
@ -991,7 +1011,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def at_post_unpuppet(self, player, sessid=None):
|
def at_post_unpuppet(self, player, session=None):
|
||||||
"""
|
"""
|
||||||
Called just after the Player successfully disconnected from
|
Called just after the Player successfully disconnected from
|
||||||
this object, severing all connections.
|
this object, severing all connections.
|
||||||
|
|
@ -999,7 +1019,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
||||||
Args:
|
Args:
|
||||||
player (Player): The player object that just disconnected
|
player (Player): The player object that just disconnected
|
||||||
from this object.
|
from this object.
|
||||||
sessid (int): Session id controlling the connection that
|
session (Session): Session id controlling the connection that
|
||||||
just disconnected.
|
just disconnected.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
@ -1404,14 +1424,14 @@ class DefaultCharacter(DefaultObject):
|
||||||
"""
|
"""
|
||||||
self.msg(self.at_look(self.location))
|
self.msg(self.at_look(self.location))
|
||||||
|
|
||||||
def at_pre_puppet(self, player, sessid=None):
|
def at_pre_puppet(self, player, session=None):
|
||||||
"""
|
"""
|
||||||
This implementation recovers the character again after having been "stoved
|
This implementation recovers the character again after having been "stoved
|
||||||
away" to the `None` location in `at_post_unpuppet`.
|
away" to the `None` location in `at_post_unpuppet`.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
player (Player): This is the connecting player.
|
player (Player): This is the connecting player.
|
||||||
sessid (int): Session id controlling the connection.
|
session (Session): Session controlling the connection.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.db.prelogout_location:
|
if self.db.prelogout_location:
|
||||||
|
|
@ -1425,7 +1445,7 @@ class DefaultCharacter(DefaultObject):
|
||||||
self.db.prelogout_location = self.location
|
self.db.prelogout_location = self.location
|
||||||
self.location.at_object_receive(self, self.location)
|
self.location.at_object_receive(self, self.location)
|
||||||
else:
|
else:
|
||||||
player.msg("{r%s has no location and no home is set.{n" % self, sessid=sessid)
|
player.msg("{r%s has no location and no home is set.{n" % self, session=session)
|
||||||
|
|
||||||
def at_post_puppet(self):
|
def at_post_puppet(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -1440,7 +1460,7 @@ class DefaultCharacter(DefaultObject):
|
||||||
obj.msg("%s has entered the game." % self.get_display_name(obj), from_obj=from_obj)
|
obj.msg("%s has entered the game." % self.get_display_name(obj), from_obj=from_obj)
|
||||||
self.location.for_contents(message, exclude=[self], from_obj=self)
|
self.location.for_contents(message, exclude=[self], from_obj=self)
|
||||||
|
|
||||||
def at_post_unpuppet(self, player, sessid=None):
|
def at_post_unpuppet(self, player, session=None):
|
||||||
"""
|
"""
|
||||||
We stove away the character when the player goes ooc/logs off,
|
We stove away the character when the player goes ooc/logs off,
|
||||||
otherwise the character object will remain in the room also
|
otherwise the character object will remain in the room also
|
||||||
|
|
@ -1449,7 +1469,7 @@ class DefaultCharacter(DefaultObject):
|
||||||
Args:
|
Args:
|
||||||
player (Player): The player object that just disconnected
|
player (Player): The player object that just disconnected
|
||||||
from this object.
|
from this object.
|
||||||
sessid (int): Session id controlling the connection that
|
session (Session): Session controlling the connection that
|
||||||
just disconnected.
|
just disconnected.
|
||||||
"""
|
"""
|
||||||
if self.location: # have to check, in case of multiple connections closing
|
if self.location: # have to check, in case of multiple connections closing
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,55 @@ _MAX_NR_CHARACTERS = settings.MAX_NR_CHARACTERS
|
||||||
_CMDSET_PLAYER = settings.CMDSET_PLAYER
|
_CMDSET_PLAYER = settings.CMDSET_PLAYER
|
||||||
_CONNECT_CHANNEL = None
|
_CONNECT_CHANNEL = None
|
||||||
|
|
||||||
|
class PlayerSessionHandler(object):
|
||||||
|
"""
|
||||||
|
Manages the session(s) attached to a player.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, player):
|
||||||
|
"""
|
||||||
|
Initializes the handler.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
player (Player): The Player on which this handler is defined.
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.player = player
|
||||||
|
|
||||||
|
def get(self, sessid=None):
|
||||||
|
"""
|
||||||
|
Get the sessions linked to this object.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sessid (int, optional): Specify a given session by
|
||||||
|
session id.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
sessions (list): A list of Session objects. If `sessid`
|
||||||
|
is given, this is a list with one (or zero) elements.
|
||||||
|
|
||||||
|
"""
|
||||||
|
global _SESSIONS
|
||||||
|
if not _SESSIONS:
|
||||||
|
from evennia.server.sessionhandler import SESSIONS as _SESSIONS
|
||||||
|
if sessid:
|
||||||
|
return make_iter(_SESSIONS.session_from_player(self, sessid))
|
||||||
|
else:
|
||||||
|
return _SESSIONS.sessions_from_player(self)
|
||||||
|
|
||||||
|
def all(self):
|
||||||
|
"""
|
||||||
|
Alias to get(), returning all sessions.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
sessions (list): All sessions.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self.get()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
"""
|
"""
|
||||||
This is the base Typeclass for all Players. Players represent
|
This is the base Typeclass for all Players. Players represent
|
||||||
|
|
@ -100,7 +149,7 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
- at_access()
|
- at_access()
|
||||||
- at_cmdset_get(**kwargs)
|
- at_cmdset_get(**kwargs)
|
||||||
- at_first_login()
|
- at_first_login()
|
||||||
- at_post_login(sessid=None)
|
- at_post_login(session=None)
|
||||||
- at_disconnect()
|
- at_disconnect()
|
||||||
- at_message_receive()
|
- at_message_receive()
|
||||||
- at_message_send()
|
- at_message_send()
|
||||||
|
|
@ -124,69 +173,37 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
def nicks(self):
|
def nicks(self):
|
||||||
return NickHandler(self)
|
return NickHandler(self)
|
||||||
|
|
||||||
|
@lazy_property
|
||||||
|
def sessions(self):
|
||||||
|
return PlayerSessionHandler(self)
|
||||||
|
|
||||||
|
|
||||||
# session-related methods
|
# session-related methods
|
||||||
|
|
||||||
def get_session(self, sessid):
|
def disconnect_session_from_player(self, session):
|
||||||
"""
|
|
||||||
Retrieve given session.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
sessid (int or list): A session id or list of such to retrieve.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
session (Session or list): One or more Sessions matching
|
|
||||||
the given `sessid`s while also being connected to this
|
|
||||||
Player.
|
|
||||||
|
|
||||||
"""
|
|
||||||
global _SESSIONS
|
|
||||||
if not _SESSIONS:
|
|
||||||
from evennia.server.sessionhandler import SESSIONS as _SESSIONS
|
|
||||||
return _SESSIONS.session_from_player(self, sessid)
|
|
||||||
|
|
||||||
def get_all_sessions(self):
|
|
||||||
"""
|
|
||||||
Get all sessions connected to this player.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
sessions (list): All Sessions currently connected to this
|
|
||||||
player.
|
|
||||||
|
|
||||||
"""
|
|
||||||
global _SESSIONS
|
|
||||||
if not _SESSIONS:
|
|
||||||
from evennia.server.sessionhandler import SESSIONS as _SESSIONS
|
|
||||||
return _SESSIONS.sessions_from_player(self)
|
|
||||||
sessions = property(get_all_sessions) # alias shortcut
|
|
||||||
|
|
||||||
def disconnect_session_from_player(self, sessid):
|
|
||||||
"""
|
"""
|
||||||
Access method for disconnecting a given session from the
|
Access method for disconnecting a given session from the
|
||||||
player (connection happens automatically in the
|
player (connection happens automatically in the
|
||||||
sessionhandler)
|
sessionhandler)
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
sessid (int): Session id to disconnect.
|
session (Session): Session to disconnect.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# this should only be one value, loop just to make sure to
|
global _SESSIONS
|
||||||
# clean everything
|
if not _SESSIONS:
|
||||||
sessions = (session for session in self.get_all_sessions()
|
from evennia.server.sessionhandler import SESSIONS as _SESSIONS
|
||||||
if session.sessid == sessid)
|
_SESSIONS.disconnect(session)
|
||||||
for session in sessions:
|
|
||||||
# this will also trigger unpuppeting
|
|
||||||
session.sessionhandler.disconnect(session)
|
|
||||||
|
|
||||||
# puppeting operations
|
# puppeting operations
|
||||||
|
|
||||||
def puppet_object(self, sessid, obj):
|
def puppet_object(self, session, obj):
|
||||||
"""
|
"""
|
||||||
Use the given session to control (puppet) the given object (usually
|
Use the given session to control (puppet) the given object (usually
|
||||||
a Character type).
|
a Character type).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
sessid (int): session id of session to connect
|
session (Session): session to use for puppeting
|
||||||
obj (Object): the object to start puppeting
|
obj (Object): the object to start puppeting
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
|
|
@ -198,46 +215,50 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
# safety checks
|
# safety checks
|
||||||
if not obj:
|
if not obj:
|
||||||
raise RuntimeError("Object not found")
|
raise RuntimeError("Object not found")
|
||||||
session = self.get_session(sessid)
|
|
||||||
if not session:
|
if not session:
|
||||||
raise RuntimeError("Session not found")
|
raise RuntimeError("Session not found")
|
||||||
if self.get_puppet(sessid) == obj:
|
if self.get_puppet(session) == obj:
|
||||||
# already puppeting this object
|
# already puppeting this object
|
||||||
raise RuntimeError("You are already puppeting this object.")
|
self.msg("You are already puppeting this object.")
|
||||||
|
return
|
||||||
if not obj.access(self, 'puppet'):
|
if not obj.access(self, 'puppet'):
|
||||||
# no access
|
# no access
|
||||||
raise RuntimeError("You don't have permission to puppet '%s'." % obj.key)
|
self.msg("You don't have permission to puppet '%s'." % obj.key)
|
||||||
|
return
|
||||||
if obj.player:
|
if obj.player:
|
||||||
# object already puppeted
|
# object already puppeted
|
||||||
if obj.player == self:
|
if obj.player == self:
|
||||||
if obj.sessid.count():
|
if obj.sessions.count():
|
||||||
# we may take over another of our sessions
|
# we may take over another of our sessions
|
||||||
# output messages to the affected sessions
|
# output messages to the affected sessions
|
||||||
if _MULTISESSION_MODE in (1, 3):
|
if _MULTISESSION_MODE in (1, 3):
|
||||||
txt1 = "{c%s{n{G is now shared from another of your sessions.{n"
|
txt1 = "Sharing {c%s{n with another of your sessions."
|
||||||
txt2 = "Sharing {c%s{n with another of your sessions."
|
txt2 = "{c%s{n{G is now shared from another of your sessions.{n"
|
||||||
|
self.msg(txt1 % obj.name, session=session)
|
||||||
|
self.msg(txt2 % obj.name, session=obj.sessions.all())
|
||||||
else:
|
else:
|
||||||
txt1 = "{c%s{n{R is now acted from another of your sessions.{n"
|
txt1 = "Taking over {c%s{n from another of your sessions."
|
||||||
txt2 = "Taking over {c%s{n from another of your sessions."
|
txt2 = "{c%s{n{R is now acted from another of your sessions.{n"
|
||||||
self.unpuppet_object(obj.sessid.get())
|
self.msg(txt1 % obj.name, session=session)
|
||||||
self.msg(txt1 % obj.name, sessid=obj.sessid.get(), _forced_nomulti=True)
|
self.msg(txt2 % obj.name, session=obj.sessions.all())
|
||||||
self.msg(txt2 % obj.name, sessid=sessid, _forced_nomulti=True)
|
self.unpuppet_object(obj.sessions.get())
|
||||||
elif obj.player.is_connected:
|
elif obj.player.is_connected:
|
||||||
# controlled by another player
|
# controlled by another player
|
||||||
raise RuntimeError("{R{c%s{R is already puppeted by another Player.")
|
self.msg("{R{c%s{R is already puppeted by another Player.")
|
||||||
|
return
|
||||||
|
|
||||||
# do the puppeting
|
# do the puppeting
|
||||||
if session.puppet:
|
if session.puppet:
|
||||||
# cleanly unpuppet eventual previous object puppeted by this session
|
# cleanly unpuppet eventual previous object puppeted by this session
|
||||||
self.unpuppet_object(sessid)
|
self.unpuppet_object(session)
|
||||||
# if we get to this point the character is ready to puppet or it
|
# if we get to this point the character is ready to puppet or it
|
||||||
# was left with a lingering player/sessid reference from an unclean
|
# was left with a lingering player/session reference from an unclean
|
||||||
# server kill or similar
|
# server kill or similar
|
||||||
|
|
||||||
obj.at_pre_puppet(self, sessid=sessid)
|
obj.at_pre_puppet(self, session=session)
|
||||||
|
|
||||||
# do the connection
|
# do the connection
|
||||||
obj.sessid.add(sessid)
|
obj.session.add(session)
|
||||||
obj.player = self
|
obj.player = self
|
||||||
session.puid = obj.id
|
session.puid = obj.id
|
||||||
session.puppet = obj
|
session.puppet = obj
|
||||||
|
|
@ -246,37 +267,30 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
|
|
||||||
# re-cache locks to make sure superuser bypass is updated
|
# re-cache locks to make sure superuser bypass is updated
|
||||||
obj.locks.cache_lock_bypass(obj)
|
obj.locks.cache_lock_bypass(obj)
|
||||||
|
# final hook
|
||||||
obj.at_post_puppet()
|
obj.at_post_puppet()
|
||||||
|
|
||||||
def unpuppet_object(self, sessid):
|
def unpuppet_object(self, session):
|
||||||
"""
|
"""
|
||||||
Disengage control over an object.
|
Disengage control over an object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
sessid(int): The session id to disengage.
|
session (Session or list): The session or a list of
|
||||||
|
sessions to disengage from their puppets.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
RuntimeError With message about error.
|
RuntimeError With message about error.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if _MULTISESSION_MODE == 1:
|
for session in make_iter(session):
|
||||||
sessions = self.get_all_sessions()
|
obj = session.puppet
|
||||||
else:
|
if obj:
|
||||||
sessions = self.get_session(sessid)
|
|
||||||
if not sessions:
|
|
||||||
raise RuntimeError("No session was found.")
|
|
||||||
for session in make_iter(sessions):
|
|
||||||
obj = session.puppet or None
|
|
||||||
if not obj:
|
|
||||||
raise RuntimeError("No puppet was found to disconnect from.")
|
|
||||||
elif obj:
|
|
||||||
# do the disconnect, but only if we are the last session to puppet
|
# do the disconnect, but only if we are the last session to puppet
|
||||||
obj.at_pre_unpuppet()
|
obj.at_pre_unpuppet()
|
||||||
obj.sessid.remove(session.sessid)
|
obj.sessions.remove(session)
|
||||||
if not obj.sessid.count():
|
if not obj.sessions.count():
|
||||||
del obj.player
|
del obj.player
|
||||||
obj.at_post_unpuppet(self, sessid=sessid)
|
obj.at_post_unpuppet(self, session=session)
|
||||||
# Just to be sure we're always clear.
|
# Just to be sure we're always clear.
|
||||||
session.puppet = None
|
session.puppet = None
|
||||||
session.puid = None
|
session.puid = None
|
||||||
|
|
@ -286,24 +300,22 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
Disconnect all puppets. This is called by server before a
|
Disconnect all puppets. This is called by server before a
|
||||||
reset/shutdown.
|
reset/shutdown.
|
||||||
"""
|
"""
|
||||||
for session in (sess for sess in self.get_all_sessions() if sess.puppet):
|
self.unpuppet_object(self.sessions.all())
|
||||||
self.unpuppet_object(session.sessid)
|
|
||||||
|
|
||||||
def get_puppet(self, sessid):
|
def get_puppet(self, session):
|
||||||
"""
|
"""
|
||||||
Get an object puppeted by this session through this player. This is
|
Get an object puppeted by this session through this player. This is
|
||||||
the main method for retrieving the puppeted object from the
|
the main method for retrieving the puppeted object from the
|
||||||
player's end.
|
player's end.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
sessid (int): Find puppeted object based on this sessid.
|
session (Session): Find puppeted object based on this session
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
puppet (Object): The matching puppeted object, if any.
|
puppet (Object): The matching puppeted object, if any.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
session = self.get_session(sessid)
|
return session.puppet
|
||||||
return session.puppet if session and session.puppet else None
|
|
||||||
|
|
||||||
def get_all_puppets(self):
|
def get_all_puppets(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -314,7 +326,7 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
by this Player.
|
by this Player.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return list(set(session.puppet for session in self.get_all_sessions()
|
return list(set(session.puppet for session in self.sessions.all()
|
||||||
if session.puppet))
|
if session.puppet))
|
||||||
|
|
||||||
def __get_single_puppet(self):
|
def __get_single_puppet(self):
|
||||||
|
|
@ -350,7 +362,7 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
# sessions remain (should usually be handled from the
|
# sessions remain (should usually be handled from the
|
||||||
# deleting command)
|
# deleting command)
|
||||||
try:
|
try:
|
||||||
self.unpuppet_object(session.sessid)
|
self.unpuppet_object(session)
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
# no puppet to disconnect from
|
# no puppet to disconnect from
|
||||||
pass
|
pass
|
||||||
|
|
@ -362,7 +374,7 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
super(PlayerDB, self).delete(*args, **kwargs)
|
super(PlayerDB, self).delete(*args, **kwargs)
|
||||||
## methods inherited from database model
|
## methods inherited from database model
|
||||||
|
|
||||||
def msg(self, text=None, from_obj=None, sessid=None, **kwargs):
|
def msg(self, text=None, from_obj=None, session=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Evennia -> User
|
Evennia -> User
|
||||||
This is the main route for sending data back to the user from the
|
This is the main route for sending data back to the user from the
|
||||||
|
|
@ -370,15 +382,18 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
text (str, optional): text data to send
|
text (str, optional): text data to send
|
||||||
from_obj (Object or Player, optional): object sending. If given,
|
from_obj (Object or Player, optional): Object sending. If given,
|
||||||
its at_msg_send() hook will be called.
|
its at_msg_send() hook will be called.
|
||||||
sessid (int or list, optional): session id or ids to receive this
|
session (Session or list, optional): Session object or a list of
|
||||||
send. If given, overrules MULTISESSION_MODE.
|
Sessions to receive this send. If given, overrules the
|
||||||
|
default send behavior for the current
|
||||||
|
MULTISESSION_MODE.
|
||||||
Notes:
|
Notes:
|
||||||
All other keywords are passed on to the protocol.
|
All other keywords are passed on to the protocol.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
text = to_str(text, force_string=True) if text else ""
|
text = to_str(text, force_string=True) if text else ""
|
||||||
|
|
||||||
if from_obj:
|
if from_obj:
|
||||||
# call hook
|
# call hook
|
||||||
try:
|
try:
|
||||||
|
|
@ -387,23 +402,11 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# session relay
|
# session relay
|
||||||
if sessid:
|
sessions = make_iter(session) if session else self.sessions.all()
|
||||||
# this could still be an iterable if sessid is an iterable
|
for session in sessions:
|
||||||
sessions = self.get_session(sessid)
|
session.msg(text=text, **kwargs)
|
||||||
if sessions:
|
|
||||||
# this is a special instruction to ignore MULTISESSION_MODE
|
|
||||||
# and only relay to this given session.
|
|
||||||
kwargs["_nomulti"] = True
|
|
||||||
for session in make_iter(sessions):
|
|
||||||
session.msg(text=text, **kwargs)
|
|
||||||
return
|
|
||||||
# we only send to the first of any connected sessions - the sessionhandler
|
|
||||||
# will disperse this to the other sessions based on MULTISESSION_MODE.
|
|
||||||
sessions = self.get_all_sessions()
|
|
||||||
if sessions:
|
|
||||||
sessions[0].msg(text=text, **kwargs)
|
|
||||||
|
|
||||||
def execute_cmd(self, raw_string, sessid=None, **kwargs):
|
def execute_cmd(self, raw_string, session=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Do something as this player. This method is never called normally,
|
Do something as this player. This method is never called normally,
|
||||||
but only when the player object itself is supposed to execute the
|
but only when the player object itself is supposed to execute the
|
||||||
|
|
@ -412,8 +415,8 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
raw_string (str): Raw command input coming from the command line.
|
raw_string (str): Raw command input coming from the command line.
|
||||||
sessid (int, optional): The optional session id to be
|
session (Session, optional): The session to be responsible
|
||||||
responsible for the command-send
|
for the command-send
|
||||||
|
|
||||||
Kwargs:
|
Kwargs:
|
||||||
kwargs (any): Other keyword arguments will be added to the
|
kwargs (any): Other keyword arguments will be added to the
|
||||||
|
|
@ -426,17 +429,12 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
raw_string = to_unicode(raw_string)
|
raw_string = to_unicode(raw_string)
|
||||||
raw_string = self.nicks.nickreplace(raw_string,
|
raw_string = self.nicks.nickreplace(raw_string,
|
||||||
categories=("inputline", "channel"), include_player=False)
|
categories=("inputline", "channel"), include_player=False)
|
||||||
if not sessid and _MULTISESSION_MODE in (0, 1):
|
if not session and _MULTISESSION_MODE in (0, 1):
|
||||||
# in this case, we should either have only one sessid, or the sessid
|
# for these modes we use the
|
||||||
# should not matter (since the return goes to all of them we can
|
session
|
||||||
# just use the first one as the source)
|
|
||||||
try:
|
|
||||||
sessid = self.get_all_sessions()[0].sessid
|
|
||||||
except IndexError:
|
|
||||||
# this can happen for bots
|
|
||||||
sessid = None
|
|
||||||
return cmdhandler.cmdhandler(self, raw_string,
|
return cmdhandler.cmdhandler(self, raw_string,
|
||||||
callertype="player", sessid=sessid, **kwargs)
|
callertype="player", session=session, **kwargs)
|
||||||
|
|
||||||
def search(self, searchdata, return_puppet=False,
|
def search(self, searchdata, return_puppet=False,
|
||||||
nofound_string=None, multimatch_string=None, **kwargs):
|
nofound_string=None, multimatch_string=None, **kwargs):
|
||||||
|
|
@ -675,7 +673,7 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
else:
|
else:
|
||||||
logger.log_info("[%s]: %s" % (now, message))
|
logger.log_info("[%s]: %s" % (now, message))
|
||||||
|
|
||||||
def at_post_login(self, sessid=None):
|
def at_post_login(self, session=None):
|
||||||
"""
|
"""
|
||||||
Called at the end of the login process, just before letting
|
Called at the end of the login process, just before letting
|
||||||
the player loose.
|
the player loose.
|
||||||
|
|
@ -693,14 +691,14 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
if _MULTISESSION_MODE == 0:
|
if _MULTISESSION_MODE == 0:
|
||||||
# in this mode we should have only one character available. We
|
# in this mode we should have only one character available. We
|
||||||
# try to auto-connect to our last conneted object, if any
|
# try to auto-connect to our last conneted object, if any
|
||||||
self.puppet_object(sessid, self.db._last_puppet)
|
self.puppet_object(session, self.db._last_puppet)
|
||||||
elif _MULTISESSION_MODE == 1:
|
elif _MULTISESSION_MODE == 1:
|
||||||
# in this mode all sessions connect to the same puppet.
|
# in this mode all sessions connect to the same puppet.
|
||||||
self.puppet_object(sessid, self.db._last_puppet)
|
self.puppet_object(session, self.db._last_puppet)
|
||||||
elif _MULTISESSION_MODE in (2, 3):
|
elif _MULTISESSION_MODE in (2, 3):
|
||||||
# In this mode we by default end up at a character selection
|
# In this mode we by default end up at a character selection
|
||||||
# screen. We execute look on the player.
|
# screen. We execute look on the player.
|
||||||
self.msg(self.at_look(sessid=sessid))
|
self.msg(self.at_look(session=session))
|
||||||
|
|
||||||
def at_failed_login(self, session):
|
def at_failed_login(self, session):
|
||||||
"""
|
"""
|
||||||
|
|
@ -765,7 +763,7 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def at_look(self, target=None, sessid=None):
|
def at_look(self, target=None, session=None):
|
||||||
"""
|
"""
|
||||||
Called when this object executes a look. It allows to customize
|
Called when this object executes a look. It allows to customize
|
||||||
just what this means.
|
just what this means.
|
||||||
|
|
@ -773,7 +771,7 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
Args:
|
Args:
|
||||||
target (Object or list, optional): An object or a list
|
target (Object or list, optional): An object or a list
|
||||||
objects to inspect.
|
objects to inspect.
|
||||||
sessid (int, optional): Id of the session doing this look.
|
session (Session, optional): The session doing this look.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
look_string (str): A prepared look string, ready to send
|
look_string (str): A prepared look string, ready to send
|
||||||
|
|
@ -799,7 +797,7 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
for isess, sess in enumerate(sessions):
|
for isess, sess in enumerate(sessions):
|
||||||
csessid = sess.sessid
|
csessid = sess.sessid
|
||||||
addr = "%s (%s)" % (sess.protocol_key, isinstance(sess.address, tuple) and str(sess.address[0]) or str(sess.address))
|
addr = "%s (%s)" % (sess.protocol_key, isinstance(sess.address, tuple) and str(sess.address[0]) or str(sess.address))
|
||||||
string += "\n %s %s" % (sessid == csessid and "{w%s{n" % (isess + 1) or (isess + 1), addr)
|
string += "\n %s %s" % (session.sessid == csessid and "{w%s{n" % (isess + 1) or (isess + 1), addr)
|
||||||
string += "\n\n {whelp{n - more commands"
|
string += "\n\n {whelp{n - more commands"
|
||||||
string += "\n {wooc <Text>{n - talk on public channel"
|
string += "\n {wooc <Text>{n - talk on public channel"
|
||||||
|
|
||||||
|
|
@ -821,16 +819,14 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
|
||||||
charmax > 1 and " (%i/%i)" % (len(characters), charmax) or "")
|
charmax > 1 and " (%i/%i)" % (len(characters), charmax) or "")
|
||||||
|
|
||||||
for char in characters:
|
for char in characters:
|
||||||
csessid = char.sessid.get()
|
csessions = char.sessions.all()
|
||||||
if csessid:
|
for sess in csessions:
|
||||||
# character is already puppeted
|
# character is already puppeted
|
||||||
sessi = self.get_session(csessid)
|
sid = sess in sessions and sessions.index(sess) + 1
|
||||||
for sess in make_iter(sessi):
|
if sess and sid:
|
||||||
sid = sess in sessions and sessions.index(sess) + 1
|
string += "\n - {G%s{n [%s] (played by you in session %i)" % (char.key, ", ".join(char.permissions.all()), sid)
|
||||||
if sess and sid:
|
else:
|
||||||
string += "\n - {G%s{n [%s] (played by you in session %i)" % (char.key, ", ".join(char.permissions.all()), sid)
|
string += "\n - {R%s{n [%s] (played by someone else)" % (char.key, ", ".join(char.permissions.all()))
|
||||||
else:
|
|
||||||
string += "\n - {R%s{n [%s] (played by someone else)" % (char.key, ", ".join(char.permissions.all()))
|
|
||||||
else:
|
else:
|
||||||
# character is "free to puppet"
|
# character is "free to puppet"
|
||||||
string += "\n - %s [%s]" % (char.key, ", ".join(char.permissions.all()))
|
string += "\n - %s [%s]" % (char.key, ", ".join(char.permissions.all()))
|
||||||
|
|
@ -843,7 +839,7 @@ class DefaultGuest(DefaultPlayer):
|
||||||
This class is used for guest logins. Unlike Players, Guests and
|
This class is used for guest logins. Unlike Players, Guests and
|
||||||
their characters are deleted after disconnection.
|
their characters are deleted after disconnection.
|
||||||
"""
|
"""
|
||||||
def at_post_login(self, sessid=None):
|
def at_post_login(self, session=None):
|
||||||
"""
|
"""
|
||||||
In theory, guests only have one character regardless of which
|
In theory, guests only have one character regardless of which
|
||||||
MULTISESSION_MODE we're in. They don't get a choice.
|
MULTISESSION_MODE we're in. They don't get a choice.
|
||||||
|
|
@ -853,7 +849,7 @@ class DefaultGuest(DefaultPlayer):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self._send_to_connect_channel("{G%s connected{n" % self.key)
|
self._send_to_connect_channel("{G%s connected{n" % self.key)
|
||||||
self.puppet_object(sessid, self.db._last_puppet)
|
self.puppet_object(session, self.db._last_puppet)
|
||||||
|
|
||||||
def at_disconnect(self):
|
def at_disconnect(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -396,9 +396,7 @@ class ServerSession(Session):
|
||||||
from evennia.utils import ansi as _ANSI
|
from evennia.utils import ansi as _ANSI
|
||||||
text = _ANSI.parse_ansi(text, strip_ansi=True, xterm256=False, mxp=False)
|
text = _ANSI.parse_ansi(text, strip_ansi=True, xterm256=False, mxp=False)
|
||||||
text = _RE_SCREENREADER_REGEX.sub("", text)
|
text = _RE_SCREENREADER_REGEX.sub("", text)
|
||||||
session = kwargs.pop('session', None)
|
self.sessionhandler.data_out(self, text=text, **kwargs)
|
||||||
session = session or self
|
|
||||||
self.sessionhandler.data_out(session, text=text, **kwargs)
|
|
||||||
# alias
|
# alias
|
||||||
msg = data_out
|
msg = data_out
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -517,53 +517,19 @@ class ServerSessionHandler(SessionHandler):
|
||||||
Sending data Server -> Portal
|
Sending data Server -> Portal
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
session (Session): Session object
|
session (Session): Session to relay to.
|
||||||
text (str, optional): text data to return
|
text (str, optional): text data to return
|
||||||
_nomulti (bool, optional): if given, only this
|
|
||||||
session will receive the rest of the data,
|
|
||||||
regardless of MULTISESSION_MODE. This is an
|
|
||||||
internal variable that will not be passed on.
|
|
||||||
This is ignored for MULTISESSION_MODE = 1,
|
|
||||||
since all messages are mirrored everywhere for
|
|
||||||
that.
|
|
||||||
_forced_nomulti (bool, optional): Like _nomulti,
|
|
||||||
but works even when MULTISESSION_MODE = 1.
|
|
||||||
Useful for connection handling messages.
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
#from evennia.server.profiling.timetrace import timetrace
|
#from evennia.server.profiling.timetrace import timetrace
|
||||||
#text = timetrace(text, "ServerSessionHandler.data_out")
|
#text = timetrace(text, "ServerSessionHandler.data_out")
|
||||||
|
|
||||||
sessions = make_iter(session)
|
|
||||||
session = sessions[0]
|
|
||||||
text = text and to_str(to_unicode(text), encoding=session.encoding)
|
text = text and to_str(to_unicode(text), encoding=session.encoding)
|
||||||
multi = not kwargs.pop("_nomulti", None)
|
|
||||||
forced_nomulti = kwargs.pop("_forced_nomulti", None)
|
|
||||||
# Mode 1 mirrors to all.
|
|
||||||
if _MULTISESSION_MODE == 1:
|
|
||||||
multi = True
|
|
||||||
# ...Unless we're absolutely sure.
|
|
||||||
if forced_nomulti:
|
|
||||||
multi = False
|
|
||||||
|
|
||||||
if multi:
|
# send across AMP
|
||||||
if _MULTISESSION_MODE == 1:
|
self.server.amp_protocol.send_MsgServer2Portal(sessid=session.sessid,
|
||||||
if session.player:
|
text=text,
|
||||||
sessions = self.sessions_from_player(session.player)
|
**kwargs)
|
||||||
if _MULTISESSION_MODE == 2:
|
|
||||||
if session.player:
|
|
||||||
sessions = self.sessions_from_player(session.player)
|
|
||||||
elif _MULTISESSION_MODE == 3:
|
|
||||||
if session.puppet:
|
|
||||||
sessions = self.sessions_from_puppet(session.puppet)
|
|
||||||
elif session.player:
|
|
||||||
sessions = self.sessions_from_player(session.player)
|
|
||||||
|
|
||||||
# send to all found sessions
|
|
||||||
for session in sessions:
|
|
||||||
self.server.amp_protocol.send_MsgServer2Portal(sessid=session.sessid,
|
|
||||||
text=text,
|
|
||||||
**kwargs)
|
|
||||||
|
|
||||||
def data_in(self, sessid, text="", **kwargs):
|
def data_in(self, sessid, text="", **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue