Cleaned up worst instability. Test suite does validate yet.

This commit is contained in:
Griatch 2013-09-21 17:33:48 +02:00
parent fa93c70e7f
commit e36c7d5cc1
24 changed files with 134 additions and 300 deletions

View file

@ -190,7 +190,7 @@ class CmdEditorGroup(CmdEditorBase):
string = editor.display_buffer(buf=buf, offset=lstart, linenums=False) string = editor.display_buffer(buf=buf, offset=lstart, linenums=False)
else: else:
string = editor.display_buffer(linenums=False) string = editor.display_buffer(linenums=False)
self.caller.msg(string, data={"raw":True}) self.caller.msg(string, raw=True)
return return
elif cmd == ":::": elif cmd == ":::":
# Insert single colon alone on a line # Insert single colon alone on a line

View file

@ -71,8 +71,8 @@ class ExampleObject(Object):
search(ostring, global_search=False, attribute_name=None, use_nicks=False, location=None, ignore_errors=False, player=False) search(ostring, global_search=False, attribute_name=None, use_nicks=False, location=None, ignore_errors=False, player=False)
execute_cmd(raw_string) execute_cmd(raw_string)
msg(message, from_obj=None, data=None) msg(text=None, **kwargs)
msg_contents(message, exclude=None, from_obj=None, data=None) msg_contents(message, exclude=None, from_obj=None, **kwargs)
move_to(destination, quiet=False, emit_to_obj=None, use_destination=True) move_to(destination, quiet=False, emit_to_obj=None, use_destination=True)
copy(new_key=None) copy(new_key=None)
delete() delete()
@ -113,9 +113,9 @@ class ExampleObject(Object):
at_after_traverse(traversing_object, source_location) - (exit-objects only) called just after a traversal has happened. at_after_traverse(traversing_object, source_location) - (exit-objects only) called just after a traversal has happened.
at_failed_traverse(traversing_object) - (exit-objects only) called if traversal fails and property err_traverse is not defined. at_failed_traverse(traversing_object) - (exit-objects only) called if traversal fails and property err_traverse is not defined.
at_msg_receive(self, msg, from_obj=None, data=None) - called when a message (via self.msg()) is sent to this obj. at_msg_receive(self, msg, from_obj=None, **kwargs) - called when a message (via self.msg()) is sent to this obj.
If returns false, aborts send. If returns false, aborts send.
at_msg_send(self, msg, to_obj=None, data=None) - called when this objects sends a message to someone via self.msg(). at_msg_send(self, msg, to_obj=None, **kwargs) - called when this objects sends a message to someone via self.msg().
return_appearance(looker) - describes this object. Used by "look" command by default return_appearance(looker) - describes this object. Used by "look" command by default
at_desc(looker=None) - called by 'look' whenever the appearance is requested. at_desc(looker=None) - called by 'look' whenever the appearance is requested.

View file

@ -59,7 +59,7 @@ class ExamplePlayer(Player):
* Helper methods * Helper methods
msg(outgoing_string, from_obj=None, data=None) msg(text=None, **kwargs)
swap_character(new_character, delete_old_character=False) swap_character(new_character, delete_old_character=False)
execute_cmd(raw_string, sessid=None) execute_cmd(raw_string, sessid=None)
search(ostring, global_search=False, attribute_name=None, use_nicks=False, location=None, ignore_errors=False, player=False) search(ostring, global_search=False, attribute_name=None, use_nicks=False, location=None, ignore_errors=False, player=False)

View file

@ -343,11 +343,11 @@ def cmdhandler(called_on, raw_string, testing=False, callertype="session", sessi
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.obj # set via command handler
cmd.sessid = session.sessid if session else sessid
cmd.raw_string = unformatted_raw_string cmd.raw_string = unformatted_raw_string
#cmd.obj # set via command handler
if hasattr(cmd, 'obj') and hasattr(cmd.obj, 'scripts'): if hasattr(cmd, 'obj') and hasattr(cmd.obj, 'scripts'):
# cmd.obj is automatically made available by the cmdhandler. # cmd.obj is automatically made available by the cmdhandler.

View file

@ -206,7 +206,7 @@ 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="", to_obj=None, from_obj=None, data=None, sessid=None, all_sessions=False): def msg(self, msg="", to_obj=None, from_obj=None, sessid=None, all_sessions=False, **kwargs):
""" """
This is a shortcut instad of calling msg() directly on an object - it will This is a shortcut instad of calling msg() directly on an object - it will
detect if caller is an Object or a Player and also appends self.sessid detect if caller is an Object or a Player and also appends self.sessid
@ -234,7 +234,7 @@ class Command(object):
# if to_obj is a different Player, all their sessions # if to_obj is a different Player, all their sessions
# will be notified unless sessid was given specifically # will be notified unless sessid was given specifically
sessid = None sessid = None
to_obj.msg(msg, from_obj=from_obj, data=data, sessid=sessid) to_obj.msg(msg, from_obj=from_obj, sessid=sessid, **kwargs)
# Common Command hooks # Common Command hooks

View file

