diff --git a/assets/translation.json b/assets/translation.json index 34cacf6..02cfff8 100644 --- a/assets/translation.json +++ b/assets/translation.json @@ -220,6 +220,10 @@ "en": "Custom Command (Default one still works)", "zh-CN": "自定义命令 (默认的依然可用)" }, + "plugin.diange.source_cmd": { + "en": "Source Command", + "zh-CN": "来源点歌命令" + }, "plugin.diange.description": { "en": "Basic Diange Configuration", "zh-CN": "点歌基本设置" diff --git a/controller/player.go b/controller/player.go index f08a26a..99c4b70 100644 --- a/controller/player.go +++ b/controller/player.go @@ -59,17 +59,21 @@ func Add(keyword string, user interface{}) { } func AddWithProvider(keyword string, pname string, user interface{}) { - medias, err := provider.Search(pname, keyword) - if err != nil { - l().Warnf("search for %s, got error %s", keyword, err) - return + media := provider.MatchMedia(pname, keyword) + if media == nil { + medias, err := provider.Search(pname, keyword) + if err != nil { + l().Warnf("search for %s, got error %s", keyword, err) + return + } + if len(medias) == 0 { + l().Infof("search for %s, got no result", keyword) + return + } + media = medias[0] } - if len(medias) == 0 { - l().Info("search for %s, got no result", keyword) - } - media := medias[0] media.User = user - l().Info("add media %s (%s)", media.Title, media.Artist) + l().Infof("add media %s (%s)", media.Title, media.Artist) UserPlaylist.Insert(-1, media) } diff --git a/plugin/diange/diange.go b/plugin/diange/diange.go index 47117dc..a521084 100644 --- a/plugin/diange/diange.go +++ b/plugin/diange/diange.go @@ -7,6 +7,7 @@ import ( "AynaLivePlayer/i18n" "AynaLivePlayer/liveclient" "AynaLivePlayer/logger" + "fmt" "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/data/binding" @@ -29,6 +30,7 @@ type Diange struct { QueueMax int UserCoolDown int CustomCMD string + SourceCMD []string cooldowns map[string]int panel fyne.CanvasObject } @@ -41,6 +43,7 @@ func NewDiange() *Diange { QueueMax: 128, UserCoolDown: -1, CustomCMD: "add", + SourceCMD: make([]string, 0), cooldowns: make(map[string]int), } } @@ -51,18 +54,42 @@ func (d *Diange) Name() string { func (d *Diange) Enable() error { config.LoadConfig(d) + d.initCMD() controller.AddCommand(d) gui.AddConfigLayout(d) return nil } -func (d *Diange) Match(command string) bool { - for _, c := range []string{"点歌", d.CustomCMD} { - if command == c { - return true +func (d *Diange) initCMD() { + if len(d.SourceCMD) == len(config.Provider.Priority) { + return + } + if len(d.SourceCMD) > len(config.Provider.Priority) { + d.SourceCMD = d.SourceCMD[:len(config.Provider.Priority)] + return + } + for i := len(d.SourceCMD); i < len(config.Provider.Priority); i++ { + d.SourceCMD = append(d.SourceCMD, "点歌"+config.Provider.Priority[i]) + } +} + +// isCMD return int if the commmand name matches our command +// -1 = not match, 0 = normal command, 1+ = source command +func (d *Diange) isCMD(cmd string) int { + if cmd == "点歌" || cmd == d.CustomCMD { + return 0 + } + fmt.Println(d.SourceCMD) + for index, c := range d.SourceCMD { + if cmd == c { + return index + 1 } } - return false + return -1 +} + +func (d *Diange) Match(command string) bool { + return d.isCMD(command) >= 0 } func (d *Diange) Execute(command string, args []string, danmu *liveclient.DanmuMessage) { @@ -78,6 +105,7 @@ func (d *Diange) Execute(command string, args []string, danmu *liveclient.DanmuM l().Infof("User %s(%s) still in cool down period, diange failed", danmu.User.Username, danmu.User.Uid) return } + cmdType := d.isCMD(command) keyword := strings.Join(args, " ") perm := d.UserPermission l().Trace("user permission check: ", perm) @@ -85,10 +113,15 @@ func (d *Diange) Execute(command string, args []string, danmu *liveclient.DanmuM l().Trace("privilege permission check: ", perm) perm = perm || (d.AdminPermission && (danmu.User.Admin)) l().Trace("admin permission check: ", perm) - if perm { - // reset cool down - d.cooldowns[danmu.User.Uid] = ct + if !perm { + return + } + // reset cool down + d.cooldowns[danmu.User.Uid] = ct + if cmdType == 0 { controller.Add(keyword, &danmu.User) + } else { + controller.AddWithProvider(keyword, config.Provider.Priority[cmdType-1], &danmu.User) } } @@ -122,6 +155,17 @@ func (d *Diange) CreatePanel() fyne.CanvasObject { widget.NewLabel(i18n.T("plugin.diange.custom_cmd")), nil, widget.NewEntryWithData(binding.BindString(&d.CustomCMD)), ) - d.panel = container.NewVBox(dgPerm, dgQueue, dgCoolDown, dgShortCut) + sourceCmds := []fyne.CanvasObject{} + for i, _ := range d.SourceCMD { + sourceCmds = append( + sourceCmds, + container.NewBorder( + nil, nil, widget.NewLabel(config.Provider.Priority[i]), nil, + widget.NewEntryWithData(binding.BindString(&d.SourceCMD[i])))) + } + dgSourceCMD := container.NewBorder( + nil, nil, widget.NewLabel(i18n.T("plugin.diange.source_cmd")), nil, + container.NewVBox(sourceCmds...)) + d.panel = container.NewVBox(dgPerm, dgQueue, dgCoolDown, dgShortCut, dgSourceCMD) return d.panel } diff --git a/provider/bilibili.go b/provider/bilibili.go index 2e7e5b8..cfdb804 100644 --- a/provider/bilibili.go +++ b/provider/bilibili.go @@ -116,7 +116,6 @@ func (b *Bilibili) UpdateMediaUrl(media *player.Media) error { media.Header = map[string]string{ "user-agent": "BiliMusic/2.233.3", } - fmt.Println(fmt.Sprintf(b.InfoApi, media.Meta.(Meta).Id)) uri := gjson.Get(resp, "data.cdns.0").String() if uri == "" { return ErrorExternalApi diff --git a/provider/bilivideo.go b/provider/bilivideo.go index bcf71dc..a3eafef 100644 --- a/provider/bilivideo.go +++ b/provider/bilivideo.go @@ -82,7 +82,7 @@ func (b *BilibiliVideo) Search(keyword string) ([]*player.Media, error) { } func (b *BilibiliVideo) UpdateMedia(media *player.Media) error { - resp := httpGetString(fmt.Sprintf(b.InfoApi, media.Meta.(Meta).Id), nil) + resp := httpGetString(fmt.Sprintf(b.InfoApi, b.getBv(media.Meta.(Meta).Id)), nil) if resp == "" { return ErrorExternalApi } @@ -98,12 +98,12 @@ func (b *BilibiliVideo) UpdateMedia(media *player.Media) error { } func (b *BilibiliVideo) UpdateMediaUrl(media *player.Media) error { - resp := httpGetString(fmt.Sprintf(b.InfoApi, media.Meta.(Meta).Id), nil) + resp := httpGetString(fmt.Sprintf(b.InfoApi, b.getBv(media.Meta.(Meta).Id)), nil) if resp == "" { return ErrorExternalApi } jresp := gjson.Parse(resp) - page := b.getPage(media.Meta.(Meta).Id) + page := b.getPage(media.Meta.(Meta).Id) - 1 cid := jresp.Get(fmt.Sprintf("data.View.pages.%d.cid", page)).String() if cid == "" { cid = jresp.Get("data.View.cid").String() diff --git a/provider/bilivideo_test.go b/provider/bilivideo_test.go index e1bada3..a74289e 100644 --- a/provider/bilivideo_test.go +++ b/provider/bilivideo_test.go @@ -3,6 +3,7 @@ package provider import ( "AynaLivePlayer/player" "fmt" + "regexp" "testing" ) @@ -42,3 +43,44 @@ func TestBV_GetMusic(t *testing.T) { //fmt.Println(media) fmt.Println(media.Url) } + +func TestBV_Regex(t *testing.T) { + fmt.Println(regexp.MustCompile("^BV[0-9A-Za-z]+(\\?p=[0-9]+)?").FindString("BV1gA411P7ir?p=3")) +} + +func TestBV_GetMusicMeta2(t *testing.T) { + var api MediaProvider = BilibiliVideoAPI + + media := player.Media{ + Meta: Meta{ + Name: api.GetName(), + Id: "BV1gA411P7ir?p=3", + }, + } + err := api.UpdateMedia(&media) + fmt.Println(err) + if err != nil { + return + } + fmt.Println(media) +} + +func TestBV_GetMusic2(t *testing.T) { + var api MediaProvider = BilibiliVideoAPI + media := player.Media{ + Meta: Meta{ + Name: api.GetName(), + Id: "BV1gA411P7ir?p=3", + }, + } + err := api.UpdateMedia(&media) + if err != nil { + return + } + err = api.UpdateMediaUrl(&media) + if err != nil { + return + } + //fmt.Println(media) + fmt.Println(media.Url) +} diff --git a/provider/provider.go b/provider/provider.go index 976d821..5d1dfbd 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -44,6 +44,13 @@ func FormatPlaylistUrl(pname, uri string) (string, error) { return "", ErrorNoSuchProvider } +func MatchMedia(provider string, keyword string) *player.Media { + if v, ok := Providers[provider]; ok { + return v.MatchMedia(keyword) + } + return nil +} + func Search(provider string, keyword string) ([]*player.Media, error) { if v, ok := Providers[provider]; ok { return v.Search(keyword) diff --git a/util/string.go b/util/string.go index ffa0df6..8e7c4fe 100644 --- a/util/string.go +++ b/util/string.go @@ -38,3 +38,9 @@ func StringToInt(s string) int { i, _ := strconv.Atoi(s) return i } + +func StringSliceCopy(src []string) []string { + x := make([]string, len(src)) + copy(x, src) + return x +}