ZeroBot-Plugin/dyloader/scan.go
2021-10-13 18:39:54 +08:00

103 lines
2.3 KiB
Go

// Package dyloader 动态插件加载器
package dyloader
import (
"io/fs"
"path/filepath"
"strings"
"time"
"github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/extension"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/dyloader/plugin"
)
var typeIsSo bool
var visited bool
var pluginsmap = make(map[string]*plugin.Plugin)
func init() {
zero.OnCommand("刷新插件", zero.SuperUserPermission).SetBlock(true).FirstPriority().
Handle(func(ctx *zero.Ctx) {
err := scan()
if err != nil {
ctx.SendChain(message.Text("Error: " + err.Error()))
} else {
ctx.SendChain(message.Text("成功!"))
}
})
zero.OnCommand("卸载插件", zero.SuperUserPermission).SetBlock(true).FirstPriority().
Handle(func(ctx *zero.Ctx) {
model := extension.CommandModel{}
_ = ctx.Parse(&model)
_, ok := control.Lookup(model.Args)
if ok {
t := ".dll"
if typeIsSo {
t = ".so"
}
target := "plugin_" + model.Args + t
logrus.Debugln("[dyloader] target:", target)
p, ok := pluginsmap[target]
if ok {
err := plugin.Close(p)
control.Delete(model.Args)
delete(pluginsmap, target)
if err != nil {
ctx.SendChain(message.Text("Error: " + err.Error()))
} else {
ctx.SendChain(message.Text("成功!"))
}
} else {
ctx.SendChain(message.Text("没有这个插件!"))
}
}
})
go func() {
time.Sleep(time.Second * 2)
_ = scan()
}()
}
func scan() error {
return filepath.WalkDir("plugins/", load)
}
func load(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
n := d.Name()
if !visited {
if strings.HasSuffix(n, ".so") {
typeIsSo = true
visited = true
} else if strings.HasSuffix(n, ".dll") {
visited = true
}
}
if strings.HasSuffix(n, ".so") || strings.HasSuffix(n, ".dll") {
target := path[strings.LastIndex(path, "/")+1:]
logrus.Debugln("[dyloader] target:", target)
_, ok := pluginsmap[target]
if !ok {
p, err := plugin.Open(path)
if err == nil {
logrus.Infoln("[dyloader]加载插件", path, "成功")
pluginsmap[target] = p
}
if err != nil {
logrus.Errorln("[dyloader]加载插件", path, "错误:", err)
}
}
}
return nil
}