Commit | Line | Data |
---|---|---|
f3dbbd91 D |
1 | var util = require('util'), |
2 | events = require('events'), | |
44197e59 | 3 | _ = require('underscore'), |
1360a454 | 4 | config = require('./configuration.js'), |
2a8e95d1 D |
5 | IrcConnection = require('./irc/connection.js').IrcConnection, |
6 | IrcCommands = require('./irc/commands.js'), | |
7 | ClientCommands = require('./clientcommands.js'); | |
a8bf3ea4 | 8 | |
772a4bb6 | 9 | |
a8bf3ea4 | 10 | var Client = function (websocket) { |
772a4bb6 | 11 | var that = this; |
a8bf3ea4 JA |
12 | |
13 | events.EventEmitter.call(this); | |
14 | this.websocket = websocket; | |
15 | ||
772a4bb6 | 16 | this.irc_connections = []; |
a8bf3ea4 JA |
17 | this.next_connection = 0; |
18 | ||
19 | this.buffer = { | |
20 | list: [], | |
21 | motd: '' | |
22 | }; | |
23 | ||
f3dbbd91 | 24 | // Handler for any commands sent from the client |
2a8e95d1 | 25 | this.client_commands = new ClientCommands(this); |
f3dbbd91 | 26 | |
a8bf3ea4 | 27 | websocket.on('irc', function () { |
772a4bb6 | 28 | handleClientMessage.apply(that, arguments); |
a8bf3ea4 JA |
29 | }); |
30 | websocket.on('kiwi', function () { | |
772a4bb6 | 31 | kiwiCommand.apply(that, arguments); |
a8bf3ea4 JA |
32 | }); |
33 | websocket.on('disconnect', function () { | |
772a4bb6 | 34 | websocketDisconnect.apply(that, arguments); |
a8bf3ea4 JA |
35 | }); |
36 | websocket.on('error', function () { | |
772a4bb6 | 37 | websocketError.apply(that, arguments); |
a8bf3ea4 JA |
38 | }); |
39 | }; | |
40 | util.inherits(Client, events.EventEmitter); | |
41 | ||
42 | module.exports.Client = Client; | |
43 | ||
44 | // Callback API: | |
45 | // Callbacks SHALL accept 2 arguments, error and response, in that order. | |
46 | // error MUST be null where the command is successul. | |
47 | // error MUST otherwise be a truthy value and SHOULD be a string where the cause of the error is known. | |
48 | // response MAY be given even if error is truthy | |
49 | ||
2f1e8a71 | 50 | Client.prototype.sendIrcCommand = function (command, data, callback) { |
a8bf3ea4 | 51 | var c = {command: command, data: data}; |
a8bf3ea4 JA |
52 | this.websocket.emit('irc', c, callback); |
53 | }; | |
54 | ||
d2d91c10 D |
55 | Client.prototype.sendKiwiCommand = function (command, data, callback) { |
56 | var c = {command: command, data: data}; | |
57 | this.websocket.emit('kiwi', c, callback); | |
a8bf3ea4 JA |
58 | }; |
59 | ||
c08717da D |
60 | Client.prototype.dispose = function () { |
61 | websocketDisconnect.apply(this); | |
62 | this.removeAllListeners(); | |
63 | }; | |
64 | ||
772a4bb6 | 65 | function handleClientMessage(msg, callback) { |
f3dbbd91 D |
66 | var server, args, obj, channels, keys; |
67 | ||
68 | // Make sure we have a server number specified | |
69 | if ((msg.server === null) || (typeof msg.server !== 'number')) { | |
40af34d4 | 70 | return (typeof callback === 'function') ? callback('server not specified') : undefined; |
772a4bb6 | 71 | } else if (!this.irc_connections[msg.server]) { |
40af34d4 | 72 | return (typeof callback === 'function') ? callback('not connected to server') : undefined; |
a8bf3ea4 | 73 | } |
f3dbbd91 D |
74 | |
75 | // The server this command is directed to | |
772a4bb6 | 76 | server = this.irc_connections[msg.server]; |
f3dbbd91 D |
77 | |
78 | if (typeof callback !== 'function') { | |
79 | callback = null; | |
40ce1c01 | 80 | } |
f3dbbd91 D |
81 | |
82 | try { | |
83 | msg.data = JSON.parse(msg.data); | |
84 | } catch (e) { | |
85 | kiwi.log('[handleClientMessage] JSON parsing error ' + msg.data); | |
86 | return; | |
a8bf3ea4 | 87 | } |
f3dbbd91 D |
88 | |
89 | // Run the client command | |
90 | this.client_commands.run(msg.data.method, msg.data.args, server, callback); | |
d2d91c10 | 91 | } |
a8bf3ea4 | 92 | |
f3dbbd91 D |
93 | |
94 | ||
95 | ||
772a4bb6 | 96 | function kiwiCommand(command, callback) { |
b8e4d9f7 | 97 | var that = this; |
772a4bb6 | 98 | |
a8bf3ea4 JA |
99 | if (typeof callback !== 'function') { |
100 | callback = function () {}; | |
101 | } | |
102 | switch (command.command) { | |
103 | case 'connect': | |
2a8e95d1 | 104 | if (command.hostname && command.port && command.nick) { |
772a4bb6 | 105 | var con = new IrcConnection(command.hostname, command.port, command.ssl, |
a8bf3ea4 | 106 | command.nick, {hostname: this.websocket.handshake.revdns, address: this.websocket.handshake.address.address}, |
15fefff7 | 107 | command.password); |
a8bf3ea4 JA |
108 | |
109 | var con_num = this.next_connection++; | |
772a4bb6 | 110 | this.irc_connections[con_num] = con; |
a8bf3ea4 | 111 | |
2a8e95d1 D |
112 | var irc_commands = new IrcCommands(con, con_num, this); |
113 | irc_commands.bindEvents(); | |
a8bf3ea4 JA |
114 | |
115 | con.on('connected', function () { | |
116 | console.log("con.on('connected')"); | |
117 | return callback(null, con_num); | |
118 | }); | |
119 | ||
120 | con.on('error', function (err) { | |
d2d91c10 D |
121 | // TODO: Once multiple servers implemented, specify which server failed |
122 | //that.sendKiwiCommand('error', {server: con_num, error: err}); | |
123 | return callback(err.code, null); | |
a8bf3ea4 | 124 | }); |
b8e4d9f7 JA |
125 | |
126 | con.on('close', function () { | |
772a4bb6 | 127 | that.irc_connections[con_num] = null; |
b8e4d9f7 | 128 | }); |
a8bf3ea4 JA |
129 | } else { |
130 | return callback('Hostname, port and nickname must be specified'); | |
131 | } | |
132 | break; | |
133 | default: | |
134 | callback(); | |
135 | } | |
c08717da | 136 | } |
a8bf3ea4 | 137 | |
a8bf3ea4 | 138 | |
772a4bb6 D |
139 | // Websocket has disconnected, so quit all the IRC connections |
140 | function websocketDisconnect() { | |
141 | _.each(this.irc_connections, function (irc_connection, i, cons) { | |
b8e4d9f7 | 142 | if (irc_connection) { |
1360a454 | 143 | irc_connection.end('QUIT :' + (config.get().quit_message || '')); |
c08717da | 144 | irc_connection.dispose(); |
b8e4d9f7 JA |
145 | cons[i] = null; |
146 | } | |
147 | }); | |
a8bf3ea4 | 148 | this.emit('destroy'); |
c08717da | 149 | } |
a8bf3ea4 | 150 | |
772a4bb6 D |
151 | |
152 | // TODO: Should this close all the websocket connections too? | |
153 | function websocketError() { | |
a8bf3ea4 | 154 | this.emit('destroy'); |
c08717da | 155 | } |