Ain't afraid of no bed

This commit is contained in:
Yessiest 2022-05-21 01:21:23 +04:00
parent ca17b716ba
commit f9bb6824f3
25 changed files with 1078 additions and 1127 deletions

View File

@ -10,106 +10,94 @@ local table_utils = import("table-utils")
local purify = import("purify") local purify = import("purify")
function command_handler:__init(parent_server) function command_handler:__init(parent_server)
self.server_handler = assert(parent_server,"parent server handler not provided") self.server_handler = assert(parent_server,"parent server handler not provided")
self.command_pool = {} self.pool = {}
self.prefixes = {} self.prefixes = {}
self.command_meta = { self.meta = {
plugins = {}, plugins = {},
categories = {} categories = {}
} }
end end
function command_handler:add_prefix(prefix) function command_handler:add_prefix(prefix)
local purified_prefix = purify.purify_escapes(prefix) self.prefixes[prefix] = purify.purify_escapes(prefix)
self.prefixes[purified_prefix] = purified_prefix
return true return true
end end
function command_handler:remove_prefix(prefix) function command_handler:remove_prefix(prefix)
local purified_prefix = purify.purify_escapes(prefix) local prefix = purify_escapes(prefix)
if self.prefixes[purified_prefix] or table_utils.count(self.prefixes) <= 1 then if self.prefixes[prefix] and table_utils.count(self.prefixes) > 1 then
self.prefix[purified_prefix] = nil self.prefixes[prefix] = nil
return true return true
else
return false, (
(self.prefixes[purified_prefix] and "No such prefix") or
"Cannot remove the last remaining prefix"
)
end end
if not self.prefixes[prefix] then
return false, "Prefix not found"
end
return false, "Cannot remove last remaining prefix!"
end end
function command_handler:get_prefixes() function command_handler:get_prefixes()
return table_utils.deepcopy(self.prefixes) return table_utils.deepcopy(self.prefixes)
end end
function command_handler:add_command(command) function command_handler:add_command(command)
assert(type(command) == "table","command object expected") assert(type(command) == "table","command object expected")
local purified_name = purify.purify_escapes(command.name) if self.pool[command.name] then
self.command_pool[purified_name] = command return false, "Already have a command with the same name"
if not self.command_meta.plugins[command.parent.name] then
self.command_meta.plugins[command.parent.name] = {}
end end
if not self.command_meta.categories[command.options.category] then self.pool[command.name] = command
self.command_meta.categories[command.options.category] = {} if not self.meta.plugins[command.parent.name] then
self.meta.plugins[command.parent.name] = {}
end end
table.insert(self.command_meta.categories[command.options.category],command.name) self.meta.plugins[command.parent.name][command.name] = command.name
table.insert(self.command_meta.plugins[command.parent.name],command.name) if not self.meta.categories[command.category] then
self.meta.categories[command.category] = {}
end
self.meta.categories[command.category][command.name] = command.name
return command return command
end end
function command_handler:remove_command(command) function command_handler:remove_command(command)
assert(type(command) == "table","command object expected") assert(type(command) == "table","command object expected")
local purified_name = purify.purify_escapes(command.name) if not self.pool[command.name] then
if self.command_pool[purified_name] then
local command = self.command_pool[purified_name]
--not exactly optimal, but lists are lists. can't do much about them.
table_utils.remove_value(self.command_meta.plugins[command.parent.name],command.name)
if #self.command_meta.plugins[command.parent.name] == 0 then
self.command_meta.plugins[command.parent.name] = nil
end
table_utils.remove_value(self.command_meta.categories[command.options.category],command.name)
if #self.command_meta.categories[command.options.category] == 0 then
self.command_meta.categories[command.options.category] = nil
end
self.command_pool[purified_name] = nil
return true
else
return false return false
end end
self.pool[command.name] = nil
self.meta.categories[command.category][command.name] = nil
self.meta.plugins[command.parent.name][command.name] = nil
end end
function command_handler:get_command(name) function command_handler:get_command(name)
local purified_name = purify.purify_escapes(assert(type(name) == "string") and name) return self.pool[name]
if self.command_pool[purified_name] then
return self.command_pool[purified_name]
else
return false
end
end end
function command_handler:get_commands(name) function command_handler:get_commands(name)
local list = {} local list = {}
for k,v in pairs(self.command_pool) do for k,v in pairs(self.pool) do
table.insert(list,k) table.insert(list,k)
end end
return list return list
end end
function command_handler:get_commands_metadata() function command_handler:get_metadata()
return table_utils.deepcopy(self.command_meta) local plugins,categories = {},{}
for k,v in pairs(self.meta.plugins) do
plugins[k] = table_utils.listcopy(v)
end
for k,v in pairs(self.meta.categories) do
categories[k] = table_utils.listcopy(v)
end
return {
plugins = plugins,
categories = categories
}
end end
function command_handler:handle(message) function command_handler:handle(message)
for name,command in pairs(self.command_pool) do local content = message.content
if command.options.regex then local prefix = ""
if message.content:match(command.options.regex) then local command
command:exec(message) for k,v in pairs(self.prefixes) do
return if content:match("^"..v) then
end prefix = v
else end
if command.options.prefix then end
for _,prefix in pairs(self.prefixes) do command = content:sub(prefix:len()+1,-1):match("^[%-_%w]+")
if message.content:match("^"..prefix..name.."$") or message.content:match("^"..prefix..name.."%s") then if self.pool[command] then
command:exec(message) if (prefix == "") and self.pool[command].options.prefix == false then
return self.pool[command]:exec(message)
end elseif (prefix ~= "") and self.pool[command].options.prefix == true then
end self.pool[command]:exec(message)
else
if message.content:match("^"..name.."$") or message.content:match("^"..name.."%s") then
command:exec(message)
return
end
end
end end
end end
end end

View File

@ -11,10 +11,10 @@ function command:__init(name,callback)
self.rules = acl() self.rules = acl()
self.name = name self.name = name
self.timer = discordia.Date():toMilliseconds() self.timer = discordia.Date():toMilliseconds()
self.category = "None"
self.options = { self.options = {
allow_bots = false, --allow bots to execute the command allow_bots = false, --allow bots to execute the command
typing_decorator = false, --set if the bot should be "typing" while the command executes typing_decorator = false, --set if the bot should be "typing" while the command executes
category = "None", --set category for the command
prefix = true, --if true check for prefix at the start. if not, don't check for prefix prefix = true, --if true check for prefix at the start. if not, don't check for prefix
no_parsing = false, --check if you want to disable the message argument parsing process no_parsing = false, --check if you want to disable the message argument parsing process
timeout = 1000, --set the timeout for a command timeout = 1000, --set the timeout for a command

View File

@ -56,4 +56,27 @@ function plugin:remove_command(command_object)
self.command_handler:remove_command(command_object) self.command_handler:remove_command(command_object)
end end
end end
function plugin:load_helpdb(path)
local helpdb_file = io.open(path,r)
local helpdb,err = load(helpdb_file:read("*a") or "","helpdb "..path,nil,
setmetatable({
require = require,
import = import
},{
__index = _G
})
)
helpdb_file:close()
if not helpdb then
error(err)
end
helpdb = helpdb()
self:for_all_commands(function(command)
if helpdb[command.name] then
command:set_help(helpdb[command.name])
end
end)
end
return plugin return plugin

View File

@ -38,8 +38,8 @@ function server_handler:__init(client,guild,options)
self.autosave = options.path or true self.autosave = options.path or true
self.autosave_frequency = options.autosave_frequency or 10 self.autosave_frequency = options.autosave_frequency or 10
self.plugin_search_paths = options.plugin_search_paths or {"./plugins/"} self.plugin_search_paths = options.plugin_search_paths or {"./plugins/"}
self.default_plugins = options.default_plugins or {"test"} self.default_plugins = options.default_plugins or {"plugins"}
self.default_prefixes = options.default_prefixes or {"&","<@!"..self.client.user.id..">"} self.default_prefixes = options.default_prefixes or {"&","<@"..self.client.user.id.."> "}
self.config = {} self.config = {}
self.config_path = self.config_path:gsub("%%id",self.id) self.config_path = self.config_path:gsub("%%id",self.id)
self:load_config() self:load_config()

View File

@ -28,7 +28,7 @@ return function(reqfunc)
import = import, import = import,
},{__index = _G})) },{__index = _G}))
if err then if err then
error("[import: "..filname.."] "..tostring(err)) error("[import: "..filename.."] "..tostring(err))
end end
return f() return f()
end end

View File

@ -21,6 +21,8 @@ purify.purify_pings = function(msg,input)
end end
text = text:gsub("<@(%D*)"..id..">",substitution) text = text:gsub("<@(%D*)"..id..">",substitution)
end end
text = text:gsub("@everyone","")
text = text:gsub("@here","")
return text return text
end end

View File

