]> jfr.im git - irc/quakenet/newserv.git/blob - lua/luacommands.c
Add chanfix and clearmode commands to lua.
[irc/quakenet/newserv.git] / lua / luacommands.c
1 /* Copyright (C) Chris Porter 2005 */
2 /* ALL RIGHTS RESERVED. */
3 /* Don't put this into the SVN repo. */
4
5 #include "../channel/channel.h"
6 #include "../control/control.h"
7 #include "../nick/nick.h"
8 #include "../localuser/localuser.h"
9 #include "../localuser/localuserchannel.h"
10 #include "../lib/irc_string.h"
11
12 #include "lua.h"
13 #include "luabot.h"
14
15 #include <stdarg.h>
16
17 static int lua_smsg(lua_State *ps);
18 static int lua_skill(lua_State *ps);
19
20 int lua_lineok(const char *data) {
21 if(strchr(data, '\r') || strchr(data, '\n'))
22 return 0;
23 return 1;
24 }
25
26 int lua_cmsg(char *channell, char *message, ...) {
27 char buf[512];
28 va_list va;
29 channel *cp;
30
31 va_start(va, message);
32 vsnprintf(buf, sizeof(buf), message, va);
33 va_end(va);
34
35 cp = findchannel(channell);
36 if(!cp)
37 return LUA_FAIL;
38
39 if(!lua_lineok(buf))
40 return LUA_FAIL;
41
42 lua_channelmessage(cp, "%s", buf);
43
44 return LUA_OK;
45 }
46
47 static int lua_chanmsg(lua_State *ps) {
48 if(!lua_isstring(ps, 1))
49 LUA_RETURN(ps, LUA_FAIL);
50
51 LUA_RETURN(ps, lua_cmsg(LUA_PUKECHAN, "lua: %s", lua_tostring(ps, 1)));
52 }
53
54 static int lua_scripterror(lua_State *ps) {
55 if(!lua_isstring(ps, 1))
56 LUA_RETURN(ps, LUA_FAIL);
57
58 LUA_RETURN(ps, lua_cmsg(LUA_PUKECHAN, "lua-error: %s", lua_tostring(ps, 1)));
59 }
60
61 static int lua_ctcp(lua_State *ps) {
62 const char *n, *msg;
63 nick *np;
64
65 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
66 LUA_RETURN(ps, LUA_FAIL);
67
68 n = lua_tostring(ps, 1);
69 msg = lua_tostring(ps, 2);
70
71 np = getnickbynick(n);
72 if(!np || !lua_lineok(msg))
73 LUA_RETURN(ps, LUA_FAIL);
74
75 lua_message(np, "\001%s\001", msg);
76
77 LUA_RETURN(ps, lua_cmsg(LUA_PUKECHAN, "lua-ctcp: %s (%s)", np->nick, msg));
78 }
79
80 static int lua_noticecmd(lua_State *ps) {
81 const char *n, *msg;
82 nick *np;
83
84 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
85 LUA_RETURN(ps, LUA_FAIL);
86
87 n = lua_tostring(ps, 1);
88 msg = lua_tostring(ps, 2);
89
90 np = getnickbynick(n);
91 if(!np || !lua_lineok(msg))
92 LUA_RETURN(ps, LUA_FAIL);
93
94 lua_notice(np, "%s", msg);
95
96 LUA_RETURN(ps, LUA_OK);
97 }
98
99 static int lua_kill(lua_State *ps) {
100 const char *n, *msg;
101 nick *np;
102
103 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
104 LUA_RETURN(ps, LUA_FAIL);
105
106 n = lua_tostring(ps, 1);
107 msg = lua_tostring(ps, 2);
108
109 np = getnickbynick(n);
110 if(!np)
111 LUA_RETURN(ps, LUA_FAIL);
112
113 if(IsOper(np) || IsService(np) || IsXOper(np))
114 LUA_RETURN(ps, LUA_FAIL);
115
116 if(!lua_lineok(msg))
117 LUA_RETURN(ps, LUA_FAIL);
118
119 killuser(lua_nick, np, "%s", msg);
120
121 LUA_RETURN(ps, lua_cmsg(LUA_PUKECHAN, "lua-KILL: %s (%s)", np->nick, msg));
122 }
123
124 static int lua_gline(lua_State *ps) {
125 const char *reason;
126 nick *target;
127 char mask[512];
128 int duration, usercount = 0;
129 host *hp;
130
131 if(!lua_isstring(ps, 1) || !lua_isint(ps, 2) || !lua_isstring(ps, 3))
132 LUA_RETURN(ps, LUA_FAIL);
133
134 duration = lua_toint(ps, 2);
135 if((duration < 1) || (duration > 86400))
136 LUA_RETURN(ps, LUA_FAIL);
137
138 reason = lua_tostring(ps, 3);
139 if(!lua_lineok(reason) || !reason)
140 LUA_RETURN(ps, LUA_FAIL);
141
142 target = getnickbynick(lua_tostring(ps, 1));
143 if(!target || (IsOper(target) || IsXOper(target) || IsService(target)))
144 LUA_RETURN(ps, LUA_FAIL);
145
146 hp = target->host;
147 if(!hp)
148 LUA_RETURN(ps, LUA_FAIL);
149
150 usercount = hp->clonecount;
151 if(usercount > 10) { /* (decent) trusted host */
152 int j;
153 nick *np;
154
155 usercount = 0;
156
157 for (j=0;j<NICKHASHSIZE;j++)
158 for (np=nicktable[j];np;np=np->next)
159 if (np && (np->host == hp) && (!ircd_strcmp(np->ident, target->ident)))
160 usercount++;
161
162 if(usercount > 50)
163 LUA_RETURN(ps, LUA_FAIL);
164
165 snprintf(mask, sizeof(mask), "*%s@%s", target->ident, IPtostr(target->ipaddress));
166 } else {
167 snprintf(mask, sizeof(mask), "*@%s", IPtostr(target->ipaddress));
168 }
169
170 irc_send("%s GL * +%s %d %d :%s", mynumeric->content, mask, duration, getnettime(), reason);
171 LUA_RETURN(ps, lua_cmsg(LUA_PUKECHAN, "lua-GLINE: %s (%d users, %d seconds -- %s)", mask, usercount, duration, reason));
172 }
173
174 static int lua_getchaninfo(lua_State *ps) {
175 channel *cp;
176
177 if(!lua_isstring(ps, 1))
178 return 0;
179
180 cp = findchannel((char *)lua_tostring(ps, 1));
181 if(!cp)
182 return 0;
183
184 LUA_PUSHCHAN(ps, cp);
185
186 return 1;
187 }
188
189 static int lua_opchan(lua_State *ps) {
190 channel *cp;
191 nick *np;
192
193 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
194 LUA_RETURN(ps, LUA_FAIL);
195
196 cp = findchannel((char *)lua_tostring(ps, 1));
197 if(!cp)
198 LUA_RETURN(ps, LUA_FAIL);
199
200 np = getnickbynick((char *)lua_tostring(ps, 2));
201 if(!np)
202 LUA_RETURN(ps, LUA_FAIL);
203
204 localsetmodes(lua_nick, cp, np, MC_OP);
205 LUA_RETURN(ps, LUA_OK);
206 }
207
208 static int lua_voicechan(lua_State *ps) {
209 channel *cp;
210 nick *np;
211
212 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
213 LUA_RETURN(ps, LUA_FAIL);
214
215 cp = findchannel((char *)lua_tostring(ps, 1));
216 if(!cp)
217 LUA_RETURN(ps, LUA_FAIL);
218
219 np = getnickbynick((char *)lua_tostring(ps, 2));
220 if(!np)
221 LUA_RETURN(ps, LUA_FAIL);
222
223 localsetmodes(lua_nick, cp, np, MC_VOICE);
224 LUA_RETURN(ps, LUA_OK);
225 }
226
227 static int lua_counthost(lua_State *ps) {
228 long numeric;
229 nick *np;
230
231 if(!lua_islong(ps, 1))
232 return 0;
233
234 numeric = lua_tolong(ps, 1);
235
236 np = getnickbynumeric(numeric);
237 if(!np)
238 return 0;
239
240 lua_pushint(ps, np->host->clonecount);
241 return 1;
242 }
243
244 static int lua_versioninfo(lua_State *ps) {
245 lua_pushstring(ps, LUA_VERSION);
246 lua_pushstring(ps, LUA_BOTVERSION);
247 lua_pushstring(ps, __DATE__);
248 lua_pushstring(ps, __TIME__);
249
250 return 4;
251 }
252
253 /* O(n) */
254 static int lua_getuserbyauth(lua_State *l) {
255 const char *acc;
256 nick *np;
257 int i, found = 0;
258
259 if(!lua_isstring(l, 1))
260 return 0;
261
262 for(i=0;i<NICKHASHSIZE;i++) {
263 for(np=nicktable[i];np;np=np->next) {
264 if(np && np->authname && !ircd_strcmp(np->authname, acc)) {
265 LUA_PUSHNICK(l, np);
266 found++;
267 }
268 }
269 }
270
271 return found;
272 }
273
274 static int lua_getnickchans(lua_State *l) {
275 nick *np;
276 int i;
277 channel **channels;
278
279 if(!lua_islong(l, 1))
280 return 0;
281
282 np = getnickbynumeric(lua_tolong(l, 1));
283 if(!np)
284 return 0;
285
286 channels = (channel **)np->channels->content;
287 for(i=0;i<np->channels->cursi;i++)
288 lua_pushstring(l, channels[i]->index->name->content);
289
290 return np->channels->cursi;
291 }
292
293 static int lua_gethostusers(lua_State *l) {
294 nick *np;
295 int count;
296
297 if(!lua_islong(l, 1))
298 return 0;
299
300 np = getnickbynumeric(lua_tolong(l, 1));
301 if(!np || !np->host || !np->host->nicks)
302 return 0;
303
304 np = np->host->nicks;
305 count = np->host->clonecount;
306
307 do {
308 LUA_PUSHNICK(l, np);
309 np = np->nextbyhost;
310 } while(np);
311
312 return count;
313 }
314
315 /*
316 static int lua_iteratenickhash(lua_State *l) {
317 nick *np;
318 int i, top;
319 void *fp;
320
321 if(!lua_isfunction(l, 1))
322 LUA_RETURN(LUA_FAIL);
323
324 fp = lua_touserdata(l, 1);
325 if(!fp)
326 LUA_RETURN(LUA_FAIL);
327
328 for(i=0;i<NICKHASHSIZE;i++) {
329 for(np=nicktable[i];np;np=np->next) {
330 if(np) {
331 top = lua_gettop(l);
332
333 lua_getglobal(l, "scripterror");
334 lua_insert
335
336 LUA_PUSHNICK(l, np);
337 lua_pcall(l, 1, 0, top + 1);
338
339 lua_settop(l, top);
340 }
341 }
342 }
343
344 LUA_RETURN(LUA_OK);
345 }
346 */
347
348 static int lua_chanfix(lua_State *ps) {
349 channel *cp;
350 nick *np;
351
352 if(!lua_isstring(ps, 1))
353 LUA_RETURN(ps, LUA_FAIL);
354
355 cp = findchannel((char *)lua_tostring(ps, 1));
356 if(!cp)
357 LUA_RETURN(ps, LUA_FAIL);
358
359 np = getnickbynick(LUA_CHANFIXBOT);
360 if(!np)
361 LUA_RETURN(ps, LUA_FAIL);
362
363 lua_message(np, "chanfix %s", cp->index->name->content);
364
365 LUA_RETURN(ps, LUA_OK);
366 }
367
368 static int lua_clearmode(lua_State *ps) {
369 channel *cp;
370 int i;
371 nick *np;
372 unsigned long *lp;
373 modechanges changes;
374
375 if(!lua_isstring(ps, 1))
376 LUA_RETURN(ps, LUA_FAIL);
377
378 cp = findchannel((char *)lua_tostring(ps, 1));
379 if(!cp)
380 LUA_RETURN(ps, LUA_FAIL);
381
382 localsetmodeinit(&changes, cp, lua_nick);
383
384 localdosetmode_key(&changes, NULL, MCB_DEL);
385 localdosetmode_simple(&changes, 0, CHANMODE_INVITEONLY | CHANMODE_LIMIT);
386
387 while(cp->bans)
388 localdosetmode_ban(&changes, bantostring(cp->bans), MCB_DEL);
389
390 for(i=0,lp=cp->users->content;i<cp->users->hashsize;i++,lp++)
391 if((*lp != nouser) && (*lp & CUMODE_OP)) {
392 np = getnickbynumeric(*lp);
393 if(np && !IsService(np))
394 localdosetmode_nick(&changes, np, MC_DEOP);
395 }
396
397 localsetmodeflush(&changes, 1);
398
399 LUA_RETURN(ps, LUA_OK);
400 }
401
402 void lua_registercommands(lua_State *l) {
403 lua_register(l, "irc_smsg", lua_smsg);
404 lua_register(l, "irc_skill", lua_skill);
405
406 lua_register(l, "chanmsg", lua_chanmsg);
407 lua_register(l, "scripterror", lua_scripterror);
408 lua_register(l, "versioninfo", lua_versioninfo);
409
410 lua_register(l, "irc_report", lua_chanmsg);
411 lua_register(l, "irc_ctcp", lua_ctcp);
412 lua_register(l, "irc_kill", lua_kill);
413 lua_register(l, "irc_gline", lua_gline);
414 lua_register(l, "irc_getchaninfo", lua_getchaninfo);
415 lua_register(l, "irc_counthost", lua_counthost);
416 lua_register(l, "irc_getuserbyauth", lua_getuserbyauth);
417 lua_register(l, "irc_notice", lua_noticecmd);
418 lua_register(l, "irc_opchan", lua_opchan);
419 lua_register(l, "irc_voicechan", lua_voicechan);
420 lua_register(l, "irc_chanfix", lua_chanfix);
421 lua_register(l, "irc_clearmode", lua_clearmode);
422
423 lua_register(l, "irc_getnickchans", lua_getnickchans);
424 lua_register(l, "irc_gethostusers", lua_gethostusers);
425
426 /* lua_register(l, "irc_iteratenickhash", lua_iteratenickhash); */
427 }
428
429 /* --- */
430
431 static int lua_smsg(lua_State *ps) {
432 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
433 LUA_RETURN(ps, LUA_FAIL);
434
435 LUA_RETURN(ps, lua_cmsg((char *)lua_tostring(ps, 2), "%s", lua_tostring(ps, 1)));
436 }
437
438 static int lua_skill(lua_State *ps) {
439 const char *n, *msg;
440 nick *np;
441
442 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
443 LUA_RETURN(ps, LUA_FAIL);
444
445 n = lua_tostring(ps, 1);
446 msg = lua_tostring(ps, 2);
447
448 np = getnickbynick(n);
449 if(!np)
450 LUA_RETURN(ps, LUA_FAIL);
451
452 if(IsOper(np) || IsService(np) || IsXOper(np))
453 LUA_RETURN(ps, LUA_FAIL);
454
455 if(!lua_lineok(msg))
456 LUA_RETURN(ps, LUA_FAIL);
457
458 killuser(lua_nick, np, "%s", msg);
459
460 LUA_RETURN(ps, LUA_OK);
461 }
462