@ -416,9 +416,8 @@ class CmdEmit(MuxCommand):
continue continue
if obj.access(caller, 'tell'): if obj.access(caller, 'tell'):
obj.msg(message) obj.msg(message)
if send_to_contents: if send_to_contents and hasattr(obj, "msg_contents"):
for content in obj.contents: obj.msg_contents(message)
content.msg(message)
caller.msg("Emitted to %s and its contents." % objname) caller.msg("Emitted to %s and its contents." % objname)
else: else:
caller.msg("Emitted to %s." % objname) caller.msg("Emitted to %s." % objname)

View file

@ -155,7 +155,7 @@ class CmdDelCom(MuxPlayerCommand):
return return
else: else:
# we are removing a channel nick # we are removing a channel nick
channame = caller.nicks.get_replace(key=ostring, category="channel") channame = caller.nicks.get(key=ostring, category="channel")
channel = find_channel(caller, channame, silent=True) channel = find_channel(caller, channame, silent=True)
if not channel: if not channel:
self.msg("No channel with alias '%s' was found." % ostring) self.msg("No channel with alias '%s' was found." % ostring)
@ -949,7 +949,7 @@ class CmdIMCInfo(MuxCommand):
return return
from src.comms.imc2 import IMC2_CLIENT from src.comms.imc2 import IMC2_CLIENT
self.msg("Sending IMC whois request. If you receive no response, no matches were found.") self.msg("Sending IMC whois request. If you receive no response, no matches were found.")
IMC2_CLIENT.msg_imc2(None, from_obj=self.caller, packet_type="imcwhois", data={"target":self.args}) IMC2_CLIENT.msg_imc2(None, from_obj=self.caller, packet_type="imcwhois", target=self.args)
elif not self.switches or "channels" in self.switches or self.cmdstring == "@imcchanlist": elif not self.switches or "channels" in self.switches or self.cmdstring == "@imcchanlist":
# show channels # show channels
@ -1007,7 +1007,7 @@ class CmdIMCTell(MuxCommand):
data = {"target":target, "destination":destination} data = {"target":target, "destination":destination}
# send to imc2 # send to imc2
IMC2_CLIENT.msg_imc2(message, from_obj=self.caller, packet_type="imctell", data=data) IMC2_CLIENT.msg_imc2(message, from_obj=self.caller, packet_type="imctell", **data)
self.msg("You paged {c%s@%s{n (over IMC): '%s'." % (target, destination, message)) self.msg("You paged {c%s@%s{n (over IMC): '%s'." % (target, destination, message))

View file

@ -628,10 +628,10 @@ class CmdQuell(MuxPlayerCommand):
player.attributes.remove('_quell') player.attributes.remove('_quell')
self.msg("Player permissions%s restored." % permstr) self.msg("Player permissions%s restored." % permstr)
else: else:
if player.get('_quell'): if player.attributes.get('_quell'):
self.msg("Already quelling Player%s permissions." % permstr) self.msg("Already quelling Player%s permissions." % permstr)
return return
player.add('_quell', True) player.attributes.add('_quell', True)
self.msg("Quelling Player permissions%s. Use @unquell to get them back." % permstr) self.msg("Quelling Player permissions%s. Use @unquell to get them back." % permstr)
self._recache_locks(player) self._recache_locks(player)

View file

@ -163,9 +163,9 @@ class CmdPy(MuxCommand):
'inherits_from':utils.inherits_from} 'inherits_from':utils.inherits_from}
try: try:
self.msg(">>> %s" % pycode, data={"raw":True}, sessid=self.sessid) self.msg(">>> %s" % pycode, raw=True, sessid=self.sessid)
except TypeError: except TypeError:
self.msg(">>> %s" % pycode, data={"raw":True}) self.msg(">>> %s" % pycode, raw=True)
mode = "eval" mode = "eval"

View file

@ -78,9 +78,11 @@ class CommandTest(TestCase):
cmdobj.cmdstring = cmdobj.key cmdobj.cmdstring = cmdobj.key
cmdobj.args = args cmdobj.args = args
cmdobj.cmdset = cmdset cmdobj.cmdset = cmdset
cmdobj.sessid = 1
cmdobj.session = None
cmdobj.player = self.player
cmdobj.raw_string = cmdobj.key + " " + args cmdobj.raw_string = cmdobj.key + " " + args
cmdobj.obj = self.char1 cmdobj.obj = self.char1
cmdobj.sessid = 1
# test # test
self.char1.player.ndb.stored_msg = [] self.char1.player.ndb.stored_msg = []
cmdobj.at_pre_cmd() cmdobj.at_pre_cmd()

View file

@ -591,7 +591,7 @@ class Channel(SharedMemoryModel):
# get all players connected to this channel and send to them # get all players connected to this channel and send to them
for conn in Channel.objects.get_all_connections(self, online=online): for conn in Channel.objects.get_all_connections(self, online=online):
try: try:
conn.player.msg(msg, from_object=senders) conn.player.msg(msg, from_obj=senders)
except AttributeError: except AttributeError:
try: try:
conn.to_external(msg, from_object=senders, from_channel=self) conn.to_external(msg, from_object=senders, from_channel=self)

View file

