more work on lua module

This commit is contained in:
Aaron Blakely 2024-02-27 01:16:58 -06:00
parent 97713e6c29
commit 80bea46895
8 changed files with 484 additions and 26 deletions

View File

@ -30,6 +30,8 @@ mods: $(MODS_DIR)
$(MODS_DIR): $(MODS_DIR):
$(MAKE) -C $@ $(MAKE) -C $@
all: main mods
clean: clean:
@rm -rf build $(EXEC) @rm -rf build $(EXEC)
@rm -rf mods/*.so @rm -rf mods/*.so

View File

@ -1,7 +1,7 @@
CC=gcc CC=gcc
CFLAGS=-fPIC -I../../lib -llua CFLAGS=-g -fPIC -I../../lib -llua
OBJ=../lua.so OBJ=../lua.so
main: main:
$(CC) -shared -o $(OBJ) $(CFLAGS) ./lua.c $(CC) -shared -o $(OBJ) $(CFLAGS) ./wrappers.c ./events.c ./handlers.c ./lua.c
@echo "All Done!" @echo "All Done!"

261
mods/lua/events.c Executable file
View File

@ -0,0 +1,261 @@
#include "lua.h"
#include "events.h"
#include <lua5.3/lua.h>
#include <string.h>
#include <stdlib.h>
void lua_init_events()
{
lua_register(lua.L, "add_handler", lua_add_handler);
lua_register(lua.L, "del_handler", lua_del_handler);
}
int lua_add_handler(lua_State *L)
{
char *event;
int lreg;
if (lua_gettop(L) < 2)
{
printf("Error: add_handler requires 2 arguments\n");
return 0;
}
luaL_checktype(L, 1, LUA_TSTRING);
luaL_checktype(L, 2, LUA_TFUNCTION);
lreg = luaL_ref(L, LUA_REGISTRYINDEX);
if (lreg == -1)
{
const char *err = lua_tostring(L, -1);
printf("Error: %s\n", err);
}
event = (char *)lua_tostring(L, 1);
printf("Installing handler for event: %s : %d\n", event, lreg);
strlcpy(lua.events[lua.event_count].event, event, 25);
lua.events[lua.event_count].lreg = lreg;
lua.event_count++;
lua_pushinteger(L, lreg);
return 1;
}
void lua_del_handler(lua_State *L)
{
char *event;
int i;
int lreg;
if (lua_gettop(L) < 2)
{
printf("Error: del_handler requires 2 arguments\n");
return;
}
luaL_checktype(L, 1, LUA_TSTRING);
luaL_checktype(L, 2, LUA_TNUMBER);
event = (char *)lua_tostring(L, 1);
lreg = (int)lua_tointeger(L, 2);
for (i = 0; i < lua.event_count; i++)
{
if (!strcmp(lua.events[i].event, event))
{
if (lua.events[i].lreg == lreg)
{
printf("Removing handler for event: %s : %d\n", event, lreg);
luaL_unref(L, LUA_REGISTRYINDEX, lua.events[i].lreg);
while (i < lua.event_count)
{
lua.events[i] = lua.events[i + 1];
i++;
}
lua.event_count--;
}
}
}
}
void lua_callfunc(int lreg, int argc, ...)
{
int i;
va_list args;
va_start(args, argc);
lua_State *L = lua.L;
int stackSize = lua_gettop(L);
lua_rawgeti(L, LUA_REGISTRYINDEX, lreg);
for (i = 0; i < argc; i++)
{
lua_pushstring(lua.L, va_arg(args, char *));
}
if (lua_pcall(lua.L, argc, 0, 0) != LUA_OK)
{
const char *err = lua_tostring(L, -1);
printf("Error: %s\n", err);
lua_pop(L, 1);
}
lua_settop(L, stackSize);
va_end(args);
}
void lua_fire_handlers(char *event, ...)
{
int i;
va_list args;
char *user, *host, *chan, *text;
for (i = 0; i < lua.event_count; i++)
{
if (!lua.events[i].lreg)
continue;
if (!strcmp(lua.events[i].event, event))
{
if (!strcmp(event, PRIVMSG_CHAN))
{
va_start(args, event);
user = va_arg(args, char *);
host = va_arg(args, char *);
chan = va_arg(args, char *);
text = va_arg(args, char *);
printf("dbug: %s %s %s %s\n", user, host, chan, text);
lua_callfunc(lua.events[i].lreg, 4, user, host, chan, text);
}
else if (!strcmp(event, PRIVMSG_SELF))
{
va_start(args, event);
user = va_arg(args, char *);
host = va_arg(args, char *);
text = va_arg(args, char *);
lua_callfunc(lua.events[i].lreg, 3, user, host, text);
}
else if (!strcmp(event, JOIN))
{
va_start(args, event);
user = va_arg(args, char *);
host = va_arg(args, char *);
chan = va_arg(args, char *);
lua_callfunc(lua.events[i].lreg, 3, user, host, chan);
}
else if (!strcmp(event, JOIN_MYSELF))
{
va_start(args, event);
chan = va_arg(args, char *);
lua_callfunc(lua.events[i].lreg, 1, chan);
}
else if (!strcmp(event, PART))
{
va_start(args, event);
user = va_arg(args, char *);
host = va_arg(args, char *);
chan = va_arg(args, char *);
lua_callfunc(lua.events[i].lreg, 3, user, host, chan);
}
else if (!strcmp(event, PART_MYSELF))
{
va_start(args, event);
chan = va_arg(args, char *);
lua_callfunc(lua.events[i].lreg, 1, chan);
}
else if (!strcmp(event, QUIT))
{
va_start(args, event);
user = va_arg(args, char *);
host = va_arg(args, char *);
text = va_arg(args, char *);
lua_callfunc(lua.events[i].lreg, 3, user, host, text);
}
else if (!strcmp(event, NICK))
{
va_start(args, event);
user = va_arg(args, char *);
host = va_arg(args, char *);
text = va_arg(args, char *);
lua_callfunc(lua.events[i].lreg, 3, user, host, text);
}
else if (!strcmp(event, NICK_MYSELF))
{
va_start(args, event);
text = va_arg(args, char *);
lua_callfunc(lua.events[i].lreg, 1, text);
}
else if (!strcmp(event, CTCP))
{
va_start(args, event);
user = va_arg(args, char *);
host = va_arg(args, char *);
text = va_arg(args, char *);
lua_callfunc(lua.events[i].lreg, 3, user, host, text);
}
else if (!strcmp(event, IRC_CONNECTED))
{
lua_callfunc(lua.events[i].lreg, 0);
}
else if (!strcmp(event, IRC_NAMREPLY))
{
va_start(args, event);
chan = va_arg(args, char *);
text = va_arg(args, char *);
lua_callfunc(lua.events[i].lreg, 2, chan, text);
}
else if (!strcmp(event, IRC_WHOREPLY))
{
va_start(args, event);
chan = va_arg(args, char *);
text = va_arg(args, char *);
lua_callfunc(lua.events[i].lreg, 2, chan, text);
}
else if (!strcmp(event, NICK_INUSE))
{
lua_callfunc(lua.events[i].lreg, 0);
}
else if (!strcmp(event, TICK))
{
lua_callfunc(lua.events[i].lreg, 0);
}
}
}
va_end(args);
}

126
mods/lua/handlers.c Executable file
View File

@ -0,0 +1,126 @@
#include "lua.h"
#include "events.h"
void lua_init_handlers()
{
// see lib/events.h
lua_setvar("PRIVMSG_CHAN", PRIVMSG_CHAN);
lua_setvar("PRIVMSG_SELF", PRIVMSG_SELF);
lua_setvar("TICK", TICK);
lua_setvar("JOIN", JOIN);
lua_setvar("JOIN_MYSELF", JOIN_MYSELF);
lua_setvar("IRC_CONNECTED", IRC_CONNECTED);
lua_setvar("NICK_MYSELF", NICK_MYSELF);
lua_setvar("NICK_INUSE", NICK_INUSE);
lua_setvar("CTCP", CTCP);
lua_setvar("IRC_NAMREPLY", IRC_NAMREPLY);
lua_setvar("IRC_WHOREPLY", IRC_WHOREPLY);
lua_setvar("PART", PART);
lua_setvar("PART_MYSELF", PART_MYSELF);
lua_setvar("QUIT", QUIT);
add_handler(PRIVMSG_CHAN, chanprivmsg_handler);
add_handler(PRIVMSG_SELF, selfprivmsg_handler);
add_handler(TICK, tick_handler);
add_handler(JOIN, join_handler);
add_handler(JOIN_MYSELF, joinmyself_handler);
add_handler(IRC_CONNECTED, ircconnected_handler);
add_handler(NICK_MYSELF, nickmyself_handler);
add_handler(NICK_INUSE, nickinuse_handler);
add_handler(CTCP, ctcp_handler);
add_handler(IRC_NAMREPLY, ircnamreply_handler);
add_handler(IRC_WHOREPLY, ircwhoreply_handler);
add_handler(PART, part_handler);
add_handler(PART_MYSELF, partmyself_handler);
add_handler(QUIT, quit_handler);
}
void lua_unload_handlers()
{
del_handler(PRIVMSG_CHAN, chanprivmsg_handler);
del_handler(PRIVMSG_SELF, selfprivmsg_handler);
del_handler(TICK, tick_handler);
del_handler(JOIN, join_handler);
del_handler(JOIN_MYSELF, joinmyself_handler);
del_handler(IRC_CONNECTED, ircconnected_handler);
del_handler(NICK_MYSELF, nickmyself_handler);
del_handler(NICK_INUSE, nickinuse_handler);
del_handler(CTCP, ctcp_handler);
del_handler(IRC_NAMREPLY, ircnamreply_handler);
del_handler(IRC_WHOREPLY, ircwhoreply_handler);
del_handler(PART, part_handler);
del_handler(PART_MYSELF, partmyself_handler);
del_handler(QUIT, quit_handler);
}
MY_API void chanprivmsg_handler(struct irc_conn *bot, char *user, char *host, char *chan, const char *text)
{
lua_fire_handlers(PRIVMSG_CHAN, user, host, chan, text);
lua_eval(bot, user, host, chan, text);
}
MY_API void selfprivmsg_handler(struct irc_conn *bot, char *user, char *host, const char *text)
{
lua_fire_handlers(PRIVMSG_SELF, user, host, text);
}
MY_API void tick_handler(struct irc_conn *bot)
{
lua_fire_handlers(TICK);
}
MY_API void join_handler(struct irc_conn *bot, char *user, char *host, char *chan)
{
lua_fire_handlers(JOIN, user, host, chan);
}
MY_API void joinmyself_handler(struct irc_conn *bot, char *chan)
{
lua_fire_handlers(JOIN_MYSELF, chan);
}
MY_API void ircconnected_handler(struct irc_conn *bot)
{
lua_fire_handlers(IRC_CONNECTED);
}
MY_API void nickmyself_handler(struct irc_conn *bot, char *newnick)
{
lua_fire_handlers(NICK_MYSELF, newnick);
}
MY_API void nickinuse_handler(struct irc_conn *bot, char *newnick)
{
lua_fire_handlers(NICK_INUSE, newnick);
}
MY_API void ctcp_handler(struct irc_conn *bot, char *user, char *host, char *chan, const char *text)
{
lua_fire_handlers(CTCP, user, host, chan, text);
}
MY_API void ircnamreply_handler(struct irc_conn *bot, char *chan, char *nicks)
{
lua_fire_handlers(IRC_NAMREPLY, chan, nicks);
}
MY_API void ircwhoreply_handler(struct irc_conn *bot, char *chan, char *user, char *host, char *server, char *nick, char *flags, char *hops, char *realname)
{
lua_fire_handlers(IRC_WHOREPLY, chan, user, host, server, nick, flags, hops, realname);
}
MY_API void part_handler(struct irc_conn *bot, char *user, char *host, char *chan)
{
lua_fire_handlers(PART, user, host, chan);
}
MY_API void partmyself_handler(struct irc_conn *bot, char *chan)
{
lua_fire_handlers(PART_MYSELF, chan);
}
MY_API void quit_handler(struct irc_conn *bot, char *user, char *host, const char *text)
{
lua_fire_handlers(QUIT, user, host, text);
}

View File

@ -14,6 +14,7 @@
struct lua_interp lua; struct lua_interp lua;
struct irc_conn *instance; struct irc_conn *instance;
MY_API void lua_eval(struct irc_conn *bot, char *user, char *host, char *chan, const char *text) MY_API void lua_eval(struct irc_conn *bot, char *user, char *host, char *chan, const char *text)
{ {
printf("lua eval called with %s\n", text); printf("lua eval called with %s\n", text);
@ -30,6 +31,7 @@ MY_API void lua_eval(struct irc_conn *bot, char *user, char *host, char *chan, c
} }
} }
MY_API void lua_load_script(struct irc_conn *bot, char *user, char *host, char *chan, const char *text) MY_API void lua_load_script(struct irc_conn *bot, char *user, char *host, char *chan, const char *text)
{ {
char *name; char *name;
@ -41,7 +43,7 @@ MY_API void lua_load_script(struct irc_conn *bot, char *user, char *host, char *
text = skip((char *)text, ' '); text = skip((char *)text, ' ');
sprintf(buf, "../scripts/%s", text); sprintf(buf, "../scripts/%s", text);
strlcpy(lua.scripts[lua.count].fname, buf, 150); strlcpy(lua.scripts[lua.script_count].fname, buf, 150);
if (luaL_loadfile(lua.L, buf)) if (luaL_loadfile(lua.L, buf))
{ {
@ -50,25 +52,18 @@ MY_API void lua_load_script(struct irc_conn *bot, char *user, char *host, char *
} }
sprintf(buf, "Loaded %s", name); sprintf(buf, "Loaded %s", name);
lua.script_count++;
irc_privmsg(bot, chan, buf); irc_privmsg(bot, chan, buf);
} }
free(buf); free(buf);
} }
void raw_wrapper(lua_State *L) void lua_setvar(char *name, char *value)
{ {
char *text = (char *)lua_tostring(L, 1); lua_pushstring(lua.L, value);
lua_setglobal(lua.L, name);
irc_raw(instance, text);
}
void privmsg_wrapper(lua_State *L)
{
char *where = (char *)lua_tostring(L, 1);
char *text = (char *)lua_tostring(L, 2);
irc_privmsg(instance, where, text);
} }
MY_API void mod_init() MY_API void mod_init()
@ -76,16 +71,19 @@ MY_API void mod_init()
instance = get_bot(); instance = get_bot();
lua.scripts = calloc(512, sizeof(struct lua_script)); lua.scripts = calloc(512, sizeof(struct lua_script));
lua.count = 0; lua.events = calloc(1024, sizeof(struct lua_event));
lua.script_count = 0;
lua.event_count = 0;
lua.L = luaL_newstate(); lua.L = luaL_newstate();
luaL_openlibs(lua.L); luaL_openlibs(lua.L);
lua_init_wrappers();
lua_register(lua.L, "privmsg", privmsg_wrapper); lua_init_events();
lua_register(lua.L, "raw", raw_wrapper);
register_module("lua", "Aaron Blakely", "v0.1", "Lua module"); register_module("lua", "Aaron Blakely", "v0.1", "Lua module");
add_handler(PRIVMSG_CHAN, lua_eval); lua_init_handlers();
printf("Lua module loaded\n"); printf("Lua module loaded\n");
} }

View File

@ -16,13 +16,59 @@ struct lua_script
char fname[256]; char fname[256];
}; };
struct lua_interp struct lua_event
{ {
lua_State *L; char event[25];
int count; int lreg;
struct lua_script *scripts;
}; };
struct lua_interp
{
int script_count;
int event_count;
lua_State *L;
struct lua_script *scripts;
struct lua_event *events;
};
extern struct lua_interp lua; extern struct lua_interp lua;
extern struct irc_conn *instance;
// events.c
void lua_init_events();
int lua_add_handler(lua_State *L);
void lua_del_handler(lua_State *L);
void lua_fire_handlers(char *event, ...);
// wrappers.c
void lua_init_wrappers();
void raw_wrapper(lua_State *L);
void privmsg_wrapper(lua_State *L);
// handlers.c
void lua_init_handlers();
void lua_unload_handlers();
MY_API void chanprivmsg_handler(struct irc_conn *bot, char *user, char *host, char *chan, const char *text);
MY_API void selfprivmsg_handler(struct irc_conn *bot, char *user, char *host, const char *text);
MY_API void tick_handler(struct irc_conn *bot);
MY_API void join_handler(struct irc_conn *bot, char *user, char *host, char *chan);
MY_API void joinmyself_handler(struct irc_conn *bot, char *chan);
MY_API void ircconnected_handler(struct irc_conn *bot);
MY_API void nickmyself_handler(struct irc_conn *bot, char *newnick);
MY_API void nickinuse_handler(struct irc_conn *bot, char *newnick);
MY_API void ctcp_handler(struct irc_conn *bot, char *user, char *host, char *chan, const char *text);
MY_API void ircnamreply_handler(struct irc_conn *bot, char *chan, char *nicks);
MY_API void ircwhoreply_handler(struct irc_conn *bot, char *chan, char *user, char *host, char *server, char *nick, char *flags, char *hops, char *realname);
MY_API void part_handler(struct irc_conn *bot, char *user, char *host, char *chan);
MY_API void partmyself_handler(struct irc_conn *bot, char *chan);
MY_API void quit_handler(struct irc_conn *bot, char *user, char *host, const char *text);
// lua.c
void lua_setvar(char *name, char *value);
MY_API void lua_eval(struct irc_conn *bot, char *user, char *host, char *chan, const char *text);
#endif #endif

22
mods/lua/wrappers.c Executable file
View File

@ -0,0 +1,22 @@
#include "lua.h"
void lua_init_wrappers()
{
lua_register(lua.L, "raw", raw_wrapper);
lua_register(lua.L, "privmsg", privmsg_wrapper);
}
void raw_wrapper(lua_State *L)
{
char *text = (char *)lua_tostring(L, 1);
irc_raw(instance, text);
}
void privmsg_wrapper(lua_State *L)
{
char *where = (char *)lua_tostring(L, 1);
char *text = (char *)lua_tostring(L, 2);
irc_privmsg(instance, where, text);
}

View File

@ -3,15 +3,18 @@ VERSION = "v0.5"
AUTHOR = "Aaron Blakely" AUTHOR = "Aaron Blakely"
DESCRIPTION = "A simple hello world script for xbot" DESCRIPTION = "A simple hello world script for xbot"
local handlers = {}
function hi(nick, host, chan, text) function hi(nick, host, chan, text)
irc_privmsg(chan, "Hello, " .. nick .. "!") irc_privmsg(chan, "Hello, " .. nick .. "!")
end end
function load() function load()
add_lua_handler("PRIVMSG_CHAN", hi) table.insert(handlers, {PRIVMSG_CHAN, add_handler(PRIVMSG_CHAN, hi)})
end end
function unload() function unload()
remove_lua_handler("PRIVMSG_CHAN", hi) for i, v in ipairs(handlers) do
del_handler(v[1], v[2])
end
end end