Skip to content

增加并发,解决FutureEvent超时问题 #552

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Jan 3, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 82 additions & 102 deletions plugin/guessmusic/guessmusic.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os/exec"
"strconv"
"strings"
"sync"
"time"

"github.com/FloatTech/floatbox/file"
Expand Down Expand Up @@ -84,11 +85,11 @@ func init() {
return
}
answerString := "歌名:" + musicInfo[0] + "\n歌手:" + musicInfo[1]
musicAlia := ""
if infoNum > 2 {
musicAlia = musicInfo[2]
answerString += "\n其他信息:\n" + strings.ReplaceAll(musicAlia, "&", "\n")
musicInfo[2] = strings.ReplaceAll(musicInfo[2], "&", "\n")
answerString += "\n其他信息:\n" + musicInfo[2]
}
musicInfo = append(musicInfo, answerString)
// 切割音频,生成3个10秒的音频
outputPath := cachePath + strconv.FormatInt(gid, 10) + "/"
err = cutMusic(musicName, pathOfMusic, outputPath)
Expand All @@ -104,13 +105,18 @@ func init() {
} else {
next = zero.NewFutureEvent("message", 999, false, zero.OnlyGroup, zero.RegexRule(`^-\S{1,}`), zero.CheckGroup(ctx.Event.GroupID))
}
var musicCount = 0 // 音频数量
var answerCount = 0 // 问答次数
recv, cancel := next.Repeat()
defer cancel()
wait := time.NewTimer(40 * time.Second)
tick := time.NewTimer(105 * time.Second)
after := time.NewTimer(120 * time.Second)
wg := sync.WaitGroup{}
var (
messageStr message.MessageSegment // 文本信息
tickCount = 0 // 音频数量
answerCount = 0 // 问答次数
win bool // 是否赢得游戏
)
for {
select {
case <-tick.C:
Expand All @@ -121,107 +127,41 @@ func init() {
return
case <-wait.C:
wait.Reset(40 * time.Second)
musicCount++
if musicCount > 2 {
tickCount++
if tickCount > 2 {
wait.Stop()
continue
}
ctx.SendChain(
message.Text("好像有些难度呢,再听这段音频,要仔细听哦"),
)
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + outputPath + strconv.Itoa(musicCount) + ".wav"))
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + outputPath + strconv.Itoa(tickCount) + ".wav"))
case c := <-recv:
wait.Reset(40 * time.Second)
tick.Reset(105 * time.Second)
after.Reset(120 * time.Second)
answer := strings.Replace(c.Event.Message.String(), "-", "", 1)
switch {
case answer == "取消":
if c.Event.UserID == ctx.Event.UserID {
wg.Add(1)
go func() {
messageStr, answerCount, tickCount, win = gameMatch(c, ctx.Event.UserID, musicInfo, answerCount, tickCount)
if win { // 游戏结束的话
wait.Stop()
tick.Stop()
after.Stop()
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID,
message.Text("游戏已取消,猜歌答案是\n", answerString, "\n\n\n下面欣赏猜歌的歌曲")))
ctx.SendChain(message.Reply(c.Event.MessageID), messageStr)
ctx.SendChain(message.Record("file:///" + pathOfMusic + musicName))
return
}
ctx.Send(
message.ReplyWithMessage(c.Event.MessageID,
message.Text("你无权限取消"),
),
)
case answer == "提示":
musicCount++
if musicCount > 2 {
wait.Stop()
ctx.Send(
message.ReplyWithMessage(c.Event.MessageID,
message.Text("已经没有提示了哦"),
),
)
continue
}
wait.Reset(40 * time.Second)
ctx.Send(
message.ReplyWithMessage(c.Event.MessageID,
message.Text("再听这段音频,要仔细听哦"),
),
)
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + outputPath + strconv.Itoa(musicCount) + ".wav"))
case strings.Contains(musicInfo[0], answer) || strings.EqualFold(musicInfo[0], answer):
wait.Stop()
tick.Stop()
after.Stop()
ctx.Send(message.ReplyWithMessage(c.Event.MessageID,
message.Text("太棒了,你猜对歌曲名了!答案是\n", answerString, "\n\n下面欣赏猜歌的歌曲")))
ctx.SendChain(message.Record("file:///" + pathOfMusic + musicName))
return
case strings.Contains(musicInfo[1], answer) || strings.EqualFold(musicInfo[1], answer):
wait.Stop()
tick.Stop()
after.Stop()
ctx.Send(message.ReplyWithMessage(c.Event.MessageID,
message.Text("太棒了,你猜对歌手名了!答案是\n", answerString, "\n\n下面欣赏猜歌的歌曲")))
ctx.SendChain(message.Record("file:///" + pathOfMusic + musicName))
return
case strings.Contains(musicAlia, answer) || strings.EqualFold(musicAlia, answer):
wait.Stop()
tick.Stop()
after.Stop()
ctx.Send(message.ReplyWithMessage(c.Event.MessageID,
message.Text("太棒了,你猜对出处了!答案是\n", answerString, "\n\n下面欣赏猜歌的歌曲")))
ctx.SendChain(message.Record("file:///" + pathOfMusic + musicName))
return
default:
musicCount++
switch {
case musicCount > 2 && answerCount < 6:
wait.Stop()
answerCount++
ctx.Send(
message.ReplyWithMessage(c.Event.MessageID,
message.Text("答案不对哦,加油啊~"),
),
)
case musicCount > 2:
wait.Stop()
tick.Stop()
after.Stop()
ctx.Send(message.ReplyWithMessage(c.Event.MessageID,
message.Text("次数到了,没能猜出来。答案是\n", answerString, "\n\n下面欣赏猜歌的歌曲")))
ctx.SendChain(message.Record("file:///" + pathOfMusic + musicName))
return
default:
} else {
wait.Reset(40 * time.Second)
answerCount++
ctx.Send(
message.ReplyWithMessage(c.Event.MessageID,
message.Text("答案不对,再听这段音频,要仔细听哦"),
),
)
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + outputPath + strconv.Itoa(musicCount) + ".wav"))
tick.Reset(105 * time.Second)
after.Reset(120 * time.Second)
if tickCount > 2 || messageStr.Data["text"] == "你无权限取消" {
ctx.SendChain(message.Reply(c.Event.MessageID), messageStr)
} else {
ctx.SendChain(message.Reply(c.Event.MessageID), messageStr)
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + outputPath + strconv.Itoa(tickCount) + ".wav"))
}
}
wg.Done()
}()
wg.Wait()
if win {
return
}
}
}
Expand All @@ -233,7 +173,7 @@ func musicLottery(musicPath, listName string) (pathOfMusic, musicName string, er
// 读取歌单文件
pathOfMusic = musicPath + listName + "/"
if file.IsNotExist(pathOfMusic) {
err = errors.New("指定的歌单不存在")
err = errors.New("指定的歌单不存在,可发送“歌单列表”查看歌单列表")
return
}
files, err := os.ReadDir(pathOfMusic)
Expand Down Expand Up @@ -271,11 +211,11 @@ func musicLottery(musicPath, listName string) (pathOfMusic, musicName string, er
}
// 进行随机抽取
if playlistID == 0 || !cfg.API {
musicName = getLocalMusic(files)
musicName = getLocalMusic(files, 10)
} else {
switch rand.Intn(3) { // 三分二概率抽取API的
case 1:
musicName = getLocalMusic(files)
musicName = getLocalMusic(files, 10)
default:
if cfg.APIURL == "" {
// 如果没有配置过API地址,尝试连接独角兽
Expand All @@ -285,22 +225,27 @@ func musicLottery(musicPath, listName string) (pathOfMusic, musicName string, er
musicName, err = drawByAPI(playlistID, pathOfMusic)
}
if err != nil {
musicName = getLocalMusic(files)
err = nil
return
musicName = getLocalMusic(files, 10)
}
}
}
if musicName == "" {
err = errors.New("抽取歌曲轮空了,请重试")
}
return
}

// 从本地列表中随机抽取一首
func getLocalMusic(files []fs.DirEntry) (musicName string) {
// 从本地列表中随机抽取一首( indexMax : 最大递归次数 )
func getLocalMusic(files []fs.DirEntry, indexMax int) (musicName string) {
if len(files) > 1 {
music := files[rand.Intn(len(files))]
// 如果是文件夹就递归
if music.IsDir() {
musicName = getLocalMusic(files)
indexMax--
if indexMax <= 0 {
return
}
musicName = getLocalMusic(files, indexMax)
} else {
musicName = music.Name()
}
Expand Down Expand Up @@ -334,3 +279,38 @@ func cutMusic(musicName, pathOfMusic, outputPath string) (err error) {
}
return
}

// 数据匹配(结果信息,答题次数,提示次数,是否结束游戏)
func gameMatch(c *zero.Ctx, beginner int64, musicInfo []string, answerTimes, tickTimes int) (message.MessageSegment, int, int, bool) {
answer := strings.Replace(c.Event.Message.String(), "-", "", 1)
switch {
case answer == "取消":
if c.Event.UserID == beginner {
return message.Text("游戏已取消,猜歌答案是\n", musicInfo[len(musicInfo)-1], "\n\n\n下面欣赏猜歌的歌曲"), answerTimes, tickTimes, true
}
return message.Text("你无权限取消"), answerTimes, tickTimes, false
case answer == "提示":
tickTimes++
if tickTimes > 2 {
return message.Text("已经没有提示了哦"), answerTimes, tickTimes, false
}
return message.Text("再听这段音频,要仔细听哦"), answerTimes, tickTimes, false
case strings.Contains(musicInfo[0], answer) || strings.EqualFold(musicInfo[0], answer):
return message.Text("太棒了,你猜对歌曲名了!答案是\n", musicInfo[len(musicInfo)-1], "\n\n下面欣赏猜歌的歌曲"), answerTimes, tickTimes, true
case strings.Contains(musicInfo[1], answer) || strings.EqualFold(musicInfo[1], answer):
return message.Text("太棒了,你猜对歌手名了!答案是\n", musicInfo[len(musicInfo)-1], "\n\n下面欣赏猜歌的歌曲"), answerTimes, tickTimes, true
case len(musicInfo) == 4 && (strings.Contains(musicInfo[2], answer) || strings.EqualFold(musicInfo[2], answer)):
return message.Text("太棒了,你猜对相关信息了!答案是\n", musicInfo[len(musicInfo)-1], "\n\n下面欣赏猜歌的歌曲"), answerTimes, tickTimes, true
default:
answerTimes++
tickTimes++
switch {
case tickTimes > 2 && answerTimes < 6:
return message.Text("答案不对哦,还有", 6-answerTimes, "次答题,加油啊~"), answerTimes, tickTimes, false
case tickTimes > 2:
return message.Text("次数到了,没能猜出来。答案是\n", musicInfo[len(musicInfo)-1], "\n\n下面欣赏猜歌的歌曲"), answerTimes, tickTimes, true
default:
return message.Text("答案不对,再听这段音频,要仔细听哦"), answerTimes, tickTimes, false
}
}
}