diff --git a/src/commands/default/cmdset_default.py b/src/commands/default/cmdset_default.py index 881ed72c29..255a38e659 100644 --- a/src/commands/default/cmdset_default.py +++ b/src/commands/default/cmdset_default.py @@ -91,6 +91,7 @@ class DefaultCmdSet(CmdSet): self.add(comms.CmdIRC2Chan()) self.add(comms.CmdIMC2Chan()) self.add(comms.CmdIMCInfo()) + self.add(comms.CmdIMCTell()) # Batchprocessor commands self.add(batchprocess.CmdBatchCommands()) diff --git a/src/commands/default/comms.py b/src/commands/default/comms.py index 7b31285a7f..0220a0fb8e 100644 --- a/src/commands/default/comms.py +++ b/src/commands/default/comms.py @@ -856,6 +856,11 @@ class CmdIRC2Chan(MuxCommand): def func(self): "Setup the irc-channel mapping" + if not settings.IRC_ENABLED: + string = """IRC is not enabled. You need to activate it in game/settings.py.""" + self.caller.msg(string) + return + if 'list' in self.switches: # show all connections connections = ExternalChannelConnection.objects.filter(db_external_key__startswith='irc_') @@ -876,10 +881,6 @@ class CmdIRC2Chan(MuxCommand): self.caller.msg("No connections found.") return - if not settings.IRC_ENABLED: - string = """IRC is not enabled. You need to activate it in game/settings.py.""" - self.caller.msg(string) - return if not self.args or not self.rhs: string = "Usage: @irc2chan[/switches] = <#irchannel> " self.caller.msg(string) @@ -943,6 +944,11 @@ class CmdIMC2Chan(MuxCommand): def func(self): "Setup the imc-channel mapping" + if not settings.IMC2_ENABLED: + string = """IMC is not enabled. You need to activate it in game/settings.py.""" + self.caller.msg(string) + return + if 'list' in self.switches: # show all connections connections = ExternalChannelConnection.objects.filter(db_external_key__startswith='imc2_') @@ -975,7 +981,8 @@ class CmdIMC2Chan(MuxCommand): try: imc2_network, imc2_port, imc2_channel, imc2_client_pwd, imc2_server_pwd = [part.strip() for part in self.rhs.split(None, 4)] except Exception: - string = "IMC2 connnection definition '%s' is not valid." % self.rhs + string = "Usage: @imc2chan[/switches] = " + string += "\nYou must supply a value in every position to define the IMC2 connnection.\nFor deletion, the tree last arguments (imc2channel and the two passwords) may be dummy values." self.caller.msg(string) return @@ -987,7 +994,7 @@ class CmdIMC2Chan(MuxCommand): if chanmatch: channel = chanmatch.key - ok = imc2.delete_connection(channel, imc2_network, imc2_port, imc2_channel, mudname) + ok = imc2.delete_connection(channel, imc2_network, imc2_port, mudname) if not ok: self.caller.msg("IMC2 connection could not be removed, does it exist?") else: @@ -1014,8 +1021,8 @@ class CmdIMCInfo(MuxCommand): @imclist - list connected muds Switches: - channels - as imcchanlist (default) - games - as imclist + channels - as @imcchanlist (default) + games or muds - as @imclist update - force an update of all lists @@ -1030,28 +1037,33 @@ class CmdIMCInfo(MuxCommand): def func(self): "Run the command" + if not settings.IMC2_ENABLED: + string = """IMC is not enabled. You need to activate it in game/settings.py.""" + self.caller.msg(string) + return + if "update" in self.switches: # update the lists import time from src.comms.imc2lib import imc2_packets as pck - from src.comms.imc2 import IMC2_MUDLIST, IMC2_CHANLIST, IMC2_CHANNELS + from src.comms.imc2 import IMC2_MUDLIST, IMC2_CHANLIST, IMC2_CONNECTIONS # update connected muds - for chan in IMC2_CHANNELS: - chan.send_packet(pck.IMC2PacketKeepAliveRequest()) + for conn in IMC2_CONNECTIONS: + conn.send_packet(pck.IMC2PacketKeepAliveRequest()) # prune inactive muds for name, mudinfo in IMC2_MUDLIST.mud_list.items(): if time.time() - mudinfo.last_updated > 3599: del IMC2_MUDLIST.mud_list[name] # update channel list checked_networks = [] - for channel in IMC2_CHANNELS: - network = channel.factory.network + for conn in IMC2_CONNECTIONS: + network = conn.factory.network if not network in checked_networks: - channel.send_packet(pck.IMC2PacketIceRefresh()) + conn.send_packet(pck.IMC2PacketIceRefresh()) checked_networks.append(network) self.caller.msg("IMC2 lists were re-synced.") - elif "games" in self.switches or self.cmdstring == "@imclist": + elif "games" in self.switches or "muds" in self.switches or self.cmdstring == "@imclist": # list muds from src.comms.imc2 import IMC2_MUDLIST @@ -1078,12 +1090,12 @@ class CmdIMCInfo(MuxCommand): self.caller.msg(string) elif not self.switches or "channels" in self.switches or self.cmdstring == "@imcchanlist": # show channels - from src.comms.imc2 import IMC2_CHANLIST, IMC2_CHANNELS + from src.comms.imc2 import IMC2_CHANLIST, IMC2_CONNECTIONS channels = IMC2_CHANLIST.get_channel_list() string = "" nchans = 0 - string += "\n {GChannels on %s:{n" % (", ".join(conn.factory.network for conn in IMC2_CHANNELS)) + string += "\n {GChannels on %s:{n" % (", ".join(conn.factory.network for conn in IMC2_CONNECTIONS)) cols = [["Full name"], ["Name"], ["Owner"], ["Perm"], ["Policy"]] for channel in channels: nchans += 1 @@ -1104,4 +1116,46 @@ class CmdIMCInfo(MuxCommand): else: # no valid inputs string = "Usage: imcinfo|imcchanlist|imclist" - self.caller(string) + self.caller.msg(string) + +# unclear if this is working ... +class CmdIMCTell(MuxCommand): + """ + imctell - send a page to a remote IMC player + + Usage: + imctell User@MUD = + imcpage " + + Sends a page to a user on a remote MUD, connected + over IMC2. + """ + + key = "imctell" + aliases = ["imcpage", "imc2tell", "imc2page"] + locks = "cmd: serversetting(IMC2_ENABLED) or perm(Immortals)" + help_category = "Comms" + + def func(self): + "Send tell across IMC" + + if not settings.IMC2_ENABLED: + string = """IMC is not enabled. You need to activate it in game/settings.py.""" + self.caller.msg(string) + return + + from src.comms.imc2 import IMC2_CONNECTIONS + + if not self.args or not '@' in self.lhs or not self.rhs: + string = "Usage: imctell User@Mud = " + self.caller.msg(string) + return + target, destination = self.lhs.split("@", 1) + message = self.rhs.strip() + data = {"target":target, "destination":destination} + + for comm in IMC2_CONNECTIONS: + # we don't know which connection we aim for, so we send to all. + comm.msg_imc2(message, from_obj=self.caller.player, packet_type="imctell", data=data) + + self.caller.msg("You paged {c%s@%s{n (over IMC): '%s'." % (target, destination, message)) diff --git a/src/commands/default/unimplemented/imc2.py b/src/commands/default/unimplemented/imc2.py index 1b9807e937..6c1188ae48 100644 --- a/src/commands/default/unimplemented/imc2.py +++ b/src/commands/default/unimplemented/imc2.py @@ -31,83 +31,83 @@ def cmd_imcwhois(command): imc2_conn.IMC2_PROTOCOL_INSTANCE.send_packet(packet) GLOBAL_CMD_TABLE.add_command("imcwhois", cmd_imcwhois, help_category="Comms") -def cmd_imcansi(command): - """ - imcansi +# def cmd_imcansi(command): +# """ +# imcansi - Usage: - imcansi +# Usage: +# imcansi - Test IMC ANSI conversion. - """ - source_object = command.source_object - if not command.command_argument: - source_object.emit_to("You must provide a string to convert.") - return - else: - retval = parse_ansi(command.command_argument, parser=IMCANSIParser()) - source_object.emit_to(retval) -GLOBAL_CMD_TABLE.add_command("imcansi", cmd_imcansi, help_category="Comms") +# Test IMC ANSI conversion. +# """ +# source_object = command.source_object +# if not command.command_argument: +# source_object.emit_to("You must provide a string to convert.") +# return +# else: +# retval = parse_ansi(command.command_argument, parser=IMCANSIParser()) +# source_object.emit_to(retval) +# GLOBAL_CMD_TABLE.add_command("imcansi", cmd_imcansi, help_category="Comms") -def cmd_imcicerefresh(command): - """ - imcicerefresh +# def cmd_imcicerefresh(command): +# """ +# imcicerefresh - Usage: - imcicerefresh +# Usage: +# imcicerefresh - IMC2: Semds an ice-refresh packet. - """ - source_object = command.source_object - packet = IMC2PacketIceRefresh() - imc2_conn.IMC2_PROTOCOL_INSTANCE.send_packet(packet) - source_object.emit_to("Sent") -GLOBAL_CMD_TABLE.add_command("imcicerefresh", cmd_imcicerefresh, help_category="Comms") +# IMC2: Semds an ice-refresh packet. +# """ +# source_object = command.source_object +# packet = IMC2PacketIceRefresh() +# imc2_conn.IMC2_PROTOCOL_INSTANCE.send_packet(packet) +# source_object.emit_to("Sent") +# GLOBAL_CMD_TABLE.add_command("imcicerefresh", cmd_imcicerefresh, help_category="Comms") -def cmd_imcchanlist(command): - """ - imcchanlist +# def cmd_imcchanlist(command): +# """ +# imcchanlist - Usage: - imcchanlist +# Usage: +# imcchanlist - Shows the list of cached channels from the IMC2 Channel list. - """ - source_object = command.source_object +# Shows the list of cached channels from the IMC2 Channel list. +# """ +# source_object = command.source_object - retval = 'Channels on %s\n\r' % imc2_conn.IMC2_PROTOCOL_INSTANCE.network_name +# retval = 'Channels on %s\n\r' % imc2_conn.IMC2_PROTOCOL_INSTANCE.network_name - retval += ' Full Name Name Owner Perm Policy\n\r' - retval += ' --------- ---- ----- ---- ------\n\r' - for channel in IMC2_CHANLIST.get_channel_list(): - retval += ' %-18s %-10s %-15s %-7s %s\n\r' % (channel.name, - channel.localname, - channel.owner, - channel.level, - channel.policy) - retval += '%s channels found.' % len(IMC2_CHANLIST.chan_list) - source_object.emit_to(retval) -GLOBAL_CMD_TABLE.add_command("imcchanlist", cmd_imcchanlist, help_category="Comms") +# retval += ' Full Name Name Owner Perm Policy\n\r' +# retval += ' --------- ---- ----- ---- ------\n\r' +# for channel in IMC2_CHANLIST.get_channel_list(): +# retval += ' %-18s %-10s %-15s %-7s %s\n\r' % (channel.name, +# channel.localname, +# channel.owner, +# channel.level, +# channel.policy) +# retval += '%s channels found.' % len(IMC2_CHANLIST.chan_list) +# source_object.emit_to(retval) +# GLOBAL_CMD_TABLE.add_command("imcchanlist", cmd_imcchanlist, help_category="Comms") -def cmd_imclist(command): - """ - imclist +# def cmd_imclist(command): +# """ +# imclist - Usage: - imclist +# Usage: +# imclist - Shows the list of cached games from the IMC2 Mud list. - """ - source_object = command.source_object +# Shows the list of cached games from the IMC2 Mud list. +# """ +# source_object = command.source_object - retval = 'Active MUDs on %s\n\r' % imc2_conn.IMC2_PROTOCOL_INSTANCE.network_name +# retval = 'Active MUDs on %s\n\r' % imc2_conn.IMC2_PROTOCOL_INSTANCE.network_name - for mudinfo in IMC2_MUDLIST.get_mud_list(): - mudline = ' %-20s %s' % (mudinfo.name, mudinfo.versionid) - retval += '%s\n\r' % mudline[:78] - retval += '%s active MUDs found.' % len(IMC2_MUDLIST.mud_list) - source_object.emit_to(retval) -GLOBAL_CMD_TABLE.add_command("imclist", cmd_imclist, help_category="Comms") +# for mudinfo in IMC2_MUDLIST.get_mud_list(): +# mudline = ' %-20s %s' % (mudinfo.name, mudinfo.versionid) +# retval += '%s\n\r' % mudline[:78] +# retval += '%s active MUDs found.' % len(IMC2_MUDLIST.mud_list) +# source_object.emit_to(retval) +# GLOBAL_CMD_TABLE.add_command("imclist", cmd_imclist, help_category="Comms") # def cmd_imcstatus(command): # """ diff --git a/src/comms/imc2.py b/src/comms/imc2.py index af6f6012e0..fdd1fa5791 100644 --- a/src/comms/imc2.py +++ b/src/comms/imc2.py @@ -19,10 +19,10 @@ from src.comms.imc2lib.imc2_listeners import handle_whois_reply # channel to send info to INFOCHANNEL = Channel.objects.channel_search(settings.CHANNEL_MUDINFO[0]) -# all linked channel connection -IMC2_CHANNELS = [] +# all linked channel connections +IMC2_CONNECTIONS = [] # IMC2 debug mode -IMC2_DEBUG = True +IMC2_DEBUG = False # Use this instance to keep track of the other games on the network. IMC2_MUDLIST = IMC2MudList() # Tracks the list of available channels on the network. @@ -58,7 +58,7 @@ class Send_IsAlive(Script): self.desc = "Send an IMC2 is-alive packet" self.persistent = True def at_repeat(self): - for channel in IMC2_CHANNELS: + for channel in IMC2_CONNECTIONS: channel.send_packet(pck.IMC2PacketIsAlive()) def is_valid(self): "Is only valid as long as there are channels to update" @@ -75,7 +75,7 @@ class Send_Keepalive_Request(Script): self.desc = "Send an IMC2 keepalive-request packet" self.persistent = True def at_repeat(self): - for channel in IMC2_CHANNELS: + for channel in IMC2_CONNECTIONS: channel.send_packet(pck.IMC2PacketKeepAliveRequest()) def is_valid(self): "Is only valid as long as there are channels to update" @@ -115,7 +115,7 @@ class Sync_Server_Channel_List(Script): self.persistent = True def at_repeat(self): checked_networks = [] - for channel in self.IMC2_CHANNELS: + for channel in self.IMC2_CONNECTIONS: network = channel.factory.network if not network in checked_networks: channel.send_packet(pkg.IMC2PacketIceRefresh()) @@ -132,8 +132,8 @@ class IMC2Protocol(telnet.StatefulTelnetProtocol): authentication, and all necessary packets. """ def __init__(self): - global IMC2_CHANNELS - IMC2_CHANNELS.append(self) + global IMC2_CONNECTIONS + IMC2_CONNECTIONS.append(self) self.is_authenticated = False self.auth_type = None self.server_name = None @@ -159,11 +159,12 @@ class IMC2Protocol(telnet.StatefulTelnetProtocol): """ if self.sequence: # This gets incremented with every command. - self.sequence += 1 + self.sequence += 1 packet.imc2_protocol = self packet_str = utils.to_str(packet.assemble(self.factory.mudname, self.factory.client_pwd, self.factory.server_pwd)) - if IMC2_DEBUG: + if IMC2_DEBUG and not (hasattr(packet, 'packet_type') and packet.packet_type == "is-alive"): logger.log_infomsg("IMC2: SENT> %s" % packet_str) + logger.log_infomsg(str(packet)) self.sendLine(packet_str) def _parse_auth_response(self, line): @@ -216,30 +217,33 @@ class IMC2Protocol(telnet.StatefulTelnetProtocol): (Message from IMC2 -> Evennia) """ conn_name = packet.optional_data.get('channel', None) + # If the packet lacks the 'echo' key, don't bother with it. - has_echo = packet.optional_data.get('echo', None) - if conn_name and has_echo: - # The second half of this is the channel name: Server:Channel - chan_name = conn_name.split(':', 1)[1] - key = "imc2_%s" % conn_name - # Look for matching IMC2 channel maps. - conns = ExternalChannelConnection.objects.filter(db_external_key=self.factory.key) - if not conns: - return + if not conn_name or not packet.optional_data.get('echo', None): + return + + chan_name = conn_name.split(':', 1)[1] + if not chan_name in self.factory.channel: + # we are not listening to this channel. + return + + key = "imc2_%s" % conn_name + # Look for matching IMC2 channel maps. + conns = ExternalChannelConnection.objects.filter(db_external_key=self.factory.key) + if not conns: + return - # Format the message to send to local channel. - message = '[%s] %s@%s: %s' % (self.factory.evennia_channel, packet.sender, packet.origin, packet.optional_data.get('text')) - - for conn in conns: - if conn.channel: - conn.to_channel(message) + # Format the message to send to local channel. + message = '[%s] %s@%s: %s' % (self.factory.evennia_channel, packet.sender, packet.origin, packet.optional_data.get('text')) + for conn in (conn for conn in conns if conn.channel): + conn.to_channel(message) def _format_tell(self, packet): """ Handle tells over IMC2 by formatting the text properly """ - return "%s@%s IMC tells: %s" % (packet.sender, packet.origin, - packet.optional_data.get('text', 'ERROR: No text provided.')) + return "{c%s@%s{n {wpages (over IMC):{n %s" % (packet.sender, packet.origin, + packet.optional_data.get('text', 'ERROR: No text provided.')) def lineReceived(self, line): """ @@ -247,24 +251,25 @@ class IMC2Protocol(telnet.StatefulTelnetProtocol): what to do with the packet. IMC2 -> Evennia """ + line = line.strip() + if not self.is_authenticated: self._parse_auth_response(line) else: if IMC2_DEBUG and not 'is-alive' in line: # if IMC2_DEBUG mode is on, print the contents of the packet - # to stdout. - logger.log_infomsg("PACKET: %s" % line) + # to stdout. + logger.log_infomsg("IMC2: RECV> %s" % line) # Parse the packet and encapsulate it for easy access packet = pck.IMC2Packet(self.factory.mudname, packet_str=line) - if IMC2_DEBUG and packet.packet_type not in ['is-alive', 'keepalive-request']: + if IMC2_DEBUG and packet.packet_type not in ('is-alive', 'keepalive-request'): # Print the parsed packet's __str__ representation. # is-alive and keepalive-requests happen pretty frequently. # Don't bore us with them in stdout. logger.log_infomsg(str(packet)) - - + # Figure out what kind of packet we're dealing with and hand it # off to the correct handler. @@ -288,9 +293,9 @@ class IMC2Protocol(telnet.StatefulTelnetProtocol): player = search.players(packet.target) if not player: return - player.msg(self._format_tell(packet)) + player[0].msg(self._format_tell(packet)) - def msg_imc2(self, message, from_obj=None): + def msg_imc2(self, message, from_obj=None, packet_type="imcbroadcast", data=None): """ Called by Evennia to send a message through the imc2 connection """ @@ -304,9 +309,18 @@ class IMC2Protocol(telnet.StatefulTelnetProtocol): from_name = from_obj else: from_name = self.factory.mudname - # send the packet - self.send_packet(pck.IMC2PacketIceMsgBroadcasted(self.factory.network, self.factory.channel, - from_name, message)) + + if packet_type == "imcbroadcast": + # send the packet + self.send_packet(pck.IMC2PacketIceMsgBroadcasted(self.factory.servername, self.factory.channel[0], + from_name, message)) + elif packet_type == "imctell": + # send a tell + if type(data) == dict: + target = data.get("target", "Unknown") + destination = data.get("destination", "Unknown") + self.send_packet(pck.IMC2PacketTell(from_name, target, destination, message)) + class IMC2Factory(protocol.ClientFactory): """ @@ -318,9 +332,11 @@ class IMC2Factory(protocol.ClientFactory): def __init__(self, key, channel, network, port, mudname, client_pwd, server_pwd, evennia_channel): self.key = key self.mudname = mudname - self.channel = channel + self.channel = channel self.pretty_key = "%s:%s/%s (%s)" % (network, port, channel, mudname) self.network = network + sname, host = network.split(".", 1) + self.servername = sname.strip() self.protocol_version = '2' self.client_pwd = client_pwd self.server_pwd = server_pwd @@ -338,16 +354,15 @@ class IMC2Factory(protocol.ClientFactory): logger.log_errmsg('IMC2: %s' % message) -def build_connection_key(channel, imc2_network, imc2_port, imc2_channel, imc2_mudname): +def build_connection_key(channel, imc2_network, imc2_port, imc2_mudname): "Build an id hash for the connection" if hasattr(channel, 'key'): channel = channel.key - return "imc2_%s:%s/%s(%s)<>%s" % (imc2_network, imc2_port, imc2_channel, imc2_mudname, channel) + return "imc2_%s:%s(%s)<>%s" % (imc2_network, imc2_port, imc2_mudname, channel) def build_service_key(key): return "IMC2:%s" % key - def start_scripts(validate=False): """ Start all the needed scripts @@ -368,7 +383,7 @@ def start_scripts(validate=False): def create_connection(channel, imc2_network, imc2_port, imc2_channel, imc2_mudname, imc2_client_pwd, imc2_server_pwd): """ - This will create a new IMC2<->channel connection. + This will create a new IMC2<->channel connection. """ if not type(channel) == Channel: new_channel = Channel.objects.filter(db_key=channel) @@ -376,15 +391,30 @@ def create_connection(channel, imc2_network, imc2_port, imc2_channel, imc2_mudna logger.log_errmsg("Cannot attach IMC2<->Evennia: Evennia Channel '%s' not found" % channel) return False channel = new_channel[0] - key = build_connection_key(channel, imc2_network, imc2_port, imc2_channel, imc2_mudname) + key = build_connection_key(channel, imc2_network, imc2_port, imc2_mudname) old_conns = ExternalChannelConnection.objects.filter(db_external_key=key) if old_conns: - return False + return + # connection already exists. We try to only connect a new channel + old_config = old_conns[0].db_external_config.split('|',5) + old_chan_subs = old_config[2].split(',') + if imc2_channel in old_chan_subs: + return False # we already listen to this channel + else: + # We add thew new channel to the connection instead of creating a new connection. + old_chan_subs.append(imc2_channel) + old_chan_subs = ",".join(old_chan_subs) + old_config[2] = old_chan_subs # add a channel subscription to old config + old_conns[0].db_external_config = "|".join(old_config) + old_conns[0].save() + return True + + # new connection config = "%s|%s|%s|%s|%s|%s" % (imc2_network, imc2_port, imc2_channel, imc2_mudname, imc2_client_pwd, imc2_server_pwd) # how the channel will be able to contact this protocol - send_code = "from src.comms.imc2 import IMC2_CHANNELS\n" - send_code += "matched_imc2s = [imc2 for imc2 in IMC2_CHANNELS if imc2.factory.key == '%s']\n" % key + send_code = "from src.comms.imc2 import IMC2_CONNECTIONS\n" + send_code += "matched_imc2s = [imc2 for imc2 in IMC2_CONNECTIONS if imc2.factory.key == '%s']\n" % key send_code += "[imc2.msg_imc2(message, from_obj=from_obj) for imc2 in matched_imc2s]\n" conn = ExternalChannelConnection(db_channel=channel, db_external_key=key, db_external_send_code=send_code, db_external_config=config) @@ -396,12 +426,12 @@ def create_connection(channel, imc2_network, imc2_port, imc2_channel, imc2_mudna start_scripts() return True -def delete_connection(channel, imc2_network, imc2_port, imc2_channel, mudname): +def delete_connection(channel, imc2_network, imc2_port, mudname): "Destroy a connection" if hasattr(channel, 'key'): channel = channel.key - key = build_connection_key(channel, imc2_network, imc2_port, imc2_channel, mudname) + key = build_connection_key(channel, imc2_network, imc2_port, mudname) service_key = build_service_key(key) try: conn = ExternalChannelConnection.objects.get(db_external_key=key) @@ -427,6 +457,7 @@ def connect_to_imc2(connection): service_key = build_service_key(key) imc2_network, imc2_port, imc2_channel, imc2_mudname, imc2_client_pwd, imc2_server_pwd = \ [utils.to_str(conf) for conf in connection.external_config.split('|')] + imc2_channel = imc2_channel.split(",") # connect imc = internet.TCPClient(imc2_network, int(imc2_port), IMC2Factory(key, imc2_channel, imc2_network, imc2_port, imc2_mudname, imc2_client_pwd, imc2_server_pwd, connection.channel.key)) diff --git a/src/comms/imc2lib/imc2_packets.py b/src/comms/imc2lib/imc2_packets.py index f104160777..ef33f2992e 100644 --- a/src/comms/imc2lib/imc2_packets.py +++ b/src/comms/imc2lib/imc2_packets.py @@ -93,24 +93,22 @@ class IMC2Packet(object): def __str__(self): retval = """ - -- Begin Packet Display -- - Sender: %s - Origin: %s + --IMC2 package (%s) + Sender: %s + Origin: %s Sequence: %s - Route: %s - Type: %s - Target: %s - Destination: %s - Data: %s - - End Packet Display --""" % (self.sender, - self.origin, - self.sequence, - self.route, - self.packet_type, - self.target, - self.destination, - self.optional_data) - return retval + Route: %s + Type: %s + Target: %s + Dest.: %s + Data: + %s + ------------------------""" % (self.packet_type, self.sender, + self.origin, self.sequence, + self.route, self.packet_type, + self.target, self.destination, + "\n ".join(["%s: %s" % items for items in self.optional_data.items()])) + return retval.strip() def _get_optional_data_string(self): """ @@ -426,7 +424,7 @@ class IMC2PacketIceMsgBroadcasted(IMC2Packet): def __init__(self, server, channel, pobject, message): """ Args: - server: (String) Server name the channel resides on. + server: (String) Server name the channel resides on (obs - this is e.g. Server01, not the full network name!) channel: (String) Name of the IMC2 channel. pobject: (Object) Object sending the message. message: (String) Message to send. @@ -507,8 +505,22 @@ class IMC2PacketTell(IMC2Packet): Reply from Dude: Dude@SomeMUD 1234567890 SomeMUD!Hub1 tell You@YourMUD text="Yeah, this is cool!" isreply=1 """ - pass - + def __init__(self, pobject, target, destination, message): + super(IMC2PacketTell, self).__init__() + self.sender = pobject + self.packet_type = "tell" + self.target = target + self.destination = destination + self.optional_data = {"text": message, + "isreply":None} + + def assemble(self, mudname=None, client_pwd=None, server_pwd=None): + self.sequence = self.imc2_protocol.sequence + #self.route = "%s!%s" % (self.origin, self.imc2_protocol.factory.servername.capitalize()) + return '''"%s@%s %s %s tell %s@%s text="%s"''' % (self.sender, self.origin, self.sequence, + self.route, self.target, self.destination, + self.optional_data.get("text","NO TEXT GIVEN")) + class IMC2PacketEmote(IMC2Packet): """ Description: diff --git a/src/settings_default.py b/src/settings_default.py index fc2b559206..d8413a2e75 100644 --- a/src/settings_default.py +++ b/src/settings_default.py @@ -286,7 +286,7 @@ IRC_ENABLED = False # 'server password' as chosen when registering on mudbytes. The # Evennia discussion channel 'ievennia' is on # server02.mudbytes.net:9000. -IMC2_ENABLED = False # OBS! DON'T CHANGE - IMC2 is not implemented yet! +IMC2_ENABLED = False ###################################################