mirror of
https://github.com/ZxwyWebSite/lx-source.git
synced 2025-05-23 21:37:42 +08:00
2024-06-14 v1.0.3.0614
This commit is contained in:
parent
76e7f5a1b6
commit
55e7c6227e
269
action.go
269
action.go
@ -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(¶m{
|
||||
@ -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
3
src/env/env.go
vendored
@ -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
|
||||
|
@ -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¬race=0&priority=bitrate&network=WIFI&mode=down`,
|
||||
`&source=`, desource,
|
||||
`&type=`, convtype,
|
||||
`&br=`, infoFile.H, infoFile.E,
|
||||
`&format=`, infoFile.E,
|
||||
`&rid=`, songMid,
|
||||
`¬race=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
|
||||
}
|
||||
|
@ -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"`
|
||||
}
|
||||
|
@ -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
|
||||
}*/
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user