Fixed a spurious error happening with mud clients not properly implementing TTYPE negotiating (sending strings instead of numbers to identify their abilities).

This commit is contained in:
Griatch 2012-04-15 19:53:03 +02:00
parent 6501f30cbc
commit 91ec33b9a7
3 changed files with 43 additions and 17 deletions

View file

@ -24,8 +24,7 @@ try:
except Exception: except Exception:
pass pass
if not CONNECTION_SCREEN: if not CONNECTION_SCREEN:
CONNECTION_SCREEN = "\nEvennia: Error in CONNECTION_SCREEN MODULE. Connect screen not found. Enter 'help' for aid." CONNECTION_SCREEN = "\nEvennia: Error in CONNECTION_SCREEN MODULE (randomly picked connection screen variable is not a string). \nEnter 'help' for aid."
class CmdUnconnectedConnect(MuxCommand): class CmdUnconnectedConnect(MuxCommand):
""" """

View file

@ -11,7 +11,7 @@ from twisted.conch.telnet import Telnet, StatefulTelnetProtocol, IAC, LINEMODE
from src.server.session import Session from src.server.session import Session
from src.server import ttype, mssp from src.server import ttype, mssp
from src.server.mccp import Mccp, mccp_compress, MCCP from src.server.mccp import Mccp, mccp_compress, MCCP
from src.utils import utils, ansi from src.utils import utils, ansi, logger
class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session): class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
""" """
@ -25,6 +25,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
established. established.
""" """
# initialize the session # initialize the session
self.iaw_mode = False
client_address = self.transport.client client_address = self.transport.client
self.init_session("telnet", client_address, self.factory.sessionhandler) self.init_session("telnet", client_address, self.factory.sessionhandler)
# negotiate mccp (data compression) # negotiate mccp (data compression)
@ -76,26 +77,32 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
""" """
This method will split the incoming data depending on if it This method will split the incoming data depending on if it
starts with IAC (a telnet command) or not. All other data will starts with IAC (a telnet command) or not. All other data will
be handled in line mode. be handled in line mode. Some clients also sends an erroneous
line break after IAC, which we must watch out for.
""" """
print "dataRcv (%s):" % data, #print "dataRcv (%s):" % data,
try: #try:
for b in data: # for b in data:
print ord(b), # print ord(b),
print "" # print ""
except Exception, e: #except Exception, e:
print str(e) + ":", str(data) # print str(e) + ":", str(data)
if data and data[0] == IAC: if data and data[0] == IAC or self.iaw_mode:
try: try:
print "IAC mode" #print "IAC mode"
super(TelnetProtocol, self).dataReceived(data) super(TelnetProtocol, self).dataReceived(data)
if len(data) == 1:
self.iaw_mode = True
else:
self.iaw_mode = False
return return
except Exception: except Exception:
pass logger.log_trace()
# if we get to this point the command must end with a linebreak. # if we get to this point the command must end with a linebreak.
#data = data.rstrip("\r\n") + "\r\n" # We make sure to add it, to fix some clients messing this up.
print "line mode: (%s)" % data data = data.rstrip("\r\n") + "\r\n"
#print "line mode: (%s)" % data
StatefulTelnetProtocol.dataReceived(self, data) StatefulTelnetProtocol.dataReceived(self, data)
def _write(self, data): def _write(self, data):

View file

@ -25,6 +25,16 @@ MTTS = [(128,'PROXY'),
(4, 'UTF-8'), (4, 'UTF-8'),
(2, 'VT100'), (2, 'VT100'),
(1, 'ANSI')] (1, 'ANSI')]
# some clients sends erroneous strings instead
# of capability numbers. We try to convert back.
MTTS_invert = {"PROXY":128,
"SCREEN COLOR PALETTE":64,
"OSC COLOR PALETTE": 32,
"MOUSE TRACKING": 16,
"256 COLORS": 8,
"UTF-8": 4,
"VT100": 2,
"ANSI": 1}
class Ttype(object): class Ttype(object):
""" """
@ -81,7 +91,17 @@ class Ttype(object):
self.protocol.protocol_flags['TTYPE']['TERM'] = option self.protocol.protocol_flags['TTYPE']['TERM'] = option
self.protocol.requestNegotiation(TTYPE, SEND) self.protocol.requestNegotiation(TTYPE, SEND)
elif self.ttype_step == 4: elif self.ttype_step == 4:
try:
option = int(option.strip('MTTS ')) option = int(option.strip('MTTS '))
except ValueError:
# it seems some clients don't send MTTS according to protocol
# specification, but instead just sends the data as plain
# strings. We try to convert back.
option = MTTS_invert.get(option.strip('MTTS ').upper())
if not option:
# no conversion possible. Give up.
self.protocol.protocol_flags['TTYPE']['init_done'] = True
return
self.protocol.protocol_flags['TTYPE']['MTTS'] = option self.protocol.protocol_flags['TTYPE']['MTTS'] = option
for codenum, standard in MTTS: for codenum, standard in MTTS:
if option == 0: if option == 0: