94 lines
2.3 KiB
Python
94 lines
2.3 KiB
Python
"""
|
|
MXP - Mud eXtension Protocol.
|
|
|
|
Partial implementation of the MXP protocol.
|
|
The MXP protocol allows more advanced formatting options for telnet clients
|
|
that supports it (mudlet, zmud, mushclient are a few)
|
|
|
|
This only implements the SEND tag.
|
|
|
|
More information can be found on the following links:
|
|
http://www.zuggsoft.com/zmud/mxp.htm
|
|
http://www.mushclient.com/mushclient/mxp.htm
|
|
http://www.gammon.com.au/mushclient/addingservermxp.htm
|
|
|
|
"""
|
|
|
|
import re
|
|
import weakref
|
|
|
|
from django.conf import settings
|
|
|
|
LINKS_SUB = re.compile(r"\|lc(.*?)\|lt(.*?)\|le", re.DOTALL)
|
|
URL_SUB = re.compile(r"\|lu(.*?)\|lt(.*?)\|le", re.DOTALL)
|
|
|
|
# MXP Telnet option
|
|
MXP = bytes([91]) # b"\x5b"
|
|
|
|
MXP_TEMPSECURE = "\x1b[4z"
|
|
MXP_SEND = MXP_TEMPSECURE + '<SEND HREF="\\1">' + "\\2" + MXP_TEMPSECURE + "</SEND>"
|
|
MXP_URL = MXP_TEMPSECURE + '<A HREF="\\1">' + "\\2" + MXP_TEMPSECURE + "</A>"
|
|
|
|
|
|
def mxp_parse(text):
|
|
"""
|
|
Replaces links to the correct format for MXP.
|
|
|
|
Args:
|
|
text (str): The text to parse.
|
|
|
|
Returns:
|
|
parsed (str): The parsed text.
|
|
|
|
"""
|
|
text = text.replace("&", "&").replace("<", "<").replace(">", ">")
|
|
|
|
text = LINKS_SUB.sub(MXP_SEND, text)
|
|
text = URL_SUB.sub(MXP_URL, text)
|
|
return text
|
|
|
|
|
|
class Mxp:
|
|
"""
|
|
Implements the MXP protocol.
|
|
|
|
"""
|
|
|
|
def __init__(self, protocol):
|
|
"""
|
|
Initializes the protocol by checking if the client supports it.
|
|
|
|
Args:
|
|
protocol (Protocol): The active protocol instance.
|
|
|
|
"""
|
|
self.protocol = weakref.ref(protocol)
|
|
self.protocol().protocol_flags["MXP"] = False
|
|
if settings.MXP_ENABLED:
|
|
self.protocol().will(MXP).addCallbacks(self.do_mxp, self.no_mxp)
|
|
|
|
def no_mxp(self, option):
|
|
"""
|
|
Called when the Client reports to not support MXP.
|
|
|
|
Args:
|
|
option (Option): Not used.
|
|
|
|
"""
|
|
self.protocol().protocol_flags["MXP"] = False
|
|
self.protocol().handshake_done()
|
|
|
|
def do_mxp(self, option):
|
|
"""
|
|
Called when the Client reports to support MXP.
|
|
|
|
Args:
|
|
option (Option): Not used.
|
|
|
|
"""
|
|
if settings.MXP_ENABLED:
|
|
self.protocol().protocol_flags["MXP"] = True
|
|
self.protocol().requestNegotiation(MXP, b"")
|
|
else:
|
|
self.protocol().wont(MXP)
|
|
self.protocol().handshake_done()
|