diff --git a/mods/lua/handlers.c b/mods/lua/handlers.c index 4f50951..1638bb3 100755 --- a/mods/lua/handlers.c +++ b/mods/lua/handlers.c @@ -58,6 +58,8 @@ MY_API void chanprivmsg_handler(struct irc_conn *bot, char *user, char *host, ch { lua_fire_handlers(PRIVMSG_CHAN, user, host, chan, text); lua_eval(bot, user, host, chan, text); + lua_load_script(bot, user, host, chan, text); + lua_unload_script(bot, user, host, chan, text); } MY_API void selfprivmsg_handler(struct irc_conn *bot, char *user, char *host, const char *text) diff --git a/mods/lua/lua.c b/mods/lua/lua.c index cbe2ea4..822cf8f 100755 --- a/mods/lua/lua.c +++ b/mods/lua/lua.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "lua.h" @@ -31,7 +32,6 @@ 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) { char *name; @@ -41,25 +41,110 @@ MY_API void lua_load_script(struct irc_conn *bot, char *user, char *host, char * if (strstr(text, "!load") != NULL) { text = skip((char *)text, ' '); - sprintf(buf, "../scripts/%s", text); + sprintf(buf, "./scripts/%s", text); strlcpy(lua.scripts[lua.script_count].fname, buf, 150); - if (luaL_loadfile(lua.L, buf)) + if (luaL_loadfile(lua.L, buf) != LUA_OK) { - irc_privmsg(bot, chan, "Error: %s", lua_tostring(lua.L, -1)); + irc_privmsg(bot, chan, "Error loading lua script: %s", lua_tostring(lua.L, -1)); return; } - sprintf(buf, "Loaded %s", name); - lua.script_count++; + name = basename(buf); - irc_privmsg(bot, chan, buf); + + // execute the script + if (lua_pcall(lua.L, 0, 0, 0) != LUA_OK) + { + irc_privmsg(bot, chan, "Error executing lua script: %s", lua_tostring(lua.L, -1)); + return; + } + + // get a ref to unload function if it exists and store it with luaL_ref + lua_getglobal(lua.L, "unload"); + + if (lua_isfunction(lua.L, -1)) + { + lua.scripts[lua.script_count].unload = luaL_ref(lua.L, LUA_REGISTRYINDEX); + printf("dbg: unload ref: %d\n", lua.scripts[lua.script_count].unload); + } + else + { + lua.scripts[lua.script_count].unload = -1; + irc_privmsg(bot, chan, "No unload() function in %s", name); + } + + // call the load function if it exists + lua_getglobal(lua.L, "load"); + + if (lua_isfunction(lua.L, -1)) + { + if (lua_pcall(lua.L, 0, 0, 0) != LUA_OK) + { + irc_privmsg(bot, chan, "Error calling load() in %s: %s", buf, lua_tostring(lua.L, -1)); + return; + } + + sprintf(buf, "Loaded %s", name); + lua.script_count++; + + irc_privmsg(bot, chan, buf); + } + else + { + irc_privmsg(bot, chan, "Error: No load() function in %s", buf); + } } free(buf); } +MY_API void lua_unload_script(struct irc_conn *bot, char *user, char *host, char *chan, const char *text) +{ + char *name; + char *script; + char *buf = (char *)malloc(sizeof(char *) * 500); + + if (strstr(text, "!unload") != NULL) + { + text = skip((char *)text, ' '); + sprintf(buf, "./scripts/%s", text); + + irc_privmsg(bot, chan, "Unloading %s", buf); + + for (int i = 0; i < lua.script_count; i++) + { + if (strcmp(lua.scripts[i].fname, buf) == 0) + { + // call from the ref in .unload + lua_rawgeti(lua.L, LUA_REGISTRYINDEX, lua.scripts[i].unload); + if (lua_pcall(lua.L, 0, 0, 0) != LUA_OK) + { + irc_privmsg(bot, chan, "Error calling unload() in %s: %s", buf, lua_tostring(lua.L, -1)); + return; + } + + luaL_unref(lua.L, LUA_REGISTRYINDEX, lua.scripts[i].unload); + lua.scripts[i].unload = -1; + + sprintf(buf, "Unloaded %s", text); + irc_privmsg(bot, chan, buf); + + lua.script_count--; + + free(buf); + return; + } + } + + irc_privmsg(bot, chan, "Error: %s not loaded", text); + } + + + free(buf); +} + void lua_setvar(char *name, char *value) { lua_pushstring(lua.L, value); diff --git a/mods/lua/lua.h b/mods/lua/lua.h index 0a4cec9..57b4637 100755 --- a/mods/lua/lua.h +++ b/mods/lua/lua.h @@ -14,6 +14,7 @@ struct lua_script char description[256]; char fname[256]; + int unload; }; struct lua_event @@ -70,5 +71,7 @@ MY_API void quit_handler(struct irc_conn *bot, char *user, char *host, const cha // 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); +MY_API void lua_load_script(struct irc_conn *bot, char *user, char *host, char *chan, const char *text); +MY_API void lua_unload_script(struct irc_conn *bot, char *user, char *host, char *chan, const char *text); #endif diff --git a/scripts/hello.lua b/scripts/hello.lua index eadba7d..ae1e766 100755 --- a/scripts/hello.lua +++ b/scripts/hello.lua @@ -6,10 +6,12 @@ DESCRIPTION = "A simple hello world script for xbot" local handlers = {} function hi(nick, host, chan, text) - irc_privmsg(chan, "Hello, " .. nick .. "!") + privmsg(chan, "Hello, " .. nick .. "!") end function load() + -- register_script(NAME, VERSION, AUTHOR, DESCRIPTION) + table.insert(handlers, {PRIVMSG_CHAN, add_handler(PRIVMSG_CHAN, hi)}) end diff --git a/scripts/test.lua b/scripts/test.lua new file mode 100755 index 0000000..53dfab2 --- /dev/null +++ b/scripts/test.lua @@ -0,0 +1,23 @@ +NAME = "hello" +VERSION = "v0.5" +AUTHOR = "Aaron Blakely" +DESCRIPTION = "A simple hello world script for xbot" + +local handlers = {} + +function hi(nick, host, chan, text) + privmsg(chan, "Hello, " .. nick .. " from test.lua!") +end + +function load() + -- register_script(NAME, VERSION, AUTHOR, DESCRIPTION) + + table.insert(handlers, {PRIVMSG_CHAN, add_handler(PRIVMSG_CHAN, hi)}) +end + +function unload() + privmsg("#lobby", "Unloading test.lua") + for i, v in ipairs(handlers) do + del_handler(v[1], v[2]) + end +end