1 var util
= require('util'),
2 events
= require('events'),
3 _
= require('underscore'),
4 IrcConnection
= require('./ircconnection.js').IrcConnection
,
5 IrcCommands
= require('./irc-commands.js'),
6 ClientCommandset
= require('./client-commands.js').ClientCommandset
;
9 var Client = function (websocket
) {
12 events
.EventEmitter
.call(this);
13 this.websocket
= websocket
;
15 this.irc_connections
= [];
16 this.next_connection
= 0;
23 // Handler for any commands sent from the client
24 this.client_commands
= new ClientCommandset(this);
26 websocket
.on('irc', function () {
27 handleClientMessage
.apply(that
, arguments
);
29 websocket
.on('kiwi', function () {
30 kiwiCommand
.apply(that
, arguments
);
32 websocket
.on('disconnect', function () {
33 websocketDisconnect
.apply(that
, arguments
);
35 websocket
.on('error', function () {
36 websocketError
.apply(that
, arguments
);
39 util
.inherits(Client
, events
.EventEmitter
);
41 module
.exports
.Client
= Client
;
44 // Callbacks SHALL accept 2 arguments, error and response, in that order.
45 // error MUST be null where the command is successul.
46 // error MUST otherwise be a truthy value and SHOULD be a string where the cause of the error is known.
47 // response MAY be given even if error is truthy
49 Client
.prototype.sendIRCCommand = function (command
, data
, callback
) {
50 var c
= {command
: command
, data
: data
};
51 //console.log('C<--', c);
52 this.websocket
.emit('irc', c
, callback
);
55 Client
.prototype.sendKiwiCommand = function (command
, callback
) {
56 this.websocket
.emit('kiwi', command
, callback
);
59 function handleClientMessage(msg
, callback
) {
60 var server
, args
, obj
, channels
, keys
;
62 // Make sure we have a server number specified
63 if ((msg
.server
=== null) || (typeof msg
.server
!== 'number')) {
64 return (typeof callback
=== 'function') ? callback('server not specified') : undefined;
65 } else if (!this.irc_connections
[msg
.server
]) {
66 return (typeof callback
=== 'function') ? callback('not connected to server') : undefined;
69 // The server this command is directed to
70 server
= this.irc_connections
[msg
.server
];
72 if (typeof callback
!== 'function') {
77 msg
.data
= JSON
.parse(msg
.data
);
79 kiwi
.log('[handleClientMessage] JSON parsing error ' + msg
.data
);
83 // Run the client command
84 this.client_commands
.run(msg
.data
.method
, msg
.data
.args
, server
, callback
);
90 function kiwiCommand(command
, callback
) {
93 if (typeof callback
!== 'function') {
94 callback = function () {};
96 switch (command
.command
) {
98 if ((command
.hostname
) && (command
.port
) && (command
.nick
)) {
99 var con
= new IrcConnection(command
.hostname
, command
.port
, command
.ssl
,
100 command
.nick
, {hostname
: this.websocket
.handshake
.revdns
, address
: this.websocket
.handshake
.address
.address
},
101 command
.password
, null);
103 var con_num
= this.next_connection
++;
104 this.irc_connections
[con_num
] = con
;
106 var binder
= new IrcCommands
.Binder(con
, con_num
, this);
107 binder
.bind_irc_commands();
109 con
.on('connected', function () {
110 console
.log("con.on('connected')");
111 return callback(null, con_num
);
114 con
.on('error', function (err
) {
115 this.websocket
.sendKiwiCommand('error', {server
: con_num
, error
: err
});
118 con
.on('close', function () {
119 that
.irc_connections
[con_num
] = null;
122 return callback('Hostname, port and nickname must be specified');
131 // Websocket has disconnected, so quit all the IRC connections
132 function websocketDisconnect() {
133 _
.each(this.irc_connections
, function (irc_connection
, i
, cons
) {
134 if (irc_connection
) {
135 irc_connection
.end('QUIT :Kiwi IRC');
139 this.emit('destroy');
143 // TODO: Should this close all the websocket connections too?
144 function websocketError() {
145 this.emit('destroy');