Skip to content

Commit 552c1a9

Browse files
committed
optimize(chat): avoid conflicts
1 parent aacf720 commit 552c1a9

File tree

5 files changed

+52
-170
lines changed

5 files changed

+52
-170
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1548,6 +1548,7 @@ print("run[CQ:image,file="+j["img"]+"]")
15481548
- [x] 设置AI聊天模型名xxx
15491549
- [x] 设置AI聊天系统提示词xxx
15501550
- [x] 设置AI聊天分隔符`</think>`(留空则清除)
1551+
- [x] 设置AI聊天(不)响应AT
15511552

15521553
</details>
15531554
<details>
@@ -1561,7 +1562,7 @@ print("run[CQ:image,file="+j["img"]+"]")
15611562

15621563
</details>
15631564
<details>
1564-
<summary>词典匹配回复</summary>
1565+
<summary>词典匹配回复, 仅@触发</summary>
15651566

15661567
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/thesaurus"`
15671568

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ go 1.20
44

55
require (
66
github.com/Baidu-AIP/golang-sdk v1.1.1
7-
github.com/FloatTech/AnimeAPI v1.7.1-0.20250214133017-28762c8262a6
7+
github.com/FloatTech/AnimeAPI v1.7.1-0.20250217140215-4856397458c9
88
github.com/FloatTech/floatbox v0.0.0-20241106130736-5aea0a935024
99
github.com/FloatTech/gg v1.1.3
1010
github.com/FloatTech/imgfactory v0.2.2-0.20230413152719-e101cc3606ef

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
github.com/Baidu-AIP/golang-sdk v1.1.1 h1:RQsAmgDSAkiq22I6n7XJ2t3afgzFeqjY46FGhvrx4cw=
22
github.com/Baidu-AIP/golang-sdk v1.1.1/go.mod h1:bXnGw7xPeKt8aF7UCELKrV6UZ/46spItONK1RQBQj1Y=
33
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
4-
github.com/FloatTech/AnimeAPI v1.7.1-0.20250214133017-28762c8262a6 h1:LxCcLzXCMUJ67I1sDaW1fOFlTxabLR29g+qpSExrGzk=
5-
github.com/FloatTech/AnimeAPI v1.7.1-0.20250214133017-28762c8262a6/go.mod h1:XXG1eBJf+eeWacQx5azsQKL5Gg7jDYTFyyZGIa/56js=
4+
github.com/FloatTech/AnimeAPI v1.7.1-0.20250217140215-4856397458c9 h1:tI9GgG8fdMK2WazFiEbMXAXjwMCckIfDaXbig9B6DdA=
5+
github.com/FloatTech/AnimeAPI v1.7.1-0.20250217140215-4856397458c9/go.mod h1:XXG1eBJf+eeWacQx5azsQKL5Gg7jDYTFyyZGIa/56js=
66
github.com/FloatTech/floatbox v0.0.0-20241106130736-5aea0a935024 h1:mrvWpiwfRklt9AyiQjKgDGJjf4YL6FZ3yC+ydbkuF2o=
77
github.com/FloatTech/floatbox v0.0.0-20241106130736-5aea0a935024/go.mod h1:+P3hs+Cvl10/Aj3SNE96TuBvKAXCe+XD1pKphTZyiwk=
88
github.com/FloatTech/gg v1.1.3 h1:+GlL02lTKsxJQr4WCuNwVxC1/eBZrCvypCIBtxuOFb4=

plugin/aichat/main.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ var (
3333
"- 设置AI聊天密钥xxx\n" +
3434
"- 设置AI聊天模型名xxx\n" +
3535
"- 设置AI聊天系统提示词xxx\n" +
36-
"- 设置AI聊天分隔符</think>(留空则清除)",
36+
"- 设置AI聊天分隔符</think>(留空则清除)\n" +
37+
"- 设置AI聊天(不)响应AT",
3738
PrivateDataFolder: "aichat",
3839
})
3940
)
@@ -42,6 +43,7 @@ var (
4243
modelname = "deepseek-ai/DeepSeek-R1"
4344
systemprompt = "你正在QQ群与用户聊天,用户发送了消息。按自己的心情简短思考后条理清晰地回复。"
4445
sepstr = ""
46+
noreplyat = false
4547
)
4648

