diff --git a/evennia/server/oob_cmds.py b/evennia/server/oob_cmds.py index e6c3fc5ead..95a733aea1 100644 --- a/evennia/server/oob_cmds.py +++ b/evennia/server/oob_cmds.py @@ -193,6 +193,7 @@ def oob_send(oobhandler, session, *args, **kwargs): if obj: for name in (a.upper() for a in args if a): try: + print "MSDP SEND inp:", name value = OOB_SENDABLE.get(name, _NA_SEND)(obj) ret[name] = value except Exception, e: diff --git a/evennia/server/oobhandler.py b/evennia/server/oobhandler.py index b26d6aeefe..7c65352e43 100644 --- a/evennia/server/oobhandler.py +++ b/evennia/server/oobhandler.py @@ -414,6 +414,7 @@ class OOBHandler(TickerHandler): (session, oobfuncname, args, kwargs) raise RuntimeError(errmsg) + print "execute_oob:", session, oobfuncname, args, kwargs # don't catch this, wrong oobfuncname should be reported oobfunc = _OOB_FUNCS[oobfuncname] diff --git a/evennia/server/portal/portalsessionhandler.py b/evennia/server/portal/portalsessionhandler.py index cc1d552a86..f714e0cecf 100644 --- a/evennia/server/portal/portalsessionhandler.py +++ b/evennia/server/portal/portalsessionhandler.py @@ -2,7 +2,7 @@ Sessionhandler for portal sessions """ import time -from evennia.server.sessionhandler import SessionHandler, PCONN, PDISCONN, PSYNC, PCONNSYNC +from evennia.server.sessionhandler import SessionHandler, PCONN, PDISCONN, PCONNSYNC _MOD_IMPORT = None diff --git a/evennia/server/portal/telnet.py b/evennia/server/portal/telnet.py index dbaa6828a3..d5adef8bdb 100644 --- a/evennia/server/portal/telnet.py +++ b/evennia/server/portal/telnet.py @@ -236,11 +236,11 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session): except Exception, e: self.sendLine(str(e)) return - if "oob" in kwargs: + if "oob" in kwargs and "OOB" in self.protocol_flags: # oob is a list of [(cmdname, arg, kwarg), ...] - if "OOB" in self.protocol_flags: - for cmdname, args, kwargs in kwargs["oob"]: - self.oob.data_out(cmdname, *args, **kwargs) + for cmdname, args, kwargs in kwargs["oob"]: + print "telnet oob data_out:", cmdname, args, kwargs + self.oob.data_out(cmdname, *args, **kwargs) # parse **kwargs, falling back to ttype if nothing is given explicitly ttype = self.protocol_flags.get('TTYPE', {}) diff --git a/evennia/server/portal/telnet_oob.py b/evennia/server/portal/telnet_oob.py index 7681a87bee..faa144fa40 100644 --- a/evennia/server/portal/telnet_oob.py +++ b/evennia/server/portal/telnet_oob.py @@ -32,8 +32,10 @@ MSDP_TABLE_CLOSE = chr(4) MSDP_ARRAY_OPEN = chr(5) MSDP_ARRAY_CLOSE = chr(6) +# GMCP GMCP = chr(200) +# General Telnet IAC = chr(255) SB = chr(250) SE = chr(240) @@ -54,7 +56,7 @@ msdp_regex_val = re.compile(MSDP_VAL) # Msdp object handler -class Telnet_OOB(object): +class TelnetOOB(object): """ Implements the MSDP and GMCP protocols. """ @@ -110,26 +112,27 @@ class Telnet_OOB(object): cmdname *args -> cmdname MSDP_ARRAY cmdname **kwargs -> cmdname MSDP_TABLE - OBS - whereas there are also definitions for making arrays and tables in - the specification, these are not actually used in the default - msdp commands -- returns are implemented as simple lists or - named lists (our name for them here, these un-bounded - structures are not named in the specification). So for now, - this routine will not explicitly create arrays nor tables, - although there are helper methods ready should it be needed in - the future. + # send 'raw' data structures + MSDP_ARRAY *args -> MSDP_ARRAY + MSDP_TABLE **kwargs -> MSDP_TABLE + """ msdp_string = "" if args: - if len(args) == 1: - msdp_string = "%s %s" % (cmdname.upper(), args[0]) + if cmdname == "MSDP_ARRAY": + msdp_string = "".join(["%s%s" % (MSDP_VAL, val) for val in args]) else: - msdp_string = "%s%s%s%s" % (MSDP_VAR, cmdname.upper(), "".join( + msdp_string = "%s%s%s" % (MSDP_VAR, cmdname.upper(), "".join( "%s%s" % (MSDP_VAL, val) for val in args)) elif kwargs: - msdp_string = "%s%s%s" % (MSDP_VAR. cmdname.upper(), "".join( + if cmdname == "MSDP_TABLE": + msdp_string = "".join(["%s%s%s%s" % (MSDP_VAR, key, MSDP_VAL, val) + for key, val in kwargs.items()]) + else: + msdp_string = "%s%s%s" % (MSDP_VAR. cmdname.upper(), "".join( ["%s%s%s%s" % (MSDP_VAR, key, MSDP_VAL, val) for key, val in kwargs.items()])) - return msdp_string + print "encode msdp result:", cmdname, args, kwargs, "->", msdp_string + return force_str(msdp_string) def encode_gmcp(self, cmdname, *args, **kwargs): """ @@ -142,11 +145,18 @@ class Telnet_OOB(object): cmdname is generally recommended to be a string on the form Module.Submodule.Function """ + if cmdname in ("SEND", "ECHO", "REPORT", "UNREPORT", "LIST"): + # we wrap the standard MSDP commands in a MSDP. submodule + # here as far as GMCP is concerned. + cmdname = "MSDP.%s" % cmdname + elif cmdname in ("MSDP_ARRAY", "MSDP_TABLE"): + # no cmdname should accompany these, just the MSDP wrapper + cmdname = "MSDP" if args: gmcp_string = "%s %s" % (cmdname, json.dumps(args)) elif kwargs: gmcp_string = "%s %s" % (cmdname, json.dumps(kwargs)) - return gmcp_string + return force_str(gmcp_string).strip() def decode_msdp(self, data): """ @@ -182,6 +192,8 @@ class Telnet_OOB(object): parts = msdp_regex_val.split(varval) variables[parts[0].upper()] = tuple(parts[1:]) if len(parts) > 1 else ("", ) + print "OOB: MSDP decode:", data, "->", variables, arrays, tables + # send to the sessionhandler if data: for varname, var in variables.items(): @@ -221,10 +233,11 @@ class Telnet_OOB(object): Return a msdp-valid subnegotiation across the protocol. """ if self.MSDP: - encoded_oob = force_str(self.encode_msdp(cmdname, *args, **kwargs)) + encoded_oob = self.encode_msdp(cmdname, *args, **kwargs) + print "data_out:", encoded_oob self.protocol._write(IAC + SB + MSDP + encoded_oob + IAC + SE) else: - encoded_oob = force_str(self.encode_gmcp(cmdname, *args, **kwargs)) + encoded_oob = self.encode_gmcp(cmdname, *args, **kwargs) self.protocol._write(IAC + SB + GMCP + encoded_oob + IAC + SE) def data_in(self, data): diff --git a/evennia/server/sessionhandler.py b/evennia/server/sessionhandler.py index d26f619b16..67608da5a9 100644 --- a/evennia/server/sessionhandler.py +++ b/evennia/server/sessionhandler.py @@ -438,6 +438,7 @@ class ServerSessionHandler(SessionHandler): if not _OOB_HANDLER: from evennia.server.oobhandler import OOB_HANDLER as _OOB_HANDLER funcname, args, kwargs = kwargs.pop("oob") + print "OOB sessionhandler.data_in:", funcname, args, kwargs if funcname: _OOB_HANDLER.execute_cmd(session, funcname, *args, **kwargs)