发布插件猜单词

This commit is contained in:
Kanri 2022-02-22 19:48:13 +08:00
parent 598a664d30
commit b0fbd6507d
3 changed files with 64 additions and 37 deletions

View File

@ -185,6 +185,9 @@ zerobot [-h] [-t token] [-u url] [-n nickname] [-p prefix] [-d|w] [-g 监听地
- [x] @BOT 创建频道 xxx - [x] @BOT 创建频道 xxx
- [x] 跳入(频道)海中 - [x] 跳入(频道)海中
- [x] 注:不显式限制时,私聊发送可在所有群抽到,群聊发送仅可在本群抽到,默认频道为 global - [x] 注:不显式限制时,私聊发送可在所有群抽到,群聊发送仅可在本群抽到,默认频道为 global
- **猜单词** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_wordle"`
- [x] 个人猜单词
- [x] 团队猜单词
- **bilibili** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_bilibili"` - **bilibili** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_bilibili"`
- [x] >vup info [名字 | uid] - [x] >vup info [名字 | uid]
- [x] >user info [名字 | uid] - [x] >user info [名字 | uid]

View File

@ -98,6 +98,7 @@ import (
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_translation" // 翻译 _ "github.com/FloatTech/ZeroBot-Plugin/plugin_translation" // 翻译
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_vtb_quotation" // vtb语录 _ "github.com/FloatTech/ZeroBot-Plugin/plugin_vtb_quotation" // vtb语录
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_wangyiyun" // 网易云音乐热评 _ "github.com/FloatTech/ZeroBot-Plugin/plugin_wangyiyun" // 网易云音乐热评
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_wordle" // 猜单词
// _ "github.com/FloatTech/ZeroBot-Plugin/plugin_wtf" // 鬼东西 // _ "github.com/FloatTech/ZeroBot-Plugin/plugin_wtf" // 鬼东西
// _ "github.com/FloatTech/ZeroBot-Plugin/plugin_bilibili_push" // b站推送 // _ "github.com/FloatTech/ZeroBot-Plugin/plugin_bilibili_push" // b站推送

View File

@ -5,7 +5,9 @@ import (
"errors" "errors"
"image/color" "image/color"
"math/rand" "math/rand"
"sort"
"strings" "strings"
"sync"
"time" "time"
"github.com/FloatTech/zbputils/binary" "github.com/FloatTech/zbputils/binary"
@ -39,13 +41,14 @@ var colors = [...]color.RGBA{
{219, 219, 219, 255}, {219, 219, 219, 255},
} }
var words []wordpack var words []string
func init() { func init() {
en := control.Register("wordle", order.AcquirePrio(), &control.Options{ en := control.Register("wordle", order.AcquirePrio(), &control.Options{
DisableOnDefault: false, DisableOnDefault: false,
Help: "猜单词\n" + Help: "猜单词\n" +
"- 开始猜单词", "- 个人猜单词" +
"- 团队猜单词",
PublicDataFolder: "Wordle", PublicDataFolder: "Wordle",
}) })
go func() { go func() {
@ -53,79 +56,99 @@ func init() {
if err != nil { if err != nil {
panic(err) panic(err)
} }
words = loadwords(data) var wordpacks = loadwords(data)
words = make([]string, 0, len(wordpacks))
for i := range wordpacks {
words = append(words, wordpacks[i].String())
}
sort.Strings(words)
}() }()
en.OnFullMatch("猜单词").SetBlock(true).Limit(ctxext.LimitByUser). var room = sync.Map{}
en.OnRegex(`(个人|团队)猜单词`, zero.OnlyGroup).SetBlock(true).Limit(ctxext.LimitByUser).
Handle(func(ctx *zero.Ctx) { Handle(func(ctx *zero.Ctx) {
if ongoing, ok := room.Load(ctx.Event.GroupID); ok && ongoing.(bool) {
ctx.SendChain(message.ReplyWithMessage(ctx.Event.MessageID,
message.Text("已经有正在进行的游戏..."))...)
return
}
room.Store(ctx.Event.GroupID, true)
game := newWordleGame() game := newWordleGame()
_, img, _ := game("") _, img, _ := game("")
ctx.SendChain(message.Image("base64://"+binary.BytesToString(img)), message.Text("请发送单词")) typ := ctx.State["regex_matched"].([]string)[1]
// 没有图片就索取 ctx.SendChain(message.ReplyWithMessage(ctx.Event.MessageID,
next := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^[A-Z]{5}$|^[a-z]{5}$`)) message.Image("base64://"+binary.BytesToString(img)),
message.Text("你有6次机会猜出单词单词长度为5请发送单词"))...)
var next *zero.FutureEvent
if typ == "个人" {
next = zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^[A-Z]{5}$|^[a-z]{5}$`), zero.OnlyGroup, zero.CheckUser(ctx.Event.UserID))
} else {
next = zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^[A-Z]{5}$|^[a-z]{5}$`), zero.OnlyGroup)
}
recv, cancel := next.Repeat() recv, cancel := next.Repeat()
var msg message.Message
defer func() { defer func() {
cancel() cancel()
ctx.Send(msg) room.Store(ctx.Event.GroupID, false)
}() }()
for { for {
select { select {
case <-time.After(time.Second * 120): case <-time.After(time.Second * 120):
ctx.SendChain(message.ReplyWithMessage(ctx.Event.MessageID,
message.Image("base64://"+binary.BytesToString(img)),
message.Text("猜单词超时,游戏结束..."))...)
return return
case e := <-recv: case e := <-recv:
win, img, err := game(e.Message.String()) win, img, err := game(e.Message.String())
msg = []message.MessageSegment{message.Image("base64://" + binary.BytesToString(img))} switch {
switch err { case win:
case nil: ctx.SendChain(message.ReplyWithMessage(e.MessageID,
if win { message.Image("base64://"+binary.BytesToString(img)),
msg = append(msg, message.Text("你赢了")) message.Text("太棒了,你猜出来了!"))...)
return return
} case err == errTimesRunOut:
case errLengthNotEnough: ctx.SendChain(message.ReplyWithMessage(e.MessageID,
msg = append(msg, message.Text("单词长度错误")) message.Image("base64://"+binary.BytesToString(img)),
case errUnknownWord: message.Text("游戏结束..."))...)
msg = append(msg, message.Text("不存在这样的单词"))
case errTimesRunOut:
msg = append(msg, message.Text("你输了"))
return return
case err == errLengthNotEnough:
ctx.SendChain(message.ReplyWithMessage(e.MessageID,
message.Image("base64://"+binary.BytesToString(img)),
message.Text("单词长度错误"))...)
case err == errUnknownWord:
ctx.SendChain(message.ReplyWithMessage(e.MessageID,
message.Image("base64://"+binary.BytesToString(img)),
message.Text("你确定存在这样的单词吗?"))...)
default:
ctx.SendChain(message.ReplyWithMessage(e.MessageID,
message.Image("base64://"+binary.BytesToString(img)))...)
} }
ctx.Send(msg)
} }
} }
}) })
} }
func newWordleGame() func(string) (bool, []byte, error) { func newWordleGame() func(string) (bool, []byte, error) {
onhandpack := words[rand.Intn(len(words))] onhand := words[rand.Intn(len(words))]
onhand := onhandpack.String()
record := make([]string, 0, len(onhand)+1) record := make([]string, 0, len(onhand)+1)
return func(s string) (win bool, base64Image []byte, err error) { return func(s string) (win bool, base64Image []byte, err error) {
if s != "" { if s != "" {
s = strings.ToLower(s) s = strings.ToLower(s)
sp := pack(s) if onhand == s {
if onhandpack == sp {
win = true win = true
} else { } else {
if len(s) != len(onhand) { if len(s) != len(onhand) {
err = errLengthNotEnough err = errLengthNotEnough
return return
} }
i := 0 i := sort.SearchStrings(words, s)
for ; i < len(words); i++ { if i >= len(words) || words[i] != s {
if words[i] == sp {
break
}
}
if i >= len(words) || words[i] != sp {
err = errUnknownWord err = errUnknownWord
return return
} }
} }
record = append(record, s)
if len(record) >= cap(record) { if len(record) >= cap(record) {
err = errTimesRunOut err = errTimesRunOut
return
} }
record = append(record, s)
} }
var side = 20 var side = 20
ctx := gg.NewContext((side+2)*5+26, (side+2)*6+26) ctx := gg.NewContext((side+2)*5+26, (side+2)*6+26)
@ -154,7 +177,7 @@ func newWordleGame() func(string) (bool, []byte, error) {
} }
} }
} }
base64Image, err = writer.ToBase64(ctx.Image()) base64Image, _ = writer.ToBase64(ctx.Image())
return return
} }
} }