Skip to content

Commit

Permalink
Merge pull request #351 from Timer/master
Browse files Browse the repository at this point in the history
  • Loading branch information
jirwin committed Jan 29, 2016
2 parents 5bd760c + ca6c0c4 commit ee5c550
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 30 deletions.
80 changes: 50 additions & 30 deletions lib/irc.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,41 +265,60 @@ function Client(server, nick, opt) {
adding = false;
return;
}
if (mode in self.prefixForMode) {
// channel user modes
var user = modeArgs.shift();
if (adding) {
if (channel.users[user] && channel.users[user].indexOf(self.prefixForMode[mode]) === -1)
channel.users[user] += self.prefixForMode[mode];

self.emit('+mode', message.args[0], message.nick, mode, user, message);
}
else {
if (channel.users[user])
channel.users[user] = channel.users[user].replace(self.prefixForMode[mode], '');

self.emit('-mode', message.args[0], message.nick, mode, user, message);
}
}
else {
var modeArg;
// channel modes
if (mode.match(/^[bkl]$/)) {
modeArg = modeArgs.shift();
if (modeArg.length === 0)
modeArg = undefined;
}
// TODO - deal nicely with channel modes that take args
var eventName = (adding ? '+' : '-') + 'mode';
var supported = self.supported.channel.modes;
var modeArg;
var chanModes = function(mode, param) {
var arr = param && Array.isArray(param);
if (adding) {
if (channel.mode.indexOf(mode) === -1)
if (channel.mode.indexOf(mode) == -1) {
channel.mode += mode;

self.emit('+mode', message.args[0], message.nick, mode, modeArg, message);
}
if (param === undefined) {
channel.modeParams[mode] = [];
} else if (arr) {
channel.modeParams[mode] = channel.modeParams[mode] ?
channel.modeParams[mode].concat(param) : param;
} else {
channel.modeParams[mode] = [param];
}
} else {
if (arr) {
channel.modeParams[mode] = channel.modeParams[mode]
.filter(function(v) { return v !== param[0]; });
}
if (!arr || channel.modeParams[mode].length === 0) {
channel.mode = channel.mode.replace(mode, '');
delete channel.modeParams[mode];
}
}
else {
channel.mode = channel.mode.replace(mode, '');
self.emit('-mode', message.args[0], message.nick, mode, modeArg, message);
};
if (mode in self.prefixForMode) {
modeArg = modeArgs.shift();
if (channel.users[modeArg]) {
if (adding) {
if (channel.users[modeArg].indexOf(self.prefixForMode[mode]) === -1)
channel.users[modeArg] += self.prefixForMode[mode];
} else channel.users[modeArg] = channel.users[modeArg].replace(self.prefixForMode[mode], '');
}
self.emit(eventName, message.args[0], message.nick, mode, modeArg, message);
} else if (supported.a.indexOf(mode) !== -1) {
modeArg = modeArgs.shift();
chanModes(mode, [modeArg]);
self.emit(eventName, message.args[0], message.nick, mode, modeArg, message);
} else if (supported.b.indexOf(mode) !== -1) {
modeArg = modeArgs.shift();
chanModes(mode, modeArg);
self.emit(eventName, message.args[0], message.nick, mode, modeArg, message);
} else if (supported.c.indexOf(mode) !== -1) {
if (adding) modeArg = modeArgs.shift();
else modeArg = undefined;
chanModes(mode, modeArg);
self.emit(eventName, message.args[0], message.nick, mode, modeArg, message);
} else if (supported.d.indexOf(mode) !== -1) {
chanModes(mode);
self.emit(eventName, message.args[0], message.nick, mode, undefined, message);
}
});
break;
Expand Down Expand Up @@ -649,6 +668,7 @@ Client.prototype.chanData = function(name, create) {
key: key,
serverName: name,
users: {},
modeParams: {},
mode: ''
};
}
Expand Down
68 changes: 68 additions & 0 deletions test/test-mode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
var irc = require('../lib/irc');
var test = require('tape');

var testHelpers = require('./helpers');

