Skip to content

Commit 09a756e

Browse files
fangliuyushudorcl
authored andcommitted
修复猜歌已知问题 (FloatTech#340)
* Update main.go * Update struct.go * Update main.go * Update main.go
1 parent f01610b commit 09a756e

File tree

2 files changed

+103
-57
lines changed

2 files changed

+103
-57
lines changed

plugin/guessmusic/main.go

Lines changed: 88 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,11 @@ const (
3939
)
4040

4141
var (
42-
catlist = make(map[string]int64, 100)
43-
filelist []string
44-
cuttime = [...]string{"00:00:05", "00:00:30", "00:01:00"} // 音乐切割时间点,可自行调节时间(时:分:秒)
45-
cfg config
42+
catlist = make(map[string]int64, 100)
43+
filelist []string
44+
musictypelist = "mp3;MP3;wav;WAV;amr;AMR;3gp;3GP;3gpp;3GPP;acc;ACC"
45+
cuttime = [...]string{"00:00:05", "00:00:30", "00:01:00"} // 音乐切割时间点,可自行调节时间(时:分:秒)
46+
cfg config
4647
)
4748

4849
func init() { // 插件主体
@@ -138,6 +139,11 @@ func init() { // 插件主体
138139
if !strings.HasSuffix(musicPath, "/") {
139140
musicPath += "/"
140141
}
142+
err = os.MkdirAll(cfg.MusicPath, 0755)
143+
if err != nil {
144+
ctx.SendChain(message.Text("[生成文件夹错误]ERROR:", err))
145+
return
146+
}
141147
cfg.MusicPath = musicPath
142148
case "本地":
143149
choice, err := strconv.ParseBool(value)
@@ -193,7 +199,9 @@ func init() { // 插件主体
193199
ctx.SendChain(message.Text("解析网易云二维码失败, ERROR:", err))
194200
return
195201
}
196-
ctx.SendChain(message.Text("[请使用手机APP扫描二维码或者进入网页扫码登录]\n", qrInfo.Data.Qrurl), message.Image("base64://"+strings.ReplaceAll(qrInfo.Data.Qrimg, "data:image/png;base64,", "")), message.Text("二维码有效时间为6分钟"))
202+
ctx.SendChain(message.Text("[请使用手机APP扫描二维码或者进入网页扫码登录]\n", qrInfo.Data.Qrurl),
203+
message.Image("base64://"+strings.ReplaceAll(qrInfo.Data.Qrimg, "data:image/png;base64,", "")),
204+
message.Text("二维码有效时间为6分钟,登陆后请耐心等待结果,获取cookie过程有些漫长。"))
197205
i := 0
198206
for range time.NewTicker(10 * time.Second).C {
199207
apiURL := "https://music.cyrilstudio.top/login/qr/check?key=" + url.QueryEscape(keyInfo.Data.Unikey)
@@ -234,11 +242,13 @@ func init() { // 插件主体
234242
}
235243
}
236244
})
237-
engine.OnRegex(`^添加歌单\s?(\d*)(\s(.*))?$`, zero.SuperUserPermission).SetBlock(true).Limit(ctxext.LimitByGroup).
245+
engine.OnRegex(`^添加歌单\s?(\d+)(\s(.*))?$`, zero.SuperUserPermission).SetBlock(true).Limit(ctxext.LimitByGroup).
238246
Handle(func(ctx *zero.Ctx) {
239247
listID := ctx.State["regex_matched"].([]string)[1]
240248
listName := ctx.State["regex_matched"].([]string)[3]
241-
apiURL := "https://music.cyrilstudio.top/playlist/detail?id=" + listID + "&cookie=" + url.QueryEscape(cfg.Cookie)
249+
ctx.SendChain(message.Text("正在校验歌单信息,请稍等"))
250+
// 是否存在该歌单
251+
apiURL := "https://music.cyrilstudio.top/playlist/detail?id=" + listID + "&cookie=" + cfg.Cookie
242252
referer := "https://music.cyrilstudio.top"
243253
data, err := web.RequestDataWith(web.NewDefaultClient(), apiURL, "GET", referer, ua)
244254
if err != nil {
@@ -251,6 +261,21 @@ func init() { // 插件主体
251261
ctx.SendChain(message.Text("无法解析歌单ID内容,[error]", err))
252262
return
253263
}
264+
// 是否有权限访问歌单列表内容
265+
apiURL = "https://music.cyrilstudio.top/playlist/track/all?id=" + listID + "&cookie=" + cfg.Cookie
266+
referer = "https://music.163.com/"
267+
data, err = web.RequestDataWith(web.NewDefaultClient(), apiURL, "GET", referer, ua)
268+
if err != nil {
269+
ctx.SendChain(message.Text("无法获取歌单列表\n ERROR:", err))
270+
return
271+
}
272+
var musiclist topMusicInfo
273+
err = json.Unmarshal(data, &musiclist)
274+
if err != nil {
275+
ctx.SendChain(message.Text("你的cookie在API中无权访问该歌单\n该歌单有可能是用户私人歌单"))
276+
return
277+
}
278+
// 获取列表名字
254279
if listName == "" {
255280
listName = parsed.Playlist.Name
256281
}
@@ -303,7 +328,7 @@ func init() { // 插件主体
303328
// 获取网易云歌单列表
304329
if cfg.API {
305330
catlist = make(map[string]int64, 100)
306-
msg = append(msg, "\n当前添加的API歌单含有以下\n")
331+
msg = append(msg, "当前添加的API歌单含有以下\n")
307332
for i, listInfo := range cfg.Playlist {
308333
catlist[listInfo.Name] = listInfo.ID
309334
msg = append(msg, strconv.Itoa(i)+":"+listInfo.Name)
@@ -318,18 +343,23 @@ func init() { // 插件主体
318343
if err == nil {
319344
files, err := ioutil.ReadDir(cfg.MusicPath)
320345
if err == nil {
321-
msg = append(msg, "\n当前本地歌单含有以下:\n")
322-
i := 0
323-
for _, name := range files {
324-
if !name.IsDir() {
325-
continue
326-
}
327-
filelist[i] = strconv.Itoa(i) + ":" + name.Name()
328-
msg = append(msg, filelist[i])
329-
if i%3 == 2 {
330-
msg = append(msg, "\n")
346+
if len(files) == 0 {
347+
ctx.SendChain(message.Text("缓存目录没有读取到任何歌单"))
348+
filelist = nil
349+
} else {
350+
msg = append(msg, "\n当前本地歌单含有以下:\n")
351+
i := 0
352+
for _, name := range files {
353+
if !name.IsDir() {
354+
continue
355+
}
356+
filelist[i] = strconv.Itoa(i) + ":" + name.Name()
357+
msg = append(msg, filelist[i])
358+
if i%3 == 2 {
359+
msg = append(msg, "\n")
360+
}
361+
i++
331362
}
332-
i++
333363
}
334364
} else {
335365
ctx.SendChain(message.Text("[读取本地列表错误]ERROR:", err))
@@ -354,6 +384,10 @@ func init() { // 插件主体
354384
engine.OnSuffix("歌单信息").SetBlock(true).Limit(ctxext.LimitByGroup).
355385
Handle(func(ctx *zero.Ctx) {
356386
list := ctx.State["args"].(string)
387+
if list == "" {
388+
ctx.SendChain(message.Text("请输入歌单ID或者API歌单名称\n歌单ID为(网页/分享)链接的“playlist”后面的第一串数字"))
389+
return
390+
}
357391
var listIDStr string
358392
for listName, listID := range catlist {
359393
if list == listName || list == strconv.FormatInt(listID, 10) {
@@ -369,7 +403,7 @@ func init() { // 插件主体
369403
}
370404
listIDStr = list
371405
}
372-
apiURL := "https://music.cyrilstudio.top/playlist/detail?id=" + listIDStr + "&cookie=" + url.QueryEscape(cfg.Cookie)
406+
apiURL := "https://music.cyrilstudio.top/playlist/detail?id=" + listIDStr + "&cookie=" + cfg.Cookie
373407
referer := "https://music.cyrilstudio.top"
374408
data, err := web.RequestDataWith(web.NewDefaultClient(), apiURL, "GET", referer, ua)
375409
if err != nil {
@@ -400,15 +434,11 @@ func init() { // 插件主体
400434
mode := ctx.State["regex_matched"].([]string)[3]
401435
if mode == "" {
402436
mode = "动画榜"
437+
catlist[mode] = 3001835560
403438
}
404439
_, ok := catlist[mode]
405-
switch {
406-
// 如果API没有开,本地也不存在这个歌单
407-
case !cfg.API && !strings.Contains(strings.Join(filelist, " "), mode):
408-
ctx.SendChain(message.Text("歌单名称错误,可以发送“获取歌单列表”获取歌单名称"))
409-
return
410-
// 如果本地没有开,网易云也不存在这个歌单
411-
case !cfg.Local && !ok:
440+
// 如果本地和API不存在该歌单
441+
if !strings.Contains(strings.Join(filelist, " "), mode) && !ok {
412442
ctx.SendChain(message.Text("歌单名称错误,可以发送“获取歌单列表”获取歌单名称"))
413443
return
414444
}
@@ -420,22 +450,36 @@ func init() { // 插件主体
420450
ctx.SendChain(message.Text(err))
421451
return
422452
}
423-
// 切割音频,生成3个10秒的音频
424-
outputPath := cachePath + gid + "/"
425-
err = cutMusic(musicName, pathOfMusic, outputPath)
426-
if err != nil {
427-
ctx.SendChain(message.Text(err))
453+
// 解析歌曲信息
454+
music := strings.Split(musicName, ".")
455+
// 获取音乐后缀
456+
musictype := music[len(music)-1]
457+
if !strings.Contains(musictypelist, musictype) {
458+
ctx.SendChain(message.Text("抽取到了本地歌曲:\n",
459+
musicName, "\n该歌曲不是音乐后缀,请联系bot主人修改"))
428460
return
429461
}
430-
// 解析歌曲信息
431-
musicInfo := strings.Split(musicName, " - ")
462+
// 获取音乐信息
463+
musicInfo := strings.Split(strings.ReplaceAll(musicName, "."+musictype, ""), " - ")
432464
infoNum := len(musicInfo)
465+
if infoNum == 1 {
466+
ctx.SendChain(message.Text("抽取到了本地歌曲:\n",
467+
musicName, "\n该歌曲命名不符合命名规则,请联系bot主人修改"))
468+
return
469+
}
433470
answerString := "歌名:" + musicInfo[0] + "\n歌手:" + musicInfo[1]
434471
musicAlia := ""
435472
if infoNum > 2 {
436473
musicAlia = musicInfo[2]
437474
answerString += "\n其他信息:\n" + strings.ReplaceAll(musicAlia, "&", "\n")
438475
}
476+
// 切割音频,生成3个10秒的音频
477+
outputPath := cachePath + gid + "/"
478+
err = cutMusic(musicName, pathOfMusic, outputPath)
479+
if err != nil {
480+
ctx.SendChain(message.Text(err))
481+
return
482+
}
439483
// 进行猜歌环节
440484
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + outputPath + "0.wav"))
441485
var next *zero.FutureEvent
@@ -660,24 +704,26 @@ func musicLottery(mode, musicPath string) (musicName, pathOfMusic string, err er
660704

661705
func getLocalMusic(files []fs.FileInfo) (musicName string) {
662706
if len(files) > 1 {
663-
musicName = strings.Replace(files[rand.Intn(len(files))].Name(), ".mp3", "", 1)
707+
musicName = files[rand.Intn(len(files))].Name()
664708
} else {
665-
musicName = strings.Replace(files[0].Name(), ".mp3", "", 1)
709+
musicName = files[0].Name()
666710
}
667711
return
668712
}
669713

670714
// 下载网易云歌单音乐
671715
func getListMusic(listID, pathOfMusic string) (musicName string, err error) {
672-
apiURL := "https://music.cyrilstudio.top/playlist/track/all?id=" + listID + "&cookie=" + url.QueryEscape(cfg.Cookie)
673-
referer := "https://music.cyrilstudio.top"
716+
apiURL := "https://music.cyrilstudio.top/playlist/track/all?id=" + listID + "&cookie=" + cfg.Cookie
717+
referer := "https://music.163.com/"
674718
data, err := web.RequestDataWith(web.NewDefaultClient(), apiURL, "GET", referer, ua)
675719
if err != nil {
720+
err = errors.Errorf("无法获取歌单列表\n ERROR: %s", err)
676721
return
677722
}
678723
var parsed topMusicInfo
679724
err = json.Unmarshal(data, &parsed)
680725
if err != nil {
726+
err = errors.Errorf("无法读取歌单列表\n ERROR: %s", err)
681727
return
682728
}
683729
listlen := len(parsed.Songs)
@@ -714,11 +760,11 @@ func getListMusic(listID, pathOfMusic string) (musicName string, err error) {
714760
return
715761
}
716762
if cource != "" {
717-
musicName = name + " - " + artistName + " - " + cource
763+
musicName = name + " - " + artistName + " - " + cource + ".mp3"
718764
} else {
719-
musicName = name + " - " + artistName
765+
musicName = name + " - " + artistName + ".mp3"
720766
}
721-
downMusic := pathOfMusic + musicName + ".mp3"
767+
downMusic := pathOfMusic + musicName
722768
if file.IsNotExist(downMusic) {
723769
data, err = web.GetData(musicURL)
724770
if err != nil {
@@ -740,7 +786,7 @@ func cutMusic(musicName, pathOfMusic, outputPath string) (err error) {
740786
return
741787
}
742788
var stderr bytes.Buffer
743-
cmdArguments := []string{"-y", "-i", pathOfMusic + musicName + ".mp3",
789+
cmdArguments := []string{"-y", "-i", pathOfMusic + musicName,
744790
"-ss", cuttime[0], "-t", "10", file.BOTPATH + "/" + outputPath + "0.wav",
745791
"-ss", cuttime[1], "-t", "10", file.BOTPATH + "/" + outputPath + "1.wav",
746792
"-ss", cuttime[2], "-t", "10", file.BOTPATH + "/" + outputPath + "2.wav", "-hide_banner"}

plugin/guessmusic/struct.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -168,25 +168,25 @@ type topList struct {
168168
} `json:"al"`
169169
Dt int `json:"dt"`
170170
H struct {
171-
Br int `json:"br"`
172-
Fid int `json:"fid"`
173-
Size int `json:"size"`
174-
Vd int `json:"vd"`
175-
Sr int `json:"sr"`
171+
Br int `json:"br"`
172+
Fid int `json:"fid"`
173+
Size int `json:"size"`
174+
Vd float64 `json:"vd"`
175+
Sr int `json:"sr"`
176176
} `json:"h"`
177177
M struct {
178-
Br int `json:"br"`
179-
Fid int `json:"fid"`
180-
Size int `json:"size"`
181-
Vd int `json:"vd"`
182-
Sr int `json:"sr"`
178+
Br int `json:"br"`
179+
Fid int `json:"fid"`
180+
Size int `json:"size"`
181+
Vd float64 `json:"vd"`
182+
Sr int `json:"sr"`
183183
} `json:"m"`
184184
L struct {
185-
Br int `json:"br"`
186-
Fid int `json:"fid"`
187-
Size int `json:"size"`
188-
Vd int `json:"vd"`
189-
Sr int `json:"sr"`
185+
Br int `json:"br"`
186+
Fid int `json:"fid"`
187+
Size int `json:"size"`
188+
Vd float64 `json:"vd"`
189+
Sr int `json:"sr"`
190190
} `json:"l"`
191191
Sq interface{} `json:"sq"`
192192
Hr interface{} `json:"hr"`

0 commit comments

Comments
 (0)