]> git.lizzy.rs Git - luairc.git/blob - test/luabot.lua
make the evalbot use per-user environments for evaling things, not one global one
[luairc.git] / test / luabot.lua
1 #!/usr/bin/env lua
2
3 local irc = require 'irc'
4 irc.DEBUG = true
5
6 local nick = "luabot"
7
8 local envs = {}
9
10 local function create_env()
11     return {
12         _VERSION =      _VERSION,
13         assert =         assert,
14         collectgarbage = collectgarbage,
15         error =          error,
16         getfenv =        getfenv,
17         getmetatable =   getmetatable,
18         ipairs =         ipairs,
19         loadstring =     loadstring,
20         next =           next,
21         pairs =          pairs,
22         pcall =          pcall,
23         rawequal =       rawequal,
24         rawget =         rawget,
25         rawset =         rawset,
26         select =         select,
27         setfenv =        setfenv,
28         setmetatable =   setmetatable,
29         tonumber =       tonumber,
30         tostring =       tostring,
31         type =           type,
32         unpack =         unpack,
33         xpcall =         xpcall,
34         coroutine =      coroutine,
35         math =           math,
36         string =         string,
37         table =          table,
38     }
39 end
40
41 local commands = {
42     eval = function(channel, from, code)
43         code = code:gsub("^=", "return ")
44         local fn, err = loadstring(code)
45         if not fn then
46             irc.say(channel.name, from .. ": Error loading code: " .. code .. err:match(".*(:.-)$"))
47             return
48         else
49             setfenv(fn, envs[from])
50             local result = {pcall(fn)}
51             local success = table.remove(result, 1)
52             if not success then
53                 irc.say(channel.name, from .. ": Error running code: " .. code .. result[1]:match(".*(:.-)$"))
54             else
55                 if result[1] == nil then
56                     irc.say(channel.name, from .. ": nil")
57                 else
58                     irc.say(channel.name, from .. ": " .. table.concat(result, ", "))
59                 end
60             end
61         end
62     end,
63     clear = function(channel, from)
64         irc.say(channel.name, from .. ": Clearing your environment")
65         envs[from] = create_env()
66     end,
67     help = function(channel, from, arg)
68         if not arg then
69             irc.say(channel.name, from .. ": Commands: !clear, !eval, !help")
70         elseif arg == "eval" then
71             irc.say(channel.name, from .. ": Evaluates a Lua statement in your own persistent environment")
72         elseif arg == "clear" then
73             irc.say(channel.name, from .. ": Clears your personal environment")
74         end
75     end
76 }
77
78 irc.register_callback("connect", function()
79     irc.join("#doytest")
80 end)
81
82 irc.register_callback("channel_msg", function(channel, from, message)
83     message = message:gsub("^" .. nick .. "[:,>] ", "!eval ")
84     local is_cmd, cmd, arg = message:match("^(!)([%w_]+) ?(.-)$")
85     if is_cmd and commands[cmd] then
86         envs[from] = envs[from] or create_env()
87         commands[cmd](channel, from, arg)
88     end
89 end)
90
91 irc.register_callback("nick_change", function(from, old_nick)
92     if envs[old_nick] and not envs[from] then
93         envs[from] = envs[old_nick]
94         envs[old_nick] = nil
95     end
96 end)
97
98 irc.connect{network = "irc.freenode.net", nick = nick}