diff --git a/src/commands/comsys.py b/src/commands/comsys.py index 28101d96f..c8c8b6121 100644 --- a/src/commands/comsys.py +++ b/src/commands/comsys.py @@ -8,6 +8,8 @@ from src import defines_global from src import ansi from src.util import functions_general from src.cmdtable import GLOBAL_CMD_TABLE +from src.imc2.models import IMC2ChannelMapping +from src.imc2.packets import IMC2PacketIceMsgBroadcasted def cmd_addcom(command): """ @@ -253,6 +255,20 @@ def cmd_cemit(command): if not "quiet" in command.command_switches: source_object.emit_to("Sent - %s" % (name_matches[0],)) src.comsys.send_cmessage(cname_parsed, final_cmessage) + + # Look for IMC2 channel maps. If one is found, send an ice-msg-b + # packet to the network. + try: + from src.imc2.connection import IMC2_PROTOCOL_INSTANCE + map = IMC2ChannelMapping.objects.get(channel__name=cname_parsed) + packet = IMC2PacketIceMsgBroadcasted(map.imc2_server_name, + map.imc2_channel_name, + source_object, + cmessage) + IMC2_PROTOCOL_INSTANCE.send_packet(packet) + except IMC2ChannelMapping.DoesNotExist: + # No map found, do nothing. + pass GLOBAL_CMD_TABLE.add_command("@cemit", cmd_cemit), def cmd_cwho(command): diff --git a/src/comsys.py b/src/comsys.py index 0fe2e7ebf..a47d43c52 100644 --- a/src/comsys.py +++ b/src/comsys.py @@ -216,7 +216,6 @@ def send_cmessage(channel_name, message): """ for user in get_cwho_list(channel_name, return_muted=False): user.msg(message) - try: chan_message = CommChannelMessage() chan_message.channel = get_cobj_from_name(channel_name) @@ -225,7 +224,6 @@ def send_cmessage(channel_name, message): except: print "send_cmessage(): Can't find channel: %s" % (channel_name,) - def get_all_channels(): """ Returns all channel objects. diff --git a/src/imc2/connection.py b/src/imc2/connection.py index eaf72716a..ead2367bf 100644 --- a/src/imc2/connection.py +++ b/src/imc2/connection.py @@ -54,7 +54,7 @@ class IMC2Protocol(StatefulTelnetProtocol): self.sequence += 1 packet.imc2_protocol = self - packet_str = packet.assemble() + packet_str = str(packet.assemble()) logger.log_infomsg("IMC2: SENT> %s" % packet_str) self.sendLine(packet_str) @@ -76,6 +76,32 @@ class IMC2Protocol(StatefulTelnetProtocol): # Let everyone know we've arrived. #self.send_packet(IMC2PacketKeepAliveRequest()) self.send_packet(IMC2PacketIsAlive()) + + def _handle_channel_mappings(self, packet): + """ + Received a message. Look for an IMC2 channel mapping and + route it accordingly. + """ + chan_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 chan_name and has_echo: + # The second half of this is the channel name: Server:Channel + chan_name = chan_name.split(':', 1)[1] + try: + # Look for matching IMC2 channel maps. + mapping = IMC2ChannelMapping.objects.get(imc2_channel_name=chan_name) + ingame_chan_name = mapping.channel.name + # Format the message to cemit to the local channel. + message = '[%s] %s@%s: %s' % (ingame_chan_name, + packet.sender, + packet.origin, + packet.optional_data.get('text')) + # Bombs away. + comsys.send_cmessage(ingame_chan_name, message) + except IMC2ChannelMapping.DoesNotExist: + # No channel mapping found for this message, ignore it. + pass def lineReceived(self, line): """ @@ -85,27 +111,15 @@ class IMC2Protocol(StatefulTelnetProtocol): if not self.is_authenticated: self._parse_auth_response(line) else: - logger.log_infomsg("PACKET: %s" % line) + if 'is-alive' not in line: + logger.log_infomsg("PACKET: %s" % line) packet = IMC2Packet(packet_str = line) - logger.log_infomsg(packet) + if packet.packet_type not in ['is-alive', 'keepalive-request']: + logger.log_infomsg(packet) if packet.packet_type == 'is-alive': IMC2_MUDLIST.update_mud_from_packet(packet) elif packet.packet_type == 'ice-msg-b': - # Received a message. Look for an IMC2 channel mapping and - # route it accordingly. - chan_name = packet.optional_data.get('channel', None) - if chan_name: - chan_name = chan_name.split(':', 1)[1] - try: - mapping = IMC2ChannelMapping.objects.get(imc2_channel_name=chan_name) - ingame_chan_name = mapping.channel.name - message = '[%s] %s@%s: %s' % (ingame_chan_name, - packet.sender, - packet.origin, - packet.optional_data.get('text')) - comsys.send_cmessage(ingame_chan_name, message) - except IMC2ChannelMapping.DoesNotExist: - pass + self._handle_channel_mappings(packet) elif packet.packet_type == 'whois-reply': reply_listener.handle_whois_reply(packet) elif packet.packet_type == 'close-notify': diff --git a/src/imc2/models.py b/src/imc2/models.py index 770ded056..40b84c669 100644 --- a/src/imc2/models.py +++ b/src/imc2/models.py @@ -7,6 +7,7 @@ class IMC2ChannelMapping(models.Model): IMC2 messages are routed to. """ channel = models.ForeignKey(CommChannel) + imc2_server_name = models.CharField(max_length=78) imc2_channel_name = models.CharField(max_length=78) is_enabled = models.BooleanField(default=True) diff --git a/src/imc2/packets.py b/src/imc2/packets.py index fade92047..c0efebba8 100644 --- a/src/imc2/packets.py +++ b/src/imc2/packets.py @@ -119,8 +119,13 @@ class IMC2Packet(object): """ if self.optional_data: data_string = '' - for value in self.optional_data: - data_string += '%s=%s ' % (value[0], value[1]) + for key, value in self.optional_data.items(): + # Determine the number of words in this value. + words = len(str(value).split(' ')) + # Anything over 1 word needs double quotes. + if words > 1: + value = '"%s"' % (value,) + data_string += '%s=%s ' % (key, value) return data_string.strip() else: return '' @@ -251,10 +256,10 @@ class IMC2PacketIsAlive(IMC2Packet): self.packet_type = 'is-alive' self.target = '*' self.destination = '*' - self.optional_data = [('versionid', '"Evennia IMC2"'), - ('url', '"http://evennia.com"'), - ('host', 'test.com'), - ('port', '5555')] + self.optional_data = {'versionid': '"Evennia IMC2"', + 'url': '"http://evennia.com"', + 'host': 'test.com', + 'port': '5555'} class IMC2PacketIceRefresh(IMC2Packet): """ @@ -413,7 +418,23 @@ class IMC2PacketIceMsgBroadcasted(IMC2Packet): Broadcasted Packet: You@YourMUD 1234567890 YourMUD!Hub1 ice-msg-b *@* channel=Hub1:ichat text=Hi! emote=0 echo=1 """ - pass + def __init__(self, server, channel, pobject, message): + """ + Args: + server: (String) Server name the channel resides on. + channel: (String) Name of the IMC2 channel. + pobject: (Object) Object sending the message. + message: (String) Message to send. + """ + super(IMC2PacketIceMsgBroadcasted, self).__init__() + self.sender = pobject + self.packet_type = 'ice-msg-b' + self.target = '*' + self.destination = '*' + self.optional_data = {'channel': '%s:%s' % (server, channel), + 'text': message, + 'emote': 0, + 'echo': 1} class IMC2PacketUserCache(IMC2Packet): """ @@ -622,7 +643,7 @@ class IMC2PacketWhois(IMC2Packet): self.packet_type = 'whois' self.target = whois_target self.destination = '*' - self.optional_data = [('level', '5')] + self.optional_data = {'level': '5'} class IMC2PacketWhoisReply(IMC2Packet): """