diff --git a/go.mod b/go.mod index 64ab5e8f..d04e58fc 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/fumiama/sqlite3 v1.14.6 github.com/jinzhu/gorm v1.9.16 github.com/mroth/weightedrand v0.4.1 + github.com/pkumza/numcn v1.0.0 github.com/shirou/gopsutil/v3 v3.21.12 github.com/sirupsen/logrus v1.8.1 github.com/tidwall/gjson v1.13.0 diff --git a/go.sum b/go.sum index 1e090505..40828355 100644 --- a/go.sum +++ b/go.sum @@ -117,6 +117,8 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkumza/numcn v1.0.0 h1:ZT5cf9IJkUZgRgEtCiNNykk0RwsrKXSTsvDHOwUTzgE= +github.com/pkumza/numcn v1.0.0/go.mod h1:QSeH+al9dWCd8di5HZM/ZqHqhZmUKfph572e9Ev/ETc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= diff --git a/plugin_ai_reply/main.go b/plugin_ai_reply/main.go index f8af36ff..8b5ca872 100644 --- a/plugin_ai_reply/main.go +++ b/plugin_ai_reply/main.go @@ -15,13 +15,13 @@ import ( ) const ( - serviceName = "aireply" + replyServiceName = "aireply" ) -var modes = [...]string{"青云客", "小爱"} +var replyModes = [...]string{"青云客", "小爱"} func init() { // 插件主体 - engine := control.Register(serviceName, order.AcquirePrio(), &control.Options{ + engine := control.Register(replyServiceName, order.AcquirePrio(), &control.Options{ DisableOnDefault: false, Help: "人工智能回复\n" + "- @Bot 任意文本(任意一句话回复)\n- 设置回复模式[青云客 | 小爱]\n- ", @@ -59,7 +59,7 @@ func setReplyMode(ctx *zero.Ctx, name string) error { } var ok bool var index int64 - for i, s := range modes { + for i, s := range replyModes { if s == name { ok = true index = int64(i) @@ -69,7 +69,7 @@ func setReplyMode(ctx *zero.Ctx, name string) error { if !ok { return errors.New("no such mode") } - m, ok := control.Lookup(serviceName) + m, ok := control.Lookup(replyServiceName) if !ok { return errors.New("no such plugin") } @@ -81,11 +81,11 @@ func getReplyMode(ctx *zero.Ctx) (name string) { if gid == 0 { gid = -ctx.Event.UserID } - m, ok := control.Lookup(serviceName) + m, ok := control.Lookup(replyServiceName) if ok { index := m.GetData(gid) - if int(index) < len(modes) { - return modes[index] + if int(index) < len(replyModes) { + return replyModes[index] } } return "青云客" diff --git a/plugin_ai_reply/tts.go b/plugin_ai_reply/tts.go index 11692da2..751228b8 100644 --- a/plugin_ai_reply/tts.go +++ b/plugin_ai_reply/tts.go @@ -1,10 +1,17 @@ package aireply import ( + "errors" + "github.com/pkumza/numcn" + log "github.com/sirupsen/logrus" zero "github.com/wdvxdr1123/ZeroBot" "github.com/wdvxdr1123/ZeroBot/message" + "regexp" + "strconv" "github.com/FloatTech/AnimeAPI/aireply" + "github.com/FloatTech/AnimeAPI/tts" + "github.com/FloatTech/AnimeAPI/tts/baidutts" "github.com/FloatTech/AnimeAPI/tts/mockingbird" "github.com/FloatTech/zbputils/control" "github.com/FloatTech/zbputils/ctxext" @@ -12,16 +19,107 @@ import ( "github.com/FloatTech/zbputils/control/order" ) +const ( + ttsServiceName = "tts" +) + +var ( + reNumber = "(\\-|\\+)?\\d+(\\.\\d+)?" + t *ttsInstances +) + +type ttsInstances struct { + m map[string]tts.TTS + l []string +} + +func (t *ttsInstances) List() []string { + return t.l +} + func init() { - control.Register("mockingbird", order.AcquirePrio(), &control.Options{ + t = &ttsInstances{ + m: map[string]tts.TTS{ + "百度女声": baidutts.NewBaiduTTS(0), + "百度男声": baidutts.NewBaiduTTS(1), + "百度度逍遥": baidutts.NewBaiduTTS(3), + "百度度丫丫": baidutts.NewBaiduTTS(4), + "拟声鸟阿梓": mockingbird.NewMockingBirdTTS(0), + "拟声鸟药水哥": mockingbird.NewMockingBirdTTS(1), + }, + l: []string{"拟声鸟阿梓", "拟声鸟药水哥", "百度女声", "百度男声", "百度度逍遥", "百度度丫丫"}, + } + engine := control.Register(ttsServiceName, order.AcquirePrio(), &control.Options{ DisableOnDefault: false, - Help: "拟声鸟\n- @Bot 任意文本(任意一句话回复)", - }).OnMessage(zero.OnlyToMe).SetBlock(true).Limit(ctxext.LimitByUser). + Help: "语音回复(包括拟声鸟和百度)\n- @Bot 任意文本(任意一句话回复)\n- 设置语音模式拟声鸟阿梓 | 设置语音模式拟声鸟药水哥 | 设置语音模式百度女声 | 设置语音模式百度男声| 设置语音模式百度度逍遥 | 设置语音模式百度度丫丫", + }) + engine.OnMessage(zero.OnlyToMe).SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { msg := ctx.ExtractPlainText() r := aireply.NewAIReply(getReplyMode(ctx)) - ctx.SendChain(message.Record(mockingbird.NewMockingBirdTTS(1).Speak(ctx.Event.UserID, func() string { - return r.TalkPlain(msg, zero.BotConfig.NickName[0]) + tts := newTTS(getSoundMode(ctx)) + ctx.SendChain(message.Record(tts.Speak(ctx.Event.UserID, func() string { + reply := r.TalkPlain(msg, zero.BotConfig.NickName[0]) + re := regexp.MustCompile(reNumber) + reply = re.ReplaceAllStringFunc(reply, func(s string) string { + f, err := strconv.ParseFloat(s, 64) + if err != nil { + log.Errorln("[tts]:", err) + return s + } + return numcn.EncodeFromFloat64(f) + }) + log.Println("[tts]:", reply) + return reply }))) }) + engine.OnRegex(`^设置语音模式(.*)$`, ctxext.FirstValueInList(t)).SetBlock(true). + Handle(func(ctx *zero.Ctx) { + param := ctx.State["regex_matched"].([]string)[1] + err := setSoundMode(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("成功")) + }) +} + +// newTTS 语音简单工厂 +func newTTS(name string) tts.TTS { + return t.m[name] +} + +func setSoundMode(ctx *zero.Ctx, name string) error { + gid := ctx.Event.GroupID + if gid == 0 { + gid = -ctx.Event.UserID + } + var index int64 + for i, s := range t.l { + if s == name { + index = int64(i) + break + } + } + m, ok := control.Lookup(ttsServiceName) + if !ok { + return errors.New("no such plugin") + } + return m.SetData(gid, index) +} + +func getSoundMode(ctx *zero.Ctx) (name string) { + gid := ctx.Event.GroupID + if gid == 0 { + gid = -ctx.Event.UserID + } + m, ok := control.Lookup(ttsServiceName) + if ok { + index := m.GetData(gid) + if int(index) < len(t.l) { + return t.l[index] + } + } + return "拟声鸟阿梓" }