@ -17,22 +17,30 @@ end
utilities.slice = function(list,start,list_end) utilities.slice = function(list,start,list_end)
local output = {} local output = {}
for I = (start or 1),(list_end or #table) do for I = (start or 1),(list_end or #table) do
table.insert(output,list[I]) table.insert(output,list[I])
end end
return output return output
end end
utilities.shallowcopy = function(orig) utilities.shallowcopy = function(orig)
local copy = {} local copy = {}
for k,v in pairs(orig) do for k,v in pairs(orig) do
copy[k] = v copy[k] = v
end end
return copy return copy
end end
utilities.listcopy = function(orig)
local list = {}
for k,v in pairs(orig) do
table.insert(list,v)
end
return list
end
--overwrite the original table's properties with new properties --overwrite the original table's properties with new properties
utilities.overwrite = function(original,overwrite) utilities.overwrite = function(original,overwrite)
local new = utilities.shallowcopy(original) local new = utilities.shallowcopy(original)
for k,v in pairs(overwrite) do for k,v in pairs(overwrite) do
new[k] = v new[k] = v
end end
return new return new
end end
@ -42,13 +50,13 @@ utilities.merge = function(...)
local args = {...} local args = {...}
local new = {} local new = {}
for k,v in pairs(args) do for k,v in pairs(args) do
if type(v) == "table" then if type(v) == "table" then
for k2,v2 in pairs(v) do for k2,v2 in pairs(v) do
table.insert(new,v2) table.insert(new,v2)
end
else
table.insert(new,v)
end end
else
table.insert(new,v)
end
end end
return new return new
end end

50
plugins/cron/help.lua Normal file
View File

@ -0,0 +1,50 @@
return {
["event"] = {embed={
title = "Add a cron event",
description = "https://github.com/512mb-org/512mb.org-bot/wiki/Events-and-cronjobs",
fields = {
{name = "Usage:",value = "event ..."},
{name = "Perms:",value = "administrator"},
}
}},
["delay"] = {embed={
title = "Delay a command",
description = "Delay fromat is <number><unit>, where unit is one of the follwing:\n\"h\" - hour,\n\"m\" - minute,\n\"d\" - day,\n\"w\" - week,\n\"y\" - year",
fields = {
{name = "Usage:",value = "delay <delayformat> <command>"},
{name = "Perms:",value = "any"},
}
}},
["events"] = {embed={
title = "View your running events",
description = "nuff said.",
fields = {
{name = "Usage:",value = "events <page>"},
{name = "Perms:",value = "any"},
}
}},
["user-events"] = {embed={
title = "View running events of a certain user",
description = "nuff said.",
fields = {
{name = "Usage:",value = "user-events <user> <page>"},
{name = "Perms:",value = "administrator"},
}
}},
["remove-event"] = {embed={
title = "Remove an event",
description = "nuff said.",
fields = {
{name = "Usage:",value = "remove-event <id>"},
{name = "Perms:",value = "any"},
}
}},
["remove-user-event"] = {embed={
title = "Remove an event from a user",
description = "nuff said.",
fields = {
{name = "Usage:",value = "remove-user-event <user> <id>"},
{name = "Perms:",value = "administrator"},
}
}},
}

View File

@ -195,20 +195,8 @@ for _,evtype in pairs(config.events.event) do
end end
local event = command("event",{ local event = command("event",{
help = {embed={ perms = {"administrator"},
title = "Add a cron event", args = {"string"},
description = "https://github.com/512mb-org/512mb.org-bot/wiki/Events-and-cronjobs",
fields = {
{name = "Usage:",value = "event ..."},
{name = "Perms:",value = "administrator"},
}
}},
perms = {
"administrator"
},
args = {
"string"
},
exec = function(msg,args,opts) exec = function(msg,args,opts)
return create_event(msg,table.concat(args," ")) return create_event(msg,table.concat(args," "))
end end
@ -216,14 +204,6 @@ local event = command("event",{
plugin:add_command(event) plugin:add_command(event)
local delay = command("delay",{ local delay = command("delay",{
help = {embed={
title = "Delay a command",
description = "Delay fromat is <number><unit>, where unit is one of the follwing:\n\"h\" - hour,\n\"m\" - minute,\n\"d\" - day,\n\"w\" - week,\n\"y\" - year",
fields = {
{name = "Usage:",value = "delay <delayformat> <command>"},
{name = "Perms:",value = "any"},
}
}},
args = { args = {
"string", "string",
"string" "string"
@ -238,14 +218,6 @@ local delay = command("delay",{
plugin:add_command(delay) plugin:add_command(delay)
local events_comm = command("events",{ local events_comm = command("events",{
help = {embed={
title = "View your running events",
description = "nuff said.",
fields = {
{name = "Usage:",value = "events <page>"},
{name = "Perms:",value = "any"},
}
}},
exec = function(msg,args,opts) exec = function(msg,args,opts)
args[1] = tonumber(args[1]) or 1 args[1] = tonumber(args[1]) or 1
local upto = args[1]*5 local upto = args[1]*5
@ -269,20 +241,8 @@ local events_comm = command("events",{
plugin:add_command(events_comm) plugin:add_command(events_comm)
local user_events_comm = command("user-events",{ local user_events_comm = command("user-events",{
help = {embed={ args = {"member"},
title = "View running events of a certain user", perms = {"administrator"},
description = "nuff said.",
fields = {
{name = "Usage:",value = "user-events <user> <page>"},
{name = "Perms:",value = "administrator"},
}
}},
args = {
"member"
},
perms = {
"administrator"
},
exec = function(msg,args,opts) exec = function(msg,args,opts)
args[2] = tonumber(args[2]) or 1 args[2] = tonumber(args[2]) or 1
local upto = args[2]*5 local upto = args[2]*5
@ -306,17 +266,7 @@ local user_events_comm = command("user-events",{
plugin:add_command(user_events_comm) plugin:add_command(user_events_comm)
local remove_event= command("remove-event",{ local remove_event= command("remove-event",{
help = {embed={ args = {"string"},
title = "Remove an event",
description = "nuff said.",
fields = {
{name = "Usage:",value = "remove-event <id>"},
{name = "Perms:",value = "any"},
}
}},
args = {
"string"
},
exec = function(msg,args,opts) exec = function(msg,args,opts)
return remove_user_event(msg.author.id,args[1]) return remove_user_event(msg.author.id,args[1])
end end
@ -324,14 +274,6 @@ local remove_event= command("remove-event",{
plugin:add_command(remove_event) plugin:add_command(remove_event)
local remove_user_event_c = command("remove-user-event",{ local remove_user_event_c = command("remove-user-event",{
help = {embed={
title = "Remove an event from a user",
description = "nuff said.",
fields = {
{name = "Usage:",value = "remove-user-event <user> <id>"},
{name = "Perms:",value = "administrator"},
}
}},
args = { args = {
"member", "member",
"string" "string"
@ -360,10 +302,10 @@ timer:on("min",function()
end) end)
--load events file --load events file
local fhandler = io.open("./plugins/cron/events.lua","r") local fhandler = io.open(plugin_path.."/events.lua","r")
local data = fhandler:read("*a") local data = fhandler:read("*a")
fhandler:close() fhandler:close()
local eventfunc = load(data,"event loader: ./plugins/cron/events.lua",nil,setmetatable({ local eventfunc = load(data,"event loader: "..plugin_path.."/events.lua",nil,setmetatable({
id = id, id = id,
client = client, client = client,
exec = exec, exec = exec,
@ -371,6 +313,7 @@ local eventfunc = load(data,"event loader: ./plugins/cron/events.lua",nil,setmet
config = config config = config
},{__index = _G})) },{__index = _G}))
eventfunc() eventfunc()
timer:start(true) timer:start(true)
plugin:load_helpdb(plugin_path.."help.lua")
return plugin return plugin

6
plugins/debug/help.lua Normal file
View File

@ -0,0 +1,6 @@
return {
["save"] = "Force-save config data",
["error"] = "Force error",
["permerror"] = "Force permission error",
["return_error"] = "Force a return value error",
}

View File

@ -1,21 +1,18 @@
local plugin = import("classes.plugin")("debug") local plugin = import("classes.plugin")("debug")
local command = import("classes.command") local command = import("classes.command")
local save = command("save",{ local save = command("save",{
help = "Force-save config data",
exec = function() exec = function()
server:save_config() server:save_config()
end end
}) })
plugin:add_command(save) plugin:add_command(save)
local err = command("error",{ local err = command("error",{
help = "Force error",
exec = function() exec = function()
error("Errored successfully!") error("Errored successfully!")
end end
}) })
plugin:add_command(err) plugin:add_command(err)
local perm_error = command("permerror",{ local perm_error = command("permerror",{
help = "Force permission error",
users = { users = {
["245973168257368076"] = -1 ["245973168257368076"] = -1
}, },
@ -25,11 +22,11 @@ local perm_error = command("permerror",{
}) })
plugin:add_command(perm_error) plugin:add_command(perm_error)
local return_error = command("return_error",{ local return_error = command("return_error",{
help = "Force a return value error",
exec = function(msg) exec = function(msg)
msg:reply("nono :)") msg:reply("nono :)")
return false return false
end end
}) })
plugin:add_command(return_error) plugin:add_command(return_error)
plugin:load_helpdb(plugin_path.."help.lua")
return plugin return plugin

View File

@ -4,112 +4,108 @@ local plugin_class = import("classes.plugin")
local command = import("classes.command") local command = import("classes.command")
local plugin = plugin_class() local plugin = plugin_class()
local settings = { local settings = {
tapesize = 30000, tapesize = 30000,
cellsize = 1, cellsize = 1,
debug = true, debug = true,
limit = 500000 limit = 500000
} }
c_brainfuck = command("brainfuck",{ c_brainfuck = command("brainfuck",{
args = { args = {
"string" "string"
}, },
exec = function(msg,args,opts) exec = function(msg,args,opts)
settings.load_extensions = {} settings.load_extensions = {}
settings.path = "./lib/brainfuck/" settings.path = "./lib/brainfuck/"
local instance = brainfuck.new(args[1],settings) local instance = brainfuck.new(args[1],settings)
local result,opcount,err = instance:run(args[2] or "") local result,opcount,err = instance:run(args[2] or "")
if result == "" then if result == "" then
result = "" result = ""
end end
if not err then if not err then
if opts["o"] or opts["output-only"] then if opts["o"] or opts["output-only"] then
msg:reply(tostring(result):gsub("@","\\@")) msg:reply(tostring(result):gsub("@","\\@"))
else else
msg:reply({ embed = { msg:reply({ embed = {
title = "Result:", title = "Result:",
color = discordia.Color.fromHex("#32cd32").value, color = discordia.Color.fromHex("#32cd32").value,
description = "```"..tostring(result):gsub("`","\\`").." ```", description = "```"..tostring(result):gsub("`","\\`").." ```",
footer = { footer = {
text = "Finished in "..opcount.." operations" text = "Finished in "..opcount.." operations"
} }
}}) }})
end
else
msg:reply({
embed = {
title = "Error:",
description = "```"..tostring(err).." ```",
color = discordia.Color.fromHex("#32cd32").value,
}
})
end
end end
else
msg:reply({
embed = {
title = "Error:",
description = "```"..tostring(err).." ```",
color = discordia.Color.fromHex("#32cd32").value,
}
})
end
end
}) })
plugin:add_command(c_brainfuck) plugin:add_command(c_brainfuck)
c_befunge = command("befunge",{ c_befunge = command("befunge",{
args = { args = {
"string" "string"
}, },
exec = function(msg,args,opts) exec = function(msg,args,opts)
local code = msg.content:match("```(.+)```") local code = msg.content:match("```(.+)```")
if not code then if not code then
msg:reply("Invalid syntax") msg:reply("Invalid syntax")
return return
end end
local input = msg.content:match("```.+``` ?(.+)") or "" local input = msg.content:match("```.+``` ?(.+)") or ""
local stdout = "" local stdout = ""
local stderr = "" local stderr = ""
befunge:init(code,{ befunge:init(code,{
opcount = 10000, opcount = 10000,
handle_int_input = function() handle_int_input = function()
local int = input:match("^%d+") local int = input:match("^%d+")
if not int then if not int then
return return
end end
input = input:gsub("^%d+","",1) input = input:gsub("^%d+","",1)
return tonumber(int) return tonumber(int)
end, end,
handle_input = function() handle_input = function()
local char = input:sub(1,1) local char = input:sub(1,1)
if not char then if not char then
return return
end end
input = input:sub(2,-1) input = input:sub(2,-1)
return string.byte(char) return string.byte(char)
end, end,
handle_output = function(char) handle_output = function(char)
stdout = stdout..char stdout = stdout..char
end, end,
handle_warning = function(warn) handle_warning = function(warn)
stderr = stderr.."[warning] "..warn.."\n" stderr = stderr.."[warning] "..warn.."\n"
end, end,
handle_error = function(error) handle_error = function(error)
stderr = stderr.."[error] "..error.."\n" stderr = stderr.."[error] "..error.."\n"
befunge.interpreter_state = false befunge.interpreter_state = false
end
})
local opcount = befunge:run()
if opts["o"] or opts["output-only"] then
msg:reply(tostring(stdout):gsub("@","\\@"))
else
msg:reply({embed = {
title = "Result: ",
color = discordia.Color.fromHex("#32cd32").value,
fields = {
{name = "out",value = "```"..stdout:gsub("`","\\`").." ```"},
{name = "err",value = "```"..stderr.." ```"}
},
footer = {
text = "Finished in "..opcount.." operations"
}
}})
end
end end
})
local opcount = befunge:run()
if opts["o"] or opts["output-only"] then
msg:reply(tostring(stdout):gsub("@","\\@"))
else
msg:reply({embed = {
title = "Result: ",
color = discordia.Color.fromHex("#32cd32").value,
fields = {
{name = "out",value = "```"..stdout:gsub("`","\\`").." ```"},
{name = "err",value = "```"..stderr.." ```"}
},
footer = {
text = "Finished in "..opcount.." operations"
}
}})
end
end
}) })
plugin:add_command(c_befunge) plugin:add_command(c_befunge)
local helpdb = import(plugin_path:sub(3,-1).."help") plugin:load_helpdb(plugin_path.."help.lua")
plugin:for_all_commands(function(command)
command:set_help(helpdb[command.name])
end)
return plugin return plugin

11
plugins/help/help.lua Normal file
View File

@ -0,0 +1,11 @@
return {
["help"] = {embed={
title = "View help embeds for commands and plugins",
description = "To specify if it's a plugin or a command, simply add the option accordingly",
fields = {
{name = "Usage:",value = "help [<command> or --plugin <plugin>]"},
{name = "Perms:",value = "any"},
{name = "Options:",value = "--plugin"}
}
}}
}

View File

@ -1,97 +1,48 @@
local pluginc = import("classes.plugin") local pluginc = import("classes.plugin")
local command = import("classes.command") local command = import("classes.command")
local plugin = pluginc("help") local plugin = pluginc("help")
math.randomseed(os.time()+os.clock()) local color = discordia.Color.fromHex
local help_message
local function randomize_stuff()
local chance = math.random(1,100)
if chance < 10 then
help_message = [[
This button here, builds Teleporters. This button, builds Dispensers.
And this little button makes them enemy sum-bitches wish they'd never been born!
--the inspiration behind this bot's design ]]
elseif chance >= 10 and chance < 90 then
help_message = [[
This plugin provides the help command, which can view help messages for plugins and commands
]]
else
help_message = [[
see the invisible
do the impossible
row row
fight da powah
]]
end
end
local function count(tab)
local count = 0
for k,v in pairs(tab) do
count = count+1
end
return count
end
local function concatenate_keys(tab)
local key_list = {}
for k,v in pairs(tab) do
table.insert(key_list,k)
end
return "``"..table.concat(key_list,"``,\n``").."``"
end
local help_command = command("help",{ local help_command = command("help",{
help = {embed={
title = "View help embeds for commands and plugins",
description = "To specify if it's a plugin or a command, simply add the option accordingly",
fields = {
{name = "Usage:",value = "help [<command> or --plugin <plugin>]"},
{name = "Perms:",value = "any"},
{name = "Options:",value = "--plugin"}
}
}},
exec = function(msg,args,opts) exec = function(msg,args,opts)
randomize_stuff() local embed = {
local embed = { color = color("32b3bc").value
color = discordia.Color.fromHex("32b3bc").value }
} if args[1] then
if args[1] then if not opts["plugin"] then
if count(opts) < 1 then if command_handler:get_command(args[1]) then
if command_handler:get_command(args[1]) then local command = command_handler:get_command(args[1])
local command = command_handler:get_command(args[1]) embed = command:get_help().embed
embed = command:get_help().embed else
else embed.description = "No such command: "..args[1]
embed.description = "No such command" embed.color = color("990000").value
end end
elseif (opts["plugin"]) then else
--[[ if plugin_data["plugins"] [args[1] ] then local meta = command_handler:get_metadata()
embed.title = "Plugin ``"..args[1].."``:" local comms = meta.plugins[args[1]]
embed.description = plugin_data["plugins"] [args[1] ]["_help"] if not comms then
embed.fields = {{ embed.description = "Unable to find plugin: "..args[1]
name = "Commands:", embed.color = color("990000").value
value ="``"..table.concat(plugin_data["plugins"] [args[1] ],"``,\n``").."``" else
}} embed.title = "Plugin ``"..args[1].."``"
else embed.description = "``"..table.concat(comms,"``,``").."``"
embed.description = "No such plugin" end
end end
--]] else
embed.title = "Not yet implemented" local meta = command_handler:get_metadata()
embed.description = "Check again later" embed.title = "512mb.org commands:"
embed.description = "use ``help <command>`` to view help messages. (type ``help help`` for more info)"
embed.fields = {}
for name,category in pairs(meta.categories) do
table.insert(embed.fields,{
name = name,
value = "``"..table.concat(category,"``,``").."``"
})
end
end end
else msg:reply({embed = embed})
embed.title = "512mb.org commands:"
embed.description = "use ``help <command>`` to view help messages. (type ``help help`` for more info)"
embed.fields = {}
for k,v in pairs(command_handler:get_commands_metadata().plugins) do
table.insert(embed.fields,{
name = k,
value = "``"..table.concat(v,"``, ``").."``"
})
end
end
msg:reply({embed = embed})
end, end,
}) })
plugin:add_command(help_command) plugin:add_command(help_command)
plugin:load_helpdb(plugin_path.."help.lua")
return plugin return plugin

View File

@ -4,13 +4,14 @@ local last_message_arrived = discordia.Stopwatch()
local unixToString = import("unixToString") local unixToString = import("unixToString")
local command = import("classes.command") local command = import("classes.command")
local plugin = import("classes.plugin")("meta") local plugin = import("classes.plugin")("meta")
local purify = import("purify")
if not config.aliases then if not config.aliases then
config.aliases = {} config.aliases = {}
end end
client:on("messageCreate",function(msg) client:on("messageCreate",function(msg)
last_message_arrived:reset() last_message_arrived:reset()
last_message_arrived:start() last_message_arrived:start()
end) end)
local prefix local prefix
@ -21,185 +22,153 @@ for k,v in pairs(command_handler:get_prefixes()) do
end end
local function add_alias(name,comm,prefix,description) local function add_alias(name,comm,prefix,description)
if (not aliases[name]) then if (not aliases[name]) then
print("[ALIAS] Adding alias \""..name.."\" for \""..comm.."\"") print("[ALIAS] Adding alias \""..name.."\" for \""..comm.."\"")
config.aliases[name] = {comm = comm,prefix = prefix} config.aliases[name] = {comm = comm,prefix = prefix}
aliases[name] = command(name,{ aliases[name] = command(name,{
help = "Alias for ``"..comm.."``", help = "Alias for ``"..comm.."``",
usage = ((prefix and globals.prefix) or "")..name, usage = ((prefix and globals.prefix) or "")..name,
exec = function(msg,args2,opts) exec = function(msg,args2,opts)
print("[ALIAS] Triggerting alias "..tostring(comm).." with args \""..tostring(msg.content).."\"") print("[ALIAS] Triggerting alias "..tostring(comm).." with args \""..tostring(msg.content).."\"")
local str = msg.content:gsub("^%S+ ?","") local str = msg.content:gsub("^%S+ ?","")
aftersub = comm:gsub("%.%.%.",str or "") aftersub = comm:gsub("%.%.%.",str or "")
aftersub = aftersub:gsub("%$prefix",prefix or "&") aftersub = aftersub:gsub("%$prefix",prefix or "&")
local status,args = require("air").parse(str) local status,args = require("air").parse(str)
for k,v in pairs(args) do for k,v in pairs(args) do
aftersub = aftersub:gsub("([^\\])%$"..k,"%1"..v) aftersub = aftersub:gsub("([^\\])%$"..k,"%1"..v)
end end
command_handler:handle(fake_message(msg,{ command_handler:handle(fake_message(msg,{
content = aftersub content = aftersub
})) }))
end, end,
options = { options = {
prefix = prefix, prefix = prefix,
custom = true custom = true
} }
}) })
plugin:add_command(aliases[name]) plugin:add_command(aliases[name])
return true return true
else else
return false return false
end end
end end
local function remove_alias(name) local function remove_alias(name)
if config.aliases[name] then if config.aliases[name] then
config.aliases[name] = nil config.aliases[name] = nil
plugin:remove_command(aliases[name]) plugin:remove_command(aliases[name])
aliases[name] = nil aliases[name] = nil
return true return true
else else
return false return false
end
end
local function purify_strings(msg,input)
local text = input
while text:match("<@(%D*)(%d*)>") do
local obj,id = text:match("<@(%D*)(%d*)>")
local substitution = ""
if obj:match("!") then
local member = msg.guild:getMember(id)
if member then
substitution = "@"..member.name
end
elseif obj:match("&") then
local role = msg.guild:getRole(id)
if role then
substitution = "@"..role.name
end
end end
if substitution == "" then
substitution = "<\\@"..obj..id..">"
end
text = text:gsub("<@(%D*)"..id..">",substitution)
end
text = text:gsub("@everyone","")
text = text:gsub("@here","")
return text
end end
for k,v in pairs(config.aliases) do for k,v in pairs(config.aliases) do
commdata = v commdata = v
if type(v) == "string" then --legacy format conversion if type(v) == "string" then --legacy format conversion
commdata = {comm = v, prefix = false} commdata = {comm = v, prefix = false}
end end
add_alias(k,commdata.comm,commdata.prefix) add_alias(k,commdata.comm,commdata.prefix)
end end
local prefix = command("prefix",{ local prefix = command("prefix",{
help = "Set prefix", help = "Set prefix",
usage = "prefix [(add | remove | list (default)) [<new prefix>]]", usage = "prefix [(add | remove | list (default)) [<new prefix>]]",
users = { perms = {
[client.owner.id] = 1 "administrator"
}, },
roles = { exec = function(msg,args,opts)
["747042157185073182"] = 1 local function list_prefixes(msg)
}, local prefixes = ""
perms = { for k,v in pairs(command_handler:get_prefixes()) do
"administrator" prefixes = prefixes..v.."\n"
}, end
exec = function(msg,args,opts) msg:reply({embed = {
local function list_prefixes(msg) title = "Prefixes for this server",
local prefixes = "" description = prefixes
for k,v in pairs(command_handler:get_prefixes()) do }})
prefixes = prefixes..v.."\n" end
end if args[1] then
msg:reply({embed = { if args[1] == "add" and args[2] then
title = "Prefixes for this server", command_handler:add_prefix(args[2])
description = prefixes msg:reply("Added "..args[2].." as a prefix")
}}) elseif args[1] == "remove" and args[2] then
end local status,err = command_handler:remove_prefix(args[2])
if args[1] then if status then
if args[1] == "add" and args[2] then msg:reply("Removed the "..args[2].." prefix")
command_handler:add_prefix(args[2]) else
msg:reply("Added "..args[2].." as a prefix") msg:reply(err)
elseif args[1] == "remove" and args[2] then end
local status,err = command_handler:remove_prefix(args[2]) elseif args[1] == "list" then
if status then list_prefixes(msg)
msg:reply("Removed the "..args[2].." prefix") else
else msg:reply("Syntax error")
msg:reply(err) end
else
list_prefixes(msg)
end end
elseif args[1] == "list" then
list_prefixes(msg)
else
msg:reply("Syntax error")
end
else
list_prefixes(msg)
end end
end
}) })
plugin:add_command(prefix) plugin:add_command(prefix)
local c_alias = command("alias", { local c_alias = command("alias", {
args = { args = {
"string","string" "string","string"
}, },
perms = { perms = {
"administrator" "administrator"
}, },
exec = function(msg,args,opts) exec = function(msg,args,opts)
if add_alias(args[1],args[2],(opts["prefix"] or opts["p"]),opts["description"]) then if add_alias(args[1],args[2],(opts["prefix"] or opts["p"]),opts["description"]) then
msg:reply("Bound ``"..args[1].."`` as an alias to ``"..args[2].."``") msg:reply("Bound ``"..args[1].."`` as an alias to ``"..args[2].."``")
else else
msg:reply("``"..args[1].."`` is already bound") msg:reply("``"..args[1].."`` is already bound")
end
end end
end
}) })
plugin:add_command(c_alias) plugin:add_command(c_alias)
local c_unalias = command("unalias", { local c_unalias = command("unalias", {
args = { args = {
"string" "string"
}, },
perms = { perms = {
"administrator" "administrator"
}, },
exec = function(msg,args,opts) exec = function(msg,args,opts)
if remove_alias(args[1]) then if remove_alias(args[1]) then
msg:reply("Removed the ``"..args[1].."`` alias") msg:reply("Removed the ``"..args[1].."`` alias")
else else
msg:reply("No such alias") msg:reply("No such alias")
end
end end
end
}) })
plugin:add_command(c_unalias) plugin:add_command(c_unalias)
local c_aliases = command("aliases", { local c_aliases = command("aliases", {
exec = function(msg,args,opts) exec = function(msg,args,opts)
msg:reply({embed = { msg:reply({embed = {
title = "Aliases for this server", title = "Aliases for this server",
fields = (function() fields = (function()
local fields = {} local fields = {}
for k,v in pairs(config.aliases) do for k,v in pairs(config.aliases) do
table.insert(fields,{name = ((v["prefix"] and prefix) or "")..k,value = v["comm"]}) table.insert(fields,{name = ((v["prefix"] and prefix) or "")..k,value = v["comm"]})
end end
return fields return fields
end)() end)()
}}) }})
end end
}) })
plugin:add_command(c_aliases) plugin:add_command(c_aliases)
local c_ping = command("ping", { local c_ping = command("ping", {
exec = function(msg,args,opts) exec = function(msg,args,opts)
local before = msg:getDate() local before = msg:getDate()
local reply = msg:reply("Pong!") local reply = msg:reply("Pong!")
if not reply then if not reply then
log("ERROR","Couldn't send the ping reply for some reason") log("ERROR","Couldn't send the ping reply for some reason")
return return
end end
local after = reply:getDate() local after = reply:getDate()
local latency = (after:toMilliseconds() - before:toMilliseconds()) local latency = (after:toMilliseconds() - before:toMilliseconds())
@ -207,82 +176,82 @@ local c_ping = command("ping", {
local uptime = discordia.Date():toSeconds() - server.uptime:toSeconds() local uptime = discordia.Date():toSeconds() - server.uptime:toSeconds()
local processing = (last_message_arrived:getTime():toMilliseconds()) local processing = (last_message_arrived:getTime():toMilliseconds())
msg:reply({embed = { msg:reply({embed = {
title = "Stats:", title = "Stats:",
fields = { fields = {
{name = "Latency",value = tostring(math.floor(latency)).."ms"}, {name = "Latency",value = tostring(math.floor(latency)).."ms"},
{name = "Processing time",value = tostring(math.floor(processing)).."ms"}, {name = "Processing time",value = tostring(math.floor(processing)).."ms"},
{name = "Uptime",value = tostring(unixToString(uptime))} {name = "Uptime",value = tostring(unixToString(uptime))}
} }
}}) }})
end end
}) })
plugin:add_command(c_ping) plugin:add_command(c_ping)
local c_about = command("about", { local c_about = command("about", {
exec = function(msg,args,opts) exec = function(msg,args,opts)
local rand = math.random local rand = math.random
local author = client:getUser("245973168257368076") local author = client:getUser("245973168257368076")
msg:reply({embed = { msg:reply({embed = {
title = "About 512mb.org bot", title = "About 512mb.org bot",
thumbnail = { thumbnail = {
url = client.user:getAvatarURL() url = client.user:getAvatarURL()
}, },
color = discordia.Color.fromRGB(rand(50,200),rand(50,200),rand(50,200)).value, color = discordia.Color.fromRGB(rand(50,200),rand(50,200),rand(50,200)).value,
description = "512mb.org is an open-source bot written in Lua. It is based on a beta rewrite version of the Suppa-Bot.", description = "512mb.org is an open-source bot written in Lua. It is based on a beta rewrite version of the Suppa-Bot.",
fields = { fields = {
{name = "Source Code: ",value = "https://github.com/512mb-xyz/512mb.org-bot"}, {name = "Source Code: ",value = "https://github.com/512mb-xyz/512mb.org-bot"},
{name = "Author: ",value = author.tag}, {name = "Author: ",value = author.tag},
{name = "Invite: ",value = "Not available yet"} {name = "Invite: ",value = "Not available yet"}
}, },
footer = { footer = {
text = "For any information regarding the bot, contact yessiest on 512mb.org discord." text = "For any information regarding the bot, contact yessiest on 512mb.org discord."
} }
}}) }})
end end
}) })
plugin:add_command(c_about) plugin:add_command(c_about)
local c_server = command("server", { local c_server = command("server", {
exec = function(msg,args,opts) exec = function(msg,args,opts)
msg:reply({embed = { msg:reply({embed = {
thumbnail = { thumbnail = {
url = msg.guild.iconURL url = msg.guild.iconURL
}, },
title = msg.guild.name, title = msg.guild.name,
description = msg.guild.description, description = msg.guild.description,
fields = { fields = {
{name = "Members",value = msg.guild.totalMemberCount}, {name = "Members",value = msg.guild.totalMemberCount},
{name = "Owner",value = (msg.guild.owner and msg.guild.owner.user.tag..":"..msg.guild.owner.user.id) or msg.guild.ownerId}, {name = "Owner",value = (msg.guild.owner and msg.guild.owner.user.tag..":"..msg.guild.owner.user.id) or msg.guild.ownerId},
{name = "Created At",value = os.date("!%c",msg.guild.createdAt).." (UTC+0)"}, {name = "Created At",value = os.date("!%c",msg.guild.createdAt).." (UTC+0)"},
{name = "Text Channels",value = msg.guild.textChannels:count()}, {name = "Text Channels",value = msg.guild.textChannels:count()},
{name = "Voice Channels",value = msg.guild.voiceChannels:count()} {name = "Voice Channels",value = msg.guild.voiceChannels:count()}
} }
}}) }})
end, end,
}) })
plugin:add_command(c_server) plugin:add_command(c_server)
local c_user = command("user", { local c_user = command("user", {
exec = function(msg,args,opts) exec = function(msg,args,opts)
local member = msg.guild:getMember((args[1] or ""):match("%d+")) or msg.guild:getMember(msg.author.id) local member = msg.guild:getMember((args[1] or ""):match("%d+")) or msg.guild:getMember(msg.author.id)
local roles = "" local roles = ""
for k,v in pairs(member.roles) do for k,v in pairs(member.roles) do
roles = roles..v.mentionString.."\n" roles = roles..v.mentionString.."\n"
end end
msg:reply({embed = { msg:reply({embed = {
title = member.user.tag..":"..member.user.id, title = member.user.tag..":"..member.user.id,
thumbnail = { thumbnail = {
url = member.user:getAvatarURL() url = member.user:getAvatarURL()
}, },
fields = { fields = {
{name = "Profile Created At",value = os.date("!%c",member.user.createdAt).." (UTC+0)"}, {name = "Profile Created At",value = os.date("!%c",member.user.createdAt).." (UTC+0)"},
{name = "Joined At",value = os.date("!%c",discordia.Date.fromISO(member.joinedAt):toSeconds()).." (UTC+0)",inline = true}, {name = "Joined At",value = os.date("!%c",discordia.Date.fromISO(member.joinedAt):toSeconds()).." (UTC+0)",inline = true},
{name = "Boosting",value = ((member.premiumSince and "Since "..member.premiumSince) or "No"),inline = true}, {name = "Boosting",value = ((member.premiumSince and "Since "..member.premiumSince) or "No"),inline = true},
{name = "Highest Role",value = member.highestRole.mentionString,inline = true}, {name = "Highest Role",value = member.highestRole.mentionString,inline = true},
{name = "Roles",value = roles,inline = true} {name = "Roles",value = roles,inline = true}
} }
}}) }})
end, end,
}) })
plugin:add_command(c_user) plugin:add_command(c_user)
@ -291,10 +260,7 @@ local c_speak = command("speak", {
"string" "string"
}, },
exec = function(msg,args,opts) exec = function(msg,args,opts)
local text = purify_strings(msg, table.concat(args," ")) local text = purify.purify_pings(msg, table.concat(args," "))
if opts["unescape"] or opts["u"] then
text = text:gsub("\\","")
end
msg:reply(text) msg:reply(text)
msg:delete() msg:delete()
end, end,
@ -302,32 +268,26 @@ local c_speak = command("speak", {
plugin:add_command(c_speak) plugin:add_command(c_speak)
local c_adminSpeak = command("adminSpeak", { local c_adminSpeak = command("adminSpeak", {
args = { args = {
"string" "string"
}, },
exec = function(msg,args,opts) exec = function(msg,args,opts)
local text = table.concat(args," ") local text = table.concat(args," ")
if opts["unescape"] or opts["u"] then msg:reply(text)
text = text:gsub("\\","") msg:delete()
end end,
msg:reply(text) perms = {
msg:delete() "mentionEveryone"
end, }
perms = {
"mentionEveryone"
}
}) })
plugin:add_command(c_adminSpeak) plugin:add_command(c_adminSpeak)
local c_echo = command("echo",{ local c_echo = command("echo",{
args = { args = {
"string" "string"
}, },
exec = function(msg,args,opts) exec = function(msg,args,opts)
local text = purify_strings(msg, table.concat(args," ")) local text = purify.purify_pings(msg, table.concat(args," "))
if opts["unescape"] or opts["u"] then
text = text:gsub("\\","")
end
msg:reply(text) msg:reply(text)
end, end,
}) })
@ -335,29 +295,20 @@ plugin:add_command(c_echo)
local c_pingself = command("pingself",{ local c_pingself = command("pingself",{
args = { args = {
"string" "string"
}, },
exec = function(msg,args,opts) exec = function(msg,args,opts)
local text = purify_strings(msg, table.concat(args," ")) local text = purify.purify_pings(msg, table.concat(args," "))
if opts["unescape"] or opts["u"] then
text = text:gsub("\\","")
end
msg:reply("<@"..tostring(msg.member.id).."> "..text) msg:reply("<@"..tostring(msg.member.id).."> "..text)
end, end,
}) })
plugin:add_command(c_pingself) plugin:add_command(c_pingself)
plugin.removal_callback = function() plugin.removal_callback = function()
for k,v in pairs(config.aliases) do for k,v in pairs(config.aliases) do
remove_alias(k) remove_alias(k)
end end
end end
local helpdb = import(plugin_path:sub(3,-1).."help") plugin:load_helpdb(plugin_path.."help.lua")
plugin:for_all_commands(function(command)
if helpdb[command.name] then
command:set_help(helpdb[command.name])
end
end)
return plugin return plugin

32
plugins/plugins/help.lua Normal file
View File

@ -0,0 +1,32 @@
local discordia = require('discordia')
return {
["enable"] = {embed = {
title = "Enable plugin",
description = [[This command loads a plugin,
addng its commands to the command pool]],
fields = {
{name = "Usage:",value = "load <plugin-name>"},
{name = "Perms:",value = "Administrator, other (via ``rules --allow``)"}
},
color = discordia.Color.fromHex("ff5100").value
}},
["disable"] = {embed = {
title = "Disable a loaded plugin",
description = [[This commands unloads a previously loaded plugin,
removing its commands from the command pool]],
fields = {
{name = "Usage:",value = "unload <plugin-name>"},
{name = "Perms:",value = "Administrator, other (via ``rules --allow``)"}
},
color = discordia.Color.fromHex("ff5100").value
}},
["plugins"] = {embed = {
title = "View all known plugins",
description = [[This commmand prints info on loaded and unloaded plugins]],
fields = {
{name = "Usage:",value = "plugins"},
{name = "Perms:",value = "Administrator, other (via ``rules --allow``)"}
},
color = discordia.Color.fromHex("ff5100").value
}},
}

View File

@ -4,107 +4,80 @@ local plugin = plugin_c("pluginmanager")
local utilities = require("table-utils") local utilities = require("table-utils")
local generic_admin_template = { local generic_admin_template = {
args = {"string"}, args = {"string"},
perms = { perms = {
"administrator" "administrator"
}, },
} }
local enable = command("enable",utilities.overwrite(generic_admin_template,{ local enable = command("enable",utilities.overwrite(generic_admin_template,{
help = {embed = {
title = "Enable plugin",
description = [[This command loads a plugin,
adding its commands to the command pool]],
fields = {
{name = "Usage:",value = "load <plugin-name>"},
{name = "Perms:",value = "Administrator, other (via ``rules --allow``)"}
},
color = discordia.Color.fromHex("ff5100").value
}},
exec = function(msg,args,opts) exec = function(msg,args,opts)
local status,message = plugin_handler:load(args[1]) local status,message = plugin_handler:load(args[1])
local plugin_data = command_handler:get_commands_metadata().plugins local plugin_data = command_handler:get_metadata().plugins
local embed = { local embed = {
description = message, description = message,
color = discordia.Color.fromHex("ff5100").value, color = discordia.Color.fromHex("ff5100").value,
}
if status then
embed.fields = {
{name = "New commands:",value =
table.concat(plugin_data[args[1]] or {},", ").." "
}
} }
end if status then
msg:reply({embed = embed}) embed.fields = {
{name = "New commands:",value =
table.concat(plugin_data[args[1]] or {},", ").." "
}
}
end
msg:reply({embed = embed})
end end
})) }))
plugin:add_command(enable) plugin:add_command(enable)
local disable = command("disable",utilities.overwrite(generic_admin_template,{ local disable = command("disable",utilities.overwrite(generic_admin_template,{
help = {embed = {
title = "Disable a loaded plugin",
description = [[This commands unloads a previously loaded plugin,
removing its commands from the command pool]],
fields = {
{name = "Usage:",value = "unload <plugin-name>"},
{name = "Perms:",value = "Administrator, other (via ``rules --allow``)"}
},
color = discordia.Color.fromHex("ff5100").value
}},
exec = function(msg,args,opts) exec = function(msg,args,opts)
local plugin_data = command_handler:get_commands_metadata().plugins local plugin_data = command_handler:get_metadata().plugins
if not (args[1] == "plugins") then if not (args[1] == "plugins") then
local status,message = plugin_handler:unload(args[1]) local status,message = plugin_handler:unload(args[1])
local embed = { local embed = {
description = message, description = message,
color = discordia.Color.fromHex("ff5100").value, color = discordia.Color.fromHex("ff5100").value,
}
if status then
embed.fields = {
{name = "Removed commands:",value =
table.concat(plugin_data[args[1]] or {},", ").." "
} }
} if status then
embed.fields = {
{name = "Removed commands:",value =
table.concat(plugin_data[args[1]] or {},", ").." "
}
}
end
msg:reply({embed = embed})
else
msg:reply("TIME PARADOX")
end end
msg:reply({embed = embed})
else
msg:reply("TIME PARADOX")
end
end end
})) }))
plugin:add_command(disable) plugin:add_command(disable)
local plugins = command("plugins",utilities.overwrite(generic_admin_template,{ local plugins = command("plugins",utilities.overwrite(generic_admin_template,{
help = {embed = { args = {},
title = "View all known plugins", exec = function(msg,args,opts)
description = [[This commmand prints info on loaded and unloaded plugins]], local all_plugins = plugin_handler:list_loadable()
fields = { local unloaded_plugins = {}
{name = "Usage:",value = "plugins"}, local loaded_plugins = {}
{name = "Perms:",value = "Administrator, other (via ``rules --allow``)"} for k,v in pairs(all_plugins) do
} if not v.loaded then
}}, table.insert(unloaded_plugins,k)
args = {}, else
exec = function(msg,args,opts) table.insert(loaded_plugins,k)
local all_plugins = plugin_handler:list_loadable() end
local unloaded_plugins = {} end
local loaded_plugins = {} if #unloaded_plugins == 0 then
for k,v in pairs(all_plugins) do table.insert(unloaded_plugins," ")
if not v.loaded then end
table.insert(unloaded_plugins,k) msg:reply({embed={
else color = discordia.Color.fromHex("ff5100").value,
table.insert(loaded_plugins,k) fields = {
{name = "Loaded plugins",value = "``"..table.concat(loaded_plugins,"``,\n``").."``"},
{name = "Unloaded plugins",value = "``"..table.concat(unloaded_plugins,"``,\n``").."``"}
}
}})
end end
end
if #unloaded_plugins == 0 then
table.insert(unloaded_plugins," ")
end
msg:reply({embed={
color = discordia.Color.fromHex("ff5100").value,
fields = {
{name = "Loaded plugins",value = "``"..table.concat(loaded_plugins,"``,\n``").."``"},
{name = "Unloaded plugins",value = "``"..table.concat(unloaded_plugins,"``,\n``").."``"}
}
}})
end
})) }))
plugin:add_command(plugins) plugin:add_command(plugins)
plugin:load_helpdb(plugin_path.."help.lua")
return plugin return plugin

View File

@ -0,0 +1,42 @@
return {
["pivot"] = {embed={
title = "Select a pivot message to manipulate",
description = "Pivot is like a message selector which allows easy reaction manipulations",
fields = {
{name = "Usage: ",value = "pivot <message link>"},
{name = "Perms: ",valeu = "Administartor"}
}
}},
["role-toggle"] = {embed={
title = "Add a simple role switch to the pivot",
description = "Note: you cannot assign more than one role to a single reaction",
fields = {
{name = "Usage: ",value = "role-toggle <emoji> <role ping or role id>"},
{name = "Perms: ",value = "administrator"}
}
}},
["remove-reaction"] = {embed={
title = "Remove a reaction from a pivot",
description = "If you don't specify a reaction to remove, the entire pivot for the message is removed automatically",
fields = {
{name = "Usage: ",value = "remove-reaction <emoji>"},
{name = "Perms: ",value = "Administrator"}
}
}},
["toggle"] = {embed={
title = "Add a toggle that runs specific commands",
description = "Note: you cannot assign more than one action to a single reaction \n``$user`` gets replaced with the id of the user that interacted with the reaction.",
fields = {
{name = "Usage: ",value = "toggle <emoji> <command-on> <command-off>"},
{name = "Perms: ",value = "administrator"}
}
}},
["button"] = {embed={
title = "Add a button that runs specific command when pressed",
description = "Note: you cannot assign more than one action to a single reaction \n``$user`` gets replaced with the id of the user that interacted with the reaction.",
fields = {
{name = "Usage: ",value = "button <emoji> <command>"},
{name = "Perms: ",value = "administrator"}
}
}},
}

View File

@ -7,334 +7,295 @@ local segment = {}
segment.pivots = config segment.pivots = config
local getEmoji = function(id) local getEmoji = function(id)
local emoji = guild:getEmoji(id:match("(%d+)[^%d]*$")) local emoji = guild:getEmoji(id:match("(%d+)[^%d]*$"))
if emoji then if emoji then
return emoji return emoji
else else
return id return id
end end
end end
local function count(tab) local function count(tab)
local n = 0 local n = 0
for k,v in pairs(tab) do for k,v in pairs(tab) do
n = n + 1 n = n + 1
end end
return n return n
end end
local pivot = command("pivot",{ local pivot = command("pivot",{
help = {embed={ args = {
title = "Select a pivot message to manipulate", "messageLink"
description = "Pivot is like a message selector which allows easy reaction manipulations", },
fields = { perms = {
{name = "Usage: ",value = "pivot <message link>"}, "administrator"
{name = "Perms: ",valeu = "Administartor"} },
} exec = function(msg,args,opts)
}}, if segment.pivot and count(segment.pivot.buttons) == 0 then
args = { print("[REACTIONS] Deleting pivot: "..tostring(segment.pivot.message))
"messageLink" segment.pivots[segment.pivot.message] = nil
}, end
perms = { local message = args[1]
"administrator" if not message then
}, msg:reply("Couldn't find message with id "..args[2])
exec = function(msg,args,opts) return false
if segment.pivot and count(segment.pivot.buttons) == 0 then end
print("[REACTIONS] Deleting pivot: "..tostring(segment.pivot.message)) if not segment.pivots[message.id] then
segment.pivots[segment.pivot.message] = nil print("[REACTIONS] Creating pivot: "..tostring(message.id))
end segment.pivots[message.id] = {}
local message = args[1] segment.pivots[message.id].message = message.id
if not message then segment.pivots[message.id].channel = message.channel.id
msg:reply("Couldn't find message with id "..args[2]) segment.pivots[message.id].buttons = {}
return false end
end segment.pivot = segment.pivots[message.id]
if not segment.pivots[message.id] then return true
print("[REACTIONS] Creating pivot: "..tostring(message.id)) end
segment.pivots[message.id] = {} })
segment.pivots[message.id].message = message.id
segment.pivots[message.id].channel = message.channel.id
segment.pivots[message.id].buttons = {}
end
segment.pivot = segment.pivots[message.id]
return true
end
})
plugin:add_command(pivot) plugin:add_command(pivot)
local role_toggle = command("role-toggle",{ local role_toggle = command("role-toggle",{
help = {embed={ args = {
title = "Add a simple role switch to the pivot", "string",
description = "Note: you cannot assign more than one role to a single reaction", "role",
fields = { },
{name = "Usage: ",value = "role-toggle <emoji> <role ping or role id>"}, perms = {
{name = "Perms: ",value = "administrator"} "administrator"
} },
}}, exec = function(msg,args,opts)
args = { if not segment.pivot then
"string", msg:reply("Pivot not selected. Use "..globals.prefix.."pivot to select it and then try again")
"role", return false
}, end
perms = { local emoji = getEmoji(args[1])
"administrator" local channel = guild:getChannel(segment.pivot.channel)
}, if not channel then
exec = function(msg,args,opts) msg:reply("Something went horribly wrong, but it's not your fault. This incident has been (hopefully) reported")
if not segment.pivot then return false
msg:reply("Pivot not selected. Use "..globals.prefix.."pivot to select it and then try again") end
return false local message = channel:getMessage(segment.pivot.message)
end if not message then
local emoji = getEmoji(args[1]) msg:reply("Something went horribly wrong, but it's not your fault. This incident has been (hopefully) reported")
local channel = guild:getChannel(segment.pivot.channel) return false
if not channel then end
msg:reply("Something went horribly wrong, but it's not your fault. This incident has been (hopefully) reported") print("[REACTIONS] Adding role-toggle listener")
return false local grabEmoji = function(reaction)
end segment.pivot.buttons[tostring(reaction.emojiId or reaction.emojiName)] = {
local message = channel:getMessage(segment.pivot.message) type = "role-toggler",
if not message then role = tostring(args[2].id)
msg:reply("Something went horribly wrong, but it's not your fault. This incident has been (hopefully) reported") }
return false end
end message:removeReaction(emoji,client.user.id)
print("[REACTIONS] Adding role-toggle listener") client:once("reactionAdd",grabEmoji)
local grabEmoji = function(reaction) if not message:addReaction(emoji) then
segment.pivot.buttons[tostring(reaction.emojiId or reaction.emojiName)] = { client:removeListener("reactionAdd",grabEmoji)
type = "role-toggler", msg:reply("Couldn't add reaction - emoji might be invalid")
role = tostring(args[2].id) return false
} else
end return true
message:removeReaction(emoji,client.user.id) end
client:once("reactionAdd",grabEmoji) end
if not message:addReaction(emoji) then })
client:removeListener("reactionAdd",grabEmoji)
msg:reply("Couldn't add reaction - emoji might be invalid")
return false
else
return true
end
end
})
plugin:add_command(role_toggle) plugin:add_command(role_toggle)
local remove_reaction = command("remove-reaction",{ local remove_reaction = command("remove-reaction",{
help = {embed={ perms = {
title = "Remove a reaction from a pivot", "administrator"
description = "If you don't specify a reaction to remove, the entire pivot for the message is removed automatically", },
fields = { exec = function(msg,args,opts)
{name = "Usage: ",value = "remove-reaction <emoji>"}, local channel = guild:getChannel(segment.pivot.channel)
{name = "Perms: ",value = "Administrator"} if not channel then
} msg:reply("Something went horribly wrong, but it's not your fault. This incident has been (hopefully) reported")
}}, return false
perms = { end
"administrator" local message = channel:getMessage(segment.pivot.message)
}, if not message then
exec = function(msg,args,opts) msg:reply("Something went horribly wrong, but it's not your fault. This incident has been (hopefully) reported")
local channel = guild:getChannel(segment.pivot.channel) return false
if not channel then end
msg:reply("Something went horribly wrong, but it's not your fault. This incident has been (hopefully) reported") print("[REACTIONS] Removing reaction listener")
return false if args[1] then
end local emoji = getEmoji(args[1])
local message = channel:getMessage(segment.pivot.message) message:removeReaction(emoji,client.user.id)
if not message then segment.pivot.buttons[((type(emoji) == "table") and emoji.id) or emoji] = nil
msg:reply("Something went horribly wrong, but it's not your fault. This incident has been (hopefully) reported") return true
return false else
end message:clearReactions()
print("[REACTIONS] Removing reaction listener") segment.pivots[tostring(message.id)] = nil
if args[1] then segment.pivot = nil
local emoji = getEmoji(args[1]) return true
message:removeReaction(emoji,client.user.id) end
segment.pivot.buttons[((type(emoji) == "table") and emoji.id) or emoji] = nil end
return true })
else
message:clearReactions()
segment.pivots[tostring(message.id)] = nil
segment.pivot = nil
return true
end
end
})
plugin:add_command(remove_reaction) plugin:add_command(remove_reaction)
local toggle = command("toggle",{ local toggle = command("toggle",{
help = {embed={ args = {
title = "Add a toggle that runs specific commands", "string",
description = "Note: you cannot assign more than one action to a single reaction \n``$user`` gets replaced with the id of the user that interacted with the reaction.", "string",
fields = { "string",
{name = "Usage: ",value = "toggle <emoji> <command-on> <command-off>"}, },
{name = "Perms: ",value = "administrator"} perms = {
} "administrator"
}}, },
args = { exec = function(msg,args,opts)
"string", if not segment.pivot then
"string", msg:reply("Pivot not selected. Use "..globals.prefix.."pivot to select it and then try again")
"string", return false
}, end
perms = { local emoji = getEmoji(args[1])
"administrator" local channel = guild:getChannel(segment.pivot.channel)
}, if not channel then
exec = function(msg,args,opts) msg:reply("Something went horribly wrong, but it's not your fault. This incident has been (hopefully) reported")
if not segment.pivot then return false
msg:reply("Pivot not selected. Use "..globals.prefix.."pivot to select it and then try again") end
return false local message = channel:getMessage(segment.pivot.message)
end if not message then
local emoji = getEmoji(args[1]) msg:reply("Something went horribly wrong, but it's not your fault. This incident has been (hopefully) reported")
local channel = guild:getChannel(segment.pivot.channel) return false
if not channel then end
msg:reply("Something went horribly wrong, but it's not your fault. This incident has been (hopefully) reported") print("[REACTIONS] Adding toggle listener")
return false local grabEmoji = function(reaction)
end segment.pivot.buttons[tostring(reaction.emojiId or reaction.emojiName)] = {
local message = channel:getMessage(segment.pivot.message) type = "toggler",
if not message then on = args[2],
msg:reply("Something went horribly wrong, but it's not your fault. This incident has been (hopefully) reported") off = args[3],
return false }
end end
print("[REACTIONS] Adding toggle listener") message:removeReaction(emoji,client.user.id)
local grabEmoji = function(reaction) client:once("reactionAdd",grabEmoji)
segment.pivot.buttons[tostring(reaction.emojiId or reaction.emojiName)] = { if not message:addReaction(emoji) then
type = "toggler", client:removeListener("reactionAdd",grabEmoji)
on = args[2], msg:reply("Couldn't add reaction - emoji might be invalid")
off = args[3], return false
} else
end return true
message:removeReaction(emoji,client.user.id) end
client:once("reactionAdd",grabEmoji) end
if not message:addReaction(emoji) then })
client:removeListener("reactionAdd",grabEmoji)
msg:reply("Couldn't add reaction - emoji might be invalid")
return false
else
return true
end
end
})
plugin:add_command(toggle) plugin:add_command(toggle)
local button = command("button",{ local button = command("button",{
help = {embed={ args = {
title = "Add a button that runs specific command when pressed", "string",
description = "Note: you cannot assign more than one action to a single reaction \n``$user`` gets replaced with the id of the user that interacted with the reaction.", "string",
fields = { },
{name = "Usage: ",value = "button <emoji> <command>"}, perms = {
{name = "Perms: ",value = "administrator"} "administrator"
} },
}}, exec = function(msg,args,opts)
args = { if not segment.pivot then
"string", msg:reply("Pivot not selected. Use "..globals.prefix.."pivot to select it and then try again")
"string", return false
}, end
perms = { local emoji = getEmoji(args[1])
"administrator" local channel = guild:getChannel(segment.pivot.channel)
}, if not channel then
exec = function(msg,args,opts) msg:reply("Something went horribly wrong, but it's not your fault. This incident has been (hopefully) reported")
if not segment.pivot then return false
msg:reply("Pivot not selected. Use "..globals.prefix.."pivot to select it and then try again") end
return false local message = channel:getMessage(segment.pivot.message)
end if not message then
local emoji = getEmoji(args[1]) msg:reply("Something went horribly wrong, but it's not your fault. This incident has been (hopefully) reported")
local channel = guild:getChannel(segment.pivot.channel) return false
if not channel then end
msg:reply("Something went horribly wrong, but it's not your fault. This incident has been (hopefully) reported") print("[REACTIONS] Adding button listener")
return false local grabEmoji = function(reaction)
end segment.pivot.buttons[tostring(reaction.emojiId or reaction.emojiName)] = {
local message = channel:getMessage(segment.pivot.message) type = "button",
if not message then on = args[2],
msg:reply("Something went horribly wrong, but it's not your fault. This incident has been (hopefully) reported") }
return false end
end message:removeReaction(emoji,client.user.id)
print("[REACTIONS] Adding button listener") client:once("reactionAdd",grabEmoji)
local grabEmoji = function(reaction) if not message:addReaction(emoji) then
segment.pivot.buttons[tostring(reaction.emojiId or reaction.emojiName)] = { client:removeListener("reactionAdd",grabEmoji)
type = "button", msg:reply("Couldn't add reaction - emoji might be invalid")
on = args[2], return false
} else
end return true
message:removeReaction(emoji,client.user.id) end
client:once("reactionAdd",grabEmoji) end
if not message:addReaction(emoji) then })
client:removeListener("reactionAdd",grabEmoji)
msg:reply("Couldn't add reaction - emoji might be invalid")
return false
else
return true
end
end
})
plugin:add_command(button) plugin:add_command(button)
local buttonOn = function(message,hash,userID) local buttonOn = function(message,hash,userID)
if not message then if not message then
log("ERROR","Attempted to find a deleted message") log("ERROR","Attempted to find a deleted message")
return return
end end
if segment.pivots[tostring(message.id)] and userID ~= client.user.id then if segment.pivots[tostring(message.id)] and userID ~= client.user.id then
local current_pivot = segment.pivots[tostring(message.id)] local current_pivot = segment.pivots[tostring(message.id)]
if current_pivot.buttons[tostring(hash)] then if current_pivot.buttons[tostring(hash)] then
local current_button = current_pivot.buttons[tostring(hash)] local current_button = current_pivot.buttons[tostring(hash)]
local new_content local new_content
if current_button.on then if current_button.on then
new_content = current_button.on:gsub("%$user",userID) new_content = current_button.on:gsub("%$user",userID)
end end
if current_button.type == "role-toggler" then if current_button.type == "role-toggler" then
guild:getMember(userID):addRole(current_button.role) guild:getMember(userID):addRole(current_button.role)
end end
if current_button.type == "toggler" then if current_button.type == "toggler" then
command_handler:handle(fake_message(message,{ command_handler:handle(fake_message(message,{
delete = function() end, delete = function() end,
content = new_content content = new_content
})) }))
end end
if current_button.type == "button" then if current_button.type == "button" then
command_handler:handle(fake_message(message,{ command_handler:handle(fake_message(message,{
delete = function() end, delete = function() end,
content = new_content content = new_content
})) }))
end end
end
end end
end
end end
local buttonOff = function(message,hash,userID) local buttonOff = function(message,hash,userID)
if not message then if not message then
log("ERROR","Attempted to find a deleted message") log("ERROR","Attempted to find a deleted message")
return return
end end
if segment.pivots[tostring(message.id)] and userID ~= client.user.id then if segment.pivots[tostring(message.id)] and userID ~= client.user.id then
local current_pivot = segment.pivots[tostring(message.id)] local current_pivot = segment.pivots[tostring(message.id)]
if current_pivot.buttons[tostring(hash)] then if current_pivot.buttons[tostring(hash)] then
local current_button = current_pivot.buttons[tostring(hash)] local current_button = current_pivot.buttons[tostring(hash)]
local new_content local new_content
if current_button.off then if current_button.off then
new_content = current_button.off:gsub("%$user",userID) new_content = current_button.off:gsub("%$user",userID)
end end
if current_button.type == "role-toggler" then if current_button.type == "role-toggler" then
guild:getMember(userID):removeRole(current_button.role) guild:getMember(userID):removeRole(current_button.role)
end end
if current_button.type == "toggler" then if current_button.type == "toggler" then
command_handler:handle(fake_message(message,{ command_handler:handle(fake_message(message,{
delete = function() end, delete = function() end,
content = new_content content = new_content
})) }))
end end
end
end end
end
end end
events:on("reactionAdd",function(reaction,userID) events:on("reactionAdd",function(reaction,userID)
local message = reaction.message local message = reaction.message
local hash = tostring(reaction.emojiId or reaction.emojiName) local hash = tostring(reaction.emojiId or reaction.emojiName)
buttonOn(message,hash,userID) buttonOn(message,hash,userID)
end) end)
events:on("reactionRemove",function(reaction,userID) events:on("reactionRemove",function(reaction,userID)
local message = reaction.message local message = reaction.message
local hash = tostring(reaction.emojiId or reaction.emojiName) local hash = tostring(reaction.emojiId or reaction.emojiName)
buttonOff(message,hash,userID) buttonOff(message,hash,userID)
end) end)
events:on("reactionAddUncached",function(channelId,messageId,hash,userId) events:on("reactionAddUncached",function(channelId,messageId,hash,userId)
local message = client:getChannel(channelId):getMessage(messageId) local message = client:getChannel(channelId):getMessage(messageId)
local hash = tostring(hash) local hash = tostring(hash)
buttonOn(message,hash,userId) buttonOn(message,hash,userId)
end) end)
events:on("reactionRemoveUncached",function(channelId,messageId,hash,userId) events:on("reactionRemoveUncached",function(channelId,messageId,hash,userId)
local message = client:getChannel(channelId):getMessage(messageId) local message = client:getChannel(channelId):getMessage(messageId)
local hash = tostring(hash) local hash = tostring(hash)
buttonOff(message,hash,userId) buttonOff(message,hash,userId)
end) end)
plugin:load_helpdb(plugin_path.."help.lua")
return plugin return plugin

View File

@ -0,0 +1,5 @@
return {
["droleadd"] = "Add a default role to assign for new users",
["droledel"] = "Remove a role from the list of default roles",
["drolelist"] = "List all default roles",
}

View File

@ -9,19 +9,17 @@ client:on("memberJoin",function(member)
end) end)
local droleadd = command("droleadd",{ local droleadd = command("droleadd",{
help = "Add a default role to assign for new users", usage = "droleadd <role>",
usage = "droleadd <role>", perms = {"administrator"},
perms = {"administrator"}, args = {
args = { "role"
"role" },
}, exec = function(msg,args,opts)
exec = function(msg,args,opts) table.insert(config.default_roles,args[1].id)
table.insert(config.default_roles,args[1].id) msg:reply("Added role "..args[1].name.." to default roles list")
msg:reply("Added role "..args[1].name.." to default roles list") end,
end,
}) })
local droledel = command("droledel",{ local droledel = command("droledel",{
help = "Remove a role from the list of default roles",
usage = "droledel <role>", usage = "droledel <role>",
perms = {"administrator"}, perms = {"administrator"},
args = { args = {
@ -37,7 +35,6 @@ local droledel = command("droledel",{
end end
}) })
local drolelist = command("drolelist", { local drolelist = command("drolelist", {
help = "List all default roles",
usage = "drolelist", usage = "drolelist",
perms = {"administrator"}, perms = {"administrator"},
exec = function(msg,args,opts) exec = function(msg,args,opts)
@ -56,5 +53,6 @@ local drolelist = command("drolelist", {
plugin:add_command(droleadd) plugin:add_command(droleadd)
plugin:add_command(droledel) plugin:add_command(droledel)
plugin:add_command(drolelist) plugin:add_command(drolelist)
plugin:load_helpdb(plugin_path.."help.lua")
return plugin return plugin

46
plugins/security/help.lua Normal file
View File

@ -0,0 +1,46 @@
return {
["grant-role"] = {embed={
title = "Grant a role to the user",
description = "If <user> is not provided, the caller is assumed as the <user> argument.",
fields = {
{name = "Usage:",value = "grant-role <role id> [<user>]"},
{name = "Perms:",value = "administrator"},
{name = "Options:",value = "-q - quiet (don't print the result)"}
}
}},
["revoke-role"] = {embed={
title = "Revoke a role from the user",
description = "If <user> is not provided, the caller is assumed as the <user> argument.",
fields = {
{name = "Usage:",value = "revoke-role <role id> [<user>]"},
{name = "Perms:",value = "administrator"},
{name = "Options:",value = "-q - quiet (don't print the result)"}
}
}},
["warn"] = {embed={
title = "Warn a user",
description = "nuff said.",
fields = {
{name = "Usage:",value = "warn <user> <reason>"},
{name = "Perms:",value = "kickMembers"},
}
}},
["infractions"] = { embed = {
title = "List user infractions",
description = "Infractions include kicks, bans, mutes and warnings.",
fields = {
{name = "Usage: ", value = "infractions <user> [<startfrom>]"},
{name = "Perms: ", value = "kickMembers"},
{name = "Options: ", value = "--type=(warn default,ban,kick)"}
}
}},
["purge"] = { embed = {
title = "Purge a number of messages",
description = "nuff said.",
fields = {
{name = "Usage: ", value = "purge <number>"},
{name = "Perms: ", value = "manageMessages"},
{name = "Options: ", value = "`--regex (regex)` - match content against regex; \n`--user (user)` - match user against id/name; \n`-w` - match webhook messages"}
}
}},
}

View File

@ -17,15 +17,6 @@ CREATE TABLE infractions(id INTEGER PRIMARY KEY AUTOINCREMENT, user TEXT, desc T
end end
local grantrole = command("grant-role",{ local grantrole = command("grant-role",{
help = {embed={
title = "Grant a role to the user",
description = "If <user> is not provided, the caller is assumed as the <user> argument.",
fields = {
{name = "Usage:",value = "grant-role <role id> [<user>]"},
{name = "Perms:",value = "administrator"},
{name = "Options:",value = "-q - quiet (don't print the result)"}
}
}},
perms = { perms = {
"administrator" "administrator"
}, },
@ -41,15 +32,6 @@ local grantrole = command("grant-role",{
plugin:add_command(grantrole) plugin:add_command(grantrole)
local revokerole = command("revoke-role",{ local revokerole = command("revoke-role",{
help = {embed={
title = "Revoke a role from the user",
description = "If <user> is not provided, the caller is assumed as the <user> argument.",
fields = {
{name = "Usage:",value = "revoke-role <role id> [<user>]"},
{name = "Perms:",value = "administrator"},
{name = "Options:",value = "-q - quiet (don't print the result)"}
}
}},
perms = { perms = {
"administrator" "administrator"
}, },
@ -65,14 +47,6 @@ local revokerole = command("revoke-role",{
plugin:add_command(revokerole) plugin:add_command(revokerole)
local warn = command("warn",{ local warn = command("warn",{
help = {embed={
title = "Warn a user",
description = "nuff said.",
fields = {
{name = "Usage:",value = "warn <user> <reason>"},
{name = "Perms:",value = "kickMembers"},
}
}},
perms = { perms = {
"kickMembers" "kickMembers"
}, },
@ -99,15 +73,6 @@ local warn = command("warn",{
plugin:add_command(warn) plugin:add_command(warn)
local infractions = command("infractions", { local infractions = command("infractions", {
help = { embed = {
title = "List user infractions",
description = "Infractions include kicks, bans, mutes and warnings.",
fields = {
{name = "Usage: ", value = "infractions <user> [<startfrom>]"},
{name = "Perms: ", value = "kickMembers"},
{name = "Options: ", value = "--type=(warn default,ban,kick)"}
}
}},
perms = { perms = {
"kickMembers" "kickMembers"
}, },
@ -150,15 +115,6 @@ local infractions = command("infractions", {
plugin:add_command(infractions) plugin:add_command(infractions)
local purge = command("purge",{ local purge = command("purge",{
help = { embed = {
title = "Purge a number of messages",
description = "nuff said.",
fields = {
{name = "Usage: ", value = "purge <number>"},
{name = "Perms: ", value = "manageMessages"},
{name = "Options: ", value = "`--regex (regex)` - match content against regex; \n`--user (user)` - match user against id/name; \n`-w` - match webhook messages"}
}
}},
perms = { perms = {
"manageMessages" "manageMessages"
}, },
@ -210,5 +166,5 @@ local purge = command("purge",{
end end
}) })
plugin:add_command(purge) plugin:add_command(purge)
plugin:load_helpdb(plugin_path.."help.lua")
return plugin return plugin

37
plugins/tools/help.lua Normal file
View File

@ -0,0 +1,37 @@
return {
["dice"] = "Simulates a dice throw, prints the value of each die",
["cards"] = "Draw a specific amount of playing cards and display them",
["calculate"] = {embed={
title = "Calculate an expression",
description = "Calculates maths using libqalculate. https://qalculate.github.io/ for more info",
fields = {
{name = "Usage",value = [[calculate "<expression>"]]},
{name = "Perms: ",value = "All"},
{name = "Options",value = "`-e` - exact mode"}
}
}},
["pfp"] = "Show the profile picture of a user, or if none is specified, of yourself",
["markpov"] = { embed = {
title = "Generate some text using markov chains",
description = "Generates text using the markov chain rule applied to a predefined set of words",
fields = {
{name = "Usage: ", value = "markov <text to start with>"},
{name = "Options: ", value = [[
--preseteset> - Select a text preset. Currently available:
``defaul- Generated from a wikipedia page on markov chains
``freud`The largest one, generated from a page on Sigmund Freud
``reddit Generated from reddit comments
``travist`` - Generated from transcript of a video by PlasticPills on travis scott burger
]] },
{name = "Perms: ", value = "any"}
}
}},
["embed"] = {embed={
title = "Convert JSON objects into embeds",
description = "If you've worked with discord.js before, this might be simple. If you haven't, then check out https://github.com/yessiest/SuppaBot/wiki/Embeds",
fields = {
{name = "Usage",value = [[embed {code}]]},
{name = "Perms: ",value = "All"},
}
}},
}

View File

@ -28,152 +28,127 @@ function to_bit_string(num)
end end
local flip = command("flip",{ local flip = command("flip",{
help = "Flips a coin, obv.", help = "Flips a coin, obv.",
usage = "flip", usage = "flip",
exec = function(msg,args,opts) exec = function(msg,args,opts)
local coin = math.random(1,100)%2 local coin = math.random(1,100)%2
if coin > 0 then if coin > 0 then
msg:reply("Heads") msg:reply("Heads")
else else
msg:reply("Tails") msg:reply("Tails")
end end
end, end,
}) })
plugin:add_command(flip) plugin:add_command(flip)
local dice = command("dice",{ local dice = command("dice",{
help = "Simulates a dice throw, prints the value of each die", usage = "dice <2d6,d30,d20+4,etc>",
usage = "dice <2d6,d30,d20+4,etc>", exec = function(msg,args,opts)
exec = function(msg,args,opts) local out = {embed = {
local out = {embed = { fields = {},
fields = {}, footer = {
footer = { text = 0
text = 0 }
} }}
}} for I = 1,#args do
for I = 1,#args do local v = args[I]
local v = args[I] for J = 1,(v:match("(%d+)d%d+") or 1) do
for J = 1,(v:match("(%d+)d%d+") or 1) do local value = math.random(1,tonumber(v:match("d(%d+)")))
local value = math.random(1,tonumber(v:match("d(%d+)"))) if v:find("d%d+[%+%-]%d+") then
if v:find("d%d+[%+%-]%d+") then if v:match("d%d+([%+%-])") == "+" then
if v:match("d%d+([%+%-])") == "+" then value = value + tonumber(v:match("d%d+[%+%-](%d+)"))
value = value + tonumber(v:match("d%d+[%+%-](%d+)")) else
else value = value - tonumber(v:match("d%d+[%+%-](%d+)"))
value = value - tonumber(v:match("d%d+[%+%-](%d+)")) end
end end
end out.embed.fields[#out.embed.fields+1] = {name = "d"..v:match("d(%d+)"),value = value, inline = true}
out.embed.fields[#out.embed.fields+1] = {name = "d"..v:match("d(%d+)"),value = value, inline = true} out.embed.footer.text = out.embed.footer.text+value
out.embed.footer.text = out.embed.footer.text+value if #out.embed.fields >= 25 then
if #out.embed.fields >= 25 then break
break
end
end end
if #out.embed.fields >= 25 then end
break if #out.embed.fields >= 25 then
end break
end end
out.embed.footer.text = "Total: "..out.embed.footer.text end
msg:reply(out) out.embed.footer.text = "Total: "..out.embed.footer.text
end, msg:reply(out)
end,
}) })
plugin:add_command(dice) plugin:add_command(dice)
local cards = command("cards",{ local cards = command("cards",{
help = "Draw a specific amount of playing cards and display them", usage = "cards <amount>",
usage = "cards <amount>", args = {"number"},
args = {"number"}, exec = function(msg,args,opts)
exec = function(msg,args,opts) local out = {embed = {
local out = {embed = { fields = {}
fields = {} }}
}} local random = math.random
local random = math.random for I = 1,(args[1] < 25 and args[1]) or 25 do
for I = 1,(args[1] < 25 and args[1]) or 25 do local suits = {"spades","clubs","diamonds","hearts"}
local suits = {"spades","clubs","diamonds","hearts"} local values = {
local values = { "A","1","2","3","4","5",
"A","1","2","3","4","5", "6","7","8","9","J","Q","K"
"6","7","8","9","J","Q","K" }
} out.embed.fields[I] = {name = "card", value = " :"..suits[random(1,4)]..":"..values[random(1,11)].." ",inline = true}
out.embed.fields[I] = {name = "card", value = " :"..suits[random(1,4)]..":"..values[random(1,11)].." ",inline = true} end
end msg:reply(out)
msg:reply(out) end,
end,
}) })
plugin:add_command(cards) plugin:add_command(cards)
local calculate = command("calculate",{ local calculate = command("calculate",{
help = "Calculates maths using libqalculate. https://qalculate.github.io/ for more info", args = {
usage = [[ "string"
calculate "<expression>" },
``-e`` - exact mode exec = function(msg,args,opts)
]], msg:reply(qalculator.qalc(args[1],opts["e"]))
args = { end,
"string"
},
exec = function(msg,args,opts)
msg:reply(qalculator.qalc(args[1],opts["e"]))
end,
}) })
plugin:add_command(calculate) plugin:add_command(calculate)
local pfp = command("pfp",{ local pfp = command("pfp",{
help = "Show the profile picture of a user, or if none is specified, of yourself", exec = function(msg,args,opts)
usage = "pfp <user or none>", local user = client:getUser((args[1] or ""):match("%d+"))
exec = function(msg,args,opts) if user then
local user = client:getUser((args[1] or ""):match("%d+")) msg:reply(user:getAvatarURL().."?size=2048")
if user then else
msg:reply(user:getAvatarURL().."?size=2048") msg:reply(msg.author:getAvatarURL().."?size=2048")
else end
msg:reply(msg.author:getAvatarURL().."?size=2048") end,
end
end,
}) })
plugin:add_command(pfp) plugin:add_command(pfp)
local markov = command("markov",{ local markov = command("markov",{
help = { embed = { exec = function(msg,args,opts)
title = "Generate some text using markov chains", local preset,code,err = import("file").readJSON("./resources/"..(opts["preset"] or "default"):match("%w+")..".json",{system_failed = true})
description = "Generates text using the markov chain rule applied to a predefined set of words", if preset.system_failed then
fields = { msg:reply("No such preset")
{name = "Usage: ", value = "markov <text to start with>"}, return
{name = "Options: ", value = [[
--preset=<preset> - Select a text preset. Currently available:
``default`` - Generated from a wikipedia page on markov chains
``freud`` - The largest one, generated from a page on Sigmund Freud
``reddit`` - Generated from reddit comments
``travisscott`` - Generated from transcript of a video by PlasticPills on travis scott burger
]] },
{name = "Perms: ", value = "any"}
}
}},
exec = function(msg,args,opts)
local preset,code,err = import("file").readJSON("./resources/"..(opts["preset"] or "default"):match("%w+")..".json",{system_failed = true})
if preset.system_failed then
msg:reply("No such preset")
return
end
markov_instance:load_state(preset)
local output = markov_instance:run("The",100)
msg:reply(output)
end end
markov_instance:load_state(preset)
local output = markov_instance:run("The",100)
msg:reply(output)
end
}) })
plugin:add_command(markov) plugin:add_command(markov)
local embed = command("embed",{ local embed = command("embed",{
help = "Convert JSON objects into embeds", args = {
usage = "If you've worked with discord.js before, this might be simple. If you haven't, then check out https://github.com/yessiest/SuppaBot/wiki/Embeds", "string"
args = { },
"string" exec = function(msg,args,opts)
}, local embed = msg.content:match("{.+}")
exec = function(msg,args,opts) if not embed then
local embed = msg.content:match("{.+}") msg:reply("Invalid embed object")
if not embed then return
msg:reply("Invalid embed object")
return
end
local embed_obj,code,err = import("json").decode(embed)
if not embed_obj then
msg:reply("Error while decoding JSON object: "..tostring(err))
return
end
if pcall(discordia.Color.fromHex,embed_obj.color) then
embed_obj.color = discordia.Color.fromHex(embed_obj.color).value
end
msg:reply({embed = embed_obj})
end end
local embed_obj,code,err = import("json").decode(embed)
if not embed_obj then
msg:reply("Error while decoding JSON object: "..tostring(err))
return
end
if pcall(discordia.Color.fromHex,embed_obj.color) then
embed_obj.color = discordia.Color.fromHex(embed_obj.color).value
end
msg:reply({embed = embed_obj})
end
}) })
plugin:add_command(embed) plugin:add_command(embed)
plugin:load_helpdb(plugin_path.."help.lua")
return plugin return plugin