From efbcefd6c12de4c6c70c63e67f56f4b02de7030f Mon Sep 17 00:00:00 2001 From: jluehrs2 Date: Wed, 5 Sep 2007 17:47:10 -0500 Subject: make the evalbot use per-user environments for evaling things, not one global one --- test/luabot.lua | 96 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 76 insertions(+), 20 deletions(-) diff --git a/test/luabot.lua b/test/luabot.lua index 6c9b43a..01b2003 100644 --- a/test/luabot.lua +++ b/test/luabot.lua @@ -4,38 +4,94 @@ local irc = require 'irc' irc.DEBUG = true local nick = "luabot" -local pre_code = [[ -io = nil -os = nil -loadfile = nil -dofile = nil -package = nil -require = nil -module = nil -debug = nil -]] -irc.register_callback("connect", function() - irc.join("#doytest") -end) +local envs = {} -irc.register_callback("channel_msg", function(channel, from, message) - local for_me, code = message:match("^(" .. nick .. ". )(.*)") - if for_me then +local function create_env() + return { + _VERSION = _VERSION, + assert = assert, + collectgarbage = collectgarbage, + error = error, + getfenv = getfenv, + getmetatable = getmetatable, + ipairs = ipairs, + loadstring = loadstring, + next = next, + pairs = pairs, + pcall = pcall, + rawequal = rawequal, + rawget = rawget, + rawset = rawset, + select = select, + setfenv = setfenv, + setmetatable = setmetatable, + tonumber = tonumber, + tostring = tostring, + type = type, + unpack = unpack, + xpcall = xpcall, + coroutine = coroutine, + math = math, + string = string, + table = table, + } +end + +local commands = { + eval = function(channel, from, code) code = code:gsub("^=", "return ") - local fn, err = loadstring(pre_code .. code) + local fn, err = loadstring(code) if not fn then - irc.say(channel.name, from .. ": Error loading code: " .. err) + irc.say(channel.name, from .. ": Error loading code: " .. code .. err:match(".*(:.-)$")) return else + setfenv(fn, envs[from]) local result = {pcall(fn)} local success = table.remove(result, 1) if not success then - irc.say(channel.name, from .. ": Error running code: " .. result[1]) + irc.say(channel.name, from .. ": Error running code: " .. code .. result[1]:match(".*(:.-)$")) else - irc.say(channel.name, from .. ": " .. table.concat(result, ", ")) + if result[1] == nil then + irc.say(channel.name, from .. ": nil") + else + irc.say(channel.name, from .. ": " .. table.concat(result, ", ")) + end end end + end, + clear = function(channel, from) + irc.say(channel.name, from .. ": Clearing your environment") + envs[from] = create_env() + end, + help = function(channel, from, arg) + if not arg then + irc.say(channel.name, from .. ": Commands: !clear, !eval, !help") + elseif arg == "eval" then + irc.say(channel.name, from .. ": Evaluates a Lua statement in your own persistent environment") + elseif arg == "clear" then + irc.say(channel.name, from .. ": Clears your personal environment") + end + end +} + +irc.register_callback("connect", function() + irc.join("#doytest") +end) + +irc.register_callback("channel_msg", function(channel, from, message) + message = message:gsub("^" .. nick .. "[:,>] ", "!eval ") + local is_cmd, cmd, arg = message:match("^(!)([%w_]+) ?(.-)$") + if is_cmd and commands[cmd] then + envs[from] = envs[from] or create_env() + commands[cmd](channel, from, arg) + end +end) + +irc.register_callback("nick_change", function(from, old_nick) + if envs[old_nick] and not envs[from] then + envs[from] = envs[old_nick] + envs[old_nick] = nil end end) -- cgit v1.2.3