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 | |
55d0f0b1 | 49 | .then(function() {\r |
ac102e9d D |
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 | |
55d0f0b1 | 56 | }, function() {\r |
ac102e9d D |
57 | // The RPC call was prevented from running by a module\r |
58 | });\r | |
59 | };\r | |
60 | \r | |
61 | // Quick + easier way to call the above function\r | |
62 | var addRpcMethod = function(rpc_method, fn) {\r | |
63 | rpc.on(rpc_method, _.partial(moduleEventWrap, rpc_method, fn));\r | |
64 | };\r | |
65 | \r | |
66 | addRpcMethod('irc.privmsg', listeners.privmsg);\r | |
67 | addRpcMethod('irc.ctcp', listeners.ctcp);\r | |
68 | addRpcMethod('irc.raw', listeners.raw);\r | |
69 | addRpcMethod('irc.join', listeners.join);\r | |
70 | addRpcMethod('irc.channel_info', listeners.channel_info);\r | |
71 | addRpcMethod('irc.part', listeners.part);\r | |
72 | addRpcMethod('irc.topic', listeners.topic);\r | |
73 | addRpcMethod('irc.kick', listeners.kick);\r | |
74 | addRpcMethod('irc.quit', listeners.quit);\r | |
75 | addRpcMethod('irc.notice', listeners.notice);\r | |
76 | addRpcMethod('irc.mode', listeners.mode);\r | |
77 | addRpcMethod('irc.nick', listeners.nick);\r | |
78 | addRpcMethod('irc.kiwi', listeners.kiwi);\r | |
79 | addRpcMethod('irc.encoding', listeners.encoding);\r | |
80 | };\r | |
81 | \r | |
f3dbbd91 D |
82 | \r |
83 | \r | |
84 | \r | |
0cd61eb7 D |
85 | /**\r |
86 | * Truncate a string into blocks of a set size\r | |
87 | */\r | |
88 | function truncateString(str, block_size) {\r | |
89 | block_size = block_size || 350;\r | |
90 | \r | |
91 | var blocks = [],\r | |
92 | current_pos;\r | |
93 | \r | |
94 | for (current_pos = 0; current_pos < str.length; current_pos = current_pos + block_size) {\r | |
95 | blocks.push(str.substr(current_pos, block_size));\r | |
96 | }\r | |
97 | \r | |
98 | return blocks;\r | |
99 | }\r | |
100 | \r | |
101 | \r | |
102 | \r | |
103 | \r | |
f3dbbd91 | 104 | var listeners = {\r |
ac102e9d | 105 | privmsg: function (irc_connection, callback, args) {\r |
5328acca JA |
106 | // Maximum length of target + message we can send to the IRC server is 500 characters\r |
107 | // but we need to leave extra room for the sender prefix so the entire message can\r | |
108 | // be sent from the IRCd to the target without being truncated.\r | |
0cd61eb7 | 109 | var blocks = truncateString(args.msg, 350);\r |
ac102e9d | 110 | \r |
a22a69f3 D |
111 | blocks.forEach(function (block, idx) {\r |
112 | // Apply the callback on the last message only\r | |
113 | var cb = (idx === blocks.length - 1) ?\r | |
114 | callback :\r | |
115 | undefined;\r | |
116 | \r | |
117 | irc_connection.write('PRIVMSG ' + args.target + ' :' + block, cb);\r | |
0cd61eb7 | 118 | });\r |
f3dbbd91 | 119 | },\r |
72db27e4 | 120 | \r |
f3dbbd91 | 121 | \r |
ac102e9d | 122 | ctcp: function (irc_connection, callback, args) {\r |
f3dbbd91 | 123 | if ((args.target) && (args.type)) {\r |
d07c8435 | 124 | if (args.is_request) {\r |
f3dbbd91 D |
125 | irc_connection.write('PRIVMSG ' + args.target + ' :' + String.fromCharCode(1) + args.type.toUpperCase() + ' ' + args.params + String.fromCharCode(1), callback);\r |
126 | } else {\r | |
127 | irc_connection.write('NOTICE ' + args.target + ' :' + String.fromCharCode(1) + args.type.toUpperCase() + ' ' + args.params + String.fromCharCode(1), callback);\r | |
128 | }\r | |
129 | }\r | |
130 | },\r | |
131 | \r | |
132 | \r | |
ac102e9d | 133 | raw: function (irc_connection, callback, args) {\r |
f3dbbd91 D |
134 | irc_connection.write(args.data, callback);\r |
135 | },\r | |
136 | \r | |
137 | \r | |
ac102e9d D |
138 | join: function (irc_connection, callback, args) {\r |
139 | var channels, keys;\r | |
f3dbbd91 D |
140 | if (args.channel) {\r |
141 | channels = args.channel.split(",");\r | |
142 | keys = (args.key) ? args.key.split(",") : [];\r | |
143 | _.each(channels, function (chan, index) {\r | |
144 | irc_connection.write('JOIN ' + chan + ' ' + (keys[index] || ''), callback);\r | |
145 | });\r | |
146 | }\r | |
147 | },\r | |
148 | \r | |
149 | \r | |
ac102e9d | 150 | channel_info: function (irc_connection, callback, args) {\r |
72db27e4 D |
151 | if (args.channel) {\r |
152 | irc_connection.write('MODE ' + args.channel, callback);\r | |
153 | }\r | |
154 | },\r | |
155 | \r | |
156 | \r | |
ac102e9d | 157 | part: function (irc_connection, callback, args) {\r |
f3dbbd91 D |
158 | if (args.channel) {\r |
159 | _.each(args.channel.split(","), function (chan) {\r | |
7f272ac9 | 160 | irc_connection.write('PART ' + chan + (args.message ? ' :' + args.message : ''), callback);\r |
f3dbbd91 D |
161 | });\r |
162 | }\r | |
163 | },\r | |
164 | \r | |
165 | \r | |
ac102e9d | 166 | topic: function (irc_connection, callback, args) {\r |
f3dbbd91 D |
167 | if (args.channel) {\r |
168 | if (args.topic) {\r | |
169 | irc_connection.write('TOPIC ' + args.channel + ' :' + args.topic, callback);\r | |
170 | } else {\r | |
171 | irc_connection.write('TOPIC ' + args.channel, callback);\r | |
172 | }\r | |
173 | }\r | |
174 | },\r | |
175 | \r | |
176 | \r | |
ac102e9d | 177 | kick: function (irc_connection, callback, args) {\r |
f3dbbd91 | 178 | if ((args.channel) && (args.nick)) {\r |
fc677b4c | 179 | irc_connection.write('KICK ' + args.channel + ' ' + args.nick + ' :' + args.reason, callback);\r |
f3dbbd91 D |
180 | }\r |
181 | },\r | |
182 | \r | |
183 | \r | |
ac102e9d | 184 | quit: function (irc_connection, callback, args) {\r |
e32ff87b | 185 | irc_connection.end('QUIT :' + (args.message||''));\r |
f3dbbd91 D |
186 | },\r |
187 | \r | |
188 | \r | |
ac102e9d | 189 | notice: function (irc_connection, callback, args) {\r |
5328acca JA |
190 | // Maximum length of target + message we can send to the IRC server is 500 characters\r |
191 | // but we need to leave extra room for the sender prefix so the entire message can\r | |
192 | // be sent from the IRCd to the target without being truncated.\r | |
0cd61eb7 D |
193 | \r |
194 | var blocks = truncateString(args.msg, 350);\r | |
a22a69f3 D |
195 | blocks.forEach(function (block, idx) {\r |
196 | // Apply the callback on the last message only\r | |
197 | var cb = (idx === blocks.length - 1) ?\r | |
198 | callback :\r | |
199 | undefined;\r | |
200 | \r | |
201 | irc_connection.write('NOTICE ' + args.target + ' :' + block, cb);\r | |
0cd61eb7 | 202 | });\r |
f3dbbd91 D |
203 | },\r |
204 | \r | |
205 | \r | |
ac102e9d | 206 | mode: function (irc_connection, callback, args) {\r |
f3dbbd91 D |
207 | if ((args.target) && (args.mode)) {\r |
208 | irc_connection.write('MODE ' + args.target + ' ' + args.mode + ' ' + args.params, callback);\r | |
209 | }\r | |
210 | },\r | |
211 | \r | |
212 | \r | |
ac102e9d | 213 | nick: function (irc_connection, callback, args) {\r |
f3dbbd91 D |
214 | if (args.nick) {\r |
215 | irc_connection.write('NICK ' + args.nick, callback);\r | |
216 | }\r | |
217 | },\r | |
218 | \r | |
219 | \r | |
ac102e9d | 220 | kiwi: function (irc_connection, callback, args) {\r |
f3dbbd91 D |
221 | if ((args.target) && (args.data)) {\r |
222 | irc_connection.write('PRIVMSG ' + args.target + ': ' + String.fromCharCode(1) + 'KIWI ' + args.data + String.fromCharCode(1), callback);\r | |
223 | }\r | |
d1b3e8b3 VDF |
224 | },\r |
225 | \r | |
ac102e9d | 226 | encoding: function (irc_connection, callback, args) {\r |
d1b3e8b3 | 227 | if (args.encoding) {\r |
3efb4f33 | 228 | return callback(irc_connection.setEncoding(args.encoding));\r |
d1b3e8b3 | 229 | }\r |
f3dbbd91 D |
230 | }\r |
231 | };\r |