ERR_PASSWORDMISMATCH; IrcServer disposing
[KiwiIRC.git] / server / irc / commands.js
1 var _ = require('lodash');
2
3 var irc_numerics = {
4 RPL_WELCOME: '001',
5 RPL_MYINFO: '004',
6 RPL_ISUPPORT: '005',
7 RPL_MAPMORE: '006',
8 RPL_MAPEND: '007',
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',
17 RPL_WHOISREGNICK: '307',
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',
31 RPL_LINKS: '364',
32 RPL_ENDOFLINKS: '365',
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',
43 ERR_UNKNOWNCOMMAND: '421',
44 ERR_NOMOTD: '422',
45 ERR_NICKNAMEINUSE: '433',
46 ERR_USERNOTINCHANNEL: '441',
47 ERR_NOTONCHANNEL: '442',
48 ERR_PASSWDMISMATCH: '464',
49 ERR_NOTREGISTERED: '451',
50 ERR_LINKCHANNEL: '470',
51 ERR_CHANNELISFULL: '471',
52 ERR_INVITEONLYCHAN: '473',
53 ERR_BANNEDFROMCHAN: '474',
54 ERR_BADCHANNELKEY: '475',
55 ERR_NOPRIVILEGES: '481',
56 ERR_CHANOPRIVSNEEDED: '482',
57 RPL_STARTTLS: '670',
58 RPL_SASLAUTHENTICATED: '900',
59 RPL_SASLLOGGEDIN: '903',
60 ERR_SASLNOTAUTHORISED: '904',
61 ERR_SASLABORTED: '906',
62 ERR_SASLALREADYAUTHED: '907'
63
64 };
65
66
67 var IrcCommands = function (irc_connection, con_num, client) {
68 this.irc_connection = irc_connection;
69 this.con_num = con_num;
70 this.client = client;
71 };
72 module.exports = IrcCommands;
73
74 IrcCommands.prototype.bindEvents = function () {
75 var that = this;
76
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
88 IrcCommands.prototype.dispose = function () {
89 this.removeAllListeners();
90 };
91
92
93
94 var listeners = {
95 'RPL_WELCOME': function (command) {
96 var nick = command.params[0];
97 this.irc_connection.registered = true;
98 this.cap_negotation = false;
99 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':connect', {
100 nick: nick
101 });
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)});
117 }
118 }
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');
125 }
126 }
127 }
128 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':options', {
129 options: this.irc_connection.options,
130 cap: this.irc_connection.cap.enabled
131 });
132 },
133 'RPL_ENDOFWHOIS': function (command) {
134 this.irc_connection.emit('user:' + command.params[1] + ':endofwhois', {
135 nick: command.params[1],
136 msg: command.trailing
137 });
138 },
139 'RPL_WHOISUSER': function (command) {
140 this.irc_connection.emit('user:' + command.params[1] + ':whoisuser', {
141 nick: command.params[1],
142 ident: command.params[2],
143 host: command.params[3],
144 msg: command.trailing
145 });
146 },
147 'RPL_WHOISSERVER': function (command) {
148 this.irc_connection.emit('user:' + command.params[1] + ':whoisserver', {
149 nick: command.params[1],
150 irc_server: command.params[2]
151 });
152 },
153 'RPL_WHOISOPERATOR': function (command) {
154 this.irc_connection.emit('user:' + command.params[1] + ':whoisoperator', {
155 nick: command.params[1],
156 msg: command.trailing
157 });
158 },
159 'RPL_WHOISCHANNELS': function (command) {
160 this.irc_connection.emit('user:' + command.params[1] + ':whoischannels', {
161 nick: command.params[1],
162 chans: command.trailing
163 });
164 },
165 'RPL_WHOISMODES': function (command) {
166 this.irc_connection.emit('user:' + command.params[1] + ':whoismodes', {
167 nick: command.params[1],
168 msg: command.trailing
169 });
170 },
171 'RPL_WHOISIDLE': function (command) {
172 this.irc_connection.emit('user:' + command.params[1] + ':whoisidle', {
173 nick: command.params[1],
174 idle: command.params[2],
175 logon: command.params[3] || undefined
176 });
177 },
178 'RPL_WHOISREGNICK': function (command) {
179 this.irc_connection.emit('user:' + command.params[1] + ':whoisregnick', {
180 nick: command.params[1],
181 msg: command.trailing
182 });
183 },
184 'RPL_LISTSTART': function (command) {
185 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':list_start', {});
186 },
187 'RPL_LISTEND': function (command) {
188 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':list_end', {});
189 },
190 'RPL_LIST': function (command) {
191 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':list_channel', {
192 channel: command.params[1],
193 num_users: parseInt(command.params[2], 10),
194 topic: command.trailing
195 });
196 },
197 'RPL_MOTD': function (command) {
198 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':motd', {
199 motd: command.trailing + '\n'
200 });
201 },
202 'RPL_MOTDSTART': function (command) {
203 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':motd_start', {});
204 },
205 'RPL_ENDOFMOTD': function (command) {
206 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':motd_end', {});
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 = [];
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 }
224 }
225 }
226 }
227
228 member_list.push({nick: member, modes: modes});
229 });
230
231 this.irc_connection.emit('channel:' + command.params[2] + ':userlist', {
232 users: member_list,
233 channel: command.params[2]
234 });
235 },
236
237
238 'RPL_ENDOFNAMES': function (command) {
239 this.irc_connection.emit('channel:' + command.params[1] + ':userlist_end', {
240 channel: command.params[1]
241 });
242 },
243
244
245 'RPL_BANLIST': function (command) {
246 this.irc_connection.emit('channel:' + command.params[1] + ':banlist', {
247 channel: command.params[1],
248 banned: command.params[2],
249 banned_by: command.params[3],
250 banned_at: command.params[4]
251 });
252 },
253 'RPL_ENDOFBANLIST': function (command) {
254 this.irc_connection.emit('channel:' + command.params[1] + ':banlist_end', {
255 channel: commands.params[1]
256 });
257 },
258 'RPL_TOPIC': function (command) {
259 this.irc_connection.emit('channel:' + command.params[1] + ':topic', {
260 channel: command.params[1],
261 topic: command.trailing
262 });
263 },
264 'RPL_NOTOPIC': function (command) {
265 this.irc_connection.emit('channel:' + command.params[1] + ':topic', {
266 channel: command.params[1],
267 topic: ''
268 });
269 },
270 'RPL_TOPICWHOTIME': function (command) {
271 this.irc_connection.emit('channel:' + command.params[1] + ':topicsetby', {
272 nick: command.params[2],
273 channel: command.params[1],
274 when: command.params[3]
275 });
276 },
277 'PING': function (command) {
278 this.irc_connection.write('PONG ' + command.trailing);
279 },
280
281
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
290 this.irc_connection.emit('channel:' + channel + ':join', {
291 nick: command.nick,
292 ident: command.ident,
293 hostname: command.hostname,
294 channel: channel
295 });
296 },
297
298
299 'PART': function (command) {
300 this.irc_connection.emit('channel:' + command.params[0] + ':part', {
301 nick: command.nick,
302 ident: command.ident,
303 hostname: command.hostname,
304 channel: command.params[0],
305 message: command.trailing
306 });
307 },
308
309
310 'KICK': function (command) {
311 this.irc_connection.emit('channel:' + command.params[0] + ':kick', {
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 });
319 },
320
321
322 'QUIT': function (command) {
323 this.irc_connection.emit('user:' + command.nick + ':quit', {
324 nick: command.nick,
325 ident: command.ident,
326 hostname: command.hostname,
327 message: command.trailing
328 });
329 },
330
331
332 'NOTICE': function (command) {
333 var namespace;
334
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
337 namespace = (command.params[0] == this.irc_connection.nick) ? 'user' : 'channel';
338 this.irc_connection.emit(namespace + ':' + command.params[0] + ':ctcp_response', {
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 });
345 } else {
346 namespace = (command.params[0] == this.irc_connection.nick) ? 'user' : 'channel';
347 this.irc_connection.emit(namespace + ':' + command.params[0] + ':notice', {
348 nick: command.nick,
349 ident: command.ident,
350 hostname: command.hostname,
351 target: command.params[0],
352 msg: command.trailing
353 });
354 }
355 },
356 'NICK': function (command) {
357 this.irc_connection.emit('user:' + command.nick + ':nick', {
358 nick: command.nick,
359 ident: command.ident,
360 hostname: command.hostname,
361 newnick: command.trailing || command.params[0]
362 });
363 },
364 'TOPIC': function (command) {
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
371 this.irc_connection.emit('channel:' + channel + ':topic', {
372 nick: command.nick,
373 channel: channel,
374 topic: topic
375 });
376 },
377 'MODE': function (command) {
378 var chanmodes = this.irc_connection.options.CHANMODES || [],
379 prefixes = this.irc_connection.options.PREFIX || [],
380 always_param = (chanmodes[0] || '').concat((chanmodes[1] || '')),
381 modes = [],
382 has_param, i, j, add, event;
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;
395 } else if (add && _.find((chanmodes[2] || '').split(''), function (m) {
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++;
420 } else {
421 modes.push({mode: (add ? '+' : '-') + command.params[1][i], param: null});
422 }
423 }
424 }
425
426 event = (_.contains(this.irc_connection.options.CHANTYPES, command.params[0][0]) ? 'channel:' : 'user:') + command.params[0] + ':mode';
427
428 this.irc_connection.emit(event, {
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));
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));
450 } else {
451 namespace = (command.params[0].toLowerCase() == this.irc_connection.nick.toLowerCase()) ? 'user' : 'channel';
452 this.irc_connection.emit(namespace + ':' + command.nick + ':ctcp_request', {
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 });
460 }
461 } else {
462 // A message to a user (private message) or to a channel?
463 namespace = (command.params[0] === this.irc_connection.nick) ? 'user:' + command.nick : 'channel:' + command.params[0];
464 this.irc_connection.emit(namespace + ':privmsg', {
465 nick: command.nick,
466 ident: command.ident,
467 hostname: command.hostname,
468 channel: command.params[0],
469 msg: command.trailing
470 });
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;
493 }
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);
499 }
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');
504 } else {
505 this.irc_connection.write('CAP END');
506 this.irc_connection.cap_negotation = false;
507 }
508 }
509 break;
510 case 'NAK':
511 if (capabilities.length > 0) {
512 this.irc_connection.cap.requested = _.difference(this.irc_connection.cap.requested, capabilities);
513 }
514 if (this.irc_connection.cap.requested.length > 0) {
515 this.irc_connection.write('CAP END');
516 this.irc_connection.cap_negotation = false;
517 }
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);
531 }
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) {
543 this.irc_connection.emit('user:' + command.nick + ':away', {
544 nick: command.nick,
545 msg: command.trailing
546 });
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) {
570 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':error', {
571 reason: command.trailing
572 });
573 },
574 ERR_PASSWDMISMATCH: function (command) {
575 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':password_mismatch', {});
576 },
577 ERR_LINKCHANNEL: function (command) {
578 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':channel_redirect', {
579 from: command.params[1],
580 to: command.params[2]
581 });
582 },
583 ERR_NOSUCHNICK: function (command) {
584 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':no_such_nick', {
585 nick: command.params[1],
586 reason: command.trailing
587 });
588 },
589 ERR_CANNOTSENDTOCHAN: function (command) {
590 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':cannot_send_to_chan', {
591 channel: command.params[1],
592 reason: command.trailing
593 });
594 },
595 ERR_TOOMANYCHANNELS: function (command) {
596 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':too_many_channels', {
597 channel: command.params[1],
598 reason: command.trailing
599 });
600 },
601 ERR_USERNOTINCHANNEL: function (command) {
602 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':user_not_in_channel', {
603 nick: command.params[0],
604 channel: command.params[1],
605 reason: command.trailing
606 });
607 },
608 ERR_NOTONCHANNEL: function (command) {
609 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':not_on_channel', {
610 channel: command.params[1],
611 reason: command.trailing
612 });
613 },
614 ERR_CHANNELISFULL: function (command) {
615 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':channel_is_full', {
616 channel: command.params[1],
617 reason: command.trailing
618 });
619 },
620 ERR_INVITEONLYCHAN: function (command) {
621 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':invite_only_channel', {
622 channel: command.params[1],
623 reason: command.trailing
624 });
625 },
626 ERR_BANNEDFROMCHAN: function (command) {
627 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':banned_from_channel', {
628 channel: command.params[1],
629 reason: command.trailing
630 });
631 },
632 ERR_BADCHANNELKEY: function (command) {
633 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':bad_channel_key', {
634 channel: command.params[1],
635 reason: command.trailing
636 });
637 },
638 ERR_CHANOPRIVSNEEDED: function (command) {
639 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':chanop_privs_needed', {
640 channel: command.params[1],
641 reason: command.trailing
642 });
643 },
644 ERR_NICKNAMEINUSE: function (command) {
645 this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':nickname_in_use', {
646 nick: command.params[1],
647 reason: command.trailing
648 });
649 },
650 ERR_NOTREGISTERED: function (command) {
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);
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);
739 }
740 };
741
742
743
744
745 function 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 }