From 2df52161e5bcffc2494123c833a87a4de3c12cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BA=90=E6=96=87=E9=9B=A8?= <41315874+fumiama@users.noreply.github.com> Date: Sun, 30 Mar 2025 21:36:31 +0900 Subject: [PATCH] feat(aichat): add OLLaMA & GenAI support --- go.mod | 10 ++-- go.sum | 20 +++---- plugin/aichat/main.go | 113 +++++++++++++++++++++++++++++------ plugin/manager/manager.go | 6 +- plugin/niuniu/main.go | 2 +- plugin/qqwife/favorSystem.go | 4 +- plugin/qqwife/function.go | 6 +- 7 files changed, 119 insertions(+), 42 deletions(-) diff --git a/go.mod b/go.mod index ab73daa6..3b80190e 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/FloatTech/sqlite v1.7.1 github.com/FloatTech/ttl v0.0.0-20240716161252-965925764562 github.com/FloatTech/zbpctrl v1.7.0 - github.com/FloatTech/zbputils v1.7.2-0.20250329045338-867cbba7dd6e + github.com/FloatTech/zbputils v1.7.2-0.20250329125132-70de78bc2407 github.com/RomiChan/syncx v0.0.0-20240418144900-b7402ffdebc7 github.com/RomiChan/websocket v1.4.3-0.20220227141055-9b2c6168c9c5 github.com/Tnze/go-mc v1.20.2 @@ -22,7 +22,7 @@ require ( github.com/disintegration/imaging v1.6.2 github.com/fumiama/ahsai v0.1.0 github.com/fumiama/cron v1.3.0 - github.com/fumiama/deepinfra v0.0.0-20250222123807-c64d9d26d2f8 + github.com/fumiama/deepinfra v0.0.0-20250329170232-577f83008e8d github.com/fumiama/go-base16384 v1.7.0 github.com/fumiama/go-registry v0.2.7 github.com/fumiama/gotracemoe v0.0.3 @@ -44,7 +44,7 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/tidwall/gjson v1.18.0 github.com/wcharczuk/go-chart/v2 v2.1.2 - github.com/wdvxdr1123/ZeroBot v1.8.0 + github.com/wdvxdr1123/ZeroBot v1.8.2-0.20250329125451-74392a01085b gitlab.com/gomidi/midi/v2 v2.1.7 golang.org/x/image v0.24.0 golang.org/x/sys v0.30.0 @@ -61,7 +61,7 @@ require ( github.com/faiface/beep v1.1.0 // indirect github.com/fumiama/go-simple-protobuf v0.2.0 // indirect github.com/fumiama/gofastTEA v0.0.10 // indirect - github.com/fumiama/imgsz v0.0.4 // indirect + github.com/fumiama/imgsz v0.0.2 // indirect github.com/gabriel-vasile/mimetype v1.0.4 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect @@ -86,7 +86,7 @@ require ( github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - golang.org/x/exp/shiny v0.0.0-20250210185358-939b2ce775ac // indirect + golang.org/x/exp/shiny v0.0.0-20250305212735-054e65f0b394 // indirect golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a // indirect golang.org/x/net v0.33.0 // indirect modernc.org/libc v1.61.0 // indirect diff --git a/go.sum b/go.sum index 45e45112..48808fa0 100644 --- a/go.sum +++ b/go.sum @@ -17,8 +17,8 @@ github.com/FloatTech/ttl v0.0.0-20240716161252-965925764562 h1:snfw7FNFym1eNnLrQ github.com/FloatTech/ttl v0.0.0-20240716161252-965925764562/go.mod h1:fHZFWGquNXuHttu9dUYoKuNbm3dzLETnIOnm1muSfDs= github.com/FloatTech/zbpctrl v1.7.0 h1:Hxo6EIhJo+pHjcQP9QgIJgluaT1pHH99zkk3njqTNMo= github.com/FloatTech/zbpctrl v1.7.0/go.mod h1:xmM4dSwHA02Gei3ogCRiG+RTrw/7Z69PfrN5NYf8BPE= -github.com/FloatTech/zbputils v1.7.2-0.20250329045338-867cbba7dd6e h1:gUJCtinmohHTHrYLQXoMqsmFLhPwexOyzuOrXXtRZb8= -github.com/FloatTech/zbputils v1.7.2-0.20250329045338-867cbba7dd6e/go.mod h1:2nILgq7ps2fLsfhns1/L2yCAM2OfIwWbEl28yLztuzk= +github.com/FloatTech/zbputils v1.7.2-0.20250329125132-70de78bc2407 h1:2+cY/Yn30x8hOczSvnU/lnj/jgtxmGyfOfv0eJn5GQI= +github.com/FloatTech/zbputils v1.7.2-0.20250329125132-70de78bc2407/go.mod h1:LOBLheF9yCSSYAA85MtkQNyVYP1DblttTLk5OYFbtpk= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/RomiChan/syncx v0.0.0-20240418144900-b7402ffdebc7 h1:S/ferNiehVjNaBMNNBxUjLtVmP/YWD6Yh79RfPv4ehU= github.com/RomiChan/syncx v0.0.0-20240418144900-b7402ffdebc7/go.mod h1:vD7Ra3Q9onRtojoY5sMCLQ7JBgjUsrXDnDKyFxqpf9w= @@ -59,8 +59,8 @@ github.com/fumiama/ahsai v0.1.0 h1:LXD61Kaj6kJHa3AEGsLIfKNzcgaVxg7JB72OR4yNNZ4= github.com/fumiama/ahsai v0.1.0/go.mod h1:fFeNnqgo44i8FIaguK659aQryuZeFy+4klYLQu/rfdk= github.com/fumiama/cron v1.3.0 h1:ZWlwuexF+HQHl3cYytEE5HNwD99q+3vNZF1GrEiXCFo= github.com/fumiama/cron v1.3.0/go.mod h1:bz5Izvgi/xEUI8tlBN8BI2jr9Moo8N4or0KV8xXuPDY= -github.com/fumiama/deepinfra v0.0.0-20250222123807-c64d9d26d2f8 h1:T3i87JQ1CR+9jyHXjhIWEUR9yO9gvOzRRlboeWHLtz0= -github.com/fumiama/deepinfra v0.0.0-20250222123807-c64d9d26d2f8/go.mod h1:wW05PQSn8mo1mZIoa6LBUE+3xIBjkoONvnfPTV5ZOhY= +github.com/fumiama/deepinfra v0.0.0-20250329170232-577f83008e8d h1:LCiYR+AbnDn8QV3s8yJrE+N340s3KwkvLjmDDQbWYvs= +github.com/fumiama/deepinfra v0.0.0-20250329170232-577f83008e8d/go.mod h1:wW05PQSn8mo1mZIoa6LBUE+3xIBjkoONvnfPTV5ZOhY= github.com/fumiama/go-base16384 v1.7.0 h1:6fep7XPQWxRlh4Hu+KsdH+6+YdUp+w6CwRXtMWSsXCA= github.com/fumiama/go-base16384 v1.7.0/go.mod h1:OEn+947GV5gsbTAnyuUW/SrfxJYUdYupSIQXOuGOcXM= github.com/fumiama/go-registry v0.2.7 h1:tLEqgEpsiybQMqBv0dLHm5leia/z1DhajMupwnOHeNs= @@ -71,8 +71,8 @@ github.com/fumiama/gofastTEA v0.0.10 h1:JJJ+brWD4kie+mmK2TkspDXKzqq0IjXm89aGYfoG github.com/fumiama/gofastTEA v0.0.10/go.mod h1:RIdbYZyB4MbH6ZBlPymRaXn3cD6SedlCu5W/HHfMPBk= github.com/fumiama/gotracemoe v0.0.3 h1:iI5EbE9A3UUbfukG6+/soYPjp1S31eCNYf4tw7s6/Jc= github.com/fumiama/gotracemoe v0.0.3/go.mod h1:tyqahdUzHf0bQIAVY/GYmDWvYYe5ik1ZbhnGYh+zl40= -github.com/fumiama/imgsz v0.0.4 h1:Lsasu2hdSSFS+vnD+nvR1UkiRMK7hcpyYCC0FzgSMFI= -github.com/fumiama/imgsz v0.0.4/go.mod h1:bISOQVTlw9sRytPwe8ir7tAaEmyz9hSNj9n8mXMBG0E= +github.com/fumiama/imgsz v0.0.2 h1:fAkC0FnIscdKOXwAxlyw3EUba5NzxZdSxGaq3Uyfxak= +github.com/fumiama/imgsz v0.0.2/go.mod h1:dR71mI3I2O5u6+PCpd47M9TZptzP+39tRBcbdIkoqM4= github.com/fumiama/jieba v0.0.0-20221203025406-36c17a10b565 h1:sQuR2+N5HurnvsZhiKdEg+Ig354TaqgCQRxd/0KgIOQ= github.com/fumiama/jieba v0.0.0-20221203025406-36c17a10b565/go.mod h1:UUEvyLTJ7yoOA/viKG4wEis4ERydM7+Ny6gZUWgkS80= github.com/fumiama/libc v0.0.0-20240530081950-6f6d8586b5c5 h1:jDxsIupsT84A6WHcs6kWbst+KqrRQ8/o0VyoFMnbBOA= @@ -194,8 +194,8 @@ github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+F github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/wcharczuk/go-chart/v2 v2.1.2 h1:Y17/oYNuXwZg6TFag06qe8sBajwwsuvPiJJXcUcLL6E= github.com/wcharczuk/go-chart/v2 v2.1.2/go.mod h1:Zi4hbaqlWpYajnXB2K22IUYVXRXaLfSGNNR7P4ukyyQ= -github.com/wdvxdr1123/ZeroBot v1.8.0 h1:v7m+0kGtL6XQlUH9O/LzmOntDJs2clzVj93YsAWWMbk= -github.com/wdvxdr1123/ZeroBot v1.8.0/go.mod h1:C86nQ0gIdAri4K2vg8IIQIslt08zzrKMcqYt8zhkx1M= +github.com/wdvxdr1123/ZeroBot v1.8.2-0.20250329125451-74392a01085b h1:JCnjOzTIOUmNaIbNnWu2ICYyVkbujl+xjuINNgSQeBM= +github.com/wdvxdr1123/ZeroBot v1.8.2-0.20250329125451-74392a01085b/go.mod h1:C86nQ0gIdAri4K2vg8IIQIslt08zzrKMcqYt8zhkx1M= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= @@ -211,8 +211,8 @@ golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp/shiny v0.0.0-20250210185358-939b2ce775ac h1:v0JK6d+F5Wcwvfz5i1UMwk2jaCEC0jkGM1xYmr6n3VQ= -golang.org/x/exp/shiny v0.0.0-20250210185358-939b2ce775ac/go.mod h1:3F+MieQB7dRYLTmnncoFbb1crS5lfQoTfDgQy6K4N0o= +golang.org/x/exp/shiny v0.0.0-20250305212735-054e65f0b394 h1:bFYqOIMdeiCEdzPJkLiOoMDzW/v3tjW4AA/RmUZYsL8= +golang.org/x/exp/shiny v0.0.0-20250305212735-054e65f0b394/go.mod h1:ygj7T6vSGhhm/9yTpOQQNvuAUFziTH7RUiH74EoE2C8= golang.org/x/image v0.0.0-20190220214146-31aff87c08e9/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= diff --git a/plugin/aichat/main.go b/plugin/aichat/main.go index 85659425..8e35ec3f 100644 --- a/plugin/aichat/main.go +++ b/plugin/aichat/main.go @@ -6,8 +6,6 @@ import ( "os" "strconv" "strings" - "sync/atomic" - "unsafe" "github.com/fumiama/deepinfra" "github.com/fumiama/deepinfra/model" @@ -24,13 +22,15 @@ import ( ) var ( - api *deepinfra.API - en = control.AutoRegister(&ctrl.Options[*zero.Ctx]{ + // en data [4 type] [8 temp] [8 rate] LSB + en = control.AutoRegister(&ctrl.Options[*zero.Ctx]{ DisableOnDefault: false, Extra: control.ExtraFromString("aichat"), Brief: "OpenAI聊天", Help: "- 设置AI聊天触发概率10\n" + "- 设置AI聊天温度80\n" + + "- 设置AI聊天接口类型[OpenAI|OLLaMA|GenAI]\n" + + "- 设置AI聊天接口地址https://xxx\n" + "- 设置AI聊天密钥xxx\n" + "- 设置AI聊天模型名xxx\n" + "- 重置AI聊天系统提示词\n" + @@ -44,14 +44,22 @@ var ( var ( modelname = model.ModelDeepDeek systemprompt = chat.SystemPrompt + api = deepinfra.OpenAIDeepInfra sepstr = "" noreplyat = false ) +var apitypes = map[string]uint8{ + "OpenAI": 0, + "OLLaMA": 1, + "GenAI": 2, +} + func init() { mf := en.DataFolder() + "model.txt" sf := en.DataFolder() + "system.txt" pf := en.DataFolder() + "sep.txt" + af := en.DataFolder() + "api.txt" nf := en.DataFolder() + "NoReplyAT" if file.IsExist(mf) { data, err := os.ReadFile(mf) @@ -77,6 +85,14 @@ func init() { sepstr = string(data) } } + if file.IsExist(af) { + data, err := os.ReadFile(af) + if err != nil { + logrus.Warnln("read api", err) + } else { + api = string(data) + } + } noreplyat = file.IsExist(nf) en.OnMessage(func(ctx *zero.Ctx) bool { @@ -92,6 +108,7 @@ func init() { } rate := c.GetData(gid) temp := (rate >> 8) & 0xff + typ := (rate >> 16) & 0x0f rate &= 0xff if !ctx.Event.IsToMe && rand.Intn(100) >= int(rate) { return @@ -109,14 +126,7 @@ func init() { logrus.Warnln("ERROR: get extra err: empty key") return } - var x deepinfra.API - y := &x - if api == nil { - x = deepinfra.NewAPI(deepinfra.APIDeepInfra, key) - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&api)), unsafe.Pointer(&x)) - } else { - y = api - } + if temp <= 0 { temp = 70 // default setting } @@ -124,14 +134,39 @@ func init() { temp = 100 } - data, err := y.Request(chat.Ask(model.NewOpenAI( - modelname, sepstr, - float32(temp)/100, 0.9, 4096, - ), gid, systemprompt)) - if err != nil { - logrus.Warnln("[niniqun] post err:", err) + var x deepinfra.API + var mod model.Protocol + + switch typ { + case 0: + x = deepinfra.NewAPI(api, key) + mod = model.NewOpenAI( + modelname, sepstr, + float32(temp)/100, 0.9, 4096, + ) + case 1: + x = deepinfra.NewAPI(api, key) + mod = model.NewOLLaMA( + modelname, sepstr, + float32(temp)/100, 0.9, 4096, + ) + case 2: + x = deepinfra.NewAPI(api, key) + mod = model.NewGenAI( + modelname, + float32(temp)/100, 0.9, 4096, + ) + default: + logrus.Warnln("[aichat] unsupported AI type", typ) return } + + data, err := x.Request(chat.Ask(mod, gid, systemprompt)) + if err != nil { + logrus.Warnln("[aichat] post err:", err) + return + } + txt := chat.Sanitize(strings.Trim(data, "\n  ")) if len(txt) > 0 { chat.Reply(gid, txt) @@ -221,6 +256,48 @@ func init() { } ctx.SendChain(message.Text("成功")) }) + en.OnPrefix("设置AI聊天接口类型", zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) { + args := strings.TrimSpace(ctx.State["args"].(string)) + if args == "" { + ctx.SendChain(message.Text("ERROR: empty args")) + return + } + c, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]) + if !ok { + ctx.SendChain(message.Text("ERROR: no such plugin")) + return + } + typ, ok := apitypes[args] + if !ok { + ctx.SendChain(message.Text("ERROR: 未知类型 ", args)) + return + } + gid := ctx.Event.GroupID + if gid == 0 { + gid = -ctx.Event.UserID + } + val := c.GetData(gid) & (^0x0f0000) + err := c.SetData(gid, val|(int64(typ&0x0f)<<16)) + if err != nil { + ctx.SendChain(message.Text("ERROR: set data err: ", err)) + return + } + ctx.SendChain(message.Text("成功")) + }) + en.OnPrefix("设置AI聊天接口地址", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) { + args := strings.TrimSpace(ctx.State["args"].(string)) + if args == "" { + ctx.SendChain(message.Text("ERROR: empty args")) + return + } + api = args + err := os.WriteFile(af, []byte(args), 0644) + if err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) + return + } + ctx.SendChain(message.Text("成功")) + }) en.OnPrefix("设置AI聊天密钥", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) { args := strings.TrimSpace(ctx.State["args"].(string)) if args == "" { diff --git a/plugin/manager/manager.go b/plugin/manager/manager.go index e6cfc056..f1a6f788 100644 --- a/plugin/manager/manager.go +++ b/plugin/manager/manager.go @@ -156,7 +156,7 @@ func init() { // 插件主体 ctx.SendChain(message.Text("全员自闭结束~")) }) // 禁言 - engine.OnMessage(zero.NewPattern().Text("^禁言").At().Text("(\\d+)\\s*(.*)").AsRule(), zero.OnlyGroup, zero.AdminPermission).SetBlock(true). + engine.OnMessage(zero.NewPattern(nil).Text("^禁言").At().Text("(\\d+)\\s*(.*)").AsRule(), zero.OnlyGroup, zero.AdminPermission).SetBlock(true). Handle(func(ctx *zero.Ctx) { parsed := ctx.State[zero.KeyPattern].([]zero.PatternParsed) duration := math.Str2Int64(parsed[2].Text()[1]) @@ -650,7 +650,7 @@ func init() { // 插件主体 if rsp.RetCode == 0 { ctx.SendChain(message.Text(option, "成功")) } else { - ctx.SendChain(message.Text(option, "失败, 信息: ", rsp.Msg, "解释: ", rsp.Wording)) + ctx.SendChain(message.Text(option, "失败, 信息: ", rsp.Message, "解释: ", rsp.Wording)) } }) engine.OnCommand("精华列表", zero.OnlyGroup, zero.AdminPermission).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) { @@ -699,7 +699,7 @@ func init() { // 插件主体 if rsp.RetCode == 0 { ctx.SendChain(message.Text("取消成功")) } else { - ctx.SendChain(message.Text("取消失败, 信息: ", rsp.Msg, "解释: ", rsp.Wording)) + ctx.SendChain(message.Text("取消失败, 信息: ", rsp.Message, "解释: ", rsp.Wording)) } }) } diff --git a/plugin/niuniu/main.go b/plugin/niuniu/main.go index 71e69778..40028efb 100644 --- a/plugin/niuniu/main.go +++ b/plugin/niuniu/main.go @@ -308,7 +308,7 @@ func init() { } ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(msg)) }) - en.OnMessage(zero.NewPattern().Text(`^(?:.*使用(.*))??jj`).At().AsRule(), + en.OnMessage(zero.NewPattern(nil).Text(`^(?:.*使用(.*))??jj`).At().AsRule(), zero.OnlyGroup).SetBlock(true).Limit(func(ctx *zero.Ctx) *rate.Limiter { lt := jjLimiter.Load(fmt.Sprintf("%d_%d", ctx.Event.GroupID, ctx.Event.UserID)) ctx.State["jj_last_touch"] = lt.LastTouch() diff --git a/plugin/qqwife/favorSystem.go b/plugin/qqwife/favorSystem.go index eb873ef3..af370c1f 100644 --- a/plugin/qqwife/favorSystem.go +++ b/plugin/qqwife/favorSystem.go @@ -32,7 +32,7 @@ type favorability struct { func init() { // 好感度系统 - engine.OnMessage(zero.NewPattern().Text(`^查好感度`).At().AsRule(), zero.OnlyGroup, getdb).SetBlock(true).Limit(ctxext.LimitByUser). + engine.OnMessage(zero.NewPattern(nil).Text(`^查好感度`).At().AsRule(), zero.OnlyGroup, getdb).SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { patternParsed := ctx.State[zero.KeyPattern].([]zero.PatternParsed) fiancee, _ := strconv.ParseInt(patternParsed[1].At(), 10, 64) @@ -49,7 +49,7 @@ func init() { ) }) // 礼物系统 - engine.OnMessage(zero.NewPattern().Text(`^买礼物给`).At().AsRule(), zero.OnlyGroup, getdb).SetBlock(true).Limit(ctxext.LimitByUser). + engine.OnMessage(zero.NewPattern(nil).Text(`^买礼物给`).At().AsRule(), zero.OnlyGroup, getdb).SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { gid := ctx.Event.GroupID uid := ctx.Event.UserID diff --git a/plugin/qqwife/function.go b/plugin/qqwife/function.go index def5c3c3..dd9a3392 100644 --- a/plugin/qqwife/function.go +++ b/plugin/qqwife/function.go @@ -93,7 +93,7 @@ func init() { ctx.SendChain(message.Text("设置成功")) }) // 单身技能 - engine.OnMessage(zero.NewPattern().Text(`^(娶|嫁)`).At().AsRule(), zero.OnlyGroup, getdb, checkSingleDog).SetBlock(true).Limit(ctxext.LimitByUser). + engine.OnMessage(zero.NewPattern(nil).Text(`^(娶|嫁)`).At().AsRule(), zero.OnlyGroup, getdb, checkSingleDog).SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { gid := ctx.Event.GroupID uid := ctx.Event.UserID @@ -168,7 +168,7 @@ func init() { ) }) // NTR技能 - engine.OnMessage(zero.NewPattern().Text(`^当`).At().Text(`的小三`).AsRule(), zero.OnlyGroup, getdb, checkMistress).SetBlock(true).Limit(ctxext.LimitByUser). + engine.OnMessage(zero.NewPattern(nil).Text(`^当`).At().Text(`的小三`).AsRule(), zero.OnlyGroup, getdb, checkMistress).SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { gid := ctx.Event.GroupID uid := ctx.Event.UserID @@ -254,7 +254,7 @@ func init() { ) }) // 做媒技能 - engine.OnMessage(zero.NewPattern().Text(`做媒`).At().At().AsRule(), zero.OnlyGroup, zero.AdminPermission, getdb, checkMatchmaker).SetBlock(true).Limit(ctxext.LimitByUser). + engine.OnMessage(zero.NewPattern(nil).Text(`做媒`).At().At().AsRule(), zero.OnlyGroup, zero.AdminPermission, getdb, checkMatchmaker).SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { gid := ctx.Event.GroupID uid := ctx.Event.UserID