@ -658,7 +658,7 @@ class ObjectDB(TypedObject):
break break
return cmdhandler.cmdhandler(_GA(self, "typeclass"), raw_string, callertype="object", sessid=sessid) return cmdhandler.cmdhandler(_GA(self, "typeclass"), raw_string, callertype="object", sessid=sessid)
def msg(self, text=None, **kwargs):#from_obj=None, data=None, sessid=0): def msg(self, text=None, from_obj=None, sessid=0, **kwargs):
""" """
Emits something to a session attached to the object. Emits something to a session attached to the object.
@ -670,22 +670,24 @@ class ObjectDB(TypedObject):
If set to 0 (default), use either from_obj.sessid (if set) or self.sessid automatically If set to 0 (default), use either from_obj.sessid (if set) or self.sessid automatically
If None, echo to all connected sessions If None, echo to all connected sessions
""" """
if "data" in kwargs:
from src.utils import logger
logger.log_depmsg("ObjectDB.msg(): 'data'-dict keyword is deprecated. Use **kwargs instead.")
data = kwargs.pop("data")
if isinstance(data, dict):
kwargs.update(data)
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.
if kwargs.get("sessid",0) == 0: if not sessid:
sessid = None if from_obj and hasattr(from_obj, "sessid"):
if "from_obj" in kwargs and hasattr(kwargs["from_obj"], "sessid"): sessid = from_obj.sessid
kwargs["sessid"] = from_obj.sessid
elif hasattr(self, "sessid"): elif hasattr(self, "sessid"):
kwargs["sessid"] = self.sessid sessid = self.sessid
_GA(_GA(self, 'player'), "typeclass").msg(text=text, **kwargs)#from_obj=from_obj, data=data, sessid=sessid) _GA(_GA(self, 'player'), "typeclass").msg(text=text, from_obj=from_obj, sessid=sessid, **kwargs)
def emit_to(self, message, from_obj=None, data=None): def msg_contents(self, message, exclude=None, from_obj=None, **kwargs):
"Deprecated. Alias for msg"
logger.log_depmsg("emit_to() is deprecated. Use msg() instead.")
_GA(self, "msg")(message, from_obj, data)
def msg_contents(self, message, exclude=None, from_obj=None, data=None):
""" """
Emits something to all objects inside an object. Emits something to all objects inside an object.
@ -697,12 +699,7 @@ class ObjectDB(TypedObject):
contents = [obj for obj in contents contents = [obj for obj in contents
if (obj not in exclude and obj not in exclude)] if (obj not in exclude and obj not in exclude)]
for obj in contents: for obj in contents:
obj.msg(message, from_obj=from_obj, data=data) obj.msg(message, from_obj=from_obj, **kwargs)
def emit_to_contents(self, message, exclude=None, from_obj=None, data=None):
"Deprecated. Alias for msg_contents"
logger.log_depmsg("emit_to_contents() is deprecated. Use msg_contents() instead.")
self.msg_contents(message, exclude=exclude, from_obj=from_obj, data=data)
def move_to(self, destination, quiet=False, def move_to(self, destination, quiet=False,
emit_to_obj=None, use_destination=True, to_none=False): emit_to_obj=None, use_destination=True, to_none=False):

View file

@ -87,8 +87,8 @@ class Object(TypeClass):
search(ostring, global_search=False, global_dbref=False, attribute_name=None, search(ostring, global_search=False, global_dbref=False, attribute_name=None,
use_nicks=False, location=None, ignore_errors=False, player=False) use_nicks=False, location=None, ignore_errors=False, player=False)
execute_cmd(raw_string) execute_cmd(raw_string)
msg(message, from_obj=None, data=None) msg(message, **kwargs)
msg_contents(message, exclude=None, from_obj=None, data=None) msg_contents(message, exclude=None, from_obj=None, **kwargs)
move_to(destination, quiet=False, emit_to_obj=None, use_destination=True, to_none=False) move_to(destination, quiet=False, emit_to_obj=None, use_destination=True, to_none=False)
copy(new_key=None) copy(new_key=None)
delete() delete()
@ -222,7 +222,7 @@ class Object(TypeClass):
""" """
return self.dbobj.execute_cmd(raw_string, sessid=sessid) return self.dbobj.execute_cmd(raw_string, sessid=sessid)
def msg(self, text=None, **kwargs):#message, from_obj=None, data=None, sessid=0): def msg(self, text=None, from_obj=None, sessid=None, **kwargs):
""" """
Emits something to any sessions attached to the object. Emits something to any sessions attached to the object.
@ -235,13 +235,13 @@ class Object(TypeClass):
""" """
self.dbobj.msg(text=text, **kwargs)#message, from_obj=from_obj, data=data, sessid=0) self.dbobj.msg(text=text, **kwargs)#message, from_obj=from_obj, data=data, sessid=0)
def msg_contents(self, message, exclude=None, from_obj=None, data=None): def msg_contents(self, text=None, exclude=None, from_obj=None, **kwargs):
""" """
Emits something to all objects inside an object. Emits something to all objects inside an object.
exclude is a list of objects not to send to. See self.msg() for more info. exclude is a list of objects not to send to. See self.msg() for more info.
""" """
self.dbobj.msg_contents(message, exclude=exclude, from_obj=from_obj, data=data) self.dbobj.msg_contents(text, exclude=exclude, from_obj=from_obj, **kwargs)
def move_to(self, destination, quiet=False, def move_to(self, destination, quiet=False,
emit_to_obj=None, use_destination=True, to_none=False): emit_to_obj=None, use_destination=True, to_none=False):
@ -653,7 +653,7 @@ class Object(TypeClass):
""" """
pass pass
def at_msg_receive(self, text=None, **kwargs):#from_obj=None, data=None): def at_msg_receive(self, text=None, **kwargs):
""" """
This hook is called whenever someone This hook is called whenever someone
sends a message to this object. sends a message to this object.
@ -674,7 +674,7 @@ class Object(TypeClass):
""" """
return True return True
def at_msg_send(self, text=None, **kwargs):#msg, to_obj=None, data=None): def at_msg_send(self, text=None, to_obj=None, **kwargs):
""" """
This is a hook that is called when /this/ object This is a hook that is called when /this/ object
sends a message to another object with obj.msg() sends a message to another object with obj.msg()

