mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-19 05:30:07 +08:00
optimize(chat): avoid conflicts
This commit is contained in:
parent
aacf720b88
commit
552c1a9a35
@ -1548,6 +1548,7 @@ print("run[CQ:image,file="+j["img"]+"]")
|
|||||||
- [x] 设置AI聊天模型名xxx
|
- [x] 设置AI聊天模型名xxx
|
||||||
- [x] 设置AI聊天系统提示词xxx
|
- [x] 设置AI聊天系统提示词xxx
|
||||||
- [x] 设置AI聊天分隔符`</think>`(留空则清除)
|
- [x] 设置AI聊天分隔符`</think>`(留空则清除)
|
||||||
|
- [x] 设置AI聊天(不)响应AT
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
@ -1561,7 +1562,7 @@ print("run[CQ:image,file="+j["img"]+"]")
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
<summary>词典匹配回复</summary>
|
<summary>词典匹配回复, 仅@触发</summary>
|
||||||
|
|
||||||
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/thesaurus"`
|
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/thesaurus"`
|
||||||
|
|
||||||
|
|||||||
2
go.mod
2
go.mod
@ -4,7 +4,7 @@ go 1.20
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Baidu-AIP/golang-sdk v1.1.1
|
github.com/Baidu-AIP/golang-sdk v1.1.1
|
||||||
github.com/FloatTech/AnimeAPI v1.7.1-0.20250214133017-28762c8262a6
|
github.com/FloatTech/AnimeAPI v1.7.1-0.20250217140215-4856397458c9
|
||||||
github.com/FloatTech/floatbox v0.0.0-20241106130736-5aea0a935024
|
github.com/FloatTech/floatbox v0.0.0-20241106130736-5aea0a935024
|
||||||
github.com/FloatTech/gg v1.1.3
|
github.com/FloatTech/gg v1.1.3
|
||||||
github.com/FloatTech/imgfactory v0.2.2-0.20230413152719-e101cc3606ef
|
github.com/FloatTech/imgfactory v0.2.2-0.20230413152719-e101cc3606ef
|
||||||
|
|||||||
4
go.sum
4
go.sum
@ -1,8 +1,8 @@
|
|||||||
github.com/Baidu-AIP/golang-sdk v1.1.1 h1:RQsAmgDSAkiq22I6n7XJ2t3afgzFeqjY46FGhvrx4cw=
|
github.com/Baidu-AIP/golang-sdk v1.1.1 h1:RQsAmgDSAkiq22I6n7XJ2t3afgzFeqjY46FGhvrx4cw=
|
||||||
github.com/Baidu-AIP/golang-sdk v1.1.1/go.mod h1:bXnGw7xPeKt8aF7UCELKrV6UZ/46spItONK1RQBQj1Y=
|
github.com/Baidu-AIP/golang-sdk v1.1.1/go.mod h1:bXnGw7xPeKt8aF7UCELKrV6UZ/46spItONK1RQBQj1Y=
|
||||||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||||
github.com/FloatTech/AnimeAPI v1.7.1-0.20250214133017-28762c8262a6 h1:LxCcLzXCMUJ67I1sDaW1fOFlTxabLR29g+qpSExrGzk=
|
github.com/FloatTech/AnimeAPI v1.7.1-0.20250217140215-4856397458c9 h1:tI9GgG8fdMK2WazFiEbMXAXjwMCckIfDaXbig9B6DdA=
|
||||||
github.com/FloatTech/AnimeAPI v1.7.1-0.20250214133017-28762c8262a6/go.mod h1:XXG1eBJf+eeWacQx5azsQKL5Gg7jDYTFyyZGIa/56js=
|
github.com/FloatTech/AnimeAPI v1.7.1-0.20250217140215-4856397458c9/go.mod h1:XXG1eBJf+eeWacQx5azsQKL5Gg7jDYTFyyZGIa/56js=
|
||||||
github.com/FloatTech/floatbox v0.0.0-20241106130736-5aea0a935024 h1:mrvWpiwfRklt9AyiQjKgDGJjf4YL6FZ3yC+ydbkuF2o=
|
github.com/FloatTech/floatbox v0.0.0-20241106130736-5aea0a935024 h1:mrvWpiwfRklt9AyiQjKgDGJjf4YL6FZ3yC+ydbkuF2o=
|
||||||
github.com/FloatTech/floatbox v0.0.0-20241106130736-5aea0a935024/go.mod h1:+P3hs+Cvl10/Aj3SNE96TuBvKAXCe+XD1pKphTZyiwk=
|
github.com/FloatTech/floatbox v0.0.0-20241106130736-5aea0a935024/go.mod h1:+P3hs+Cvl10/Aj3SNE96TuBvKAXCe+XD1pKphTZyiwk=
|
||||||
github.com/FloatTech/gg v1.1.3 h1:+GlL02lTKsxJQr4WCuNwVxC1/eBZrCvypCIBtxuOFb4=
|
github.com/FloatTech/gg v1.1.3 h1:+GlL02lTKsxJQr4WCuNwVxC1/eBZrCvypCIBtxuOFb4=
|
||||||
|
|||||||
@ -33,7 +33,8 @@ var (
|
|||||||
"- 设置AI聊天密钥xxx\n" +
|
"- 设置AI聊天密钥xxx\n" +
|
||||||
"- 设置AI聊天模型名xxx\n" +
|
"- 设置AI聊天模型名xxx\n" +
|
||||||
"- 设置AI聊天系统提示词xxx\n" +
|
"- 设置AI聊天系统提示词xxx\n" +
|
||||||
"- 设置AI聊天分隔符</think>(留空则清除)",
|
"- 设置AI聊天分隔符</think>(留空则清除)\n" +
|
||||||
|
"- 设置AI聊天(不)响应AT",
|
||||||
PrivateDataFolder: "aichat",
|
PrivateDataFolder: "aichat",
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@ -42,6 +43,7 @@ var (
|
|||||||
modelname = "deepseek-ai/DeepSeek-R1"
|
modelname = "deepseek-ai/DeepSeek-R1"
|
||||||
systemprompt = "你正在QQ群与用户聊天,用户发送了消息。按自己的心情简短思考后条理清晰地回复。"
|
systemprompt = "你正在QQ群与用户聊天,用户发送了消息。按自己的心情简短思考后条理清晰地回复。"
|
||||||
sepstr = ""
|
sepstr = ""
|
||||||
|
noreplyat = false
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -74,7 +76,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
en.OnMessage(func(ctx *zero.Ctx) bool {
|
en.OnMessage(func(ctx *zero.Ctx) bool {
|
||||||
return ctx.ExtractPlainText() != ""
|
return ctx.ExtractPlainText() != "" && (!noreplyat || (noreplyat && !ctx.Event.IsToMe))
|
||||||
}).SetBlock(false).Handle(func(ctx *zero.Ctx) {
|
}).SetBlock(false).Handle(func(ctx *zero.Ctx) {
|
||||||
gid := ctx.Event.GroupID
|
gid := ctx.Event.GroupID
|
||||||
if gid == 0 {
|
if gid == 0 {
|
||||||
@ -270,4 +272,23 @@ func init() {
|
|||||||
}
|
}
|
||||||
ctx.SendChain(message.Text("设置成功"))
|
ctx.SendChain(message.Text("设置成功"))
|
||||||
})
|
})
|
||||||
|
en.OnRegex("^设置AI聊天(不)?响应AT$", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||||
|
args := ctx.State["regex_matched"].([]string)
|
||||||
|
isno := args[1] == "不"
|
||||||
|
fp := en.DataFolder() + "NoReplyAT"
|
||||||
|
if isno {
|
||||||
|
f, err := os.Create(fp)
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("ERROR: ", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
f.WriteString("PLACEHOLDER")
|
||||||
|
noreplyat = true
|
||||||
|
} else {
|
||||||
|
_ = os.Remove(fp)
|
||||||
|
noreplyat = false
|
||||||
|
}
|
||||||
|
ctx.SendChain(message.Text("成功"))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,61 +1,33 @@
|
|||||||
// Package thesaurus 修改过的单纯回复插件
|
// Package thesaurus 修改过的单纯回复插件, 仅@触发
|
||||||
package thesaurus
|
package thesaurus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/FloatTech/floatbox/binary"
|
|
||||||
"github.com/FloatTech/floatbox/ctxext"
|
|
||||||
"github.com/FloatTech/floatbox/file"
|
|
||||||
"github.com/FloatTech/floatbox/process"
|
|
||||||
"github.com/FloatTech/floatbox/web"
|
|
||||||
ctrl "github.com/FloatTech/zbpctrl"
|
|
||||||
"github.com/FloatTech/zbputils/control"
|
|
||||||
"github.com/fumiama/jieba"
|
"github.com/fumiama/jieba"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
zero "github.com/wdvxdr1123/ZeroBot"
|
zero "github.com/wdvxdr1123/ZeroBot"
|
||||||
"github.com/wdvxdr1123/ZeroBot/message"
|
"github.com/wdvxdr1123/ZeroBot/message"
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
|
"github.com/FloatTech/AnimeAPI/kimoi"
|
||||||
|
"github.com/FloatTech/floatbox/ctxext"
|
||||||
|
"github.com/FloatTech/floatbox/process"
|
||||||
|
ctrl "github.com/FloatTech/zbpctrl"
|
||||||
|
"github.com/FloatTech/zbputils/control"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
|
engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
|
||||||
DisableOnDefault: false,
|
DisableOnDefault: false,
|
||||||
Brief: "词典匹配回复",
|
Brief: "词典匹配回复, 仅@触发",
|
||||||
Help: "- 切换[kimo|傲娇|可爱|🦙]词库\n- 设置词库触发概率0.x (0<x<9)",
|
Help: "- 切换[kimo|傲娇|可爱]词库",
|
||||||
PublicDataFolder: "Chat",
|
PublicDataFolder: "Chat",
|
||||||
})
|
})
|
||||||
alpacafolder := engine.DataFolder() + "alpaca/"
|
engine.OnRegex(`^切换(kimo|傲娇|可爱)词库$`, zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||||
err := os.MkdirAll(alpacafolder, 0755)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
alpacapifile := alpacafolder + "api.txt"
|
|
||||||
alpacapiurl := ""
|
|
||||||
if file.IsExist(alpacapifile) {
|
|
||||||
data, err := os.ReadFile(alpacapifile)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
alpacapiurl = binary.BytesToString(data)
|
|
||||||
}
|
|
||||||
alpacatokenfile := alpacafolder + "token.txt"
|
|
||||||
alpacatoken := ""
|
|
||||||
if file.IsExist(alpacatokenfile) {
|
|
||||||
data, err := os.ReadFile(alpacatokenfile)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
alpacatoken = binary.BytesToString(data)
|
|
||||||
}
|
|
||||||
engine.OnRegex(`^切换(kimo|傲娇|可爱|🦙)词库$`, zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
|
||||||
c, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
|
c, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
|
||||||
if !ok {
|
if !ok {
|
||||||
ctx.SendChain(message.Text("ERROR: 找不到 manager"))
|
ctx.SendChain(message.Text("ERROR: 找不到 manager"))
|
||||||
@ -74,8 +46,6 @@ func init() {
|
|||||||
t = tDERE
|
t = tDERE
|
||||||
case "可爱":
|
case "可爱":
|
||||||
t = tKAWA
|
t = tKAWA
|
||||||
case "🦙":
|
|
||||||
t = tALPACA
|
|
||||||
}
|
}
|
||||||
err := c.SetData(gid, (d&^3)|t)
|
err := c.SetData(gid, (d&^3)|t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -84,48 +54,6 @@ func init() {
|
|||||||
}
|
}
|
||||||
ctx.SendChain(message.Text("成功!"))
|
ctx.SendChain(message.Text("成功!"))
|
||||||
})
|
})
|
||||||
engine.OnRegex(`^设置词库触发概率\s*0.(\d)$`, zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
|
||||||
c, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
|
|
||||||
if !ok {
|
|
||||||
ctx.SendChain(message.Text("ERROR: 找不到 manager"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n := ctx.State["regex_matched"].([]string)[1][0] - '0'
|
|
||||||
if n <= 0 || n >= 9 {
|
|
||||||
ctx.SendChain(message.Text("ERROR: 概率越界"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n-- // 0~7
|
|
||||||
gid := ctx.Event.GroupID
|
|
||||||
if gid == 0 {
|
|
||||||
gid = -ctx.Event.UserID
|
|
||||||
}
|
|
||||||
d := c.GetData(gid)
|
|
||||||
err := c.SetData(gid, (d&3)|(int64(n)<<59))
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR: ", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.SendChain(message.Text("成功!"))
|
|
||||||
})
|
|
||||||
engine.OnRegex(`^设置🦙API地址\s*(http.*)\s*$`, zero.SuperUserPermission, zero.OnlyPrivate).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
|
||||||
alpacapiurl = ctx.State["regex_matched"].([]string)[1]
|
|
||||||
err := os.WriteFile(alpacapifile, binary.StringToBytes(alpacapiurl), 0644)
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR: ", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.SendChain(message.Text("成功!"))
|
|
||||||
})
|
|
||||||
engine.OnRegex(`^设置🦙token\s*([0-9a-f]{112})\s*$`, zero.SuperUserPermission, zero.OnlyPrivate).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
|
||||||
alpacatoken = ctx.State["regex_matched"].([]string)[1]
|
|
||||||
err := os.WriteFile(alpacatokenfile, binary.StringToBytes(alpacatoken), 0644)
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR: ", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.SendChain(message.Text("成功!"))
|
|
||||||
})
|
|
||||||
go func() {
|
go func() {
|
||||||
data, err := engine.GetLazyData("dict.txt", false)
|
data, err := engine.GetLazyData("dict.txt", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -144,21 +72,6 @@ func init() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
data, err = engine.GetLazyData("kimoi.json", false)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
kimomap := make(kimo, 256)
|
|
||||||
err = json.Unmarshal(data, &kimomap)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
chatList := make([]string, 0, len(kimomap))
|
|
||||||
for k := range kimomap {
|
|
||||||
chatList = append(chatList, k)
|
|
||||||
}
|
|
||||||
logrus.Infoln("[thesaurus]加载", len(chatList), "条kimoi")
|
|
||||||
|
|
||||||
chatListD := make([]string, 0, len(sm.D))
|
chatListD := make([]string, 0, len(sm.D))
|
||||||
for k := range sm.D {
|
for k := range sm.D {
|
||||||
chatListD = append(chatListD, k)
|
chatListD = append(chatListD, k)
|
||||||
@ -169,86 +82,32 @@ func init() {
|
|||||||
}
|
}
|
||||||
logrus.Infoln("[thesaurus]加载", len(chatListD), "条傲娇词库", len(chatListK), "条可爱词库")
|
logrus.Infoln("[thesaurus]加载", len(chatListD), "条傲娇词库", len(chatListK), "条可爱词库")
|
||||||
|
|
||||||
engine.OnMessage(canmatch(tKIMO), match(chatList, seg)).
|
engine.OnMessage(zero.OnlyToMe, canmatch(tKIMO)).
|
||||||
SetBlock(false).
|
SetBlock(false).Handle(func(ctx *zero.Ctx) {
|
||||||
Handle(randreply(kimomap))
|
r, err := kimoi.Chat(ctx.ExtractPlainText())
|
||||||
engine.OnMessage(canmatch(tDERE), match(chatListD, seg)).
|
if err == nil && r.Confidence > 0.5 && r.Confidence < 0.95 {
|
||||||
SetBlock(false).
|
ctx.Block()
|
||||||
Handle(randreply(sm.D))
|
ctx.SendChain(message.Text(r.Reply))
|
||||||
engine.OnMessage(canmatch(tKAWA), match(chatListK, seg)).
|
|
||||||
SetBlock(false).
|
|
||||||
Handle(randreply(sm.K))
|
|
||||||
engine.OnMessage(canmatch(tALPACA), func(_ *zero.Ctx) bool {
|
|
||||||
return alpacapiurl != "" && alpacatoken != ""
|
|
||||||
}).SetBlock(false).Handle(func(ctx *zero.Ctx) {
|
|
||||||
msg := ctx.ExtractPlainText()
|
|
||||||
if msg != "" {
|
|
||||||
data, err := web.RequestDataWithHeaders(http.DefaultClient, alpacapiurl+"/reply", "POST",
|
|
||||||
func(r *http.Request) error {
|
|
||||||
r.Header.Set("Authorization", alpacatoken)
|
|
||||||
return nil
|
|
||||||
}, bytes.NewReader(binary.NewWriterF(func(writer *binary.Writer) {
|
|
||||||
_ = json.NewEncoder(writer).Encode(&[]alpacamsg{{
|
|
||||||
Name: ctx.CardOrNickName(ctx.Event.UserID),
|
|
||||||
Message: msg,
|
|
||||||
}})
|
|
||||||
})))
|
|
||||||
if err != nil {
|
|
||||||
logrus.Warnln("[chat] 🦙 err:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
type reply struct {
|
|
||||||
ID int
|
|
||||||
Msg string
|
|
||||||
}
|
|
||||||
m := reply{}
|
|
||||||
err = json.Unmarshal(data, &m)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Warnln("[chat] 🦙 unmarshal err:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < 60; i++ {
|
|
||||||
time.Sleep(time.Second * 4)
|
|
||||||
data, err := web.RequestDataWithHeaders(http.DefaultClient, alpacapiurl+"/get?id="+strconv.Itoa(m.ID), "GET",
|
|
||||||
func(r *http.Request) error {
|
|
||||||
r.Header.Set("Authorization", alpacatoken)
|
|
||||||
return nil
|
|
||||||
}, nil)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
err = json.Unmarshal(data, &m)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Warnln("[chat] 🦙 unmarshal err:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(m.Msg) > 0 {
|
|
||||||
ctx.Send(message.Text(m.Msg))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
engine.OnMessage(zero.OnlyToMe, canmatch(tDERE), match(chatListD, seg)).
|
||||||
|
SetBlock(false).
|
||||||
|
Handle(randreply(sm.D))
|
||||||
|
engine.OnMessage(zero.OnlyToMe, canmatch(tKAWA), match(chatListK, seg)).
|
||||||
|
SetBlock(false).
|
||||||
|
Handle(randreply(sm.K))
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
type kimo = map[string][]string
|
|
||||||
|
|
||||||
type simai struct {
|
type simai struct {
|
||||||
D map[string][]string `yaml:"傲娇"`
|
D map[string][]string `yaml:"傲娇"`
|
||||||
K map[string][]string `yaml:"可爱"`
|
K map[string][]string `yaml:"可爱"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type alpacamsg struct {
|
|
||||||
Name string
|
|
||||||
Message string
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
tKIMO = iota
|
tKIMO = iota
|
||||||
tDERE
|
tDERE
|
||||||
tKAWA
|
tKAWA
|
||||||
tALPACA
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func match(l []string, seg *jieba.Segmenter) zero.Rule {
|
func match(l []string, seg *jieba.Segmenter) zero.Rule {
|
||||||
@ -273,12 +132,13 @@ func canmatch(typ int64) zero.Rule {
|
|||||||
gid = -ctx.Event.UserID
|
gid = -ctx.Event.UserID
|
||||||
}
|
}
|
||||||
d := c.GetData(gid)
|
d := c.GetData(gid)
|
||||||
return d&3 == typ && rand.Int63n(10) <= d>>59
|
return ctx.ExtractPlainText() != "" && d&3 == typ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func randreply(m map[string][]string) zero.Handler {
|
func randreply(m map[string][]string) zero.Handler {
|
||||||
return func(ctx *zero.Ctx) {
|
return func(ctx *zero.Ctx) {
|
||||||
|
ctx.Block()
|
||||||
key := ctx.State["matched"].(string)
|
key := ctx.State["matched"].(string)
|
||||||
val := m[key]
|
val := m[key]
|
||||||
nick := zero.BotConfig.NickName[rand.Intn(len(zero.BotConfig.NickName))]
|
nick := zero.BotConfig.NickName[rand.Intn(len(zero.BotConfig.NickName))]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user