From 703d27782542f8ce1355072321f8d7844687c2d0 Mon Sep 17 00:00:00 2001 From: Jack Allnutt Date: Thu, 27 Sep 2012 03:58:25 +0100 Subject: [PATCH] Proper handling of the MODE command. Resolves issues #80, #60 and #61. Also resolves Issue #50, but that bug was filed against the old codebase. --- client_backbone/dev/model_application.js | 53 ++++++++++++------ server/irc-commands.js | 69 +++++++++++++++++------- 2 files changed, 86 insertions(+), 36 deletions(-) diff --git a/client_backbone/dev/model_application.js b/client_backbone/dev/model_application.js index 9952ac2..6d1d4d7 100755 --- a/client_backbone/dev/model_application.js +++ b/client_backbone/dev/model_application.js @@ -378,22 +378,43 @@ kiwi.model.Application = function () { gw.on('onmode', function (event) { - var channel, members, member; - - if (!event.channel) return; - channel = that.panels.getByName(event.channel); - if (!channel) return; - - members = channel.get('members'); - if (!members) return; - - member = members.getByNick(event.effected_nick); - if (!member) return; - - if (event.mode[0] === '+') { - member.addMode(event.mode.substr(1)); - } else if (event.mode[0] === '-') { - member.removeMode(event.mode.substr(1)); + var channel, i, prefixes, members, member, find_prefix; + + channel = that.panels.getByName(event.target); + if (channel) { + prefixes = kiwi.gateway.get('user_prefixes'); + find_prefix = function (p) { + return event.modes[i].mode[1] === p.mode; + }; + for (i = 0; i < event.modes.length; i++) { + if (_.any(prefixes, find_prefix)) { + if (!members) { + members = channel.get('members'); + } + member = members.getByNick(event.modes[i].param); + if (!member) { + console.log('MODE command recieved for unknown member %s on channel %s', event.modes[i].param, event.target); + return; + } else { + if (event.modes[i].mode[0] === '+') { + member.addMode(event.modes[i].mode[1]); + } else if (event.modes[i].mode[0] === '-') { + member.removeMode(event.modes[i].mode[1]); + } + channel.addMsg(event.nick, 'set mode ' + event.modes[i].mode + ' ' + event.modes[i].param, 'mode'); + } + } else { + // TODO: Store this somewhere? + channel.addMsg(event.nick, 'set mode ' + event.modes[i].mode + ' on ' + event.target, 'mode'); + } + } + } else { + // This is probably a mode being set on us. + if (event.target.toLowerCase() === kiwi.gateway.get("nick").toLowerCase()) { + that.panels.server.addMsg(event.nick, 'set mode ' + event.modes[i].mode + ' on ' + event.target, 'mode'); + } else { + console.log('MODE command recieved for unknown target %s: ', event.target, event.modes[i].mode,); + } } }); diff --git a/server/irc-commands.js b/server/irc-commands.js index c40bfa7..c882009 100755 --- a/server/irc-commands.js +++ b/server/irc-commands.js @@ -336,27 +336,56 @@ var listeners = { //{nick: msg.nick, channel: msg.params, topic: msg.trailing}; this.client.sendIRCCommand('topic', {server: this.con_num, nick: command.nick, channel: command.params[0], topic: command.trailing}); }, - 'MODE': function (command) { - /*command.server = this.con_num; - command.command = 'MODE'; - this.client.sendIRCCommand(command);*/ - var ret = { server: this.con_num, nick: command.nick }; - switch (command.params.length) { - case 1: - ret.affected_nick = command.params[0]; - ret.mode = command.trailing; - break; - case 2: - ret.channel = command.params[0]; - ret.mode = command.params[1]; - break; - default: - ret.channel = command.params[0]; - ret.mode = command.params[1]; - ret.affected_nick = command.params[2]; - break; + 'MODE': function (command) { + var chanmodes = this.irc_connection.options.CHANMODES, + prefixes = this.irc_connection.options.PREFIX, + always_param = chanmodes[0].concat(chanmodes[1]), + modes = [], + has_param, i, j, add; + + prefixes = _.reduce(prefixes, function (list, prefix) { + list.push(prefix.mode); + return list; + }, []); + always_param = always_param.split('').concat(prefixes); + + has_param = function (mode, add) { + if (_.find(always_param, function (m) { + return m === mode; + })) { + return true; + } else if (add && _.find(chanmodes[2].split(''), function (m) { + return m === mode; + })) { + return true; + } else { + return false; + } + }; + + if (!command.params[1]) { + command.params[1] = command.trailing; } - this.client.sendIRCCommand('mode', ret); + j = 0; + for (i = 0; i < command.params[1].length; i++) { + switch (command.params[1][i]) { + case '+': + add = true; + break; + case '-': + add = false; + break; + default: + if (has_param(command.params[1][i], add)) { + modes.push({mode: (add ? '+' : '-') + command.params[1][i], param: command.params[2 + j]}); + j++; + } else { + modes.push({mode: (add ? '+' : '-') + command.params[1][i], param: null}); + } + } + } + + this.client.sendIRCCommand('mode', {server: this.con_num, target: command.params[0], nick: command.nick, modes: modes}); }, 'PRIVMSG': function (command) { /*command.server = this.con_num; -- 2.25.1