owobot/internal/systems/plugins/api.go

108 lines
2.3 KiB
Go

package plugins
import (
"sync"
"github.com/bwmarrin/discordgo"
"github.com/dop251/goja"
"go.elara.ws/logger/log"
"go.elara.ws/owobot/internal/db"
"go.elara.ws/owobot/internal/util"
)
type lockableRuntime struct {
*sync.Mutex
*goja.Runtime
}
// Plugins is a list of plugins
var Plugins []Plugin
// Plugin represents an owobot plugin
type Plugin struct {
Info db.PluginInfo
Commands []Command
VM lockableRuntime
api *owobotAPI
}
// Command represents a plugin command
type Command struct {
Name string
Desc string
Usage goja.Value
OnExec goja.Value
Permissions []int64
Subcommands []Command
}
func (c Command) usage() string {
if c.Usage == nil {
return ""
} else {
return c.Usage.String()
}
}
type owobotAPI struct {
PluginInfo db.PluginInfo
Init goja.Value
OnEnable goja.Value
OnDisable goja.Value
Commands []Command
path string
vm lockableRuntime
}
func (oa *owobotAPI) Enabled(guildID string) bool {
return pluginEnabled(guildID, oa.PluginInfo.Name)
}
func (oa *owobotAPI) Respond(s *discordgo.Session, i *discordgo.Interaction, content string) error {
return util.Respond(s, i, content)
}
func (oa *owobotAPI) RespondEphemeral(s *discordgo.Session, i *discordgo.Interaction, content string) error {
return util.RespondEphemeral(s, i, content)
}
// On adds an event handler function for the given event type
func (oa *owobotAPI) On(eventType string, fn goja.Value) {
if !oa.PluginInfo.IsValid() {
log.Warn("No plugin information provided, ignoring handler registration.").Str("path", oa.path).Send()
return
}
callable, ok := goja.AssertFunction(fn)
if !ok {
log.Warn("Value passed to handler registrar is not a function, ignoring.").
Str("plugin", oa.PluginInfo.Name).
Str("event-type", eventType).
Send()
return
}
handlersMtx.Lock()
defer handlersMtx.Unlock()
this := oa.vm.ToValue(oa)
handlerMap[eventType] = append(handlerMap[eventType], Handler{
PluginName: oa.PluginInfo.Name,
Func: func(s *discordgo.Session, data any) {
oa.vm.Lock()
defer oa.vm.Unlock()
_, err := callable(this, oa.vm.ToValue(s), oa.vm.ToValue(data))
if err != nil {
log.Error("Exception thrown in plugin function").
Str("plugin", oa.PluginInfo.Name).
Str("event-type", eventType).
Err(err).
Send()
}
},
})
}