Commit | Line | Data |
---|---|---|
a8bf3ea4 JA |
1 | var util = require('util'), |
2 | events = require('events'), | |
3 | IRCConnection = require('./irc-connection.js').IRCConnection; | |
4 | IRCCommands = require('./irc-commands.js'); | |
5 | ||
6 | var Client = function (websocket) { | |
7 | var c = this; | |
8 | ||
9 | events.EventEmitter.call(this); | |
10 | this.websocket = websocket; | |
11 | ||
12 | this.IRC_connections = []; | |
13 | this.next_connection = 0; | |
14 | ||
15 | this.buffer = { | |
16 | list: [], | |
17 | motd: '' | |
18 | }; | |
19 | ||
20 | websocket.on('irc', function () { | |
21 | IRC_command.apply(c, arguments); | |
22 | }); | |
23 | websocket.on('kiwi', function () { | |
24 | kiwi_command.apply(c, arguments); | |
25 | }); | |
26 | websocket.on('disconnect', function () { | |
27 | disconnect.apply(c, arguments); | |
28 | }); | |
29 | websocket.on('error', function () { | |
30 | error.apply(c, arguments); | |
31 | }); | |
32 | }; | |
33 | util.inherits(Client, events.EventEmitter); | |
34 | ||
35 | module.exports.Client = Client; | |
36 | ||
37 | // Callback API: | |
38 | // Callbacks SHALL accept 2 arguments, error and response, in that order. | |
39 | // error MUST be null where the command is successul. | |
40 | // error MUST otherwise be a truthy value and SHOULD be a string where the cause of the error is known. | |
41 | // response MAY be given even if error is truthy | |
42 | ||
43 | Client.prototype.sendIRCCommand = function (command, data, callback) { | |
44 | var c = {command: command, data: data}; | |
45 | console.log('C<--', c); | |
46 | this.websocket.emit('irc', c, callback); | |
47 | }; | |
48 | ||
49 | Client.prototype.sendKiwiCommand = function (command, callback) { | |
50 | this.websocket.emit('kiwi', command, callback); | |
51 | }; | |
52 | ||
53 | var IRC_command = function (command, callback) { | |
54 | console.log('C-->', command); | |
55 | var method, str = ''; | |
56 | if (typeof callback !== 'function') { | |
57 | callback = function () {}; | |
58 | } | |
59 | if ((command.server === null) || (typeof command.server !== 'number')) { | |
60 | return callback('server not specified'); | |
61 | } else if (!this.IRC_connections[command.server]) { | |
62 | return callback('not connected to server'); | |
63 | } | |
64 | ||
65 | command.data = JSON.parse(command.data); | |
66 | ||
40ce1c01 JA |
67 | if (!_.isArray(command.data.args.params)){ |
68 | command.data.args.params = [command.data.args.params]; | |
69 | } | |
70 | ||
a8bf3ea4 JA |
71 | if (command.data.method === 'ctcp') { |
72 | if (command.data.args.request) { | |
73 | str += 'PRIVMSG '; | |
74 | } else { | |
75 | str += 'NOTICE '; | |
76 | } | |
77 | str += command.data.args.target + ' :' | |
78 | str += String.fromCharCode(1) + command.data.args.type + ' '; | |
79 | str += command.data.args.params + String.fromCharCode(1); | |
b8e4d9f7 | 80 | this.IRC_connections[command.server].write(str); |
a8bf3ea4 | 81 | } else if (command.data.method === 'raw') { |
b8e4d9f7 | 82 | this.IRC_connections[command.server].write(command.data.args.data); |
a8bf3ea4 JA |
83 | } else if (command.data.method === 'kiwi') { |
84 | // do special Kiwi stuff here | |
85 | } else { | |
86 | method = command.data.method; | |
87 | command.data = command.data.args; | |
b8e4d9f7 | 88 | this.IRC_connections[command.server].write(method + ((command.data.params) ? ' ' + command.data.params.join(' ') : '') + ((command.data.trailing) ? ' :' + command.data.trailing : ''), callback); |
a8bf3ea4 JA |
89 | } |
90 | }; | |
91 | ||
92 | var kiwi_command = function (command, callback) { | |
b8e4d9f7 | 93 | var that = this; |
a8bf3ea4 JA |
94 | console.log(typeof callback); |
95 | if (typeof callback !== 'function') { | |
96 | callback = function () {}; | |
97 | } | |
98 | switch (command.command) { | |
99 | case 'connect': | |
100 | if ((command.hostname) && (command.port) && (command.nick)) { | |
101 | var con = new IRCConnection(command.hostname, command.port, command.ssl, | |
102 | command.nick, {hostname: this.websocket.handshake.revdns, address: this.websocket.handshake.address.address}, | |
103 | command.password, null); | |
104 | ||
105 | var con_num = this.next_connection++; | |
106 | this.IRC_connections[con_num] = con; | |
107 | ||
108 | var binder = new IRCCommands.Binder(con, con_num, this); | |
109 | binder.bind_irc_commands(); | |
110 | ||
111 | con.on('connected', function () { | |
112 | console.log("con.on('connected')"); | |
113 | return callback(null, con_num); | |
114 | }); | |
115 | ||
116 | con.on('error', function (err) { | |
117 | this.websocket.sendKiwiCommand('error', {server: con_num, error: err}); | |
118 | }); | |
b8e4d9f7 JA |
119 | |
120 | con.on('close', function () { | |
121 | that.IRC_connections[con_num] = null; | |
122 | }); | |
a8bf3ea4 JA |
123 | } else { |
124 | return callback('Hostname, port and nickname must be specified'); | |
125 | } | |
126 | break; | |
127 | default: | |
128 | callback(); | |
129 | } | |
130 | }; | |
131 | ||
132 | var extension_command = function (command, callback) { | |
133 | if (typeof callback === 'function') { | |
134 | callback('not implemented'); | |
135 | } | |
136 | }; | |
137 | ||
138 | var disconnect = function () { | |
b8e4d9f7 JA |
139 | _.each(this.IRC_connections, function (irc_connection, i, cons) { |
140 | if (irc_connection) { | |
141 | irc_connection.end('QUIT :Kiwi IRC'); | |
142 | cons[i] = null; | |
143 | } | |
144 | }); | |
a8bf3ea4 JA |
145 | this.emit('destroy'); |
146 | }; | |
147 | ||
148 | var error = function () { | |
149 | this.emit('destroy'); | |
150 | }; |