diff --git a/src/commands/default/comms.py b/src/commands/default/comms.py index 1376386239..555a5f7f0d 100644 --- a/src/commands/default/comms.py +++ b/src/commands/default/comms.py @@ -12,6 +12,7 @@ from src.comms.models import Channel, Msg, PlayerChannelConnection, ExternalChan from src.comms import irc, imc2, rss from src.comms.channelhandler import CHANNELHANDLER from src.utils import create, utils, prettytable +from src.utils.utils import make_iter from src.commands.default.muxcommand import MuxCommand, MuxPlayerCommand # limit symbol import for API @@ -263,9 +264,9 @@ class CmdChannels(MuxPlayerCommand): comtable = prettytable.PrettyTable(["{wchannel","{wmy aliases", "{wdescription"]) for chan in subs: clower = chan.key.lower() - nicks = [nick for nick in caller.nicks.get(category="channel")] + nicks = caller.nicks.get(category="channel") comtable.add_row(["%s%s" % (chan.key, chan.aliases and "(%s)" % ",".join(chan.aliases) or ""), - "%s".join(nick.db_nick for nick in nicks if nick.db_real.lower()==clower()), + "%s".join(nick.db_key for nick in make_iter(nicks) if nick and nick.value.lower()==clower()), chan.desc]) caller.msg("\n{wChannel subscriptions{n (use {w@channels{n to list all, {waddcom{n/{wdelcom{n to sub/unsub):{n\n%s" % comtable) else: @@ -276,7 +277,7 @@ class CmdChannels(MuxPlayerCommand): if nicks: comtable.add_row([chan in subs and "{gYes{n" or "{rNo{n", "%s%s" % (chan.key, chan.aliases and "(%s)" % ",".join(chan.aliases) or ""), - "%s".join(nick.db_nick for nick in make_iter(nicks) if nick.db_real.lower()==clower()), + "%s".join(nick.db_key for nick in make_iter(nicks) if nick.value.lower()==clower()), chan.locks, chan.desc]) caller.msg("\n{wAvailable channels{n (use {wcomlist{n,{waddcom{n and {wdelcom{n to manage subscriptions):\n%s" % comtable) diff --git a/src/scripts/migrations/0014_create_db_liteattributes_db_tags.py b/src/scripts/migrations/0014_create_db_liteattributes_db_tags.py index 9a24cb6a0f..a7a68c5601 100644 --- a/src/scripts/migrations/0014_create_db_liteattributes_db_tags.py +++ b/src/scripts/migrations/0014_create_db_liteattributes_db_tags.py @@ -143,4 +143,4 @@ class Migration(SchemaMigration): } } - complete_apps = ['scripts'] \ No newline at end of file + complete_apps = ['scripts'] diff --git a/src/server/portal/mccp.py b/src/server/portal/mccp.py index 2e6aa77cd3..7625bbe607 100644 --- a/src/server/portal/mccp.py +++ b/src/server/portal/mccp.py @@ -47,7 +47,7 @@ class Mccp(object): def no_mccp(self, option): """ - If client doesn't support mccp, don't do anything. + Called if client doesn't support mccp or chooses to turn it off """ if hasattr(self.protocol, 'zlib'): del self.protocol.zlib diff --git a/src/server/portal/msdp.py b/src/server/portal/msdp.py index f457e13548..86e2847dfc 100644 --- a/src/server/portal/msdp.py +++ b/src/server/portal/msdp.py @@ -24,10 +24,14 @@ MSDP_TABLE_CLOSE = chr(4) MSDP_ARRAY_OPEN = chr(5) MSDP_ARRAY_CLOSE = chr(6) +IAC = chr(255) +SB = chr(250) +SE = chr(240) + # pre-compiled regexes regex_array = re.compile(r"%s(.*?)%s%s(.*?)%s" % (MSDP_VAR, MSDP_VAL, MSDP_ARRAY_OPEN, MSDP_ARRAY_CLOSE)) # return 2-tuple regex_table = re.compile(r"%s(.*?)%s%s(.*?)%s" % (MSDP_VAR, MSDP_VAL, MSDP_TABLE_OPEN, MSDP_TABLE_CLOSE)) # return 2-tuple (may be nested) -regex_varval = re.compile(r"%s(.*?)%s(.*?)" % (MSDP_VAR, MSDP_VAL)) # return 2-tuple +regex_varval = re.compile(r"%s(.*?)%s(.*)" % (MSDP_VAR, MSDP_VAL)) # return 2-tuple # MSDP default definition commands supported by Evennia (can be supplemented with custom commands as well) MSDP_COMMANDS = ("LIST", "REPORT", "RESET", "SEND", "UNREPORT") @@ -103,7 +107,7 @@ MSDP_REPORTABLE = { MSDP_SENDABLE = MSDP_REPORTABLE # try to load custom OOB module -OOB_MODULE = mod_import(settings.OOB_FUNC_MODULE) +OOB_MODULE = None#mod_import(settings.OOB_FUNC_MODULE) if OOB_MODULE: # loading customizations from OOB_FUNC_MODULE if available try: MSDP_REPORTABLE = OOB_MODULE.OOB_REPORTABLE # replaces the default MSDP definitions @@ -127,21 +131,26 @@ class Msdp(object): if the client supports MSDP. """ self.protocol = protocol - self.protocol.protocol_FLAGS['MSDP'] = False - self.protocol.negotiationMap['MSDP'] = self.parse_msdp + self.protocol.protocol_flags['MSDP'] = False + self.protocol.negotiationMap[MSDP] = self.msdp_to_func self.protocol.will(MSDP).addCallbacks(self.do_msdp, self.no_msdp) self.msdp_reported = {} def no_msdp(self, option): "No msdp supported or wanted" + print "No msdp supported" pass def do_msdp(self, option): """ Called when client confirms that it can do MSDP. """ + print "msdp supported" self.protocol.protocol_flags['MSDP'] = True + def parse_msdp(self, args): + "Called with arguments to subnegotiation" + def func_to_msdp(self, cmdname, data): """ handle return data from cmdname by converting it to @@ -168,7 +177,7 @@ class Msdp(object): string += MSDP_TABLE_CLOSE return string - def make_array(name, string, datalist): + def make_array(name, datalist, string): "build a simple array. Arrays may not nest tables by definition." string += MSDP_VAR + name + MSDP_ARRAY_OPEN for val in datalist: @@ -176,7 +185,7 @@ class Msdp(object): string += MSDP_ARRAY_CLOSE return string - if type(data) == type({}): + if isinstance(data, dict): msdp_string = make_table(cmdname, data, "") elif hasattr(data, '__iter__'): msdp_string = make_array(cmdname, data, "") @@ -206,11 +215,19 @@ class Msdp(object): arrays = {} variables = {} + if hasattr(data, "__iter__"): + data = "".join(data) + + logger.log_infomsg("MSDP SUBNEGOTIATION: %s" % data) + for table in regex_table.findall(data): - tables[table[0].upper()] = dict(regex_varval(table[1])) + tables[table[0].upper()] = dict(regex_varval.findall(table[1])) for array in regex_array.findall(data): - arrays[array[0].upper()] = dict(regex_varval(array[1])) - variables = dict((key.upper(), val) for key, val in regex_varval(regex_array.sub("", regex_table.sub("", data)))) + arrays[array[0].upper()] = dict(regex_varval.findall(array[1])) + # get all stand-alone variables, but first we must clean out all tables and arrays (which also contain vars) + variables = dict((key.upper(), val) for key, val in regex_varval.findall(regex_array.sub("", regex_table.sub("", data)))) + + print "MSDP: table, array, variables:", tables, arrays, variables ret = "" @@ -253,7 +270,20 @@ class Msdp(object): ooc_func = MSDP_COMMANDS_CUSTOM.get(arrayname.upper()) if ooc_func: ret += self.func_to_msdp(tablename, ooc_func(**table)) - return ret + + if ret: + # send return value if it exists + self.msdp_send(ret) + ret = IAC + SB + MSDP + ret + IAC + SE + #ret = IAC + SB + MSDP + MSDP_VAR + "SEND" + MSDP_VAL + "Testsend" + IAC + SE + self.protocol._write(ret) + logger.log_infomsg("MSDP_RESULT: %s" % ret) + + def msdp_send(self, msdp_string): + """ + Return a msdp-valid subnegotiation across the protocol. + """ + self.protocol._write(IAC + SB + MSDP + msdp_string + IAC + SE) # MSDP Commands # Some given MSDP (varname, value) pairs can also be treated as command + argument. @@ -289,7 +319,7 @@ class Msdp(object): reportable variable to the client. """ try: - MSDP_REPORTABLE[arg](report=True) + return MSDP_REPORTABLE[arg](report=True) except Exception: logger.log_trace() @@ -319,11 +349,12 @@ class Msdp(object): arg - this is a list of variables the client wants. """ ret = [] - for var in make_iter(arg): - try: - ret.append(MSDP_REPORTABLE[arg](send=True)) - except Exception: - logger.log_trace() + if arg: + for var in make_iter(arg): + try: + ret.append(MSDP_REPORTABLE[var.upper()])# (send=True)) + except Exception: + ret.append("ERROR")#logger.log_trace() return ret diff --git a/src/server/portal/mssp.py b/src/server/portal/mssp.py index c62975945d..3bda35d696 100644 --- a/src/server/portal/mssp.py +++ b/src/server/portal/mssp.py @@ -8,7 +8,6 @@ listings to have their crawlers find the mud and automatically extract relevant information about it, such as genre, how many active players and so on. -Most of these settings are de """ from django.conf import settings diff --git a/src/server/portal/telnet.py b/src/server/portal/telnet.py index b264e1a382..9ed178b2da 100644 --- a/src/server/portal/telnet.py +++ b/src/server/portal/telnet.py @@ -10,7 +10,7 @@ sessions etc. import re from twisted.conch.telnet import Telnet, StatefulTelnetProtocol, IAC, LINEMODE from src.server.session import Session -from src.server.portal import ttype, mssp +from src.server.portal import ttype, mssp, msdp from src.server.portal.mccp import Mccp, mccp_compress, MCCP from src.utils import utils, ansi, logger @@ -32,12 +32,13 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session): client_address = self.transport.client self.init_session("telnet", client_address, self.factory.sessionhandler) # negotiate mccp (data compression) - self.mccp = Mccp(self) + #self.mccp = Mccp(self) # negotiate ttype (client info) - self.ttype = ttype.Ttype(self) + #self.ttype = ttype.Ttype(self) # negotiate mssp (crawler communication) self.mssp = mssp.Mssp(self) - + # msdp + #self.msdp = msdp.Msdp(self) # add this new connection to sessionhandler so # the Server becomes aware of it. self.sessionhandler.connect(self) @@ -45,7 +46,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session): def enableRemote(self, option): """ - This sets up the options we allow for this protocol. + This sets up the remote-activated options we allow for this protocol. """ return (option == LINEMODE or option == ttype.TTYPE or @@ -54,11 +55,14 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session): def enableLocal(self, option): """ - Allow certain options on this protocol + Call to allow the activation of options for this protocol """ return option == MCCP def disableLocal(self, option): + """ + Disable a given option + """ if option == MCCP: self.mccp.no_mccp(option) return True diff --git a/src/settings_default.py b/src/settings_default.py index bccd743472..ec2a0ce384 100644 --- a/src/settings_default.py +++ b/src/settings_default.py @@ -314,8 +314,7 @@ PERMISSION_PLAYER_DEFAULT = "Players" # In-game Channels created from server start ###################################################################### -# Defines a dict with one key for each from-start -# channel. Each key points to a tuple containing +# Each default channel is defined by a tuple containing # (name, aliases, description, locks) # where aliases may be a tuple too, and locks is # a valid lockstring definition. diff --git a/src/typeclasses/migrations/0003_auto__add_liteattribute__add_index_liteattribute_db_key_db_category__a.py b/src/typeclasses/migrations/0003_auto__add_liteattribute__add_index_liteattribute_db_key_db_category__a.py index 01a4f29685..a624ab0a1b 100644 --- a/src/typeclasses/migrations/0003_auto__add_liteattribute__add_index_liteattribute_db_key_db_category__a.py +++ b/src/typeclasses/migrations/0003_auto__add_liteattribute__add_index_liteattribute_db_key_db_category__a.py @@ -78,4 +78,4 @@ class Migration(SchemaMigration): } } - complete_apps = ['typeclasses'] \ No newline at end of file + complete_apps = ['typeclasses'] diff --git a/src/typeclasses/migrations/0006_auto__del_liteattribute__del_index_liteattribute_db_key_db_category.py b/src/typeclasses/migrations/0006_auto__del_liteattribute__del_index_liteattribute_db_key_db_category.py index f4aa0ae2d2..2f7686f38e 100644 --- a/src/typeclasses/migrations/0006_auto__del_liteattribute__del_index_liteattribute_db_key_db_category.py +++ b/src/typeclasses/migrations/0006_auto__del_liteattribute__del_index_liteattribute_db_key_db_category.py @@ -7,6 +7,10 @@ from django.db import models class Migration(SchemaMigration): + depends_on = (("scripts", "0014_create_db_liteattributes_db_tags"), + ("objects", "0022_add_db_liteattributes_db_tags"), + ("players", "0025_auto__add_db_liteattributes_db_tags")) + def forwards(self, orm): # Deleting model 'LiteAttribute' db.delete_table(u'typeclasses_liteattribute')