Merge branch 'development' of https://github.com/DaHispanicNinja/KiwiIRC into DaHispa...
[KiwiIRC.git] / client / src / models / gateway.js
CommitLineData
eaaf73b0 1_kiwi.model.Gateway = function () {\r
696a66f8
D
2\r
3 // Set to a reference to this object within initialize()\r
4 var that = null;\r
5\r
696a66f8
D
6 this.initialize = function () {\r
7 that = this;\r
09c26937 8\r
696a66f8
D
9 // For ease of access. The socket.io object\r
10 this.socket = this.get('socket');\r
6228b635
D
11\r
12 this.applyEventHandlers();\r
09c26937
D
13\r
14 // Used to check if a disconnection was unplanned\r
15 this.disconnect_requested = false;\r
6228b635
D
16 };\r
17\r
18\r
19 this.applyEventHandlers = function () {\r
20 /*\r
a1629e09
D
21 kiwi.gateway.on('message:#channel', my_function);\r
22 kiwi.gateway.on('message:somenick', my_function);\r
6228b635
D
23\r
24 kiwi.gateway.on('notice:#channel', my_function);\r
25 kiwi.gateway.on('action:somenick', my_function);\r
26\r
27 kiwi.gateway.on('join:#channel', my_function);\r
28 kiwi.gateway.on('part:#channel', my_function);\r
29 kiwi.gateway.on('quit', my_function);\r
30 */\r
31 var that = this;\r
09c26937 32\r
6228b635
D
33 // Some easier handler events\r
34 this.on('onmsg', function (event) {\r
35 var source,\r
fc9b83de 36 connection = _kiwi.app.connections.getByConnectionId(event.server),\r
aef6e2a7 37 is_pm = (event.channel.toLowerCase() == connection.get('nick').toLowerCase());\r
6228b635
D
38\r
39 source = is_pm ? event.nick : event.channel;\r
09c26937 40\r
8913f3ea
D
41 that.trigger('message:' + source, event);\r
42 that.trigger('message', event);\r
6228b635
D
43\r
44 if (is_pm) {\r
6228b635 45 that.trigger('pm:' + source, event);\r
8913f3ea 46 that.trigger('pm', event);\r
6228b635
D
47 }\r
48 }, this);\r
49\r
50\r
51 this.on('onnotice', function (event) {\r
52 // The notice towards a channel or a query window?\r
53 var source = event.target || event.nick;\r
54\r
6228b635 55 this.trigger('notice:' + source, event);\r
8913f3ea 56 this.trigger('notice', event);\r
6228b635
D
57 }, this);\r
58\r
59\r
60 this.on('onaction', function (event) {\r
61 var source,\r
fc9b83de 62 connection = _kiwi.app.connections.getByConnectionId(event.server),\r
aef6e2a7 63 is_pm = (event.channel.toLowerCase() == connection.get('nick').toLowerCase());\r
6228b635
D
64\r
65 source = is_pm ? event.nick : event.channel;\r
09c26937 66\r
6228b635
D
67 that.trigger('action:' + source, event);\r
68\r
69 if (is_pm) {\r
6228b635 70 that.trigger('action:' + source, event);\r
8913f3ea 71 that.trigger('action', event);\r
6228b635
D
72 }\r
73 }, this);\r
74\r
75\r
76 this.on('ontopic', function (event) {\r
6228b635 77 that.trigger('topic:' + event.channel, event);\r
8913f3ea 78 that.trigger('topic', event);\r
6228b635 79 });\r
22373da6
D
80\r
81\r
82 this.on('onjoin', function (event) {\r
83 that.trigger('join:' + event.channel, event);\r
84 that.trigger('join', event);\r
85 });\r
86\r
696a66f8
D
87 };\r
88\r
89\r
6228b635 90\r
09c26937 91 this.reconnect = function (callback) {\r
d6eec6ed
D
92 var that = this,\r
93 transport_path;\r
94\r
09c26937 95 this.disconnect_requested = true;\r
d99e7823
D
96 this.socket.close();\r
97\r
33432128 98 this.socket = null;\r
c6a65334 99 this.connect(callback);\r
09c26937
D
100 };\r
101\r
102\r
103\r
696a66f8
D
104 /**\r
105 * Connects to the server\r
696a66f8
D
106 * @param {Function} callback A callback function to be invoked once Kiwi's server has connected to the IRC server\r
107 */\r
f2bb5380 108 this.connect = function (callback) {\r
8cc59dbe
D
109 this.connect_callback = callback;\r
110\r
e5baa247
D
111 // Keep note of the server we are connecting to\r
112 this.set('kiwi_server', _kiwi.app.kiwi_server);\r
113\r
33432128 114 this.socket = new EngineioTools.ReconnectingSocket(this.get('kiwi_server'), {\r
d99e7823 115 path: _kiwi.app.get('base_path') + '/transport',\r
d99e7823
D
116 reconnect_max_attempts: 5,\r
117 reconnect_delay: 2000\r
118 });\r
8b0eb787 119\r
33432128 120 this.rpc = new EngineioTools.Rpc(this.socket);\r
f2bb5380 121\r
696a66f8 122 this.socket.on('connect_failed', function (reason) {\r
696a66f8
D
123 this.socket.disconnect();\r
124 this.trigger("connect_fail", {reason: reason});\r
125 });\r
126\r
127 this.socket.on('error', function (e) {\r
eaaf73b0 128 console.log("_kiwi.gateway.socket.on('error')", {reason: e});\r
28b4b095
D
129 if (that.connect_callback) {\r
130 that.connect_callback(e);\r
131 delete that.connect_callback;\r
132 }\r
133\r
696a66f8
D
134 that.trigger("connect_fail", {reason: e});\r
135 });\r
136\r
137 this.socket.on('connecting', function (transport_type) {\r
eaaf73b0 138 console.log("_kiwi.gateway.socket.on('connecting')");\r
696a66f8
D
139 that.trigger("connecting");\r
140 });\r
141\r
142 /**\r
143 * Once connected to the kiwi server send the IRC connect command along\r
144 * with the IRC server details.\r
145 * A `connect` event is sent from the kiwi server once connected to the\r
146 * IRCD and the nick has been accepted.\r
147 */\r
d99e7823 148 this.socket.on('open', function () {\r
09c26937
D
149 // Reset the disconnect_requested flag\r
150 that.disconnect_requested = false;\r
151\r
28635406 152 console.log("_kiwi.gateway.socket.on('open')");\r
696a66f8
D
153 });\r
154\r
d99e7823 155 this.rpc.on('too_many_connections', function () {\r
696a66f8
D
156 that.trigger("connect_fail", {reason: 'too_many_connections'});\r
157 });\r
158\r
d99e7823 159 this.rpc.on('irc', function (response, data) {\r
696a66f8
D
160 that.parse(data.command, data.data);\r
161 });\r
162\r
d99e7823 163 this.rpc.on('kiwi', function (response, data) {\r
d2d91c10
D
164 that.parseKiwi(data.command, data.data);\r
165 });\r
166\r
696a66f8 167 this.socket.on('close', function () {\r
d99e7823 168 that.trigger("disconnect", {});\r
eaaf73b0 169 console.log("_kiwi.gateway.socket.on('close')");\r
696a66f8
D
170 });\r
171\r
d99e7823 172 this.socket.on('reconnecting', function (status) {\r
eaaf73b0 173 console.log("_kiwi.gateway.socket.on('reconnecting')");\r
d99e7823 174 that.trigger("reconnecting", {delay: status.delay, attempts: status.attempts});\r
696a66f8
D
175 });\r
176\r
d99e7823 177 this.socket.on('reconnecting_failed', function () {\r
eaaf73b0 178 console.log("_kiwi.gateway.socket.on('reconnect_failed')");\r
696a66f8
D
179 });\r
180 };\r
181\r
182\r
d6eec6ed
D
183 /**\r
184 * Return a new network object with the new connection details\r
185 */\r
2a27c998 186 this.newConnection = function(connection_info, callback_fn) {\r
d6eec6ed 187 var that = this;\r
2a27c998 188\r
28b4b095
D
189 // If not connected, connect first then re-call this function\r
190 if (!this.isConnected()) {\r
191 this.connect(function(err) {\r
192 if (err) {\r
193 callback_fn(err);\r
194 return;\r
195 }\r
196\r
197 that.newConnection(connection_info, callback_fn);\r
198 });\r
199\r
200 return;\r
201 }\r
202\r
d6eec6ed 203 this.makeIrcConnection(connection_info, function(err, server_num) {\r
c966123a
D
204 var connection;\r
205\r
2a27c998 206 if (!err) {\r
f2bb5380 207 if (!_kiwi.app.connections.getByConnectionId(server_num)){\r
d6eec6ed
D
208 var inf = {\r
209 connection_id: server_num,\r
210 nick: connection_info.nick,\r
211 address: connection_info.host,\r
212 port: connection_info.port,\r
213 ssl: connection_info.ssl,\r
214 password: connection_info.password\r
215 };\r
216 connection = new _kiwi.model.Network(inf);\r
c966123a 217 _kiwi.app.connections.add(connection);\r
2a27c998
D
218 }\r
219\r
d6eec6ed 220 console.log("_kiwi.gateway.socket.on('connect')", connection);\r
c966123a 221 callback_fn && callback_fn(err, connection);\r
09c26937 222\r
2a27c998
D
223 } else {\r
224 console.log("_kiwi.gateway.socket.on('error')", {reason: err});\r
225 callback_fn && callback_fn(err);\r
226 }\r
227 });\r
228 };\r
229\r
d6eec6ed
D
230\r
231 /**\r
232 * Make a new IRC connection and return its connection ID\r
233 */\r
234 this.makeIrcConnection = function(connection_info, callback_fn) {\r
235 var server_info = {\r
236 command: 'connect',\r
237 nick: connection_info.nick,\r
238 hostname: connection_info.host,\r
239 port: connection_info.port,\r
240 ssl: connection_info.ssl,\r
241 password: connection_info.password\r
242 };\r
243\r
c6a65334
D
244 connection_info.options = connection_info.options || {};\r
245\r
cc54c0a1
D
246 // A few optional parameters\r
247 if (connection_info.options.encoding)\r
248 server_info.encoding = connection_info.options.encoding;\r
249\r
d99e7823 250 this.rpc.call('kiwi', server_info, function (err, server_num) {\r
d6eec6ed
D
251 if (!err) {\r
252 callback_fn && callback_fn(err, server_num);\r
253\r
254 } else {\r
255 callback_fn && callback_fn(err);\r
256 }\r
257 });\r
258 };\r
259\r
260\r
696a66f8 261 this.isConnected = function () {\r
d99e7823
D
262 // TODO: Check this. Might want to use .readyState\r
263 return this.socket;\r
696a66f8
D
264 };\r
265\r
266\r
d2d91c10
D
267\r
268 this.parseKiwi = function (command, data) {\r
9b95f5f1
D
269 var client_info_data;\r
270\r
a1629e09
D
271 this.trigger('kiwi:' + command, data);\r
272 this.trigger('kiwi', data);\r
8cc59dbe
D
273\r
274 switch (command) {\r
275 case 'connected':\r
9b95f5f1
D
276 // Send some info on this client to the server\r
277 client_info_data = {\r
278 command: 'client_info',\r
279 build_version: _kiwi.global.build_version\r
280 };\r
281 this.rpc.call('kiwi', client_info_data);\r
282\r
8cc59dbe
D
283 this.connect_callback && this.connect_callback();\r
284 delete this.connect_callback;\r
9b95f5f1 285\r
8cc59dbe
D
286 break;\r
287 }\r
d2d91c10 288 };\r
696a66f8
D
289 /*\r
290 Events:\r
291 msg\r
292 action\r
293 server_connect\r
294 options\r
295 motd\r
296 notice\r
297 userlist\r
298 nick\r
299 join\r
300 topic\r
301 part\r
302 kick\r
303 quit\r
304 whois\r
305 syncchannel_redirect\r
306 debug\r
307 */\r
308 /**\r
309 * Parses the response from the server\r
310 */\r
311 this.parse = function (command, data) {\r
d2d91c10 312 //console.log('gateway event', command, data);\r
ce13508b 313\r
696a66f8 314 if (command !== undefined) {\r
696a66f8
D
315 switch (command) {\r
316 case 'options':\r
317 $.each(data.options, function (name, value) {\r
318 switch (name) {\r
319 case 'CHANTYPES':\r
d9e06c6e 320 that.set('channel_prefix', value.join(''));\r
696a66f8
D
321 break;\r
322 case 'NETWORK':\r
323 that.set('name', value);\r
324 break;\r
325 case 'PREFIX':\r
326 that.set('user_prefixes', value);\r
327 break;\r
328 }\r
329 });\r
dff8edba 330 that.set('cap', data.cap);\r
696a66f8
D
331 break;\r
332\r
696a66f8
D
333 /*\r
334 case 'sync':\r
eaaf73b0
D
335 if (_kiwi.gateway.onSync && _kiwi.gateway.syncing) {\r
336 _kiwi.gateway.syncing = false;\r
337 _kiwi.gateway.onSync(item);\r
696a66f8
D
338 }\r
339 break;\r
340 */\r
341\r
342 case 'kiwi':\r
eaaf73b0 343 this.emit('_kiwi.' + data.namespace, data.data);\r
696a66f8
D
344 break;\r
345 }\r
346 }\r
ce13508b
D
347\r
348\r
349 if (typeof data.server !== 'undefined') {\r
350 that.trigger('connection:' + data.server.toString(), {\r
351 event_name: command,\r
352 event_data: data\r
353 });\r
354 }\r
fc9b83de
D
355\r
356 // Trigger the global events (Mainly legacy now)\r
357 that.trigger('on' + command, data);\r
696a66f8
D
358 };\r
359\r
360 /**\r
361 * Sends data to the server\r
362 * @private\r
363 * @param {Object} data The data to send\r
364 * @param {Function} callback A callback function\r
365 */\r
e7d65587
D
366 this.sendData = function (connection_id, data, callback) {\r
367 if (typeof connection_id === 'undefined' || connection_id === null)\r
368 connection_id = _kiwi.app.connections.active_connection.get('connection_id');\r
369\r
2ffd1291 370 var data_buffer = {\r
e7d65587 371 server: connection_id,\r
2ffd1291
D
372 data: JSON.stringify(data)\r
373 };\r
d99e7823 374 this.rpc.call('irc', data_buffer, callback);\r
696a66f8
D
375 };\r
376\r
377 /**\r
378 * Sends a PRIVMSG message\r
379 * @param {String} target The target of the message (e.g. a channel or nick)\r
380 * @param {String} msg The message to send\r
381 * @param {Function} callback A callback function\r
382 */\r
e7d65587 383 this.privmsg = function (connection_id, target, msg, callback) {\r
696a66f8
D
384 var data = {\r
385 method: 'privmsg',\r
386 args: {\r
387 target: target,\r
388 msg: msg\r
389 }\r
390 };\r
391\r
e7d65587 392 this.sendData(connection_id, data, callback);\r
696a66f8
D
393 };\r
394\r
395 /**\r
396 * Sends a NOTICE message\r
397 * @param {String} target The target of the message (e.g. a channel or nick)\r
398 * @param {String} msg The message to send\r
399 * @param {Function} callback A callback function\r
400 */\r
e7d65587 401 this.notice = function (connection_id, target, msg, callback) {\r
696a66f8
D
402 var data = {\r
403 method: 'notice',\r
404 args: {\r
405 target: target,\r
406 msg: msg\r
407 }\r
408 };\r
409\r
e7d65587 410 this.sendData(connection_id, data, callback);\r
696a66f8
D
411 };\r
412\r
413 /**\r
414 * Sends a CTCP message\r
415 * @param {Boolean} request Indicates whether this is a CTCP request (true) or reply (false)\r
416 * @param {String} type The type of CTCP message, e.g. 'VERSION', 'TIME', 'PING' etc.\r
417 * @param {String} target The target of the message, e.g a channel or nick\r
418 * @param {String} params Additional paramaters\r
419 * @param {Function} callback A callback function\r
420 */\r
e7d65587 421 this.ctcp = function (connection_id, request, type, target, params, callback) {\r
696a66f8
D
422 var data = {\r
423 method: 'ctcp',\r
424 args: {\r
425 request: request,\r
426 type: type,\r
427 target: target,\r
428 params: params\r
429 }\r
430 };\r
431\r
e7d65587 432 this.sendData(connection_id, data, callback);\r
696a66f8
D
433 };\r
434\r
435 /**\r
436 * @param {String} target The target of the message (e.g. a channel or nick)\r
437 * @param {String} msg The message to send\r
438 * @param {Function} callback A callback function\r
439 */\r
e7d65587 440 this.action = function (connection_id, target, msg, callback) {\r
11177392 441 this.ctcp(connection_id, true, 'ACTION', target, msg, callback);\r
696a66f8
D
442 };\r
443\r
444 /**\r
445 * Joins a channel\r
446 * @param {String} channel The channel to join\r
447 * @param {String} key The key to the channel\r
448 * @param {Function} callback A callback function\r
449 */\r
e7d65587 450 this.join = function (connection_id, channel, key, callback) {\r
696a66f8
D
451 var data = {\r
452 method: 'join',\r
453 args: {\r
454 channel: channel,\r
455 key: key\r
456 }\r
457 };\r
458\r
e7d65587 459 this.sendData(connection_id, data, callback);\r
696a66f8
D
460 };\r
461\r
72db27e4
D
462 /**\r
463 * Retrieves channel information\r
464 */\r
465 this.channelInfo = function (connection_id, channel, callback) {\r
466 var data = {\r
467 method: 'channel_info',\r
468 args: {\r
469 channel: channel\r
470 }\r
471 };\r
472\r
473 this.sendData(connection_id, data, callback);\r
474 };\r
475\r
696a66f8
D
476 /**\r
477 * Leaves a channel\r
478 * @param {String} channel The channel to part\r
479 * @param {Function} callback A callback function\r
480 */\r
e7d65587 481 this.part = function (connection_id, channel, callback) {\r
696a66f8
D
482 var data = {\r
483 method: 'part',\r
484 args: {\r
485 channel: channel\r
486 }\r
487 };\r
488\r
e7d65587 489 this.sendData(connection_id, data, callback);\r
696a66f8
D
490 };\r
491\r
492 /**\r
493 * Queries or modifies a channell topic\r
494 * @param {String} channel The channel to query or modify\r
495 * @param {String} new_topic The new topic to set\r
496 * @param {Function} callback A callback function\r
497 */\r
e7d65587 498 this.topic = function (connection_id, channel, new_topic, callback) {\r
696a66f8
D
499 var data = {\r
500 method: 'topic',\r
501 args: {\r
502 channel: channel,\r
503 topic: new_topic\r
504 }\r
505 };\r
506\r
e7d65587 507 this.sendData(connection_id, data, callback);\r
696a66f8
D
508 };\r
509\r
510 /**\r
511 * Kicks a user from a channel\r
512 * @param {String} channel The channel to kick the user from\r
513 * @param {String} nick The nick of the user to kick\r
514 * @param {String} reason The reason for kicking the user\r
515 * @param {Function} callback A callback function\r
516 */\r
e7d65587 517 this.kick = function (connection_id, channel, nick, reason, callback) {\r
696a66f8
D
518 var data = {\r
519 method: 'kick',\r
520 args: {\r
521 channel: channel,\r
522 nick: nick,\r
523 reason: reason\r
524 }\r
525 };\r
526\r
e7d65587 527 this.sendData(connection_id, data, callback);\r
696a66f8
D
528 };\r
529\r
530 /**\r
531 * Disconnects us from the server\r
532 * @param {String} msg The quit message to send to the IRC server\r
533 * @param {Function} callback A callback function\r
534 */\r
e7d65587 535 this.quit = function (connection_id, msg, callback) {\r
696a66f8
D
536 msg = msg || "";\r
537 var data = {\r
538 method: 'quit',\r
539 args: {\r
540 message: msg\r
541 }\r
542 };\r
543\r
e7d65587 544 this.sendData(connection_id, data, callback);\r
696a66f8
D
545 };\r
546\r
547 /**\r
548 * Sends a string unmodified to the IRC server\r
549 * @param {String} data The data to send to the IRC server\r
550 * @param {Function} callback A callback function\r
551 */\r
e7d65587 552 this.raw = function (connection_id, data, callback) {\r
696a66f8
D
553 data = {\r
554 method: 'raw',\r
555 args: {\r
556 data: data\r
557 }\r
558 };\r
559\r
e7d65587 560 this.sendData(connection_id, data, callback);\r
696a66f8
D
561 };\r
562\r
563 /**\r
564 * Changes our nickname\r
565 * @param {String} new_nick Our new nickname\r
566 * @param {Function} callback A callback function\r
567 */\r
e7d65587 568 this.changeNick = function (connection_id, new_nick, callback) {\r
696a66f8
D
569 var data = {\r
570 method: 'nick',\r
571 args: {\r
572 nick: new_nick\r
573 }\r
574 };\r
575\r
e7d65587 576 this.sendData(connection_id, data, callback);\r
696a66f8
D
577 };\r
578\r
72db27e4
D
579 /**\r
580 * Sets a mode for a target\r
581 */\r
582 this.mode = function (connection_id, target, mode_string, callback) {\r
583 data = {\r
584 method: 'raw',\r
585 args: {\r
586 data: 'MODE ' + target + ' ' + mode_string\r
587 }\r
588 };\r
589\r
590 this.sendData(connection_id, data, callback);\r
591 };\r
592\r
593\r
d1b3e8b3
VDF
594 /**\r
595 * Sends ENCODING change request to server.\r
596 * @param {String} new_encoding The new proposed encode\r
597 * @param {Fucntion} callback A callback function\r
598 */\r
599 this.setEncoding = function (connection_id, new_encoding, callback) {\r
65c5a477
VDF
600 var data = {\r
601 method: 'encoding',\r
602 args: {\r
603 encoding: new_encoding\r
604 }\r
605 };\r
606 this.sendData(connection_id, data, callback);\r
d1b3e8b3
VDF
607 };\r
608\r
696a66f8
D
609 /**\r
610 * Sends data to a fellow Kiwi IRC user\r
611 * @param {String} target The nick of the Kiwi IRC user to send to\r
612 * @param {String} data The data to send\r
613 * @param {Function} callback A callback function\r
614 */\r
615 this.kiwi = function (target, data, callback) {\r
616 data = {\r
617 method: 'kiwi',\r
618 args: {\r
619 target: target,\r
620 data: data\r
621 }\r
622 };\r
623\r
624 this.sendData(data, callback);\r
625 };\r
626\r
f3091277 627\r
696a66f8 628 return new (Backbone.Model.extend(this))(arguments);\r
d1b3e8b3 629};\r