Basic plugin system.
parent
6703df6f78
commit
839323b009
|
@ -0,0 +1,95 @@
|
|||
-- An isolated API for plugins
|
||||
-- These plugins are not yet made to be a secure sandbox, as hooking
|
||||
-- into signal might be destructive or reveal sensitive data.
|
||||
-- The goal is to be able to unload a plugin and remove all its' hooks
|
||||
-- and commands.
|
||||
|
||||
local Plugins = {}
|
||||
|
||||
plugin = {}
|
||||
local API = {}
|
||||
|
||||
-- All these functions start with the 'plugin_id' argument, which
|
||||
-- will be auto-bound to the plugin name when called from a plugin.
|
||||
function API.HookAdd(plugin_id, event_name, hook_name, callback)
|
||||
local HookName = plugin_id .. ':' .. hook_name
|
||||
local PluginHooks = Plugins[plugin_id].Hooks
|
||||
PluginHooks[#PluginHooks + 1] = HookName
|
||||
hook.Add(event_name, HookName, function(...)
|
||||
local Args = {...}
|
||||
local Success, Message = pcall(callback(unpack(Args)))
|
||||
if not Success then
|
||||
hook.Call("plugin.HookCallFailed", HookName, Message)
|
||||
return nil
|
||||
else
|
||||
return Message
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function API.CommandAdd(plugin_id, command_name, arity, callback, access, help)
|
||||
bot:AddCommand(command_name, arity, callback, access, help)
|
||||
local PluginCommands = Plugins[plugin_id].Commands
|
||||
PluginCommands[#PluginCommands + 1] = command_name
|
||||
end
|
||||
|
||||
function API.Register(plugin_id, plugin_name, version, url, author)
|
||||
local Plugin = Plugins[plugin_id]
|
||||
Plugin.Name = plugin_name
|
||||
Plugin.Version = Version
|
||||
Plugin.URL = url
|
||||
Plugin.Author = author
|
||||
|
||||
end
|
||||
|
||||
function plugin.Create(plugin_id)
|
||||
local Plugin = {}
|
||||
Plugin.Hooks = {}
|
||||
Plugin.Commands = {}
|
||||
|
||||
Plugin.ID = plugin_id
|
||||
Plugin.Name = ""
|
||||
Plugin.Version = 1.0
|
||||
Plugin.URL = ""
|
||||
Plugin.Author = "Nameless Wonder"
|
||||
|
||||
Plugins[plugin_id] = Plugin
|
||||
Plugins[plugin_id].Env = plugin.PrepareEnvironment(plugin_id)
|
||||
end
|
||||
|
||||
function plugin.PrepareEnvironment(plugin_id)
|
||||
local function BindPluginID(f)
|
||||
return function(...)
|
||||
local Args = {...}
|
||||
return f(plugin_id, unpack(Args))
|
||||
end
|
||||
end
|
||||
|
||||
local Env = {}
|
||||
Env.table = require('table')
|
||||
Env.string = require('string')
|
||||
Env.json = require('json')
|
||||
|
||||
Env.plugin = {}
|
||||
for K, F in pairs(API) do
|
||||
Env.plugin[K] = BindPluginID(F)
|
||||
end
|
||||
|
||||
return Env
|
||||
end
|
||||
|
||||
function plugin.RunCode(plugin_id, code)
|
||||
if not Plugins[plugin_id] then
|
||||
plugin.Create(plugin_id)
|
||||
end
|
||||
|
||||
if code:byte(1) == 27 then
|
||||
return nil, "Refused to load bytecode."
|
||||
end
|
||||
local Function, Message = loadstring(code)
|
||||
if not Function then
|
||||
return nil, Message
|
||||
end
|
||||
setfenv(Function, Plugins[plugin_id].Env)
|
||||
return pcall(Function)
|
||||
end
|
|
@ -2,6 +2,7 @@ require('core.hook')
|
|||
require('core.reactor')
|
||||
require('core.irc')
|
||||
require('core.bot')
|
||||
require('core.plugin')
|
||||
|
||||
require('socket')
|
||||
local https = require('ssl.https')
|
||||
|
@ -22,7 +23,7 @@ end)
|
|||
reactor:Initialize()
|
||||
bot:Initialize(irc, ',')
|
||||
|
||||
bot:AddCommand('at', 0, function(Username, Channel)
|
||||
--[[bot:AddCommand('at', 0, function(Username, Channel)
|
||||
local Body, Code, Headers, Status = https.request('https://at.hackerspace.pl/api')
|
||||
if Code ~= 200 then
|
||||
error(string.format("Status code returned: %i", Code))
|
||||
|
@ -34,7 +35,11 @@ bot:AddCommand('at', 0, function(Username, Channel)
|
|||
end
|
||||
Channel:Say(table.concat(Users, ','))
|
||||
|
||||
end, "Show who's at the Warsaw Hackerspace.")
|
||||
end, "Show who's at the Warsaw Hackerspace.")]]--
|
||||
|
||||
plugin.RunCode('test', [[plugin.CommandAdd('test', 0, function(Username, Channel)
|
||||
Channel:Say('hello!')
|
||||
end, "Test command.", 0)]])
|
||||
|
||||
irc:Connect('irc.freenode.net', 6667, 'moonspeak', 'moonspeak', 'moonspeak')
|
||||
reactor:Run()
|
||||
|
|
Loading…
Reference in New Issue