mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-19 22:00:11 +08:00
182 lines
4.8 KiB
Go
182 lines
4.8 KiB
Go
package aireply
|
|
|
|
import (
|
|
"regexp"
|
|
"strconv"
|
|
"sync"
|
|
|
|
"github.com/pkumza/numcn"
|
|
log "github.com/sirupsen/logrus"
|
|
zero "github.com/wdvxdr1123/ZeroBot"
|
|
"github.com/wdvxdr1123/ZeroBot/message"
|
|
|
|
"github.com/FloatTech/AnimeAPI/aireply"
|
|
"github.com/FloatTech/AnimeAPI/tts"
|
|
"github.com/FloatTech/AnimeAPI/tts/baidutts"
|
|
"github.com/FloatTech/AnimeAPI/tts/mockingbird"
|
|
ctrl "github.com/FloatTech/zbpctrl"
|
|
"github.com/FloatTech/zbputils/control"
|
|
"github.com/FloatTech/zbputils/ctxext"
|
|
)
|
|
|
|
const ttsServiceName = "tts"
|
|
|
|
var re = regexp.MustCompile(`(\-|\+)?\d+(\.\d+)?`)
|
|
|
|
type ttsInstances struct {
|
|
sync.RWMutex
|
|
m map[string]tts.TTS
|
|
l []string
|
|
}
|
|
|
|
func (t *ttsInstances) List() []string {
|
|
t.RLock()
|
|
cl := make([]string, len(t.l))
|
|
_ = copy(cl, t.l)
|
|
t.RUnlock()
|
|
return cl
|
|
}
|
|
|
|
func init() {
|
|
t := &ttsInstances{
|
|
m: map[string]tts.TTS{
|
|
"百度女声": baidutts.NewBaiduTTS(0),
|
|
"百度男声": baidutts.NewBaiduTTS(1),
|
|
"百度度逍遥": baidutts.NewBaiduTTS(3),
|
|
"百度度丫丫": baidutts.NewBaiduTTS(4),
|
|
"拟声鸟阿梓": nil,
|
|
"拟声鸟文静": nil,
|
|
"拟声鸟药水哥": nil,
|
|
},
|
|
l: []string{"拟声鸟阿梓", "拟声鸟文静", "拟声鸟药水哥", "百度女声", "百度男声", "百度度逍遥", "百度度丫丫"},
|
|
}
|
|
engine := control.Register(ttsServiceName, &ctrl.Options[*zero.Ctx]{
|
|
DisableOnDefault: true,
|
|
Help: "语音回复(包括拟声鸟和百度)\n" +
|
|
"- @Bot 任意文本(任意一句话回复)\n" +
|
|
"- 设置语音模式[拟声鸟阿梓 | 拟声鸟文静 | 拟声鸟药水哥 | 百度女声 | 百度男声| 百度度逍遥 | 百度度丫丫]\n" +
|
|
"- 设置默认语音模式[拟声鸟阿梓 | 拟声鸟文静 | 拟声鸟药水哥 | 百度女声 | 百度男声| 百度度逍遥 | 百度度丫丫]\n",
|
|
})
|
|
engine.OnMessage(zero.OnlyToMe).SetBlock(true).Limit(ctxext.LimitByUser).
|
|
Handle(func(ctx *zero.Ctx) {
|
|
msg := ctx.ExtractPlainText()
|
|
r := aireply.NewAIReply(getReplyMode(ctx))
|
|
tts, err := t.new(t.getSoundMode(ctx))
|
|
if err != nil {
|
|
ctx.SendChain(message.Text("ERROR:", err))
|
|
return
|
|
}
|
|
var reply string
|
|
if tts != nil {
|
|
rec, err := tts.Speak(ctx.Event.UserID, func() string {
|
|
reply = r.TalkPlain(msg, zero.BotConfig.NickName[0])
|
|
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.Debugln("[tts]:", reply)
|
|
return reply
|
|
})
|
|
if err == nil {
|
|
ctx.SendChain(message.Record(rec))
|
|
} else {
|
|
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(reply))
|
|
}
|
|
}
|
|
})
|
|
engine.OnRegex(`^设置语音模式(.*)$`, ctxext.FirstValueInList(t)).SetBlock(true).
|
|
Handle(func(ctx *zero.Ctx) {
|
|
param := ctx.State["regex_matched"].([]string)[1]
|
|
err := t.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("设置成功,当前模式为", param))
|
|
})
|
|
engine.OnRegex(`^设置默认语音模式(.*)$`, ctxext.FirstValueInList(t)).SetBlock(true).
|
|
Handle(func(ctx *zero.Ctx) {
|
|
param := ctx.State["regex_matched"].([]string)[1]
|
|
t.setDefaultSoundMode(param)
|
|
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("设置成功,默认模式为", param))
|
|
})
|
|
}
|
|
|
|
// new 语音简单工厂
|
|
func (t *ttsInstances) new(name string) (ts tts.TTS, err error) {
|
|
t.RLock()
|
|
ts = t.m[name]
|
|
t.RUnlock()
|
|
if ts == nil {
|
|
switch name {
|
|
case "拟声鸟阿梓":
|
|
t.Lock()
|
|
ts, err = mockingbird.NewMockingBirdTTS(0)
|
|
t.Unlock()
|
|
case "拟声鸟文静":
|
|
t.Lock()
|
|
ts, err = mockingbird.NewMockingBirdTTS(1)
|
|
t.Unlock()
|
|
case "拟声鸟药水哥":
|
|
t.Lock()
|
|
ts, err = mockingbird.NewMockingBirdTTS(2)
|
|
t.Unlock()
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (t *ttsInstances) setSoundMode(ctx *zero.Ctx, name string) error {
|
|
gid := ctx.Event.GroupID
|
|
if gid == 0 {
|
|
gid = -ctx.Event.UserID
|
|
}
|
|
var index int64
|
|
t.RLock()
|
|
for i, s := range t.l {
|
|
if s == name {
|
|
index = int64(i)
|
|
break
|
|
}
|
|
}
|
|
t.RUnlock()
|
|
m := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
|
|
return m.SetData(gid, index)
|
|
}
|
|
|
|
func (t *ttsInstances) getSoundMode(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 {
|
|
t.RLock()
|
|
defer t.RUnlock()
|
|
index := m.GetData(gid)
|
|
if int(index) < len(t.l) {
|
|
return t.l[index]
|
|
}
|
|
}
|
|
return "拟声鸟阿梓"
|
|
}
|
|
|
|
func (t *ttsInstances) setDefaultSoundMode(name string) {
|
|
var index int
|
|
t.RLock()
|
|
for _, s := range t.l {
|
|
if s == name {
|
|
break
|
|
}
|
|
index++
|
|
}
|
|
t.RUnlock()
|
|
t.Lock()
|
|
t.l[0], t.l[index] = t.l[index], t.l[0]
|
|
t.Unlock()
|
|
}
|