View file

@ -248,26 +248,31 @@ class PlayerDB(TypedObject, AbstractUser):
# PlayerDB class access methods # PlayerDB class access methods
# #
def msg(self, text=None, **kwargs):#outgoing_string, from_obj=None, data=None, sessid=None): def msg(self, text=None, from_obj=None, sessid=None, **kwargs):
""" """
Evennia -> User Evennia -> User
This is the main route for sending data back to the user from the server. This is the main route for sending data back to the user from the server.
outgoing_string (string) - text data to send outgoing_string (string) - text data to send
from_obj (Object/Player) - source object of message to send from_obj (Object/Player) - source object of message to send
data (dict) - arbitrary data object containing eventual protocol-specific options
sessid - the session id of the session to send to. If not given, return to sessid - the session id of the session to send to. If not given, return to
all sessions connected to this player. This is usually only all sessions connected to this player. This is usually only
relevant when using msg() directly from a player-command (from relevant when using msg() directly from a player-command (from
a command on a Character, the character automatically stores and a command on a Character, the character automatically stores and
handles the sessid). handles the sessid).
kwargs (dict) - All other keywords are parsed as extra data.
""" """
from_obj = kwargs.pop("from_obj", None) if "data" in kwargs:
sessid = kwargs.pop("sessid", 0) from src.utils import logger
logger.log_depmsg("PlayerDB:msg() 'data'-dict keyword is deprecated. Use **kwargs instead.")
data = kwargs.pop("data")
if isinstance(data, dict):
kwargs.update(data)
if from_obj: if from_obj:
# call hook # call hook
try: try:
_GA(from_obj, "at_msg_send")(text=text, to_obj=self, data=data) _GA(from_obj, "at_msg_send")(text=text, to_obj=self, **kwargs)
except Exception: except Exception:
pass pass
outgoing_string = utils.to_str(text, force_string=True) outgoing_string = utils.to_str(text, force_string=True)
@ -275,7 +280,7 @@ class PlayerDB(TypedObject, AbstractUser):
session = _MULTISESSION_MODE == 2 and sessid and _GA(self, "get_session")(sessid) or None session = _MULTISESSION_MODE == 2 and sessid and _GA(self, "get_session")(sessid) or None
if session: if session:
obj = session.puppet obj = session.puppet
if obj and not obj.at_msg_receive(text, **kwargs): if obj and not obj.at_msg_receive(text=text, **kwargs):
# if hook returns false, cancel send # if hook returns false, cancel send
return return
session.msg(text=text, **kwargs) session.msg(text=text, **kwargs)

View file

@ -64,7 +64,7 @@ class Player(TypeClass):
* Helper methods * Helper methods
msg(outgoing_string, from_obj=None, data=None) msg(outgoing_string, from_obj=None, **kwargs)
swap_character(new_character, delete_old_character=False) swap_character(new_character, delete_old_character=False)
execute_cmd(raw_string) execute_cmd(raw_string)
search(ostring, global_search=False, attribute_name=None, use_nicks=False, location=None, ignore_errors=False, player=False) search(ostring, global_search=False, attribute_name=None, use_nicks=False, location=None, ignore_errors=False, player=False)
@ -96,21 +96,21 @@ class Player(TypeClass):
## methods inherited from database model ## methods inherited from database model
def msg(self, text=None, **kwargs):#outgoing_string, from_obj=None, data=None, sessid=None): def msg(self, text=None, from_obj=None, sessid=None, **kwargs):
""" """
Evennia -> User Evennia -> User
This is the main route for sending data back to the user from the server. This is the main route for sending data back to the user from the server.
outgoing_string (string) - text data to send text (string) - text data to send
from_obj (Object/Player) - source object of message to send from_obj (Object/Player) - source object of message to send
data (dict) - arbitrary data object containing eventual protocol-specific options
sessid - the session id of the session to send to. If not given, return to sessid - the session id of the session to send to. If not given, return to
all sessions connected to this player. This is usually only all sessions connected to this player. This is usually only
relevant when using msg() directly from a player-command (from relevant when using msg() directly from a player-command (from
a command on a Character, the character automatically stores and a command on a Character, the character automatically stores and
handles the sessid). handles the sessid).
kwargs - extra data to send through protocol
""" """
self.dbobj.msg(text=text, **kwargs)#outgoing_string, from_obj=from_obj, data=data, sessid=sessid) self.dbobj.msg(text=text, from_obj=from_obj, sessid=sessid, **kwargs)
def swap_character(self, new_character, delete_old_character=False): def swap_character(self, new_character, delete_old_character=False):
""" """

View file

@ -151,24 +151,6 @@ class MsgServer2Portal(amp.Command):
errors = [(Exception, 'EXCEPTION')] errors = [(Exception, 'EXCEPTION')]
response = [] response = []
class OOBPortal2Server(amp.Command):
"""
OOB data portal -> server
"""
arguments = [('sessid', amp.Integer()),
('data', amp.String())]
errors = [(Exception, "EXCEPTION")]
response = []
class OOBServer2Portal(amp.Command):
"""
OOB data server -> portal
"""
arguments = [('sessid', amp.Integer()),
('data', amp.String())]
errors = [(Exception, "EXCEPTION")]
response = []
class ServerAdmin(amp.Command): class ServerAdmin(amp.Command):
""" """
Portal -> Server Portal -> Server
@ -289,7 +271,7 @@ class AMPProtocol(amp.AMP):
msg=to_str(msg), msg=to_str(msg),
ipart=icall, ipart=icall,
nparts=nmsglist, nparts=nmsglist,
data=dumps(data)).addErrback(self.errback, "OOBServer2Portal") data=dumps(data)).addErrback(self.errback, "MsgServer2Portal")
for icall, (msg, data) in enumerate(zip(msglist, datalist))] for icall, (msg, data) in enumerate(zip(msglist, datalist))]
# Message definition + helper methods to call/create each message type # Message definition + helper methods to call/create each message type
@ -317,11 +299,11 @@ class AMPProtocol(amp.AMP):
data = "".join(t[2] for t in sorted(MSGBUFFER[sessid], key=lambda o:o[0])) data = "".join(t[2] for t in sorted(MSGBUFFER[sessid], key=lambda o:o[0]))
del MSGBUFFER[sessid] del MSGBUFFER[sessid]
# call session hook with the data # call session hook with the data
self.factory.server.sessions.data_in(sessid, msg, loads(data)) self.factory.server.sessions.data_in(sessid, text=msg, **loads(data))
return {} return {}
MsgPortal2Server.responder(amp_msg_portal2server) MsgPortal2Server.responder(amp_msg_portal2server)
def call_remote_MsgPortal2Server(self, sessid, msg, data=""): def call_remote_MsgPortal2Server(self, sessid, msg, **kwargs):
""" """
Access method called by the Portal and executed on the Portal. Access method called by the Portal and executed on the Portal.
""" """
@ -332,10 +314,10 @@ class AMPProtocol(amp.AMP):
msg=msg, msg=msg,
ipart=0, ipart=0,
nparts=1, nparts=1,
data=dumps(data)).addErrback(self.errback, "MsgPortal2Server") data=dumps(kwargs)).addErrback(self.errback, "MsgPortal2Server")
except amp.TooLong: except amp.TooLong:
# the msg (or data) was too long for AMP to send. We need to send in blocks. # the msg (or data) was too long for AMP to send. We need to send in blocks.
return self.send_split_msg(sessid, msg, data, MsgPortal2Server) return self.send_split_msg(sessid, msg, kwargs, MsgPortal2Server)
# Server -> Portal message # Server -> Portal message
@ -357,11 +339,11 @@ class AMPProtocol(amp.AMP):
data = "".join(t[2] for t in sorted(MSGBUFFER[sessid], key=lambda o:o[0])) data = "".join(t[2] for t in sorted(MSGBUFFER[sessid], key=lambda o:o[0]))
del MSGBUFFER[sessid] del MSGBUFFER[sessid]
# call session hook with the data # call session hook with the data
self.factory.portal.sessions.data_out(sessid, msg, loads(data)) self.factory.portal.sessions.data_out(sessid, text=msg, **loads(data))
return {} return {}
MsgServer2Portal.responder(amp_msg_server2portal) MsgServer2Portal.responder(amp_msg_server2portal)
def call_remote_MsgServer2Portal(self, sessid, msg, data=""): def call_remote_MsgServer2Portal(self, sessid, msg, **kwargs):
""" """
Access method called by the Server and executed on the Server. Access method called by the Server and executed on the Server.
""" """
@ -372,52 +354,10 @@ class AMPProtocol(amp.AMP):
msg=to_str(msg), msg=to_str(msg),
ipart=0, ipart=0,
nparts=1, nparts=1,
data=dumps(data)).addErrback(self.errback, "OOBServer2Portal") data=dumps(kwargs)).addErrback(self.errback, "MsgServer2Portal")
except amp.TooLong: except amp.TooLong:
# the msg (or data) was too long for AMP to send. We need to send in blocks. # the msg (or data) was too long for AMP to send. We need to send in blocks.
return self.send_split_msg(sessid, msg, data, MsgServer2Portal) return self.send_split_msg(sessid, msg, kwargs, MsgServer2Portal)
# OOB Portal -> Server
# Portal -> Server Msg
def amp_oob_portal2server(self, sessid, data):
"""
Relays out-of-band data to server. This method is executed on the Server.
"""
#print "oob portal -> server (server side):", sessid, loads(data)
self.factory.server.sessions.oob_data_in(sessid, loads(data))
return {}
OOBPortal2Server.responder(amp_oob_portal2server)
def call_remote_OOBPortal2Server(self, sessid, data=""):
"""
Access method called by the Portal and executed on the Portal.
"""
#print "oob portal->server (portal side):", sessid, data
self.callRemote(OOBPortal2Server,
sessid=sessid,
data=dumps(data)).addErrback(self.errback, "OOBPortal2Server")
# OOB Server -> Portal message
def amp_oob_server2portal(self, sessid, data):
"""
Relays out-of-band data to Portal. This method is executed on the Portal.
"""
#print "oob server->portal (portal side):", sessid, data
self.factory.portal.sessions.oob_data_out(sessid, loads(data))
return {}
OOBServer2Portal.responder(amp_oob_server2portal)
def call_remote_OOBServer2Portal(self, sessid, data=""):
"""
Access method called by the Server and executed on the Portal.
"""
#print "oob server->portal (server side):", sessid, data
return self.callRemote(OOBServer2Portal,
sessid=sessid,
data=dumps(data)).addErrback(self.errback, "OOBServer2Portal")
# Server administration from the Portal side # Server administration from the Portal side
@ -501,21 +441,19 @@ class AMPProtocol(amp.AMP):
return {} return {}
PortalAdmin.responder(amp_portal_admin) PortalAdmin.responder(amp_portal_admin)
def call_remote_PortalAdmin(self, sessid, operation="", data=""): def call_remote_PortalAdmin(self, sessid, operation="", **kwargs):
""" """
Access method called by the server side. Access method called by the server side.
""" """
#print "portaladmin (server side):", sessid, ord(operation), data #print "portaladmin (server side):", sessid, ord(operation), data
data = dumps(data)
return self.callRemote(PortalAdmin, return self.callRemote(PortalAdmin,
sessid=sessid, sessid=sessid,
operation=operation, operation=operation,
data=data).addErrback(self.errback, "PortalAdmin") data=dumps(kwargs)).addErrback(self.errback, "PortalAdmin")
# Extra functions # Extra functions
def amp_function_call(self, module, function, args, kwargs): def amp_function_call(self, module, function, args, **kwargs):
""" """
This allows Portal- and Server-process to call an arbitrary function This allows Portal- and Server-process to call an arbitrary function
in the other process. It is intended for use by plugin modules. in the other process. It is intended for use by plugin modules.

View file

@ -121,7 +121,7 @@ class PortalSessionHandler(SessionHandler):
return [sess for sess in self.get_sessions(include_unloggedin=True) return [sess for sess in self.get_sessions(include_unloggedin=True)
if hasattr(sess, 'suid') and sess.suid == suid] if hasattr(sess, 'suid') and sess.suid == suid]
def data_in(self, session, string="", data=""): def data_in(self, session, string="", **kwargs):
""" """
Called by portal sessions for relaying data coming Called by portal sessions for relaying data coming
in from the protocol to the server. data is in from the protocol to the server. data is
@ -130,7 +130,7 @@ class PortalSessionHandler(SessionHandler):
#print "portal_data_in:", string #print "portal_data_in:", string
self.portal.amp_protocol.call_remote_MsgPortal2Server(session.sessid, self.portal.amp_protocol.call_remote_MsgPortal2Server(session.sessid,
msg=string, msg=string,
data=data) data=kwargs)
def announce_all(self, message): def announce_all(self, message):
""" """
Send message to all connection sessions Send message to all connection sessions
@ -138,30 +138,13 @@ class PortalSessionHandler(SessionHandler):
for session in self.sessions.values(): for session in self.sessions.values():
session.data_out(message) session.data_out(message)
def data_out(self, sessid, string="", data=""): def data_out(self, sessid, text=None, **kwargs):
""" """
Called by server for having the portal relay messages and data Called by server for having the portal relay messages and data
to the correct session protocol. to the correct session protocol.
""" """
session = self.sessions.get(sessid, None) session = self.sessions.get(sessid, None)
if session: if session:
session.data_out(string, data=data) session.data_out(text=text, **kwargs)
def oob_data_in(self, session, data):
"""
OOB (Out-of-band) data Portal -> Server
"""
print "portal_oob_data_in:", data
self.portal.amp_protocol.call_remote_OOBPortal2Server(session.sessid,
data=data)
def oob_data_out(self, sessid, data):
"""
OOB (Out-of-band) data Server -> Portal
"""
print "portal_oob_data_out:", data
session = self.sessions.get(sessid, None)
if session:
session.oob_data_out(data)
PORTAL_SESSIONS = PortalSessionHandler() PORTAL_SESSIONS = PortalSessionHandler()

View file

@ -173,22 +173,22 @@ class SshProtocol(Manhole, session.Session):
self.data_out(reason) self.data_out(reason)
self.connectionLost(reason) self.connectionLost(reason)
def data_out(self, string, data=None): def data_out(self, text=None, **kwargs):
""" """
Data Evennia -> Player access hook. 'data' argument is a dict parsed for string settings. Data Evennia -> Player access hook. 'data' argument is a dict parsed for string settings.
ssh flags:
raw=True - leave all ansi markup and tokens unparsed
nomarkup=True - remove all ansi markup
""" """
try: try:
string = utils.to_str(string, encoding=self.encoding) text = utils.to_str(text if text else "", encoding=self.encoding)
except Exception, e: except Exception, e:
self.lineSend(str(e)) self.lineSend(str(e))
return return
nomarkup = False raw = kwargs.get("raw", False)
raw = False nomarkup = kwargs.get("nomarkup", False)
if type(data) == dict:
# check if we want escape codes to go through unparsed.
raw = data.get("raw", False)
# check if we want to remove all markup
nomarkup = data.get("nomarkup", False)
if raw: if raw:
self.lineSend(string) self.lineSend(string)
else: else:

View file

@ -141,28 +141,31 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
self.data_out(reason) self.data_out(reason)
self.connectionLost(reason) self.connectionLost(reason)
def data_out(self, string, data=None): def data_out(self, text=None, **kwargs):
""" """
generic hook method for engine to call in order to send data generic hook method for engine to call in order to send data
through the telnet connection. through the telnet connection.
Data Evennia -> Player. Data Evennia -> Player.
data argument may contain a dict with output flags.
valid telnet kwargs:
raw=True - pass string through without any ansi processing (i.e. include Evennia
ansi markers but do not convert them into ansi tokens)
nomarkup=True - strip all ansi markup
The telnet ttype negotiation flags, if any, are used if no kwargs are given.
""" """
try: try:
string = utils.to_str(string, encoding=self.encoding) text = utils.to_str(text if text else "", encoding=self.encoding)
except Exception, e: except Exception, e:
self.sendLine(str(e)) self.sendLine(str(e))
return return
ttype = self.protocol_flags.get('TTYPE', {}) ttype = self.protocol_flags.get('TTYPE', {})
raw = kwargs.get("raw", False)
nomarkup = not (ttype or ttype.get('256 COLORS') or ttype.get('ANSI') or not ttype.get("init_done")) nomarkup = not (ttype or ttype.get('256 COLORS') or ttype.get('ANSI') or not ttype.get("init_done"))
raw = False nomarkup = kwargs.get("nomarkup", nomarkup)
if type(data) == dict:
# check if we want escape codes to go through unparsed.
raw = data.get("raw", False)
# check if we want to remove all markup (TTYPE override)
nomarkup = data.get("nomarkup", False)
if raw: if raw:
self.sendLine(string) # no processing whatsoever
self.sendLine(text)
else: else:
# we need to make sure to kill the color at the end in order to match the webclient output. # we need to make sure to kill the color at the end in order to match the webclient output.
self.sendLine(ansi.parse_ansi(_RE_N.sub("", string) + "{n", strip_ansi=nomarkup, xterm256=ttype.get('256 COLORS'))) self.sendLine(ansi.parse_ansi(_RE_N.sub("", text) + "{n", strip_ansi=nomarkup, xterm256=ttype.get('256 COLORS')))

View file

@ -224,33 +224,24 @@ class WebClientSession(session.Session):
self.client.lineSend(self.suid, reason) self.client.lineSend(self.suid, reason)
self.client.client_disconnect(self.suid) self.client.client_disconnect(self.suid)
def data_out(self, string='', data=None): def data_out(self, text=None, **kwargs):
""" """
Data Evennia -> Player access hook. Data Evennia -> Player access hook.
data argument may be used depending on webclient flags checked are
the client-server implementation. raw=True - no parsing at all (leave ansi-to-html markers unparsed)
nomarkup=True - clean out all ansi/html markers and tokens
""" """
if data:
# treat data?
pass
# string handling is similar to telnet # string handling is similar to telnet
try: try:
string = utils.to_str(string, encoding=self.encoding) text = utils.to_str(text if text else "", encoding=self.encoding)
raw = kwargs.get("raw", False)
nomarkup = False nomarkup = kwargs.get("nomarkup", False)
raw = False
if type(data) == dict:
# check if we want escape codes to go through unparsed.
raw = data.get("raw", False)
# check if we want to remove all markup
nomarkup = data.get("nomarkup", False)
if raw: if raw:
self.client.lineSend(self.suid, string) self.client.lineSend(self.suid, text)
else: else:
self.client.lineSend(self.suid, parse_html(string, strip_ansi=nomarkup)) self.client.lineSend(self.suid, parse_html(text, strip_ansi=nomarkup))
return return
except Exception, e: except Exception:
logger.log_trace() logger.log_trace()

View file

