]>
jfr.im git - irc/quakenet/newserv.git/blob - lua/lualocal.c
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"
13 void lua_localnickhandler(nick
*target
, int type
, void **args
);
14 void lua_reconnectlocal(void *arg
);
16 static int lua_registerlocaluserid(lua_State
*ps
) {
19 char *nickname
, *ident
, *hostname
, *realname
, *account
;
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))
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);
31 if(lua_islong(ps
, 6)) {
32 userid
= lua_tolong(ps
, 6);
37 setflags(&modes
, UMODE_ALL
, (char *)lua_tostring(ps
, 7), umodeflags
, REJECT_NONE
);
39 if(!lua_lineok(nickname
) || !lua_lineok(ident
) || !lua_lineok(hostname
) || !lua_lineok(realname
) || !lua_lineok(account
))
42 l
= lua_listfromstate(ps
);
46 ln
= (lua_localnick
*)luamalloc(sizeof(lua_localnick
));
52 ln
->nick
= registerlocaluserflags(nickname
, ident
, hostname
, realname
, account
, userid
, 0, modes
, &lua_localnickhandler
);
58 ln
->handler
= luaL_ref(ps
, LUA_REGISTRYINDEX
);
63 lua_pushlong(ps
, ln
->nick
->numeric
);
67 void lua_freelocalnick(lua_State
*ps
, lua_localnick
*l
, char *quitm
) {
69 deregisterlocaluser(l
->nick
, quitm
);
72 deleteschedule(l
->reconnect
, &lua_reconnectlocal
, l
);
74 luaL_unref(ps
, LUA_REGISTRYINDEX
, l
->handler
);
79 int lua_getlocalnickbynick(nick
*np
, lua_list
**rl
, lua_localnick
**rln
) {
83 for(l
=lua_head
;l
;l
=l
->next
)
84 for(ln
=l
->nicks
;ln
;ln
=ln
->next
)
94 static int lua_deregisterlocaluser(lua_State
*ps
) {
96 lua_localnick
*l2
, *lp
= NULL
;
100 if(!lua_islong(ps
, 1))
101 LUA_RETURN(ps
, LUA_FAIL
);
103 numeric
= lua_tolong(ps
, 1);
105 quitm
= lua_isstring(ps
, 2)?(char *)lua_tostring(ps
, 2):"localuser unregistered.";
107 l
= lua_listfromstate(ps
);
109 for(l2
=l
->nicks
;l2
;lp
=l2
,l2
=l2
->next
) {
110 if(l2
->nick
&& l2
->nick
->numeric
== numeric
) {
117 lua_freelocalnick(ps
, l2
, quitm
);
118 LUA_RETURN(ps
, LUA_OK
);
122 LUA_RETURN(ps
, LUA_FAIL
);
125 void lua_deregisternicks(lua_list
*l
) {
126 struct lua_localnick
*ln
, *pn
;
133 lua_freelocalnick(l
->l
, ln
, "Script unloaded.");
140 void lua_localnickhandler(nick
*target
, int type
, void **args
) {
147 if(!lua_getlocalnickbynick(target
, &l
, &ln
))
152 np
= (nick
*)args
[0];
158 lua_vlpcall(l
, ln
, "irc_onmsg", "Ns", np
, p
);
163 np
= (nick
*)args
[0];
169 lua_vlpcall(l
, ln
, "irc_onnotice", "Ns", np
, p
);
174 np
= (nick
*)args
[0];
175 c
= (channel
*)args
[1];
178 if(!np
|| !p
|| !c
|| !c
->index
|| !c
->index
->name
|| !c
->index
->name
->content
)
181 lua_vlpcall(l
, ln
, "irc_onchanmsg", "Nss", np
, c
->index
->name
->content
, p
);
185 lua_vlpcall(l
, ln
, "irc_onkilled", "");
187 strlcpy(ln
->nickname
, target
->nick
, sizeof(ln
->nickname
));
188 strlcpy(ln
->ident
, target
->ident
, sizeof(ln
->ident
));
189 strlcpy(ln
->hostname
, target
->host
->name
->content
, sizeof(ln
->hostname
));
190 strlcpy(ln
->realname
, target
->realname
->name
->content
, sizeof(ln
->realname
));
191 strlcpy(ln
->account
, target
->authname
, sizeof(ln
->account
));
193 ln
->umodes
= target
->umodes
;
196 ln
->reconnect
= scheduleoneshot(time(NULL
) + 1, &lua_reconnectlocal
, ln
);
200 /* we were invited, check if someone invited us to PUBLICCHAN */
201 np
= (nick
*)args
[0];
202 c
= (channel
*)args
[1];
204 if(!c
|| !np
|| !c
->index
|| !c
->index
->name
|| !c
->index
->name
->content
)
207 lua_vlpcall(l
, ln
, "irc_oninvite", "Ns", np
, c
->index
->name
->content
);
212 void lua_reconnectlocal(void *arg
) {
214 lua_localnick
*ln
= (lua_localnick
*)arg
;
216 ln
->nick
= registerlocaluser(ln
->nickname
, ln
->ident
, ln
->hostname
, ln
->realname
, ln
->account
, ln
->umodes
, &lua_localnickhandler
);
218 ln
->reconnect
= scheduleoneshot(time(NULL
) + 1, &lua_reconnectlocal
, ln
);
222 ln
->reconnect
= NULL
;
224 if(lua_getlocalnickbynick(ln
->nick
, &l
, &ln
)) /* hacky! */
225 lua_vlpcall(l
, ln
, "irc_onkillreconnect", "");
228 static int lua_localjoin(lua_State
*ps
) {
233 if(!lua_islong(ps
, 1) || !lua_isstring(ps
, 2))
234 LUA_RETURN(ps
, LUA_FAIL
);
236 source
= getnickbynumeric(lua_tolong(ps
, 1));
238 LUA_RETURN(ps
, LUA_FAIL
);
240 chan
= (char *)lua_tostring(ps
, 2);
242 LUA_RETURN(ps
, LUA_FAIL
);
244 if(!lua_lineok(chan
))
245 LUA_RETURN(ps
, LUA_FAIL
);
247 target
= findchannel(chan
);
249 localjoinchannel(source
, target
);
251 localcreatechannel(source
, chan
);
254 LUA_RETURN(ps
, LUA_OK
);
257 static int lua_localpart(lua_State
*ps
) {
262 if(!lua_islong(ps
, 1) || !lua_isstring(ps
, 2))
263 LUA_RETURN(ps
, LUA_FAIL
);
265 source
= getnickbynumeric(lua_tolong(ps
, 1));
267 LUA_RETURN(ps
, LUA_FAIL
);
269 chan
= (char *)lua_tostring(ps
, 2);
271 if(!lua_lineok(chan
))
272 LUA_RETURN(ps
, LUA_FAIL
);
274 if(lua_isstring(ps
, 3)) {
275 reason
= (char *)lua_tostring(ps
, 3);
276 if(!lua_lineok(reason
))
277 LUA_RETURN(ps
, LUA_FAIL
);
282 target
= findchannel(chan
);
284 localpartchannel(source
, target
, reason
);
286 LUA_RETURN(ps
, LUA_FAIL
);
289 LUA_RETURN(ps
, LUA_OK
);
292 static int lua_localchanmsg(lua_State
*ps
) {
297 if(!lua_islong(ps
, 1) || !lua_isstring(ps
, 2) || !lua_isstring(ps
, 3))
298 LUA_RETURN(ps
, LUA_FAIL
);
300 source
= getnickbynumeric(lua_tolong(ps
, 1));
302 LUA_RETURN(ps
, LUA_FAIL
);
304 target
= findchannel((char *)lua_tostring(ps
, 2));
306 LUA_RETURN(ps
, LUA_FAIL
);
308 msg
= (char *)lua_tostring(ps
, 3);
311 LUA_RETURN(ps
, LUA_FAIL
);
313 sendmessagetochannel(source
, target
, "%s", msg
);
315 LUA_RETURN(ps
, LUA_OK
);
318 static int lua_localnotice(lua_State
*ps
) {
323 if(!lua_islong(ps
, 1) || !lua_islong(ps
, 2) || !lua_isstring(ps
, 3))
324 LUA_RETURN(ps
, LUA_FAIL
);
326 source
= getnickbynumeric(lua_tolong(ps
, 1));
328 LUA_RETURN(ps
, LUA_FAIL
);
330 target
= getnickbynumeric(lua_tolong(ps
, 2));
332 LUA_RETURN(ps
, LUA_FAIL
);
334 msg
= (char *)lua_tostring(ps
, 3);
337 LUA_RETURN(ps
, LUA_FAIL
);
339 sendnoticetouser(source
, target
, "%s", msg
);
341 LUA_RETURN(ps
, LUA_OK
);
344 static int lua_localprivmsg(lua_State
*ps
) {
349 if(!lua_islong(ps
, 1) || !lua_islong(ps
, 2) || !lua_isstring(ps
, 3))
350 LUA_RETURN(ps
, LUA_FAIL
);
352 source
= getnickbynumeric(lua_tolong(ps
, 1));
354 LUA_RETURN(ps
, LUA_FAIL
);
356 target
= getnickbynumeric(lua_tolong(ps
, 2));
358 LUA_RETURN(ps
, LUA_FAIL
);
360 msg
= (char *)lua_tostring(ps
, 3);
363 LUA_RETURN(ps
, LUA_FAIL
);
365 sendmessagetouser(source
, target
, "%s", msg
);
367 LUA_RETURN(ps
, LUA_OK
);
370 static int lua_localovmode(lua_State
*l
) {
373 int state
= 0, add
= 0, realmode
= 0, ignoring
= 0;
376 if(!lua_islong(l
, 1) || !lua_isstring(l
, 2) || !lua_istable(l
, 3))
377 LUA_RETURN(l
, LUA_FAIL
);
379 source
= getnickbynumeric(lua_tolong(l
, 1));
381 LUA_RETURN(l
, LUA_FAIL
);
383 chan
= findchannel((char *)lua_tostring(l
, 2));
385 LUA_RETURN(l
, LUA_FAIL
);
387 localsetmodeinit(&changes
, chan
, source
);
391 while(lua_next(l
, 3)) {
395 if(!lua_isboolean(l
, -1)) {
398 add
= (int)lua_toboolean(l
, -1);
400 } else if((state
== 1) && !ignoring
) {
401 if(!lua_isstring(l
, -1)) {
404 char *mode
= (char *)lua_tostring(l
, -1);
405 if((*mode
== 'o') && add
) {
407 } else if (*mode
== 'o') {
409 } else if((*mode
== 'v') && add
) {
411 } else if (*mode
== 'v') {
412 realmode
= MC_DEVOICE
;
417 } else if((state
== 2) && !ignoring
) {
418 if(lua_islong(l
, -1)) {
419 nick
*target
= getnickbynumeric(lua_tolong(l
, -1));
421 localdosetmode_nick(&changes
, target
, realmode
);
427 state
= (state
+ 1) % 3;
430 localsetmodeflush(&changes
, 1);
432 LUA_RETURN(l
, LUA_OK
);
435 static int lua_localumodes(lua_State
*ps
) {
440 if(!lua_islong(ps
, 1) || !lua_isstring(ps
, 2))
441 LUA_RETURN(ps
, LUA_FAIL
);
443 np
= getnickbynumeric(lua_tolong(ps
, 1));
445 LUA_RETURN(ps
, LUA_FAIL
);
447 modes
= (char *)lua_tostring(ps
, 2);
449 setflags(&newmodes
, UMODE_ALL
, modes
, umodeflags
, REJECT_NONE
);
451 localusersetumodes(np
, newmodes
);
452 LUA_RETURN(ps
, LUA_OK
);
455 static int lua_localtopic(lua_State
*ps
) {
460 if(!lua_islong(ps
, 1) || !lua_isstring(ps
, 2) || !lua_isstring(ps
, 3))
461 LUA_RETURN(ps
, LUA_FAIL
);
463 np
= getnickbynumeric(lua_tolong(ps
, 1));
465 LUA_RETURN(ps
, LUA_FAIL
);
467 cp
= findchannel((char *)lua_tostring(ps
, 2));
469 LUA_RETURN(ps
, LUA_FAIL
);
471 topic
= (char *)lua_tostring(ps
, 3);
472 if(!topic
|| !lua_lineok(topic
))
473 LUA_RETURN(ps
, LUA_FAIL
);
475 localsettopic(np
, cp
, topic
);
477 LUA_RETURN(ps
, LUA_OK
);
480 static int lua_localban(lua_State
*ps
) {
488 if(!lua_islong(ps
, 1) || !lua_isstring(ps
, 2) || !lua_isstring(ps
, 3))
489 LUA_RETURN(ps
, LUA_FAIL
);
491 if(lua_isboolean(ps
, 4) && lua_toboolean(ps
, 4))
494 source
= getnickbynumeric(lua_tolong(ps
, 1));
496 cp
= findchannel((char *)lua_tostring(ps
, 2));
498 LUA_RETURN(ps
, LUA_FAIL
);
500 mask
= lua_tostring(ps
, 3);
501 if(!mask
|| !mask
[0] || !lua_lineok(mask
))
502 LUA_RETURN(ps
, LUA_FAIL
);
504 localsetmodeinit(&changes
, cp
, source
);
505 localdosetmode_ban(&changes
, mask
, dir
);
506 localsetmodeflush(&changes
, 1);
508 LUA_RETURN(ps
, LUA_OK
);
511 static int lua_localkick(lua_State
*ps
) {
512 const char *n
, *msg
, *chan
;
517 if(!lua_islong(ps
, 1) || !lua_isstring(ps
, 2) || !lua_isstring(ps
, 3) || !lua_isstring(ps
, 4))
518 LUA_RETURN(ps
, LUA_FAIL
);
520 source
= getnickbynumeric(lua_tolong(ps
, 1));
521 chan
= lua_tostring(ps
, 2);
522 n
= lua_tostring(ps
, 3);
523 msg
= lua_tostring(ps
, 4);
525 LUA_RETURN(ps
, LUA_FAIL
);
527 if(lua_isboolean(ps
, 4) && !lua_toboolean(ps
, 4))
530 np
= getnickbynick(n
);
532 LUA_RETURN(ps
, LUA_FAIL
);
534 if(dochecks
&& (IsOper(np
) || IsXOper(np
) || IsService(np
)))
535 LUA_RETURN(ps
, LUA_FAIL
);
537 cp
= findchannel((char *)chan
);
539 LUA_RETURN(ps
, LUA_FAIL
);
542 LUA_RETURN(ps
, LUA_FAIL
);
544 localkickuser(source
, cp
, np
, msg
);
546 LUA_RETURN(ps
, LUA_OK
);
549 static int lua_localrename(lua_State
*ps
) {
553 if(!lua_islong(ps
, 1) || !lua_isstring(ps
, 2) )
554 LUA_RETURN(ps
, LUA_FAIL
);
556 np
= getnickbynumeric(lua_tolong(ps
, 1));
557 changeto
= (char *)lua_tostring(ps
, 2);
559 if(!lua_lineok(changeto
))
560 LUA_RETURN(ps
, LUA_FAIL
);
562 renamelocaluser(np
, changeto
);
564 LUA_RETURN(ps
, LUA_OK
);
567 static int lua_localwallusers(lua_State
*ps
) {
572 if(!lua_islong(ps
, 1) || !lua_isstring(ps
, 2))
573 LUA_RETURN(ps
, LUA_FAIL
);
575 source
= getnickbynumeric(lua_tolong(ps
, 1));
577 LUA_RETURN(ps
, LUA_FAIL
);
579 msg
= (char *)lua_tostring(ps
, 2);
582 LUA_RETURN(ps
, LUA_FAIL
);
584 longtonumeric2(source
->numeric
,5,senderstr
);
585 irc_send("%s WU :%s", senderstr
, msg
);
587 LUA_RETURN(ps
, LUA_OK
);
590 static int lua_localwallops(lua_State
*ps
) {
595 if(!lua_islong(ps
, 1) || !lua_isstring(ps
, 2))
596 LUA_RETURN(ps
, LUA_FAIL
);
598 source
= getnickbynumeric(lua_tolong(ps
, 1));
600 LUA_RETURN(ps
, LUA_FAIL
);
602 msg
= (char *)lua_tostring(ps
, 2);
605 LUA_RETURN(ps
, LUA_FAIL
);
607 longtonumeric2(source
->numeric
,5,senderstr
);
608 irc_send("%s WA :%s", senderstr
, msg
);
610 LUA_RETURN(ps
, LUA_OK
);
613 static int lua_localsimplechanmode(lua_State
*ps
) {
617 flag_t add
= 0, del
= ~add
;
618 flag_t permitted
= CHANMODE_NOEXTMSG
| CHANMODE_TOPICLIMIT
| CHANMODE_SECRET
| CHANMODE_PRIVATE
| CHANMODE_INVITEONLY
| CHANMODE_MODERATE
| CHANMODE_NOCOLOUR
| CHANMODE_NOCTCP
| CHANMODE_REGONLY
| CHANMODE_DELJOINS
| CHANMODE_NOQUITMSG
| CHANMODE_NONOTICE
| CHANMODE_MODNOAUTH
| CHANMODE_SINGLETARG
;
621 if(!lua_islong(ps
, 1) || !lua_isstring(ps
, 2) || !lua_isstring(ps
, 3))
622 LUA_RETURN(ps
, LUA_FAIL
);
624 source
= getnickbynumeric(lua_tolong(ps
, 1));
626 LUA_RETURN(ps
, LUA_FAIL
);
628 cp
= findchannel((char *)lua_tostring(ps
, 2));
630 LUA_RETURN(ps
, LUA_FAIL
);
632 modes
= (char *)lua_tostring(ps
, 3);
634 LUA_RETURN(ps
, LUA_FAIL
);
636 if(setflags(&add
, permitted
, modes
, cmodeflags
, REJECT_DISALLOWED
|REJECT_UNKNOWN
) != REJECT_NONE
)
637 LUA_RETURN(ps
, LUA_FAIL
);
639 if(setflags(&del
, permitted
, modes
, cmodeflags
, REJECT_DISALLOWED
|REJECT_UNKNOWN
) != REJECT_NONE
)
640 LUA_RETURN(ps
, LUA_FAIL
);
642 localsetmodeinit(&changes
, cp
, source
);
643 localdosetmode_simple(&changes
, add
, ~del
);
644 localsetmodeflush(&changes
, 1);
646 LUA_RETURN(ps
, LUA_OK
);
649 void lua_registerlocalcommands(lua_State
*l
) {
650 lua_register(l
, "irc_localregisteruserid", lua_registerlocaluserid
);
651 lua_register(l
, "irc_localderegisteruser", lua_deregisterlocaluser
);
652 lua_register(l
, "irc_localjoin", lua_localjoin
);
653 lua_register(l
, "irc_localpart", lua_localpart
);
654 lua_register(l
, "irc_localchanmsg", lua_localchanmsg
);
655 lua_register(l
, "irc_localnotice", lua_localnotice
);
656 lua_register(l
, "irc_localprivmsg", lua_localprivmsg
);
658 lua_register(l
, "irc_localovmode", lua_localovmode
);
659 lua_register(l
, "irc_localtopic", lua_localtopic
);
661 lua_register(l
, "irc_localban", lua_localban
);
662 lua_register(l
, "irc_localkick", lua_localkick
);
663 lua_register(l
, "irc_localumodes", lua_localumodes
);
665 lua_register(l
, "irc_localrename", lua_localrename
);
667 lua_register(l
, "irc_localwallusers", lua_localwallusers
);
668 lua_register(l
, "irc_localwallops", lua_localwallops
);
670 lua_register(l
, "irc_localsimplechanmode", lua_localsimplechanmode
);