X-Git-Url: https://jfr.im/git/irc/quakenet/newserv.git/blobdiff_plain/cf317a57d63af205f40ff63ba47c6fb6103e9fea..3898f97325dbed800d4b424e68a0c2858b8d8be7:/lua/luabot.c diff --git a/lua/luabot.c b/lua/luabot.c index 780f5ffc..a4d5fc67 100644 --- a/lua/luabot.c +++ b/lua/luabot.c @@ -6,14 +6,11 @@ #include "../localuser/localuserchannel.h" #include "../core/schedule.h" #include "../lib/irc_string.h" +#include "../core/config.h" #include "lua.h" #include "luabot.h" -#ifdef LUA_USEJIT -#include -#endif - #include nick *lua_nick = NULL; @@ -34,8 +31,12 @@ void lua_onquit(int hooknum, void *arg); void lua_onrename(int hooknum, void *arg); void lua_onconnect(int hooknum, void *arg); void lua_onjoin(int hooknum, void *arg); +void lua_onpart(int hooknum, void *arg); + +sstring *luabotnick; void lua_registerevents(void) { + registerhook(HOOK_CHANNEL_MODECHANGE, &lua_onmode); registerhook(HOOK_NICK_NEWNICK, &lua_onnewnick); registerhook(HOOK_IRC_DISCON, &lua_ondisconnect); registerhook(HOOK_IRC_PRE_DISCON, &lua_ondisconnect); @@ -49,10 +50,12 @@ void lua_registerevents(void) { registerhook(HOOK_IRC_CONNECTED, &lua_onconnect); registerhook(HOOK_SERVER_END_OF_BURST, &lua_onconnect); registerhook(HOOK_CHANNEL_JOIN, &lua_onjoin); + registerhook(HOOK_CHANNEL_PART, &lua_onpart); registerhook(HOOK_CHANNEL_CREATE, &lua_onjoin); } void lua_deregisterevents(void) { + deregisterhook(HOOK_CHANNEL_PART, &lua_onpart); deregisterhook(HOOK_CHANNEL_CREATE, &lua_onjoin); deregisterhook(HOOK_CHANNEL_JOIN, &lua_onjoin); deregisterhook(HOOK_SERVER_END_OF_BURST, &lua_onconnect); @@ -67,6 +70,7 @@ void lua_deregisterevents(void) { deregisterhook(HOOK_IRC_PRE_DISCON, &lua_ondisconnect); deregisterhook(HOOK_IRC_DISCON, &lua_ondisconnect); deregisterhook(HOOK_NICK_NEWNICK, &lua_onnewnick); + deregisterhook(HOOK_CHANNEL_MODECHANGE, &lua_onmode); } void lua_startbot(void *arg) { @@ -74,24 +78,28 @@ void lua_startbot(void *arg) { myureconnect = NULL; - lua_nick = registerlocaluser("U", "lua", "quakenet.department.of.corrections", -"Lua engine v" LUA_BOTVERSION " (" LUA_VERSION -#ifdef LUA_USEJIT -" + " LUAJIT_VERSION -#endif -")", "U", UMODE_ACCOUNT | UMODE_DEAF | UMODE_OPER | UMODE_SERVICE, &lua_bothandler); + if(!luabotnick) + luabotnick = getcopyconfigitem("lua", "botnick", "U", NICKLEN); + + lua_nick = registerlocaluser(luabotnick->content, "lua", "quakenet.department.of.corrections", LUA_FULLVERSION, "U", UMODE_ACCOUNT | UMODE_DEAF | UMODE_OPER | UMODE_SERVICE, &lua_bothandler); if(!lua_nick) { myureconnect = scheduleoneshot(time(NULL) + 1, &lua_startbot, NULL); return; } cp = findchannel(LUA_OPERCHAN); - if(cp && localjoinchannel(lua_nick, cp)) + if(cp && localjoinchannel(lua_nick, cp)) { localgetops(lua_nick, cp); + } else { + localcreatechannel(lua_nick, LUA_OPERCHAN); + } cp = findchannel(LUA_PUKECHAN); - if(cp && localjoinchannel(lua_nick, cp)) + if(cp && localjoinchannel(lua_nick, cp)) { localgetops(lua_nick, cp); + } else { + localcreatechannel(lua_nick, LUA_PUKECHAN); + } myublip = schedulerecurring(time(NULL) + 1, 0, 60, &lua_blip, NULL); myutick = schedulerecurring(time(NULL) + 1, 0, 1, &lua_tick, NULL); @@ -113,14 +121,24 @@ void lua_destroybot(void) { if(lua_nick) deregisterlocaluser(lua_nick, NULL); + + if(luabotnick) { + freesstring(luabotnick); + luabotnick = NULL; + } } -int lua_vpcall(lua_State *l, const char *function, const char *sig, ...) { +int _lua_vpcall(lua_State *l, void *function, int mode, const char *sig, ...) { va_list va; int narg = 0, nres, top = lua_gettop(l); lua_getglobal(l, "scripterror"); - lua_getglobal(l, function); + if(mode == LUA_CHARMODE) { + lua_getglobal(l, (const char *)function); + } else { + lua_rawgeti(l, LUA_REGISTRYINDEX, (long)function); + } + if(!lua_isfunction(l, -1)) { lua_settop(l, top); return 1; @@ -142,10 +160,17 @@ int lua_vpcall(lua_State *l, const char *function, const char *sig, ...) { case 'S': lua_pushstring(l, ((sstring *)(va_arg(va, sstring *)))->content); break; + case 'L': /* BE VERY CAREFUL USING THIS, MAKE SURE YOU CAST THE VALUE TO LONG */ + { + char *p = va_arg(va, char *); + long len = va_arg(va, long); + lua_pushlstring(l, p, len); + } + break; case 'N': { nick *np = va_arg(va, nick *); - LUA_PUSHNICK(l, np); + lua_pushnumeric(l, np->numeric); break; } case 'C': @@ -157,6 +182,12 @@ int lua_vpcall(lua_State *l, const char *function, const char *sig, ...) { case '0': lua_pushnil(l); break; + case 'R': + lua_rawgeti(l, LUA_REGISTRYINDEX, va_arg(va, long)); + break; + case 'b': + lua_pushboolean(l, va_arg(va, int)); + break; case '>': goto endwhile; @@ -170,15 +201,17 @@ endwhile: nres = strlen(sig); - lua_debugpcall(l, function, narg, nres, 0); - - nres = -nres; - while(*sig) { - switch(*sig++) { - default: - Error("lua", ERR_ERROR, "Unable to parse vpcall return structure (%c)", *(sig - 1)); + if(lua_debugpcall(l, (mode==LUA_CHARMODE)?function:"some_handler", narg, nres, top + 1)) { + Error("lua", ERR_ERROR, "Error pcalling %s: %s.", (mode==LUA_CHARMODE)?(char *)function:"some_handler", lua_tostring(l, -1)); + } else { + nres = -nres; + while(*sig) { + switch(*sig++) { + default: + Error("lua", ERR_ERROR, "Unable to parse vpcall return structure (%c)", *(sig - 1)); + } + nres++; } - nres++; } lua_settop(l, top); @@ -199,7 +232,7 @@ void lua_bothandler(nick *target, int type, void **args) { if(!np || !p) return; - lua_avpcall("irc_onmsg", "Ns", np, p); + lua_avpcall("irc_onmsg", "ls", np->numeric, p); break; case LU_PRIVNOTICE: @@ -214,8 +247,9 @@ void lua_bothandler(nick *target, int type, void **args) { if(p[le - 1] == '\001') p[le - 1] = '\000'; - lua_avpcall("irc_onctcp", "Ns", np, p + 1); - + lua_avpcall("irc_onctcp", "ls", np->numeric, p + 1); + } else { + lua_avpcall("irc_onnotice", "ls", np->numeric, p); } break; @@ -252,7 +286,7 @@ void lua_onnewnick(int hooknum, void *arg) { if(!np) return; - lua_avpcall("irc_onnewnick", "N", np); + lua_avpcall("irc_onnewnick", "l", np->numeric); } void lua_onkick(int hooknum, void *arg) { @@ -261,11 +295,18 @@ void lua_onkick(int hooknum, void *arg) { nick *kicked = arglist[1]; nick *kicker = arglist[2]; char *message = (char *)arglist[3]; + int mode = 1; if(!kicker || IsOper(kicker) || IsService(kicker) || IsXOper(kicker)) /* bloody Cruicky */ - return; + mode = 0; - lua_avpcall("irc_onkick", "SNNs", ci->name, kicked, kicker, message); + if(mode) { + lua_avpcall("irc_onkick", "Slls", ci->name, kicked->numeric, kicker->numeric, message); + } else if(kicker) { + lua_avpcall("irc_onkickall", "Slls", ci->name, kicked->numeric, kicker->numeric, message); + } else { + lua_avpcall("irc_onkickall", "Sl0s", ci->name, kicked->numeric, message); + } } void lua_ontopic(int hooknum, void *arg) { @@ -278,7 +319,7 @@ void lua_ontopic(int hooknum, void *arg) { if(!cp || !cp->topic) return; - lua_avpcall("irc_ontopic", "SNS", cp->index->name, np, cp->topic); + lua_avpcall("irc_ontopic", "SlS", cp->index->name, np->numeric, cp->topic); } void lua_onop(int hooknum, void *arg) { @@ -291,9 +332,9 @@ void lua_onop(int hooknum, void *arg) { return; if(np) { - lua_avpcall(hooknum == HOOK_CHANNEL_OPPED?"irc_onop":"irc_ondeop", "SNN", ci->name, np, target); + lua_avpcall(hooknum == HOOK_CHANNEL_OPPED?"irc_onop":"irc_ondeop", "Sll", ci->name, np->numeric, target->numeric); } else { - lua_avpcall(hooknum == HOOK_CHANNEL_OPPED?"irc_onop":"irc_ondeop", "S0N", ci->name, target); + lua_avpcall(hooknum == HOOK_CHANNEL_OPPED?"irc_onop":"irc_ondeop", "S0l", ci->name, target->numeric); } } @@ -305,16 +346,30 @@ void lua_onjoin(int hooknum, void *arg) { if(!ci || !np) return; - lua_avpcall("irc_onjoin", "SN", ci->name, np); + lua_avpcall("irc_onjoin", "Sl", ci->name, np->numeric); +} + +void lua_onpart(int hooknum, void *arg) { + void **arglist = (void **)arg; + chanindex *ci = ((channel *)arglist[0])->index; + nick *np = arglist[1]; + char *reason = arglist[2]; + + if(!ci || !np) + return; + + lua_avpcall("irc_onpart", "Sls", ci->name, np->numeric, reason); } void lua_onrename(int hooknum, void *arg) { - nick *np = (void *)arg; + void **harg = (void **)arg; + nick *np = harg[0]; + char *oldnick = harg[1]; if(!np) return; - lua_avpcall("irc_onrename", "N", np); + lua_avpcall("irc_onrename", "ls", np->numeric, oldnick); } void lua_onquit(int hooknum, void *arg) { @@ -323,7 +378,7 @@ void lua_onquit(int hooknum, void *arg) { if(!np) return; - lua_avpcall("irc_onquit", "N", np); + lua_avpcall("irc_onquit", "l", np->numeric); } void lua_onauth(int hooknum, void *arg) { @@ -332,7 +387,7 @@ void lua_onauth(int hooknum, void *arg) { if(!np) return; - lua_avpcall("irc_onauth", "N", np); + lua_avpcall("irc_onauth", "l", np->numeric); } void lua_ondisconnect(int hooknum, void *arg) { @@ -390,4 +445,38 @@ int lua_notice(nick *np, char *message, ...) { return 0; } +char *printallmodes(channel *cp) { + static char buf[1024]; + char buf2[12]; + + if(IsLimit(cp)) + snprintf(buf2, sizeof(buf2), "%d", cp->limit); + + snprintf(buf, sizeof(buf), "%s %s%s%s", printflags(cp->flags, cmodeflags), IsLimit(cp)?buf2:"", IsLimit(cp)?" ":"", IsKey(cp)?cp->key->content:""); + + return buf; +} + +static char *printlimitedmodes(channel *cp, flag_t before) { + static char buf[1024]; + + snprintf(buf, sizeof(buf), "%s", printflags(cp->flags, cmodeflags)); + + return buf; +} + +void lua_onmode(int hooknum, void *arg) { + void **arglist = (void **)arg; + channel *cp = (channel *)arglist[0]; + chanindex *ci = cp->index; + nick *np = arglist[1]; + flag_t beforeflags = (flag_t)(long)arglist[3]; + + if(np) { + lua_avpcall("irc_onmode", "Slss", ci->name, np->numeric, printallmodes(cp), printlimitedmodes(cp, beforeflags)); + } else { + lua_avpcall("irc_onmode", "S0ss", ci->name, printallmodes(cp), printlimitedmodes(cp, beforeflags)); + } +} +