merging extensive changes from prawnsalad/KiwiIRC
[KiwiIRC.git] / server / client.js
CommitLineData
a8bf3ea4
JA
1var util = require('util'),
2 events = require('events'),
3 IRCConnection = require('./irc-connection.js').IRCConnection;
4 IRCCommands = require('./irc-commands.js');
5
6var 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};
33util.inherits(Client, events.EventEmitter);
34
35module.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
43Client.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
49Client.prototype.sendKiwiCommand = function (command, callback) {
50 this.websocket.emit('kiwi', command, callback);
51};
52
53var 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
92var 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
132var extension_command = function (command, callback) {
133 if (typeof callback === 'function') {
134 callback('not implemented');
135 }
136};
137
138var 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
148var error = function () {
149 this.emit('destroy');
150};