2024-06-14 v1.0.3.0614

This commit is contained in:
ZxwyWebSite 2024-06-15 01:03:38 +08:00
parent 76e7f5a1b6
commit 55e7c6227e
9 changed files with 431 additions and 89 deletions

269
action.go
View File

@ -12,6 +12,7 @@ import (
"path/filepath"
"runtime"
"strings"
"unicode"
)
const (
@ -23,7 +24,10 @@ const (
args_home = `/home/runner` // 用户目录
)
var workDir string
var (
workDir string
homeDir string
)
func init() {
if runtime.GOOS != `linux` {
@ -32,21 +36,35 @@ func init() {
}
workDir, _ = os.Getwd()
fmt.Println(`运行目录:`, workDir)
homeDir = os.Getenv(`HOME`)
if homeDir == `` {
homeDir = args_home
}
fmt.Println(`用户目录:`, homeDir)
}
type (
// 架构参数 [v2]
list_vers map[string]struct {
Tags string
}
list_arch map[string]struct {
AR string
CC string
CXX string
Vers list_vers
// CGO参数 [nil]
list_cgos struct {
AR string
CC string
CXX string
}
// 架构列表 [amd64]
list_arch map[string]struct {
Cgos *list_cgos
Vers list_vers
Venv string // 覆盖架构参数名 'mipsle'->'GOMIPS'
}
// 目标系统 [linux]
list_goos map[string]struct {
Arch list_arch
}
// 编译环境 [go1.20.14]
list_conf map[string]struct {
Args []string
GoOS list_goos
@ -66,9 +84,24 @@ type param struct {
GoIns string // 指令 GOAMD64=v2
Args []string // 参数 ldflags
Tag string // 标志 go_json
AR string
CC string
CXX string
Cgos *list_cgos
Venv string
}
// 获取相对用户目录
func home(str string) string {
return homeDir + `/` + str
}
// 检测环境是否存在
func chkenv(s ...string) (err error) {
for _, f := range s {
if _, e := exec.LookPath(f); e != nil && !errors.Is(e, exec.ErrDot) {
err = fmt.Errorf(`未找到指定环境: %s`, e)
break
}
}
return
}
func main() {
@ -79,9 +112,11 @@ func main() {
`linux`: {
Arch: list_arch{
`amd64`: {
AR: `x86_64-linux-gnu-ar`,
CC: `x86_64-linux-gnu-gcc`,
CXX: `x86_64-linux-gnu-g++`,
Cgos: &list_cgos{
AR: `x86_64-linux-gnu-ar`,
CC: `x86_64-linux-gnu-gcc`,
CXX: `x86_64-linux-gnu-g++`,
},
Vers: list_vers{
`v1`: {
Tags: `go_json`,
@ -98,9 +133,11 @@ func main() {
},
},
`arm`: {
AR: `arm-linux-gnueabihf-gcc-ar`,
CC: `arm-linux-gnueabihf-gcc`,
CXX: `arm-linux-gnueabihf-cpp`,
Cgos: &list_cgos{
AR: `arm-linux-gnueabihf-gcc-ar`,
CC: `arm-linux-gnueabihf-gcc`,
CXX: `arm-linux-gnueabihf-cpp`,
},
Vers: list_vers{
`5`: {
Tags: `go_json`,
@ -114,23 +151,70 @@ func main() {
},
},
`arm64`: {
AR: `aarch64-linux-gnu-gcc-ar`,
CC: `aarch64-linux-gnu-gcc`,
CXX: `aarch64-linux-gnu-cpp`,
Cgos: &list_cgos{
AR: `aarch64-linux-gnu-gcc-ar`,
CC: `aarch64-linux-gnu-gcc`,
CXX: `aarch64-linux-gnu-cpp`,
},
Vers: list_vers{
``: {
Tags: `go_json`,
},
},
},
// 针对部分OpenWrt路由器系统 暂不支持开启CGO
`mips`: {
Vers: list_vers{
`hardfloat`: {
Tags: `go_json`,
},
`softfloat`: {
Tags: `go_json`,
},
},
},
`mipsle`: {
Vers: list_vers{
`hardfloat`: {
Tags: `go_json`,
},
`softfloat`: {
Tags: `go_json`,
},
},
Venv: `MIPS`,
},
`mips64`: {
Vers: list_vers{
`hardfloat`: {
Tags: `go_json`,
},
`softfloat`: {
Tags: `go_json`,
},
},
},
`mips64le`: {
Vers: list_vers{
`hardfloat`: {
Tags: `go_json`,
},
`softfloat`: {
Tags: `go_json`,
},
},
Venv: `MIPS64`,
},
},
},
`windows`: {
Arch: list_arch{
`amd64`: {
AR: `x86_64-w64-mingw32-ar`,
CC: `x86_64-w64-mingw32-gcc`,
CXX: `x86_64-w64-mingw32-cpp`,
Cgos: &list_cgos{
AR: `x86_64-w64-mingw32-ar`,
CC: `x86_64-w64-mingw32-gcc`,
CXX: `x86_64-w64-mingw32-cpp`,
},
Vers: list_vers{
`v2`: {
Tags: `go_json`,
@ -148,9 +232,11 @@ func main() {
`android`: {
Arch: list_arch{
`amd64`: {
AR: args_home + `/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar`,
CC: args_home + `/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang`,
CXX: args_home + `/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang++`,
Cgos: &list_cgos{
AR: home(`android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar`),
CC: home(`android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang`),
CXX: home(`android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang++`),
},
Vers: list_vers{
``: {
Tags: `go_json`,
@ -158,9 +244,11 @@ func main() {
},
},
`arm64`: {
AR: args_home + `/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar`,
CC: args_home + `/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang`,
CXX: args_home + `/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang++`,
Cgos: &list_cgos{
AR: home(`android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar`),
CC: home(`android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang`),
CXX: home(`android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang++`),
},
Vers: list_vers{
``: {
Tags: `go_json`,
@ -168,9 +256,11 @@ func main() {
},
},
`386`: {
AR: args_home + `/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar`,
CC: args_home + `/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android24-clang`,
CXX: args_home + `/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android24-clang++`,
Cgos: &list_cgos{
AR: home(`android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar`),
CC: home(`android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang`),
CXX: home(`android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang++`),
},
Vers: list_vers{
``: {
Tags: `go_json`,
@ -178,9 +268,33 @@ func main() {
},
},
`arm`: {
AR: args_home + `/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar`,
CC: args_home + `/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi24-clang`,
CXX: args_home + `/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi24-clang++`,
Cgos: &list_cgos{
AR: home(`android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar`),
CC: home(`android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang`),
CXX: home(`android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang++`),
},
Vers: list_vers{
``: {
Tags: `go_json`,
},
},
},
},
},
// Mac OS
`darwin`: {
Arch: list_arch{
`amd64`: {
Vers: list_vers{
`v2`: {
Tags: `go_json`,
},
`v3`: {
Tags: `sonic avx`,
},
},
},
`arm64`: {
Vers: list_vers{
``: {
Tags: `go_json`,
@ -189,27 +303,22 @@ func main() {
},
},
},
// `darwin`: {
// Arch: list_arch{
// `amd64`: {
// CC: ``,
// },
// `arm64`: {
// CC: ``,
// },
// },
// },
},
},
args_home + `/go/bin/go1.20.14`: {
Args: def_args,
home(`go/bin/go1.20.14`): {
Args: []string{
`-trimpath`, `-buildvcs=false`,
`-ldflags`, `-s -w`,
},
GoOS: list_goos{
`windows`: {
Arch: list_arch{
`amd64`: {
AR: `x86_64-w64-mingw32-ar`,
CC: `x86_64-w64-mingw32-gcc`,
CXX: `x86_64-w64-mingw32-cpp`,
Cgos: &list_cgos{
AR: `x86_64-w64-mingw32-ar`,
CC: `x86_64-w64-mingw32-gcc`,
CXX: `x86_64-w64-mingw32-cpp`,
},
Vers: list_vers{
`v1`: {
Tags: `go_json`,
@ -237,8 +346,24 @@ func main() {
`, args_name, args_path, args_zpak)
// 解析配置文件
for goVer, conf_list := range def_list {
// 环境检测
if err := chkenv(goVer); err != nil {
fmt.Println(err, `跳过该环境`)
continue
}
for goOS, goos_list := range conf_list.GoOS {
for goArch, arch_list := range goos_list.Arch {
// 工具链检测
if arch_list.Cgos != nil {
if err := chkenv(
arch_list.Cgos.AR,
arch_list.Cgos.CC,
arch_list.Cgos.CXX,
); err != nil {
fmt.Println(err, `跳过该架构`)
continue
}
}
for goIns, vers_list := range arch_list.Vers {
// 构建程序二进制
if err := build(&param{
@ -248,9 +373,8 @@ func main() {
GoIns: goIns,
Args: conf_list.Args,
Tag: vers_list.Tags,
AR: arch_list.AR,
CC: arch_list.CC,
CXX: arch_list.CXX,
Cgos: arch_list.Cgos,
Venv: arch_list.Venv,
}); err != nil {
fmt.Println(`err:`, err)
}
@ -262,15 +386,6 @@ func main() {
}
func build(p *param) (err error) {
// 检测必要环境
for _, f := range []string{
p.GoVer, p.AR, p.CC, p.CXX,
} {
if _, e := exec.LookPath(f); e != nil && !errors.Is(e, exec.ErrDot) {
err = fmt.Errorf(`未找到指定环境: %s`, e)
return
}
}
// 拼接程序名称
var b strings.Builder
b.WriteString(args_name) // lx-source
@ -278,7 +393,17 @@ func build(p *param) (err error) {
b.WriteString(p.GoOS) // lx-source-linux
b.WriteByte('-') // lx-source-linux-
b.WriteString(p.GoArch) // lx-source-linux-amd64
b.WriteString(p.GoIns) // lx-source-linux-amd64v2
var digit byte
if p.Venv != `` {
digit = p.Venv[len(p.Venv)-1]
} else {
digit = p.GoArch[len(p.GoArch)-1]
}
if !unicode.IsDigit(rune(digit)) {
// 架构名结尾不是数字的再加一个连字符
b.WriteByte('-') // lx-source-linux-mipsle-softfloat
}
b.WriteString(p.GoIns) // lx-source-linux-amd64v2
if biname := filepath.Base(p.GoVer); biname != `go` {
b.WriteByte('-') // lx-source-linux-amd64v2-
b.WriteString(biname) // lx-source-linux-amd64v2-go1.20.14
@ -309,12 +434,24 @@ func build(p *param) (err error) {
cmd.Env = append(os.Environ(), []string{
`GOOS=` + p.GoOS,
`GOARCH=` + p.GoArch,
`AR=` + p.AR,
`CC=` + p.CC,
`CXX=` + p.CXX,
`CGO_ENABLED=1`,
`GO` + strings.ToUpper(p.GoArch) + `=` + p.GoIns,
}...)
if p.Cgos != nil {
cmd.Env = append(cmd.Env, []string{
`AR=` + p.Cgos.AR,
`CC=` + p.Cgos.CC,
`CXX=` + p.Cgos.CXX,
`CGO_ENABLED=1`,
}...)
} else {
cmd.Env = append(cmd.Env, `CGO_ENABLED=0`)
}
if p.GoIns != `` {
if p.Venv != `` {
cmd.Env = append(cmd.Env, `GO`+p.Venv+`=`+p.GoIns)
} else {
cmd.Env = append(cmd.Env, `GO`+strings.ToUpper(p.GoArch)+`=`+p.GoIns)
}
}
if err = cmd.Start(); err == nil {
err = cmd.Wait()

3
src/env/env.go vendored
View File

@ -12,7 +12,7 @@ import (
)
const (
Version = `1.0.3.0518`
Version = `1.0.3.0614`
)
var (
@ -124,6 +124,7 @@ type (
Kw_Bd_DevId string `comment:"field user.device_id"`
// kw kwdes
Kw_Des_Type string `comment:"返回格式 0: text, 1: json"`
Kw_Des_Source string `comment:"query source"`
Kw_Des_Header string `comment:"请求头 User-Agent"`
// kg

View File

@ -1,15 +1,19 @@
package kw
import (
"errors"
"io"
"lx-source/src/env"
"lx-source/src/sources"
"lx-source/src/sources/custom/utils"
"net/http"
"strconv"
"strings"
"sync"
"github.com/ZxwyWebSite/ztool"
"github.com/ZxwyWebSite/ztool/x/bytesconv"
"github.com/ZxwyWebSite/ztool/zcypt"
)
var (
@ -19,6 +23,7 @@ var (
parsemod bool
convtype string
desource string
// desParse func([]byte, *playInfo) error
// desParse func(any) ztool.Net_ResHandlerFunc
)
@ -36,11 +41,13 @@ func init() {
) {
loger.Fatal(`使用bdapi且验证参数为空`)
}
// bdheader[`token`] = env.Config.Custom.Kw_Bd_Token
bdheader[`uid`] = env.Config.Custom.Kw_Bd_Uid
bdheader[`devId`] = env.Config.Custom.Kw_Bd_DevId
kw_pool = &sync.Pool{New: func() any { return new(kwApi_Song) }}
Url = bdapi
case `1`, `kwdes`:
Url = kwdes
switch env.Config.Custom.Kw_Des_Type {
case `0`, `text`:
loger.Debug(`use kwdes text`)
@ -51,12 +58,20 @@ func init() {
convtype = `convert_url_with_sign`
// desParse = ztool.Net_ResToStruct
parsemod = true
case `2`, `anti`:
loger.Debug(`use kwdes anti`)
Url = manti
default:
loger.Fatal(`未定义的返回格式,请检查配置 [Custom].Kw_Des_Type`)
}
desheader[`User-Agent`] = env.Config.Custom.Kw_Des_Header
kw_pool = &sync.Pool{New: func() any { return new(playInfo) }}
Url = kwdes
if env.Config.Custom.Kw_Des_Source != `` {
desource = env.Config.Custom.Kw_Des_Source
} else {
dec, _ := zcypt.HexDecode([]byte{0x36, 0x62, 0x37, 0x37, 0x37, 0x30, 0x36, 0x63, 0x36, 0x31, 0x37, 0x39, 0x36, 0x35, 0x37, 0x32, 0x36, 0x38, 0x36, 0x34, 0x35, 0x66, 0x36, 0x31, 0x37, 0x32, 0x35, 0x66, 0x33, 0x35, 0x32, 0x65, 0x33, 0x31, 0x32, 0x65, 0x33, 0x30, 0x32, 0x65, 0x33, 0x30, 0x35, 0x66, 0x34, 0x32, 0x35, 0x66, 0x36, 0x61, 0x36, 0x39, 0x36, 0x31, 0x36, 0x62, 0x36, 0x66, 0x36, 0x65, 0x36, 0x37, 0x35, 0x66, 0x37, 0x36, 0x36, 0x38, 0x32, 0x65, 0x36, 0x31, 0x37, 0x30, 0x36, 0x62})
desource = bytesconv.BytesToString(dec)
}
default:
loger.Fatal(`未定义的接口模式,请检查配置 [Custom].Kw_Mode`)
}
@ -92,7 +107,7 @@ func bdapi(songMid, quality string) (ourl, msg string) {
loger.Debug(`Resp: %+v`, resp)
if resp.Code != 200 || resp.Data.AudioInfo.Bitrate == `1` {
// jx.Debug(`Kw, Err: %#v`, resp)
msg = ztool.Str_FastConcat(`failed: `, resp.Msg)
msg = ztool.Str_FastConcat(strconv.Itoa(resp.Code), `: `, resp.Msg)
return
}
ourl = utils.DelQuery(resp.Data.URL) //strings.Split(resp.Data.URL, `?`)[0]
@ -110,12 +125,12 @@ func kwdes(songMid, quality string) (ourl, msg string) {
target_url := ztool.Str_FastConcat(
`https://mobi.kuwo.cn/mobi.s?f=kuwo&q=`,
base64_encrypt(ztool.Str_FastConcat(
`corp=kuwo&source=kwplayer_ar_1.1.9_oppo_118980_320.apk&p2p=1&sig=0`,
`corp=kuwo&p2p=1&sig=0&notrace=0&priority=bitrate&network=WIFI&mode=down`,
`&source=`, desource,
`&type=`, convtype,
`&br=`, infoFile.H, infoFile.E,
`&format=`, infoFile.E,
`&rid=`, songMid,
`&notrace=0&priority=bitrate&network=WIFI&mode=down`,
)),
)
if parsemod {
@ -131,6 +146,7 @@ func kwdes(songMid, quality string) (ourl, msg string) {
msg = sources.ErrHttpReq
return
}
resp.Data.URL = utils.DelQuery(resp.Data.URL)
loger.Debug(`Resp: %+v`, resp)
if resp.Code != http.StatusOK {
msg = ztool.Str_FastConcat(`failed: `, resp.Msg)
@ -144,7 +160,7 @@ func kwdes(songMid, quality string) (ourl, msg string) {
return
}
}
ourl = utils.DelQuery(resp.Data.URL) //resp.Data.URL[:strings.Index(resp.Data.URL, `?`)]
ourl = resp.Data.URL //resp.Data.URL[:strings.Index(resp.Data.URL, `?`)]
return
}
ztool.Net_Request(http.MethodGet, target_url, nil,
@ -179,3 +195,133 @@ func kwdes(songMid, quality string) (ourl, msg string) {
)
return
}
// 一种替代方案仅在试听可用时获取cdn前缀缺点是无法获取不能试听的歌曲
func manti(songMid, quality string) (ourl, msg string) {
loger := env.Loger.NewGroup(`Kw`)
defer loger.Free()
infoFile, ok := fileInfo[quality]
if !ok {
msg = sources.E_QNotSupport
return
}
// 获取CDN地址
// var out_a string
/*var out_c struct {
// Timestamp int `json:"timestamp"`
Songs []struct {
ID int `json:"id"`
Duration int `json:"duration"`
URL string `json:"url"`
HTTPS string `json:"https"`
CarURL string `json:"car_url"`
CarURLHTTPS string `json:"car_url_https"`
Format string `json:"format"`
Br int `json:"br"`
OverseasCopyright string `json:"overseas_copyright"`
Start int `json:"start"`
End int `json:"end"`
Group string `json:"group"`
} `json:"songs"`
IP string `json:"ip"`
Country string `json:"country"`
Region string `json:"region"`
Locationid int `json:"locationid"`
Code int `json:"code"`
Result string `json:"result"`
}
err := ztool.Net_Request(
http.MethodGet,
`https://musicpay30.kuwo.cn/audi.tion?op=query&ids=`+songMid,
nil,
[]ztool.Net_ReqHandlerFunc{ztool.Net_ReqAddHeaders()},
[]ztool.Net_ResHandlerFunc{ztool.Net_ResToStruct(&out_c)},
)
if err != nil {
loger.Error(`Request: %s`, err)
msg = sources.ErrHttpReq
return
}*/
// 获取音频路径
if quality != sources.Q_128k {
ourl, msg = manti(songMid, sources.Q_128k)
if msg != `` {
return
}
if i := strings.LastIndexByte(ourl, '/'); i != -1 {
if ourl[i+1:] == `2272659253.mp3` {
msg = sources.ErrNoLink
return
}
}
target_url := ztool.Str_FastConcat(
`https://mobi.kuwo.cn/mobi.s?f=web&type=convert_url`,
`&br=`, infoFile.H, infoFile.E,
`&format=`, infoFile.E,
`&rid=`, songMid,
)
var out_u, realQuality string
err := ztool.Net_Request(
http.MethodGet, target_url, nil,
[]ztool.Net_ReqHandlerFunc{ztool.Net_ReqAddHeaders()},
[]ztool.Net_ResHandlerFunc{func(res *http.Response) (err error) {
var data []byte
data, err = io.ReadAll(res.Body)
if err != nil {
return
}
if res.StatusCode != http.StatusOK {
return errors.New(`failed: ` + res.Status)
}
infoData := mkMap(data)
loger.Debug(`uData: %+v`, infoData)
realQuality = infoData[`bitrate`]
out_u = utils.DelQuery(infoData[`url`])
return
}},
)
if err != nil {
loger.Error(`Request: %s`, err)
msg = sources.ErrHttpReq
return
}
if realQuality != infoFile.H[:len(infoFile.H)-1] {
msg = sources.E_QNotMatch
if !env.Config.Source.ForceFallback {
return
}
}
if ourl != `` && out_u != `` {
ourl = ourl[:24] + out_u
}
return
}
resp := kw_pool.Get().(*playInfo)
defer kw_pool.Put(resp)
err := ztool.Net_Request(
http.MethodGet, `https://mobi.kuwo.cn/mobi.s?f=web&type=convert_url_with_sign&br=128kmp3&format=mp3&rid=`+songMid, nil,
[]ztool.Net_ReqHandlerFunc{ztool.Net_ReqAddHeader(desheader)},
[]ztool.Net_ResHandlerFunc{ztool.Net_ResToStruct(&resp)},
)
if err != nil {
loger.Error(`Request: %s`, err)
msg = sources.ErrHttpReq
return
}
loger.Debug(`tData: %+v`, resp)
if resp.Code != http.StatusOK {
msg = ztool.Str_FastConcat(`failed: `, resp.Msg)
loger.Debug(msg)
return
}
realQuality := strconv.Itoa(resp.Data.Bitrate)
if realQuality != infoFile.H[:len(infoFile.H)-1] && resp.Data.Bitrate != 1 {
msg = sources.E_QNotMatch
if !env.Config.Source.ForceFallback {
return
}
}
ourl = utils.DelQuery(resp.Data.URL)
return
}

View File

@ -13,8 +13,8 @@ type (
Format string `json:"format"`
P2PAudiosourceid string `json:"p2p_audiosourceid"`
Rid int `json:"rid"`
Source string `json:"source"`
URL string `json:"url"`
// Source string `json:"source"`
URL string `json:"url"`
} `json:"data"`
Msg string `json:"msg"`
}

View File

@ -40,25 +40,64 @@ var (
// `User-Agent`: `okhttp/3.10.0`,
}
bdheader = map[string]string{
`channel`: `qq`,
`channel`: `guanfang`,
`plat`: `ar`,
`net`: `wifi`,
`ver`: `3.1.2`,
// `uid`: ``,
// `devId`: `0`,
`ver`: `3.1.4`,
`api-ver`: `application/json`,
`user-agent`: `Dart/2.18 (dart:io)`, //`Dalvik/2.1.0 (Linux; U; Android 7.1.1; OPPO R9sk Build/NMF26F)`,
}
// bdsreg = regexp.MustCompile(`[^a-zA-Z0-9]`)
)
func mkMap(data []byte) map[string]string {
out := make(map[string]string)
sep := bytes.Split(data, []byte{13, 10})
for i, r := 0, len(sep); i < r; i++ {
pat := bytes.Split(sep[i], []byte{61})
if len(pat) == 2 {
var s = sep[i]
if p := bytes.IndexByte(s, '='); p != -1 {
out[bytesconv.BytesToString(s[:p])] = bytesconv.BytesToString(s[p+1:])
continue
} else {
out[`_`] += bytesconv.BytesToString(s) + `;`
}
/*pat := bytes.Split(sep[i], []byte{61})
if len(pat) >= 2 {
out[bytesconv.BytesToString(pat[0])] = bytesconv.BytesToString(pat[1])
continue
}
out[`_`] += bytesconv.BytesToString(pat[0]) + `;`
out[`_`] += bytesconv.BytesToString(pat[0]) + `;`*/
}
return out
}
// 波点签名算法
/*func Bdsign(str string, m, m2 map[string]string) *strings.Builder {
var b strings.Builder
b.WriteString(`uid=`)
b.WriteString(env.Config.Custom.Kw_Bd_Uid)
b.WriteByte('&')
b.WriteString(`token=`)
b.WriteString(env.Config.Custom.Kw_Bd_Token)
b.WriteByte('&')
b.WriteString(`timestamp=`)
b.WriteString(strconv.FormatInt(time.Now().UnixMilli(), 10))
for k, v := range m2 {
b.WriteByte('&')
b.WriteString(k)
b.WriteByte('=')
b.WriteString(url.QueryEscape(v))
}
// 取 strings.Builder.buf []byte 地址
pb := (*[]byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&b)) + unsafe.Sizeof((*strings.Builder)(nil))))
charArray := bdsreg.ReplaceAll(*pb, []byte{})
slices.Sort(charArray)
str3 := string(charArray)
fmt.Println(str3)
lowerCase := zcypt.MD5EncStr(`kuwotest` + str3 + `/api/play/music/v2/audioUrl`)
b.WriteByte('&')
b.WriteString(`sign=`)
b.WriteString(lowerCase)
return &b
}*/

View File

@ -343,8 +343,8 @@ func Qlogin_graph(l *logs.Logger) error {
env.Config.Custom.Tx_Enable = true
env.Config.Custom.Tx_Uuin = out6.Req.Data.StrMusicid
env.Config.Custom.Tx_Ukey = out6.Req.Data.Musickey
env.Config.Custom.Tx_Refresh_Enable = true
env.Config.Custom.Tx_Refresh_Interval = time.Date(now.Year(), now.Month(), now.Day()+5, 0, 0, 0, 0, now.Location()).Unix()
env.Config.Custom.Tx_Refresh_Enable = false
// env.Config.Custom.Tx_Refresh_Interval = time.Date(now.Year(), now.Month(), now.Day()+5, 0, 0, 0, 0, now.Location()).Unix()
// env.Config.Custom.Tx_RefreshToken = out6.Req.Data.RefreshToken
// env.Config.Custom.Tx_AccessToken = out6.Req.Data.AccessToken

View File

@ -123,9 +123,18 @@ func refresh(loger *logs.Logger, now int64) error {
// loger.Error(`请求Api失败: %s`, err)
return errors.New(`请求Api失败: ` + err.Error())
}
loger.Debug(`Resp: %+v`, resp)
if resp.Req1.Code != 0 {
switch resp.Req1.Code {
case 1000:
return fmt.Errorf(`%v: Token无效或已过期`, resp.Req1.Code)
case 2000:
return fmt.Errorf(`%v: 该Token不支持刷新`, resp.Req1.Code)
default:
return fmt.Errorf(`%v: 刷新登录失败`, resp.Req1.Code)
}
// loger.Warn("刷新登录失败, code: %v\n响应体: %+v", resp.Req1.Code, resp)
return fmt.Errorf("刷新登录失败, code: %v\n响应体: %+v", resp.Req1.Code, resp)
// return fmt.Errorf("刷新登录失败, code: %v\n响应体: %+v", resp.Req1.Code, resp)
}
loger.Info(`刷新登录成功`)
env.Config.Custom.Tx_Uuin = resp.Req1.Data.StrMusicId

View File

@ -20,7 +20,11 @@ import (
const anonymous_token = `1f5fa7b6a6a9f81a11886e5186fde7fb98e25cf0036d7afd055b980b2261f5464b7f5273fc3921d1262bfec66a19a30c41d8da00c3685f5ace96f0d5a48b6db334d974731083682e3324751bcc9aaf44c3061cd1`
var wapiReg = regexp.MustCompile(`\w*api`)
var (
wapiReg = regexp.MustCompile(`\w*api`)
csrfReg = regexp.MustCompile(`_csrf=([^(;|$)]+)`)
domaReg = regexp.MustCompile(`\s*Domain=[^(;|$)]+;*`)
)
var userAgentMap = map[string]string{
`mobile`: `Mozilla/5.0 (iPhone; CPU iPhone OS 17_2_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Mobile/15E148 Safari/604.1`,
@ -103,8 +107,7 @@ func createRequest(method, url string, data map[string]any, options reqOptions)
switch options.Crypto {
case `weapi`:
options.Headers[`User-Agent`] = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.69`
reg := regexp.MustCompile(`_csrf=([^(;|$)]+)`)
csrfToken := reg.FindStringSubmatch(options.Headers[`Cookie`])
csrfToken := csrfReg.FindStringSubmatch(options.Headers[`Cookie`])
if len(csrfToken) > 1 {
data[`csrf_token`] = csrfToken[1]
} else {
@ -189,9 +192,8 @@ func createRequest(method, url string, data map[string]any, options reqOptions)
}
if err == nil {
answer.Cookie = res.Header[`Set-Cookie`] //res.Header.Values(`set-cookie`)
reg := regexp.MustCompile(`\s*Domain=[^(;|$)]+;*`)
for i, v := range answer.Cookie {
answer.Cookie[i] = reg.ReplaceAllString(v, ``)
answer.Cookie[i] = domaReg.ReplaceAllString(v, ``)
}
if options.Crypto == `eapi` && body[0] != '{' {
err = json.Unmarshal(decrypt(body), &answer.Body)

View File

@ -3,6 +3,14 @@
<!-- #### \# 2024-02-14 v1.0.3-rel (release)
+ **停止更新:感谢这三个月的陪伴,现因无力维护,停止后续更新,发布最后版本,大家有缘再见** -->
#### \# 2024-06-14 v1.0.3.0614 (dev)
+ 更新编译脚本,支持更多架构
#### \# 2024-05-31 v1.0.3.0531 (dev)
+ Wy源优化模块同步部分更改
+ Kw源测试接口无需白名单包名二次甚至三次查询
+ Kw源允许自定义Des_Source参数
#### \# 2024-05-25 Special Ver (dev)
+ 更新Action构建脚本正式兼容Go1.20(windows7)