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