]>
jfr.im git - irc/quakenet/newserv.git/blob - lua/luacommands.c
1 /* Copyright (C) Chris Porter 2005-2007 */
2 /* ALL RIGHTS RESERVED. */
3 /* Don't put this into the SVN repo. */
7 - Write a nick printf type thing for pcalled functions.
8 - Make commands register as apposed to blinding calling.
9 - Use numerics instead of huge structures, and add lookup functions.
12 #include "../channel/channel.h"
13 #include "../control/control.h"
14 #include "../nick/nick.h"
15 #include "../localuser/localuser.h"
16 #include "../localuser/localuserchannel.h"
17 #include "../lib/irc_string.h"
18 #include "../lib/flags.h"
19 #include "../authext/authext.h"
20 #include "../glines/glines.h"
30 static int lua_smsg(lua_State
*ps
);
31 static int lua_skill(lua_State
*ps
);
33 typedef struct lua_pusher
{
36 const char *structname
;
39 struct lua_pusher nickpusher
[MAX_PUSHER
];
40 struct lua_pusher chanpusher
[MAX_PUSHER
];
41 int nickpushercount
, chanpushercount
;
43 void lua_setuppusher(struct lua_pusher
*pusherlist
, lua_State
*l
, int index
, struct lua_pusher
**lp
, int max
, int pcount
);
44 int lua_usepusher(lua_State
*l
, struct lua_pusher
**lp
, void *np
);
46 void lua_initnickpusher(void);
47 void lua_initchanpusher(void);
49 #define lua_setupnickpusher(L2, I2, P2, M2) lua_setuppusher(&nickpusher[0], L2, I2, P2, M2, nickpushercount)
50 #define lua_setupchanpusher(L2, I2, P2, M2) lua_setuppusher(&chanpusher[0], L2, I2, P2, M2, chanpushercount)
52 int lua_cmsg(char *channell
, char *message
, ...) __attribute__ ((format (printf
, 2, 3)));
54 int lua_cmsg(char *channell
, char *message
, ...) {
59 va_start(va
, message
);
60 vsnprintf(buf
, sizeof(buf
), message
, va
);
63 cp
= findchannel(channell
);
70 lua_channelmessage(cp
, "%s", buf
);
75 static int lua_chanmsg(lua_State
*ps
) {
76 if(!lua_isstring(ps
, 1))
77 LUA_RETURN(ps
, LUA_FAIL
);
79 LUA_RETURN(ps
, lua_cmsg(LUA_PUKECHAN
, "lua: %s", lua_tostring(ps
, 1)));
82 static int lua_ctcp(lua_State
*ps
) {
86 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
87 LUA_RETURN(ps
, LUA_FAIL
);
89 n
= lua_tostring(ps
, 1);
90 msg
= lua_tostring(ps
, 2);
92 np
= getnickbynick(n
);
93 if(!np
|| !lua_lineok(msg
))
94 LUA_RETURN(ps
, LUA_FAIL
);
96 lua_message(np
, "\001%s\001", msg
);
98 LUA_RETURN(ps
, lua_cmsg(LUA_PUKECHAN
, "lua-ctcp: %s (%s)", np
->nick
, msg
));
101 static int lua_noticecmd(lua_State
*ps
) {
105 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
106 LUA_RETURN(ps
, LUA_FAIL
);
108 n
= lua_tostring(ps
, 1);
109 msg
= lua_tostring(ps
, 2);
111 np
= getnickbynick(n
);
112 if(!np
|| !lua_lineok(msg
))
113 LUA_RETURN(ps
, LUA_FAIL
);
115 lua_notice(np
, "%s", msg
);
117 LUA_RETURN(ps
, LUA_OK
);
120 static int lua_privmsgcmd(lua_State
*ps
) {
124 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
125 LUA_RETURN(ps
, LUA_FAIL
);
127 n
= lua_tostring(ps
, 1);
128 msg
= lua_tostring(ps
, 2);
130 np
= getnickbynick(n
);
131 if(!np
|| !lua_lineok(msg
))
132 LUA_RETURN(ps
, LUA_FAIL
);
134 lua_message(np
, "%s", msg
);
136 LUA_RETURN(ps
, LUA_OK
);
139 static int lua_kill(lua_State
*ps
) {
143 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
144 LUA_RETURN(ps
, LUA_FAIL
);
146 n
= lua_tostring(ps
, 1);
147 msg
= lua_tostring(ps
, 2);
149 np
= getnickbynick(n
);
151 LUA_RETURN(ps
, LUA_FAIL
);
153 if(IsOper(np
) || IsService(np
) || IsXOper(np
))
154 LUA_RETURN(ps
, LUA_FAIL
);
157 LUA_RETURN(ps
, LUA_FAIL
);
159 killuser(lua_nick
, np
, "%s", msg
);
161 LUA_RETURN(ps
, lua_cmsg(LUA_PUKECHAN
, "lua-KILL: %s (%s)", np
->nick
, msg
));
164 static int lua_kick(lua_State
*ps
) {
165 const char *n
, *msg
, *chan
;
170 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2) || !lua_isstring(ps
, 3))
171 LUA_RETURN(ps
, LUA_FAIL
);
173 chan
= lua_tostring(ps
, 1);
174 n
= lua_tostring(ps
, 2);
175 msg
= lua_tostring(ps
, 3);
177 if(lua_isboolean(ps
, 4) && !lua_toboolean(ps
, 4))
180 np
= getnickbynick(n
);
182 LUA_RETURN(ps
, LUA_FAIL
);
184 if(dochecks
&& (IsOper(np
) || IsXOper(np
) || IsService(np
)))
185 LUA_RETURN(ps
, LUA_FAIL
);
187 cp
= findchannel((char *)chan
);
189 LUA_RETURN(ps
, LUA_FAIL
);
192 LUA_RETURN(ps
, LUA_FAIL
);
194 localkickuser(lua_nick
, cp
, np
, msg
);
196 LUA_RETURN(ps
, LUA_OK
);
199 static int lua_invite(lua_State
*ps
) {
203 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
204 LUA_RETURN(ps
, LUA_FAIL
);
206 np
= getnickbynick((char *)lua_tostring(ps
, 1));
208 LUA_RETURN(ps
, LUA_FAIL
);
210 cp
= findchannel((char *)lua_tostring(ps
, 2));
212 LUA_RETURN(ps
, LUA_FAIL
);
214 localinvite(lua_nick
, cp
->index
, np
);
216 LUA_RETURN(ps
, LUA_OK
);
219 static int lua_gline(lua_State
*ps
) {
223 int duration
, usercount
= 0;
225 if(!lua_isstring(ps
, 1) || !lua_isint(ps
, 2) || !lua_isstring(ps
, 3))
226 LUA_RETURN(ps
, LUA_FAIL
);
228 duration
= lua_toint(ps
, 2);
229 if((duration
< 1) || (duration
> 31 * 86400))
230 LUA_RETURN(ps
, LUA_FAIL
);
232 reason
= lua_tostring(ps
, 3);
233 if(!lua_lineok(reason
) || !reason
)
234 LUA_RETURN(ps
, LUA_FAIL
);
236 target
= getnickbynick(lua_tostring(ps
, 1));
237 if(!target
|| (IsOper(target
) || IsXOper(target
) || IsService(target
)))
238 LUA_RETURN(ps
, LUA_FAIL
);
240 if(glinebynick(target
, duration
, reason
, GLINE_SIMULATE
, "lua") > 50)
241 LUA_RETURN(ps
, LUA_FAIL
);
243 usercount
= glinebynick(target
, duration
, reason
, 0, "lua");
244 LUA_RETURN(ps
, lua_cmsg(LUA_PUKECHAN
, "lua-GLINE: %s (%d users, %d seconds -- %s)", mask
, usercount
, duration
, reason
));
247 static int lua_fastgetchaninfo(lua_State
*ps
) {
248 static struct lua_pusher
*ourpusher
[MAX_PUSHER
];
251 if(!lua_isstring(ps
, 1))
254 cp
= findchannel((char *)lua_tostring(ps
, 1));
255 if(!cp
|| cp
->index
->channel
!= cp
)
258 lua_setupchanpusher(ps
, 2, ourpusher
, MAX_PUSHER
);
259 return lua_usepusher(ps
, ourpusher
, cp
->index
);
262 static int lua_opchan(lua_State
*ps
) {
266 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
267 LUA_RETURN(ps
, LUA_FAIL
);
269 cp
= findchannel((char *)lua_tostring(ps
, 1));
271 LUA_RETURN(ps
, LUA_FAIL
);
273 np
= getnickbynick((char *)lua_tostring(ps
, 2));
275 LUA_RETURN(ps
, LUA_FAIL
);
277 localsetmodes(lua_nick
, cp
, np
, MC_OP
);
278 LUA_RETURN(ps
, LUA_OK
);
281 static int lua_deopchan(lua_State
*ps
) {
285 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
286 LUA_RETURN(ps
, LUA_FAIL
);
288 cp
= findchannel((char *)lua_tostring(ps
, 1));
290 LUA_RETURN(ps
, LUA_FAIL
);
292 np
= getnickbynick((char *)lua_tostring(ps
, 2));
294 LUA_RETURN(ps
, LUA_FAIL
);
296 localsetmodes(lua_nick
, cp
, np
, MC_DEOP
);
297 LUA_RETURN(ps
, LUA_OK
);
300 static int lua_voicechan(lua_State
*ps
) {
304 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
305 LUA_RETURN(ps
, LUA_FAIL
);
307 cp
= findchannel((char *)lua_tostring(ps
, 1));
309 LUA_RETURN(ps
, LUA_FAIL
);
311 np
= getnickbynick((char *)lua_tostring(ps
, 2));
313 LUA_RETURN(ps
, LUA_FAIL
);
315 localsetmodes(lua_nick
, cp
, np
, MC_VOICE
);
316 LUA_RETURN(ps
, LUA_OK
);
319 static int lua_counthost(lua_State
*ps
) {
323 if(!lua_islong(ps
, 1))
326 numeric
= lua_tolong(ps
, 1);
328 np
= getnickbynumeric(numeric
);
332 lua_pushint(ps
, np
->host
->clonecount
);
336 static int lua_versioninfo(lua_State
*ps
) {
337 lua_pushstring(ps
, LUA_VERSION
);
338 lua_pushstring(ps
, LUA_BOTVERSION
);
339 lua_pushstring(ps
, __DATE__
);
340 lua_pushstring(ps
, __TIME__
);
342 lua_pushstring(ps
, LUA_AUXVERSION
);
347 static int lua_basepath(lua_State
*ps
) {
348 lua_pushfstring(ps
, "%s/", cpath
->content
);
353 static int lua_botnick(lua_State
*ps
) {
354 lua_pushstring(ps
, luabotnick
->content
);
359 static int lua_numerictobase64(lua_State
*ps
) {
360 if(!lua_islong(ps
, 1))
363 lua_pushstring(ps
, longtonumeric(lua_tolong(ps
, 1), 5));
367 static int lua_getuserbyauth(lua_State
*l
) {
372 if(!lua_isstring(l
, 1))
375 au
= getauthbyname(lua_tostring(l
, 1));
379 for(np
=au
->nicks
;np
;np
=np
->nextbyauthname
) {
380 lua_pushnumeric(l
, np
->numeric
);
387 static int lua_getnickchans(lua_State
*l
) {
392 if(!lua_islong(l
, 1))
395 np
= getnickbynumeric(lua_tolong(l
, 1));
399 channels
= (channel
**)np
->channels
->content
;
400 for(i
=0;i
<np
->channels
->cursi
;i
++)
401 lua_pushstring(l
, channels
[i
]->index
->name
->content
);
403 return np
->channels
->cursi
;
406 static int lua_getnickchanindex(lua_State
*l
) {
410 if(!lua_islong(l
, 1) || !lua_isint(l
, 2))
413 np
= getnickbynumeric(lua_tolong(l
, 1));
417 offset
= lua_toint(l
, 2);
418 if((offset
< 0) || (offset
>= np
->channels
->cursi
))
421 lua_pushstring(l
, ((channel
**)np
->channels
->content
)[offset
]->index
->name
->content
);
430 struct lua_pusher
*nickhashpusher
[MAX_PUSHER
];
432 static int lua_getnextnick(lua_State
*l
) {
433 if(!lasthashnick
&& (hashindex
!= -1))
439 if(hashindex
>= NICKHASHSIZE
)
441 lasthashnick
= nicktable
[hashindex
];
443 lasthashnick
= lasthashnick
->next
;
445 } while(!lasthashnick
);
447 return lua_usepusher(l
, nickhashpusher
, lasthashnick
);
450 static int lua_getfirstnick(lua_State
*l
) {
454 lua_setupnickpusher(l
, 1, nickhashpusher
, MAX_PUSHER
);
455 geoipext
= findnickext("geoip");
457 return lua_getnextnick(l
);
461 chanindex
*lasthashchan
;
463 struct lua_pusher
*chanhashpusher
[MAX_PUSHER
];
465 static int lua_getnextchan(lua_State
*l
) {
466 if(!lasthashchan
&& (chanhashindex
!= -1))
472 if(chanhashindex
>= CHANNELHASHSIZE
)
474 lasthashchan
= chantable
[chanhashindex
];
476 lasthashchan
= lasthashchan
->next
;
478 } while(!lasthashchan
|| !lasthashchan
->channel
);
480 return lua_usepusher(l
, chanhashpusher
, lasthashchan
);
483 static int lua_getfirstchan(lua_State
*l
) {
487 lua_setupchanpusher(l
, 1, chanhashpusher
, MAX_PUSHER
);
489 return lua_getnextchan(l
);
492 static int lua_getnickchancount(lua_State
*l
) {
495 if(!lua_islong(l
, 1))
498 np
= getnickbynumeric(lua_tolong(l
, 1));
502 lua_pushint(l
, np
->channels
->cursi
);
507 static int lua_gethostusers(lua_State
*l
) {
511 if(!lua_islong(l
, 1))
514 np
= getnickbynumeric(lua_tolong(l
, 1));
515 if(!np
|| !np
->host
|| !np
->host
->nicks
)
518 np
= np
->host
->nicks
;
519 count
= np
->host
->clonecount
;
522 lua_pushnumeric(l
, np
->numeric
);
529 static int lua_getnickcountry(lua_State
*l
) {
533 ext
= findnickext("geoip");
537 if(!lua_islong(l
, 1))
540 np
= getnickbynumeric(lua_tolong(l
, 1));
544 lua_pushint(l
, (long)np
->exts
[ext
]);
548 static int lua_chanfix(lua_State
*ps
) {
552 if(!lua_isstring(ps
, 1))
553 LUA_RETURN(ps
, LUA_FAIL
);
555 cp
= findchannel((char *)lua_tostring(ps
, 1));
556 if(!cp
|| !cp
->index
)
557 LUA_RETURN(ps
, LUA_FAIL
);
559 np
= getnickbynick(LUA_CHANFIXBOT
);
561 LUA_RETURN(ps
, LUA_FAIL
);
563 lua_message(np
, "chanfix %s", cp
->index
->name
->content
);
565 LUA_RETURN(ps
, LUA_OK
);
568 static int lua_clearmode(lua_State
*ps
) {
575 if(!lua_isstring(ps
, 1))
576 LUA_RETURN(ps
, LUA_FAIL
);
578 cp
= findchannel((char *)lua_tostring(ps
, 1));
579 if(!cp
|| !cp
->users
)
580 LUA_RETURN(ps
, LUA_FAIL
);
582 localsetmodeinit(&changes
, cp
, lua_nick
);
584 localdosetmode_key(&changes
, NULL
, MCB_DEL
);
585 localdosetmode_simple(&changes
, 0, CHANMODE_INVITEONLY
| CHANMODE_LIMIT
);
588 localdosetmode_ban(&changes
, bantostring(cp
->bans
), MCB_DEL
);
590 for(i
=0,lp
=cp
->users
->content
;i
<cp
->users
->hashsize
;i
++,lp
++)
591 if((*lp
!= nouser
) && (*lp
& CUMODE_OP
)) {
592 np
= getnickbynumeric(*lp
);
593 if(np
&& !IsService(np
))
594 localdosetmode_nick(&changes
, np
, MC_DEOP
);
597 localsetmodeflush(&changes
, 1);
599 LUA_RETURN(ps
, LUA_OK
);
602 static int lua_ban(lua_State
*ps
) {
608 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
609 LUA_RETURN(ps
, LUA_FAIL
);
611 if(lua_isboolean(ps
, 3) && lua_toboolean(ps
, 3))
614 cp
= findchannel((char *)lua_tostring(ps
, 1));
616 LUA_RETURN(ps
, LUA_FAIL
);
618 mask
= lua_tostring(ps
, 2);
619 if(!mask
|| !mask
[0] || !lua_lineok(mask
))
620 LUA_RETURN(ps
, LUA_FAIL
);
622 localsetmodeinit(&changes
, cp
, lua_nick
);
623 localdosetmode_ban(&changes
, mask
, dir
);
624 localsetmodeflush(&changes
, 1);
626 LUA_RETURN(ps
, LUA_OK
);
629 static int lua_topic(lua_State
*ps
) {
633 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
634 LUA_RETURN(ps
, LUA_FAIL
);
636 cp
= findchannel((char *)lua_tostring(ps
, 1));
638 LUA_RETURN(ps
, LUA_FAIL
);
640 topic
= (char *)lua_tostring(ps
, 2);
641 if(!topic
|| !lua_lineok(topic
))
642 LUA_RETURN(ps
, LUA_FAIL
);
644 localsettopic(lua_nick
, cp
, topic
);
646 LUA_RETURN(ps
, LUA_OK
);
649 static int lua_getuserchanmodes(lua_State
*l
) {
654 if(!lua_islong(l
, 1) || !lua_isstring(l
, 2))
657 np
= getnickbynumeric(lua_tolong(l
, 1));
661 cp
= findchannel((char *)lua_tostring(l
, 2));
662 if(!cp
|| !cp
->users
)
665 lp
= getnumerichandlefromchanhash(cp
->users
, np
->numeric
);
669 LUA_PUSHNICKCHANMODES(l
, lp
);
673 static int lua_getusermodes(lua_State
*l
) {
676 if(!lua_islong(l
, 1))
679 np
= getnickbynumeric(lua_tolong(l
, 1));
683 lua_pushstring(l
, printflags(np
->umodes
, umodeflags
));
687 static int lua_fastgetnickbynumeric(lua_State
*l
) {
688 static struct lua_pusher
*ourpusher
[MAX_PUSHER
];
691 if(!lua_islong(l
, 1))
694 np
= getnickbynumeric(lua_tolong(l
, 1));
698 lua_setupnickpusher(l
, 2, ourpusher
, MAX_PUSHER
);
699 return lua_usepusher(l
, ourpusher
, np
);
702 static int lua_fastgetnickbynick(lua_State
*l
) {
703 static struct lua_pusher
*ourpusher
[MAX_PUSHER
];
706 if(!lua_isstring(l
, 1))
709 np
= getnickbynick((char *)lua_tostring(l
, 1));
713 lua_setupnickpusher(l
, 2, ourpusher
, MAX_PUSHER
);
714 return lua_usepusher(l
, ourpusher
, np
);
717 int channelnicklistindex
, channelnicklistcount
= -1;
718 channel
*channelnicklist
;
720 struct lua_pusher
*channelnickpusher
[MAX_PUSHER
];
722 static int lua_getnextchannick(lua_State
*l
) {
726 channelnicklistindex
++;
728 if(channelnicklistindex
>= channelnicklistcount
)
730 } while((channelnicklist
->users
->content
[channelnicklistindex
] == nouser
) || !(np
= getnickbynumeric(channelnicklist
->users
->content
[channelnicklistindex
])));
732 return lua_usepusher(l
, channelnickpusher
, np
);
735 static int lua_getfirstchannick(lua_State
*l
) {
736 if(!lua_isstring(l
, 1))
739 channelnicklist
= findchannel((char *)lua_tostring(l
, 1));
740 if(!channelnicklist
|| !channelnicklist
->users
)
743 channelnicklistindex
= -1;
744 channelnicklistcount
= channelnicklist
->users
->hashsize
;
746 lua_setupnickpusher(l
, 2, channelnickpusher
, MAX_PUSHER
);
748 return lua_getnextchannick(l
);
751 static int lua_nickonchan(lua_State
*l
) {
753 if(lua_islong(l
, 1) && lua_isstring(l
, 2)) {
754 channel
*cp
= findchannel((char *)lua_tostring(l
, 2));
755 if(cp
&& cp
->users
) {
756 unsigned long *lp
= getnumerichandlefromchanhash(cp
->users
, lua_tolong(l
, 1));
762 lua_pushboolean(l
, success
);
766 static int lua_simplechanmode(lua_State
*ps
) {
769 flag_t add
= 0, del
= ~add
;
770 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
;
773 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
774 LUA_RETURN(ps
, LUA_FAIL
);
776 cp
= findchannel((char *)lua_tostring(ps
, 1));
778 LUA_RETURN(ps
, LUA_FAIL
);
780 modes
= (char *)lua_tostring(ps
, 2);
782 LUA_RETURN(ps
, LUA_FAIL
);
784 if(setflags(&add
, permitted
, modes
, cmodeflags
, REJECT_DISALLOWED
|REJECT_UNKNOWN
) != REJECT_NONE
)
785 LUA_RETURN(ps
, LUA_FAIL
);
787 if(setflags(&del
, permitted
, modes
, cmodeflags
, REJECT_DISALLOWED
|REJECT_UNKNOWN
) != REJECT_NONE
)
788 LUA_RETURN(ps
, LUA_FAIL
);
790 localsetmodeinit(&changes
, cp
, lua_nick
);
791 localdosetmode_simple(&changes
, add
, ~del
);
792 localsetmodeflush(&changes
, 1);
794 LUA_RETURN(ps
, LUA_OK
);
797 static int lua_sethost(lua_State
*ps
) {
801 if(!lua_islong(ps
, 1) || !lua_isstring(ps
, 2) || !lua_isstring(ps
, 3))
802 LUA_RETURN(ps
, LUA_FAIL
);
804 np
= getnickbynumeric(lua_tolong(ps
, 1));
806 LUA_RETURN(ps
, LUA_FAIL
);
808 ident
= (char *)lua_tostring(ps
, 2);
809 host
= (char *)lua_tostring(ps
, 3);
810 if(!lua_lineok(ident
) || !lua_lineok(host
))
811 LUA_RETURN(ps
, LUA_FAIL
);
813 sethostuser(np
, ident
, host
);
815 LUA_RETURN(ps
, LUA_OK
);
818 static int lua_getvisiblehostmask(lua_State
*l
) {
820 char buf
[HOSTLEN
+USERLEN
+NICKLEN
+REALLEN
+10];
822 if(!lua_islong(l
, 1))
825 np
= getnickbynumeric(lua_tolong(l
, 1));
829 lua_pushstring(l
, visiblehostmask(np
, buf
));
833 void lua_registercommands(lua_State
*l
) {
834 lua_register(l
, "irc_smsg", lua_smsg
);
835 lua_register(l
, "irc_skill", lua_skill
);
837 lua_register(l
, "chanmsg", lua_chanmsg
);
838 lua_register(l
, "versioninfo", lua_versioninfo
);
839 lua_register(l
, "basepath", lua_basepath
);
840 lua_register(l
, "botnick", lua_botnick
);
842 lua_register(l
, "irc_report", lua_chanmsg
);
843 lua_register(l
, "irc_ctcp", lua_ctcp
);
844 lua_register(l
, "irc_kill", lua_kill
);
845 lua_register(l
, "irc_kick", lua_kick
);
846 lua_register(l
, "irc_invite", lua_invite
);
847 lua_register(l
, "irc_gline", lua_gline
);
848 lua_register(l
, "irc_counthost", lua_counthost
);
849 lua_register(l
, "irc_getuserbyauth", lua_getuserbyauth
);
850 lua_register(l
, "irc_notice", lua_noticecmd
);
851 lua_register(l
, "irc_privmsg", lua_privmsgcmd
);
852 lua_register(l
, "irc_opchan", lua_opchan
);
853 lua_register(l
, "irc_voicechan", lua_voicechan
);
854 lua_register(l
, "irc_chanfix", lua_chanfix
);
855 lua_register(l
, "irc_clearmode", lua_clearmode
);
856 lua_register(l
, "irc_ban", lua_ban
);
857 lua_register(l
, "irc_deopchan", lua_deopchan
);
858 lua_register(l
, "irc_topic", lua_topic
);
860 lua_register(l
, "irc_getfirstnick", lua_getfirstnick
);
861 lua_register(l
, "irc_getnextnick", lua_getnextnick
);
863 lua_register(l
, "irc_getnickchans", lua_getnickchans
);
864 lua_register(l
, "irc_getnickchanindex", lua_getnickchanindex
);
865 lua_register(l
, "irc_getnickchancount", lua_getnickchancount
);
867 lua_register(l
, "irc_getuserchanmodes", lua_getuserchanmodes
);
869 lua_register(l
, "irc_getfirstchannick", lua_getfirstchannick
);
870 lua_register(l
, "irc_getnextchannick", lua_getnextchannick
);
872 lua_register(l
, "irc_gethostusers", lua_gethostusers
);
873 lua_register(l
, "irc_getnickcountry", lua_getnickcountry
);
875 lua_register(l
, "irc_getfirstchan", lua_getfirstchan
);
876 lua_register(l
, "irc_getnextchan", lua_getnextchan
);
877 lua_register(l
, "irc_getusermodes", lua_getusermodes
);
878 lua_register(l
, "irc_nickonchan", lua_nickonchan
);
880 lua_register(l
, "irc_fastgetnickbynumeric", lua_fastgetnickbynumeric
);
881 lua_register(l
, "irc_fastgetnickbynick", lua_fastgetnickbynick
);
882 lua_register(l
, "irc_fastgetchaninfo", lua_fastgetchaninfo
);
884 lua_register(l
, "irc_getvisiblehostmask", lua_getvisiblehostmask
);
886 lua_register(l
, "irc_simplechanmode", lua_simplechanmode
);
887 lua_register(l
, "irc_sethost", lua_sethost
);
889 lua_register(l
, "irc_numerictobase64", lua_numerictobase64
);
894 static int lua_smsg(lua_State
*ps
) {
895 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
896 LUA_RETURN(ps
, LUA_FAIL
);
898 LUA_RETURN(ps
, lua_cmsg((char *)lua_tostring(ps
, 2), "%s", lua_tostring(ps
, 1)));
901 static int lua_skill(lua_State
*ps
) {
905 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
906 LUA_RETURN(ps
, LUA_FAIL
);
908 n
= lua_tostring(ps
, 1);
909 msg
= lua_tostring(ps
, 2);
911 np
= getnickbynick(n
);
913 LUA_RETURN(ps
, LUA_FAIL
);
915 if(IsOper(np
) || IsService(np
) || IsXOper(np
))
916 LUA_RETURN(ps
, LUA_FAIL
);
919 LUA_RETURN(ps
, LUA_FAIL
);
921 killuser(lua_nick
, np
, "%s", msg
);
923 LUA_RETURN(ps
, LUA_OK
);
926 #define PUSHER_STRING 1
927 #define PUSHER_REALNAME 2
929 #define PUSHER_LONG 4
930 #define PUSHER_HOSTNAME 5
931 #define PUSHER_SSTRING 6
932 #define PUSHER_TOTALUSERS 7
933 #define PUSHER_TOPIC 8
934 #define PUSHER_UMODES 9
935 #define PUSHER_COUNTRY 10
936 #define PUSHER_REALUSERS 11
937 #define PUSHER_CHANMODES 12
938 #define PUSHER_TIMESTAMP 13
939 #define PUSHER_STRING_INDIRECT 14
940 #define PUSHER_ACC_ID 15
941 #define PUSHER_SERVER_NAME 16
942 #define PUSHER_SERVER_NUMERIC 17
944 void lua_initnickpusher(void) {
947 #define PUSH_NICKPUSHER(F2, O2) nickpusher[i].argtype = F2; nickpusher[i].structname = #O2; nickpusher[i].offset = offsetof(nick, O2); i++;
948 #define PUSH_NICKPUSHER_CUSTOM(F2, custom) nickpusher[i].argtype = F2; nickpusher[i].structname = custom; nickpusher[i].offset = 0; i++;
950 PUSH_NICKPUSHER(PUSHER_STRING
, nick
);
951 PUSH_NICKPUSHER(PUSHER_STRING
, ident
);
952 PUSH_NICKPUSHER(PUSHER_HOSTNAME
, host
);
953 PUSH_NICKPUSHER(PUSHER_REALNAME
, realname
);
954 PUSH_NICKPUSHER(PUSHER_STRING_INDIRECT
, authname
);
955 PUSH_NICKPUSHER(PUSHER_IP
, ipnode
);
956 PUSH_NICKPUSHER(PUSHER_LONG
, numeric
);
957 PUSH_NICKPUSHER(PUSHER_LONG
, timestamp
);
958 PUSH_NICKPUSHER(PUSHER_LONG
, accountts
);
959 PUSH_NICKPUSHER(PUSHER_UMODES
, umodes
);
960 PUSH_NICKPUSHER_CUSTOM(PUSHER_COUNTRY
, "country");
961 PUSH_NICKPUSHER_CUSTOM(PUSHER_ACC_ID
, "accountid");
962 PUSH_NICKPUSHER_CUSTOM(PUSHER_SERVER_NAME
, "servername");
963 PUSH_NICKPUSHER_CUSTOM(PUSHER_SERVER_NUMERIC
, "servernumeric");
966 nickpusher
[i
].argtype
= 0;
969 void lua_setuppusher(struct lua_pusher
*pusherlist
, lua_State
*l
, int index
, struct lua_pusher
**lp
, int max
, int pcount
) {
975 if(!lua_istable(l
, index
) || (max
< 2))
982 while(lua_next(l
, index
)) {
983 if(lua_isint(l
, -1)) {
984 int index
= lua_toint(l
, -1);
985 if((index
>= 0) && (index
< pcount
))
986 lp
[current
++] = &pusherlist
[index
];
998 int lua_usepusher(lua_State
*l
, struct lua_pusher
**lp
, void *np
) {
1002 void *offset
= (void *)np
+ (*lp
)->offset
;
1004 switch((*lp
)->argtype
) {
1006 lua_pushstring(l
, (char *)offset
);
1008 case PUSHER_STRING_INDIRECT
:
1009 lua_pushstring(l
, *(char **)offset
);
1011 case PUSHER_HOSTNAME
:
1012 lua_pushstring(l
, (*(host
**)offset
)->name
->content
);
1014 case PUSHER_REALNAME
:
1015 lua_pushstring(l
, (*(realname
**)offset
)->name
->content
);
1017 case PUSHER_SSTRING
:
1018 lua_pushstring(l
, (*((sstring
**)offset
))->content
);
1021 lua_pushlong(l
, *((long *)offset
));
1023 case PUSHER_TIMESTAMP
:
1024 lua_pushlong(l
, (*((channel
**)offset
))->timestamp
);
1027 lua_pushstring(l
, IPtostr((*((patricia_node_t
**)offset
))->prefix
->sin
));
1029 case PUSHER_TOTALUSERS
:
1030 lua_pushint(l
, (*((channel
**)offset
))->users
->totalusers
);
1032 case PUSHER_CHANMODES
:
1033 lua_pushstring(l
, printallmodes(*((channel
**)offset
)));
1037 nick
*tnp
= (nick
*)np
;
1038 if(IsAccount(tnp
) && tnp
->auth
) {
1039 lua_pushlong(l
, tnp
->auth
->userid
);
1045 case PUSHER_REALUSERS
:
1047 channel
*cp
= *((channel
**)offset
);
1049 int i
, currentusers
= countuniquehosts(cp
);
1050 for(i
=0;i
<cp
->users
->hashsize
;i
++) {
1051 if(cp
->users
->content
[i
]==nouser
)
1054 if((np2
=getnickbynumeric(cp
->users
->content
[i
]))==NULL
) {
1055 Error("lua", ERR_ERROR
, "Found unknown numeric %lu on channel %s", cp
->users
->content
[i
], cp
->index
->name
->content
);
1059 if (IsXOper(np2
) || IsService(np2
))
1062 lua_pushint(l
, currentusers
);
1066 lua_pushstring(l
, printflags(*((flag_t
*)offset
), umodeflags
));
1069 if((*((channel
**)offset
))->topic
) {
1070 lua_pushstring(l
, (*((channel
**)offset
))->topic
->content
);
1075 case PUSHER_COUNTRY
:
1079 lua_pushint(l
, (long)((nick
*)offset
)->exts
[geoipext
]);
1082 case PUSHER_SERVER_NAME
:
1083 lua_pushstring(l
, serverlist
[homeserver(((nick
*)offset
)->numeric
)].name
->content
);
1085 case PUSHER_SERVER_NUMERIC
:
1086 lua_pushint(l
, homeserver(((nick
*)offset
)->numeric
));
1097 void lua_initchanpusher(void) {
1100 #define PUSH_CHANPUSHER(F2, O2, N2) chanpusher[i].argtype = F2; chanpusher[i].structname = N2; chanpusher[i].offset = offsetof(chanindex, O2); i++;
1102 PUSH_CHANPUSHER(PUSHER_SSTRING
, name
, "name");
1103 PUSH_CHANPUSHER(PUSHER_TOTALUSERS
, channel
, "totalusers");
1104 PUSH_CHANPUSHER(PUSHER_TOPIC
, channel
, "topic");
1105 PUSH_CHANPUSHER(PUSHER_REALUSERS
, channel
, "realusers");
1106 PUSH_CHANPUSHER(PUSHER_TIMESTAMP
, channel
, "timestamp");
1107 PUSH_CHANPUSHER(PUSHER_CHANMODES
, channel
, "modes");
1109 chanpushercount
= i
;
1110 chanpusher
[i
].argtype
= 0;