test('various origins and types of chanmodes get handled correctly', function(t) {
var mock = testHelpers.MockIrcd();
var client = new irc.Client('localhost', 'testbot', { debug: true });

var count = 0;
client.on('+mode', function() {
//console.log(client.chans['#channel']);
t.deepEqual(client.chans['#channel'], expected[count++]);
});
client.on('-mode', function() {
//console.log(client.chans['#channel']);
t.deepEqual(client.chans['#channel'], expected[count++]);
});

var expected = [
{ key: '#channel', serverName: '#channel', users: {}, modeParams: { n: [] }, mode: 'n' },
{ key: '#channel', serverName: '#channel', users: {}, modeParams: { n: [], t: [] }, mode: 'nt' },
{ key: '#channel', serverName: '#channel', users: { testbot: '@' }, mode: '+ntb', modeParams: { b: ['*!*@AN.IP.1'], n: [], t: [] } },
{ key: '#channel', serverName: '#channel', users: { testbot: '@' }, mode: '+ntb', modeParams: { b: ['*!*@AN.IP.1', '*!*@AN.IP.2'], n: [], t: [] } },
{ key: '#channel', serverName: '#channel', users: { testbot: '@' }, mode: '+ntb', modeParams: { b: ['*!*@AN.IP.1', '*!*@AN.IP.2', '*!*@AN.IP.3'], n: [], t: [] } },
{ key: '#channel', serverName: '#channel', users: { testbot: '@' }, mode: '+ntb', modeParams: { b: ['*!*@AN.IP.1', '*!*@AN.IP.3'], n: [], t: [] } },
{ key: '#channel', serverName: '#channel', users: { testbot: '@' }, mode: '+ntbf', modeParams: { f: ['[10j]:15'], b: ['*!*@AN.IP.1', '*!*@AN.IP.3'], n: [], t: [] } },
{ key: '#channel', serverName: '#channel', users: { testbot: '@' }, mode: '+ntbf', modeParams: { f: ['[8j]:15'], b: ['*!*@AN.IP.1', '*!*@AN.IP.3'], n: [], t: [] } },
{ key: '#channel', serverName: '#channel', users: { testbot: '@' }, mode: '+ntb', modeParams: { b: ['*!*@AN.IP.1', '*!*@AN.IP.3'], n: [], t: [] } },
{ key: '#channel', serverName: '#channel', users: { testbot: '@' }, mode: '+ntbj', modeParams: { j: ['3:5'], b: ['*!*@AN.IP.1', '*!*@AN.IP.3'], n: [], t: [] } },
{ key: '#channel', serverName: '#channel', users: { testbot: '@' }, mode: '+ntbj', modeParams: { j: ['2:5'], b: ['*!*@AN.IP.1', '*!*@AN.IP.3'], n: [], t: [] } },
{ key: '#channel', serverName: '#channel', users: { testbot: '@' }, mode: '+ntb', modeParams: { b: ['*!*@AN.IP.1', '*!*@AN.IP.3'], n: [], t: [] } },
{ key: '#channel', serverName: '#channel', users: { testbot: '@' }, mode: '+ntbp', modeParams: { p: [], b: ['*!*@AN.IP.1', '*!*@AN.IP.3'], n: [], t: [] } },
{ key: '#channel', serverName: '#channel', users: { testbot: '@' }, mode: '+ntbps', modeParams: { s: [], p: [], b: ['*!*@AN.IP.1', '*!*@AN.IP.3'], n: [], t: [] } },
{ key: '#channel', serverName: '#channel', users: { testbot: '@' }, mode: '+ntbpsK', modeParams: { K: [], s: [], p: [], b: ['*!*@AN.IP.1', '*!*@AN.IP.3'], n: [], t: [] } },
{ key: '#channel', serverName: '#channel', users: { testbot: '@' }, mode: '+ntbsK', modeParams: { K: [], s: [], b: ['*!*@AN.IP.1', '*!*@AN.IP.3'], n: [], t: [] } },
{ key: '#channel', serverName: '#channel', users: { testbot: '@' }, mode: '+ntbK', modeParams: { K: [], b: ['*!*@AN.IP.1', '*!*@AN.IP.3'], n: [], t: [] } },
{ key: '#channel', serverName: '#channel', users: { testbot: '@' }, mode: '+ntbKF', modeParams: { F: [], K: [], b: ['*!*@AN.IP.1', '*!*@AN.IP.3'], n: [], t: [] } }
];

mock.server.on('connection', function() {
mock.send(':localhost 001 testbot :Welcome!\r\n');
mock.send(':localhost 005 testbot MODES=12 CHANTYPES=# PREFIX=(ohv)@%+ CHANMODES=beIqa,kfL,lj,psmntirRcOAQKVCuzNSMTGHFEB\r\n');
mock.send(':testbot MODE testbot :+ix\r\n');
mock.send(':testbot JOIN :#channel\r\n');
mock.send(':localhost MODE #channel +nt\r\n');
mock.send(':localhost 353 testbot = #channel :@testbot\r\n');
mock.send(':localhost 366 testbot #channel :End of /NAMES list.\r\n');
mock.send(':localhost 324 testbot #channel +nt\r\n');
mock.send(':localhost MODE #channel +b *!*@AN.IP.1\r\n');
mock.send(':localhost MODE #channel +bb *!*@AN.IP.2 *!*@AN.IP.3\r\n');
mock.send(':localhost MODE #channel -b *!*@AN.IP.2\r\n');
mock.send(':localhost MODE #channel +f [10j]:15\r\n');
mock.send(':localhost MODE #channel +f [8j]:15\r\n');
mock.send(':localhost MODE #channel -f+j [10j]:15 3:5\r\n');
mock.send(':localhost MODE #channel +j 2:5\r\n');
mock.send(':localhost MODE #channel -j\r\n');
mock.send(':localhost MODE #channel +ps\r\n');
mock.send(':localhost MODE #channel +K-p-s+F\r\n');

client.disconnect();
});

mock.on('end', function() {
mock.close();
t.end();
});
});

0 comments on commit ee5c550

Please sign in to comment.