优化代码结构 (#565)

This commit is contained in:
DreamZero 2023-01-30 17:42:53 +08:00 committed by GitHub
parent 07e6f33b04
commit f96b5f8965
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 73 additions and 48 deletions

View File

@ -104,6 +104,10 @@ zerobot [-h] [-n nickname] [-t token] [-u url] [-p prefix] [-d|w] [-c|s config.j
- [x] /禁用 xxx (在发送的群/用户禁用xxx) - [x] /禁用 xxx (在发送的群/用户禁用xxx)
- [x] /此处启用所有插件
- [x] /此处禁用所有插件
- [x] /全局启用 xxx - [x] /全局启用 xxx
- [x] /全局禁用 xxx - [x] /全局禁用 xxx
@ -1267,6 +1271,16 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 更新vtb - [x] 更新vtb
</details>
<details>
<summary>钱包</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wallet"`
- [x] 查看我的钱包
- [x] 查看钱包排名
</details> </details>
<details> <details>
<summary>网易云音乐热评</summary> <summary>网易云音乐热评</summary>

2
go.mod
View File

@ -10,7 +10,7 @@ require (
github.com/FloatTech/sqlite v1.5.7 github.com/FloatTech/sqlite v1.5.7
github.com/FloatTech/ttl v0.0.0-20220715042055-15612be72f5b github.com/FloatTech/ttl v0.0.0-20220715042055-15612be72f5b
github.com/FloatTech/zbpctrl v1.5.3-0.20230109124217-41203036b80a github.com/FloatTech/zbpctrl v1.5.3-0.20230109124217-41203036b80a
github.com/FloatTech/zbputils v1.6.2-0.20230113162508-c8966fa17745 github.com/FloatTech/zbputils v1.6.2-0.20230119092935-1c36d138f0c0
github.com/RomiChan/syncx v0.0.0-20221202055724-5f842c53020e github.com/RomiChan/syncx v0.0.0-20221202055724-5f842c53020e
github.com/RomiChan/websocket v1.4.3-0.20220227141055-9b2c6168c9c5 github.com/RomiChan/websocket v1.4.3-0.20220227141055-9b2c6168c9c5
github.com/antchfx/htmlquery v1.2.5 github.com/antchfx/htmlquery v1.2.5

4
go.sum
View File

@ -16,8 +16,8 @@ github.com/FloatTech/ttl v0.0.0-20220715042055-15612be72f5b h1:tvciXWq2nuvTbFeJG
github.com/FloatTech/ttl v0.0.0-20220715042055-15612be72f5b/go.mod h1:fHZFWGquNXuHttu9dUYoKuNbm3dzLETnIOnm1muSfDs= github.com/FloatTech/ttl v0.0.0-20220715042055-15612be72f5b/go.mod h1:fHZFWGquNXuHttu9dUYoKuNbm3dzLETnIOnm1muSfDs=
github.com/FloatTech/zbpctrl v1.5.3-0.20230109124217-41203036b80a h1:O+GS8J1pEM4E8q05EcopHBK6kfIr0BJJ/cHuPa8yWLM= github.com/FloatTech/zbpctrl v1.5.3-0.20230109124217-41203036b80a h1:O+GS8J1pEM4E8q05EcopHBK6kfIr0BJJ/cHuPa8yWLM=
github.com/FloatTech/zbpctrl v1.5.3-0.20230109124217-41203036b80a/go.mod h1:UT3bZNKMF/+r2XzSvIVXWudnTgmWsQrRPOJ3bmBfjFI= github.com/FloatTech/zbpctrl v1.5.3-0.20230109124217-41203036b80a/go.mod h1:UT3bZNKMF/+r2XzSvIVXWudnTgmWsQrRPOJ3bmBfjFI=
github.com/FloatTech/zbputils v1.6.2-0.20230113162508-c8966fa17745 h1:+fha5TfD9l0DGKXFApshxNd8GTnO5ZzpH9JURfnk0Bk= github.com/FloatTech/zbputils v1.6.2-0.20230119092935-1c36d138f0c0 h1:MPZ1yKgENXMNp1ypyRF4fksdyEDUZ5i4GDNzmymke1Y=
github.com/FloatTech/zbputils v1.6.2-0.20230113162508-c8966fa17745/go.mod h1:A43VDRGxLk0nV8jv0ONMErudXRn58W/JQTg7S9RpbfU= github.com/FloatTech/zbputils v1.6.2-0.20230119092935-1c36d138f0c0/go.mod h1:A43VDRGxLk0nV8jv0ONMErudXRn58W/JQTg7S9RpbfU=
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
github.com/RomiChan/syncx v0.0.0-20221202055724-5f842c53020e h1:wR3MXQ3VbUlPKOOUwLOYgh/QaJThBTYtsl673O3lqSA= github.com/RomiChan/syncx v0.0.0-20221202055724-5f842c53020e h1:wR3MXQ3VbUlPKOOUwLOYgh/QaJThBTYtsl673O3lqSA=
github.com/RomiChan/syncx v0.0.0-20221202055724-5f842c53020e/go.mod h1:vD7Ra3Q9onRtojoY5sMCLQ7JBgjUsrXDnDKyFxqpf9w= github.com/RomiChan/syncx v0.0.0-20221202055724-5f842c53020e/go.mod h1:vD7Ra3Q9onRtojoY5sMCLQ7JBgjUsrXDnDKyFxqpf9w=

View File

@ -30,7 +30,7 @@ func init() {
engine := control.Register("ahsai", &ctrl.Options[*zero.Ctx]{ engine := control.Register("ahsai", &ctrl.Options[*zero.Ctx]{
DisableOnDefault: false, DisableOnDefault: false,
Brief: "フリーテキスト音声合成", Brief: "フリーテキスト音声合成",
Help: "- 使[伊織弓鶴|紲星あかり|結月ゆかり|京町セイカ|東北きりたん|東北イタコ|ついなちゃん標準語|ついなちゃん関西弁|音街ウナ|琴葉茜|吉田くん|民安ともえ|桜乃そら|月読アイ|琴葉葵|東北ずん子|月読ショウタ|水奈瀬コウ]说(日语)\n", Help: "- 使[伊織弓鶴|紲星あかり|結月ゆかり|京町セイカ|東北きりたん|東北イタコ|ついなちゃん標準語|ついなちゃん関西弁|音街ウナ|琴葉茜|吉田くん|民安ともえ|桜乃そら|月読アイ|琴葉葵|東北ずん子|月読ショウタ|水奈瀬コウ]说(日语)",
PrivateDataFolder: "ahsai", PrivateDataFolder: "ahsai",
}) })
cachePath := engine.DataFolder() + "cache/" cachePath := engine.DataFolder() + "cache/"

View File

@ -54,9 +54,9 @@ func init() { // 插件主体
"- 设置ai绘图配置 [server] [token]\n" + "- 设置ai绘图配置 [server] [token]\n" +
"- 设置ai绘图撤回时间90s\n" + "- 设置ai绘图撤回时间90s\n" +
"- 查看ai绘图配置\n" + "- 查看ai绘图配置\n" +
"例: 设置ai绘图配置 http://91.217.139.190:5010 abc\n" + "Tips: 使用前请先前往 http://91.217.139.190:5010/token 按提示获取token" +
"设置token示例(请确保是主人并且响应): 设置ai绘图配置 http://91.217.139.190:5010 [token] (中括号无需输入)\n" +
"参考服务器 http://91.217.139.190:5010, http://91.216.169.75:5010, http://185.80.202.180:5010\n" + "参考服务器 http://91.217.139.190:5010, http://91.216.169.75:5010, http://185.80.202.180:5010\n" +
"通过 http://91.217.139.190:5010/token 获取token\n" +
"[prompt]参数如下\n" + "[prompt]参数如下\n" +
"tags:tag词条\nntags:ntag词条\nshape:[Portrait|Landscape|Square]\nscale:[6:20]\nseed:种子\nstrength:[0-1] 建议0-0.7\nnoise:[0-1] 建议0-0.15" + "tags:tag词条\nntags:ntag词条\nshape:[Portrait|Landscape|Square]\nscale:[6:20]\nseed:种子\nstrength:[0-1] 建议0-0.7\nnoise:[0-1] 建议0-0.15" +
"参数与参数内容用:连接,每个参数之间用回车分割", "参数与参数内容用:连接,每个参数之间用回车分割",
@ -146,7 +146,7 @@ func init() { // 插件主体
} }
sendAiImg(ctx, data, cfg.Interval) sendAiImg(ctx, data, cfg.Interval)
}) })
engine.OnRegex(`^设置ai绘图配置\s(.*[^\s$])\s(.+)$`, zero.SuperUserPermission).SetBlock(true). engine.OnRegex(`^设置ai绘图配置\s(.*[^\s$])\s(.+)$`, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) { Handle(func(ctx *zero.Ctx) {
regexMatched := ctx.State["regex_matched"].([]string) regexMatched := ctx.State["regex_matched"].([]string)
err := cfg.load() err := cfg.load()
@ -159,8 +159,7 @@ func init() { // 插件主体
ctx.SendChain(message.Text("ERROR: ", err)) ctx.SendChain(message.Text("ERROR: ", err))
return return
} }
text := fmt.Sprintf("成功设置\nbase_url: %v\ntoken: %v\ninterval: %v\n", cfg.BaseURL, cfg.Token, cfg.Interval) ctx.SendChain(message.Text("成功设置\nbase_url: ", cfg.BaseURL, "\ntoken: ", cfg.Token, "\ninterval: ", cfg.Interval))
ctx.SendChain(message.Text(text))
}) })
engine.OnRegex(`^设置ai绘图撤回时间(\d{1,3})s$`, zero.SuperUserPermission).SetBlock(true). engine.OnRegex(`^设置ai绘图撤回时间(\d{1,3})s$`, zero.SuperUserPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) { Handle(func(ctx *zero.Ctx) {
@ -180,18 +179,16 @@ func init() { // 插件主体
ctx.SendChain(message.Text("ERROR: ", err)) ctx.SendChain(message.Text("ERROR: ", err))
return return
} }
text := fmt.Sprintf("成功设置\nbase_url: %v\ntoken: %v\ninterval: %v\n", cfg.BaseURL, cfg.Token, cfg.Interval) ctx.SendChain(message.Text("成功设置撤回时间为", cfg.Interval, "s"))
ctx.SendChain(message.Text(text))
}) })
engine.OnFullMatch(`查看ai绘图配置`, zero.SuperUserPermission).SetBlock(true). engine.OnFullMatch(`查看ai绘图配置`, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) { Handle(func(ctx *zero.Ctx) {
err := cfg.load() err := cfg.load()
if err != nil { if err != nil {
ctx.SendChain(message.Text("ERROR: ", err)) ctx.SendChain(message.Text("ERROR: ", err))
return return
} }
text := fmt.Sprintf("base_url: %v\ntoken: %v\ninterval: %v\n", cfg.BaseURL, cfg.Token, cfg.Interval) ctx.SendChain(message.Text("base_url: ", cfg.BaseURL, "\ntoken: ", cfg.Token, "\ninterval: ", cfg.Interval))
ctx.SendChain(message.Text(text))
}) })
} }

