Use a space instead of colon as event delimiter
[KiwiIRC.git] / server / irc / commands.js
CommitLineData
f9ff7686 1var _ = require('lodash');
a8bf3ea4
JA
2
3var irc_numerics = {
4 RPL_WELCOME: '001',
5 RPL_MYINFO: '004',
6 RPL_ISUPPORT: '005',
cea1f25b
D
7 RPL_MAPMORE: '006',
8 RPL_MAPEND: '007',
28ce8b75
D
9 RPL_STATSCONN: '250',
10 RPL_LUSERCLIENT: '251',
11 RPL_LUSEROP: '252',
12 RPL_LUSERUNKNOWN: '253',
13 RPL_LUSERCHANNELS: '254',
14 RPL_LUSERME: '255',
15 RPL_LOCALUSERS: '265',
16 RPL_GLOBALUSERS: '266',
f3766a0b 17 RPL_WHOISREGNICK: '307',
a8bf3ea4
JA
18 RPL_WHOISUSER: '311',
19 RPL_WHOISSERVER: '312',
20 RPL_WHOISOPERATOR: '313',
21 RPL_WHOISIDLE: '317',
22 RPL_ENDOFWHOIS: '318',
23 RPL_WHOISCHANNELS: '319',
24 RPL_LISTSTART: '321',
25 RPL_LIST: '322',
26 RPL_LISTEND: '323',
27 RPL_NOTOPIC: '331',
28 RPL_TOPIC: '332',
29 RPL_TOPICWHOTIME: '333',
30 RPL_NAMEREPLY: '353',
cea1f25b
D
31 RPL_LINKS: '364',
32 RPL_ENDOFLINKS: '365',
a8bf3ea4
JA
33 RPL_ENDOFNAMES: '366',
34 RPL_BANLIST: '367',
35 RPL_ENDOFBANLIST: '368',
36 RPL_MOTD: '372',
37 RPL_MOTDSTART: '375',
38 RPL_ENDOFMOTD: '376',
39 RPL_WHOISMODES: '379',
40 ERR_NOSUCHNICK: '401',
41 ERR_CANNOTSENDTOCHAN: '404',
42 ERR_TOOMANYCHANNELS: '405',
cea1f25b
D
43 ERR_UNKNOWNCOMMAND: '421',
44 ERR_NOMOTD: '422',
a8bf3ea4
JA
45 ERR_NICKNAMEINUSE: '433',
46 ERR_USERNOTINCHANNEL: '441',
47 ERR_NOTONCHANNEL: '442',
ebe178d6 48 ERR_PASSWDMISMATCH: '464',
a8bf3ea4
JA
49 ERR_NOTREGISTERED: '451',
50 ERR_LINKCHANNEL: '470',
51 ERR_CHANNELISFULL: '471',
52 ERR_INVITEONLYCHAN: '473',
53 ERR_BANNEDFROMCHAN: '474',
54 ERR_BADCHANNELKEY: '475',
cea1f25b 55 ERR_NOPRIVILEGES: '481',
a8bf3ea4 56 ERR_CHANOPRIVSNEEDED: '482',
7dfe47c6
JA
57 RPL_STARTTLS: '670',
58 RPL_SASLAUTHENTICATED: '900',
59 RPL_SASLLOGGEDIN: '903',
60 ERR_SASLNOTAUTHORISED: '904',
7dfe47c6
JA
61 ERR_SASLABORTED: '906',
62 ERR_SASLALREADYAUTHED: '907'
63
a8bf3ea4
JA
64};
65
66
2a8e95d1 67var IrcCommands = function (irc_connection, con_num, client) {
a8bf3ea4
JA
68 this.irc_connection = irc_connection;
69 this.con_num = con_num;
70 this.client = client;
71};
2a8e95d1 72module.exports = IrcCommands;
a8bf3ea4 73
2a8e95d1 74IrcCommands.prototype.bindEvents = function () {
a8bf3ea4 75 var that = this;
2a8e95d1 76
a8bf3ea4
JA
77 _.each(listeners, function (listener, command) {
78 var s = command.substr(0, 4);
79 if ((s === 'RPL_') || (s === 'ERR_')) {
80 command = irc_numerics[command];
81 }
82 that.irc_connection.on('irc_' + command, function () {
83 listener.apply(that, arguments);
84 });
85 });
86};
87
c08717da
D
88IrcCommands.prototype.dispose = function () {
89 this.removeAllListeners();
90};
91
2a8e95d1
D
92
93
a8bf3ea4 94var listeners = {
a49e0dcf
JA
95 'RPL_WELCOME': function (command) {
96 var nick = command.params[0];
97 this.irc_connection.registered = true;
98 this.cap_negotation = false;
d9285da9 99 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' connect', {
1cc056b8
JA
100 nick: nick
101 });
a49e0dcf
JA
102 },
103 'RPL_ISUPPORT': function (command) {
104 var options, i, option, matches, j;
105 options = command.params;
106 for (i = 1; i < options.length; i++) {
107 option = options[i].split("=", 2);
108 option[0] = option[0].toUpperCase();
109 this.irc_connection.options[option[0]] = (typeof option[1] !== 'undefined') ? option[1] : true;
110 if (_.include(['NETWORK', 'PREFIX', 'CHANTYPES', 'CHANMODES', 'NAMESX'], option[0])) {
111 if (option[0] === 'PREFIX') {
112 matches = /\(([^)]*)\)(.*)/.exec(option[1]);
113 if ((matches) && (matches.length === 3)) {
114 this.irc_connection.options.PREFIX = [];
115 for (j = 0; j < matches[2].length; j++) {
116 this.irc_connection.options.PREFIX.push({symbol: matches[2].charAt(j), mode: matches[1].charAt(j)});
a8bf3ea4
JA
117 }
118 }
a49e0dcf
JA
119 } else if (option[0] === 'CHANTYPES') {
120 this.irc_connection.options.CHANTYPES = this.irc_connection.options.CHANTYPES.split('');
121 } else if (option[0] === 'CHANMODES') {
122 this.irc_connection.options.CHANMODES = option[1].split(',');
123 } else if ((option[0] === 'NAMESX') && (!_.contains(this.irc_connection.cap.enabled, 'multi-prefix'))) {
124 this.irc_connection.write('PROTOCTL NAMESX');
a8bf3ea4 125 }
a49e0dcf
JA
126 }
127 }
d9285da9 128 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' options', {
1cc056b8
JA
129 options: this.irc_connection.options,
130 cap: this.irc_connection.cap.enabled
131 });
a49e0dcf
JA
132 },
133 'RPL_ENDOFWHOIS': function (command) {
d9285da9 134 this.irc_connection.emit('user ' + command.params[1] + ' endofwhois', {
692163ca
JA
135 nick: command.params[1],
136 msg: command.trailing
137 });
a49e0dcf
JA
138 },
139 'RPL_WHOISUSER': function (command) {
d9285da9 140 this.irc_connection.emit('user ' + command.params[1] + ' whoisuser', {
692163ca
JA
141 nick: command.params[1],
142 ident: command.params[2],
143 host: command.params[3],
144 msg: command.trailing
145 });
a49e0dcf
JA
146 },
147 'RPL_WHOISSERVER': function (command) {
d9285da9 148 this.irc_connection.emit('user ' + command.params[1] + ' whoisserver', {
692163ca
JA
149 nick: command.params[1],
150 irc_server: command.params[2]
151 });
a49e0dcf
JA
152 },
153 'RPL_WHOISOPERATOR': function (command) {
d9285da9 154 this.irc_connection.emit('user ' + command.params[1] + ' whoisoperator', {
692163ca
JA
155 nick: command.params[1],
156 msg: command.trailing
157 });
a49e0dcf
JA
158 },
159 'RPL_WHOISCHANNELS': function (command) {
d9285da9 160 this.irc_connection.emit('user ' + command.params[1] + ' whoischannels', {
692163ca 161 nick: command.params[1],
cefa0900 162 chans: command.trailing
692163ca 163 });
a49e0dcf
JA
164 },
165 'RPL_WHOISMODES': function (command) {
d9285da9 166 this.irc_connection.emit('user ' + command.params[1] + ' whoismodes', {
692163ca
JA
167 nick: command.params[1],
168 msg: command.trailing
169 });
a49e0dcf
JA
170 },
171 'RPL_WHOISIDLE': function (command) {
d9285da9 172 this.irc_connection.emit('user ' + command.params[1] + ' whoisidle', {
692163ca
JA
173 nick: command.params[1],
174 idle: command.params[2],
175 logon: command.params[3] || undefined
176 });
a49e0dcf
JA
177 },
178 'RPL_WHOISREGNICK': function (command) {
d9285da9 179 this.irc_connection.emit('user ' + command.params[1] + ' whoisregnick', {
692163ca
JA
180 nick: command.params[1],
181 msg: command.trailing
182 });
a49e0dcf
JA
183 },
184 'RPL_LISTSTART': function (command) {
d9285da9 185 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' list_start', {});
a49e0dcf
JA
186 },
187 'RPL_LISTEND': function (command) {
d9285da9 188 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' list_end', {});
a49e0dcf
JA
189 },
190 'RPL_LIST': function (command) {
d9285da9 191 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' list_channel', {
fb1b18bc 192 channel: command.params[1],
25edd441 193 num_users: parseInt(command.params[2], 10),
fb1b18bc
JA
194 topic: command.trailing
195 });
a49e0dcf
JA
196 },
197 'RPL_MOTD': function (command) {
d9285da9 198 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' motd', {
fb1b18bc 199 motd: command.trailing + '\n'
1cc056b8 200 });
a49e0dcf
JA
201 },
202 'RPL_MOTDSTART': function (command) {
d9285da9 203 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' motd_start', {});
a49e0dcf
JA
204 },
205 'RPL_ENDOFMOTD': function (command) {
d9285da9 206 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' motd_end', {});
a49e0dcf
JA
207 },
208 'RPL_NAMEREPLY': function (command) {
209 var members = command.trailing.split(' ');
210 var member_list = [];
211 var that = this;
212 var i = 0;
213 _.each(members, function (member) {
214 var j, k, modes = [];
30b4d43a
D
215
216 // Make sure we have some prefixes already
217 if (that.irc_connection.options.PREFIX) {
218 for (j = 0; j < member.length; j++) {
219 for (k = 0; k < that.irc_connection.options.PREFIX.length; k++) {
220 if (member.charAt(j) === that.irc_connection.options.PREFIX[k].symbol) {
221 modes.push(that.irc_connection.options.PREFIX[k].mode);
222 i++;
223 }
a8bf3ea4 224 }
a8bf3ea4 225 }
a49e0dcf 226 }
30b4d43a 227
a49e0dcf 228 member_list.push({nick: member, modes: modes});
a49e0dcf 229 });
e2752476 230
d9285da9 231 this.irc_connection.emit('channel ' + command.params[2] + ' userlist', {
e2752476
D
232 users: member_list,
233 channel: command.params[2]
234 });
a49e0dcf 235 },
e2752476
D
236
237
a49e0dcf 238 'RPL_ENDOFNAMES': function (command) {
d9285da9 239 this.irc_connection.emit('channel ' + command.params[1] + ' userlist_end', {
e2752476
D
240 channel: command.params[1]
241 });
a49e0dcf 242 },
e2752476
D
243
244
a49e0dcf 245 'RPL_BANLIST': function (command) {
d9285da9 246 this.irc_connection.emit('channel ' + command.params[1] + ' banlist', {
059f4918
JA
247 channel: command.params[1],
248 banned: command.params[2],
249 banned_by: command.params[3],
250 banned_at: command.params[4]
251 });
a49e0dcf
JA
252 },
253 'RPL_ENDOFBANLIST': function (command) {
d9285da9 254 this.irc_connection.emit('channel ' + command.params[1] + ' banlist_end', {
aa22caa9 255 channel: command.params[1]
059f4918 256 });
a49e0dcf
JA
257 },
258 'RPL_TOPIC': function (command) {
d9285da9 259 this.irc_connection.emit('channel ' + command.params[1] + ' topic', {
059f4918
JA
260 channel: command.params[1],
261 topic: command.trailing
262 });
a49e0dcf
JA
263 },
264 'RPL_NOTOPIC': function (command) {
d9285da9 265 this.irc_connection.emit('channel ' + command.params[1] + ' topic', {
059f4918
JA
266 channel: command.params[1],
267 topic: ''
268 });
a49e0dcf
JA
269 },
270 'RPL_TOPICWHOTIME': function (command) {
d9285da9 271 this.irc_connection.emit('channel ' + command.params[1] + ' topicsetby', {
059f4918
JA
272 nick: command.params[2],
273 channel: command.params[1],
274 when: command.params[3]
275 });
a49e0dcf
JA
276 },
277 'PING': function (command) {
278 this.irc_connection.write('PONG ' + command.trailing);
279 },
e2752476
D
280
281
a49e0dcf
JA
282 'JOIN': function (command) {
283 var channel;
284 if (typeof command.trailing === 'string' && command.trailing !== '') {
285 channel = command.trailing;
286 } else if (typeof command.params[0] === 'string' && command.params[0] !== '') {
287 channel = command.params[0];
288 }
289
d9285da9 290 this.irc_connection.emit('channel ' + channel + ' join', {
e2752476
D
291 nick: command.nick,
292 ident: command.ident,
293 hostname: command.hostname,
294 channel: channel
295 });
a49e0dcf 296 },
e2752476
D
297
298
a49e0dcf 299 'PART': function (command) {
d9285da9 300 this.irc_connection.emit('channel ' + command.params[0] + ' part', {
e2752476
D
301 nick: command.nick,
302 ident: command.ident,
303 hostname: command.hostname,
304 channel: command.params[0],
305 message: command.trailing
306 });
a49e0dcf 307 },
e2752476
D
308
309
a49e0dcf 310 'KICK': function (command) {
d9285da9 311 this.irc_connection.emit('channel ' + command.params[0] + ' kick', {
e2752476
D
312 kicked: command.params[1],
313 nick: command.nick,
314 ident: command.ident,
315 hostname: command.hostname,
316 channel: command.params[0],
317 message: command.trailing
318 });
a49e0dcf 319 },
e2752476
D
320
321
a49e0dcf 322 'QUIT': function (command) {
d9285da9 323 this.irc_connection.emit('user ' + command.nick + ' quit', {
e2752476
D
324 nick: command.nick,
325 ident: command.ident,
326 hostname: command.hostname,
327 message: command.trailing
328 });
a49e0dcf 329 },
e2752476
D
330
331
a49e0dcf 332 'NOTICE': function (command) {
e2752476
D
333 var namespace;
334
a49e0dcf
JA
335 if ((command.trailing.charAt(0) === String.fromCharCode(1)) && (command.trailing.charAt(command.trailing.length - 1) === String.fromCharCode(1))) {
336 // It's a CTCP response
e2752476 337 namespace = (command.params[0] == this.irc_connection.nick) ? 'user' : 'channel';
d9285da9 338 this.irc_connection.emit(namespace + ' ' + command.params[0] + ' ctcp_response', {
e2752476
D
339 nick: command.nick,
340 ident: command.ident,
341 hostname: command.hostname,
342 channel: command.params[0],
343 msg: command.trailing.substr(1, command.trailing.length - 2)
344 });
a49e0dcf 345 } else {
e2752476 346 namespace = (command.params[0] == this.irc_connection.nick) ? 'user' : 'channel';
d9285da9 347 this.irc_connection.emit(namespace + ' ' + command.params[0] + ' notice', {
e2752476
D
348 nick: command.nick,
349 ident: command.ident,
350 hostname: command.hostname,
351 target: command.params[0],
352 msg: command.trailing
353 });
a49e0dcf
JA
354 }
355 },
356 'NICK': function (command) {
d9285da9 357 this.irc_connection.emit('user ' + command.nick + ' nick', {
692163ca
JA
358 nick: command.nick,
359 ident: command.ident,
360 hostname: command.hostname,
361 newnick: command.trailing || command.params[0]
362 });
a49e0dcf
JA
363 },
364 'TOPIC': function (command) {
30b4d43a
D
365 // If we don't have an associated channel, no need to continue
366 if (!command.params[0]) return;
367
368 var channel = command.params[0],
369 topic = command.trailing || '';
370
d9285da9 371 this.irc_connection.emit('channel ' + channel + ' topic', {
f4ec5774
D
372 nick: command.nick,
373 channel: channel,
374 topic: topic
375 });
a49e0dcf 376 },
d9285da9 377 'MODE': function (command) {
30b4d43a
D
378 var chanmodes = this.irc_connection.options.CHANMODES || [],
379 prefixes = this.irc_connection.options.PREFIX || [],
380 always_param = (chanmodes[0] || '').concat((chanmodes[1] || '')),
a49e0dcf 381 modes = [],
a7973dfb 382 has_param, i, j, add, event;
a49e0dcf
JA
383
384 prefixes = _.reduce(prefixes, function (list, prefix) {
385 list.push(prefix.mode);
386 return list;
387 }, []);
388 always_param = always_param.split('').concat(prefixes);
389
390 has_param = function (mode, add) {
391 if (_.find(always_param, function (m) {
392 return m === mode;
393 })) {
394 return true;
30b4d43a 395 } else if (add && _.find((chanmodes[2] || '').split(''), function (m) {
a49e0dcf
JA
396 return m === mode;
397 })) {
398 return true;
399 } else {
400 return false;
401 }
402 };
403
404 if (!command.params[1]) {
405 command.params[1] = command.trailing;
406 }
407 j = 0;
408 for (i = 0; i < command.params[1].length; i++) {
409 switch (command.params[1][i]) {
410 case '+':
411 add = true;
412 break;
413 case '-':
414 add = false;
415 break;
416 default:
417 if (has_param(command.params[1][i], add)) {
418 modes.push({mode: (add ? '+' : '-') + command.params[1][i], param: command.params[2 + j]});
419 j++;
703d2778 420 } else {
a49e0dcf 421 modes.push({mode: (add ? '+' : '-') + command.params[1][i], param: null});
703d2778 422 }
a49e0dcf
JA
423 }
424 }
425
d9285da9 426 event = (_.contains(this.irc_connection.options.CHANTYPES, command.params[0][0]) ? 'channel ' : 'user ') + command.params[0] + ' mode';
a7973dfb
JA
427
428 this.irc_connection.emit(event, {
a49e0dcf
JA
429 target: command.params[0],
430 nick: command.nick || command.prefix || '',
431 modes: modes
432 });
433 },
434 'PRIVMSG': function (command) {
435 var tmp, namespace;
436 if ((command.trailing.charAt(0) === String.fromCharCode(1)) && (command.trailing.charAt(command.trailing.length - 1) === String.fromCharCode(1))) {
437 //CTCP request
438 if (command.trailing.substr(1, 6) === 'ACTION') {
439 this.client.sendIrcCommand('action', {server: this.con_num, nick: command.nick, ident: command.ident, hostname: command.hostname, channel: command.params[0], msg: command.trailing.substr(7, command.trailing.length - 2)});
440 } else if (command.trailing.substr(1, 4) === 'KIWI') {
441 tmp = command.trailing.substr(6, command.trailing.length - 2);
442 namespace = tmp.split(' ', 1)[0];
443 this.client.sendIrcCommand('kiwi', {server: this.con_num, namespace: namespace, data: tmp.substr(namespace.length + 1)});
444 } else if (command.trailing.substr(1, 7) === 'VERSION') {
445 this.irc_connection.write('NOTICE ' + command.nick + ' :' + String.fromCharCode(1) + 'VERSION KiwiIRC' + String.fromCharCode(1));
b39bb331
D
446 } else if (command.trailing.substr(1, 6) === 'SOURCE') {
447 this.irc_connection.write('NOTICE ' + command.nick + ' :' + String.fromCharCode(1) + 'SOURCE http://www.kiwiirc.com/' + String.fromCharCode(1));
448 } else if (command.trailing.substr(1, 10) === 'CLIENTINFO') {
449 this.irc_connection.write('NOTICE ' + command.nick + ' :' + String.fromCharCode(1) + 'CLIENTINFO SOURCE VERSION TIME' + String.fromCharCode(1));
a49e0dcf 450 } else {
7d969e05 451 namespace = (command.params[0].toLowerCase() == this.irc_connection.nick.toLowerCase()) ? 'user' : 'channel';
d9285da9 452 this.irc_connection.emit(namespace + ' ' + command.nick + ' ctcp_request', {
b39bb331
D
453 nick: command.nick,
454 ident: command.ident,
455 hostname: command.hostname,
456 target: command.params[0],
457 type: (command.trailing.substr(1, command.trailing.length - 2).split(' ') || [null])[0],
458 msg: command.trailing.substr(1, command.trailing.length - 2)
459 });
a49e0dcf
JA
460 }
461 } else {
e2752476 462 // A message to a user (private message) or to a channel?
d9285da9
JA
463 namespace = (command.params[0] === this.irc_connection.nick) ? 'user ' + command.nick : 'channel ' + command.params[0];
464 this.irc_connection.emit(namespace + ' privmsg', {
ffbbc70f
D
465 nick: command.nick,
466 ident: command.ident,
467 hostname: command.hostname,
468 channel: command.params[0],
469 msg: command.trailing
b09157de 470 });
a49e0dcf
JA
471 }
472 },
473 'CAP': function (command) {
474 // TODO: capability modifiers
475 // i.e. - for disable, ~ for requires ACK, = for sticky
476 var capabilities = command.trailing.replace(/[\-~=]/, '').split(' ');
477 var request;
478 var want = ['multi-prefix', 'away-notify'];
479
480 if (this.irc_connection.password) {
481 want.push('sasl');
482 }
483
484 switch (command.params[1]) {
485 case 'LS':
486 request = _.intersection(capabilities, want);
487 if (request.length > 0) {
488 this.irc_connection.cap.requested = request;
489 this.irc_connection.write('CAP REQ :' + request.join(' '));
490 } else {
491 this.irc_connection.write('CAP END');
492 this.irc_connection.cap_negotation = false;
a8bf3ea4 493 }
a49e0dcf
JA
494 break;
495 case 'ACK':
496 if (capabilities.length > 0) {
497 this.irc_connection.cap.enabled = capabilities;
498 this.irc_connection.cap.requested = _.difference(this.irc_connection.cap.requested, capabilities);
703d2778 499 }
a49e0dcf
JA
500 if (this.irc_connection.cap.requested.length > 0) {
501 if (_.contains(this.irc_connection.cap.enabled, 'sasl')) {
502 this.irc_connection.sasl = true;
503 this.irc_connection.write('AUTHENTICATE PLAIN');
a8bf3ea4 504 } else {
a49e0dcf
JA
505 this.irc_connection.write('CAP END');
506 this.irc_connection.cap_negotation = false;
a8bf3ea4 507 }
a8bf3ea4 508 }
a49e0dcf
JA
509 break;
510 case 'NAK':
511 if (capabilities.length > 0) {
512 this.irc_connection.cap.requested = _.difference(this.irc_connection.cap.requested, capabilities);
7dfe47c6 513 }
a49e0dcf 514 if (this.irc_connection.cap.requested.length > 0) {
7dfe47c6
JA
515 this.irc_connection.write('CAP END');
516 this.irc_connection.cap_negotation = false;
7dfe47c6 517 }
a49e0dcf
JA
518 break;
519 case 'LIST':
520 // should we do anything here?
521 break;
522 }
523 },
524 'AUTHENTICATE': function (command) {
525 var b = new Buffer(this.irc_connection.nick + "\0" + this.irc_connection.nick + "\0" + this.irc_connection.password, 'utf8');
526 var b64 = b.toString('base64');
527 if (command.params[0] === '+') {
528 while (b64.length >= 400) {
529 this.irc_connection.write('AUTHENTICATE ' + b64.slice(0, 399));
530 b64 = b64.slice(399);
a8bf3ea4 531 }
a49e0dcf
JA
532 if (b64.length > 0) {
533 this.irc_connection.write('AUTHENTICATE ' + b64);
534 } else {
535 this.irc_connection.write('AUTHENTICATE +');
536 }
537 } else {
538 this.irc_connection.write('CAP END');
539 this.irc_connection.cap_negotation = false;
540 }
541 },
542 'AWAY': function (command) {
d9285da9 543 this.irc_connection.emit('user ' + command.nick + ' away', {
692163ca
JA
544 nick: command.nick,
545 msg: command.trailing
546 });
a49e0dcf
JA
547 },
548 'RPL_SASLAUTHENTICATED': function (command) {
549 this.irc_connection.write('CAP END');
550 this.irc_connection.cap_negotation = false;
551 this.irc_connection.sasl = true;
552 },
553 'RPL_SASLLOGGEDIN': function (command) {
554 if (this.irc_connection.cap_negotation === false) {
555 this.irc_connection.write('CAP END');
556 }
557 },
558 'ERR_SASLNOTAUTHORISED': function (command) {
559 this.irc_connection.write('CAP END');
560 this.irc_connection.cap_negotation = false;
561 },
562 'ERR_SASLABORTED': function (command) {
563 this.irc_connection.write('CAP END');
564 this.irc_connection.cap_negotation = false;
565 },
566 'ERR_SASLALREADYAUTHED': function (command) {
567 // noop
568 },
569 'ERROR': function (command) {
d9285da9 570 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' error', {
1cc056b8
JA
571 reason: command.trailing
572 });
a49e0dcf 573 },
ebe178d6 574 ERR_PASSWDMISMATCH: function (command) {
d9285da9 575 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' password_mismatch', {});
ebe178d6 576 },
a49e0dcf 577 ERR_LINKCHANNEL: function (command) {
d9285da9 578 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' channel_redirect', {
1cc056b8
JA
579 from: command.params[1],
580 to: command.params[2]
581 });
a49e0dcf
JA
582 },
583 ERR_NOSUCHNICK: function (command) {
d9285da9 584 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' no_such_nick', {
1cc056b8
JA
585 nick: command.params[1],
586 reason: command.trailing
587 });
a49e0dcf
JA
588 },
589 ERR_CANNOTSENDTOCHAN: function (command) {
d9285da9 590 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' cannot_send_to_chan', {
1cc056b8
JA
591 channel: command.params[1],
592 reason: command.trailing
593 });
a49e0dcf
JA
594 },
595 ERR_TOOMANYCHANNELS: function (command) {
d9285da9 596 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' too_many_channels', {
1cc056b8
JA
597 channel: command.params[1],
598 reason: command.trailing
599 });
a49e0dcf
JA
600 },
601 ERR_USERNOTINCHANNEL: function (command) {
d9285da9 602 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' user_not_in_channel', {
1cc056b8
JA
603 nick: command.params[0],
604 channel: command.params[1],
605 reason: command.trailing
606 });
a49e0dcf
JA
607 },
608 ERR_NOTONCHANNEL: function (command) {
d9285da9 609 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' not_on_channel', {
1cc056b8
JA
610 channel: command.params[1],
611 reason: command.trailing
612 });
a49e0dcf
JA
613 },
614 ERR_CHANNELISFULL: function (command) {
d9285da9 615 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' channel_is_full', {
1cc056b8
JA
616 channel: command.params[1],
617 reason: command.trailing
618 });
a49e0dcf
JA
619 },
620 ERR_INVITEONLYCHAN: function (command) {
d9285da9 621 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' invite_only_channel', {
1cc056b8
JA
622 channel: command.params[1],
623 reason: command.trailing
624 });
a49e0dcf
JA
625 },
626 ERR_BANNEDFROMCHAN: function (command) {
d9285da9 627 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' banned_from_channel', {
1cc056b8
JA
628 channel: command.params[1],
629 reason: command.trailing
630 });
a49e0dcf
JA
631 },
632 ERR_BADCHANNELKEY: function (command) {
d9285da9 633 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' bad_channel_key', {
1cc056b8
JA
634 channel: command.params[1],
635 reason: command.trailing
636 });
a49e0dcf
JA
637 },
638 ERR_CHANOPRIVSNEEDED: function (command) {
d9285da9 639 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' chanop_privs_needed', {
1cc056b8
JA
640 channel: command.params[1],
641 reason: command.trailing
642 });
a49e0dcf
JA
643 },
644 ERR_NICKNAMEINUSE: function (command) {
d9285da9 645 this.irc_connection.emit('server ' + this.irc_connection.irc_host.hostname + ' nickname_in_use', {
1cc056b8
JA
646 nick: command.params[1],
647 reason: command.trailing
648 });
a49e0dcf
JA
649 },
650 ERR_NOTREGISTERED: function (command) {
cea1f25b
D
651 },
652
653 RPL_MAPMORE: function (command) {
654 var params = _.clone(command.params);
655 params.shift();
656 genericNotice.call(this, command, params.join(', ') + ' ' + command.trailing);
657 },
658 RPL_MAPEND: function (command) {
659 var params = _.clone(command.params);
660 params.shift();
661 genericNotice.call(this, command, params.join(', ') + ' ' + command.trailing);
662 },
663
664 RPL_LINKS: function (command) {
665 var params = _.clone(command.params);
666 params.shift();
667 genericNotice.call(this, command, params.join(', ') + ' ' + command.trailing);
668 },
669 RPL_ENDOFLINKS: function (command) {
670 var params = _.clone(command.params);
671 params.shift();
672 genericNotice.call(this, command, params.join(', ') + ' ' + command.trailing);
673 },
674
675 ERR_UNKNOWNCOMMAND: function (command) {
676 var params = _.clone(command.params);
677 params.shift();
678 genericNotice.call(this, command, '`' + params.join(', ') + '` ' + command.trailing);
679 },
680
681 ERR_NOMOTD: function (command) {
682 var params = _.clone(command.params);
683 params.shift();
684 genericNotice.call(this, command, command.trailing);
685 },
686
687 ERR_NOPRIVILEGES: function (command) {
688 var params = _.clone(command.params);
689 params.shift();
690 genericNotice.call(this, command, command.trailing);
28ce8b75
D
691 },
692
693 RPL_STATSCONN: function (command) {
694 var params = _.clone(command.params);
695 params.shift();
696 genericNotice.call(this, command, params.join(', ') + ' ' + command.trailing);
697 },
698
699 RPL_LUSERCLIENT: function (command) {
700 var params = _.clone(command.params);
701 params.shift();
702 genericNotice.call(this, command, params.join(', ') + ' ' + command.trailing);
703 },
704
705 RPL_LUSEROP: function (command) {
706 var params = _.clone(command.params);
707 params.shift();
708 genericNotice.call(this, command, params.join(', ') + ' ' + command.trailing);
709 },
710
711 RPL_LUSERUNKNOWN: function (command) {
712 var params = _.clone(command.params);
713 params.shift();
714 genericNotice.call(this, command, params.join(', ') + ' ' + command.trailing);
715 },
716
717 RPL_LUSERCHANNELS: function (command) {
718 var params = _.clone(command.params);
719 params.shift();
720 genericNotice.call(this, command, params.join(', ') + ' ' + command.trailing);
721 },
722
723 RPL_LUSERME: function (command) {
724 var params = _.clone(command.params);
725 params.shift();
726 genericNotice.call(this, command, params.join(', ') + ' ' + command.trailing);
727 },
728
729 RPL_LOCALUSERS: function (command) {
730 var params = _.clone(command.params);
731 params.shift();
732 genericNotice.call(this, command, params.join(', ') + ' ' + command.trailing);
733 },
734
735 RPL_GLOBALUSERS: function (command) {
736 var params = _.clone(command.params);
737 params.shift();
738 genericNotice.call(this, command, params.join(', ') + ' ' + command.trailing);
a49e0dcf 739 }
a8bf3ea4 740};
cea1f25b
D
741
742
743
744
745function genericNotice (command, msg, is_error) {
746 // Default to being an error
747 if (typeof is_error !== 'boolean')
748 is_error = true;
749
750 this.client.sendIrcCommand('notice', {
751 server: this.con_num,
752 nick: command.prefix,
753 ident: '',
754 hostname: '',
755 target: command.params[0],
756 msg: msg,
757 numeric: parseInt(command.command, 10)
758 });
759}