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