Proper handling of the MODE command.
authorJack Allnutt <m2ys4u@Gmail.com>
Thu, 27 Sep 2012 02:58:25 +0000 (03:58 +0100)
committerJack Allnutt <m2ys4u@Gmail.com>
Thu, 27 Sep 2012 02:58:25 +0000 (03:58 +0100)
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
server/irc-commands.js

index 9952ac205401bf524c5784142c1da5d5289cc82b..6d1d4d7808f4cb686174b2523e50c9030456ebaf 100755 (executable)
@@ -378,22 +378,43 @@ kiwi.model.Application = function () {
 \r
 \r
         gw.on('onmode', function (event) {\r
-            var channel, members, member;\r
-\r
-            if (!event.channel) return;\r
-            channel = that.panels.getByName(event.channel);\r
-            if (!channel) return;\r
-\r
-            members = channel.get('members');\r
-            if (!members) return;\r
-\r
-            member = members.getByNick(event.effected_nick);\r
-            if (!member) return;\r
-\r
-            if (event.mode[0] === '+') {\r
-                member.addMode(event.mode.substr(1));\r
-            } else if (event.mode[0] === '-') {\r
-                member.removeMode(event.mode.substr(1));\r
+            var channel, i, prefixes, members, member, find_prefix;\r
+            \r
+            channel = that.panels.getByName(event.target);\r
+            if (channel) {\r
+                prefixes = kiwi.gateway.get('user_prefixes');\r
+                find_prefix = function (p) {\r
+                    return event.modes[i].mode[1] === p.mode;\r
+                };\r
+                for (i = 0; i < event.modes.length; i++) {\r
+                    if (_.any(prefixes, find_prefix)) {\r
+                        if (!members) {\r
+                            members = channel.get('members');\r
+                        }\r
+                        member = members.getByNick(event.modes[i].param);\r
+                        if (!member) {\r
+                            console.log('MODE command recieved for unknown member %s on channel %s', event.modes[i].param, event.target);\r
+                            return;\r
+                        } else {\r
+                            if (event.modes[i].mode[0] === '+') {\r
+                                member.addMode(event.modes[i].mode[1]);\r
+                            } else if (event.modes[i].mode[0] === '-') {\r
+                                member.removeMode(event.modes[i].mode[1]);\r
+                            }\r
+                            channel.addMsg(event.nick, 'set mode ' + event.modes[i].mode + ' ' + event.modes[i].param, 'mode');\r
+                        }\r
+                    } else {\r
+                        // TODO: Store this somewhere?\r
+                        channel.addMsg(event.nick, 'set mode ' + event.modes[i].mode + ' on ' + event.target, 'mode');\r
+                    }\r
+                }\r
+            } else {\r
+                // This is probably a mode being set on us.\r
+                if (event.target.toLowerCase() === kiwi.gateway.get("nick").toLowerCase()) {\r
+                    that.panels.server.addMsg(event.nick, 'set mode ' + event.modes[i].mode + ' on ' + event.target, 'mode');\r
+                } else {\r
+                   console.log('MODE command recieved for unknown target %s: ', event.target, event.modes[i].mode,); \r
+                }\r
             }\r
         });\r
 \r
index c40bfa7cabbd4916e2011e4226365826fd033bbb..c88200994831ff399b4be49ac80961ec72b938f7 100755 (executable)
@@ -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;