@ -13,7 +13,7 @@ from django.conf import settings
from src.scripts.models import ScriptDB from src.scripts.models import ScriptDB
from src.comms.models import Channel from src.comms.models import Channel
from src.utils import logger, utils from src.utils import logger, utils
from src.utils.utils import make_iter from src.utils.utils import make_iter, to_str
from src.commands import cmdhandler, cmdsethandler from src.commands import cmdhandler, cmdsethandler
from src.server.session import Session from src.server.session import Session
@ -162,25 +162,25 @@ class ServerSession(Session):
# Player-visible idle time, not used in idle timeout calcs. # Player-visible idle time, not used in idle timeout calcs.
self.cmd_last_visible = time.time() self.cmd_last_visible = time.time()
def data_in(self, command_string): def data_in(self, text=None, **kwargs):
""" """
Send Player->Evennia. This will in effect Send Player->Evennia. This will in effect
execute a command string on the server. execute a command string on the server.
Eventual extra data moves through oob_data_in Eventual extra data moves through oob_data_in
""" """
if text:
# this is treated as a command input
text = to_str(text)
# handle the 'idle' command # handle the 'idle' command
if str(command_string).strip() == IDLE_COMMAND: if text.strip() == IDLE_COMMAND:
self.update_session_counters(idle=True) self.update_session_counters(idle=True)
return return
cmdhandler.cmdhandler(self, command_string, callertype="session", sessid=self.sessid) cmdhandler.cmdhandler(self, text, callertype="session", sessid=self.sessid)
#if self.logged_in:
# # the inmsg handler will relay to the right place
# self.player.inmsg(command_string, self)
#else:
# # we are not logged in. Execute cmd with the the session directly
# # (it uses the settings.UNLOGGEDIN cmdset)
# cmdhandler.cmdhandler(self, command_string, sessid=self.sessid)
self.update_session_counters() self.update_session_counters()
if "oob" in kwargs:
# relay to OOB handler
pass
execute_cmd = data_in # alias execute_cmd = data_in # alias
def data_out(self, text=None, **kwargs): def data_out(self, text=None, **kwargs):
@ -189,58 +189,6 @@ class ServerSession(Session):
""" """
self.sessionhandler.data_out(self, text=text, **kwargs) self.sessionhandler.data_out(self, text=text, **kwargs)
def oob_data_in(self, data):
"""
This receives out-of-band data from the Portal.
OBS - preliminary. OOB not yet functional in Evennia. Don't use.
This method parses the data input (a dict) and uses
it to launch correct methods from those plugged into
the system.
data = {oobkey: (funcname, (args), {kwargs}),
oobkey: (funcname, (args), {kwargs}), ...}
example:
data = {"get_hp": ("oob_get_hp, [], {}),
"update_counter", ("counter", ["counter1"], {"now":True}) }
All function names must be defined in settings.OOB_PLUGIN_MODULE. Each
function will be called with the oobkey and a back-reference to this session
as their first two arguments.
"""
outdata = {}
for oobkey, functuple in data.items():
# loop through the data, calling available functions.
func = OOB_PLUGIN_MODULE.__dict__.get(functuple[0])
if func:
try:
outdata[functuple[0]] = func(oobkey, self, *functuple[1], **functuple[2])
except Exception:
logger.log_trace()
else:
logger.log_errmsg("oob_data_in error: funcname '%s' not found in OOB_PLUGIN_MODULE." % functuple[0])
if outdata:
# we have a direct result - send it back right away
self.oob_data_out(outdata)
def oob_data_out(self, data):
"""
This sends data from Server to the Portal across the AMP connection.
OBS - preliminary. OOB not yet functional in Evennia. Don't use.
data = {oobkey: (funcname, (args), {kwargs}),
oobkey: (funcname, (args), {kwargs}), ...}
"""
self.sessionhandler.oob_data_out(self, data)
def __eq__(self, other): def __eq__(self, other):
return self.address == other.address return self.address == other.address

View file

@ -111,7 +111,7 @@ class Session(object):
""" """
pass pass
def data_out(self, msg, data=None): 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
@ -119,26 +119,9 @@ class Session(object):
""" """
pass pass
def data_in(self, msg, data=None): 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.
""" """
pass pass
def oob_data_out(self, data):
"""
for Portal, this receives out-of-band data from Server across the AMP.
for Server, this sends out-of-band data to Portal.
data is a dictionary
"""
pass
def oob_data_in(self, data):
"""
for Portal, this sends out-of-band requests to Server over the AMP.
for Server, this receives data from Portal.
data is a dictionary
"""
pass

View file

@ -367,31 +367,13 @@ class ServerSessionHandler(SessionHandler):
self.server.amp_protocol.call_remote_MsgServer2Portal(sessid=session.sessid, self.server.amp_protocol.call_remote_MsgServer2Portal(sessid=session.sessid,
msg=text, msg=text,
data=kwargs) data=kwargs)
def data_in(self, sessid, text="", data=""): def data_in(self, sessid, text="", **kwargs):
""" """
Data Portal -> Server Data Portal -> Server
""" """
session = self.sessions.get(sessid, None) session = self.sessions.get(sessid, None)
if session: if session:
kwargs = data if data else {} session.data_in(text=text, **kwargs)
session.data_in(text, **kwargs)
# ignore 'data' argument for now; this is otherwise the place
# to put custom effects on the server due to data input, e.g.
# from a custom client.
def oob_data_in(self, sessid, data):
"""
OOB (Out-of-band) Data Portal -> Server
"""
session = self.sessions.get(sessid, None)
if session:
session.oob_data_in(data)
def oob_data_out(self, session, data):
"""
OOB (Out-of-band) Data Server -> Portal
"""
self.server.amp_protocol.call_remote_OOBServer2Portal(session.sessid,
data=data)
SESSIONS = ServerSessionHandler() SESSIONS = ServerSessionHandler()

View file

@ -428,6 +428,9 @@ class NickHandler(AttributeHandler):
""" """
Handles the addition and removal of Nicks Handles the addition and removal of Nicks
(uses Attributes' strvalue and category fields) (uses Attributes' strvalue and category fields)
Nicks are stored as Attributes
with categories nick_<nicktype>
""" """
def has(self, key, category="inputline"): def has(self, key, category="inputline"):
categry = "nick_%s" % category categry = "nick_%s" % category