Commit | Line | Data |
---|---|---|
f9ff7686 | 1 | var _ = require('lodash');\r |
f3dbbd91 D |
2 | \r |
3 | \r | |
4 | \r | |
5 | \r | |
2a8e95d1 | 6 | var ClientCommands = function (client) {\r |
f3dbbd91 D |
7 | this.client = client;\r |
8 | };\r | |
2a8e95d1 | 9 | module.exports = ClientCommands;\r |
f3dbbd91 | 10 | \r |
2a8e95d1 | 11 | ClientCommands.prototype.run = function (command, args, irc_connection, callback) {\r |
f3dbbd91 D |
12 | // Do we have a function to handle this command?\r |
13 | if (!listeners[command.toUpperCase()]) {\r | |
14 | return;\r | |
15 | }\r | |
16 | \r | |
17 | return listeners[command.toUpperCase()](args, irc_connection, callback);\r | |
18 | };\r | |
19 | \r | |
ac102e9d D |
20 | ClientCommands.prototype.addRpcEvents = function(client, rpc) {\r |
21 | // Called for each RPC call\r | |
22 | // addRpcMethod() below prepends the incoming RPC call with the method name and\r | |
23 | // the listener that handles this call, and passes that argument list to moduleEventWrap().\r | |
24 | // This gives us the chance to wrap all calls with connection_id checks and passing\r | |
25 | // them off to the module system.\r | |
26 | \r | |
27 | var moduleEventWrap = function(rpc_method, the_fn, callback, connection_id) {\r | |
28 | var connection, rpc_args, fn_args;\r | |
29 | \r | |
30 | // Make sure we have a connection_id specified\r | |
31 | if (!connection_id && connection_id !== 0) {\r | |
32 | return callback('server not specified');\r | |
33 | \r | |
34 | } else if (!client.state.irc_connections[connection_id]) {\r | |
35 | return callback('not connected to server');\r | |
36 | }\r | |
37 | \r | |
38 | // The server this command is directed to\r | |
39 | connection = client.state.irc_connections[connection_id];\r | |
40 | \r | |
41 | // Get the arguments for the RPC call only (starts at 4)\r | |
42 | rpc_args = Array.prototype.slice.call(arguments, 4);\r | |
43 | \r | |
44 | global.modules.emit('rpc ' + rpc_method, {\r | |
45 | arguments: rpc_args,\r | |
46 | client: client,\r | |
47 | connection: connection\r | |
48 | })\r | |
49 | .done(function() {\r | |
50 | // Listeners expect arguments in a (connection, callback, args..n) format, so preppend\r | |
51 | // the connection + callback\r | |
52 | fn_args = rpc_args.slice(0);\r | |
53 | fn_args.unshift(connection, callback);\r | |
54 | \r | |
55 | the_fn.apply(client, fn_args);\r | |
56 | })\r | |
57 | .prevented(function() {\r | |
58 | // The RPC call was prevented from running by a module\r | |
59 | });\r | |
60 | };\r | |
61 | \r | |
62 | // Quick + easier way to call the above function\r | |
63 | var addRpcMethod = function(rpc_method, fn) {\r | |
64 | rpc.on(rpc_method, _.partial(moduleEventWrap, rpc_method, fn));\r | |
65 | };\r | |
66 | \r | |
67 | addRpcMethod('irc.privmsg', listeners.privmsg);\r | |
68 | addRpcMethod('irc.ctcp', listeners.ctcp);\r | |
69 | addRpcMethod('irc.raw', listeners.raw);\r | |
70 | addRpcMethod('irc.join', listeners.join);\r | |
71 | addRpcMethod('irc.channel_info', listeners.channel_info);\r | |
72 | addRpcMethod('irc.part', listeners.part);\r | |
73 | addRpcMethod('irc.topic', listeners.topic);\r | |
74 | addRpcMethod('irc.kick', listeners.kick);\r | |
75 | addRpcMethod('irc.quit', listeners.quit);\r | |
76 | addRpcMethod('irc.notice', listeners.notice);\r | |
77 | addRpcMethod('irc.mode', listeners.mode);\r | |
78 | addRpcMethod('irc.nick', listeners.nick);\r | |
79 | addRpcMethod('irc.kiwi', listeners.kiwi);\r | |
80 | addRpcMethod('irc.encoding', listeners.encoding);\r | |
81 | };\r | |
82 | \r | |
f3dbbd91 D |
83 | \r |
84 | \r | |
85 | \r | |
0cd61eb7 D |
86 | /**\r |
87 | * Truncate a string into blocks of a set size\r | |
88 | */\r | |
89 | function truncateString(str, block_size) {\r | |
90 | block_size = block_size || 350;\r | |
91 | \r | |
92 | var blocks = [],\r | |
93 | current_pos;\r | |
94 | \r | |
95 | for (current_pos = 0; current_pos < str.length; current_pos = current_pos + block_size) {\r | |
96 | blocks.push(str.substr(current_pos, block_size));\r | |
97 | }\r | |
98 | \r | |
99 | return blocks;\r | |
100 | }\r | |
101 | \r | |
102 | \r | |
103 | \r | |
104 | \r | |
f3dbbd91 | 105 | var listeners = {\r |
ac102e9d | 106 | privmsg: function (irc_connection, callback, args) {\r |
5328acca JA |
107 | // Maximum length of target + message we can send to the IRC server is 500 characters\r |
108 | // but we need to leave extra room for the sender prefix so the entire message can\r | |
109 | // be sent from the IRCd to the target without being truncated.\r | |
0cd61eb7 | 110 | var blocks = truncateString(args.msg, 350);\r |
ac102e9d | 111 | \r |
a22a69f3 D |
112 | blocks.forEach(function (block, idx) {\r |
113 | // Apply the callback on the last message only\r | |
114 | var cb = (idx === blocks.length - 1) ?\r | |
115 | callback :\r | |
116 | undefined;\r | |
117 | \r | |
118 | irc_connection.write('PRIVMSG ' + args.target + ' :' + block, cb);\r | |
0cd61eb7 | 119 | });\r |
f3dbbd91 | 120 | },\r |
72db27e4 | 121 | \r |
f3dbbd91 | 122 | \r |
ac102e9d | 123 | ctcp: function (irc_connection, callback, args) {\r |
f3dbbd91 | 124 | if ((args.target) && (args.type)) {\r |
d07c8435 | 125 | if (args.is_request) {\r |
f3dbbd91 D |
126 | irc_connection.write('PRIVMSG ' + args.target + ' :' + String.fromCharCode(1) + args.type.toUpperCase() + ' ' + args.params + String.fromCharCode(1), callback);\r |
127 | } else {\r | |
128 | irc_connection.write('NOTICE ' + args.target + ' :' + String.fromCharCode(1) + args.type.toUpperCase() + ' ' + args.params + String.fromCharCode(1), callback);\r | |
129 | }\r | |
130 | }\r | |
131 | },\r | |
132 | \r | |
133 | \r | |
ac102e9d | 134 | raw: function (irc_connection, callback, args) {\r |
f3dbbd91 D |
135 | irc_connection.write(args.data, callback);\r |
136 | },\r | |
137 | \r | |
138 | \r | |
ac102e9d D |
139 | join: function (irc_connection, callback, args) {\r |
140 | var channels, keys;\r | |
f3dbbd91 D |
141 | if (args.channel) {\r |
142 | channels = args.channel.split(",");\r | |
143 | keys = (args.key) ? args.key.split(",") : [];\r | |
144 | _.each(channels, function (chan, index) {\r | |
145 | irc_connection.write('JOIN ' + chan + ' ' + (keys[index] || ''), callback);\r | |
146 | });\r | |
147 | }\r | |
148 | },\r | |
149 | \r | |
150 | \r | |
ac102e9d | 151 | channel_info: function (irc_connection, callback, args) {\r |
72db27e4 D |
152 | if (args.channel) {\r |
153 | irc_connection.write('MODE ' + args.channel, callback);\r | |
154 | }\r | |
155 | },\r | |
156 | \r | |
157 | \r | |
ac102e9d | 158 | part: function (irc_connection, callback, args) {\r |
f3dbbd91 D |
159 | if (args.channel) {\r |
160 | _.each(args.channel.split(","), function (chan) {\r | |
7f272ac9 | 161 | irc_connection.write('PART ' + chan + (args.message ? ' :' + args.message : ''), callback);\r |
f3dbbd91 D |
162 | });\r |
163 | }\r | |
164 | },\r | |
165 | \r | |
166 | \r | |
ac102e9d | 167 | topic: function (irc_connection, callback, args) {\r |
f3dbbd91 D |
168 | if (args.channel) {\r |
169 | if (args.topic) {\r | |
170 | irc_connection.write('TOPIC ' + args.channel + ' :' + args.topic, callback);\r | |
171 | } else {\r | |
172 | irc_connection.write('TOPIC ' + args.channel, callback);\r | |
173 | }\r | |
174 | }\r | |
175 | },\r | |
176 | \r | |
177 | \r | |
ac102e9d | 178 | kick: function (irc_connection, callback, args) {\r |
f3dbbd91 | 179 | if ((args.channel) && (args.nick)) {\r |
fc677b4c | 180 | irc_connection.write('KICK ' + args.channel + ' ' + args.nick + ' :' + args.reason, callback);\r |
f3dbbd91 D |
181 | }\r |
182 | },\r | |
183 | \r | |
184 | \r | |
ac102e9d | 185 | quit: function (irc_connection, callback, args) {\r |
e32ff87b | 186 | irc_connection.end('QUIT :' + (args.message||''));\r |
f3dbbd91 D |
187 | },\r |
188 | \r | |
189 | \r | |
ac102e9d | 190 | notice: function (irc_connection, callback, args) {\r |
5328acca JA |
191 | // Maximum length of target + message we can send to the IRC server is 500 characters\r |
192 | // but we need to leave extra room for the sender prefix so the entire message can\r | |
193 | // be sent from the IRCd to the target without being truncated.\r | |
0cd61eb7 D |
194 | \r |
195 | var blocks = truncateString(args.msg, 350);\r | |
a22a69f3 D |
196 | blocks.forEach(function (block, idx) {\r |
197 | // Apply the callback on the last message only\r | |
198 | var cb = (idx === blocks.length - 1) ?\r | |
199 | callback :\r | |
200 | undefined;\r | |
201 | \r | |
202 | irc_connection.write('NOTICE ' + args.target + ' :' + block, cb);\r | |
0cd61eb7 | 203 | });\r |
f3dbbd91 D |
204 | },\r |
205 | \r | |
206 | \r | |
ac102e9d | 207 | mode: function (irc_connection, callback, args) {\r |
f3dbbd91 D |
208 | if ((args.target) && (args.mode)) {\r |
209 | irc_connection.write('MODE ' + args.target + ' ' + args.mode + ' ' + args.params, callback);\r | |
210 | }\r | |
211 | },\r | |
212 | \r | |
213 | \r | |
ac102e9d | 214 | nick: function (irc_connection, callback, args) {\r |
f3dbbd91 D |
215 | if (args.nick) {\r |
216 | irc_connection.write('NICK ' + args.nick, callback);\r | |
217 | }\r | |
218 | },\r | |
219 | \r | |
220 | \r | |
ac102e9d | 221 | kiwi: function (irc_connection, callback, args) {\r |
f3dbbd91 D |
222 | if ((args.target) && (args.data)) {\r |
223 | irc_connection.write('PRIVMSG ' + args.target + ': ' + String.fromCharCode(1) + 'KIWI ' + args.data + String.fromCharCode(1), callback);\r | |
224 | }\r | |
d1b3e8b3 VDF |
225 | },\r |
226 | \r | |
ac102e9d | 227 | encoding: function (irc_connection, callback, args) {\r |
d1b3e8b3 | 228 | if (args.encoding) {\r |
3efb4f33 | 229 | return callback(irc_connection.setEncoding(args.encoding));\r |
d1b3e8b3 | 230 | }\r |
f3dbbd91 D |
231 | }\r |
232 | };\r |