]> jfr.im git - irc/quakenet/newserv.git/blob - lua/luabot.c
Added ontick, called once per second.
[irc/quakenet/newserv.git] / lua / luabot.c
1 /* Copyright (C) Chris Porter 2005 */
2 /* ALL RIGHTS RESERVED. */
3 /* Don't put this into the SVN repo. */
4
5 #include "../localuser/localuser.h"
6 #include "../localuser/localuserchannel.h"
7 #include "../core/schedule.h"
8
9 #include "lua.h"
10 #include "luabot.h"
11
12 nick *lua_nick = NULL;
13 void *myureconnect = NULL, *myublip = NULL, *myutick = NULL;
14
15 void lua_bothandler(nick *target, int type, void **args);
16
17 void lua_onnewnick(int hooknum, void *arg);
18 void lua_blip(void *arg);
19 void lua_tick(void *arg);
20 void lua_onkick(int hooknum, void *arg);
21 void lua_ontopic(int hooknum, void *arg);
22 void lua_onauth(int hooknum, void *arg);
23 void lua_ondisconnect(int hooknum, void *arg);
24 void lua_onmode(int hooknum, void *arg);
25 void lua_onop(int hooknum, void *arg);
26 void lua_onquit(int hooknum, void *arg);
27 void lua_onrename(int hooknum, void *arg);
28 void lua_onconnect(int hooknum, void *arg);
29 void lua_onjoin(int hooknum, void *arg);
30
31 void lua_registerevents(void) {
32 registerhook(HOOK_NICK_NEWNICK, &lua_onnewnick);
33 registerhook(HOOK_IRC_DISCON, &lua_ondisconnect);
34 registerhook(HOOK_IRC_PRE_DISCON, &lua_ondisconnect);
35 registerhook(HOOK_NICK_ACCOUNT, &lua_onauth);
36 registerhook(HOOK_CHANNEL_TOPIC, &lua_ontopic);
37 registerhook(HOOK_CHANNEL_KICK, &lua_onkick);
38 registerhook(HOOK_CHANNEL_OPPED, &lua_onop);
39 registerhook(HOOK_CHANNEL_DEOPPED, &lua_onop);
40 registerhook(HOOK_NICK_LOSTNICK, &lua_onquit);
41 registerhook(HOOK_NICK_RENAME, &lua_onrename);
42 registerhook(HOOK_IRC_CONNECTED, &lua_onconnect);
43 registerhook(HOOK_SERVER_END_OF_BURST, &lua_onconnect);
44 registerhook(HOOK_CHANNEL_JOIN, &lua_onjoin);
45 }
46
47 void lua_deregisterevents(void) {
48 deregisterhook(HOOK_CHANNEL_JOIN, &lua_onjoin);
49 deregisterhook(HOOK_SERVER_END_OF_BURST, &lua_onconnect);
50 deregisterhook(HOOK_IRC_CONNECTED, &lua_onconnect);
51 deregisterhook(HOOK_NICK_RENAME, &lua_onrename);
52 deregisterhook(HOOK_NICK_LOSTNICK, &lua_onquit);
53 deregisterhook(HOOK_CHANNEL_DEOPPED, &lua_onop);
54 deregisterhook(HOOK_CHANNEL_OPPED, &lua_onop);
55 deregisterhook(HOOK_CHANNEL_KICK, &lua_onkick);
56 deregisterhook(HOOK_CHANNEL_TOPIC, &lua_ontopic);
57 deregisterhook(HOOK_NICK_ACCOUNT, &lua_onauth);
58 deregisterhook(HOOK_IRC_PRE_DISCON, &lua_ondisconnect);
59 deregisterhook(HOOK_IRC_DISCON, &lua_ondisconnect);
60 deregisterhook(HOOK_NICK_NEWNICK, &lua_onnewnick);
61 }
62
63 void lua_startbot(void *arg) {
64 channel *cp;
65
66 myureconnect = NULL;
67
68 lua_nick = registerlocaluser("U", "lua", "quakenet.department.of.corrections", "Lua engine v" LUA_BOTVERSION " (" LUA_VERSION ")", "U", UMODE_ACCOUNT | UMODE_DEAF | UMODE_OPER | UMODE_SERVICE, &lua_bothandler);
69 if(!lua_nick) {
70 myureconnect = scheduleoneshot(time(NULL) + 1, &lua_startbot, NULL);
71 return;
72 }
73
74 cp = findchannel(LUA_OPERCHAN);
75 if(cp && localjoinchannel(lua_nick, cp))
76 localgetops(lua_nick, cp);
77
78 cp = findchannel(LUA_PUKECHAN);
79 if(cp && localjoinchannel(lua_nick, cp))
80 localgetops(lua_nick, cp);
81
82 myublip = schedulerecurring(time(NULL) + 1, 0, 60, &lua_blip, NULL);
83 myutick = schedulerecurring(time(NULL) + 1, 0, 1, &lua_tick, NULL);
84
85 lua_registerevents();
86 }
87
88 void lua_destroybot(void) {
89 if(myutick)
90 deleteschedule(myutick, &lua_tick, NULL);
91
92 if(myublip)
93 deleteschedule(myublip, &lua_blip, NULL);
94
95 lua_deregisterevents();
96
97 if (myureconnect)
98 deleteschedule(myureconnect, &lua_startbot, NULL);
99
100 if(lua_nick)
101 deregisterlocaluser(lua_nick, NULL);
102 }
103
104 void lua_bothandler(nick *target, int type, void **args) {
105 nick *np;
106 char *p;
107 lua_State *l;
108 int le, top;
109
110 switch(type) {
111 case LU_PRIVMSG:
112 np = (nick *)args[0];
113 p = (char *)args[1];
114
115 if(!np || !p)
116 return;
117
118 LUA_STARTLOOP(l);
119
120 top = lua_gettop(l);
121
122 lua_getglobal(l, "scripterror");
123 lua_getglobal(l, "irc_onmsg");
124
125 if(lua_isfunction(l, -1)) {
126 LUA_PUSHNICK(l, np);
127 lua_pushstring(l, p);
128
129 lua_pcall(l, 2, 0, top + 1);
130 }
131
132 lua_settop(l, top);
133
134 LUA_ENDLOOP();
135
136 break;
137 case LU_PRIVNOTICE:
138 np = (nick *)args[0];
139 p = (char *)args[1];
140
141 if(!np || !p)
142 return;
143
144 le = strlen(p);
145 if((le > 1) && (p[0] == '\001')) {
146 if(p[le - 1] == '\001')
147 p[le - 1] = '\000';
148
149 LUA_STARTLOOP(l);
150
151 top = lua_gettop(l);
152
153 lua_getglobal(l, "scripterror");
154 lua_getglobal(l, "irc_onctcp");
155
156 if(lua_isfunction(l, -1)) {
157 LUA_PUSHNICK(l, np);
158 lua_pushstring(l, p + 1);
159
160 lua_pcall(l, 2, 0, top + 1);
161 }
162
163 lua_settop(l, top);
164
165 LUA_ENDLOOP();
166
167 }
168
169 break;
170
171 case LU_KILLED:
172 if(myublip) {
173 myublip = NULL;
174 deleteschedule(myublip, &lua_blip, NULL);
175 }
176
177 if(myutick) {
178 myutick = NULL;
179 deleteschedule(myutick, &lua_tick, NULL);
180 }
181
182 lua_nick = NULL;
183 myureconnect = scheduleoneshot(time(NULL) + 1, &lua_startbot, NULL);
184
185 break;
186 }
187 }
188
189 void lua_blip(void *arg) {
190 lua_State *l;
191 int top;
192
193 LUA_STARTLOOP(l);
194 top = lua_gettop(l);
195
196 lua_getglobal(l, "scripterror");
197 lua_getglobal(l, "onblip");
198
199 if(lua_isfunction(l, -1))
200 lua_pcall(l, 0, 0, top + 1);
201
202 lua_settop(l, top);
203 LUA_ENDLOOP();
204 }
205
206 void lua_tick(void *arg) {
207 lua_State *l;
208 int top;
209
210 LUA_STARTLOOP(l);
211 top = lua_gettop(l);
212
213 lua_getglobal(l, "scripterror");
214 lua_getglobal(l, "ontick");
215
216 if(lua_isfunction(l, -1))
217 lua_pcall(l, 0, 0, top + 1);
218
219 lua_settop(l, top);
220 LUA_ENDLOOP();
221 }
222
223 void lua_onnewnick(int hooknum, void *arg) {
224 nick *np = (nick *)arg;
225 int top;
226 lua_State *l;
227
228 if(!np)
229 return;
230
231 LUA_STARTLOOP(l);
232 top = lua_gettop(l);
233
234 lua_getglobal(l, "scripterror");
235 lua_getglobal(l, "irc_onnewnick");
236
237 if(lua_isfunction(l, -1)) {
238 LUA_PUSHNICK(l, np);
239
240 lua_pcall(l, 1, 0, top + 1);
241 }
242
243 lua_settop(l, top);
244 LUA_ENDLOOP();
245 }
246
247 void lua_onkick(int hooknum, void *arg) {
248 void **arglist = (void **)arg;
249 chanindex *ci = ((channel *)arglist[0])->index;
250 nick *kicked = arglist[1];
251 nick *kicker = arglist[2];
252 char *message = (char *)arglist[3];
253 lua_State *l;
254 int top;
255
256 if(!kicker || IsOper(kicker) || IsService(kicker) || IsXOper(kicker)) /* bloody Cruicky */
257 return;
258
259 LUA_STARTLOOP(l);
260 top = lua_gettop(l);
261
262 lua_getglobal(l, "scripterror");
263 lua_getglobal(l, "irc_onkick");
264
265 if(lua_isfunction(l, -1)) {
266 lua_pushstring(l, ci->name->content);
267 LUA_PUSHNICK(l, kicked);
268 LUA_PUSHNICK(l, kicker);
269 lua_pushstring(l, message);
270
271 lua_pcall(l, 4, 0, top + 1);
272 }
273
274 lua_settop(l, top);
275 LUA_ENDLOOP();
276 }
277
278 void lua_ontopic(int hooknum, void *arg) {
279 void **arglist = (void **)arg;
280 channel *cp=(channel*)arglist[0];
281 nick *np = (nick *)arglist[1];
282 lua_State *l;
283 int top;
284
285 if(!np || IsOper(np) || IsService(np) || IsXOper(np))
286 return;
287 if(!cp || !cp->topic)
288 return;
289
290 LUA_STARTLOOP(l);
291 top = lua_gettop(l);
292
293 lua_getglobal(l, "scripterror");
294 lua_getglobal(l, "irc_ontopic");
295
296 if(lua_isfunction(l, -1)) {
297 lua_pushstring(l, cp->index->name->content);
298 LUA_PUSHNICK(l, np);
299 lua_pushstring(l, cp->topic->content);
300
301 lua_pcall(l, 3, 0, top + 1);
302 }
303 lua_settop(l, top);
304 LUA_ENDLOOP();
305 }
306
307 void lua_onop(int hooknum, void *arg) {
308 void **arglist = (void **)arg;
309 chanindex *ci = ((channel *)arglist[0])->index;
310 nick *np = arglist[1];
311 nick *target = arglist[2];
312 lua_State *l;
313 int top;
314
315 if(!target)
316 return;
317
318 LUA_STARTLOOP(l);
319 top = lua_gettop(l);
320
321 lua_getglobal(l, "scripterror");
322 if(hooknum == HOOK_CHANNEL_OPPED) {
323 lua_getglobal(l, "irc_onop");
324 } else {
325 lua_getglobal(l, "irc_ondeop");
326 }
327
328 if(lua_isfunction(l, -1)) {
329 lua_pushstring(l, ci->name->content);
330
331 if(np) {
332 LUA_PUSHNICK(l, np);
333 } else {
334 lua_pushnil(l);
335 }
336 LUA_PUSHNICK(l, target);
337
338 lua_pcall(l, 3, 0, top + 1);
339 }
340
341 lua_settop(l, top);
342 LUA_ENDLOOP();
343 }
344
345 void lua_onjoin(int hooknum, void *arg) {
346 void **arglist = (void **)arg;
347 chanindex *ci = ((channel *)arglist[0])->index;
348 nick *np = arglist[1];
349 lua_State *l;
350 int top;
351
352 if(!ci || !np)
353 return;
354
355 LUA_STARTLOOP(l);
356 top = lua_gettop(l);
357
358 lua_getglobal(l, "scripterror");
359 lua_getglobal(l, "irc_onjoin");
360
361 if(lua_isfunction(l, -1)) {
362 lua_pushstring(l, ci->name->content);
363
364 LUA_PUSHNICK(l, np);
365
366 lua_pcall(l, 2, 0, top + 1);
367 }
368
369 lua_settop(l, top);
370 LUA_ENDLOOP();
371 }
372
373 void lua_onrename(int hooknum, void *arg) {
374 nick *np = (void *)arg;
375 lua_State *l;
376 int top;
377
378 if(!np)
379 return;
380
381 LUA_STARTLOOP(l);
382 top = lua_gettop(l);
383
384 lua_getglobal(l, "scripterror");
385 lua_getglobal(l, "irc_onrename");
386
387 if(lua_isfunction(l, -1)) {
388 LUA_PUSHNICK(l, np);
389
390 lua_pcall(l, 1, 0, top + 1);
391 }
392
393 lua_settop(l, top);
394 LUA_ENDLOOP();
395 }
396
397 void lua_onquit(int hooknum, void *arg) {
398 nick *np = (nick *)arg;
399 lua_State *l;
400 int top;
401
402 if(!np)
403 return;
404
405 LUA_STARTLOOP(l);
406 top = lua_gettop(l);
407
408 lua_getglobal(l, "scripterror");
409 lua_getglobal(l, "irc_onquit");
410
411 if(lua_isfunction(l, -1)) {
412 LUA_PUSHNICK(l, np);
413
414 lua_pcall(l, 1, 0, top + 1);
415 }
416
417 lua_settop(l, top);
418 LUA_ENDLOOP();
419 }
420
421 void lua_onauth(int hooknum, void *arg) {
422 nick *np = (nick *)arg;
423 lua_State *l;
424 int top;
425
426 if(!np)
427 return;
428
429 LUA_STARTLOOP(l);
430 top = lua_gettop(l);
431
432 lua_getglobal(l, "scripterror");
433 lua_getglobal(l, "irc_onauth");
434
435 if(lua_isfunction(l, -1)) {
436 LUA_PUSHNICK(l, np);
437
438 lua_pcall(l, 1, 0, top + 1);
439 }
440 lua_settop(l, top);
441 LUA_ENDLOOP();
442 }
443
444 void lua_ondisconnect(int hooknum, void *arg) {
445 lua_State *l;
446 int top;
447
448 LUA_STARTLOOP(l);
449 top = lua_gettop(l);
450
451 lua_getglobal(l, "scripterror");
452 if(hooknum == HOOK_IRC_DISCON) {
453 lua_getglobal(l, "irc_ondisconnect");
454 } else {
455 lua_getglobal(l, "irc_onpredisconnect");
456 }
457 if(lua_isfunction(l, -1))
458 lua_pcall(l, 0, 0, top + 1);
459 lua_settop(l, top);
460 LUA_ENDLOOP();
461 }
462
463 void lua_onconnect(int hooknum, void *arg) {
464 lua_State *l;
465 int top;
466
467 LUA_STARTLOOP(l);
468 top = lua_gettop(l);
469
470 lua_getglobal(l, "scripterror");
471 if(hooknum == HOOK_IRC_CONNECTED) {
472 lua_getglobal(l, "irc_onconnect");
473 } else {
474 lua_getglobal(l, "irc_onendofburst");
475 }
476 if(lua_isfunction(l, -1))
477 lua_pcall(l, 0, 0, top + 1);
478 lua_settop(l, top);
479 LUA_ENDLOOP();
480 }
481
482 void lua_onload(lua_State *l) {
483 int top;
484
485 top = lua_gettop(l);
486
487 lua_getglobal(l, "scripterror");
488 lua_getglobal(l, "onload");
489
490 if(lua_isfunction(l, -1))
491 lua_pcall(l, 0, 0, top + 1);
492 lua_settop(l, top);
493 }
494
495 void lua_onunload(lua_State *l) {
496 int top;
497
498 top = lua_gettop(l);
499
500 lua_getglobal(l, "scripterror");
501 lua_getglobal(l, "onunload");
502
503 if(lua_isfunction(l, -1))
504 lua_pcall(l, 0, 0, top + 1);
505 lua_settop(l, top);
506 }
507
508 int lua_channelmessage(channel *cp, char *message, ...) {
509 char buf[512];
510 va_list va;
511
512 va_start(va, message);
513 vsnprintf(buf, sizeof(buf), message, va);
514 va_end(va);
515
516 sendmessagetochannel(lua_nick, cp, "%s", buf);
517
518 return 0;
519 }
520
521 int lua_message(nick *np, char *message, ...) {
522 char buf[512];
523 va_list va;
524
525 va_start(va, message);
526 vsnprintf(buf, sizeof(buf), message, va);
527 va_end(va);
528
529 sendmessagetouser(lua_nick, np, "%s", buf);
530
531 return 0;
532 }
533
534 int lua_notice(nick *np, char *message, ...) {
535 char buf[512];
536 va_list va;
537
538 va_start(va, message);
539 vsnprintf(buf, sizeof(buf), message, va);
540 va_end(va);
541
542 sendnoticetouser(lua_nick, np, "%s", buf);
543
544 return 0;
545 }
546
547