mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-19 05:30:07 +08:00
* 优化在两个命令中使用空格分隔的体验 - fortune的设置底图功能 - b14的加密功能 * 优化四个插件中使用空格分隔的体验 - 加密 - 哔哩哔哩推送 - 藏头诗 - 运势 * 优化并修正了上一个commit - 加上了因为复制粘贴疏忽又没有注意测试遗漏的`?` - 调整藏头诗和加密的正则触发,使其不必多此一举 - 删去了未被发现的测试代码 * - 删去了遗漏的Trim * 优化了更多插件中使用空格的体验 - 优化了music bilibili image_finder 中使用空格的体验 - 补上了plugin_bilibili中未实现的vup开头触发 - 为plugin_bilibili_parse输出的消息加上一个换行符,优化排版 * - 调整funny - 补回readme中bilibili_push的注释说明 * - 简化funny说明 * - 用暴力的办法使抽多张塔罗牌不重复 - 逆位的图片现在可以倒过来了 * - 解塔罗牌 * - 修改readme * 大幅减少全局变量,简化抽塔罗牌输出 * - 更新了塔罗牌阵 * - 顺lint心意 - 添加判断避免重复装填 * 调整塔罗牌阵消息 - 用图片说明牌阵信息避免被封 * 调整DoOnceOnSuccess,减少冗余 * 🎨 改进代码样式 * 调整发送牌阵信息 * 🎨 改进代码样式 * 改回base64 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
206 lines
6.4 KiB
Go
206 lines
6.4 KiB
Go
// Package tarot 塔罗牌
|
|
package tarot
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"math/rand"
|
|
"strconv"
|
|
"strings"
|
|
|
|
ctrl "github.com/FloatTech/zbpctrl"
|
|
"github.com/FloatTech/zbputils/binary"
|
|
"github.com/FloatTech/zbputils/control"
|
|
"github.com/FloatTech/zbputils/ctxext"
|
|
"github.com/FloatTech/zbputils/img/text"
|
|
"github.com/sirupsen/logrus"
|
|
zero "github.com/wdvxdr1123/ZeroBot"
|
|
"github.com/wdvxdr1123/ZeroBot/message"
|
|
)
|
|
|
|
const bed = "https://gitcode.net/shudorcl/zbp-tarot/-/raw/master/"
|
|
|
|
type cardInfo struct {
|
|
Description string `json:"description"`
|
|
ReverseDescription string `json:"reverseDescription"`
|
|
ImgURL string `json:"imgUrl"`
|
|
}
|
|
type card struct {
|
|
Name string `json:"name"`
|
|
cardInfo `json:"info"`
|
|
}
|
|
|
|
type formation struct {
|
|
CardsNum int `json:"cards_num"`
|
|
IsCut bool `json:"is_cut"`
|
|
Represent [][]string `json:"represent"`
|
|
}
|
|
type cardSet = map[string]card
|
|
|
|
var cardMap = make(cardSet, 30)
|
|
var infoMap = make(map[string]cardInfo, 30)
|
|
var formationMap = make(map[string]formation, 10)
|
|
|
|
// var cardName = make([]string, 30)
|
|
// var formationName = make([]string, 10)
|
|
|
|
func init() {
|
|
engine := control.Register("tarot", &ctrl.Options[*zero.Ctx]{
|
|
DisableOnDefault: false,
|
|
Help: "塔罗牌\n" +
|
|
"- 抽塔罗牌\n" +
|
|
"- 抽n张塔罗牌\n" +
|
|
"- 解塔罗牌[牌名]\n" +
|
|
"- 塔罗牌阵[圣三角|时间之流|四要素|五牌阵|吉普赛十字|马蹄|六芒星]",
|
|
PublicDataFolder: "Tarot",
|
|
}).ApplySingle(ctxext.DefaultSingle)
|
|
|
|
getTarot := ctxext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
|
|
data, err := engine.GetLazyData("tarots.json", true)
|
|
if err != nil {
|
|
ctx.SendChain(message.Text("ERROR:", err))
|
|
return false
|
|
}
|
|
err = json.Unmarshal(data, &cardMap)
|
|
if err != nil {
|
|
ctx.SendChain(message.Text("ERROR:", err))
|
|
return false
|
|
}
|
|
for _, card := range cardMap {
|
|
infoMapKey := strings.Split(card.Name, "(")[0]
|
|
infoMap[infoMapKey] = card.cardInfo
|
|
// 可以拿来显示大阿尔卡纳列表
|
|
// cardName = append(cardName, infoMapKey)
|
|
}
|
|
logrus.Infof("[tarot]读取%d张大阿尔卡纳塔罗牌", len(cardMap))
|
|
formation, err := engine.GetLazyData("formation.json", true)
|
|
if err != nil {
|
|
ctx.SendChain(message.Text("ERROR:", err))
|
|
return false
|
|
}
|
|
err = json.Unmarshal(formation, &formationMap)
|
|
if err != nil {
|
|
ctx.SendChain(message.Text("ERROR:", err))
|
|
return false
|
|
}
|
|
logrus.Infof("[tarot]读取%d组塔罗牌阵", len(formationMap))
|
|
return true
|
|
})
|
|
engine.OnRegex(`^抽(\d{1,2}张)?塔罗牌$`, getTarot).SetBlock(true).Limit(ctxext.LimitByGroup).Handle(func(ctx *zero.Ctx) {
|
|
match := ctx.State["regex_matched"].([]string)[1]
|
|
n := 1
|
|
reasons := [...]string{"您抽到的是~\n", "锵锵锵,塔罗牌的预言是~\n", "诶,让我看看您抽到了~\n"}
|
|
position := [...]string{"正位", "逆位"}
|
|
reverse := [...]string{"", "Reverse"}
|
|
if match != "" {
|
|
var err error
|
|
n, err = strconv.Atoi(match[:len(match)-3])
|
|
if err != nil {
|
|
ctx.SendChain(message.Text("ERROR:", err))
|
|
return
|
|
}
|
|
if n <= 0 {
|
|
ctx.SendChain(message.Text("ERROR:张数必须为正"))
|
|
return
|
|
}
|
|
if n > 1 && !zero.OnlyGroup(ctx) {
|
|
ctx.SendChain(message.Text("ERROR:抽取多张仅支持群聊"))
|
|
return
|
|
}
|
|
if n > 20 {
|
|
ctx.SendChain(message.Text("ERROR:抽取张数过多"))
|
|
return
|
|
}
|
|
}
|
|
if n == 1 {
|
|
i := rand.Intn(22)
|
|
p := rand.Intn(2)
|
|
card := cardMap[(strconv.Itoa(i))]
|
|
name := card.Name
|
|
if id := ctx.SendChain(
|
|
message.Text(reasons[rand.Intn(len(reasons))], position[p], " 的 ", name, "\n"),
|
|
message.Image(fmt.Sprintf(bed+"MajorArcana%s/%d.png", reverse[p], i))); id.ID() == 0 {
|
|
ctx.SendChain(message.Text("ERROR:可能被风控了"))
|
|
}
|
|
return
|
|
}
|
|
msg := make([]message.MessageSegment, n)
|
|
randomIntMap := make(map[int]int, 30)
|
|
for i := range msg {
|
|
j := rand.Intn(22)
|
|
_, ok := randomIntMap[j]
|
|
for ok {
|
|
j = rand.Intn(22)
|
|
_, ok = randomIntMap[j]
|
|
}
|
|
randomIntMap[j] = 0
|
|
p := rand.Intn(2)
|
|
card := cardMap[(strconv.Itoa(j))]
|
|
name := card.Name
|
|
tarotMsg := []message.MessageSegment{
|
|
message.Text(reasons[rand.Intn(len(reasons))], position[p], " 的 ", name, "\n"),
|
|
message.Image(fmt.Sprintf(bed+"MajorArcana%s/%d.png", reverse[p], j))}
|
|
msg[i] = ctxext.FakeSenderForwardNode(ctx, tarotMsg...)
|
|
}
|
|
ctx.SendGroupForwardMessage(ctx.Event.GroupID, msg)
|
|
})
|
|
|
|
engine.OnRegex(`^解塔罗牌\s?(.*)`, getTarot).SetBlock(true).Limit(ctxext.LimitByGroup).Handle(func(ctx *zero.Ctx) {
|
|
match := ctx.State["regex_matched"].([]string)[1]
|
|
info, ok := infoMap[match]
|
|
if ok {
|
|
ctx.SendChain(
|
|
message.Image(bed+info.ImgURL),
|
|
message.Text("\n", match, "的含义是~"),
|
|
message.Text("\n正位:", info.Description),
|
|
message.Text("\n逆位:", info.ReverseDescription))
|
|
} else {
|
|
ctx.SendChain(message.Text("没有找到", match, "噢~"))
|
|
}
|
|
})
|
|
engine.OnRegex(`^塔罗牌阵\s?(.*)`, getTarot).SetBlock(true).Limit(ctxext.LimitByGroup).Handle(func(ctx *zero.Ctx) {
|
|
match := ctx.State["regex_matched"].([]string)[1]
|
|
info, ok := formationMap[match]
|
|
position := [...]string{"正位", "逆位"}
|
|
reverse := [...]string{"", "Reverse"}
|
|
if ok {
|
|
var build strings.Builder
|
|
build.WriteString(ctx.CardOrNickName(ctx.Event.UserID))
|
|
build.WriteString("\n")
|
|
msg := make([]message.MessageSegment, info.CardsNum)
|
|
randomIntMap := make(map[int]int, 30)
|
|
for i := range msg {
|
|
j := rand.Intn(22)
|
|
_, ok := randomIntMap[j]
|
|
for ok {
|
|
j = rand.Intn(22)
|
|
_, ok = randomIntMap[j]
|
|
}
|
|
randomIntMap[j] = 0
|
|
p := rand.Intn(2)
|
|
card := cardMap[(strconv.Itoa(j))]
|
|
name := card.Name
|
|
tarotMsg := []message.MessageSegment{message.Image(fmt.Sprintf(bed+"MajorArcana%s/%d.png", reverse[p], j))}
|
|
build.WriteString(info.Represent[0][i])
|
|
build.WriteString(": ")
|
|
build.WriteString(position[p])
|
|
build.WriteString(" 的 ")
|
|
build.WriteString(name)
|
|
build.WriteString("\n")
|
|
msg[i] = ctxext.FakeSenderForwardNode(ctx, tarotMsg...)
|
|
}
|
|
txt := build.String()
|
|
formation, err := text.RenderToBase64(txt, text.FontFile, 400, 20)
|
|
if err != nil {
|
|
ctx.SendChain(message.Text("ERROR:", err))
|
|
return
|
|
}
|
|
// TODO 视gocq变化将牌阵信息加入转发列表中
|
|
ctx.SendChain(message.Image("base64://" + binary.BytesToString(formation)))
|
|
ctx.SendGroupForwardMessage(ctx.Event.GroupID, msg)
|
|
} else {
|
|
ctx.SendChain(message.Text("没有找到", match, "噢~"))
|
|
}
|
|
})
|
|
}
|