mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-20 06:20:08 +08:00
新增多功能抽签插件 (#606)
This commit is contained in:
parent
7b27bc8f7a
commit
1550cb7fcc
18
README.md
18
README.md
@ -656,6 +656,24 @@ print("run[CQ:image,file="+j["img"]+"]")
|
|||||||
|
|
||||||
- [x] 教你一篇小作文[作文]
|
- [x] 教你一篇小作文[作文]
|
||||||
|
|
||||||
|
</details>
|
||||||
|
<details>
|
||||||
|
<summary>多功能抽签</summary>
|
||||||
|
|
||||||
|
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/drawlots"`
|
||||||
|
|
||||||
|
支持图包文件夹和gif抽签
|
||||||
|
|
||||||
|
- [x] (刷新)抽签列表
|
||||||
|
|
||||||
|
- [x] 抽签-[签名]
|
||||||
|
|
||||||
|
- [x] 查看抽签[gif签名]
|
||||||
|
|
||||||
|
- [x] 添加抽签[签名][gif图片]
|
||||||
|
|
||||||
|
- [x] 删除抽签[gif签名]
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
<summary>女装</summary>
|
<summary>女装</summary>
|
||||||
|
|||||||
1
main.go
1
main.go
@ -82,6 +82,7 @@ import (
|
|||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/dailynews" // 今日早报
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/dailynews" // 今日早报
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/danbooru" // DeepDanbooru二次元图标签识别
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/danbooru" // DeepDanbooru二次元图标签识别
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/diana" // 嘉心糖发病
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/diana" // 嘉心糖发病
|
||||||
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/drawlots" // 多功能抽签
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/dress" // 女装
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/dress" // 女装
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/drift_bottle" // 漂流瓶
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/drift_bottle" // 漂流瓶
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/emojimix" // 合成emoji
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/emojimix" // 合成emoji
|
||||||
|
|||||||
249
plugin/drawlots/main.go
Normal file
249
plugin/drawlots/main.go
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
// Package drawlots 多功能抽签插件
|
||||||
|
package drawlots
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"image"
|
||||||
|
"image/gif"
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/FloatTech/floatbox/file"
|
||||||
|
"github.com/FloatTech/imgfactory"
|
||||||
|
ctrl "github.com/FloatTech/zbpctrl"
|
||||||
|
control "github.com/FloatTech/zbputils/control"
|
||||||
|
"github.com/FloatTech/zbputils/ctxext"
|
||||||
|
"github.com/FloatTech/zbputils/img/text"
|
||||||
|
"github.com/fumiama/jieba/util/helper"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
zero "github.com/wdvxdr1123/ZeroBot"
|
||||||
|
"github.com/wdvxdr1123/ZeroBot/message"
|
||||||
|
)
|
||||||
|
|
||||||
|
type info struct {
|
||||||
|
lotsType string // 文件后缀
|
||||||
|
quantity int // 签数
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
lotsList = func() map[string]info {
|
||||||
|
lotsList, err := getList()
|
||||||
|
if err != nil {
|
||||||
|
logrus.Infoln("[drawlots]加载失败:", err)
|
||||||
|
} else {
|
||||||
|
logrus.Infoln("[drawlots]加载", len(lotsList), "个抽签")
|
||||||
|
}
|
||||||
|
return lotsList
|
||||||
|
}()
|
||||||
|
en = control.Register("drawlots", &ctrl.Options[*zero.Ctx]{
|
||||||
|
DisableOnDefault: false,
|
||||||
|
Brief: "多功能抽签",
|
||||||
|
Help: "支持图包文件夹和gif抽签\n-------------\n- (刷新)抽签列表\n- 抽[签名]签\n- 看签[gif签名]\n- 加签[签名][gif图片]\n- 删签[gif签名]",
|
||||||
|
PrivateDataFolder: "drawlots",
|
||||||
|
}).ApplySingle(ctxext.DefaultSingle)
|
||||||
|
datapath = file.BOTPATH + "/" + en.DataFolder()
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
en.OnFullMatchGroup([]string{"抽签列表", "刷新抽签列表"}).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||||
|
lotsList, err := getList() // 刷新列表
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
messageText := &strings.Builder{}
|
||||||
|
messageText.WriteString(" 签 名 [ 类 型 ]----签数\n")
|
||||||
|
messageText.WriteString("———————————\n")
|
||||||
|
for name, fileInfo := range lotsList {
|
||||||
|
messageText.WriteString(name + "[" + fileInfo.lotsType + "]----" + strconv.Itoa(fileInfo.quantity) + "\n")
|
||||||
|
messageText.WriteString("----------\n")
|
||||||
|
}
|
||||||
|
textPic, err := text.RenderToBase64(messageText.String(), text.BoldFontFile, 400, 50)
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.SendChain(message.Image("base64://" + helper.BytesToString(textPic)))
|
||||||
|
})
|
||||||
|
en.OnRegex(`^抽(.*)签$`).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||||
|
lotsType := ctx.State["regex_matched"].([]string)[1]
|
||||||
|
fileInfo, ok := lotsList[lotsType]
|
||||||
|
if !ok {
|
||||||
|
ctx.SendChain(message.Text("签名[", lotsType, "]不存在"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if fileInfo.lotsType == "folder" {
|
||||||
|
picPath, err := randFile(lotsType, 3)
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("file:///"+picPath))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lotsImg, err := randGif(lotsType + "." + fileInfo.lotsType)
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 生成图片
|
||||||
|
data, err := imgfactory.ToBytes(lotsImg)
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.ImageBytes(data))
|
||||||
|
})
|
||||||
|
en.OnPrefix("看签", zero.UserOrGrpAdmin).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
|
||||||
|
id := ctx.Event.MessageID
|
||||||
|
lotsName := strings.TrimSpace(ctx.State["args"].(string))
|
||||||
|
fileInfo, ok := lotsList[lotsName]
|
||||||
|
if !ok {
|
||||||
|
ctx.Send(message.ReplyWithMessage(id, message.Text("签名[", lotsName, "]不存在")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if fileInfo.lotsType == "folder" {
|
||||||
|
ctx.Send(message.ReplyWithMessage(id, message.Text("仅支持查看gif抽签")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Send(message.ReplyWithMessage(id, message.Image("file:///"+datapath+lotsName+"."+fileInfo.lotsType)))
|
||||||
|
})
|
||||||
|
en.OnPrefix("加签", zero.SuperUserPermission, zero.MustProvidePicture).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
|
||||||
|
id := ctx.Event.MessageID
|
||||||
|
lotsName := strings.TrimSpace(ctx.State["args"].(string))
|
||||||
|
if lotsName == "" {
|
||||||
|
ctx.Send(message.ReplyWithMessage(id, message.Text("请使用正确的指令形式")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
picURL := ctx.State["image_url"].([]string)[0]
|
||||||
|
err := file.DownloadTo(picURL, datapath+"/"+lotsName+".gif")
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
file, err := os.Open(datapath + "/" + lotsName + ".gif")
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
im, err := gif.DecodeAll(file)
|
||||||
|
_ = file.Close()
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lotsList[lotsName] = info{
|
||||||
|
lotsType: "gif",
|
||||||
|
quantity: len(im.Image),
|
||||||
|
}
|
||||||
|
ctx.Send(message.ReplyWithMessage(id, message.Text("成功")))
|
||||||
|
})
|
||||||
|
en.OnPrefix("删签", zero.SuperUserPermission).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
|
||||||
|
id := ctx.Event.MessageID
|
||||||
|
lotsName := strings.TrimSpace(ctx.State["args"].(string))
|
||||||
|
fileInfo, ok := lotsList[lotsName]
|
||||||
|
if !ok {
|
||||||
|
ctx.Send(message.ReplyWithMessage(id, message.Text("签名[", lotsName, "]不存在")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if fileInfo.lotsType == "folder" {
|
||||||
|
ctx.Send(message.ReplyWithMessage(id, message.Text("图包请手动移除(保护图源误删),谢谢")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := os.Remove(datapath + lotsName + "." + fileInfo.lotsType)
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
delete(lotsList, lotsName)
|
||||||
|
ctx.Send(message.ReplyWithMessage(id, message.Text("成功")))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func getList() (list map[string]info, err error) {
|
||||||
|
list = make(map[string]info, 100)
|
||||||
|
files, err := os.ReadDir(datapath)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(files) == 0 {
|
||||||
|
err = errors.New("不存在任何抽签")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, lots := range files {
|
||||||
|
if lots.IsDir() {
|
||||||
|
files, _ := os.ReadDir(datapath + "/" + lots.Name())
|
||||||
|
list[lots.Name()] = info{
|
||||||
|
lotsType: "folder",
|
||||||
|
quantity: len(files),
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
before, after, ok := strings.Cut(lots.Name(), ".")
|
||||||
|
if !ok || before == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
file, err := os.Open(datapath + "/" + lots.Name())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
im, err := gif.DecodeAll(file)
|
||||||
|
_ = file.Close()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
list[before] = info{
|
||||||
|
lotsType: after,
|
||||||
|
quantity: len(im.Image),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func randFile(path string, indexMax int) (string, error) {
|
||||||
|
picPath := datapath + path
|
||||||
|
files, err := os.ReadDir(picPath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if len(files) > 0 {
|
||||||
|
drawFile := files[rand.Intn(len(files))]
|
||||||
|
// 如果是文件夹就递归
|
||||||
|
if drawFile.IsDir() {
|
||||||
|
indexMax--
|
||||||
|
if indexMax <= 0 {
|
||||||
|
return "", errors.New("图包[" + path + "]存在太多非图片文件,请清理")
|
||||||
|
}
|
||||||
|
return randFile(path, indexMax)
|
||||||
|
}
|
||||||
|
return picPath + "/" + drawFile.Name(), err
|
||||||
|
}
|
||||||
|
return "", errors.New("图包[" + path + "]不存在签内容")
|
||||||
|
}
|
||||||
|
|
||||||
|
func randGif(gifName string) (image.Image, error) {
|
||||||
|
name := datapath + gifName
|
||||||
|
file, err := os.Open(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
im, err := gif.DecodeAll(file)
|
||||||
|
_ = file.Close()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
firstImg, err := imgfactory.Load(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
v := im.Image[rand.Intn(len(im.Image))]
|
||||||
|
return imgfactory.Size(firstImg, firstImg.Bounds().Max.X, firstImg.Bounds().Max.Y).InsertUpC(v, 0, 0, firstImg.Bounds().Max.X/2, firstImg.Bounds().Max.Y/2).Clone().Image(),err
|
||||||
|
/*/
|
||||||
|
// 如果gif图片出现信息缺失请使用上面注释掉的代码,把下面注释了(上面代码部分图存在bug)
|
||||||
|
v := im.Image[rand.Intn(len(im.Image))]
|
||||||
|
return imgfactory.Size(v, v.Bounds().Max.X, v.Bounds().Max.Y).Image(), err
|
||||||
|
// */
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user