Validating GMCP/MSDP protocol commands, first debugging run and fixes to make a few of the default inputfuncs work. Added INPUTDEBUG to the options dict, to echo input function errors directly.
This commit is contained in:
parent
76dc51f885
commit
043be6dba4
6 changed files with 43 additions and 40 deletions
|
|
@ -458,7 +458,8 @@ class CmdOption(MuxPlayerCommand):
|
||||||
"SCREENREADER": validate_bool,
|
"SCREENREADER": validate_bool,
|
||||||
"TERM": utils.to_str,
|
"TERM": utils.to_str,
|
||||||
"UTF-8": validate_bool,
|
"UTF-8": validate_bool,
|
||||||
"XTERM256": validate_bool}
|
"XTERM256": validate_bool,
|
||||||
|
"INPUTDEBUG": validate_bool}
|
||||||
|
|
||||||
name = self.lhs.upper()
|
name = self.lhs.upper()
|
||||||
val = self.rhs.strip()
|
val = self.rhs.strip()
|
||||||
|
|
|
||||||
|
|
@ -77,9 +77,7 @@ def echo(session, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Echo test function
|
Echo test function
|
||||||
"""
|
"""
|
||||||
print "Inputfunc echo:", session, args, kwargs
|
session.data_out(text="Echo returns: %s" % args)
|
||||||
session.data_out(text="Echo returns: ")
|
|
||||||
session.data_out(echo=(args, kwargs))
|
|
||||||
|
|
||||||
|
|
||||||
def default(session, cmdname, *args, **kwargs):
|
def default(session, cmdname, *args, **kwargs):
|
||||||
|
|
@ -90,8 +88,13 @@ def default(session, cmdname, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
err = "Session {sessid}: Input command not recognized:\n" \
|
err = "Session {sessid}: Input command not recognized:\n" \
|
||||||
" name: '{cmdname}'\n" \
|
" name: '{cmdname}'\n" \
|
||||||
" args, kwargs: {args}, {kwargs}"
|
" args, kwargs: {args}, {kwargs}".format(sessid=session.sessid,
|
||||||
log_err(err.format(sessid=session.sessid, cmdname=cmdname, args=args, kwargs=kwargs))
|
cmdname=cmdname,
|
||||||
|
args=args,
|
||||||
|
kwargs=kwargs)
|
||||||
|
if session.protocol_flags.get("INPUTDEBUG", False):
|
||||||
|
session.msg(err)
|
||||||
|
log_err(err)
|
||||||
|
|
||||||
|
|
||||||
def client_options(session, *args, **kwargs):
|
def client_options(session, *args, **kwargs):
|
||||||
|
|
@ -112,16 +115,17 @@ def client_options(session, *args, **kwargs):
|
||||||
mccp (bool): MCCP compression on/off
|
mccp (bool): MCCP compression on/off
|
||||||
screenheight (int): Screen height in lines
|
screenheight (int): Screen height in lines
|
||||||
screenwidth (int): Screen width in characters
|
screenwidth (int): Screen width in characters
|
||||||
|
inputdebug (bool): Debug input functions
|
||||||
|
|
||||||
"""
|
"""
|
||||||
flags = session.protocol_flags
|
flags = session.protocol_flags
|
||||||
if kwargs.get("get", False):
|
if not kwargs or kwargs.get("get", False):
|
||||||
# return current settings
|
# return current settings
|
||||||
options = dict((key, flags[key]) for key in flags
|
options = dict((key, flags[key]) for key in flags
|
||||||
if key in ("ANSI", "XTERM256", "MXP",
|
if key.upper() in ("ANSI", "XTERM256", "MXP",
|
||||||
"UTF-8", "SCREENREADER",
|
"UTF-8", "SCREENREADER",
|
||||||
"MCCP", "SCREENHEIGHT",
|
"MCCP", "SCREENHEIGHT",
|
||||||
"SCREENWIDTH"))
|
"SCREENWIDTH", "INPUTDEBUG"))
|
||||||
session.msg(client_options=options)
|
session.msg(client_options=options)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -148,6 +152,8 @@ def client_options(session, *args, **kwargs):
|
||||||
flags["SCREENHEIGHT"] = int(value)
|
flags["SCREENHEIGHT"] = int(value)
|
||||||
elif key == "screenwidth":
|
elif key == "screenwidth":
|
||||||
flags["SCREENWIDTH"] = int(value)
|
flags["SCREENWIDTH"] = int(value)
|
||||||
|
elif key == "inputdebug":
|
||||||
|
flags["INPUTDEBUG"] = bool(value)
|
||||||
elif not key == "options":
|
elif not key == "options":
|
||||||
err = _ERROR_INPUT.format(
|
err = _ERROR_INPUT.format(
|
||||||
name="client_settings", session=session, inp=key)
|
name="client_settings", session=session, inp=key)
|
||||||
|
|
@ -192,6 +198,7 @@ def login(session, *args, **kwargs):
|
||||||
|
|
||||||
_gettable = {
|
_gettable = {
|
||||||
"name": lambda obj: obj.key,
|
"name": lambda obj: obj.key,
|
||||||
|
"key": lambda obj: obj.key,
|
||||||
"location": lambda obj: obj.location.key if obj.location else "None",
|
"location": lambda obj: obj.location.key if obj.location else "None",
|
||||||
"servername": lambda obj: settings.SERVERNAME
|
"servername": lambda obj: settings.SERVERNAME
|
||||||
}
|
}
|
||||||
|
|
@ -324,8 +331,8 @@ gmcp_char_monitor_on = monitor # Char.Monitor.On
|
||||||
gmcp_char_monitor_off = unmonitor # Char.Monitor.Off
|
gmcp_char_monitor_off = unmonitor # Char.Monitor.Off
|
||||||
|
|
||||||
# aliases for MSDP
|
# aliases for MSDP
|
||||||
SEND = get_value # SEND
|
#SEND = get_value # SEND
|
||||||
REPEAT = repeat # REPEAT
|
#REPEAT = repeat # REPEAT
|
||||||
UNREPEAT = unrepeat # UNREPEAT
|
#UNREPEAT = unrepeat # UNREPEAT
|
||||||
MONITOR = monitor # REPORT
|
#MONITOR = monitor # REPORT
|
||||||
LIST = get_inputfuncs # LIST
|
#LIST = get_inputfuncs # LIST
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
|
||||||
|
|
||||||
def _write(self, data):
|
def _write(self, data):
|
||||||
"hook overloading the one used in plain telnet"
|
"hook overloading the one used in plain telnet"
|
||||||
|
print "Activated GMCP"
|
||||||
data = data.replace('\n', '\r\n').replace('\r\r\n', '\r\n')
|
data = data.replace('\n', '\r\n').replace('\r\r\n', '\r\n')
|
||||||
#data = data.replace('\n', '\r\n')
|
#data = data.replace('\n', '\r\n')
|
||||||
super(TelnetProtocol, self)._write(mccp_compress(self, data))
|
super(TelnetProtocol, self)._write(mccp_compress(self, data))
|
||||||
|
|
@ -312,7 +313,6 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
|
||||||
mxp = options.get("mxp", flags.get("MXP", False))
|
mxp = options.get("mxp", flags.get("MXP", False))
|
||||||
screenreader = options.get("screenreader", flags.get("SCREENREADER", False))
|
screenreader = options.get("screenreader", flags.get("SCREENREADER", False))
|
||||||
|
|
||||||
print "screenreader:", screenreader, options, flags
|
|
||||||
if screenreader:
|
if screenreader:
|
||||||
# screenreader mode cleans up output
|
# screenreader mode cleans up output
|
||||||
text = ansi.parse_ansi(text, strip_ansi=True, xterm256=False, mxp=False)
|
text = ansi.parse_ansi(text, strip_ansi=True, xterm256=False, mxp=False)
|
||||||
|
|
|
||||||
|
|
@ -61,27 +61,12 @@ msdp_regex_array = re.compile(r"%s\s*(\w*?)\s*%s\s*%s(.*?)%s" % (MSDP_VAR, MSDP_
|
||||||
msdp_regex_var = re.compile(r"%s" % MSDP_VAR)
|
msdp_regex_var = re.compile(r"%s" % MSDP_VAR)
|
||||||
msdp_regex_val = re.compile(r"%s" % MSDP_VAL)
|
msdp_regex_val = re.compile(r"%s" % MSDP_VAL)
|
||||||
|
|
||||||
EVENNIA_TO_MSDP = {"client_options": "OPTIONS",
|
|
||||||
"get_inputfuncs": "LIST",
|
|
||||||
"get_value": "SEND",
|
|
||||||
"repeat": "REPEAT",
|
|
||||||
"monitor": "REPORT"}
|
|
||||||
|
|
||||||
EVENNIA_TO_GMCP = {"client_options": "Core.Supports.Get",
|
EVENNIA_TO_GMCP = {"client_options": "Core.Supports.Get",
|
||||||
"get_inputfuncs": "Core.Commands.Get",
|
"get_inputfuncs": "Core.Commands.Get",
|
||||||
"get_value": "Char.Value.Get",
|
"get_value": "Char.Value.Get",
|
||||||
"repeat": "Char.Repeat.Update",
|
"repeat": "Char.Repeat.Update",
|
||||||
"monitor": "Char.Monitor.Update"}
|
"monitor": "Char.Monitor.Update"}
|
||||||
|
|
||||||
|
|
||||||
# MSDP output templates
|
|
||||||
|
|
||||||
# cmdname
|
|
||||||
MSDP_STRING_A = "{msdp_var}{{cmdname}}{msdp_val}''".format(
|
|
||||||
msdp_var=MSDP_VAR, msdp_val=MSDP_VAL)
|
|
||||||
# cmdname arg
|
|
||||||
|
|
||||||
|
|
||||||
# Msdp object handler
|
# Msdp object handler
|
||||||
|
|
||||||
class TelnetOOB(object):
|
class TelnetOOB(object):
|
||||||
|
|
@ -192,6 +177,8 @@ class TelnetOOB(object):
|
||||||
if not (args or kwargs):
|
if not (args or kwargs):
|
||||||
return msdp_cmdname
|
return msdp_cmdname
|
||||||
|
|
||||||
|
print "encode_msdp in:", cmdname, args, kwargs
|
||||||
|
|
||||||
msdp_args = ''
|
msdp_args = ''
|
||||||
if args:
|
if args:
|
||||||
msdp_args = msdp_cmdname
|
msdp_args = msdp_cmdname
|
||||||
|
|
@ -273,7 +260,7 @@ class TelnetOOB(object):
|
||||||
Clients should always send MSDP data on
|
Clients should always send MSDP data on
|
||||||
one of the following forms:
|
one of the following forms:
|
||||||
|
|
||||||
cmdname -> [cmdname, [], {}]
|
cmdname '' -> [cmdname, [], {}]
|
||||||
cmdname val -> [cmdname, [val], {}]
|
cmdname val -> [cmdname, [val], {}]
|
||||||
cmdname array -> [cmdname, [array], {}]
|
cmdname array -> [cmdname, [array], {}]
|
||||||
cmdname table -> [cmdname, [], {table}]
|
cmdname table -> [cmdname, [], {table}]
|
||||||
|
|
@ -289,6 +276,8 @@ class TelnetOOB(object):
|
||||||
if hasattr(data, "__iter__"):
|
if hasattr(data, "__iter__"):
|
||||||
data = "".join(data)
|
data = "".join(data)
|
||||||
|
|
||||||
|
print "decode_msdp in:", data
|
||||||
|
|
||||||
tables = {}
|
tables = {}
|
||||||
arrays = {}
|
arrays = {}
|
||||||
variables = {}
|
variables = {}
|
||||||
|
|
@ -298,7 +287,8 @@ class TelnetOOB(object):
|
||||||
tables[key] = {} if not key in tables else tables[key]
|
tables[key] = {} if not key in tables else tables[key]
|
||||||
for varval in msdp_regex_var.split(table)[1:]:
|
for varval in msdp_regex_var.split(table)[1:]:
|
||||||
var, val = msdp_regex_val.split(varval, 1)
|
var, val = msdp_regex_val.split(varval, 1)
|
||||||
tables[key][var] = val
|
if var:
|
||||||
|
tables[key][var] = val
|
||||||
|
|
||||||
# decode arrays from all that was not a table
|
# decode arrays from all that was not a table
|
||||||
data_no_tables = msdp_regex_table.sub("", data)
|
data_no_tables = msdp_regex_table.sub("", data)
|
||||||
|
|
@ -341,6 +331,7 @@ class TelnetOOB(object):
|
||||||
for key, var in variables.iteritems():
|
for key, var in variables.iteritems():
|
||||||
cmds[key] = [[var], {}]
|
cmds[key] = [[var], {}]
|
||||||
|
|
||||||
|
print "msdp data in:", cmds
|
||||||
self.protocol.data_in(**cmds)
|
self.protocol.data_in(**cmds)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -382,7 +373,7 @@ class TelnetOOB(object):
|
||||||
args, kwargs = [], {}
|
args, kwargs = [], {}
|
||||||
if hasattr(structure, "__iter__"):
|
if hasattr(structure, "__iter__"):
|
||||||
if isinstance(structure, dict):
|
if isinstance(structure, dict):
|
||||||
kwargs = structure
|
kwargs = {key: value for key, value in structure.iteritems() if key }
|
||||||
else:
|
else:
|
||||||
args = list(structure)
|
args = list(structure)
|
||||||
else:
|
else:
|
||||||
|
|
@ -409,12 +400,10 @@ class TelnetOOB(object):
|
||||||
args, kwargs (any): Arguments to OOB command.
|
args, kwargs (any): Arguments to OOB command.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
kwargs.pop("options", None)
|
||||||
|
|
||||||
if self.MSDP:
|
if self.MSDP:
|
||||||
if cmdname in EVENNIA_TO_MSDP:
|
msdp_cmdname = cmdname
|
||||||
msdp_cmdname = EVENNIA_TO_MSDP[cmdname]
|
|
||||||
else:
|
|
||||||
msdp_cmdname = "CUSTOM"
|
|
||||||
kwargs["cmdname"] = cmdname
|
|
||||||
encoded_oob = self.encode_msdp(msdp_cmdname, *args, **kwargs)
|
encoded_oob = self.encode_msdp(msdp_cmdname, *args, **kwargs)
|
||||||
print "sending MSDP:", encoded_oob
|
print "sending MSDP:", encoded_oob
|
||||||
self.protocol._write(IAC + SB + MSDP + encoded_oob + IAC + SE)
|
self.protocol._write(IAC + SB + MSDP + encoded_oob + IAC + SE)
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,9 @@ class Session(object):
|
||||||
self.cmd_last = self.conn_time
|
self.cmd_last = self.conn_time
|
||||||
self.cmd_total = 0
|
self.cmd_total = 0
|
||||||
|
|
||||||
self.protocol_flags = {"ENCODING": "utf-8", "SCREENREADER":False}
|
self.protocol_flags = {"ENCODING": "utf-8",
|
||||||
|
"SCREENREADER":False,
|
||||||
|
"INPUTDEBUG": False}
|
||||||
self.server_data = {}
|
self.server_data = {}
|
||||||
|
|
||||||
# map of input data to session methods
|
# map of input data to session methods
|
||||||
|
|
|
||||||
|
|
@ -645,14 +645,18 @@ class ServerSessionHandler(SessionHandler):
|
||||||
|
|
||||||
# distribute incoming data to the correct receiving methods.
|
# distribute incoming data to the correct receiving methods.
|
||||||
if session:
|
if session:
|
||||||
|
input_debug = session.protocol_flags.get("INPUTDEBUG", False)
|
||||||
for cmdname, (cmdargs, cmdkwargs) in kwargs.iteritems():
|
for cmdname, (cmdargs, cmdkwargs) in kwargs.iteritems():
|
||||||
cname = cmdname.strip().lower()
|
cname = cmdname.strip().lower()
|
||||||
try:
|
try:
|
||||||
|
cmdkwargs.pop("options", None)
|
||||||
if cname in _INPUT_FUNCS:
|
if cname in _INPUT_FUNCS:
|
||||||
_INPUT_FUNCS[cname](session, *cmdargs, **cmdkwargs)
|
_INPUT_FUNCS[cname](session, *cmdargs, **cmdkwargs)
|
||||||
else:
|
else:
|
||||||
_INPUT_FUNCS["default"](session, cname, *cmdargs, **cmdkwargs)
|
_INPUT_FUNCS["default"](session, cname, *cmdargs, **cmdkwargs)
|
||||||
except Exception:
|
except Exception, err:
|
||||||
|
if input_debug:
|
||||||
|
session.msg(err)
|
||||||
log_trace()
|
log_trace()
|
||||||
|
|
||||||
SESSION_HANDLER = ServerSessionHandler()
|
SESSION_HANDLER = ServerSessionHandler()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue