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 .prevented(function() {
58 // The RPC call was prevented from running by a module
62 // Quick + easier way to call the above function
63 var addRpcMethod = function(rpc_method
, fn
) {
64 rpc
.on(rpc_method
, _
.partial(moduleEventWrap
, rpc_method
, fn
));
67 addRpcMethod('irc.privmsg', listeners
.privmsg
);
68 addRpcMethod('irc.ctcp', listeners
.ctcp
);
69 addRpcMethod('irc.raw', listeners
.raw
);
70 addRpcMethod('irc.join', listeners
.join
);
71 addRpcMethod('irc.channel_info', listeners
.channel_info
);
72 addRpcMethod('irc.part', listeners
.part
);
73 addRpcMethod('irc.topic', listeners
.topic
);
74 addRpcMethod('irc.kick', listeners
.kick
);
75 addRpcMethod('irc.quit', listeners
.quit
);
76 addRpcMethod('irc.notice', listeners
.notice
);
77 addRpcMethod('irc.mode', listeners
.mode
);
78 addRpcMethod('irc.nick', listeners
.nick
);
79 addRpcMethod('irc.kiwi', listeners
.kiwi
);
80 addRpcMethod('irc.encoding', listeners
.encoding
);
87 * Truncate a string into blocks of a set size
89 function truncateString(str
, block_size
) {
90 block_size
= block_size
|| 350;
95 for (current_pos
= 0; current_pos
< str
.length
; current_pos
= current_pos
+ block_size
) {
96 blocks
.push(str
.substr(current_pos
, block_size
));
106 privmsg: function (irc_connection
, callback
, args
) {
107 // Maximum length of target + message we can send to the IRC server is 500 characters
108 // but we need to leave extra room for the sender prefix so the entire message can
109 // be sent from the IRCd to the target without being truncated.
110 var blocks
= truncateString(args
.msg
, 350);
112 blocks
.forEach(function (block
, idx
) {
113 // Apply the callback on the last message only
114 var cb
= (idx
=== blocks
.length
- 1) ?
118 irc_connection
.write('PRIVMSG ' + args
.target
+ ' :' + block
, cb
);
123 ctcp: function (irc_connection
, callback
, args
) {
124 if ((args
.target
) && (args
.type
)) {
125 if (args
.is_request
) {
126 irc_connection
.write('PRIVMSG ' + args
.target
+ ' :' + String
.fromCharCode(1) + args
.type
.toUpperCase() + ' ' + args
.params
+ String
.fromCharCode(1), callback
);
128 irc_connection
.write('NOTICE ' + args
.target
+ ' :' + String
.fromCharCode(1) + args
.type
.toUpperCase() + ' ' + args
.params
+ String
.fromCharCode(1), callback
);
134 raw: function (irc_connection
, callback
, args
) {
135 irc_connection
.write(args
.data
, callback
);
139 join: function (irc_connection
, callback
, args
) {
142 channels
= args
.channel
.split(",");
143 keys
= (args
.key
) ? args
.key
.split(",") : [];
144 _
.each(channels
, function (chan
, index
) {
145 irc_connection
.write('JOIN ' + chan
+ ' ' + (keys
[index
] || ''), callback
);
151 channel_info: function (irc_connection
, callback
, args
) {
153 irc_connection
.write('MODE ' + args
.channel
, callback
);
158 part: function (irc_connection
, callback
, args
) {
160 _
.each(args
.channel
.split(","), function (chan
) {
161 irc_connection
.write('PART ' + chan
+ (args
.message
? ' :' + args
.message
: ''), callback
);
167 topic: function (irc_connection
, callback
, args
) {
170 irc_connection
.write('TOPIC ' + args
.channel
+ ' :' + args
.topic
, callback
);
172 irc_connection
.write('TOPIC ' + args
.channel
, callback
);
178 kick: function (irc_connection
, callback
, args
) {
179 if ((args
.channel
) && (args
.nick
)) {
180 irc_connection
.write('KICK ' + args
.channel
+ ' ' + args
.nick
+ ' :' + args
.reason
, callback
);
185 quit: function (irc_connection
, callback
, args
) {
186 irc_connection
.end('QUIT :' + (args
.message
||''));
190 notice: function (irc_connection
, callback
, args
) {
191 // Maximum length of target + message we can send to the IRC server is 500 characters
192 // but we need to leave extra room for the sender prefix so the entire message can
193 // be sent from the IRCd to the target without being truncated.
195 var blocks
= truncateString(args
.msg
, 350);
196 blocks
.forEach(function (block
, idx
) {
197 // Apply the callback on the last message only
198 var cb
= (idx
=== blocks
.length
- 1) ?
202 irc_connection
.write('NOTICE ' + args
.target
+ ' :' + block
, cb
);
207 mode: function (irc_connection
, callback
, args
) {
208 if ((args
.target
) && (args
.mode
)) {
209 irc_connection
.write('MODE ' + args
.target
+ ' ' + args
.mode
+ ' ' + args
.params
, callback
);
214 nick: function (irc_connection
, callback
, args
) {
216 irc_connection
.write('NICK ' + args
.nick
, callback
);
221 kiwi: function (irc_connection
, callback
, args
) {
222 if ((args
.target
) && (args
.data
)) {
223 irc_connection
.write('PRIVMSG ' + args
.target
+ ': ' + String
.fromCharCode(1) + 'KIWI ' + args
.data
+ String
.fromCharCode(1), callback
);
227 encoding: function (irc_connection
, callback
, args
) {
229 return callback(irc_connection
.setEncoding(args
.encoding
));