diff --git a/plugin/ai_reply/ai_tts.go b/plugin/ai_reply/ai_tts.go index b0e0fb18..caafde89 100644 --- a/plugin/ai_reply/ai_tts.go +++ b/plugin/ai_reply/ai_tts.go @@ -13,7 +13,6 @@ import ( const ( cnapi = "https://genshin.azurewebsites.net/api/speak?format=mp3&id=%d&text=%s" - // testString = "这是测试语音......" ) // 每个角色的测试文案 @@ -86,6 +85,51 @@ var ( } ) +/************************************************************* +*******************************AIreply************************ +*************************************************************/ +func setReplyMode(ctx *zero.Ctx, name string) error { + gid := ctx.Event.GroupID + if gid == 0 { + gid = -ctx.Event.UserID + } + var ok bool + var index int64 + for i, s := range replyModes { + if s == name { + ok = true + index = int64(i) + break + } + } + if !ok { + return errors.New("no such mode") + } + m, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]) + if !ok { + return errors.New("no such plugin") + } + return m.SetData(gid, index) +} + +func getReplyMode(ctx *zero.Ctx) (name string) { + gid := ctx.Event.GroupID + if gid == 0 { + gid = -ctx.Event.UserID + } + m, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]) + if ok { + index := m.GetData(gid) + if int(index) < len(replyModes) { + return replyModes[index] + } + } + return "青云客" +} + +/************************************************************* +***********************tts************************************ +*************************************************************/ type ttsmode struct { sync.RWMutex mode map[int64]int64 @@ -106,10 +150,16 @@ func list(list []string, num int) string { func newttsmode() *ttsmode { tts := &ttsmode{} + tts.Lock() + defer tts.Unlock() m, ok := control.Lookup(ttsServiceName) - tts.mode = make(map[int64]int64) + tts.mode = make(map[int64]int64, 2*len(soundList)) + tts.mode[-2905] = 1 if ok { - tts.mode[-2905] = m.GetData(-2905) + index := m.GetData(-2905) + if index > 0 && index < int64(len(soundList)) { + tts.mode[-2905] = index + } } return tts } @@ -119,31 +169,42 @@ func (tts *ttsmode) setSoundMode(ctx *zero.Ctx, name string) error { if gid == 0 { gid = -ctx.Event.UserID } - var i int - var s string - for i, s = range soundList { + var index int64 + for i, s := range soundList { if s == name { + index = int64(i + 1) break } } + if index == 0 { + return errors.New("不支持设置语音人物" + name) + } m := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]) tts.Lock() defer tts.Unlock() - tts.mode[gid] = int64(i) - return m.SetData(gid, int64(i)) + tts.mode[gid] = index + return m.SetData(gid, index) } -func (tts *ttsmode) getSoundMode(ctx *zero.Ctx) (i int64) { +func (tts *ttsmode) getSoundMode(ctx *zero.Ctx) int64 { gid := ctx.Event.GroupID if gid == 0 { gid = -ctx.Event.UserID } - tts.RLock() - defer tts.RUnlock() - return tts.mode[gid] + tts.Lock() + defer tts.Unlock() + i, ok := tts.mode[gid] + if !ok { + m := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]) + i = m.GetData(gid) + } + if i <= 0 || i >= int64(len(soundList)) { + i = tts.mode[-2905] + } + return i - 1 } -func (tts *ttsmode) resetSoundMode(ctx *zero.Ctx) { +func (tts *ttsmode) resetSoundMode(ctx *zero.Ctx) error { gid := ctx.Event.GroupID if gid == 0 { gid = -ctx.Event.UserID @@ -151,20 +212,27 @@ func (tts *ttsmode) resetSoundMode(ctx *zero.Ctx) { tts.Lock() defer tts.Unlock() m := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]) - tts.mode[gid] = m.GetData(-2905) + tts.mode[gid] = 0 + return m.SetData(gid, 0) // 重置数据 } -func setDefaultSoundMode(name string) error { - var i int - var s string - for i, s = range soundList { +func (tts *ttsmode) setDefaultSoundMode(name string) error { + var index int64 + for i, s := range soundList { if s == name { + index = int64(i + 1) break } } + if index == 0 { + return errors.New("不支持设置语音人物" + name) + } + tts.Lock() + defer tts.Unlock() m, ok := control.Lookup(ttsServiceName) if !ok { return errors.New("[tts] service not found") } - return m.SetData(-2905, int64(i)) + tts.mode[-2905] = index + return m.SetData(-2905, index) } diff --git a/plugin/ai_reply/main.go b/plugin/ai_reply/main.go index 6f2cb273..b15f9af8 100644 --- a/plugin/ai_reply/main.go +++ b/plugin/ai_reply/main.go @@ -2,7 +2,6 @@ package aireply import ( - "errors" "fmt" "net/url" "strconv" @@ -26,7 +25,7 @@ const ( var replyModes = [...]string{"青云客", "小爱"} func init() { // 插件主体 - engine := control.Register(ttsServiceName, &ctrl.Options[*zero.Ctx]{ + enOftts := control.Register(ttsServiceName, &ctrl.Options[*zero.Ctx]{ DisableOnDefault: true, Help: "语音回复(大家一起来炼丹)\n" + "- @Bot 任意文本(任意一句话回复)\n" + @@ -36,7 +35,40 @@ func init() { // 插件主体 "当前适用的原神人物含有以下:\n" + list(soundList[:], 5), }) tts := newttsmode() - engine.OnMessage(zero.OnlyToMe).SetBlock(true).Limit(ctxext.LimitByUser). + enOfreply := control.Register(replyServiceName, &ctrl.Options[*zero.Ctx]{ + DisableOnDefault: false, + Help: "人工智能回复\n" + + "- @Bot 任意文本(任意一句话回复)\n- 设置回复模式[青云客|小爱]", + }) + /************************************************************* + *******************************AIreply************************ + *************************************************************/ + enOfreply.OnMessage(zero.OnlyToMe).SetBlock(true).Limit(ctxext.LimitByUser). + Handle(func(ctx *zero.Ctx) { + aireply := aireply.NewAIReply(getReplyMode(ctx)) + reply := message.ParseMessageFromString(aireply.Talk(ctx.ExtractPlainText(), zero.BotConfig.NickName[0])) + // 回复 + time.Sleep(time.Second * 1) + if zero.OnlyPublic(ctx) { + reply = append(reply, message.Reply(ctx.Event.MessageID)) + ctx.Send(reply) + return + } + ctx.Send(reply) + }) + enOfreply.OnPrefix("设置回复模式", zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) { + param := ctx.State["args"].(string) + err := setReplyMode(ctx, param) + if err != nil { + ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(err)) + return + } + ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("成功")) + }) + /************************************************************* + ***********************tts************************************ + *************************************************************/ + enOftts.OnMessage(zero.OnlyToMe).SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { msg := ctx.ExtractPlainText() // 获取回复模式 @@ -44,7 +76,8 @@ func init() { // 插件主体 // 获取回复的文本 reply := r.TalkPlain(msg, zero.BotConfig.NickName[0]) // 获取语音 - record := message.Record(fmt.Sprintf(cnapi, tts.getSoundMode(ctx), url.QueryEscape( + index := tts.getSoundMode(ctx) + record := message.Record(fmt.Sprintf(cnapi, index, url.QueryEscape( // 将数字转文字 re.ReplaceAllStringFunc(reply, func(s string) string { f, err := strconv.ParseFloat(s, 64) @@ -55,16 +88,12 @@ func init() { // 插件主体 return numcn.EncodeFromFloat64(f) }), ))).Add("cache", 0) - if record.Data == nil { - ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(reply)) - return - } // 发送语音 if ID := ctx.SendChain(record); ID.ID() == 0 { ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(reply)) } }) - engine.OnRegex(`^设置语音模式(.*)$`, zero.AdminPermission, func(ctx *zero.Ctx) bool { + enOftts.OnRegex(`^设置语音模式(.*)$`, zero.AdminPermission, func(ctx *zero.Ctx) bool { param := ctx.State["regex_matched"].([]string)[1] if _, ok := testRecord[param]; !ok { return false @@ -92,7 +121,7 @@ func init() { // 插件主体 time.Sleep(time.Second * 2) ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("设置成功")) }) - engine.OnRegex(`^设置默认语音模式(.*)$`, zero.SuperUserPermission, func(ctx *zero.Ctx) bool { + enOftts.OnRegex(`^设置默认语音模式(.*)$`, zero.SuperUserPermission, func(ctx *zero.Ctx) bool { param := ctx.State["regex_matched"].([]string)[1] if _, ok := testRecord[param]; !ok { return false @@ -101,85 +130,21 @@ func init() { // 插件主体 }).SetBlock(true).Handle(func(ctx *zero.Ctx) { param := ctx.State["regex_matched"].([]string)[1] // 保存设置 - err := setDefaultSoundMode(param) + err := tts.setDefaultSoundMode(param) if err != nil { ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(err)) return } ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("设置成功")) }) - engine.OnFullMatch("恢复成默认语音模式", zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) { - tts.resetSoundMode(ctx) + enOftts.OnFullMatch("恢复成默认语音模式", zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) { + err := tts.resetSoundMode(ctx) + if err != nil { + ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(err)) + return + } // 设置验证 - name := tts.getSoundMode(ctx) - ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("设置成功,当前为", name)) + index := tts.getSoundMode(ctx) + ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("设置成功,当前为", soundList[index])) }) - engine = control.Register(replyServiceName, &ctrl.Options[*zero.Ctx]{ - DisableOnDefault: false, - Help: "人工智能回复\n" + - "- @Bot 任意文本(任意一句话回复)\n- 设置回复模式[青云客|小爱]", - }) - // 回复 @和包括名字 - engine.OnMessage(zero.OnlyToMe).SetBlock(true).Limit(ctxext.LimitByUser). - Handle(func(ctx *zero.Ctx) { - aireply := aireply.NewAIReply(getReplyMode(ctx)) - reply := message.ParseMessageFromString(aireply.Talk(ctx.ExtractPlainText(), zero.BotConfig.NickName[0])) - // 回复 - time.Sleep(time.Second * 1) - if zero.OnlyPublic(ctx) { - reply = append(reply, message.Reply(ctx.Event.MessageID)) - ctx.Send(reply) - return - } - ctx.Send(reply) - }) - engine.OnPrefix("设置回复模式").SetBlock(true). - Handle(func(ctx *zero.Ctx) { - param := ctx.State["args"].(string) - err := setReplyMode(ctx, param) - if err != nil { - ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(err)) - return - } - ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("成功")) - }) -} - -func setReplyMode(ctx *zero.Ctx, name string) error { - gid := ctx.Event.GroupID - if gid == 0 { - gid = -ctx.Event.UserID - } - var ok bool - var index int64 - for i, s := range replyModes { - if s == name { - ok = true - index = int64(i) - break - } - } - if !ok { - return errors.New("no such mode") - } - m, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]) - if !ok { - return errors.New("no such plugin") - } - return m.SetData(gid, index) -} - -func getReplyMode(ctx *zero.Ctx) (name string) { - gid := ctx.Event.GroupID - if gid == 0 { - gid = -ctx.Event.UserID - } - m, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]) - if ok { - index := m.GetData(gid) - if int(index) < len(replyModes) { - return replyModes[index] - } - } - return "青云客" }