View File

@ -53,7 +53,7 @@ func init() {
text := strings.ReplaceAll(cs.Story, "<攻>", gong) text := strings.ReplaceAll(cs.Story, "<攻>", gong)
text = strings.ReplaceAll(text, "<受>", shou) text = strings.ReplaceAll(text, "<受>", shou)
text = strings.ReplaceAll(text, cs.Gong, gong) text = strings.ReplaceAll(text, cs.Gong, gong)
text = strings.ReplaceAll(text, cs.Shou, gong) text = strings.ReplaceAll(text, cs.Shou, shou)
ctx.SendChain(message.Text(text)) ctx.SendChain(message.Text(text))
}) })
engine.OnPrefix("磕cp", getdb).SetBlock(true).Handle(func(ctx *zero.Ctx) { engine.OnPrefix("磕cp", getdb).SetBlock(true).Handle(func(ctx *zero.Ctx) {

View File

@ -129,21 +129,22 @@ func init() { // 插件主体
en := control.Register("gif", &ctrl.Options[*zero.Ctx]{ en := control.Register("gif", &ctrl.Options[*zero.Ctx]{
DisableOnDefault: false, DisableOnDefault: false,
Brief: "制图", Brief: "制图",
Help: "下为制图命令: " + Help: "下为制图命令:\n" +
"- 搓|-冲|-摸|-拍|-丢|-吃|-敲|-啃|-蹭|-爬|-撕|-灰度|-上翻|-下翻\n" + "- 搓|- 冲|- 摸|-拍|- 丢|- 吃|- 敲|- 啃|- 蹭|- 爬|- 撕\n" +
"- 左翻|-右翻|-反色|-浮雕|- 打码|- 负片|- 旋转|- 变形|- 亲\n" + "- 吸|- 嗦|- 扔|- 锤|- 紧贴|紧紧贴着|- 转|- 抬棺|- 远离\n" +
"- 结婚申请|结婚登记|- 阿尼亚喜欢XXX|- 像只|- 我永远喜欢XXX\n" + "- 揍|- 吞|- 膜拜|- 诶嘿|- 2蹭|- 你犯法了|- 砰|- 注意力涣散\n" +
"- 像样的亲亲|- 国旗|- 不要靠近|- 万能表情|-空白表情|- 采访\n" + "- 2敲|- 听音乐|- 永远爱你|- 2拍|- 顶|- 捣|- 打拳|- 滚\n" +
"- 需要|-你可能需要|- 这像画吗|- 小画家|- 完美|- 玩游戏|- 出警\n" + "- 灰度|- 上翻|- 下翻|- 左翻|- 右翻|- 反色|- 浮雕|- 打码\n" +
"- 警察|- 舔|舔屏|prpr|- 安全感|- 精神支柱|- 想什么|- 墙纸\n" + "- 负片|- 旋转|- 变形|- 亲|- 结婚申请|结婚登记|- 阿尼亚喜欢XXX\n" +
"- 为什么at我|- 交个朋友|- 打工人|-继续干活|- 兑换券|- 炖\n" + "- 像只|- 我永远喜欢XXX|- 像样的亲亲|- 国旗|- 不要靠近\n" +
"- 垃圾桶|- 垃圾|- 捶|- 啾啾|- 2敲|- 听音乐|- 永远爱你|- 2拍\n" + "- 蒙蔽|- 踩|- 好玩|- 2转|- 踢球|- 2舔|- 可莉吃|- 胡桃啃|- 怀\n" +
"- 顶|- 捣|- 打拳|- 滚|- 吸|- 嗦|- 扔|- 锤|- 紧贴|紧紧贴着|- 转\n" + "- 小画家|- 完美|- 玩游戏|- 出警|- 警察|- 舔|舔屏|prpr\n" +
"- 抬棺|- 远离|- 我老婆|- 小天使XXX|- 你的XXX|- 不要看\n" + "- 安全感|- 精神支柱|- 想什么|- 墙纸|- 为什么at我|- 交个朋友\n" +
"- 玩一下XXX|- 给我变|- 揍|- 吞|- 膜拜|- 诶嘿|- 2蹭|- 你犯法了\n" + "- 打工人|- 继续干活|- 兑换券|- 炖|- 垃圾桶|- 垃圾|- 捶|- 啾啾\n" +
"- 砰|- 注意力涣散|- 蒙蔽|- 踩|- 好玩|- 2转|- 踢球|- 2舔|\n" + "- 我老婆|- 小天使XXX|- 你的XXX|- 不要看|- 玩一下XXX|- 给我变\n" +
"- 可莉吃|- 胡桃啃|- 怀|- 一直(支持动图)\n" + "- 万能表情|- 空白表情|- 采访|- 需要|- 你可能需要|- 这像画吗\n" +
"例: 制图命令XXX[@用户|QQ号|图片]" + "- 一直(支持动图)\n" +
"例: 制图命令XXX[@用户|QQ号|图片]\n" +
"Tips: XXX可以为限制长度的任何文字\n" + "Tips: XXX可以为限制长度的任何文字\n" +
"对Bot使用为 @Bot制图命令[XXX]@Bot", "对Bot使用为 @Bot制图命令[XXX]@Bot",
PrivateDataFolder: "gif", PrivateDataFolder: "gif",

View File

@ -222,7 +222,7 @@ func init() { // 插件主体
ctx.SendChain(message.Text("那我就不手下留情了~")) ctx.SendChain(message.Text("那我就不手下留情了~"))
}) })
// 修改名片 // 修改名片
engine.OnRegex(`^修改名片.*(\d+).*\s+(.*)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true). engine.OnRegex(`^修改名片.*?(\d+).+?\s*(.*)$`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) { Handle(func(ctx *zero.Ctx) {
if len(ctx.State["regex_matched"].([]string)[2]) > 60 { if len(ctx.State["regex_matched"].([]string)[2]) > 60 {
ctx.SendChain(message.Text("名字太长啦!")) ctx.SendChain(message.Text("名字太长啦!"))
@ -236,30 +236,38 @@ func init() { // 插件主体
ctx.SendChain(message.Text("嗯!已经修改了")) ctx.SendChain(message.Text("嗯!已经修改了"))
}) })
// 修改头衔 // 修改头衔
engine.OnRegex(`^修改头衔.*(\d+).*\s+(.*)$`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true). engine.OnRegex(`^修改头衔.*?(\d+).+?\s*(.*)$`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) { Handle(func(ctx *zero.Ctx) {
if len(ctx.State["regex_matched"].([]string)[1]) > 18 { sptitle := ctx.State["regex_matched"].([]string)[2]
if sptitle == "" {
ctx.SendChain(message.Text("头衔不能为空!"))
return
} else if len(sptitle) > 18 {
ctx.SendChain(message.Text("头衔太长啦!")) ctx.SendChain(message.Text("头衔太长啦!"))
return return
} }
ctx.SetGroupSpecialTitle( ctx.SetGroupSpecialTitle(
ctx.Event.GroupID, ctx.Event.GroupID,
math.Str2Int64(ctx.State["regex_matched"].([]string)[1]), // 被修改群头衔的人 math.Str2Int64(ctx.State["regex_matched"].([]string)[1]), // 被修改群头衔的人
ctx.State["regex_matched"].([]string)[2], // 修改成的群头衔 sptitle, // 修改成的群头衔
) )
ctx.SendChain(message.Text("嗯!已经修改了")) ctx.SendChain(message.Text("嗯!已经修改了"))
}) })
// 申请头衔 // 申请头衔
engine.OnRegex(`^申请头衔\s+(.*)$`, zero.OnlyGroup).SetBlock(true). engine.OnRegex(`^申请头衔\s*(.*)$`, zero.OnlyGroup).SetBlock(true).
Handle(func(ctx *zero.Ctx) { Handle(func(ctx *zero.Ctx) {
if len(ctx.State["regex_matched"].([]string)[1]) > 18 { sptitle := ctx.State["regex_matched"].([]string)[1]
if sptitle == "" {
ctx.SendChain(message.Text("头衔不能为空!"))
return
} else if len(sptitle) > 18 {
ctx.SendChain(message.Text("头衔太长啦!")) ctx.SendChain(message.Text("头衔太长啦!"))
return return
} }
ctx.SetGroupSpecialTitle( ctx.SetGroupSpecialTitle(
ctx.Event.GroupID, ctx.Event.GroupID,
ctx.Event.UserID, // 被修改群头衔的人 ctx.Event.UserID, // 被修改群头衔的人
ctx.State["regex_matched"].([]string)[1], // 修改成的群头衔 sptitle, // 修改成的群头衔
) )
ctx.SendChain(message.Text("嗯!不错的头衔呢~")) ctx.SendChain(message.Text("嗯!不错的头衔呢~"))
}) })

View File

@ -69,7 +69,7 @@ var (
"- 做媒 @攻方QQ @受方QQ\n身为管理, 群友的xing福是要搭把手的(攻受双方好感度越高成功率越高,保底30%概率)\n" + "- 做媒 @攻方QQ @受方QQ\n身为管理, 群友的xing福是要搭把手的(攻受双方好感度越高成功率越高,保底30%概率)\n" +
"--------------------------------\n好感度规则\n--------------------------------\n" + "--------------------------------\n好感度规则\n--------------------------------\n" +
"\"娶群友\"指令好感度随机增加1~5。\n\"A牛B的C\"会导致C恨A, 好感度-5;\nB为了报复A, 好感度+5(什么柜子play)\nA为BC做媒,成功B、C对A好感度+1反之-1\n做媒成功BC好感度+1" + "\"娶群友\"指令好感度随机增加1~5。\n\"A牛B的C\"会导致C恨A, 好感度-5;\nB为了报复A, 好感度+5(什么柜子play)\nA为BC做媒,成功B、C对A好感度+1反之-1\n做媒成功BC好感度+1" +
"Tips: 群老婆列表过0点刷新", "\nTips: 群老婆列表过0点刷新",
PrivateDataFolder: "qqwife", PrivateDataFolder: "qqwife",
}).ApplySingle(single.New( }).ApplySingle(single.New(
single.WithKeyFn(func(ctx *zero.Ctx) int64 { return ctx.Event.GroupID }), single.WithKeyFn(func(ctx *zero.Ctx) int64 { return ctx.Event.GroupID }),

View File

@ -10,9 +10,12 @@ import (
"time" "time"
"github.com/Coloured-glaze/gg" "github.com/Coloured-glaze/gg"
"github.com/FloatTech/AnimeAPI/bilibili"
"github.com/FloatTech/AnimeAPI/wallet"
"github.com/FloatTech/floatbox/file" "github.com/FloatTech/floatbox/file"
"github.com/FloatTech/floatbox/img/writer" "github.com/FloatTech/floatbox/img/writer"
"github.com/FloatTech/floatbox/process" "github.com/FloatTech/floatbox/process"
"github.com/FloatTech/floatbox/web"
ctrl "github.com/FloatTech/zbpctrl" ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control" "github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/ctxext" "github.com/FloatTech/zbputils/ctxext"
@ -23,13 +26,11 @@ import (
"github.com/wcharczuk/go-chart/v2" "github.com/wcharczuk/go-chart/v2"
zero "github.com/wdvxdr1123/ZeroBot" zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message" "github.com/wdvxdr1123/ZeroBot/message"
// 货币系统
"github.com/FloatTech/AnimeAPI/wallet"
) )
const ( const (
backgroundURL = "https://img.moehu.org/pic.php?id=pc" backgroundURL = "https://iw233.cn/api.php?sort=pc"
referer = "https://weibo.com/"
signinMax = 1 signinMax = 1
// SCOREMAX 分数上限定为1200 // SCOREMAX 分数上限定为1200
SCOREMAX = 1200 SCOREMAX = 1200
@ -307,5 +308,13 @@ func initPic(picFile string) error {
return nil return nil
} }
defer process.SleepAbout1sTo2s() defer process.SleepAbout1sTo2s()
return file.DownloadTo(backgroundURL, picFile) url, err := bilibili.GetRealURL(backgroundURL)
if err != nil {
return err
}
data, err := web.RequestDataWith(web.NewDefaultClient(), url, "", referer, "", nil)
if err != nil {
return err
}
return os.WriteFile(picFile, data, 0644)
} }

View File

@ -122,10 +122,6 @@ func init() {
ctx.SendChain(message.Text("ERROR: 张数必须为正")) ctx.SendChain(message.Text("ERROR: 张数必须为正"))
return return
} }
if n > 1 && !zero.OnlyGroup(ctx) {
ctx.SendChain(message.Text("ERROR: 抽取多张仅支持群聊"))
return
}
if n > 20 { if n > 20 {
ctx.SendChain(message.Text("ERROR: 抽取张数过多")) ctx.SendChain(message.Text("ERROR: 抽取张数过多"))
return return