4749
func init() {
@@ -74,7 +76,7 @@ func init() {
7476
}
7577

7678
en.OnMessage(func(ctx *zero.Ctx) bool {
77-
return ctx.ExtractPlainText() != ""
79+
return ctx.ExtractPlainText() != "" && (!noreplyat || (noreplyat && !ctx.Event.IsToMe))
7880
}).SetBlock(false).Handle(func(ctx *zero.Ctx) {
7981
gid := ctx.Event.GroupID
8082
if gid == 0 {
@@ -270,4 +272,23 @@ func init() {
270272
}
271273
ctx.SendChain(message.Text("设置成功"))
272274
})
275+
en.OnRegex("^设置AI聊天(不)?响应AT$", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
276+
args := ctx.State["regex_matched"].([]string)
277+
isno := args[1] == "不"
278+
fp := en.DataFolder() + "NoReplyAT"
279+
if isno {
280+
f, err := os.Create(fp)
281+
if err != nil {
282+
ctx.SendChain(message.Text("ERROR: ", err))
283+
return
284+
}
285+
defer f.Close()
286+
f.WriteString("PLACEHOLDER")
287+
noreplyat = true
288+
} else {
289+
_ = os.Remove(fp)
290+
noreplyat = false
291+
}
292+
ctx.SendChain(message.Text("成功"))
293+
})
273294
}

plugin/thesaurus/chat.go

Lines changed: 24 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,33 @@
1-
// Package thesaurus 修改过的单纯回复插件
1+
// Package thesaurus 修改过的单纯回复插件, 仅@触发
22
package thesaurus
33

44
import (
55
"bytes"
6-
"encoding/json"
76
"math/rand"
8-
"net/http"
9-
"os"
10-
"strconv"
117
"strings"
12-
"time"
138

14-
"github.com/FloatTech/floatbox/binary"
15-
"github.com/FloatTech/floatbox/ctxext"
16-
"github.com/FloatTech/floatbox/file"
17-
"github.com/FloatTech/floatbox/process"
18-
"github.com/FloatTech/floatbox/web"
19-
ctrl "github.com/FloatTech/zbpctrl"
20-
"github.com/FloatTech/zbputils/control"
219
"github.com/fumiama/jieba"
2210
"github.com/sirupsen/logrus"
11+
"gopkg.in/yaml.v3"
12+
2313
zero "github.com/wdvxdr1123/ZeroBot"
2414
"github.com/wdvxdr1123/ZeroBot/message"
25-
"gopkg.in/yaml.v3"
15+
16+
"github.com/FloatTech/AnimeAPI/kimoi"
17+
"github.com/FloatTech/floatbox/ctxext"
18+
"github.com/FloatTech/floatbox/process"
19+
ctrl "github.com/FloatTech/zbpctrl"
20+
"github.com/FloatTech/zbputils/control"
2621
)
2722

