Log client startup errors to console
[KiwiIRC.git] / server / clientcommands.js
CommitLineData
f9ff7686 1var _ = require('lodash');\r
f3dbbd91
D
2\r
3\r
4\r
5\r
2a8e95d1 6var ClientCommands = function (client) {\r
f3dbbd91
D
7 this.client = client;\r
8};\r
2a8e95d1 9module.exports = ClientCommands;\r
f3dbbd91 10\r
2a8e95d1 11ClientCommands.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
20ClientCommands.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
88function 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 104var 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