Implements away-notify
[KiwiIRC.git] / server / irc / commands.js
1 var _ = require('underscore');
2
3 var irc_numerics = {
4 RPL_WELCOME: '001',
5 RPL_MYINFO: '004',
6 RPL_ISUPPORT: '005',
7 RPL_WHOISREGNICK: '307',
8 RPL_WHOISUSER: '311',
9 RPL_WHOISSERVER: '312',
10 RPL_WHOISOPERATOR: '313',
11 RPL_WHOISIDLE: '317',
12 RPL_ENDOFWHOIS: '318',
13 RPL_WHOISCHANNELS: '319',
14 RPL_LISTSTART: '321',
15 RPL_LIST: '322',
16 RPL_LISTEND: '323',
17 RPL_NOTOPIC: '331',
18 RPL_TOPIC: '332',
19 RPL_TOPICWHOTIME: '333',
20 RPL_NAMEREPLY: '353',
21 RPL_ENDOFNAMES: '366',
22 RPL_BANLIST: '367',
23 RPL_ENDOFBANLIST: '368',
24 RPL_MOTD: '372',
25 RPL_MOTDSTART: '375',
26 RPL_ENDOFMOTD: '376',
27 RPL_WHOISMODES: '379',
28 ERR_NOSUCHNICK: '401',
29 ERR_CANNOTSENDTOCHAN: '404',
30 ERR_TOOMANYCHANNELS: '405',
31 ERR_NICKNAMEINUSE: '433',
32 ERR_USERNOTINCHANNEL: '441',
33 ERR_NOTONCHANNEL: '442',
34 ERR_NOTREGISTERED: '451',
35 ERR_LINKCHANNEL: '470',
36 ERR_CHANNELISFULL: '471',
37 ERR_INVITEONLYCHAN: '473',
38 ERR_BANNEDFROMCHAN: '474',
39 ERR_BADCHANNELKEY: '475',
40 ERR_CHANOPRIVSNEEDED: '482',
41 RPL_STARTTLS: '670',
42 RPL_SASLAUTHENTICATED: '900',
43 RPL_SASLLOGGEDIN: '903',
44 ERR_SASLNOTAUTHORISED: '904',
45 ERR_SASLNOTAUTHORISED: '905',
46 ERR_SASLABORTED: '906',
47 ERR_SASLALREADYAUTHED: '907'
48
49 };
50
51
52 var IrcCommands = function (irc_connection, con_num, client) {
53 this.irc_connection = irc_connection;
54 this.con_num = con_num;
55 this.client = client;
56 };
57 module.exports = IrcCommands;
58
59 IrcCommands.prototype.bindEvents = function () {
60 var that = this;
61
62 _.each(listeners, function (listener, command) {
63 var s = command.substr(0, 4);
64 if ((s === 'RPL_') || (s === 'ERR_')) {
65 command = irc_numerics[command];
66 }
67 that.irc_connection.on('irc_' + command, function () {
68 listener.apply(that, arguments);
69 });
70 });
71 };
72
73 IrcCommands.prototype.dispose = function () {
74 this.removeAllListeners();
75 };
76
77
78
79 var listeners = {
80 'RPL_WELCOME': function (command) {
81 var nick = command.params[0];
82 this.irc_connection.registered = true;
83 this.cap_negotation = false;
84 this.client.sendIrcCommand('connect', {server: this.con_num, nick: nick});
85 },
86 'RPL_ISUPPORT': function (command) {
87 var options, i, option, matches, j;
88 options = command.params;
89 for (i = 1; i < options.length; i++) {
90 option = options[i].split("=", 2);
91 option[0] = option[0].toUpperCase();
92 this.irc_connection.options[option[0]] = (typeof option[1] !== 'undefined') ? option[1] : true;
93 if (_.include(['NETWORK', 'PREFIX', 'CHANTYPES', 'CHANMODES', 'NAMESX'], option[0])) {
94 if (option[0] === 'PREFIX') {
95 matches = /\(([^)]*)\)(.*)/.exec(option[1]);
96 if ((matches) && (matches.length === 3)) {
97 this.irc_connection.options.PREFIX = [];
98 for (j = 0; j < matches[2].length; j++) {
99 this.irc_connection.options.PREFIX.push({symbol: matches[2].charAt(j), mode: matches[1].charAt(j)});
100 }
101 }
102 } else if (option[0] === 'CHANTYPES') {
103 this.irc_connection.options.CHANTYPES = this.irc_connection.options.CHANTYPES.split('');
104 } else if (option[0] === 'CHANMODES') {
105 this.irc_connection.options.CHANMODES = option[1].split(',');
106 } else if ((option[0] === 'NAMESX') && (!_.contains(this.irc_connection.cap.enabled, 'multi-prefix'))) {
107 this.irc_connection.write('PROTOCTL NAMESX');
108 }
109 }
110 }
111 //this.client.sendIrcCommand({server: this.con_num, command: 'RPL_ISUPPORT', options: this.irc_connection.options});
112 //websocket.sendClientEvent('options', {server: '', "options": irc_connection.IRC.options});
113 this.client.sendIrcCommand('options', {server: this.con_num, options: this.irc_connection.options, cap: this.irc_connections.cap.enabled});
114 },
115 'RPL_ENDOFWHOIS': function (command) {
116 /*command.server = this.con_num;
117 command.command = 'RPL_ENDOFWHOIS';
118 this.client.sendIrcCommand(command);*/
119 //websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: true});
120 this.client.sendIrcCommand('whois', {server: this.con_num, nick: command.params[1], msg: command.trailing, end: true});
121 },
122 'RPL_WHOISUSER': function (command) {
123 /*command.server = this.con_num;
124 command.command = 'RPL_WHOISUSER';
125 this.client.sendIrcCommand(command);*/
126 //websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: false});
127 this.client.sendIrcCommand('whois', {server: this.con_num, nick: command.params[1], ident: command.params[2], host: command.params[3], msg: command.trailing, end: false});
128 },
129 'RPL_WHOISSERVER': function (command) {
130 /*command.server = this.con_num;
131 command.command = 'RPL_WHOISSERVER';
132 this.client.sendIrcCommand(command);*/
133 //websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: false});
134 this.client.sendIrcCommand('whois', {server: this.con_num, nick: command.params[1], irc_server: command.params[2], end: false});
135 },
136 'RPL_WHOISOPERATOR': function (command) {
137 /*command.server = this.con_num;
138 command.command = 'RPL_WHOISOPERATOR';
139 this.client.sendIrcCommand(command);*/
140 //websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: false});
141 this.client.sendIrcCommand('whois', {server: this.con_num, nick: command.params[1], msg: command.trailing, end: false});
142 },
143 'RPL_WHOISCHANNELS': function (command) {
144 /*command.server = this.con_num;
145 command.command = 'RPL_WHOISCHANNELS';
146 this.client.sendIrcCommand(command);*/
147 //websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: false});
148 this.client.sendIrcCommand('whois', {server: this.con_num, nick: command.params[1], chans: command.trailing, end: false});
149 },
150 'RPL_WHOISMODES': function (command) {
151 /*command.server = this.con_num;
152 command.command = 'RPL_WHOISMODES';
153 this.client.sendIrcCommand(command);*/
154 //websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: false});
155 this.client.sendIrcCommand('whois', {server: this.con_num, nick: command.params[1], msg: command.trailing, end: false});
156 },
157 'RPL_WHOISIDLE': function (command) {
158 /*command.server = this.con_num;
159 command.command = 'RPL_WHOISIDLE';
160 this.client.sendIrcCommand(command);*/
161 //websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: false});
162 if (command.params[3]) {
163 this.client.sendIrcCommand('whois', {server: this.con_num, nick: command.params[1], idle: command.params[2], logon: command.params[3], end: false});
164 } else {
165 this.client.sendIrcCommand('whois', {server: this.con_num, nick: command.params[1], idle: command.params[2], end: false});
166 }
167 },
168 'RPL_WHOISREGNICK': function (command) {
169 this.client.sendIrcCommand('whois', {server: this.con_num, nick: command.params[1], msg: command.trailing, end: false});
170 },
171 'RPL_LISTSTART': function (command) {
172 /*command.server = this.con_num;
173 command.command = 'RPL_LISTSTART';
174 this.client.sendIrcCommand(command);*/
175 this.client.sendIrcCommand('list_start', {server: this.con_num});
176 this.client.buffer.list = [];
177 },
178 'RPL_LISTEND': function (command) {
179 /*command.server = this.con_num;
180 command.command = 'RPL_LISTEND';
181 this.client.sendIrcCommand(command);*/
182 if (this.client.buffer.list.length > 0) {
183 this.client.buffer.list = _.sortBy(this.client.buffer.list, function (channel) {
184 return channel.num_users;
185 });
186 this.client.sendIrcCommand('list_channel', {server: this.con_num, chans: this.client.buffer.list});
187 this.client.buffer.list = [];
188 }
189 this.client.sendIrcCommand('list_end', {server: this.con_num});
190 },
191 'RPL_LIST': function (command) {
192 /*command.server = this.con_num;
193 command.command = 'RPL_LIST';
194 this.client.sendIrcCommand(command);*/
195 this.client.buffer.list.push({server: this.con_num, channel: command.params[1], num_users: parseInt(command.params[2], 10), topic: command.trailing});
196 if (this.client.buffer.list.length > 200){
197 this.client.buffer.list = _.sortBy(this.client.buffer.list, function (channel) {
198 return channel.num_users;
199 });
200 this.client.sendIrcCommand('list_channel', {server: this.con_num, chans: this.client.buffer.list});
201 this.client.buffer.list = [];
202 }
203 },
204 'RPL_MOTD': function (command) {
205 /*command.server = this.con_num;
206 command.command = 'RPL_MOTD';
207 this.client.sendIrcCommand(command);*/
208 this.client.buffer.motd += command.trailing + '\n';
209 },
210 'RPL_MOTDSTART': function (command) {
211 /*command.server = this.con_num;
212 command.command = 'RPL_MOTDSTART';
213 this.client.sendIrcCommand(command);*/
214 this.client.buffer.motd = '';
215 },
216 'RPL_ENDOFMOTD': function (command) {
217 /*command.server = this.con_num;
218 command.command = 'RPL_ENDOFMOTD';
219 this.client.sendIrcCommand(command);*/
220 //websocket.sendClientEvent('motd', {server: '', 'msg': websocket.kiwi.buffer.motd});
221 this.client.sendIrcCommand('motd', {server: this.con_num, msg: this.client.buffer.motd});
222 },
223 'RPL_NAMEREPLY': function (command) {
224 /*command.server = this.con_num;
225 command.command = 'RPL_NAMEREPLY';
226 this.client.sendIrcCommand(command);*/
227 var members = command.trailing.split(' ');
228 var member_list = [];
229 var that = this;
230 var i = 0;
231 _.each(members, function (member) {
232 var j, k, modes = [];
233 for (j = 0; j < member.length; j++) {
234 for (k = 0; k < that.irc_connection.options.PREFIX.length; k++) {
235 if (member.charAt(j) === that.irc_connection.options.PREFIX[k].symbol) {
236 modes.push(that.irc_connection.options.PREFIX[k].mode);
237 i++;
238 }
239 }
240 }
241 member_list.push({nick: member, modes: modes});
242 if (i++ >= 50) {
243 that.client.sendIrcCommand('userlist', {server: that.con_num, users: member_list, channel: command.params[2]});
244 member_list = [];
245 i = 0;
246 }
247 });
248 if (i > 0) {
249 this.client.sendIrcCommand('userlist', {server: this.con_num, users: member_list, channel: command.params[2]});
250 }
251 },
252 'RPL_ENDOFNAMES': function (command) {
253 /*command.server = this.con_num;
254 command.command = 'RPL_ENDOFNAMES';
255 this.client.sendIrcCommand(command);*/
256 //websocket.sendClientEvent('userlist_end', {server: '', channel: msg.params.split(" ")[1]});
257 this.client.sendIrcCommand('userlist_end', {server: this.con_num, channel: command.params[1]});
258 },
259 'RPL_BANLIST': function (command) {
260 /*command.server = this.con_num;
261 command.command = 'RPL_BANLIST';
262 this.client.sendIrcCommand(command);*/
263 //websocket.sendClientEvent('banlist', {server: '', channel: params[1], banned: params[2], banned_by: params[3], banned_at: params[4]});
264 this.client.sendIrcCommand('banlist', {server: this.con_num, channel: command.params[1], banned: command.params[2], banned_by: command.params[3], banned_at: command.params[4]});
265 },
266 'RPL_ENDOFBANLIST': function (command) {
267 /*command.server = this.con_num;
268 command.command = 'RPL_ENDOFBANLIST';
269 this.client.sendIrcCommand(command);*/
270 //websocket.sendClientEvent('banlist_end', {server: '', channel: msg.params.split(" ")[1]});
271 this.client.sendIrcCommand('banlist_end', {server: this.con_num, channel: command.params[1]});
272 },
273 'RPL_TOPIC': function (command) {
274 /*command.server = this.con_num;
275 command.command = 'RPL_TOPIC';
276 this.client.sendIrcCommand(command);*/
277 //{nick: '', channel: msg.params.split(" ")[1], topic: msg.trailing};
278 this.client.sendIrcCommand('topic', {server: this.con_num, nick: '', channel: command.params[1], topic: command.trailing});
279 },
280 'RPL_NOTOPIC': function (command) {
281 /*command.server = this.con_num;
282 command.command = 'RPL_NOTOPIC';
283 this.client.sendIrcCommand(command);*/
284 this.client.sendIrcCommand('topic', {server: this.con_num, nick: '', channel: command.params[1], topic: ''});
285 },
286 'RPL_TOPICWHOTIME': function (command) {
287 /*command.server = this.con_num;
288 command.command = 'RPL_TOPICWHOTIME';
289 this.client.sendIrcCommand(command);*/
290 //{nick: nick, channel: channel, when: when};
291 this.client.sendIrcCommand('topicsetby', {server: this.con_num, nick: command.params[2], channel: command.params[1], when: command.params[3]});
292 },
293 'PING': function (command) {
294 this.irc_connection.write('PONG ' + command.trailing);
295 },
296 'JOIN': function (command) {
297 var channel;
298 if (typeof command.trailing === 'string' && command.trailing !== '') {
299 channel = command.trailing;
300 } else if (typeof command.params[0] === 'string' && command.params[0] !== '') {
301 channel = command.params[0];
302 }
303 /*command.server = this.con_num;
304 command.command = 'JOIN';
305 command.params = [channel];
306 this.client.sendIrcCommand(command);*/
307 //websocket.sendClientEvent('join', {nick: msg.nick, ident: msg.ident, hostname: msg.hostname, channel: channel});
308 this.client.sendIrcCommand('join', {server: this.con_num, nick: command.nick, ident: command.ident, hostname: command.hostname, channel: channel});
309
310 if (command.nick === this.nick) {
311 this.irc_connection.write('NAMES ' + channel);
312 }
313 },
314 'PART': function (command) {
315 /*command.server = this.con_num;
316 command.command = 'PART';
317 this.client.sendIrcCommand(command);*/
318 //websocket.sendClientEvent('part', {nick: msg.nick, ident: msg.ident, hostname: msg.hostname, channel: msg.params.trim(), message: msg.trailing});
319 this.client.sendIrcCommand('part', {server: this.con_num, nick: command.nick, ident: command.ident, hostname: command.hostname, channel: command.params[0], message: command.trailing});
320 },
321 'KICK': function (command) {
322 /*command.server = this.con_num;
323 command.command = 'KICK';
324 this.client.sendIrcCommand(command);*/
325 //websocket.sendClientEvent('kick', {kicked: params[1], nick: msg.nick, ident: msg.ident, hostname: msg.hostname, channel: params[0].trim(), message: msg.trailing});
326 this.client.sendIrcCommand('kick', {server: this.con_num, kicked: command.params[1], nick: command.nick, ident: command.ident, hostname: command.hostname, channel: command.params[0], message: command.trailing});
327 },
328 'QUIT': function (command) {
329 /*command.server = this.con_num;
330 command.command = 'QUIT';
331 this.client.sendIrcCommand(command);*/
332 //websocket.sendClientEvent('quit', {nick: msg.nick, ident: msg.ident, hostname: msg.hostname, message: msg.trailing});
333 this.client.sendIrcCommand('quit', {server: this.con_num, nick: command.nick, ident: command.ident, hostname: command.hostname, message: command.trailing});
334 },
335 'NOTICE': function (command) {
336 /*command.server = this.con_num;
337 command.command = 'NOTICE';
338 this.client.sendIrcCommand(command);*/
339 if ((command.trailing.charAt(0) === String.fromCharCode(1)) && (command.trailing.charAt(command.trailing.length - 1) === String.fromCharCode(1))) {
340 // It's a CTCP response
341 //websocket.sendClientEvent('ctcp_response', {nick: msg.nick, ident: msg.ident, hostname: msg.hostname, channel: msg.params.trim(), msg: msg.trailing.substr(1, msg.trailing.length - 2)});
342 this.client.sendIrcCommand('ctcp_response', {server: this.con_num, nick: command.nick, ident: command.ident, hostname: command.hostname, channel: command.params[0], msg: command.trailing.substr(1, command.trailing.length - 2)});
343 } else {
344 //websocket.sendClientEvent('notice', {nick: msg.nick, ident: msg.ident, hostname: msg.hostname, target: msg.params.trim(), msg: msg.trailing});
345 this.client.sendIrcCommand('notice', {server: this.con_num, nick: command.nick, ident: command.ident, hostname: command.hostname, target: command.params[0], msg: command.trailing});
346 }
347 },
348 'NICK': function (command) {
349 /*command.server = this.con_num;
350 command.command = 'NICK';
351 this.client.sendIrcCommand(command);*/
352 //websocket.sendClientEvent('nick', {nick: msg.nick, ident: msg.ident, hostname: msg.hostname, newnick: msg.trailing});
353 this.client.sendIrcCommand('nick', {server: this.con_num, nick: command.nick, ident: command.ident, hostname: command.hostname, newnick: command.trailing});
354 },
355 'TOPIC': function (command) {
356 /*command.server = this.con_num;
357 command.command = 'TOPIC';
358 this.client.sendIrcCommand(command);*/
359 //{nick: msg.nick, channel: msg.params, topic: msg.trailing};
360 this.client.sendIrcCommand('topic', {server: this.con_num, nick: command.nick, channel: command.params[0], topic: command.trailing});
361 },
362 'MODE': function (command) {
363 var chanmodes = this.irc_connection.options.CHANMODES,
364 prefixes = this.irc_connection.options.PREFIX,
365 always_param = chanmodes[0].concat(chanmodes[1]),
366 modes = [],
367 has_param, i, j, add;
368
369 prefixes = _.reduce(prefixes, function (list, prefix) {
370 list.push(prefix.mode);
371 return list;
372 }, []);
373 always_param = always_param.split('').concat(prefixes);
374
375 has_param = function (mode, add) {
376 if (_.find(always_param, function (m) {
377 return m === mode;
378 })) {
379 return true;
380 } else if (add && _.find(chanmodes[2].split(''), function (m) {
381 return m === mode;
382 })) {
383 return true;
384 } else {
385 return false;
386 }
387 };
388
389 if (!command.params[1]) {
390 command.params[1] = command.trailing;
391 }
392 j = 0;
393 for (i = 0; i < command.params[1].length; i++) {
394 switch (command.params[1][i]) {
395 case '+':
396 add = true;
397 break;
398 case '-':
399 add = false;
400 break;
401 default:
402 if (has_param(command.params[1][i], add)) {
403 modes.push({mode: (add ? '+' : '-') + command.params[1][i], param: command.params[2 + j]});
404 j++;
405 } else {
406 modes.push({mode: (add ? '+' : '-') + command.params[1][i], param: null});
407 }
408 }
409 }
410
411 this.client.sendIrcCommand('mode', {
412 server: this.con_num,
413 target: command.params[0],
414 nick: command.nick || command.prefix || '',
415 modes: modes
416 });
417 },
418 'PRIVMSG': function (command) {
419 /*command.server = this.con_num;
420 command.command = 'PRIVMSG';
421 this.client.sendIrcCommand(command);*/
422 var tmp, namespace;
423 if ((command.trailing.charAt(0) === String.fromCharCode(1)) && (command.trailing.charAt(command.trailing.length - 1) === String.fromCharCode(1))) {
424 //CTCP request
425 if (command.trailing.substr(1, 6) === 'ACTION') {
426 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)});
427 } else if (command.trailing.substr(1, 4) === 'KIWI') {
428 tmp = command.trailing.substr(6, command.trailing.length - 2);
429 namespace = tmp.split(' ', 1)[0];
430 this.client.sendIrcCommand('kiwi', {server: this.con_num, namespace: namespace, data: tmp.substr(namespace.length + 1)});
431 } else if (command.trailing.substr(1, 7) === 'VERSION') {
432 this.irc_connection.write('NOTICE ' + command.nick + ' :' + String.fromCharCode(1) + 'VERSION KiwiIRC' + String.fromCharCode(1));
433 } else {
434 this.client.sendIrcCommand('ctcp_request', {server: this.con_num, nick: command.nick, ident: command.ident, hostname: command.hostname, channel: command.params[0], msg: command.trailing.substr(1, command.trailing.length - 2)});
435 }
436 } else {
437 //{nick: msg.nick, ident: msg.ident, hostname: msg.hostname, channel: msg.params.trim(), msg: msg.trailing}
438 this.client.sendIrcCommand('msg', {server: this.con_num, nick: command.nick, ident: command.ident, hostname: command.hostname, channel: command.params[0], msg: command.trailing});
439 }
440 },
441 'CAP': function (command) {
442 // TODO: capability modifiers
443 // i.e. - for disable, ~ for requires ACK, = for sticky
444 var capabilities = command.trailing.replace(/[\-~=]/, '').split(' ');
445 var request;
446 var want = ['multi-prefix', 'away-notify'];
447
448 if (this.irc_connection.password) {
449 want.push('sasl');
450 }
451
452 switch (command.params[1]) {
453 case 'LS':
454 request = _.intersection(capabilities, want);
455 if (request.length > 0) {
456 this.irc_connection.cap.requested = request;
457 this.irc_connection.write('CAP REQ :' + request.join(' '));
458 } else {
459 this.irc_connection.write('CAP END');
460 this.irc_connection.cap_negotation = false;
461 this.irc_connection.register();
462 }
463 break;
464 case 'ACK':
465 if (capabilities.length > 0) {
466 this.irc_connection.cap.enabled = capabilities;
467 this.irc_connection.cap.requested = _.difference(this.irc_connection.cap.requested, capabilities);
468 }
469 if (this.irc_connection.cap.requested.length > 0) {
470 if (_.contains(this.irc_connection.cap.enabled, 'sasl')) {
471 this.irc_connection.sasl = true;
472 this.irc_connection.write('AUTHENTICATE PLAIN');
473 } else {
474 this.irc_connection.write('CAP END');
475 this.irc_connection.cap_negotation = false;
476 this.irc_connection.register();
477 }
478 }
479 break;
480 case 'NAK':
481 if (capabilities.length > 0) {
482 this.irc_connection.cap.requested = _.difference(this.irc_connection.cap.requested, capabilities);
483 }
484 if (this.irc_connection.cap.requested.length > 0) {
485 this.irc_connection.write('CAP END');
486 this.irc_connection.cap_negotation = false;
487 this.irc_connection.register();
488 }
489 break;
490 case 'LIST':
491 // should we do anything here?
492 break;
493 }
494 },
495 'AUTHENTICATE': function (command) {
496 var b = new Buffer(this.irc_connection.nick + "\0" + this.irc_connection.nick + "\0" + this.irc_connection.password, 'utf8');
497 var b64 = b.toString('base64');
498 if (command.params[0] === '+') {
499 while (b64.length >= 400) {
500 this.irc_connection.write('AUTHENTICATE ' + b64.slice(0, 399));
501 b64 = b64.slice(399);
502 }
503 if (b64.length > 0) {
504 this.irc_connection.write('AUTHENTICATE ' + b64);
505 } else {
506 this.irc_connection.write('AUTHENTICATE +');
507 }
508 } else {
509 this.irc_connection.write('CAP END');
510 this.irc_connection.cap_negotation = false;
511 this.irc_connection.register();
512 }
513 },
514 'AWAY': function (command) {
515 this.client.sendIrcCommand('away', {server: this.con_num, nick: command.nick, msg: command.trailing});
516 },
517 'RPL_SASLAUTHENTICATED':function (command) {
518 this.irc_connection.write('CAP END');
519 this.irc_connection.cap_negotation = false;
520 this.irc_connection.sasl = true;
521 this.irc_connection.register();
522 },
523 'RPL_SASLLOGGEDIN': function (command) {
524 // noop
525 },
526 'ERR_SASLNOTAUTHORISED':function (command) {
527 this.irc_connection.write('CAP END');
528 this.irc_connection.cap_negotation = false;
529 this.irc_connection.register();
530 },
531 'ERR_SASLABORTED': function (command) {
532 // noop
533 },
534 'ERR_SASLALREADYAUTHED':function (command) {
535 // noop
536 },
537 'ERROR': function (command) {
538 /*command.server = this.con_num;
539 command.command = 'ERROR';
540 this.client.sendIrcCommand(command);*/
541 //websocket.sendClientEvent('irc_error', {error: 'error', reason: msg.trailing});
542 this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'error', reason: command.trailing});
543 },
544 ERR_LINKCHANNEL: function (command) {
545 /*command.server = this.con_num;
546 command.command = 'ERR_LINKCHANNEL';
547 this.client.sendIrcCommand(command);*/
548 //websocket.sendClientEvent('channel_redirect', {from: params[1], to: params[2]});
549 this.client.sendIrcCommand('channel_redirect', {server: this.con_num, from: command.params[1], to: command.params[2]});
550 },
551 ERR_NOSUCHNICK: function (command) {
552 /*command.server = this.con_num;
553 command.command = 'ERR_NOSUCHNICK';
554 this.client.sendIrcCommand(command);*/
555 //websocket.sendClientEvent('irc_error', {error: 'no_such_nick', nick: msg.params.split(" ")[1], reason: msg.trailing});
556 this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'no_such_nick', nick: command.params[1], reason: command.trailing});
557 },
558 ERR_CANNOTSENDTOCHAN: function (command) {
559 /*command.server = this.con_num;
560 command.command = 'ERR_CANNOTSENDTOCHAN';
561 this.client.sendIrcCommand(command);*/
562 //websocket.sendClientEvent('irc_error', {error: 'cannot_send_to_chan', channel: msg.params.split(" ")[1], reason: msg.trailing});
563 this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'cannot_send_to_chan', channel: command.params[1], reason: command.trailing});
564 },
565 ERR_TOOMANYCHANNELS: function (command) {
566 /*command.server = this.con_num;
567 command.command = 'ERR_TOOMANYCHANNELS';
568 this.client.sendIrcCommand(command);*/
569 //websocket.sendClientEvent('irc_error', {error: 'too_many_channels', channel: msg.params.split(" ")[1], reason: msg.trailing});
570 this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'too_many_channels', channel: command.params[1], reason: command.trailing});
571 },
572 ERR_USERNOTINCHANNEL: function (command) {
573 /*command.server = this.con_num;
574 command.command = 'ERR_USERNOTINCHANNEL';
575 this.client.sendIrcCommand(command);*/
576 //websocket.sendClientEvent('irc_error', {error: 'user_not_in_channel', nick: params[0], channel: params[1], reason: msg.trainling});
577 this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'user_not_in_channel', nick: command.params[0], channel: command.params[1], reason: command.trailing});
578 },
579 ERR_NOTONCHANNEL: function (command) {
580 /*command.server = this.con_num;
581 command.command = 'ERR_NOTONCHANNEL';
582 this.client.sendIrcCommand(command);*/
583 //websocket.sendClientEvent('irc_error', {error: 'not_on_channel', channel: msg.params.split(" ")[1], reason: msg.trailing});
584 this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'not_on_channel', channel: command.params[1], reason: command.trailing});
585 },
586 ERR_CHANNELISFULL: function (command) {
587 /*command.server = this.con_num;
588 command.command = 'ERR_CHANNELISFULL';
589 this.client.sendIrcCommand(command);*/
590 //websocket.sendClientEvent('irc_error', {error: 'channel_is_full', channel: msg.params.split(" ")[1], reason: msg.trailing});
591 this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'channel_is_full', channel: command.params[1], reason: command.trailing});
592 },
593 ERR_INVITEONLYCHAN: function (command) {
594 /*command.server = this.con_num;
595 command.command = 'ERR_INVITEONLYCHAN';
596 this.client.sendIrcCommand(command);*/
597 //websocket.sendClientEvent('irc_error', {error: 'invite_only_channel', channel: msg.params.split(" ")[1], reason: msg.trailing});
598 this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'invite_only_channel', channel: command.params[1], reason: command.trailing});
599 },
600 ERR_BANNEDFROMCHAN: function (command) {
601 /*command.server = this.con_num;
602 command.command = 'ERR_BANNEDFROMCHAN';
603 this.client.sendIrcCommand(command);*/
604 //websocket.sendClientEvent('irc_error', {error: 'banned_from_channel', channel: msg.params.split(" ")[1], reason: msg.trailing});
605 this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'banned_from_channel', channel: command.params[1], reason: command.trailing});
606 },
607 ERR_BADCHANNELKEY: function (command) {
608 /*command.server = this.con_num;
609 command.command = 'ERR_BADCHANNELKEY';
610 this.client.sendIrcCommand(command);*/
611 //websocket.sendClientEvent('irc_error', {error: 'bad_channel_key', channel: msg.params.split(" ")[1], reason: msg.trailing});
612 this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'bad_channel_key', channel: command.params[1], reason: command.trailing});
613 },
614 ERR_CHANOPRIVSNEEDED: function (command) {
615 /*command.server = this.con_num;
616 command.command = 'ERR_CHANOPRIVSNEEDED';
617 this.client.sendIrcCommand(command);*/
618 //websocket.sendClientEvent('irc_error', {error: 'chanop_privs_needed', channel: msg.params.split(" ")[1], reason: msg.trailing});
619 this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'chanop_privs_needed', channel: command.params[1], reason: command.trailing});
620 },
621 ERR_NICKNAMEINUSE: function (command) {
622 /*command.server = this.con_num;
623 command.command = 'ERR_NICKNAMEINUSE';
624 this.client.sendIrcCommand(command);*/
625 //websocket.sendClientEvent('irc_error', {error: 'nickname_in_use', nick: _.last(msg.params.split(" ")), reason: msg.trailing});
626 this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'nickname_in_use', nick: command.params[1], reason: command.trailing});
627 },
628 ERR_NOTREGISTERED: function (command) {
629 /*command.server = this.con_num;
630 command.command = 'ERR_NOTREGISTERED';
631 this.client.sendIrcCommand(command);*/
632 }
633 };