1 var _
= require('lodash');
6 var ClientCommands = function (client
) {
9 module
.exports
= ClientCommands
;
11 ClientCommands
.prototype.run = function (command
, args
, irc_connection
, callback
) {
12 // Do we have a function to handle this command?
13 if (!listeners
[command
.toUpperCase()]) {
17 return listeners
[command
.toUpperCase()](args
, irc_connection
, callback
);
20 ClientCommands
.prototype.addRpcEvents = function(client
, rpc
) {
21 // Called for each RPC call
22 // addRpcMethod() below prepends the incoming RPC call with the method name and
23 // the listener that handles this call, and passes that argument list to moduleEventWrap().
24 // This gives us the chance to wrap all calls with connection_id checks and passing
25 // them off to the module system.
27 var moduleEventWrap = function(rpc_method
, the_fn
, callback
, connection_id
) {
28 var connection
, rpc_args
, fn_args
;
30 // Make sure we have a connection_id specified
31 if (!connection_id
&& connection_id
!== 0) {
32 return callback('server not specified');
34 } else if (!client
.state
.irc_connections
[connection_id
]) {
35 return callback('not connected to server');
38 // The server this command is directed to
39 connection
= client
.state
.irc_connections
[connection_id
];
41 // Get the arguments for the RPC call only (starts at 4)
42 rpc_args
= Array
.prototype.slice
.call(arguments
, 4);
44 global
.modules
.emit('rpc ' + rpc_method
, {
47 connection
: connection
50 // Listeners expect arguments in a (connection, callback, args..n) format, so preppend
51 // the connection + callback
52 fn_args
= rpc_args
.slice(0);
53 fn_args
.unshift(connection
, callback
);
55 the_fn
.apply(client
, fn_args
);
57 // The RPC call was prevented from running by a module
61 // Quick + easier way to call the above function
62 var addRpcMethod = function(rpc_method
, fn
) {
63 rpc
.on(rpc_method
, _
.partial(moduleEventWrap
, rpc_method
, fn
));
66 addRpcMethod('irc.privmsg', listeners
.privmsg
);
67 addRpcMethod('irc.ctcp', listeners
.ctcp
);
68 addRpcMethod('irc.raw', listeners
.raw
);
69 addRpcMethod('irc.join', listeners
.join
);
70 addRpcMethod('irc.channel_info', listeners
.channel_info
);
71 addRpcMethod('irc.part', listeners
.part
);
72 addRpcMethod('irc.topic', listeners
.topic
);
73 addRpcMethod('irc.kick', listeners
.kick
);
74 addRpcMethod('irc.quit', listeners
.quit
);
75 addRpcMethod('irc.notice', listeners
.notice
);
76 addRpcMethod('irc.mode', listeners
.mode
);
77 addRpcMethod('irc.nick', listeners
.nick
);
78 addRpcMethod('irc.kiwi', listeners
.kiwi
);
79 addRpcMethod('irc.encoding', listeners
.encoding
);
86 * Truncate a string into blocks of a set size
88 function truncateString(str
, block_size
) {
89 block_size
= block_size
|| 350;
94 for (current_pos
= 0; current_pos
< str
.length
; current_pos
= current_pos
+ block_size
) {
95 blocks
.push(str
.substr(current_pos
, block_size
));
105 privmsg: function (irc_connection
, callback
, args
) {
106 // Maximum length of target + message we can send to the IRC server is 500 characters
107 // but we need to leave extra room for the sender prefix so the entire message can
108 // be sent from the IRCd to the target without being truncated.
109 var blocks
= truncateString(args
.msg
, 350);
111 blocks
.forEach(function (block
, idx
) {
112 // Apply the callback on the last message only
113 var cb
= (idx
=== blocks
.length
- 1) ?
117 irc_connection
.write('PRIVMSG ' + args
.target
+ ' :' + block
, cb
);
122 ctcp: function (irc_connection
, callback
, args
) {
123 if ((args
.target
) && (args
.type
)) {
124 if (args
.is_request
) {
125 irc_connection
.write('PRIVMSG ' + args
.target
+ ' :' + String
.fromCharCode(1) + args
.type
.toUpperCase() + ' ' + args
.params
+ String
.fromCharCode(1), callback
);
127 irc_connection
.write('NOTICE ' + args
.target
+ ' :' + String
.fromCharCode(1) + args
.type
.toUpperCase() + ' ' + args
.params
+ String
.fromCharCode(1), callback
);
133 raw: function (irc_connection
, callback
, args
) {
134 irc_connection
.write(args
.data
, callback
);
138 join: function (irc_connection
, callback
, args
) {
141 channels
= args
.channel
.split(",");
142 keys
= (args
.key
) ? args
.key
.split(",") : [];
143 _
.each(channels
, function (chan
, index
) {
144 irc_connection
.write('JOIN ' + chan
+ ' ' + (keys
[index
] || ''), callback
);
150 channel_info: function (irc_connection
, callback
, args
) {
152 irc_connection
.write('MODE ' + args
.channel
, callback
);
157 part: function (irc_connection
, callback
, args
) {
159 _
.each(args
.channel
.split(","), function (chan
) {
160 irc_connection
.write('PART ' + chan
+ (args
.message
? ' :' + args
.message
: ''), callback
);
166 topic: function (irc_connection
, callback
, args
) {
169 irc_connection
.write('TOPIC ' + args
.channel
+ ' :' + args
.topic
, callback
);
171 irc_connection
.write('TOPIC ' + args
.channel
, callback
);
177 kick: function (irc_connection
, callback
, args
) {
178 if ((args
.channel
) && (args
.nick
)) {
179 irc_connection
.write('KICK ' + args
.channel
+ ' ' + args
.nick
+ ' :' + args
.reason
, callback
);
184 quit: function (irc_connection
, callback
, args
) {
185 irc_connection
.end('QUIT :' + (args
.message
||''));
189 notice: function (irc_connection
, callback
, args
) {
190 // Maximum length of target + message we can send to the IRC server is 500 characters
191 // but we need to leave extra room for the sender prefix so the entire message can
192 // be sent from the IRCd to the target without being truncated.
194 var blocks
= truncateString(args
.msg
, 350);
195 blocks
.forEach(function (block
, idx
) {
196 // Apply the callback on the last message only
197 var cb
= (idx
=== blocks
.length
- 1) ?
201 irc_connection
.write('NOTICE ' + args
.target
+ ' :' + block
, cb
);
206 mode: function (irc_connection
, callback
, args
) {
207 if ((args
.target
) && (args
.mode
)) {
208 irc_connection
.write('MODE ' + args
.target
+ ' ' + args
.mode
+ ' ' + args
.params
, callback
);
213 nick: function (irc_connection
, callback
, args
) {
215 irc_connection
.write('NICK ' + args
.nick
, callback
);
220 kiwi: function (irc_connection
, callback
, args
) {
221 if ((args
.target
) && (args
.data
)) {
222 irc_connection
.write('PRIVMSG ' + args
.target
+ ': ' + String
.fromCharCode(1) + 'KIWI ' + args
.data
+ String
.fromCharCode(1), callback
);
226 encoding: function (irc_connection
, callback
, args
) {
228 return callback(irc_connection
.setEncoding(args
.encoding
));