""" mssp.py Adds MSSP support to NakedMud. Add new variables with register_mssp_var. """ import hooks, mudsock, telnetlib, types, time ################################################################################ # variables ################################################################################ # the character for MSSP MSSP = 'F' # "%c" % 70 # markers for sending MSSP info MSSP_VAR = '\x01' # "%c" % 1 MSSP_VAL = '\x02' # "%c" % 2 # handshake crap server_will_mssp = telnetlib.IAC + telnetlib.WILL + MSSP client_do_mssp = telnetlib.IAC + telnetlib.DO + MSSP # subnegotion crap subneg_start_mssp = telnetlib.IAC + telnetlib.SB + MSSP subneg_end_mssp = telnetlib.IAC + telnetlib.SE # a table of MSSP variables and functions to build their values mssp_variables = { } ################################################################################ # functions ################################################################################ def register_mssp_var(var, val): """register a new variable to build info for when we are sending MSSP info. val should either a function that builds the arguments, or something that can be cast as a string. If val is a string, it should return either something that can be cast as a string or, if multiple values are acceptable (e.g., in the case of ports) a list of things that can be cast as a string. """ mssp_variables[var] = val ################################################################################ # local functions ################################################################################ def build_one_mssp_info(var, val): """returns MSSP info for one var:val pair. """ # first, if it's a function, figure out what it returns if type(val) == types.FunctionType: val = val() # next, if the return was a list, turn everything to strings for join() if type(val) == list: val = MSSP_VAL.join([str(x) for x in val]) # return our info return MSSP_VAR + var + MSSP_VAL + str(val) def build_mssp_info(): """returns a string for our current MSSP info. """ buf=[build_one_mssp_info(var,val) for var,val in mssp_variables.iteritems()] return subneg_start_mssp + "".join(buf) + subneg_end_mssp ################################################################################ # hooks ################################################################################ def will_mssp_hook(info): """connection has been received. See if they are an MSSP crawler. """ sock, = hooks.parse_info(info) sock.send_raw(server_will_mssp) def do_mssp_hook(info): """check to see if the iac command was a signal that the client handles MSSP """ sock, cmd = hooks.parse_info(info) if cmd == client_do_mssp: sock.send_raw(build_mssp_info()) ################################################################################ # initialization ################################################################################ hooks.add("receive_iac", do_mssp_hook) hooks.add("receive_connection", will_mssp_hook) # register all of our default MSSP variables register_mssp_var("PLAYERS", lambda : len(mudsock.socket_list())) register_mssp_var("UPTIME", int(time.time())) register_mssp_var("FAMILY", "Custom") register_mssp_var("ANSI", 1)