Compare commits

...

5 Commits

5 changed files with 95 additions and 26 deletions

View File

@ -7,7 +7,7 @@ local command = class("Command")
local acl = import("classes.command-acl") local acl = import("classes.command-acl")
local discordia = import("discordia") local discordia = import("discordia")
function command:__init(name,callback) function command:__init(name,callback)
assert(name:match("^[-_%w]+$"),"Name can only contain alphanumeric characters, underscores or dashes") assert(name:match("^%S+$"),"Name cannot contain any space characters")
self.rules = acl() self.rules = acl()
self.name = name self.name = name
self.timer = discordia.Date():toMilliseconds() self.timer = discordia.Date():toMilliseconds()

@ -1 +1 @@
Subproject commit 23fcea17c2eb380b6a6b1ba848d5bc7ebdc38b05 Subproject commit 8a1906df7a402349ff7b083e59cf17223363f59b

View File

@ -13,25 +13,64 @@ local events = {
event = {} event = {}
} }
local exec = function(v,command) -- timer threads are not API-friendly so we need to call certain functions
-- in context of a discordia emitter.
sync_emitter:on("execContext",function(comm)
comm()
end)
exec = function(v,command,tried)
local channel = client:getChannel(v.channel) local channel = client:getChannel(v.channel)
if not channel then if not channel then
log("ERROR","Unable to retrieve event channel: "..tostring(v.channel)) log("ERROR","Unable to retrieve event channel: "..tostring(v.channel))
log("ERROR","Failed event: "..command) log("ERROR","Failed event: "..command.."\nChannel Object: "..tostring(channel))
return if not tried then
log("INFO","Retrying...")
timer.setTimeout(2000,function()
sync_emitter:emit("execContext",function()
exec(v,command,true)
end)
end)
return
else
log("ERROR","Tried 2 times to run the event and failed.")
return
end
end end
local msg = channel:getMessage(v.id) local msg = channel:getMessage(v.id)
if not msg then if not msg then
log("ERROR","Unable to retrieve event message: "..tostring(v.id)) log("ERROR","Unable to retrieve event message: "..tostring(v.id))
log("ERROR","Failed event: "..command) log("ERROR","Failed event: "..command.."\nMessage object: "..tostring(msg).."\nChannel: "..tostring(channel.id))
return if not tried then
log("INFO","Retrying...")
timer.setTimeout(2000,function()
sync_emitter:emit("execContext",function()
exec(v,command,true)
end)
end)
return
else
log("ERROR","Tried 2 times to run the event and failed.")
return
end
end end
--forcefully caching the goddamn member --forcefully caching the goddamn member
local member = msg.guild:getMember(v.user) local member = msg.guild:getMember(v.user)
if not member then if not member then
log("ERROR","Unable to retrieve event creator: "..tostring(v.user)) log("ERROR","Unable to retrieve event creator: "..tostring(v.user))
log("ERROR","Failed event: "..command) log("ERROR","Failed event: "..command)
return if not tried then
log("INFO","Retrying...")
timer.setTimeout(2000,function()
sync_emitter:emit("execContext",function()
exec(v,command,true)
end)
end)
return
else
log("ERROR","Tried 2 times to run the event and failed.")
return
end
end end
command_handler:handle(fake_message(msg,{ command_handler:handle(fake_message(msg,{
delete = function() end, delete = function() end,
@ -157,7 +196,7 @@ local remove_user_event = function(user_id,id)
return false return false
end end
sync_emitter:on("createEventEntry",function(k,v,timer,evname) register_event = function(k,v,timer,evname)
local channel = client:getChannel(v.channel) local channel = client:getChannel(v.channel)
if channel then if channel then
local message = channel:getMessage(v.id) local message = channel:getMessage(v.id)
@ -178,25 +217,26 @@ sync_emitter:on("createEventEntry",function(k,v,timer,evname)
log("ERROR","No message with id "..v.id) log("ERROR","No message with id "..v.id)
log("ERROR","Event id: "..k..".\nEvent description: ") log("ERROR","Event id: "..k..".\nEvent description: ")
print(v.comm) print(v.comm)
sync_emitter:emit("eventEntryCreated",false,k) return false,k
end end
else else
log("ERROR","No channel with id "..v.channel) log("ERROR","No channel with id "..v.channel)
log("ERROR","Event id: "..k..".\nEvent description: ") log("ERROR","Event id: "..k..".\nEvent description: ")
print(v.comm) print(v.comm)
sync_emitter:emit("eventEntryCreated",false,k) return false,k
end end
sync_emitter:emit("eventEntryCreated",true,k) return true,k
end) end
-- load timer events -- load timer events
for k,v in pairs(config.events.timer) do for k,v in pairs(config.events.timer) do
sync_emitter:emit("createEventEntry",k,v,true) local ev,hash = register_event(k,v,true)
local cor, ev, hash = sync_emitter:waitFor("eventEntryCreated") if (not ev) then
if (not cor) or (not ev) then log("INFO","Retrying event "..k.." in 2 seconds")
log("INFO","Retrying in 2 seconds")
timer.setTimeout(2000,function() timer.setTimeout(2000,function()
sync_emitter:emit("createEventEntry",k,v,true) sync_emitter:emit("execContext",function()
register_event(k,v)
end)
end) end)
end end
end end
@ -205,12 +245,13 @@ end
for _,evtype in pairs(config.events.event) do for _,evtype in pairs(config.events.event) do
events.event[_] = {} events.event[_] = {}
for k,v in pairs(evtype) do for k,v in pairs(evtype) do
sync_emitter:emit("createEventEntry",k,v,false,_) local ev,hash = register_event(k,v,true)
local cor,ev,hash = sync_emitter:waitFor("eventEntryCreated") if (not ev) then
if (not cor) or (not ev) then log("INFO","Retrying event "..k.." in 2 seconds")
log("INFO","Retrying in 2 seconds")
timer.setTimeout(2000,function() timer.setTimeout(2000,function()
sync_emitter:emit("createEventEntry",k,v,false,_) sync_emitter:emit("execContext",function()
register_event(k,v)
end)
end) end)
end end
end end
@ -328,7 +369,7 @@ timer:on("min",function()
for k,v in pairs(events.timer) do for k,v in pairs(events.timer) do
local status,command = v.comm(os.date("*t")) local status,command = v.comm(os.date("*t"))
if status then if status then
exec(v,command) sync_emitter:emit("executeCommand",v,command)
if v.type == "onetime" then if v.type == "onetime" then
events.timer[k] = nil events.timer[k] = nil
config.events.timer[k] = nil config.events.timer[k] = nil

View File

@ -7,7 +7,12 @@ return {
fields = { fields = {
{name = "Usage",value = [[calculate "<expression>"]]}, {name = "Usage",value = [[calculate "<expression>"]]},
{name = "Perms: ",value = "All"}, {name = "Perms: ",value = "All"},
{name = "Options",value = "`-e` - exact mode"} {name = "Options",value = [[
`-e` - exact mode (try to be as exact as possible)
`-i` - interval mode (imprecise numbers will be calculated using variance formula)
`-f` - factorize mode (factorize result, default behaviour is to expand result)
`-o` - output only (don't show embed and messages)
]]}
} }
}}, }},
["pfp"] = "Show the profile picture of a user, or if none is specified, of yourself", ["pfp"] = "Show the profile picture of a user, or if none is specified, of yourself",

View File

@ -104,7 +104,30 @@ local calculate = command("calculate",{
"string" "string"
}, },
exec = function(msg,args,opts) exec = function(msg,args,opts)
msg:reply(qalculator.qalc(table.concat(args," "),opts["e"])) local e,i,f = opts["e"],opts["i"],opts["f"]
local result = {embed = {
title = "Result",
fields = {
{name = "Value: ",value = nil},
},
footer = {
text = "Powered by libqalculate"
},
color = discordia.Color.fromHex("7A365F").value
}}
local value,err = qalculator.qalc(table.concat(args," "),e,i,f)
result.embed.fields[1].value = "```"..value.."```"
if opts["o"] then
msg:reply(value)
return
end
if #err > 0 then
result.embed.fields[2] = {
name = "Messages: ",
value = "```"..table.concat(err,"\n").."```"
}
end
msg:reply(result)
end, end,
}) })
plugin:add_command(calculate) plugin:add_command(calculate)