mirror of
https://github.com/ZxwyWebSite/lx-source.git
synced 2025-05-23 21:37:42 +08:00
2024-02-20 v1.0.3-fix
This commit is contained in:
parent
2dea36c3ce
commit
07c32ab6d4
@ -99,5 +99,5 @@
|
||||
|
||||
音乐平台不易,请尊重版权,支持正版。
|
||||
本项目仅用于对技术可行性的探索及研究,不接受任何商业(包括但不限于广告等)合作及捐赠。
|
||||
若对此有疑问请 mail to: admin+zxwy.tk (请将`+`替换为`@`)
|
||||
若对此有疑问请 mail to: admin+zxwy.link (请将`+`替换为`@`)
|
||||
|
23
src/env/env.go
vendored
23
src/env/env.go
vendored
@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
Version = `1.0.3-pre`
|
||||
Version = `1.0.3-fix`
|
||||
)
|
||||
|
||||
var (
|
||||
@ -121,9 +121,19 @@ type (
|
||||
Kw_Des_Header string `comment:"请求头 User-Agent"`
|
||||
|
||||
// kg
|
||||
Kg_Enable bool `comment:"是否启用小枸源"`
|
||||
Kg_Enable bool `comment:"是否启用小枸源"`
|
||||
// kg client
|
||||
Kg_Client_AppId string `comment:"酷狗音乐的appid,官方安卓为1005,官方PC为1001(client.appid)"`
|
||||
Kg_Client_SignKey string `comment:"客户端signature采用的key值,需要与appid对应(client.signatureKey)"`
|
||||
Kg_Client_Version string `comment:"客户端versioncode,pidversionsecret可能随此值而变化(client.clientver)"`
|
||||
Kg_Client_PidVerSec string `comment:"获取URL时所用的key值计算验证值(client.pidversionsecret)"`
|
||||
Kg_Client_Pid string `comment:"field client.pid"`
|
||||
// kg user
|
||||
Kg_token string `comment:"field user.token"`
|
||||
Kg_userId string `comment:"field user.userid"`
|
||||
// kg lite_sign_in
|
||||
Kg_Lite_Enable bool `comment:"是否启用概念版自动签到,仅在appid=3116时运行"`
|
||||
Kg_Lite_Interval int64 `comment:"调用时间,自动刷新"`
|
||||
|
||||
// tx
|
||||
Tx_Enable bool `comment:"是否启用小秋源"`
|
||||
@ -227,8 +237,13 @@ var (
|
||||
Kw_Des_Type: `json`,
|
||||
Kw_Des_Header: `okhttp/3.10.0`,
|
||||
|
||||
Kg_Enable: false,
|
||||
Kg_userId: `0`,
|
||||
Kg_Enable: false,
|
||||
Kg_Client_AppId: `1005`,
|
||||
Kg_Client_SignKey: `OIlwieks28dk2k092lksi2UIkp`,
|
||||
Kg_Client_Version: `12029`,
|
||||
Kg_Client_PidVerSec: `57ae12eb6890223e355ccfcb74edf70d`,
|
||||
Kg_Client_Pid: `2`,
|
||||
Kg_userId: `0`,
|
||||
|
||||
Tx_Enable: false,
|
||||
Tx_Refresh_Enable: false,
|
||||
|
@ -56,12 +56,12 @@ func (o *Resp) Execute(c *gin.Context) {
|
||||
default:
|
||||
status = http.StatusOK
|
||||
}
|
||||
// if o.Code != 0 {
|
||||
// if o.Code == 2 /*&& o.Data == ``*/ {
|
||||
// o.Data = ErrMp3
|
||||
// }
|
||||
// c.Abort()
|
||||
// }
|
||||
if o.Code != 0 {
|
||||
// if o.Code == 2 /*&& o.Data == ``*/ {
|
||||
// o.Data = ErrMp3
|
||||
// }
|
||||
c.Abort()
|
||||
}
|
||||
c.JSON(status, o)
|
||||
}
|
||||
|
||||
|
@ -3,11 +3,13 @@ package server
|
||||
import (
|
||||
"lx-source/src/caches"
|
||||
"lx-source/src/env"
|
||||
"lx-source/src/middleware/auth"
|
||||
"lx-source/src/middleware/resp"
|
||||
"lx-source/src/middleware/util"
|
||||
"lx-source/src/sources"
|
||||
"lx-source/src/sources/custom"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/ZxwyWebSite/ztool"
|
||||
"github.com/gin-gonic/gin"
|
||||
@ -23,10 +25,9 @@ import (
|
||||
// }
|
||||
// )
|
||||
|
||||
func loadMusic(api *gin.RouterGroup) {
|
||||
func loadMusic(api gin.IRouter) {
|
||||
// /{method}/{source}/{musicId}/{?quality}
|
||||
api.GET(`/:m/:s/:id/*q`, musicHandler)
|
||||
|
||||
api.GET(`/:m/:s/:id/*q`, auth.InitHandler(musicHandler)...)
|
||||
}
|
||||
|
||||
func musicHandler(c *gin.Context) {
|
||||
@ -40,32 +41,36 @@ func musicHandler(c *gin.Context) {
|
||||
loger.Debug(`s:'%v', m:'%v', id:'%v', q:'%v'`, ps, pm, pid, pq)
|
||||
// 查询内存缓存
|
||||
cquery := strings.Join([]string{pm, ps, pid, pq}, `/`)
|
||||
loger.Debug(cquery)
|
||||
if clink, ok := env.Cache.Get(cquery); ok {
|
||||
if cstr, ok := clink.(string); ok {
|
||||
loger.Debug(`MemHIT [%q]=>[%q]`, cquery, cstr)
|
||||
if cstr == `` {
|
||||
out.Code = 2
|
||||
out.Msg = `Memory Reject`
|
||||
} else {
|
||||
out.Msg = `Memory HIT`
|
||||
out.Data = cstr
|
||||
}
|
||||
return out
|
||||
loger.Debug(`MemoGet: %v`, cquery)
|
||||
if cdata, ok := env.Cache.Get(cquery); ok {
|
||||
loger.Debug(`MemoHIT: %q`, cdata)
|
||||
if cdata == `` {
|
||||
out.Code = 2
|
||||
out.Msg = memRej
|
||||
} else {
|
||||
out.Msg = memHIT
|
||||
out.Data = cdata
|
||||
}
|
||||
return out
|
||||
}
|
||||
// 定位音乐源
|
||||
var source custom.Source
|
||||
var active bool // 是否激活(自定义账号)
|
||||
switch ps {
|
||||
case sources.S_wy:
|
||||
active = env.Config.Custom.Wy_Enable
|
||||
source = custom.WySource
|
||||
case sources.S_mg:
|
||||
active = env.Config.Custom.Mg_Enable
|
||||
source = custom.MgSource
|
||||
case sources.S_kw:
|
||||
active = env.Config.Custom.Kw_Enable
|
||||
source = custom.KwSource
|
||||
case sources.S_kg:
|
||||
active = env.Config.Custom.Kg_Enable
|
||||
source = custom.KgSource
|
||||
case sources.S_tx:
|
||||
active = env.Config.Custom.Tx_Enable
|
||||
source = custom.TxSource
|
||||
case sources.S_lx:
|
||||
source = custom.LxSource
|
||||
@ -88,18 +93,45 @@ func musicHandler(c *gin.Context) {
|
||||
switch pm {
|
||||
case `url`, `link`:
|
||||
// 查询文件缓存
|
||||
if caches.UseCache.Stat() {
|
||||
uquery := caches.NewQuery(ps, pid, pq)
|
||||
defer uquery.Free()
|
||||
var cstat bool
|
||||
if caches.UseCache != nil {
|
||||
cstat = caches.UseCache.Stat()
|
||||
}
|
||||
uquery := caches.NewQuery(ps, pid, pq)
|
||||
defer uquery.Free()
|
||||
if cstat {
|
||||
loger.Debug(`FileGet: %v`, uquery.Query())
|
||||
if olink := caches.UseCache.Get(uquery); olink != `` {
|
||||
env.Cache.Set(cquery, olink, 3600)
|
||||
out.Msg = `Cache HIT`
|
||||
env.Cache.Set(cquery, olink, 7200)
|
||||
out.Msg = cacheHIT
|
||||
out.Data = olink
|
||||
return out
|
||||
}
|
||||
}
|
||||
out.Msg = `No Link`
|
||||
// out.Data, out.Msg = source.Url(pid, pq)
|
||||
// 解析歌曲外链
|
||||
atomic.AddInt64(&reqnum, 1)
|
||||
out.Data, out.Msg = source.Url(pid, pq)
|
||||
if out.Data != `` {
|
||||
// 缓存并获取直链
|
||||
atomic.AddInt64(&secnum, 1)
|
||||
if out.Msg == `` {
|
||||
if cstat && active {
|
||||
loger.Debug(`FileSet: %v`, out.Data)
|
||||
if link := caches.UseCache.Set(uquery, out.Data.(string)); link != `` {
|
||||
env.Cache.Set(cquery, link, 7200)
|
||||
out.Msg = cacheSet
|
||||
out.Data = link
|
||||
return out
|
||||
}
|
||||
out.Msg = cacheFAIL
|
||||
} else {
|
||||
out.Msg = cacheMISS
|
||||
}
|
||||
}
|
||||
// 无法获取直链 直接返回原链接
|
||||
env.Cache.Set(cquery, out.Data, 1200)
|
||||
return out
|
||||
}
|
||||
case `lrc`, `lyric`:
|
||||
out.Data, out.Msg = source.Lrc(pid)
|
||||
case `pic`, `cover`:
|
||||
@ -107,10 +139,11 @@ func musicHandler(c *gin.Context) {
|
||||
default:
|
||||
out.Code = 6
|
||||
out.Msg = ztool.Str_FastConcat(`无效源方法:'`, pm, `'`)
|
||||
// return
|
||||
return out
|
||||
}
|
||||
// 缓存并获取直链
|
||||
if out.Data != `` {
|
||||
if out.Msg != `` {
|
||||
out.Code = 2
|
||||
env.Cache.Set(cquery, out.Data, 600)
|
||||
}
|
||||
return out
|
||||
})
|
||||
|
@ -3,7 +3,6 @@ package server
|
||||
import (
|
||||
"lx-source/src/caches"
|
||||
"lx-source/src/env"
|
||||
"lx-source/src/middleware/auth"
|
||||
"lx-source/src/middleware/dynlink"
|
||||
"lx-source/src/middleware/resp"
|
||||
"lx-source/src/middleware/util"
|
||||
@ -64,7 +63,8 @@ func InitRouter() *gin.Engine {
|
||||
// r.StaticFile(`/favicon.ico`, `public/icon.ico`)
|
||||
// r.StaticFile(`/lx-custom-source.js`, `public/lx-custom-source.js`)
|
||||
// 解析接口
|
||||
r.GET(`/link/:s/:id/:q`, auth.InitHandler(linkHandler)...)
|
||||
loadMusic(r)
|
||||
// r.GET(`/link/:s/:id/:q`, auth.InitHandler(linkHandler)...)
|
||||
dynlink.LoadHandler(r)
|
||||
// 动态链?
|
||||
// r.GET(`/file/:t/:x/:f`, dynlink.FileHandler())
|
||||
@ -75,7 +75,6 @@ func InitRouter() *gin.Engine {
|
||||
// r.Static(`/file`, env.Config.Cache.Local_Path)
|
||||
// }
|
||||
// 功能接口
|
||||
// loadMusic(r.Group(`/api`))
|
||||
// api := r.Group(`/api`)
|
||||
// {
|
||||
// api.GET(`/:s/:m/:q`) // {source}/{method}/{query}
|
||||
@ -105,6 +104,7 @@ const (
|
||||
cacheHIT = `Cache HIT` // 缓存已命中
|
||||
cacheMISS = `Cache MISS` // 缓存未命中
|
||||
cacheSet = `Cache Seted` // 缓存已设置
|
||||
cacheFAIL = `Cache FAIL` // 缓存未成功
|
||||
|
||||
memHIT = `Memory HIT` // 内存已命中
|
||||
memRej = `Memory Reject` // 内存已拒绝
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"lx-source/src/sources/custom/tx"
|
||||
"lx-source/src/sources/custom/wy"
|
||||
wm "lx-source/src/sources/custom/wy/modules"
|
||||
"lx-source/src/sources/example"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"sync"
|
||||
@ -72,8 +73,8 @@ func (s *Source) GetLink(c *caches.Query) (outlink string, msg string) {
|
||||
if env.Config.Source.MusicIdVerify {
|
||||
vef := wv_pool.Get().(*wm.VerifyInfo)
|
||||
defer wv_pool.Put(vef)
|
||||
vurl := ztool.Str_FastConcat(`https://`, vef_wy, `&id=`, c.MusicID)
|
||||
_, err := ztool.Net_HttpReq(http.MethodGet, vurl, nil, header_wy, &vef)
|
||||
vurl := ztool.Str_FastConcat(`https://`, example.Vef_wy, `&id=`, c.MusicID)
|
||||
_, err := ztool.Net_HttpReq(http.MethodGet, vurl, nil, example.Header_wy, &vef)
|
||||
if err != nil {
|
||||
jx.Error(`Wy, VefReq: %s`, err)
|
||||
msg = sources.ErrHttpReq
|
||||
@ -95,13 +96,13 @@ func (s *Source) GetLink(c *caches.Query) (outlink string, msg string) {
|
||||
// }
|
||||
// url := urls[rand.Intn(len(urls))]
|
||||
url := ztool.Str_FastConcat(
|
||||
`https://`, api_wy, `&id=`, c.MusicID, `&level=`, rquery,
|
||||
`https://`, example.Api_wy, `&id=`, c.MusicID, `&level=`, rquery,
|
||||
`×tamp=`, strconv.FormatInt(time.Now().UnixMilli(), 10),
|
||||
)
|
||||
// jx.Debug(`Wy, Url: %v`, url)
|
||||
// wy源增加后端重试 默认3次
|
||||
for i := 0; true; i++ {
|
||||
_, err := ztool.Net_HttpReq(http.MethodGet, url, nil, header_wy, &resp)
|
||||
_, err := ztool.Net_HttpReq(http.MethodGet, url, nil, example.Header_wy, &resp)
|
||||
if err != nil {
|
||||
jx.Error(`HttpReq, Err: %s, ReTry: %v`, err, i)
|
||||
if i > 3 {
|
||||
@ -149,9 +150,9 @@ func (s *Source) GetLink(c *caches.Query) (outlink string, msg string) {
|
||||
resp := mg_pool.Get().(*MgApi_Song)
|
||||
defer mg_pool.Put(resp)
|
||||
|
||||
url := ztool.Str_FastConcat(`https://`, api_mg, `?copyrightId=`, c.MusicID, `&type=`, rquery)
|
||||
url := ztool.Str_FastConcat(`https://`, example.Api_mg, `?copyrightId=`, c.MusicID, `&type=`, rquery)
|
||||
// jx.Debug(`Mg, Url: %v`, url)
|
||||
_, err := ztool.Net_HttpReq(http.MethodGet, url, nil, header_mg, &resp)
|
||||
_, err := ztool.Net_HttpReq(http.MethodGet, url, nil, example.Header_mg, &resp)
|
||||
if err != nil {
|
||||
jx.Error(`Mg, HttpReq: %s`, err)
|
||||
msg = sources.ErrHttpReq
|
||||
|
@ -1,11 +1,7 @@
|
||||
package builtin
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"lx-source/src/sources"
|
||||
|
||||
"github.com/ZxwyWebSite/ztool"
|
||||
"github.com/ZxwyWebSite/ztool/zcypt"
|
||||
)
|
||||
|
||||
type (
|
||||
@ -242,18 +238,20 @@ var (
|
||||
sources.S_wy: `exhigh`,
|
||||
sources.S_mg: `2`,
|
||||
sources.S_kw: sources.Q_320k,
|
||||
// sources.S_kg: ``,
|
||||
sources.S_kg: ``,
|
||||
sources.S_tx: `M800`,
|
||||
},
|
||||
sources.Q_flac: {
|
||||
sources.S_wy: `lossless`,
|
||||
sources.S_mg: `3`,
|
||||
sources.S_kw: `2000k`,
|
||||
sources.S_kg: ``,
|
||||
sources.S_tx: `F000`,
|
||||
},
|
||||
sources.Q_fl24: {
|
||||
sources.S_wy: `hires`,
|
||||
sources.S_mg: `4`,
|
||||
sources.S_kg: ``,
|
||||
// sources.S_tx: `RS01`,
|
||||
},
|
||||
// `fl24`: {
|
||||
@ -262,35 +260,15 @@ var (
|
||||
// },
|
||||
}
|
||||
// ApiAddr
|
||||
api_wy string
|
||||
api_mg string
|
||||
// api_wy string
|
||||
// api_mg string
|
||||
// api_kw string
|
||||
// api_kg string = `https://wwwapi.kugou.com/yy/index.php?r=play/getdata&platid=4&mid=1`
|
||||
// api_tx string = `https://u.y.qq.com/cgi-bin/musicu.fcg?data=`
|
||||
vef_wy string
|
||||
// vef_wy string
|
||||
// Headers
|
||||
header_wy map[string]string
|
||||
header_mg map[string]string
|
||||
// header_wy map[string]string
|
||||
// header_mg map[string]string
|
||||
// header_kw map[string]string
|
||||
// header_tx = map[string]string{`Referer`: `https://y.qq.com/`}
|
||||
)
|
||||
|
||||
func init() {
|
||||
// InitBuiltInSource
|
||||
var initdata = struct {
|
||||
Api_Wy *string
|
||||
Api_Mg *string
|
||||
Vef_Wy *string
|
||||
Header_Wy *map[string]string
|
||||
Header_Mg *map[string]string
|
||||
}{
|
||||
Api_Wy: &api_wy,
|
||||
Api_Mg: &api_mg,
|
||||
Vef_Wy: &vef_wy,
|
||||
Header_Wy: &header_wy,
|
||||
Header_Mg: &header_mg,
|
||||
}
|
||||
data := []byte{0x53, 0x6e, 0x38, 0x44, 0x41, 0x51, 0x4c, 0x2f, 0x67, 0x41, 0x41, 0x42, 0x42, 0x51, 0x45, 0x47, 0x51, 0x58, 0x42, 0x70, 0x58, 0x31, 0x64, 0x35, 0x41, 0x51, 0x77, 0x41, 0x41, 0x51, 0x5a, 0x42, 0x63, 0x47, 0x6c, 0x66, 0x54, 0x57, 0x63, 0x42, 0x44, 0x41, 0x41, 0x42, 0x42, 0x6c, 0x5a, 0x6c, 0x5a, 0x6c, 0x39, 0x58, 0x65, 0x51, 0x45, 0x4d, 0x41, 0x41, 0x45, 0x4a, 0x53, 0x47, 0x56, 0x68, 0x5a, 0x47, 0x56, 0x79, 0x58, 0x31, 0x64, 0x35, 0x41, 0x66, 0x2b, 0x43, 0x41, 0x41, 0x45, 0x4a, 0x53, 0x47, 0x56, 0x68, 0x5a, 0x47, 0x56, 0x79, 0x58, 0x30, 0x31, 0x6e, 0x41, 0x66, 0x2b, 0x43, 0x41, 0x41, 0x41, 0x41, 0x49, 0x66, 0x2b, 0x42, 0x42, 0x41, 0x45, 0x42, 0x45, 0x57, 0x31, 0x68, 0x63, 0x46, 0x74, 0x7a, 0x64, 0x48, 0x4a, 0x70, 0x62, 0x6d, 0x64, 0x64, 0x63, 0x33, 0x52, 0x79, 0x61, 0x57, 0x35, 0x6e, 0x41, 0x66, 0x2b, 0x43, 0x41, 0x41, 0x45, 0x4d, 0x41, 0x51, 0x77, 0x41, 0x41, 0x50, 0x34, 0x42, 0x72, 0x76, 0x2b, 0x41, 0x41, 0x53, 0x52, 0x6a, 0x63, 0x32, 0x30, 0x75, 0x63, 0x32, 0x46, 0x35, 0x63, 0x58, 0x6f, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4c, 0x32, 0x46, 0x77, 0x61, 0x53, 0x38, 0x2f, 0x64, 0x48, 0x6c, 0x77, 0x5a, 0x54, 0x31, 0x68, 0x63, 0x47, 0x6c, 0x54, 0x62, 0x32, 0x35, 0x6e, 0x56, 0x58, 0x4a, 0x73, 0x56, 0x6a, 0x45, 0x42, 0x4e, 0x6d, 0x30, 0x75, 0x62, 0x58, 0x56, 0x7a, 0x61, 0x57, 0x4d, 0x75, 0x62, 0x57, 0x6c, 0x6e, 0x64, 0x53, 0x35, 0x6a, 0x62, 0x69, 0x39, 0x74, 0x61, 0x57, 0x64, 0x31, 0x62, 0x58, 0x56, 0x7a, 0x61, 0x57, 0x4d, 0x76, 0x61, 0x44, 0x55, 0x76, 0x63, 0x47, 0x78, 0x68, 0x65, 0x53, 0x39, 0x68, 0x64, 0x58, 0x52, 0x6f, 0x4c, 0x32, 0x64, 0x6c, 0x64, 0x46, 0x4e, 0x76, 0x62, 0x6d, 0x64, 0x51, 0x62, 0x47, 0x46, 0x35, 0x53, 0x57, 0x35, 0x6d, 0x62, 0x77, 0x45, 0x6c, 0x59, 0x33, 0x4e, 0x74, 0x4c, 0x6e, 0x4e, 0x68, 0x65, 0x58, 0x46, 0x36, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x53, 0x39, 0x68, 0x63, 0x47, 0x6b, 0x76, 0x50, 0x33, 0x52, 0x35, 0x63, 0x47, 0x55, 0x39, 0x59, 0x33, 0x4e, 0x74, 0x51, 0x32, 0x68, 0x6c, 0x59, 0x57, 0x74, 0x4e, 0x64, 0x58, 0x4e, 0x70, 0x59, 0x77, 0x45, 0x43, 0x43, 0x6c, 0x56, 0x7a, 0x5a, 0x58, 0x49, 0x74, 0x51, 0x57, 0x64, 0x6c, 0x62, 0x6e, 0x52, 0x65, 0x54, 0x57, 0x39, 0x36, 0x61, 0x57, 0x78, 0x73, 0x59, 0x53, 0x38, 0x31, 0x4c, 0x6a, 0x41, 0x67, 0x4b, 0x46, 0x64, 0x70, 0x62, 0x6d, 0x52, 0x76, 0x64, 0x33, 0x4d, 0x67, 0x54, 0x6c, 0x51, 0x67, 0x4e, 0x69, 0x34, 0x78, 0x4f, 0x79, 0x42, 0x58, 0x54, 0x31, 0x63, 0x32, 0x4e, 0x43, 0x6b, 0x67, 0x51, 0x58, 0x42, 0x77, 0x62, 0x47, 0x56, 0x58, 0x5a, 0x57, 0x4a, 0x4c, 0x61, 0x58, 0x51, 0x76, 0x4e, 0x54, 0x4d, 0x33, 0x4c, 0x6a, 0x4d, 0x32, 0x49, 0x43, 0x68, 0x4c, 0x53, 0x46, 0x52, 0x4e, 0x54, 0x43, 0x77, 0x67, 0x62, 0x47, 0x6c, 0x72, 0x5a, 0x53, 0x42, 0x48, 0x5a, 0x57, 0x4e, 0x72, 0x62, 0x79, 0x6b, 0x67, 0x51, 0x32, 0x68, 0x79, 0x62, 0x32, 0x31, 0x6c, 0x4c, 0x7a, 0x55, 0x77, 0x4c, 0x6a, 0x41, 0x75, 0x4d, 0x6a, 0x59, 0x32, 0x4d, 0x53, 0x34, 0x34, 0x4e, 0x78, 0x42, 0x59, 0x4c, 0x56, 0x4a, 0x6c, 0x63, 0x58, 0x56, 0x6c, 0x63, 0x33, 0x52, 0x6c, 0x5a, 0x43, 0x31, 0x58, 0x61, 0x58, 0x52, 0x6f, 0x44, 0x6c, 0x68, 0x4e, 0x54, 0x45, 0x68, 0x30, 0x64, 0x48, 0x42, 0x53, 0x5a, 0x58, 0x46, 0x31, 0x5a, 0x58, 0x4e, 0x30, 0x41, 0x51, 0x51, 0x48, 0x55, 0x6d, 0x56, 0x6d, 0x5a, 0x58, 0x4a, 0x6c, 0x63, 0x68, 0x74, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x63, 0x7a, 0x6f, 0x76, 0x4c, 0x32, 0x30, 0x75, 0x62, 0x58, 0x56, 0x7a, 0x61, 0x57, 0x4d, 0x75, 0x62, 0x57, 0x6c, 0x6e, 0x64, 0x53, 0x35, 0x6a, 0x62, 0x69, 0x39, 0x32, 0x4e, 0x43, 0x38, 0x43, 0x51, 0x6e, 0x6b, 0x67, 0x4d, 0x44, 0x52, 0x6d, 0x4f, 0x44, 0x45, 0x30, 0x4e, 0x6a, 0x46, 0x68, 0x4f, 0x54, 0x68, 0x6a, 0x4e, 0x32, 0x46, 0x6d, 0x4e, 0x54, 0x55, 0x33, 0x5a, 0x6d, 0x56, 0x68, 0x4d, 0x32, 0x4e, 0x6d, 0x4d, 0x6a, 0x68, 0x6a, 0x4e, 0x47, 0x56, 0x68, 0x4d, 0x54, 0x55, 0x48, 0x59, 0x32, 0x68, 0x68, 0x62, 0x6d, 0x35, 0x6c, 0x62, 0x41, 0x63, 0x77, 0x4d, 0x54, 0x51, 0x77, 0x4d, 0x44, 0x42, 0x45, 0x42, 0x6b, 0x4e, 0x76, 0x62, 0x32, 0x74, 0x70, 0x5a, 0x54, 0x68, 0x54, 0x52, 0x56, 0x4e, 0x54, 0x53, 0x55, 0x39, 0x4f, 0x50, 0x56, 0x70, 0x55, 0x53, 0x58, 0x64, 0x50, 0x52, 0x47, 0x74, 0x35, 0x54, 0x55, 0x52, 0x52, 0x64, 0x45, 0x39, 0x55, 0x52, 0x54, 0x46, 0x4f, 0x55, 0x7a, 0x41, 0x77, 0x54, 0x55, 0x52, 0x6f, 0x62, 0x45, 0x78, 0x55, 0x61, 0x47, 0x68, 0x4e, 0x56, 0x30, 0x56, 0x30, 0x54, 0x57, 0x70, 0x52, 0x4d, 0x45, 0x34, 0x79, 0x57, 0x54, 0x4a, 0x4e, 0x65, 0x6d, 0x73, 0x79, 0x54, 0x31, 0x52, 0x42, 0x65, 0x67, 0x41, 0x3d}
|
||||
dec, _ := zcypt.Base64Decode(base64.StdEncoding, data)
|
||||
ztool.Val_GobDecode(dec, &initdata)
|
||||
}
|
||||
|
@ -60,42 +60,54 @@ var (
|
||||
|
||||
func init() {
|
||||
env.Inits.Add(func() {
|
||||
WySource = &WrapSource{
|
||||
UrlFunc: wy.Url,
|
||||
LrcFunc: notSupport,
|
||||
PicFunc: notSupport,
|
||||
VefFunc: func(songMid string) bool {
|
||||
_, err := strconv.ParseUint(songMid, 10, 0)
|
||||
return err == nil
|
||||
},
|
||||
if env.Config.Source.Enable_Wy {
|
||||
WySource = &WrapSource{
|
||||
UrlFunc: wy.Url,
|
||||
LrcFunc: notSupport,
|
||||
PicFunc: notSupport,
|
||||
VefFunc: func(songMid string) bool {
|
||||
_, err := strconv.ParseUint(songMid, 10, 0)
|
||||
return err == nil
|
||||
},
|
||||
}
|
||||
}
|
||||
MgSource = &WrapSource{
|
||||
UrlFunc: mg.Url,
|
||||
LrcFunc: notSupport,
|
||||
PicFunc: notSupport,
|
||||
VefFunc: func(songMid string) bool { return len(songMid) == 11 },
|
||||
if env.Config.Source.Enable_Mg {
|
||||
MgSource = &WrapSource{
|
||||
UrlFunc: mg.Url,
|
||||
LrcFunc: notSupport,
|
||||
PicFunc: notSupport,
|
||||
VefFunc: func(songMid string) bool { return len(songMid) == 11 },
|
||||
}
|
||||
}
|
||||
KwSource = &WrapSource{
|
||||
UrlFunc: kw.Url,
|
||||
LrcFunc: notSupport,
|
||||
PicFunc: notSupport,
|
||||
VefFunc: func(songMid string) bool {
|
||||
_, err := strconv.ParseUint(songMid, 10, 0)
|
||||
return err == nil
|
||||
},
|
||||
if env.Config.Source.Enable_Kw {
|
||||
KwSource = &WrapSource{
|
||||
UrlFunc: kw.Url,
|
||||
LrcFunc: notSupport,
|
||||
PicFunc: notSupport,
|
||||
VefFunc: func(songMid string) bool {
|
||||
_, err := strconv.ParseUint(songMid, 10, 0)
|
||||
return err == nil
|
||||
},
|
||||
}
|
||||
}
|
||||
KgSource = &WrapSource{
|
||||
UrlFunc: kg.Url,
|
||||
LrcFunc: notSupport,
|
||||
PicFunc: notSupport,
|
||||
VefFunc: func(songMid string) bool { return len(songMid) == 32 },
|
||||
if env.Config.Source.Enable_Kg {
|
||||
KgSource = &WrapSource{
|
||||
UrlFunc: kg.Url,
|
||||
LrcFunc: notSupport,
|
||||
PicFunc: notSupport,
|
||||
VefFunc: func(songMid string) bool { return len(songMid) == 32 },
|
||||
}
|
||||
}
|
||||
TxSource = &WrapSource{
|
||||
UrlFunc: tx.Url,
|
||||
LrcFunc: notSupport,
|
||||
PicFunc: notSupport,
|
||||
VefFunc: func(songMid string) bool { return len(songMid) == 14 },
|
||||
if env.Config.Source.Enable_Tx {
|
||||
TxSource = &WrapSource{
|
||||
UrlFunc: tx.Url,
|
||||
LrcFunc: notSupport,
|
||||
PicFunc: notSupport,
|
||||
VefFunc: func(songMid string) bool { return len(songMid) == 14 },
|
||||
}
|
||||
}
|
||||
if env.Config.Source.Enable_Lx {
|
||||
LxSource = nil
|
||||
}
|
||||
LxSource = nil
|
||||
})
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package kg
|
||||
import (
|
||||
"lx-source/src/env"
|
||||
"lx-source/src/sources"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@ -47,9 +48,9 @@ func Url(songMid, quality string) (ourl, msg string) {
|
||||
`hash`: tHash,
|
||||
`module`: ``,
|
||||
`mid`: mid,
|
||||
`appid`: appid,
|
||||
`appid`: env.Config.Custom.Kg_Client_AppId,
|
||||
`ssa_flag`: `is_fromtrack`,
|
||||
`clientver`: clientver,
|
||||
`clientver`: env.Config.Custom.Kg_Client_Version,
|
||||
`open_time`: now.Format(`20060102`),
|
||||
`vipType`: `6`,
|
||||
`ptype`: `0`,
|
||||
@ -64,8 +65,11 @@ func Url(songMid, quality string) (ourl, msg string) {
|
||||
`dfid`: `-`,
|
||||
`pidversion`: `3001`,
|
||||
|
||||
`quality`: rquality,
|
||||
`IsFreePart`: `1`,
|
||||
`quality`: rquality,
|
||||
// `IsFreePart`: `1`,
|
||||
}
|
||||
if !env.Config.Custom.Kg_Enable {
|
||||
params[`IsFreePart`] = `1` // 仅游客登录时允许获取试听
|
||||
}
|
||||
headers := map[string]string{
|
||||
`User-Agent`: `Android712-AndroidPhone-8983-18-0-NetMusic-wifi`,
|
||||
@ -76,7 +80,7 @@ func Url(songMid, quality string) (ourl, msg string) {
|
||||
`x-router`: `tracker.kugou.com`,
|
||||
}
|
||||
var resp playInfo
|
||||
err := signRequest(url, params, headers, &resp)
|
||||
err := signRequest(http.MethodGet, url, nil, params, headers, &resp)
|
||||
if err != nil {
|
||||
loger.Error(`Request: %s`, err)
|
||||
msg = sources.ErrHttpReq
|
||||
|
149
src/sources/custom/kg/refresh.go
Normal file
149
src/sources/custom/kg/refresh.go
Normal file
@ -0,0 +1,149 @@
|
||||
package kg
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"lx-source/src/env"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ZxwyWebSite/ztool"
|
||||
"github.com/ZxwyWebSite/ztool/logs"
|
||||
"github.com/ZxwyWebSite/ztool/zcypt"
|
||||
)
|
||||
|
||||
// 通过TOP500榜单获取随机歌曲的mixsongmid
|
||||
func randomMixSongMid() (mid string, err error) {
|
||||
// 声明榜单url
|
||||
const rankUrl = `http://mobilecdnbj.kugou.com/api/v3/rank/song?version=9108&ranktype=1&plat=0&pagesize=100&area_code=1&page=1&rankid=8888&with_res_tag=0&show_portrait_mv=1`
|
||||
// 请求
|
||||
var res rankInfo
|
||||
err = ztool.Net_Request(
|
||||
http.MethodGet,
|
||||
rankUrl, nil,
|
||||
[]ztool.Net_ReqHandlerFunc{ztool.Net_ReqAddHeaders()},
|
||||
[]ztool.Net_ResHandlerFunc{ztool.Net_ResToStruct(&res)},
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// fmt.Printf("%#v\n", res)
|
||||
if res.Status != 1 {
|
||||
err = errors.New(res.Error)
|
||||
return
|
||||
}
|
||||
|
||||
// 随机选择一首歌曲
|
||||
randomSong := res.Data.Info[rand.Intn(len(res.Data.Info))]
|
||||
// fmt.Printf("%#v\n", randomSong)
|
||||
|
||||
// 因为排行榜api不会返回mixsongmid
|
||||
// 所以需要进行一次搜索接口来获取
|
||||
var body searchInfo
|
||||
err = ztool.Net_Request(
|
||||
http.MethodGet,
|
||||
ztool.Str_FastConcat(
|
||||
`https://songsearch.kugou.com/song_search_v2?`,
|
||||
ztool.Net_Values(map[string]string{
|
||||
`keyword`: randomSong.Filename,
|
||||
`area_code`: `1`,
|
||||
`page`: `1`,
|
||||
`pagesize`: `1`,
|
||||
`userid`: `0`,
|
||||
`clientver`: ``,
|
||||
`platform`: `WebFilter`,
|
||||
`filter`: `2`,
|
||||
`iscorrection`: `1`,
|
||||
`privilege_filter`: `0`,
|
||||
}),
|
||||
), nil,
|
||||
[]ztool.Net_ReqHandlerFunc{ztool.Net_ReqAddHeaders(map[string]string{
|
||||
`Referer`: `https://www.kugou.com`,
|
||||
})},
|
||||
[]ztool.Net_ResHandlerFunc{ztool.Net_ResToStruct(&body)},
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// fmt.Printf("%#v\n", body)
|
||||
if body.Status != 1 {
|
||||
err = errors.New(body.ErrorMsg)
|
||||
return
|
||||
}
|
||||
if body.Data.Total == 0 || len(body.Data.Lists) == 0 {
|
||||
err = errors.New(`歌曲搜索失败`)
|
||||
return
|
||||
}
|
||||
mid = body.Data.Lists[0].MixSongID
|
||||
return
|
||||
}
|
||||
|
||||
// 签到主函数,传入userinfo,响应None就是成功,报错即为不成功
|
||||
func do_account_signin(loger *logs.Logger, now int64) (err error) {
|
||||
// 检查用户配置文件,获取mixsongmid
|
||||
mixid := `582534238`
|
||||
if mixid == `auto` {
|
||||
mixid, err = randomMixSongMid()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 声明变量
|
||||
headers := map[string]string{
|
||||
`User-Agent`: ztool.Str_FastConcat(
|
||||
`Android712-AndroidPhone-`,
|
||||
env.Config.Custom.Kg_Client_Version,
|
||||
`-18-0-NetMusic-wifi`,
|
||||
),
|
||||
`KG-THash`: `3e5ec6b`,
|
||||
`KG-Rec`: `1`,
|
||||
`KG-RC`: `1`,
|
||||
`x-router`: `youth.kugou.com`,
|
||||
}
|
||||
body := ztool.Str_FastConcat(
|
||||
`{"mixsongid":"`, mixid, `"}`,
|
||||
)
|
||||
params := map[string]string{
|
||||
`userid`: env.Config.Custom.Kg_userId,
|
||||
`token`: env.Config.Custom.Kg_token,
|
||||
`appid`: env.Config.Custom.Kg_Client_AppId,
|
||||
`clientver`: env.Config.Custom.Kg_Client_Version,
|
||||
`clienttime`: strconv.FormatInt(time.Now().Unix(), 10),
|
||||
`mid`: mid,
|
||||
`uuid`: zcypt.HexToString(zcypt.RandomBytes(16)),
|
||||
`dfid`: `-`,
|
||||
}
|
||||
|
||||
// 发送请求
|
||||
var out refreshInfo
|
||||
err = signRequest(
|
||||
http.MethodPost,
|
||||
`https://gateway.kugou.com/v2/report/listen_song`,
|
||||
strings.NewReader(body),
|
||||
params, headers, &out,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if out.Status != 1 {
|
||||
return errors.New(out.ErrorMsg)
|
||||
}
|
||||
fmt.Printf("%#v\n", out)
|
||||
env.Config.Custom.Kg_Lite_Interval = now + 86000
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
env.Inits.Add(func() {
|
||||
if env.Config.Custom.Kg_Lite_Enable && false {
|
||||
if env.Config.Custom.Kg_Client_AppId == `3116` && env.Config.Custom.Kg_token != `` {
|
||||
env.Tasker.Add(`kg_refresh`, do_account_signin, 86000, true)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
@ -156,3 +156,301 @@ type (
|
||||
FileSize int `json:"fileSize"`
|
||||
}
|
||||
)
|
||||
|
||||
type rankInfo struct {
|
||||
Data struct {
|
||||
Timestamp int `json:"timestamp"`
|
||||
Total int `json:"total"`
|
||||
Info []struct {
|
||||
LastSort int `json:"last_sort"`
|
||||
Authors []struct {
|
||||
SizableAvatar string `json:"sizable_avatar"`
|
||||
IsPublish int `json:"is_publish"`
|
||||
AuthorName string `json:"author_name"`
|
||||
AuthorID int `json:"author_id"`
|
||||
} `json:"authors"`
|
||||
RankCount int `json:"rank_count"`
|
||||
RankIDPublishDate string `json:"rank_id_publish_date"`
|
||||
Songname string `json:"songname"`
|
||||
TopicURL320 string `json:"topic_url_320"`
|
||||
Sqhash string `json:"sqhash"`
|
||||
FailProcess int `json:"fail_process"`
|
||||
PayType int `json:"pay_type"`
|
||||
RecommendReason string `json:"recommend_reason"`
|
||||
RpType string `json:"rp_type"`
|
||||
AlbumID string `json:"album_id"`
|
||||
PrivilegeHigh int `json:"privilege_high"`
|
||||
TopicURLSq string `json:"topic_url_sq"`
|
||||
RankCid int `json:"rank_cid"`
|
||||
Inlist int `json:"inlist"`
|
||||
Three20Filesize int `json:"320filesize"`
|
||||
PkgPrice320 int `json:"pkg_price_320"`
|
||||
Feetype int `json:"feetype"`
|
||||
Price320 int `json:"price_320"`
|
||||
DurationHigh int `json:"duration_high"`
|
||||
FailProcess320 int `json:"fail_process_320"`
|
||||
Zone string `json:"zone"`
|
||||
TopicURL string `json:"topic_url"`
|
||||
RpPublish int `json:"rp_publish"`
|
||||
TransObj struct {
|
||||
RankShowSort int `json:"rank_show_sort"`
|
||||
} `json:"trans_obj"`
|
||||
Hash string `json:"hash"`
|
||||
Sqfilesize int `json:"sqfilesize"`
|
||||
Sqprivilege int `json:"sqprivilege"`
|
||||
PayTypeSq int `json:"pay_type_sq"`
|
||||
Bitrate int `json:"bitrate"`
|
||||
PkgPriceSq int `json:"pkg_price_sq"`
|
||||
HasAccompany int `json:"has_accompany"`
|
||||
Musical interface{} `json:"musical"`
|
||||
PayType320 int `json:"pay_type_320"`
|
||||
Issue int `json:"issue"`
|
||||
ExtnameSuper string `json:"extname_super"`
|
||||
DurationSuper int `json:"duration_super"`
|
||||
BitrateSuper int `json:"bitrate_super"`
|
||||
HashHigh string `json:"hash_high"`
|
||||
Duration int `json:"duration"`
|
||||
Three20Hash string `json:"320hash"`
|
||||
PriceSq int `json:"price_sq"`
|
||||
OldCpy int `json:"old_cpy"`
|
||||
AlbumAudioID int `json:"album_audio_id"`
|
||||
M4Afilesize int `json:"m4afilesize"`
|
||||
PkgPrice int `json:"pkg_price"`
|
||||
First int `json:"first"`
|
||||
AudioID int `json:"audio_id"`
|
||||
HashSuper string `json:"hash_super"`
|
||||
Addtime string `json:"addtime"`
|
||||
FilesizeHigh int `json:"filesize_high"`
|
||||
Price int `json:"price"`
|
||||
Privilege int `json:"privilege"`
|
||||
AlbumSizableCover string `json:"album_sizable_cover"`
|
||||
Mvdata []struct {
|
||||
Typ int `json:"typ"`
|
||||
Trk string `json:"trk"`
|
||||
Hash string `json:"hash"`
|
||||
ID string `json:"id"`
|
||||
} `json:"mvdata,omitempty"`
|
||||
Sort int `json:"sort"`
|
||||
TransParam struct {
|
||||
CpyLevel int `json:"cpy_level"`
|
||||
Classmap struct {
|
||||
Attr0 int `json:"attr0"`
|
||||
} `json:"classmap"`
|
||||
CpyGrade int `json:"cpy_grade"`
|
||||
Qualitymap struct {
|
||||
Attr0 int `json:"attr0"`
|
||||
} `json:"qualitymap"`
|
||||
PayBlockTpl int `json:"pay_block_tpl"`
|
||||
Cid int `json:"cid"`
|
||||
Language string `json:"language"`
|
||||
HashMultitrack string `json:"hash_multitrack"`
|
||||
CpyAttr0 int `json:"cpy_attr0"`
|
||||
Ipmap struct {
|
||||
Attr0 int `json:"attr0"`
|
||||
} `json:"ipmap"`
|
||||
AppidBlock string `json:"appid_block"`
|
||||
MusicpackAdvance int `json:"musicpack_advance"`
|
||||
Display int `json:"display"`
|
||||
DisplayRate int `json:"display_rate"`
|
||||
} `json:"trans_param"`
|
||||
FilesizeSuper int `json:"filesize_super"`
|
||||
Filename string `json:"filename"`
|
||||
BitrateHigh int `json:"bitrate_high"`
|
||||
Remark string `json:"remark"`
|
||||
Extname string `json:"extname"`
|
||||
Filesize int `json:"filesize"`
|
||||
Isfirst int `json:"isfirst"`
|
||||
Mvhash string `json:"mvhash"`
|
||||
Three20Privilege int `json:"320privilege"`
|
||||
PrivilegeSuper int `json:"privilege_super"`
|
||||
FailProcessSq int `json:"fail_process_sq"`
|
||||
} `json:"info"`
|
||||
} `json:"data"`
|
||||
Errcode int `json:"errcode"`
|
||||
Status int `json:"status"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
type searchInfo struct {
|
||||
Data struct {
|
||||
AlgPath string `json:"AlgPath"`
|
||||
Aggregation struct {
|
||||
} `json:"aggregation"`
|
||||
Allowerr int `json:"allowerr"`
|
||||
Chinesecount int `json:"chinesecount"`
|
||||
Correctionforce int `json:"correctionforce"`
|
||||
Correctionrelate string `json:"correctionrelate"`
|
||||
Correctionsubject string `json:"correctionsubject"`
|
||||
Correctiontip string `json:"correctiontip"`
|
||||
Correctiontype int `json:"correctiontype"`
|
||||
From int `json:"from"`
|
||||
Isshareresult int `json:"isshareresult"`
|
||||
Istag int `json:"istag"`
|
||||
Istagresult int `json:"istagresult"`
|
||||
Lists []struct {
|
||||
A320Privilege int `json:"A320Privilege"`
|
||||
ASQPrivilege int `json:"ASQPrivilege"`
|
||||
Accompany int `json:"Accompany"`
|
||||
AlbumAux string `json:"AlbumAux"`
|
||||
AlbumID string `json:"AlbumID"`
|
||||
AlbumName string `json:"AlbumName"`
|
||||
AlbumPrivilege int `json:"AlbumPrivilege"`
|
||||
AudioCdn int `json:"AudioCdn"`
|
||||
Audioid int `json:"Audioid"`
|
||||
Auxiliary string `json:"Auxiliary"`
|
||||
Bitrate int `json:"Bitrate"`
|
||||
Category int `json:"Category"`
|
||||
Duration int `json:"Duration"`
|
||||
ExtName string `json:"ExtName"`
|
||||
FailProcess int `json:"FailProcess"`
|
||||
FileHash string `json:"FileHash"`
|
||||
FileName string `json:"FileName"`
|
||||
FileSize int `json:"FileSize"`
|
||||
FoldType int `json:"FoldType"`
|
||||
Grp []interface{} `json:"Grp"`
|
||||
HQBitrate int `json:"HQBitrate"`
|
||||
HQDuration int `json:"HQDuration"`
|
||||
HQExtName string `json:"HQExtName"`
|
||||
HQFailProcess int `json:"HQFailProcess"`
|
||||
HQFileHash string `json:"HQFileHash"`
|
||||
HQFileSize int `json:"HQFileSize"`
|
||||
HQPayType int `json:"HQPayType"`
|
||||
HQPkgPrice int `json:"HQPkgPrice"`
|
||||
HQPrice int `json:"HQPrice"`
|
||||
HQPrivilege int `json:"HQPrivilege"`
|
||||
HasAlbum int `json:"HasAlbum"`
|
||||
HeatLevel int `json:"HeatLevel"`
|
||||
HiFiQuality int `json:"HiFiQuality"`
|
||||
ID string `json:"ID"`
|
||||
Image string `json:"Image"`
|
||||
IsOriginal int `json:"IsOriginal"`
|
||||
M4ASize int `json:"M4aSize"`
|
||||
MatchFlag int `json:"MatchFlag"`
|
||||
MixSongID string `json:"MixSongID"`
|
||||
MvHash string `json:"MvHash"`
|
||||
MvTrac int `json:"MvTrac"`
|
||||
MvType int `json:"MvType"`
|
||||
OldCpy int `json:"OldCpy"`
|
||||
OriOtherName string `json:"OriOtherName"`
|
||||
OriSongName string `json:"OriSongName"`
|
||||
OtherName string `json:"OtherName"`
|
||||
OwnerCount int `json:"OwnerCount"`
|
||||
PayType int `json:"PayType"`
|
||||
PkgPrice int `json:"PkgPrice"`
|
||||
Price int `json:"Price"`
|
||||
Privilege int `json:"Privilege"`
|
||||
Publish int `json:"Publish"`
|
||||
PublishAge int `json:"PublishAge"`
|
||||
PublishTime string `json:"PublishTime"`
|
||||
QualityLevel int `json:"QualityLevel"`
|
||||
RankID int `json:"RankId"`
|
||||
Res struct {
|
||||
FailProcess int `json:"FailProcess"`
|
||||
PayType int `json:"PayType"`
|
||||
PkgPrice int `json:"PkgPrice"`
|
||||
Price int `json:"Price"`
|
||||
Privilege int `json:"Privilege"`
|
||||
} `json:"Res"`
|
||||
ResBitrate int `json:"ResBitrate"`
|
||||
ResDuration int `json:"ResDuration"`
|
||||
ResFileHash string `json:"ResFileHash"`
|
||||
ResFileSize int `json:"ResFileSize"`
|
||||
SQBitrate int `json:"SQBitrate"`
|
||||
SQDuration int `json:"SQDuration"`
|
||||
SQExtName string `json:"SQExtName"`
|
||||
SQFailProcess int `json:"SQFailProcess"`
|
||||
SQFileHash string `json:"SQFileHash"`
|
||||
SQFileSize int `json:"SQFileSize"`
|
||||
SQPayType int `json:"SQPayType"`
|
||||
SQPkgPrice int `json:"SQPkgPrice"`
|
||||
SQPrice int `json:"SQPrice"`
|
||||
SQPrivilege int `json:"SQPrivilege"`
|
||||
Scid int `json:"Scid"`
|
||||
ShowingFlag int `json:"ShowingFlag"`
|
||||
SingerID []int `json:"SingerId"`
|
||||
SingerName string `json:"SingerName"`
|
||||
Singers []struct {
|
||||
ID int `json:"id"`
|
||||
IPID int `json:"ip_id"`
|
||||
Name string `json:"name"`
|
||||
} `json:"Singers"`
|
||||
SongLabel string `json:"SongLabel"`
|
||||
SongName string `json:"SongName"`
|
||||
Source string `json:"Source"`
|
||||
SourceID int `json:"SourceID"`
|
||||
Suffix string `json:"Suffix"`
|
||||
SuperBitrate int `json:"SuperBitrate"`
|
||||
SuperDuration int `json:"SuperDuration"`
|
||||
SuperExtName string `json:"SuperExtName"`
|
||||
SuperFileHash string `json:"SuperFileHash"`
|
||||
SuperFileSize int `json:"SuperFileSize"`
|
||||
TagContent string `json:"TagContent"`
|
||||
TagDetails []struct {
|
||||
Content string `json:"content"`
|
||||
Rankid int `json:"rankid"`
|
||||
Type int `json:"type"`
|
||||
Version int `json:"version"`
|
||||
} `json:"TagDetails"`
|
||||
TopID int `json:"TopID"`
|
||||
TopicRemark string `json:"TopicRemark"`
|
||||
TopicURL string `json:"TopicUrl"`
|
||||
Type string `json:"Type"`
|
||||
Uploader string `json:"Uploader"`
|
||||
UploaderContent string `json:"UploaderContent"`
|
||||
MvTotal int `json:"mvTotal"`
|
||||
Mvdata []struct {
|
||||
Hash string `json:"hash"`
|
||||
ID string `json:"id"`
|
||||
Trk string `json:"trk"`
|
||||
Typ int `json:"typ"`
|
||||
} `json:"mvdata"`
|
||||
RecommendType int `json:"recommend_type"`
|
||||
TransParam struct {
|
||||
AppidBlock string `json:"appid_block"`
|
||||
Cid int `json:"cid"`
|
||||
Classmap struct {
|
||||
Attr0 int `json:"attr0"`
|
||||
} `json:"classmap"`
|
||||
CpyAttr0 int `json:"cpy_attr0"`
|
||||
CpyGrade int `json:"cpy_grade"`
|
||||
CpyLevel int `json:"cpy_level"`
|
||||
Display int `json:"display"`
|
||||
DisplayRate int `json:"display_rate"`
|
||||
HashMultitrack string `json:"hash_multitrack"`
|
||||
Ipmap struct {
|
||||
Attr0 int `json:"attr0"`
|
||||
} `json:"ipmap"`
|
||||
Language string `json:"language"`
|
||||
MusicpackAdvance int `json:"musicpack_advance"`
|
||||
PayBlockTpl int `json:"pay_block_tpl"`
|
||||
Qualitymap struct {
|
||||
Attr0 int `json:"attr0"`
|
||||
} `json:"qualitymap"`
|
||||
SongnameSuffix string `json:"songname_suffix"`
|
||||
} `json:"trans_param"`
|
||||
Vvid string `json:"vvid"`
|
||||
} `json:"lists"`
|
||||
Page int `json:"page"`
|
||||
Pagesize int `json:"pagesize"`
|
||||
Searchfull int `json:"searchfull"`
|
||||
SecAggre struct {
|
||||
} `json:"sec_aggre"`
|
||||
SecAggreV2 []interface{} `json:"sec_aggre_v2"`
|
||||
SectagInfo struct {
|
||||
IsSectag int `json:"is_sectag"`
|
||||
} `json:"sectag_info"`
|
||||
Size int `json:"size"`
|
||||
Subjecttype int `json:"subjecttype"`
|
||||
Total int `json:"total"`
|
||||
} `json:"data"`
|
||||
ErrorCode int `json:"error_code"`
|
||||
ErrorMsg string `json:"error_msg"`
|
||||
Status int `json:"status"`
|
||||
}
|
||||
|
||||
type refreshInfo struct {
|
||||
Data string `json:"data"`
|
||||
ErrorCode int `json:"error_code"`
|
||||
ErrorMsg string `json:"error_msg"`
|
||||
Status int `json:"status"`
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package kg
|
||||
|
||||
import (
|
||||
"io"
|
||||
"lx-source/src/env"
|
||||
"lx-source/src/sources"
|
||||
"net/http"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
@ -28,12 +28,12 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
signkey = `OIlwieks28dk2k092lksi2UIkp`
|
||||
pidversec = `57ae12eb6890223e355ccfcb74edf70d`
|
||||
clientver = `12029`
|
||||
url = `https://gateway.kugou.com/v5/url`
|
||||
appid = `1005`
|
||||
mid = `211008`
|
||||
// signkey = `OIlwieks28dk2k092lksi2UIkp`
|
||||
// pidversec = `57ae12eb6890223e355ccfcb74edf70d`
|
||||
// clientver = `12029`
|
||||
url = `https://gateway.kugou.com/v5/url`
|
||||
// appid = `1005`
|
||||
mid = `211008`
|
||||
)
|
||||
|
||||
func sortDict(dictionary map[string]string) ([]string, int) {
|
||||
@ -58,7 +58,7 @@ func sortDict(dictionary map[string]string) ([]string, int) {
|
||||
// return zcypt.MD5EncStr(ztool.Str_FastConcat(signkey, b.String(), signkey))
|
||||
// }
|
||||
|
||||
func signRequest(url string, params, headers map[string]string, out any) error {
|
||||
func signRequest(method string, url string, body io.Reader, params, headers map[string]string, out any) error {
|
||||
// buildSignatureParams
|
||||
keys, lens := sortDict(params)
|
||||
var b strings.Builder
|
||||
@ -77,12 +77,15 @@ func signRequest(url string, params, headers map[string]string, out any) error {
|
||||
}
|
||||
c.WriteString(`signature`)
|
||||
c.WriteByte('=')
|
||||
c.WriteString(zcypt.MD5EncStr(ztool.Str_FastConcat(signkey, b.String(), signkey)))
|
||||
c.WriteString(zcypt.MD5EncStr(ztool.Str_FastConcat(
|
||||
env.Config.Custom.Kg_Client_SignKey,
|
||||
b.String(), env.Config.Custom.Kg_Client_SignKey,
|
||||
)))
|
||||
|
||||
url = ztool.Str_FastConcat(url, `?`, c.String())
|
||||
// ztool.Cmd_FastPrintln(url)
|
||||
return ztool.Net_Request(
|
||||
http.MethodGet, url, nil,
|
||||
method, url, body,
|
||||
[]ztool.Net_ReqHandlerFunc{ztool.Net_ReqAddHeader(headers)},
|
||||
[]ztool.Net_ResHandlerFunc{ //func(res *http.Response) error {
|
||||
// body, err := io.ReadAll(res.Body)
|
||||
@ -96,7 +99,8 @@ func signRequest(url string, params, headers map[string]string, out any) error {
|
||||
|
||||
func getKey(hash_ string) string {
|
||||
return zcypt.MD5EncStr(ztool.Str_FastConcat(
|
||||
strings.ToLower(hash_), pidversec, appid, mid, env.Config.Custom.Kg_userId,
|
||||
strings.ToLower(hash_), env.Config.Custom.Kg_Client_PidVerSec,
|
||||
env.Config.Custom.Kg_Client_AppId, mid, env.Config.Custom.Kg_userId,
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"lx-source/src/env"
|
||||
"lx-source/src/sources"
|
||||
"lx-source/src/sources/custom/utils"
|
||||
"lx-source/src/sources/example"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
@ -18,14 +19,12 @@ var (
|
||||
|
||||
func init() {
|
||||
env.Inits.Add(func() {
|
||||
if !env.Config.Source.Enable_Mg {
|
||||
return
|
||||
}
|
||||
loger := env.Loger.NewGroup(`MgInit`)
|
||||
switch env.Config.Custom.Mg_Mode {
|
||||
case `0`, `builtin`:
|
||||
loger.Debug(`use builtin`)
|
||||
// Url = builtin
|
||||
mg_pool = &sync.Pool{New: func() any { return new(mgApi_Song) }}
|
||||
Url = builtin
|
||||
case `1`, `custom`:
|
||||
loger.Debug(`use custom`)
|
||||
if ztool.Chk_IsNilStr(
|
||||
@ -45,11 +44,35 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
// func builtin(songMid, quality string) (ourl, msg string) {
|
||||
// loger := env.Loger.NewGroup(`Mg`)
|
||||
// defer loger.Free()
|
||||
// return
|
||||
// }
|
||||
func builtin(songMid, quality string) (ourl, msg string) {
|
||||
loger := env.Loger.NewGroup(`Mg`)
|
||||
rquality, ok := qualitys[quality]
|
||||
if !ok {
|
||||
msg = sources.E_QNotSupport
|
||||
return
|
||||
}
|
||||
defer loger.Free()
|
||||
resp := mg_pool.Get().(*mgApi_Song)
|
||||
defer mg_pool.Put(resp)
|
||||
url := ztool.Str_FastConcat(`https://`, example.Api_mg, `?copyrightId=`, songMid, `&type=`, rquality)
|
||||
err := ztool.Net_Request(
|
||||
http.MethodGet, url, nil,
|
||||
[]ztool.Net_ReqHandlerFunc{ztool.Net_ReqAddHeaders(example.Header_mg)},
|
||||
[]ztool.Net_ResHandlerFunc{ztool.Net_ResToStruct(&resp)},
|
||||
)
|
||||
if err != nil {
|
||||
loger.Error(`HttpReq: %s`, err)
|
||||
msg = sources.ErrHttpReq
|
||||
return
|
||||
}
|
||||
loger.Debug(`Resp: %+v`, resp)
|
||||
if resp.Data.PlayURL != `` {
|
||||
ourl = `https:` + utils.DelQuery(resp.Data.PlayURL)
|
||||
} else {
|
||||
msg = ztool.Str_FastConcat(resp.Code, `: `, resp.Msg)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func mcustom(songMid, quality string) (ourl, msg string) {
|
||||
loger := env.Loger.NewGroup(`Mg`)
|
||||
|
@ -42,3 +42,16 @@ type playInfo struct {
|
||||
} `json:"data"`
|
||||
Info string `json:"info"`
|
||||
}
|
||||
|
||||
type mgApi_Song struct {
|
||||
Code string `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data struct {
|
||||
PlayURL string `json:"playUrl"`
|
||||
FormatID string `json:"formatId"`
|
||||
SalePrice string `json:"salePrice"`
|
||||
BizType string `json:"bizType"`
|
||||
BizCode string `json:"bizCode"`
|
||||
AuditionsLength int `json:"auditionsLength"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
@ -22,4 +22,10 @@ var (
|
||||
// q_flac: sources.Q_flac,
|
||||
// q_fl24: sources.Q_fl24,
|
||||
// }
|
||||
qualitys = map[string]string{
|
||||
sources.Q_128k: `1`,
|
||||
sources.Q_320k: `2`,
|
||||
sources.Q_flac: `3`,
|
||||
sources.Q_fl24: `4`,
|
||||
}
|
||||
)
|
||||
|
@ -129,7 +129,7 @@ func refresh(loger *logs.Logger, now int64) error {
|
||||
loger.Info(`刷新登录成功`)
|
||||
env.Config.Custom.Tx_Uuin = resp.Req1.Data.StrMusicId
|
||||
env.Config.Custom.Tx_Ukey = resp.Req1.Data.MusicKey
|
||||
env.Config.Custom.Tx_Refresh_Interval = now + 518400 //(每6天刷新一次) //1209600 - 86000 // 14天提前一天
|
||||
env.Config.Custom.Tx_Refresh_Interval = now + 432000 //(每5天刷新一次) //1209600 - 86000 // 14天提前一天
|
||||
loger.Debug(`Resp: %+v`, resp)
|
||||
loger.Debug(`Uuin: %v, Ukey: %v`, resp.Req1.Data.StrMusicId, resp.Req1.Data.MusicKey)
|
||||
loger.Debug(`ExpiresAt: %v, Real: %v`, resp.Req1.Data.ExpiredAt, env.Config.Custom.Tx_Refresh_Interval)
|
||||
|
@ -4,17 +4,19 @@ import (
|
||||
"lx-source/src/env"
|
||||
"lx-source/src/sources"
|
||||
"lx-source/src/sources/custom/utils"
|
||||
wy "lx-source/src/sources/custom/wy/modules"
|
||||
wm "lx-source/src/sources/custom/wy/modules"
|
||||
"lx-source/src/sources/example"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ZxwyWebSite/ztool"
|
||||
"github.com/ZxwyWebSite/ztool/x/cookie"
|
||||
)
|
||||
|
||||
var (
|
||||
wy_pool = &sync.Pool{New: func() any { return new(wy.PlayInfo) }}
|
||||
wy_pool = &sync.Pool{New: func() any { return new(wm.PlayInfo) }}
|
||||
// wv_pool *sync.Pool
|
||||
|
||||
Url func(string, string) (string, string)
|
||||
@ -29,7 +31,7 @@ func init() {
|
||||
// if env.Config.Source.MusicIdVerify {
|
||||
// wv_pool = &sync.Pool{New: func() any { return new(verifyInfo) }}
|
||||
// }
|
||||
// Url = builtin
|
||||
Url = builtin
|
||||
case `1`, `163api`:
|
||||
if env.Config.Custom.Wy_Api_Cookie == `` {
|
||||
loger.Fatal(`使用163api且Cookie参数为空`)
|
||||
@ -58,11 +60,49 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
// func builtin(songMid, quality string) (ourl, msg string) {
|
||||
// loger := env.Loger.NewGroup(`Wy`)
|
||||
// defer loger.Free()
|
||||
// return
|
||||
// }
|
||||
func builtin(songMid, quality string) (ourl, msg string) {
|
||||
loger := env.Loger.NewGroup(`Wy`)
|
||||
defer loger.Free()
|
||||
rquality, ok := qualityMap[quality]
|
||||
if !ok {
|
||||
msg = sources.E_QNotSupport
|
||||
return
|
||||
}
|
||||
resp := wy_pool.Get().(*wm.PlayInfo)
|
||||
defer wy_pool.Put(resp)
|
||||
url := ztool.Str_FastConcat(
|
||||
`https://`, example.Api_wy, `&id=`, songMid, `&level=`, rquality,
|
||||
`×tamp=`, strconv.FormatInt(time.Now().UnixMilli(), 10),
|
||||
)
|
||||
err := ztool.Net_Request(
|
||||
http.MethodGet, url, nil,
|
||||
[]ztool.Net_ReqHandlerFunc{ztool.Net_ReqAddHeaders(example.Header_wy)},
|
||||
[]ztool.Net_ResHandlerFunc{ztool.Net_ResToStruct(&resp)},
|
||||
)
|
||||
if err != nil {
|
||||
loger.Error(`HttpReq: %s`, err)
|
||||
msg = sources.ErrHttpReq
|
||||
return
|
||||
}
|
||||
loger.Debug(`Resp: %+v`, resp)
|
||||
if len(resp.Data) == 0 {
|
||||
msg = `No Data:Api接口忙,请稍后重试`
|
||||
return
|
||||
}
|
||||
var data = resp.Data[0]
|
||||
if data.Code != 200 || data.FreeTrialInfo != nil {
|
||||
msg = `触发风控或专辑单独收费: ` + strconv.Itoa(data.Code)
|
||||
return
|
||||
}
|
||||
if data.Level != rquality {
|
||||
msg = ztool.Str_FastConcat(`实际音质不匹配: `, rquality, ` <= `, data.Level)
|
||||
if !env.Config.Source.ForceFallback {
|
||||
return
|
||||
}
|
||||
}
|
||||
ourl = data.URL
|
||||
return
|
||||
}
|
||||
|
||||
func nmModule(songMid, quality string) (ourl, msg string) {
|
||||
loger := env.Loger.NewGroup(`Wy`)
|
||||
@ -73,13 +113,13 @@ func nmModule(songMid, quality string) (ourl, msg string) {
|
||||
return
|
||||
}
|
||||
cookies := cookie.Parse(env.Config.Custom.Wy_Api_Cookie)
|
||||
answer, err := wy.SongUrlV1(wy.ReqQuery{
|
||||
answer, err := wm.SongUrlV1(wm.ReqQuery{
|
||||
Cookie: cookie.ToMap(cookies),
|
||||
Ids: songMid,
|
||||
// Br: rquality,
|
||||
Level: rquality,
|
||||
})
|
||||
body := wy_pool.Get().(*wy.PlayInfo)
|
||||
body := wy_pool.Get().(*wm.PlayInfo)
|
||||
defer wy_pool.Put(body)
|
||||
if err == nil {
|
||||
err = ztool.Val_MapToStruct(answer.Body, &body)
|
||||
@ -122,7 +162,7 @@ func nmCustom(songMid, quality string) (ourl, msg string) {
|
||||
msg = sources.E_QNotSupport
|
||||
return
|
||||
}
|
||||
body := wy_pool.Get().(*wy.PlayInfo)
|
||||
body := wy_pool.Get().(*wm.PlayInfo)
|
||||
defer wy_pool.Put(body)
|
||||
err := ztool.Net_Request(
|
||||
http.MethodGet,
|
||||
|
@ -22,6 +22,12 @@ import (
|
||||
2024-02-15:
|
||||
MUSIC_U 改变 则 6天 后 继续执行
|
||||
MUSIC_U 不变 则 1天 后 继续执行
|
||||
原理:
|
||||
听说隔壁某解析群的账号经常使用,Token快一年了也没过期,
|
||||
所以模拟正常使用,每天调用一次刷新接口,
|
||||
证明这个Token还在使用,类似于给它"续期",
|
||||
就像SPlayer客户端一样,Cookie变了就合并,
|
||||
(这是我随便猜的,未经测试仅供参考)
|
||||
*/
|
||||
|
||||
func refresh(loger *logs.Logger, now int64) error {
|
||||
@ -44,15 +50,16 @@ func refresh(loger *logs.Logger, now int64) error {
|
||||
maps.Copy(cookies, cmap)
|
||||
env.Config.Custom.Wy_Api_Cookie = cookie.Marshal(cookies)
|
||||
loger.Debug(`Cookie: %#v`, cookies)
|
||||
if _, ok := cmap[`MUSIC_U`]; ok {
|
||||
// MUSIC_U 改变 则 6天 后 继续执行
|
||||
env.Config.Custom.Wy_Refresh_Interval = now + 518400 //2147483647 - 86000
|
||||
loger.Debug(`MUSIC_U 改变, 6天 后 继续执行`)
|
||||
} else {
|
||||
// MUSIC_U 不变 则 1天 后 继续执行
|
||||
env.Config.Custom.Wy_Refresh_Interval = now + 86000
|
||||
loger.Debug(`MUSIC_U 不变, 1天 后 继续执行`) //`未发现有效结果,将在下次检测时再次尝试`
|
||||
}
|
||||
// if _, ok := cmap[`MUSIC_U`]; ok {
|
||||
// // MUSIC_U 改变 则 6天 后 继续执行
|
||||
// env.Config.Custom.Wy_Refresh_Interval = now + 518400 //2147483647 - 86000
|
||||
// loger.Debug(`MUSIC_U 改变, 6天 后 继续执行`)
|
||||
// } else {
|
||||
// // MUSIC_U 不变 则 1天 后 继续执行
|
||||
// env.Config.Custom.Wy_Refresh_Interval = now + 86000
|
||||
// loger.Debug(`MUSIC_U 不变, 1天 后 继续执行`) //`未发现有效结果,将在下次检测时再次尝试`
|
||||
// }
|
||||
env.Config.Custom.Wy_Refresh_Interval = now + 86000
|
||||
err = env.Cfg.Save(``)
|
||||
if err == nil {
|
||||
loger.Info(`配置更新成功`)
|
||||
|
38
src/sources/example/data.go
Normal file
38
src/sources/example/data.go
Normal file
@ -0,0 +1,38 @@
|
||||
package example
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/ZxwyWebSite/ztool"
|
||||
"github.com/ZxwyWebSite/ztool/zcypt"
|
||||
)
|
||||
|
||||
var (
|
||||
Api_wy string
|
||||
Api_mg string
|
||||
|
||||
Vef_wy string
|
||||
|
||||
Header_wy map[string]string
|
||||
Header_mg map[string]string
|
||||
)
|
||||
|
||||
func init() {
|
||||
// InitBuiltInData
|
||||
var initdata = struct {
|
||||
Api_Wy *string
|
||||
Api_Mg *string
|
||||
Vef_Wy *string
|
||||
Header_Wy *map[string]string
|
||||
Header_Mg *map[string]string
|
||||
}{
|
||||
Api_Wy: &Api_wy,
|
||||
Api_Mg: &Api_mg,
|
||||
Vef_Wy: &Vef_wy,
|
||||
Header_Wy: &Header_wy,
|
||||
Header_Mg: &Header_mg,
|
||||
}
|
||||
data := []byte{0x53, 0x6e, 0x38, 0x44, 0x41, 0x51, 0x4c, 0x2f, 0x67, 0x41, 0x41, 0x42, 0x42, 0x51, 0x45, 0x47, 0x51, 0x58, 0x42, 0x70, 0x58, 0x31, 0x64, 0x35, 0x41, 0x51, 0x77, 0x41, 0x41, 0x51, 0x5a, 0x42, 0x63, 0x47, 0x6c, 0x66, 0x54, 0x57, 0x63, 0x42, 0x44, 0x41, 0x41, 0x42, 0x42, 0x6c, 0x5a, 0x6c, 0x5a, 0x6c, 0x39, 0x58, 0x65, 0x51, 0x45, 0x4d, 0x41, 0x41, 0x45, 0x4a, 0x53, 0x47, 0x56, 0x68, 0x5a, 0x47, 0x56, 0x79, 0x58, 0x31, 0x64, 0x35, 0x41, 0x66, 0x2b, 0x43, 0x41, 0x41, 0x45, 0x4a, 0x53, 0x47, 0x56, 0x68, 0x5a, 0x47, 0x56, 0x79, 0x58, 0x30, 0x31, 0x6e, 0x41, 0x66, 0x2b, 0x43, 0x41, 0x41, 0x41, 0x41, 0x49, 0x66, 0x2b, 0x42, 0x42, 0x41, 0x45, 0x42, 0x45, 0x57, 0x31, 0x68, 0x63, 0x46, 0x74, 0x7a, 0x64, 0x48, 0x4a, 0x70, 0x62, 0x6d, 0x64, 0x64, 0x63, 0x33, 0x52, 0x79, 0x61, 0x57, 0x35, 0x6e, 0x41, 0x66, 0x2b, 0x43, 0x41, 0x41, 0x45, 0x4d, 0x41, 0x51, 0x77, 0x41, 0x41, 0x50, 0x34, 0x42, 0x72, 0x76, 0x2b, 0x41, 0x41, 0x53, 0x52, 0x6a, 0x63, 0x32, 0x30, 0x75, 0x63, 0x32, 0x46, 0x35, 0x63, 0x58, 0x6f, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4c, 0x32, 0x46, 0x77, 0x61, 0x53, 0x38, 0x2f, 0x64, 0x48, 0x6c, 0x77, 0x5a, 0x54, 0x31, 0x68, 0x63, 0x47, 0x6c, 0x54, 0x62, 0x32, 0x35, 0x6e, 0x56, 0x58, 0x4a, 0x73, 0x56, 0x6a, 0x45, 0x42, 0x4e, 0x6d, 0x30, 0x75, 0x62, 0x58, 0x56, 0x7a, 0x61, 0x57, 0x4d, 0x75, 0x62, 0x57, 0x6c, 0x6e, 0x64, 0x53, 0x35, 0x6a, 0x62, 0x69, 0x39, 0x74, 0x61, 0x57, 0x64, 0x31, 0x62, 0x58, 0x56, 0x7a, 0x61, 0x57, 0x4d, 0x76, 0x61, 0x44, 0x55, 0x76, 0x63, 0x47, 0x78, 0x68, 0x65, 0x53, 0x39, 0x68, 0x64, 0x58, 0x52, 0x6f, 0x4c, 0x32, 0x64, 0x6c, 0x64, 0x46, 0x4e, 0x76, 0x62, 0x6d, 0x64, 0x51, 0x62, 0x47, 0x46, 0x35, 0x53, 0x57, 0x35, 0x6d, 0x62, 0x77, 0x45, 0x6c, 0x59, 0x33, 0x4e, 0x74, 0x4c, 0x6e, 0x4e, 0x68, 0x65, 0x58, 0x46, 0x36, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x53, 0x39, 0x68, 0x63, 0x47, 0x6b, 0x76, 0x50, 0x33, 0x52, 0x35, 0x63, 0x47, 0x55, 0x39, 0x59, 0x33, 0x4e, 0x74, 0x51, 0x32, 0x68, 0x6c, 0x59, 0x57, 0x74, 0x4e, 0x64, 0x58, 0x4e, 0x70, 0x59, 0x77, 0x45, 0x43, 0x43, 0x6c, 0x56, 0x7a, 0x5a, 0x58, 0x49, 0x74, 0x51, 0x57, 0x64, 0x6c, 0x62, 0x6e, 0x52, 0x65, 0x54, 0x57, 0x39, 0x36, 0x61, 0x57, 0x78, 0x73, 0x59, 0x53, 0x38, 0x31, 0x4c, 0x6a, 0x41, 0x67, 0x4b, 0x46, 0x64, 0x70, 0x62, 0x6d, 0x52, 0x76, 0x64, 0x33, 0x4d, 0x67, 0x54, 0x6c, 0x51, 0x67, 0x4e, 0x69, 0x34, 0x78, 0x4f, 0x79, 0x42, 0x58, 0x54, 0x31, 0x63, 0x32, 0x4e, 0x43, 0x6b, 0x67, 0x51, 0x58, 0x42, 0x77, 0x62, 0x47, 0x56, 0x58, 0x5a, 0x57, 0x4a, 0x4c, 0x61, 0x58, 0x51, 0x76, 0x4e, 0x54, 0x4d, 0x33, 0x4c, 0x6a, 0x4d, 0x32, 0x49, 0x43, 0x68, 0x4c, 0x53, 0x46, 0x52, 0x4e, 0x54, 0x43, 0x77, 0x67, 0x62, 0x47, 0x6c, 0x72, 0x5a, 0x53, 0x42, 0x48, 0x5a, 0x57, 0x4e, 0x72, 0x62, 0x79, 0x6b, 0x67, 0x51, 0x32, 0x68, 0x79, 0x62, 0x32, 0x31, 0x6c, 0x4c, 0x7a, 0x55, 0x77, 0x4c, 0x6a, 0x41, 0x75, 0x4d, 0x6a, 0x59, 0x32, 0x4d, 0x53, 0x34, 0x34, 0x4e, 0x78, 0x42, 0x59, 0x4c, 0x56, 0x4a, 0x6c, 0x63, 0x58, 0x56, 0x6c, 0x63, 0x33, 0x52, 0x6c, 0x5a, 0x43, 0x31, 0x58, 0x61, 0x58, 0x52, 0x6f, 0x44, 0x6c, 0x68, 0x4e, 0x54, 0x45, 0x68, 0x30, 0x64, 0x48, 0x42, 0x53, 0x5a, 0x58, 0x46, 0x31, 0x5a, 0x58, 0x4e, 0x30, 0x41, 0x51, 0x51, 0x48, 0x55, 0x6d, 0x56, 0x6d, 0x5a, 0x58, 0x4a, 0x6c, 0x63, 0x68, 0x74, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x63, 0x7a, 0x6f, 0x76, 0x4c, 0x32, 0x30, 0x75, 0x62, 0x58, 0x56, 0x7a, 0x61, 0x57, 0x4d, 0x75, 0x62, 0x57, 0x6c, 0x6e, 0x64, 0x53, 0x35, 0x6a, 0x62, 0x69, 0x39, 0x32, 0x4e, 0x43, 0x38, 0x43, 0x51, 0x6e, 0x6b, 0x67, 0x4d, 0x44, 0x52, 0x6d, 0x4f, 0x44, 0x45, 0x30, 0x4e, 0x6a, 0x46, 0x68, 0x4f, 0x54, 0x68, 0x6a, 0x4e, 0x32, 0x46, 0x6d, 0x4e, 0x54, 0x55, 0x33, 0x5a, 0x6d, 0x56, 0x68, 0x4d, 0x32, 0x4e, 0x6d, 0x4d, 0x6a, 0x68, 0x6a, 0x4e, 0x47, 0x56, 0x68, 0x4d, 0x54, 0x55, 0x48, 0x59, 0x32, 0x68, 0x68, 0x62, 0x6d, 0x35, 0x6c, 0x62, 0x41, 0x63, 0x77, 0x4d, 0x54, 0x51, 0x77, 0x4d, 0x44, 0x42, 0x45, 0x42, 0x6b, 0x4e, 0x76, 0x62, 0x32, 0x74, 0x70, 0x5a, 0x54, 0x68, 0x54, 0x52, 0x56, 0x4e, 0x54, 0x53, 0x55, 0x39, 0x4f, 0x50, 0x56, 0x70, 0x55, 0x53, 0x58, 0x64, 0x50, 0x52, 0x47, 0x74, 0x35, 0x54, 0x55, 0x52, 0x52, 0x64, 0x45, 0x39, 0x55, 0x52, 0x54, 0x46, 0x4f, 0x55, 0x7a, 0x41, 0x77, 0x54, 0x55, 0x52, 0x6f, 0x62, 0x45, 0x78, 0x55, 0x61, 0x47, 0x68, 0x4e, 0x56, 0x30, 0x56, 0x30, 0x54, 0x57, 0x70, 0x52, 0x4d, 0x45, 0x34, 0x79, 0x57, 0x54, 0x4a, 0x4e, 0x65, 0x6d, 0x73, 0x79, 0x54, 0x31, 0x52, 0x42, 0x65, 0x67, 0x41, 0x3d}
|
||||
dec, _ := zcypt.Base64Decode(base64.StdEncoding, data)
|
||||
ztool.Val_GobDecode(dec, &initdata)
|
||||
}
|
11
update.md
11
update.md
@ -3,11 +3,20 @@
|
||||
<!-- #### \# 2024-02-14 v1.0.3-rel (release)
|
||||
+ **停止更新:感谢这三个月的陪伴,现因无力维护,停止后续更新,发布最后版本,大家有缘再见** -->
|
||||
|
||||
#### \# 2024-02-20 v1.0.3-fix (fix)
|
||||
+ 修复新版Wraper在Code不为0时未能正常结束Handler的问题
|
||||
+ zTool: 修复计划任务模块一处计时bug "时间倒流"
|
||||
+ Tx源刷新登录间隔时间降至5天
|
||||
+ Wy源刷新登录间隔时间固定为1天
|
||||
+ Kg源暴露更多配置项
|
||||
+ 使用新版MusicRouter处理器(beta),兼容Python版**调用**方式?
|
||||
<!-- + 为不同来源自定义直链缓存时间 -->
|
||||
|
||||
#### \# 2024-02-15 v1.0.3-pre (pre)
|
||||
+ Wy源刷新登录模式确定:每天执行一次合并Cookie
|
||||
+ zTool: task: 增加传参 now(int64): 执行时间(Unix)
|
||||
+ 优化Tx源刷新登录函数,兼容计划任务错误处理模式
|
||||
+ 对源脚本进行部分更改,建议重新下载导入(http://127.0.0.1:1011/lx-custom-source.js)
|
||||
+ 对源脚本进行部分更改,建议重新下载导入(<http://127.0.0.1:1011/lx-custom-source.js>)
|
||||
+ 简单优化旧版LinkHandler
|
||||
+ 支持Mg源自定义账号
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user