From a8d93de000bc15c9ee719a9d8c7442e721163ddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=AB=E6=80=9D=E6=BD=8B?= <55676105+shudorcl@users.noreply.github.com> Date: Sat, 18 Jun 2022 16:51:11 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E5=A1=94=E7=BD=97=E7=89=8C?= =?UTF-8?q?=E9=98=B5=20(#268)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 优化在两个命令中使用空格分隔的体验 - 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> --- README.md | 1 + plugin/tarot/tarot.go | 140 +++++++++++++++++++++++++++--------------- 2 files changed, 91 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 7f4c6137..b9795b9f 100644 --- a/README.md +++ b/README.md @@ -862,6 +862,7 @@ print("run[CQ:image,file="+j["img"]+"]") - [x] 抽塔罗牌 - [x] 抽n张塔罗牌 - [x] 解塔罗牌[牌名] + - [x] 塔罗牌阵[圣三角|时间之流|四要素|五牌阵|吉普赛十字|马蹄|六芒星]"
diff --git a/plugin/tarot/tarot.go b/plugin/tarot/tarot.go index f019fdc1..fbb9e2f5 100644 --- a/plugin/tarot/tarot.go +++ b/plugin/tarot/tarot.go @@ -9,8 +9,10 @@ import ( "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" @@ -27,12 +29,20 @@ 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, 22) +// var cardName = make([]string, 30) +// var formationName = make([]string, 10) func init() { engine := control.Register("tarot", &ctrl.Options[*zero.Ctx]{ @@ -40,26 +50,43 @@ func init() { Help: "塔罗牌\n" + "- 抽塔罗牌\n" + "- 抽n张塔罗牌\n" + - "- 解塔罗牌[牌名]", + "- 解塔罗牌[牌名]\n" + + "- 塔罗牌阵[圣三角|时间之流|四要素|五牌阵|吉普赛十字|马蹄|六芒星]", PublicDataFolder: "Tarot", }).ApplySingle(ctxext.DefaultSingle) - engine.OnRegex(`^抽(\d{1,2}张)?塔罗牌$`, 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 - } - logrus.Infof("[tarot]读取%d张塔罗牌", len(cardMap)) - return true - }, - )).SetBlock(true).Limit(ctxext.LimitByGroup).Handle(func(ctx *zero.Ctx) { + 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"} @@ -118,38 +145,7 @@ func init() { ctx.SendGroupForwardMessage(ctx.Event.GroupID, msg) }) - engine.OnRegex(`^解塔罗牌\s?(.*)`, ctxext.DoOnceOnSuccess( - func(ctx *zero.Ctx) bool { - if len(cardMap) > 0 { - for _, card := range cardMap { - infoMapKey := strings.Split(card.Name, "(")[0] - infoMap[infoMapKey] = card.cardInfo - // 可以拿来显示大阿尔卡纳列表 - // cardName = append(cardName, infoMapKey) - } - return true - } - tempMap := make(cardSet, 30) - data, err := engine.GetLazyData("tarots.json", true) - if err != nil { - ctx.SendChain(message.Text("ERROR:", err)) - return false - } - err = json.Unmarshal(data, &tempMap) - if err != nil { - ctx.SendChain(message.Text("ERROR:", err)) - return false - } - - for _, card := range tempMap { - infoMapKey := strings.Split(card.Name, "(")[0] - infoMap[infoMapKey] = card.cardInfo - // 可以拿来显示大阿尔卡纳列表 - // cardName = append(cardName, infoMapKey) - } - return true - }, - )).SetBlock(true).Limit(ctxext.LimitByGroup).Handle(func(ctx *zero.Ctx) { + 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 { @@ -162,4 +158,48 @@ func init() { 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, "噢~")) + } + }) }