]> jfr.im git - irc/quakenet/newserv.git/blame - lua/lualocal.c
Merge.
[irc/quakenet/newserv.git] / lua / lualocal.c
CommitLineData
0225bed3
CP
1#include <stdlib.h>
2
3#include "../localuser/localuser.h"
4#include "../lib/strlfunc.h"
5#include "../core/schedule.h"
6#include "../channel/channel.h"
7#include "../localuser/localuserchannel.h"
8
9#include "lua.h"
10#include "luabot.h"
11#include "lualocal.h"
12
13void lua_localnickhandler(nick *target, int type, void **args);
14void lua_reconnectlocal(void *arg);
15
5541f23c 16static int lua_registerlocaluserid(lua_State *ps) {
0225bed3
CP
17 lua_list *l;
18 lua_localnick *ln;
19 char *nickname, *ident, *hostname, *realname, *account;
20 flag_t modes = 0;
5541f23c 21 long userid;
0225bed3 22
5541f23c 23 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2) || !lua_isstring(ps, 3) || !lua_isstring(ps, 4) || !lua_isstring(ps, 5) || !lua_isstring(ps, 7) || !lua_isfunction(ps, 8))
0225bed3
CP
24 return 0;
25
26 nickname = (char *)lua_tostring(ps, 1);
27 ident = (char *)lua_tostring(ps, 2);
28 hostname = (char *)lua_tostring(ps, 3);
29 realname = (char *)lua_tostring(ps, 4);
30 account = (char *)lua_tostring(ps, 5);
5541f23c
CP
31 if(lua_islong(ps, 6)) {
32 userid = lua_tolong(ps, 6);
33 } else {
34 userid = 0;
35 }
0225bed3 36
5541f23c 37 setflags(&modes, UMODE_ALL, (char *)lua_tostring(ps, 7), umodeflags, REJECT_NONE);
0225bed3
CP
38
39 if(!lua_lineok(nickname) || !lua_lineok(ident) || !lua_lineok(hostname) || !lua_lineok(realname) || !lua_lineok(account))
40 return 0;
41
42 l = lua_listfromstate(ps);
43 if(!l)
44 return 0;
45
d0e17ef9 46 ln = (lua_localnick *)luamalloc(sizeof(lua_localnick));
0225bed3
CP
47 if(!ln)
48 return 0;
49
50 ln->reconnect = NULL;
51
5541f23c 52 ln->nick = registerlocaluserflags(nickname, ident, hostname, realname, account, userid, 0, modes, &lua_localnickhandler);
0225bed3 53 if(!ln->nick) {
d0e17ef9 54 luafree(ln);
0225bed3
CP
55 return 0;
56 }
57
58 ln->handler = luaL_ref(ps, LUA_REGISTRYINDEX);
59
60 ln->next = l->nicks;
61 l->nicks = ln;
62
eda80ef2 63 lua_pushlong(ps, ln->nick->numeric);
0225bed3
CP
64 return 1;
65}
66
67void lua_freelocalnick(lua_State *ps, lua_localnick *l, char *quitm) {
68 if(l->nick)
69 deregisterlocaluser(l->nick, quitm);
70
71 if(l->reconnect)
72 deleteschedule(l->reconnect, &lua_reconnectlocal, l);
73
74 luaL_unref(ps, LUA_REGISTRYINDEX, l->handler);
75
d0e17ef9 76 luafree(l);
0225bed3
CP
77}
78
79int lua_getlocalnickbynick(nick *np, lua_list **rl, lua_localnick **rln) {
80 lua_list *l;
81 lua_localnick *ln;
82
83 for(l=lua_head;l;l=l->next)
84 for(ln=l->nicks;ln;ln=ln->next)
85 if(ln->nick == np) {
86 *rl = l;
87 *rln = ln;
88 return 1;
89 }
90
91 return 0;
92}
93
94static int lua_deregisterlocaluser(lua_State *ps) {
95 lua_list *l;
96 lua_localnick *l2, *lp = NULL;
97 long numeric;
98 char *quitm;
99
100 if(!lua_islong(ps, 1))
101 LUA_RETURN(ps, LUA_FAIL);
102
3f1c5f43
CP
103 numeric = lua_tolong(ps, 1);
104
0225bed3
CP
105 quitm = lua_isstring(ps, 2)?(char *)lua_tostring(ps, 2):"localuser unregistered.";
106
107 l = lua_listfromstate(ps);
108
109 for(l2=l->nicks;l2;lp=l2,l2=l2->next) {
c0088ccb 110 if(l2->nick && l2->nick->numeric == numeric) {
9315931c
CP
111 if(lp) {
112 lp->next = l2->next;
113 } else {
114 l->nicks = l2->next;
115 }
116
0225bed3
CP
117 lua_freelocalnick(ps, l2, quitm);
118 LUA_RETURN(ps, LUA_OK);
119 }
120 }
121
122 LUA_RETURN(ps, LUA_FAIL);
123}
124
125void lua_deregisternicks(lua_list *l) {
126 struct lua_localnick *ln, *pn;
127
c0088ccb
CP
128 ln = l->nicks;
129 l->nicks = NULL;
130 for(;ln;ln=pn) {
0225bed3
CP
131 pn = ln->next;
132
133 lua_freelocalnick(l->l, ln, "Script unloaded.");
134 }
135
136 l->nicks = NULL;
137}
138
139/* todo */
140void lua_localnickhandler(nick *target, int type, void **args) {
141 nick *np;
142 char *p;
143 lua_localnick *ln;
144 lua_list *l;
e8b79634 145 channel *c;
0225bed3
CP
146
147 if(!lua_getlocalnickbynick(target, &l, &ln))
148 return;
149
150 switch(type) {
151 case LU_PRIVMSG:
152 np = (nick *)args[0];
153 p = (char *)args[1];
154
155 if(!np || !p)
156 return;
157
158 lua_vlpcall(l, ln, "irc_onmsg", "Ns", np, p);
159
160 break;
161
e8b79634
CP
162 case LU_CHANMSG:
163 np = (nick *)args[0];
164 c = (channel *)args[1];
165 p = (char *)args[2];
166
167 if(!np || !p || !c || !c->index || !c->index->name || !c->index->name->content)
168 return;
169
170 lua_vlpcall(l, ln, "irc_onchanmsg", "Nss", np, c->index->name->content, p);
171 break;
172
0225bed3 173 case LU_KILLED:
980b51af 174 lua_vlpcall(l, ln, "irc_onkilled", "");
0225bed3
CP
175
176 strlcpy(ln->nickname, target->nick, sizeof(ln->nickname));
177 strlcpy(ln->ident, target->ident, sizeof(ln->ident));
178 strlcpy(ln->hostname, target->host->name->content, sizeof(ln->hostname));
179 strlcpy(ln->realname, target->realname->name->content, sizeof(ln->realname));
180 strlcpy(ln->account, target->authname, sizeof(ln->account));
181
182 ln->umodes = target->umodes;
183 ln->nick = NULL;
184
185 ln->reconnect = scheduleoneshot(time(NULL) + 1, &lua_reconnectlocal, ln);
186
23518e11
CP
187 break;
188 case LU_INVITE:
189 /* we were invited, check if someone invited us to PUBLICCHAN */
190 np = (nick *)args[0];
191 c = (channel *)args[1];
192
193 if(!c || !np || !c->index || !c->index->name || !c->index->name->content)
194 return;
195
196 lua_vlpcall(l, ln, "irc_oninvite", "Ns", np, c->index->name->content);
0225bed3
CP
197 break;
198 }
199}
200
201void lua_reconnectlocal(void *arg) {
202 lua_list *l;
203 lua_localnick *ln = (lua_localnick *)arg;
204
205 ln->nick = registerlocaluser(ln->nickname, ln->ident, ln->hostname, ln->realname, ln->account, ln->umodes, &lua_localnickhandler);
206 if(!ln->nick) {
207 ln->reconnect = scheduleoneshot(time(NULL) + 1, &lua_reconnectlocal, ln);
208 return;
209 }
210
211 ln->reconnect = NULL;
212
213 if(lua_getlocalnickbynick(ln->nick, &l, &ln)) /* hacky! */
980b51af 214 lua_vlpcall(l, ln, "irc_onkillreconnect", "N", ln->nick);
0225bed3
CP
215}
216
217static int lua_localjoin(lua_State *ps) {
218 nick *source;
219 channel *target;
220 char *chan;
221
222 if(!lua_islong(ps, 1) || !lua_isstring(ps, 2))
223 LUA_RETURN(ps, LUA_FAIL);
224
225 source = getnickbynumeric(lua_tolong(ps, 1));
226 if(!source)
227 LUA_RETURN(ps, LUA_FAIL);
228
229 chan = (char *)lua_tostring(ps, 2);
89b1bd77
CP
230 if(chan[0] != '#')
231 LUA_RETURN(ps, LUA_FAIL);
0225bed3
CP
232
233 if(!lua_lineok(chan))
234 LUA_RETURN(ps, LUA_FAIL);
235
236 target = findchannel(chan);
237 if(target) {
238 localjoinchannel(source, target);
239 } else {
e8b79634 240 localcreatechannel(source, chan);
0225bed3
CP
241 }
242
243 LUA_RETURN(ps, LUA_OK);
244}
245
b7252b44
CP
246static int lua_localpart(lua_State *ps) {
247 nick *source;
248 channel *target;
d70f70a1 249 char *chan, *reason;
b7252b44
CP
250
251 if(!lua_islong(ps, 1) || !lua_isstring(ps, 2))
252 LUA_RETURN(ps, LUA_FAIL);
253
254 source = getnickbynumeric(lua_tolong(ps, 1));
255 if(!source)
256 LUA_RETURN(ps, LUA_FAIL);
257
258 chan = (char *)lua_tostring(ps, 2);
259
260 if(!lua_lineok(chan))
261 LUA_RETURN(ps, LUA_FAIL);
d70f70a1
CP
262
263 if(lua_isstring(ps, 3)) {
264 reason = (char *)lua_tostring(ps, 3);
265 if(!lua_lineok(reason))
266 LUA_RETURN(ps, LUA_FAIL);
267 } else {
268 reason = NULL;
269 }
270
b7252b44
CP
271 target = findchannel(chan);
272 if(target) {
d70f70a1 273 localpartchannel(source, target, reason);
b7252b44
CP
274 } else {
275 LUA_RETURN(ps, LUA_FAIL);
276 }
277
278 LUA_RETURN(ps, LUA_OK);
279}
280
0225bed3
CP
281static int lua_localchanmsg(lua_State *ps) {
282 char *msg;
283 nick *source;
284 channel *target;
285
286 if(!lua_islong(ps, 1) || !lua_isstring(ps, 2) || !lua_isstring(ps, 3))
287 LUA_RETURN(ps, LUA_FAIL);
288
289 source = getnickbynumeric(lua_tolong(ps, 1));
290 if(!source)
291 LUA_RETURN(ps, LUA_FAIL);
292
293 target = findchannel((char *)lua_tostring(ps, 2));
294 if(!target)
295 LUA_RETURN(ps, LUA_FAIL);
296
297 msg = (char *)lua_tostring(ps, 3);
298
299 if(!lua_lineok(msg))
300 LUA_RETURN(ps, LUA_FAIL);
301
302 sendmessagetochannel(source, target, "%s", msg);
303
304 LUA_RETURN(ps, LUA_OK);
305}
306
307static int lua_localnotice(lua_State *ps) {
308 char *msg;
309 nick *source;
310 nick *target;
311
312 if(!lua_islong(ps, 1) || !lua_islong(ps, 2) || !lua_isstring(ps, 3))
313 LUA_RETURN(ps, LUA_FAIL);
314
315 source = getnickbynumeric(lua_tolong(ps, 1));
316 if(!source)
317 LUA_RETURN(ps, LUA_FAIL);
318
319 target = getnickbynumeric(lua_tolong(ps, 2));
320 if(!target)
321 LUA_RETURN(ps, LUA_FAIL);
322
323 msg = (char *)lua_tostring(ps, 3);
324
325 if(!lua_lineok(msg))
326 LUA_RETURN(ps, LUA_FAIL);
327
328 sendnoticetouser(source, target, "%s", msg);
329
330 LUA_RETURN(ps, LUA_OK);
331}
332
34552caa
CP
333static int lua_localprivmsg(lua_State *ps) {
334 char *msg;
335 nick *source;
336 nick *target;
337
338 if(!lua_islong(ps, 1) || !lua_islong(ps, 2) || !lua_isstring(ps, 3))
339 LUA_RETURN(ps, LUA_FAIL);
340
341 source = getnickbynumeric(lua_tolong(ps, 1));
342 if(!source)
343 LUA_RETURN(ps, LUA_FAIL);
344
345 target = getnickbynumeric(lua_tolong(ps, 2));
346 if(!target)
347 LUA_RETURN(ps, LUA_FAIL);
348
349 msg = (char *)lua_tostring(ps, 3);
350
351 if(!lua_lineok(msg))
352 LUA_RETURN(ps, LUA_FAIL);
353
354 sendmessagetouser(source, target, "%s", msg);
355
356 LUA_RETURN(ps, LUA_OK);
357}
358
533af02d
CP
359static int lua_localovmode(lua_State *l) {
360 nick *source;
ba436ecf 361 channel *chan;
09cb349b 362 int state = 0, add = 0, realmode = 0, ignoring = 0;
533af02d 363 modechanges changes;
ba436ecf 364
533af02d
CP
365 if(!lua_islong(l, 1) || !lua_isstring(l, 2) || !lua_istable(l, 3))
366 LUA_RETURN(l, LUA_FAIL);
ba436ecf 367
533af02d 368 source = getnickbynumeric(lua_tolong(l, 1));
ba436ecf 369 if(!source)
533af02d 370 LUA_RETURN(l, LUA_FAIL);
ba436ecf 371
533af02d 372 chan = findchannel((char *)lua_tostring(l, 2));
ba436ecf 373 if(!chan)
533af02d 374 LUA_RETURN(l, LUA_FAIL);
ba436ecf 375
533af02d 376 localsetmodeinit(&changes, chan, source);
ba436ecf 377
533af02d 378 lua_pushnil(l);
ba436ecf 379
533af02d
CP
380 while(lua_next(l, 3)) {
381 if(state == 0) {
382 ignoring = 0;
383
384 if(!lua_isboolean(l, -1)) {
385 ignoring = 1;
386 } else {
387 add = (int)lua_toboolean(l, -1);
388 }
389 } else if((state == 1) && !ignoring) {
390 if(!lua_isstring(l, -1)) {
391 ignoring = 1;
392 } else {
393 char *mode = (char *)lua_tostring(l, -1);
394 if((*mode == 'o') && add) {
395 realmode = MC_OP;
396 } else if (*mode == 'o') {
397 realmode = MC_DEOP;
398 } else if((*mode == 'v') && add) {
399 realmode = MC_VOICE;
400 } else if (*mode == 'v') {
401 realmode = MC_DEVOICE;
402 } else {
403 ignoring = 1;
404 }
405 }
406 } else if((state == 2) && !ignoring) {
407 if(lua_islong(l, -1)) {
408 nick *target = getnickbynumeric(lua_tolong(l, -1));
409 if(target)
410 localdosetmode_nick(&changes, target, realmode);
411 }
412 }
413
414 lua_pop(l, 1);
415
416 state = (state + 1) % 3;
ba436ecf
CP
417 }
418
533af02d 419 localsetmodeflush(&changes, 1);
ba436ecf 420
533af02d 421 LUA_RETURN(l, LUA_OK);
ba436ecf
CP
422}
423
eac66732
CP
424static int lua_localumodes(lua_State *ps) {
425 nick *np;
426 char *modes;
427 flag_t newmodes = 0;
428
429 if(!lua_islong(ps, 1) || !lua_isstring(ps, 2))
430 LUA_RETURN(ps, LUA_FAIL);
431
432 np = getnickbynumeric(lua_tolong(ps, 1));
433 if(!np)
434 LUA_RETURN(ps, LUA_FAIL);
435
436 modes = (char *)lua_tostring(ps, 2);
437
438 setflags(&newmodes, UMODE_ALL, modes, umodeflags, REJECT_NONE);
439
440 localusersetumodes(np, newmodes);
441 LUA_RETURN(ps, LUA_OK);
442}
443
f9f8ee13
CP
444static int lua_localtopic(lua_State *ps) {
445 nick *np;
446 channel *cp;
447 char *topic;
448
449 if(!lua_islong(ps, 1) || !lua_isstring(ps, 2) || !lua_isstring(ps, 3))
450 LUA_RETURN(ps, LUA_FAIL);
451
452 np = getnickbynumeric(lua_tolong(ps, 1));
453 if(!np)
454 LUA_RETURN(ps, LUA_FAIL);
455
456 cp = findchannel((char *)lua_tostring(ps, 2));
457 if(!cp)
458 LUA_RETURN(ps, LUA_FAIL);
459
460 topic = (char *)lua_tostring(ps, 3);
461 if(!topic || !lua_lineok(topic))
462 LUA_RETURN(ps, LUA_FAIL);
463
464 localsettopic(np, cp, topic);
465
466 LUA_RETURN(ps, LUA_OK);
467}
468
c0d574fa
CP
469static int lua_localban(lua_State *ps) {
470 channel *cp;
471 const char *mask;
472 modechanges changes;
473 nick *source;
474
475 int dir = MCB_ADD;
476
477 if(!lua_islong(ps, 1) || !lua_isstring(ps, 2) || !lua_isstring(ps, 3))
478 LUA_RETURN(ps, LUA_FAIL);
479
480 if(lua_isboolean(ps, 4) && lua_toboolean(ps, 4))
481 dir = MCB_DEL;
482
483 source = getnickbynumeric(lua_tolong(ps, 1));
484
485 cp = findchannel((char *)lua_tostring(ps, 2));
486 if(!cp)
487 LUA_RETURN(ps, LUA_FAIL);
488
489 mask = lua_tostring(ps, 3);
490 if(!mask || !mask[0] || !lua_lineok(mask))
491 LUA_RETURN(ps, LUA_FAIL);
492
493 localsetmodeinit(&changes, cp, source);
494 localdosetmode_ban(&changes, mask, dir);
495 localsetmodeflush(&changes, 1);
496
497 LUA_RETURN(ps, LUA_OK);
498}
499
500static int lua_localkick(lua_State *ps) {
501 const char *n, *msg, *chan;
502 nick *source, *np;
503 channel *cp;
504 int dochecks = 1;
505
506 if(!lua_islong(ps, 1) || !lua_isstring(ps, 2) || !lua_isstring(ps, 3) || !lua_isstring(ps, 4))
507 LUA_RETURN(ps, LUA_FAIL);
508
509 source = getnickbynumeric(lua_tolong(ps, 1));
510 chan = lua_tostring(ps, 2);
511 n = lua_tostring(ps, 3);
512 msg = lua_tostring(ps, 4);
513 if(!source)
514 LUA_RETURN(ps, LUA_FAIL);
515
516 if(lua_isboolean(ps, 4) && !lua_toboolean(ps, 4))
517 dochecks = 0;
518
519 np = getnickbynick(n);
520 if(!np)
521 LUA_RETURN(ps, LUA_FAIL);
522
523 if(dochecks && (IsOper(np) || IsXOper(np) || IsService(np)))
524 LUA_RETURN(ps, LUA_FAIL);
525
526 cp = findchannel((char *)chan);
527 if(!cp)
528 LUA_RETURN(ps, LUA_FAIL);
529
530 if(!lua_lineok(msg))
531 LUA_RETURN(ps, LUA_FAIL);
532
533 localkickuser(source, cp, np, msg);
534
535 LUA_RETURN(ps, LUA_OK);
536}
537
c0088ccb
CP
538static int lua_localrename(lua_State *ps) {
539 nick *np;
540 char *changeto;
541
542 if(!lua_islong(ps, 1) || !lua_isstring(ps, 2) )
543 LUA_RETURN(ps, LUA_FAIL);
544
545 np = getnickbynumeric(lua_tolong(ps, 1));
546 changeto = (char *)lua_tostring(ps, 2);
547
548 if(!lua_lineok(changeto))
549 LUA_RETURN(ps, LUA_FAIL);
550
551 renamelocaluser(np, changeto);
552
553 LUA_RETURN(ps, LUA_OK);
554}
555
e01edd32
CP
556static int lua_localwallusers(lua_State *ps) {
557 char *msg;
558 nick *source;
559 char senderstr[6];
560
561 if(!lua_islong(ps, 1) || !lua_isstring(ps, 2))
562 LUA_RETURN(ps, LUA_FAIL);
563
564 source = getnickbynumeric(lua_tolong(ps, 1));
565 if(!source)
566 LUA_RETURN(ps, LUA_FAIL);
567
568 msg = (char *)lua_tostring(ps, 2);
569
570 if(!lua_lineok(msg))
571 LUA_RETURN(ps, LUA_FAIL);
572
573 longtonumeric2(source->numeric,5,senderstr);
574 irc_send("%s WU :%s", senderstr, msg);
575
576 LUA_RETURN(ps, LUA_OK);
577}
578
579static int lua_localwallops(lua_State *ps) {
580 char *msg;
581 nick *source;
582 char senderstr[6];
583
584 if(!lua_islong(ps, 1) || !lua_isstring(ps, 2))
585 LUA_RETURN(ps, LUA_FAIL);
586
587 source = getnickbynumeric(lua_tolong(ps, 1));
588 if(!source)
589 LUA_RETURN(ps, LUA_FAIL);
590
591 msg = (char *)lua_tostring(ps, 2);
592
593 if(!lua_lineok(msg))
594 LUA_RETURN(ps, LUA_FAIL);
595
596 longtonumeric2(source->numeric,5,senderstr);
597 irc_send("%s WA :%s", senderstr, msg);
598
599 LUA_RETURN(ps, LUA_OK);
600}
601
0225bed3 602void lua_registerlocalcommands(lua_State *l) {
5541f23c 603 lua_register(l, "irc_localregisteruserid", lua_registerlocaluserid);
0225bed3
CP
604 lua_register(l, "irc_localderegisteruser", lua_deregisterlocaluser);
605 lua_register(l, "irc_localjoin", lua_localjoin);
b7252b44 606 lua_register(l, "irc_localpart", lua_localpart);
0225bed3
CP
607 lua_register(l, "irc_localchanmsg", lua_localchanmsg);
608 lua_register(l, "irc_localnotice", lua_localnotice);
34552caa 609 lua_register(l, "irc_localprivmsg", lua_localprivmsg);
ba436ecf
CP
610
611 lua_register(l, "irc_localovmode", lua_localovmode);
f9f8ee13 612 lua_register(l, "irc_localtopic", lua_localtopic);
ba436ecf 613
c0d574fa
CP
614 lua_register(l, "irc_localban", lua_localban);
615 lua_register(l, "irc_localkick", lua_localkick);
eac66732 616 lua_register(l, "irc_localumodes", lua_localumodes);
c0088ccb
CP
617
618 lua_register(l, "irc_localrename", lua_localrename);
e01edd32
CP
619
620 lua_register(l, "irc_localwallusers", lua_localwallusers);
621 lua_register(l, "irc_localwallops", lua_localwallops);
0225bed3
CP
622}
623