Commit | Line | Data |
---|---|---|
a8bf3ea4 JA |
1 | var _ = require('underscore'); |
2 | ||
3 | var irc_numerics = { | |
4 | RPL_WELCOME: '001', | |
5 | RPL_MYINFO: '004', | |
6 | RPL_ISUPPORT: '005', | |
f3766a0b | 7 | RPL_WHOISREGNICK: '307', |
a8bf3ea4 JA |
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', | |
7dfe47c6 JA |
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 | ||
a8bf3ea4 JA |
49 | }; |
50 | ||
51 | ||
2a8e95d1 | 52 | var IrcCommands = function (irc_connection, con_num, client) { |
a8bf3ea4 JA |
53 | this.irc_connection = irc_connection; |
54 | this.con_num = con_num; | |
55 | this.client = client; | |
56 | }; | |
2a8e95d1 | 57 | module.exports = IrcCommands; |
a8bf3ea4 | 58 | |
2a8e95d1 | 59 | IrcCommands.prototype.bindEvents = function () { |
a8bf3ea4 | 60 | var that = this; |
2a8e95d1 | 61 | |
a8bf3ea4 JA |
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 | ||
c08717da D |
73 | IrcCommands.prototype.dispose = function () { |
74 | this.removeAllListeners(); | |
75 | }; | |
76 | ||
2a8e95d1 D |
77 | |
78 | ||
a8bf3ea4 JA |
79 | var listeners = { |
80 | 'RPL_WELCOME': function (command) { | |
81 | var nick = command.params[0]; | |
82 | this.irc_connection.registered = true; | |
eec8c71e | 83 | this.cap_negotation = false; |
2f1e8a71 | 84 | this.client.sendIrcCommand('connect', {server: this.con_num, nick: nick}); |
a8bf3ea4 JA |
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(','); | |
eec8c71e | 106 | } else if ((option[0] === 'NAMESX') && (!_.contains(this.irc_connection.cap.enabled, 'multi-prefix'))) { |
b8e4d9f7 | 107 | this.irc_connection.write('PROTOCTL NAMESX'); |
a8bf3ea4 JA |
108 | } |
109 | } | |
110 | } | |
2f1e8a71 | 111 | //this.client.sendIrcCommand({server: this.con_num, command: 'RPL_ISUPPORT', options: this.irc_connection.options}); |
a8bf3ea4 | 112 | //websocket.sendClientEvent('options', {server: '', "options": irc_connection.IRC.options}); |
2f1e8a71 | 113 | this.client.sendIrcCommand('options', {server: this.con_num, options: this.irc_connection.options}); |
a8bf3ea4 JA |
114 | }, |
115 | 'RPL_ENDOFWHOIS': function (command) { | |
116 | /*command.server = this.con_num; | |
117 | command.command = 'RPL_ENDOFWHOIS'; | |
2f1e8a71 | 118 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 119 | //websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: true}); |
2f1e8a71 | 120 | this.client.sendIrcCommand('whois', {server: this.con_num, nick: command.params[1], msg: command.trailing, end: true}); |
a8bf3ea4 JA |
121 | }, |
122 | 'RPL_WHOISUSER': function (command) { | |
123 | /*command.server = this.con_num; | |
124 | command.command = 'RPL_WHOISUSER'; | |
2f1e8a71 | 125 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 126 | //websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: false}); |
2f1e8a71 | 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}); |
a8bf3ea4 JA |
128 | }, |
129 | 'RPL_WHOISSERVER': function (command) { | |
130 | /*command.server = this.con_num; | |
131 | command.command = 'RPL_WHOISSERVER'; | |
2f1e8a71 | 132 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 133 | //websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: false}); |
0cfbecfc | 134 | this.client.sendIrcCommand('whois', {server: this.con_num, nick: command.params[1], irc_server: command.params[2], end: false}); |
a8bf3ea4 JA |
135 | }, |
136 | 'RPL_WHOISOPERATOR': function (command) { | |
137 | /*command.server = this.con_num; | |
138 | command.command = 'RPL_WHOISOPERATOR'; | |
2f1e8a71 | 139 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 140 | //websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: false}); |
2f1e8a71 | 141 | this.client.sendIrcCommand('whois', {server: this.con_num, nick: command.params[1], msg: command.trailing, end: false}); |
a8bf3ea4 JA |
142 | }, |
143 | 'RPL_WHOISCHANNELS': function (command) { | |
144 | /*command.server = this.con_num; | |
145 | command.command = 'RPL_WHOISCHANNELS'; | |
2f1e8a71 | 146 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 147 | //websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: false}); |
2f1e8a71 | 148 | this.client.sendIrcCommand('whois', {server: this.con_num, nick: command.params[1], chans: command.trailing, end: false}); |
a8bf3ea4 JA |
149 | }, |
150 | 'RPL_WHOISMODES': function (command) { | |
151 | /*command.server = this.con_num; | |
152 | command.command = 'RPL_WHOISMODES'; | |
2f1e8a71 | 153 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 154 | //websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: false}); |
2f1e8a71 | 155 | this.client.sendIrcCommand('whois', {server: this.con_num, nick: command.params[1], msg: command.trailing, end: false}); |
a8bf3ea4 JA |
156 | }, |
157 | 'RPL_WHOISIDLE': function (command) { | |
158 | /*command.server = this.con_num; | |
159 | command.command = 'RPL_WHOISIDLE'; | |
2f1e8a71 | 160 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 161 | //websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: false}); |
7f96413b | 162 | if (command.params[3]) { |
2f1e8a71 | 163 | this.client.sendIrcCommand('whois', {server: this.con_num, nick: command.params[1], idle: command.params[2], logon: command.params[3], end: false}); |
7f96413b | 164 | } else { |
2f1e8a71 | 165 | this.client.sendIrcCommand('whois', {server: this.con_num, nick: command.params[1], idle: command.params[2], end: false}); |
7f96413b | 166 | } |
a8bf3ea4 | 167 | }, |
f3766a0b | 168 | 'RPL_WHOISREGNICK': function (command) { |
2f1e8a71 | 169 | this.client.sendIrcCommand('whois', {server: this.con_num, nick: command.params[1], msg: command.trailing, end: false}); |
f3766a0b | 170 | }, |
a8bf3ea4 JA |
171 | 'RPL_LISTSTART': function (command) { |
172 | /*command.server = this.con_num; | |
173 | command.command = 'RPL_LISTSTART'; | |
2f1e8a71 D |
174 | this.client.sendIrcCommand(command);*/ |
175 | this.client.sendIrcCommand('list_start', {server: this.con_num}); | |
a8bf3ea4 JA |
176 | this.client.buffer.list = []; |
177 | }, | |
178 | 'RPL_LISTEND': function (command) { | |
179 | /*command.server = this.con_num; | |
180 | command.command = 'RPL_LISTEND'; | |
2f1e8a71 | 181 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 JA |
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 | }); | |
2f1e8a71 | 186 | this.client.sendIrcCommand('list_channel', {server: this.con_num, chans: this.client.buffer.list}); |
a8bf3ea4 JA |
187 | this.client.buffer.list = []; |
188 | } | |
2f1e8a71 | 189 | this.client.sendIrcCommand('list_end', {server: this.con_num}); |
a8bf3ea4 JA |
190 | }, |
191 | 'RPL_LIST': function (command) { | |
192 | /*command.server = this.con_num; | |
193 | command.command = 'RPL_LIST'; | |
2f1e8a71 | 194 | this.client.sendIrcCommand(command);*/ |
6d3dc969 | 195 | this.client.buffer.list.push({server: this.con_num, channel: command.params[1], num_users: parseInt(command.params[2], 10), topic: command.trailing}); |
a8bf3ea4 JA |
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 | }); | |
2f1e8a71 | 200 | this.client.sendIrcCommand('list_channel', {server: this.con_num, chans: this.client.buffer.list}); |
a8bf3ea4 JA |
201 | this.client.buffer.list = []; |
202 | } | |
203 | }, | |
204 | 'RPL_MOTD': function (command) { | |
205 | /*command.server = this.con_num; | |
206 | command.command = 'RPL_MOTD'; | |
2f1e8a71 | 207 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 JA |
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'; | |
2f1e8a71 | 213 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 JA |
214 | this.client.buffer.motd = ''; |
215 | }, | |
216 | 'RPL_ENDOFMOTD': function (command) { | |
217 | /*command.server = this.con_num; | |
218 | command.command = 'RPL_ENDOFMOTD'; | |
2f1e8a71 | 219 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 220 | //websocket.sendClientEvent('motd', {server: '', 'msg': websocket.kiwi.buffer.motd}); |
2f1e8a71 | 221 | this.client.sendIrcCommand('motd', {server: this.con_num, msg: this.client.buffer.motd}); |
a8bf3ea4 JA |
222 | }, |
223 | 'RPL_NAMEREPLY': function (command) { | |
224 | /*command.server = this.con_num; | |
225 | command.command = 'RPL_NAMEREPLY'; | |
2f1e8a71 | 226 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 JA |
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) { | |
2f1e8a71 | 243 | that.client.sendIrcCommand('userlist', {server: that.con_num, users: member_list, channel: command.params[2]}); |
a8bf3ea4 JA |
244 | member_list = []; |
245 | i = 0; | |
246 | } | |
247 | }); | |
248 | if (i > 0) { | |
2f1e8a71 | 249 | this.client.sendIrcCommand('userlist', {server: this.con_num, users: member_list, channel: command.params[2]}); |
a8bf3ea4 JA |
250 | } |
251 | }, | |
252 | 'RPL_ENDOFNAMES': function (command) { | |
253 | /*command.server = this.con_num; | |
254 | command.command = 'RPL_ENDOFNAMES'; | |
2f1e8a71 | 255 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 256 | //websocket.sendClientEvent('userlist_end', {server: '', channel: msg.params.split(" ")[1]}); |
2f1e8a71 | 257 | this.client.sendIrcCommand('userlist_end', {server: this.con_num, channel: command.params[1]}); |
a8bf3ea4 JA |
258 | }, |
259 | 'RPL_BANLIST': function (command) { | |
260 | /*command.server = this.con_num; | |
261 | command.command = 'RPL_BANLIST'; | |
2f1e8a71 | 262 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 263 | //websocket.sendClientEvent('banlist', {server: '', channel: params[1], banned: params[2], banned_by: params[3], banned_at: params[4]}); |
2f1e8a71 | 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]}); |
a8bf3ea4 JA |
265 | }, |
266 | 'RPL_ENDOFBANLIST': function (command) { | |
267 | /*command.server = this.con_num; | |
268 | command.command = 'RPL_ENDOFBANLIST'; | |
2f1e8a71 | 269 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 270 | //websocket.sendClientEvent('banlist_end', {server: '', channel: msg.params.split(" ")[1]}); |
2f1e8a71 | 271 | this.client.sendIrcCommand('banlist_end', {server: this.con_num, channel: command.params[1]}); |
a8bf3ea4 JA |
272 | }, |
273 | 'RPL_TOPIC': function (command) { | |
274 | /*command.server = this.con_num; | |
275 | command.command = 'RPL_TOPIC'; | |
2f1e8a71 | 276 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 277 | //{nick: '', channel: msg.params.split(" ")[1], topic: msg.trailing}; |
2f1e8a71 | 278 | this.client.sendIrcCommand('topic', {server: this.con_num, nick: '', channel: command.params[1], topic: command.trailing}); |
a8bf3ea4 JA |
279 | }, |
280 | 'RPL_NOTOPIC': function (command) { | |
281 | /*command.server = this.con_num; | |
282 | command.command = 'RPL_NOTOPIC'; | |
2f1e8a71 D |
283 | this.client.sendIrcCommand(command);*/ |
284 | this.client.sendIrcCommand('topic', {server: this.con_num, nick: '', channel: command.params[1], topic: ''}); | |
a8bf3ea4 JA |
285 | }, |
286 | 'RPL_TOPICWHOTIME': function (command) { | |
287 | /*command.server = this.con_num; | |
288 | command.command = 'RPL_TOPICWHOTIME'; | |
2f1e8a71 | 289 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 290 | //{nick: nick, channel: channel, when: when}; |
2f1e8a71 | 291 | this.client.sendIrcCommand('topicsetby', {server: this.con_num, nick: command.params[2], channel: command.params[1], when: command.params[3]}); |
a8bf3ea4 JA |
292 | }, |
293 | 'PING': function (command) { | |
b8e4d9f7 | 294 | this.irc_connection.write('PONG ' + command.trailing); |
a8bf3ea4 JA |
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]; | |
2f1e8a71 | 306 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 307 | //websocket.sendClientEvent('join', {nick: msg.nick, ident: msg.ident, hostname: msg.hostname, channel: channel}); |
2f1e8a71 | 308 | this.client.sendIrcCommand('join', {server: this.con_num, nick: command.nick, ident: command.ident, hostname: command.hostname, channel: channel}); |
a8bf3ea4 JA |
309 | |
310 | if (command.nick === this.nick) { | |
b8e4d9f7 | 311 | this.irc_connection.write('NAMES ' + channel); |
a8bf3ea4 JA |
312 | } |
313 | }, | |
314 | 'PART': function (command) { | |
315 | /*command.server = this.con_num; | |
316 | command.command = 'PART'; | |
2f1e8a71 | 317 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 318 | //websocket.sendClientEvent('part', {nick: msg.nick, ident: msg.ident, hostname: msg.hostname, channel: msg.params.trim(), message: msg.trailing}); |
2f1e8a71 | 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}); |
a8bf3ea4 JA |
320 | }, |
321 | 'KICK': function (command) { | |
322 | /*command.server = this.con_num; | |
323 | command.command = 'KICK'; | |
2f1e8a71 | 324 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 325 | //websocket.sendClientEvent('kick', {kicked: params[1], nick: msg.nick, ident: msg.ident, hostname: msg.hostname, channel: params[0].trim(), message: msg.trailing}); |
2f1e8a71 | 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}); |
a8bf3ea4 JA |
327 | }, |
328 | 'QUIT': function (command) { | |
329 | /*command.server = this.con_num; | |
330 | command.command = 'QUIT'; | |
2f1e8a71 | 331 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 332 | //websocket.sendClientEvent('quit', {nick: msg.nick, ident: msg.ident, hostname: msg.hostname, message: msg.trailing}); |
2f1e8a71 | 333 | this.client.sendIrcCommand('quit', {server: this.con_num, nick: command.nick, ident: command.ident, hostname: command.hostname, message: command.trailing}); |
a8bf3ea4 JA |
334 | }, |
335 | 'NOTICE': function (command) { | |
336 | /*command.server = this.con_num; | |
337 | command.command = 'NOTICE'; | |
2f1e8a71 | 338 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 JA |
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)}); | |
2f1e8a71 | 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)}); |
a8bf3ea4 JA |
343 | } else { |
344 | //websocket.sendClientEvent('notice', {nick: msg.nick, ident: msg.ident, hostname: msg.hostname, target: msg.params.trim(), msg: msg.trailing}); | |
2f1e8a71 | 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}); |
a8bf3ea4 JA |
346 | } |
347 | }, | |
348 | 'NICK': function (command) { | |
349 | /*command.server = this.con_num; | |
350 | command.command = 'NICK'; | |
2f1e8a71 | 351 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 352 | //websocket.sendClientEvent('nick', {nick: msg.nick, ident: msg.ident, hostname: msg.hostname, newnick: msg.trailing}); |
2f1e8a71 | 353 | this.client.sendIrcCommand('nick', {server: this.con_num, nick: command.nick, ident: command.ident, hostname: command.hostname, newnick: command.trailing}); |
a8bf3ea4 JA |
354 | }, |
355 | 'TOPIC': function (command) { | |
356 | /*command.server = this.con_num; | |
357 | command.command = 'TOPIC'; | |
2f1e8a71 | 358 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 359 | //{nick: msg.nick, channel: msg.params, topic: msg.trailing}; |
2f1e8a71 | 360 | this.client.sendIrcCommand('topic', {server: this.con_num, nick: command.nick, channel: command.params[0], topic: command.trailing}); |
a8bf3ea4 | 361 | }, |
703d2778 JA |
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; | |
a8bf3ea4 | 391 | } |
703d2778 JA |
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 | ||
2f1e8a71 | 411 | this.client.sendIrcCommand('mode', { |
4e85992d D |
412 | server: this.con_num, |
413 | target: command.params[0], | |
414 | nick: command.nick || command.prefix || '', | |
415 | modes: modes | |
416 | }); | |
a8bf3ea4 JA |
417 | }, |
418 | 'PRIVMSG': function (command) { | |
419 | /*command.server = this.con_num; | |
420 | command.command = 'PRIVMSG'; | |
2f1e8a71 | 421 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 JA |
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') { | |
2f1e8a71 | 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)}); |
a8bf3ea4 | 427 | } else if (command.trailing.substr(1, 4) === 'KIWI') { |
6d3dc969 | 428 | tmp = command.trailing.substr(6, command.trailing.length - 2); |
a8bf3ea4 | 429 | namespace = tmp.split(' ', 1)[0]; |
2f1e8a71 | 430 | this.client.sendIrcCommand('kiwi', {server: this.con_num, namespace: namespace, data: tmp.substr(namespace.length + 1)}); |
6d3dc969 | 431 | } else if (command.trailing.substr(1, 7) === 'VERSION') { |
b8e4d9f7 | 432 | this.irc_connection.write('NOTICE ' + command.nick + ' :' + String.fromCharCode(1) + 'VERSION KiwiIRC' + String.fromCharCode(1)); |
a8bf3ea4 | 433 | } else { |
2f1e8a71 | 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)}); |
a8bf3ea4 JA |
435 | } |
436 | } else { | |
437 | //{nick: msg.nick, ident: msg.ident, hostname: msg.hostname, channel: msg.params.trim(), msg: msg.trailing} | |
2f1e8a71 | 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}); |
a8bf3ea4 JA |
439 | } |
440 | }, | |
eec8c71e JA |
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(' '); | |
eec8c71e | 445 | var request; |
7dfe47c6 JA |
446 | var want = ['multi-prefix']; |
447 | ||
448 | if (this.irc_connection.password) { | |
449 | want.push('sasl'); | |
450 | } | |
eec8c71e JA |
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; | |
7dfe47c6 | 461 | this.irc_connection.register(); |
eec8c71e JA |
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) { | |
7dfe47c6 JA |
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 | } | |
eec8c71e JA |
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; | |
7dfe47c6 | 487 | this.irc_connection.register(); |
eec8c71e JA |
488 | } |
489 | break; | |
490 | case 'LIST': | |
491 | // should we do anything here? | |
492 | break; | |
493 | } | |
494 | }, | |
7dfe47c6 JA |
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 | 'RPL_SASLAUTHENTICATED':function (command) { | |
515 | this.irc_connection.write('CAP END'); | |
516 | this.irc_connection.cap_negotation = false; | |
517 | this.irc_connection.register(); | |
518 | }, | |
519 | 'RPL_SASLLOGGEDIN': function (command) { | |
520 | // noop | |
521 | }, | |
522 | 'ERR_SASLNOTAUTHORISED':function (command) { | |
523 | this.irc_connection.write('CAP END'); | |
524 | this.irc_connection.cap_negotation = false; | |
525 | this.irc_connection.cap.enabled = _.without(this.irc_connection.cap.enabled, 'sasl'); | |
526 | this.irc_connection.register(); | |
527 | }, | |
528 | 'ERR_SASLABORTED': function (command) { | |
529 | this.irc_connection.cap.enabled = _.without(this.irc_connection.cap.enabled, 'sasl'); | |
530 | }, | |
531 | 'ERR_SASLALREADYAUTHED':function (command) { | |
532 | // noop | |
533 | }, | |
a8bf3ea4 JA |
534 | 'ERROR': function (command) { |
535 | /*command.server = this.con_num; | |
536 | command.command = 'ERROR'; | |
2f1e8a71 | 537 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 538 | //websocket.sendClientEvent('irc_error', {error: 'error', reason: msg.trailing}); |
2f1e8a71 | 539 | this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'error', reason: command.trailing}); |
a8bf3ea4 JA |
540 | }, |
541 | ERR_LINKCHANNEL: function (command) { | |
542 | /*command.server = this.con_num; | |
543 | command.command = 'ERR_LINKCHANNEL'; | |
2f1e8a71 | 544 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 545 | //websocket.sendClientEvent('channel_redirect', {from: params[1], to: params[2]}); |
2f1e8a71 | 546 | this.client.sendIrcCommand('channel_redirect', {server: this.con_num, from: command.params[1], to: command.params[2]}); |
a8bf3ea4 JA |
547 | }, |
548 | ERR_NOSUCHNICK: function (command) { | |
549 | /*command.server = this.con_num; | |
550 | command.command = 'ERR_NOSUCHNICK'; | |
2f1e8a71 | 551 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 552 | //websocket.sendClientEvent('irc_error', {error: 'no_such_nick', nick: msg.params.split(" ")[1], reason: msg.trailing}); |
2f1e8a71 | 553 | this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'no_such_nick', nick: command.params[1], reason: command.trailing}); |
a8bf3ea4 JA |
554 | }, |
555 | ERR_CANNOTSENDTOCHAN: function (command) { | |
556 | /*command.server = this.con_num; | |
557 | command.command = 'ERR_CANNOTSENDTOCHAN'; | |
2f1e8a71 | 558 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 559 | //websocket.sendClientEvent('irc_error', {error: 'cannot_send_to_chan', channel: msg.params.split(" ")[1], reason: msg.trailing}); |
2f1e8a71 | 560 | this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'cannot_send_to_chan', channel: command.params[1], reason: command.trailing}); |
a8bf3ea4 JA |
561 | }, |
562 | ERR_TOOMANYCHANNELS: function (command) { | |
563 | /*command.server = this.con_num; | |
564 | command.command = 'ERR_TOOMANYCHANNELS'; | |
2f1e8a71 | 565 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 566 | //websocket.sendClientEvent('irc_error', {error: 'too_many_channels', channel: msg.params.split(" ")[1], reason: msg.trailing}); |
2f1e8a71 | 567 | this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'too_many_channels', channel: command.params[1], reason: command.trailing}); |
a8bf3ea4 JA |
568 | }, |
569 | ERR_USERNOTINCHANNEL: function (command) { | |
570 | /*command.server = this.con_num; | |
571 | command.command = 'ERR_USERNOTINCHANNEL'; | |
2f1e8a71 | 572 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 573 | //websocket.sendClientEvent('irc_error', {error: 'user_not_in_channel', nick: params[0], channel: params[1], reason: msg.trainling}); |
2f1e8a71 | 574 | 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}); |
a8bf3ea4 JA |
575 | }, |
576 | ERR_NOTONCHANNEL: function (command) { | |
577 | /*command.server = this.con_num; | |
578 | command.command = 'ERR_NOTONCHANNEL'; | |
2f1e8a71 | 579 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 580 | //websocket.sendClientEvent('irc_error', {error: 'not_on_channel', channel: msg.params.split(" ")[1], reason: msg.trailing}); |
2f1e8a71 | 581 | this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'not_on_channel', channel: command.params[1], reason: command.trailing}); |
a8bf3ea4 JA |
582 | }, |
583 | ERR_CHANNELISFULL: function (command) { | |
584 | /*command.server = this.con_num; | |
585 | command.command = 'ERR_CHANNELISFULL'; | |
2f1e8a71 | 586 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 587 | //websocket.sendClientEvent('irc_error', {error: 'channel_is_full', channel: msg.params.split(" ")[1], reason: msg.trailing}); |
2f1e8a71 | 588 | this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'channel_is_full', channel: command.params[1], reason: command.trailing}); |
a8bf3ea4 JA |
589 | }, |
590 | ERR_INVITEONLYCHAN: function (command) { | |
591 | /*command.server = this.con_num; | |
592 | command.command = 'ERR_INVITEONLYCHAN'; | |
2f1e8a71 | 593 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 594 | //websocket.sendClientEvent('irc_error', {error: 'invite_only_channel', channel: msg.params.split(" ")[1], reason: msg.trailing}); |
2f1e8a71 | 595 | this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'invite_only_channel', channel: command.params[1], reason: command.trailing}); |
a8bf3ea4 JA |
596 | }, |
597 | ERR_BANNEDFROMCHAN: function (command) { | |
598 | /*command.server = this.con_num; | |
599 | command.command = 'ERR_BANNEDFROMCHAN'; | |
2f1e8a71 | 600 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 601 | //websocket.sendClientEvent('irc_error', {error: 'banned_from_channel', channel: msg.params.split(" ")[1], reason: msg.trailing}); |
2f1e8a71 | 602 | this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'banned_from_channel', channel: command.params[1], reason: command.trailing}); |
a8bf3ea4 JA |
603 | }, |
604 | ERR_BADCHANNELKEY: function (command) { | |
605 | /*command.server = this.con_num; | |
606 | command.command = 'ERR_BADCHANNELKEY'; | |
2f1e8a71 | 607 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 608 | //websocket.sendClientEvent('irc_error', {error: 'bad_channel_key', channel: msg.params.split(" ")[1], reason: msg.trailing}); |
2f1e8a71 | 609 | this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'bad_channel_key', channel: command.params[1], reason: command.trailing}); |
a8bf3ea4 JA |
610 | }, |
611 | ERR_CHANOPRIVSNEEDED: function (command) { | |
612 | /*command.server = this.con_num; | |
613 | command.command = 'ERR_CHANOPRIVSNEEDED'; | |
2f1e8a71 | 614 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 615 | //websocket.sendClientEvent('irc_error', {error: 'chanop_privs_needed', channel: msg.params.split(" ")[1], reason: msg.trailing}); |
2f1e8a71 | 616 | this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'chanop_privs_needed', channel: command.params[1], reason: command.trailing}); |
a8bf3ea4 JA |
617 | }, |
618 | ERR_NICKNAMEINUSE: function (command) { | |
619 | /*command.server = this.con_num; | |
620 | command.command = 'ERR_NICKNAMEINUSE'; | |
2f1e8a71 | 621 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 | 622 | //websocket.sendClientEvent('irc_error', {error: 'nickname_in_use', nick: _.last(msg.params.split(" ")), reason: msg.trailing}); |
2f1e8a71 | 623 | this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'nickname_in_use', nick: command.params[1], reason: command.trailing}); |
a8bf3ea4 JA |
624 | }, |
625 | ERR_NOTREGISTERED: function (command) { | |
626 | /*command.server = this.con_num; | |
627 | command.command = 'ERR_NOTREGISTERED'; | |
2f1e8a71 | 628 | this.client.sendIrcCommand(command);*/ |
a8bf3ea4 JA |
629 | } |
630 | }; |