2823
func init() {
2924
engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
3025
DisableOnDefault: false,
31-
Brief: "词典匹配回复",
32-
Help: "- 切换[kimo|傲娇|可爱|🦙]词库\n- 设置词库触发概率0.x (0<x<9)",
26+
Brief: "词典匹配回复, 仅@触发",
27+
Help: "- 切换[kimo|傲娇|可爱]词库",
3328
PublicDataFolder: "Chat",
3429
})
35-
alpacafolder := engine.DataFolder() + "alpaca/"
36-
err := os.MkdirAll(alpacafolder, 0755)
37-
if err != nil {
38-
panic(err)
39-
}
40-
alpacapifile := alpacafolder + "api.txt"
41-
alpacapiurl := ""
42-
if file.IsExist(alpacapifile) {
43-
data, err := os.ReadFile(alpacapifile)
44-
if err != nil {
45-
panic(err)
46-
}
47-
alpacapiurl = binary.BytesToString(data)
48-
}
49-
alpacatokenfile := alpacafolder + "token.txt"
50-
alpacatoken := ""
51-
if file.IsExist(alpacatokenfile) {
52-
data, err := os.ReadFile(alpacatokenfile)
53-
if err != nil {
54-
panic(err)
55-
}
56-
alpacatoken = binary.BytesToString(data)
57-
}
58-
engine.OnRegex(`^切换(kimo|傲娇|可爱|🦙)词库$`, zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
30+
engine.OnRegex(`^切换(kimo|傲娇|可爱)词库$`, zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
5931
c, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
6032
if !ok {
6133
ctx.SendChain(message.Text("ERROR: 找不到 manager"))
@@ -74,8 +46,6 @@ func init() {
7446
t = tDERE
7547
case "可爱":
7648
t = tKAWA
77-
case "🦙":
78-
t = tALPACA
7949
}
8050
err := c.SetData(gid, (d&^3)|t)
8151
if err != nil {
@@ -84,48 +54,6 @@ func init() {
8454
}
8555
ctx.SendChain(message.Text("成功!"))
8656
})
87-
engine.OnRegex(`^设置词库触发概率\s*0.(\d)$`, zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
88-
c, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
89-
if !ok {
90-
ctx.SendChain(message.Text("ERROR: 找不到 manager"))
91-
return
92-
}
93-
n := ctx.State["regex_matched"].([]string)[1][0] - '0'
94-
if n <= 0 || n >= 9 {
95-
ctx.SendChain(message.Text("ERROR: 概率越界"))
96-
return
97-
}
98-
n-- // 0~7
99-
gid := ctx.Event.GroupID
100-
if gid == 0 {
101-
gid = -ctx.Event.UserID
102-
}
103-
d := c.GetData(gid)
104-
err := c.SetData(gid, (d&3)|(int64(n)<<59))
105-
if err != nil {
106-
ctx.SendChain(message.Text("ERROR: ", err))
107-
return
108-
}
109-
ctx.SendChain(message.Text("成功!"))
110-
})
111-
engine.OnRegex(`^设置🦙API地址\s*(http.*)\s*$`, zero.SuperUserPermission, zero.OnlyPrivate).SetBlock(true).Handle(func(ctx *zero.Ctx) {
112-
alpacapiurl = ctx.State["regex_matched"].([]string)[1]
113-
err := os.WriteFile(alpacapifile, binary.StringToBytes(alpacapiurl), 0644)
114-
if err != nil {
115-
ctx.SendChain(message.Text("ERROR: ", err))
116-
return
117-
}
118-
ctx.SendChain(message.Text("成功!"))
119-
})
120-
engine.OnRegex(`^设置🦙token\s*([0-9a-f]{112})\s*$`, zero.SuperUserPermission, zero.OnlyPrivate).SetBlock(true).Handle(func(ctx *zero.Ctx) {
121-
alpacatoken = ctx.State["regex_matched"].([]string)[1]
122-
err := os.WriteFile(alpacatokenfile, binary.StringToBytes(alpacatoken), 0644)
123-
if err != nil {
124-
ctx.SendChain(message.Text("ERROR: ", err))
125-
return
126-
}
127-
ctx.SendChain(message.Text("成功!"))
128-
})
12957
go func() {
13058
data, err := engine.GetLazyData("dict.txt", false)
13159
if err != nil {
@@ -144,21 +72,6 @@ func init() {
14472
if err != nil {
14573
panic(err)
14674
}
147-
data, err = engine.GetLazyData("kimoi.json", false)
148-
if err != nil {
149-
panic(err)
150-
}
151-
kimomap := make(kimo, 256)
152-
err = json.Unmarshal(data, &kimomap)
153-
if err != nil {
154-
panic(err)
155-
}
156-
chatList := make([]string, 0, len(kimomap))
157-
for k := range kimomap {
158-
chatList = append(chatList, k)
159-
}
160-
logrus.Infoln("[thesaurus]加载", len(chatList), "条kimoi")
161-
16275
chatListD := make([]string, 0, len(sm.D))
16376
for k := range sm.D {
16477
chatListD = append(chatListD, k)
@@ -169,86 +82,32 @@ func init() {
16982
}
17083
logrus.Infoln("[thesaurus]加载", len(chatListD), "条傲娇词库", len(chatListK), "条可爱词库")
17184

172-
engine.OnMessage(canmatch(tKIMO), match(chatList, seg)).
173-
SetBlock(false).
174-
Handle(randreply(kimomap))
175-
engine.OnMessage(canmatch(tDERE), match(chatListD, seg)).
85+
engine.OnMessage(zero.OnlyToMe, canmatch(tKIMO)).
86+
SetBlock(false).Handle(func(ctx *zero.Ctx) {
87+
r, err := kimoi.Chat(ctx.ExtractPlainText())
88+
if err == nil && r.Confidence > 0.5 && r.Confidence < 0.95 {
89+
ctx.Block()
90+
ctx.SendChain(message.Text(r.Reply))
91+
}
92+
})
93+
engine.OnMessage(zero.OnlyToMe, canmatch(tDERE), match(chatListD, seg)).
17694
SetBlock(false).
17795
Handle(randreply(sm.D))
178-
engine.OnMessage(canmatch(tKAWA), match(chatListK, seg)).
96+
engine.OnMessage(zero.OnlyToMe, canmatch(tKAWA), match(chatListK, seg)).
17997
SetBlock(false).
18098
Handle(randreply(sm.K))
181-
engine.OnMessage(canmatch(tALPACA), func(_ *zero.Ctx) bool {
182-
return alpacapiurl != "" && alpacatoken != ""
183-
}).SetBlock(false).Handle(func(ctx *zero.Ctx) {
184-
msg := ctx.ExtractPlainText()
185-
if msg != "" {
186-
data, err := web.RequestDataWithHeaders(http.DefaultClient, alpacapiurl+"/reply", "POST",
187-
func(r *http.Request) error {
188-
r.Header.Set("Authorization", alpacatoken)
189-
return nil
190-
}, bytes.NewReader(binary.NewWriterF(func(writer *binary.Writer) {
191-
_ = json.NewEncoder(writer).Encode(&[]alpacamsg{{
192-
Name: ctx.CardOrNickName(ctx.Event.UserID),
193-
Message: msg,
194-
}})
195-
})))
196-
if err != nil {
197-
logrus.Warnln("[chat] 🦙 err:", err)
198-
return
199-
}
200-
type reply struct {
201-
ID int
202-
Msg string
203-
}
204-
m := reply{}
205-
err = json.Unmarshal(data, &m)
206-
if err != nil {
207-
logrus.Warnln("[chat] 🦙 unmarshal err:", err)
208-
return
209-
}
210-
for i := 0; i < 60; i++ {
211-
time.Sleep(time.Second * 4)
212-
data, err := web.RequestDataWithHeaders(http.DefaultClient, alpacapiurl+"/get?id="+strconv.Itoa(m.ID), "GET",
213-
func(r *http.Request) error {
214-
r.Header.Set("Authorization", alpacatoken)
215-
return nil
216-
}, nil)
217-
if err != nil {
218-
continue
219-
}
220-
err = json.Unmarshal(data, &m)
221-
if err != nil {
222-
logrus.Warnln("[chat] 🦙 unmarshal err:", err)
223-
return
224-
}
225-
if len(m.Msg) > 0 {
226-
ctx.Send(message.Text(m.Msg))
227-
}
228-
return
229-
}
230-
}
231-
})
23299
}()
233100
}
234101

235-
type kimo = map[string][]string
236-
237102
type simai struct {
238103
D map[string][]string `yaml:"傲娇"`
239104
K map[string][]string `yaml:"可爱"`
240105
}
241106

242-
type alpacamsg struct {
243-
Name string
244-
Message string
245-
}
246-
247107
const (
248108
tKIMO = iota
249109
tDERE
250110
tKAWA
251-
tALPACA
252111
)
253112

254113
func match(l []string, seg *jieba.Segmenter) zero.Rule {
@@ -273,12 +132,13 @@ func canmatch(typ int64) zero.Rule {
273132
gid = -ctx.Event.UserID
274133
}
275134
d := c.GetData(gid)
276-
return d&3 == typ && rand.Int63n(10) <= d>>59
135+
return ctx.ExtractPlainText() != "" && d&3 == typ
277136
}
278137
}
279138

280139
func randreply(m map[string][]string) zero.Handler {
281140
return func(ctx *zero.Ctx) {
141+
ctx.Block()
282142
key := ctx.State["matched"].(string)
283143
val := m[key]
284144
nick := zero.BotConfig.NickName[rand.Intn(len(zero.BotConfig.NickName))]

0 commit comments

Comments
 (0)