feat(thunderx): generate UserAgent automatically (#6664)
This commit is contained in:
parent
227d034db8
commit
432901db5a
@ -3,10 +3,6 @@ package thunderx
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/go-resty/resty/v2"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/alist-org/alist/v3/drivers/base"
|
"github.com/alist-org/alist/v3/drivers/base"
|
||||||
"github.com/alist-org/alist/v3/internal/driver"
|
"github.com/alist-org/alist/v3/internal/driver"
|
||||||
"github.com/alist-org/alist/v3/internal/errs"
|
"github.com/alist-org/alist/v3/internal/errs"
|
||||||
@ -18,6 +14,9 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
"github.com/aws/aws-sdk-go/aws/session"
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
||||||
|
"github.com/go-resty/resty/v2"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ThunderX struct {
|
type ThunderX struct {
|
||||||
@ -41,26 +40,15 @@ func (x *ThunderX) Init(ctx context.Context) (err error) {
|
|||||||
if x.XunLeiXCommon == nil {
|
if x.XunLeiXCommon == nil {
|
||||||
x.XunLeiXCommon = &XunLeiXCommon{
|
x.XunLeiXCommon = &XunLeiXCommon{
|
||||||
Common: &Common{
|
Common: &Common{
|
||||||
client: base.NewRestyClient(),
|
client: base.NewRestyClient(),
|
||||||
Algorithms: []string{
|
Algorithms: Algorithms,
|
||||||
"lHwINjLeqssT28Ym99p5MvR",
|
|
||||||
"xvFcxvtqPKCa9Ajf",
|
|
||||||
"2ywOP8spKHzfuhZMUYZ9IpsViq0t8vT0",
|
|
||||||
"FTBrJism20SHKQ2m2",
|
|
||||||
"BHrWJsPwjnr5VeLtOUr2191X9uXhWmt",
|
|
||||||
"yu0QgHEjNmDoPNwXN17so2hQlDT83T",
|
|
||||||
"OcaMfLMCGZ7oYlvZGIbTqb4U7cCY",
|
|
||||||
"jBGGu0GzXOjtCXYwkOBb+c6TZ/Nymv",
|
|
||||||
"YLWRjVor2rOuYEL",
|
|
||||||
"94wjoPazejyNC+gRpOj+JOm1XXvxa",
|
|
||||||
},
|
|
||||||
DeviceID: utils.GetMD5EncodeStr(x.Username + x.Password),
|
DeviceID: utils.GetMD5EncodeStr(x.Username + x.Password),
|
||||||
ClientID: "ZQL_zwA4qhHcoe_2",
|
ClientID: ClientID,
|
||||||
ClientSecret: "Og9Vr1L8Ee6bh0olFxFDRg",
|
ClientSecret: ClientSecret,
|
||||||
ClientVersion: "1.05.0.2115",
|
ClientVersion: ClientVersion,
|
||||||
PackageName: "com.thunder.downloader",
|
PackageName: PackageName,
|
||||||
UserAgent: "ANDROID-com.thunder.downloader/1.05.0.2115 netWorkType/5G appid/40 deviceName/Xiaomi_M2004j7ac deviceModel/M2004J7AC OSVersion/12 protocolVersion/301 platformVersion/10 sdkVersion/220200 Oauth2Client/0.9 (Linux 4_14_186-perf-gddfs8vbb238b) (JAVA 0)",
|
UserAgent: BuildCustomUserAgent(utils.GetMD5EncodeStr(x.Username+x.Password), ClientID, PackageName, SdkVersion, ClientVersion, PackageName, ""),
|
||||||
DownloadUserAgent: "Dalvik/2.1.0 (Linux; U; Android 12; M2004J7AC Build/SP1A.210812.016)",
|
DownloadUserAgent: DownloadUserAgent,
|
||||||
UseVideoUrl: x.UseVideoUrl,
|
UseVideoUrl: x.UseVideoUrl,
|
||||||
|
|
||||||
refreshCTokenCk: func(token string) {
|
refreshCTokenCk: func(token string) {
|
||||||
@ -76,6 +64,10 @@ func (x *ThunderX) Init(ctx context.Context) (err error) {
|
|||||||
token, err = x.Login(x.Username, x.Password)
|
token, err = x.Login(x.Username, x.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
x.GetStorage().SetStatus(fmt.Sprintf("%+v", err.Error()))
|
x.GetStorage().SetStatus(fmt.Sprintf("%+v", err.Error()))
|
||||||
|
if token.UserID != "" {
|
||||||
|
x.SetUserID(token.UserID)
|
||||||
|
x.UserAgent = BuildCustomUserAgent(utils.GetMD5EncodeStr(x.Username+x.Password), ClientID, PackageName, SdkVersion, ClientVersion, PackageName, token.UserID)
|
||||||
|
}
|
||||||
op.MustSaveDriverStorage(x)
|
op.MustSaveDriverStorage(x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,10 +78,14 @@ func (x *ThunderX) Init(ctx context.Context) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 自定义验证码token
|
// 自定义验证码token
|
||||||
ctoekn := strings.TrimSpace(x.CaptchaToken)
|
ctoken := strings.TrimSpace(x.CaptchaToken)
|
||||||
if ctoekn != "" {
|
if ctoken != "" {
|
||||||
x.SetCaptchaToken(ctoekn)
|
x.SetCaptchaToken(ctoken)
|
||||||
}
|
}
|
||||||
|
if x.DeviceID == "" {
|
||||||
|
x.SetDeviceID(utils.GetMD5EncodeStr(x.Username + x.Password))
|
||||||
|
}
|
||||||
|
|
||||||
x.XunLeiXCommon.UseVideoUrl = x.UseVideoUrl
|
x.XunLeiXCommon.UseVideoUrl = x.UseVideoUrl
|
||||||
x.Addition.RootFolderID = x.RootFolderID
|
x.Addition.RootFolderID = x.RootFolderID
|
||||||
// 防止重复登录
|
// 防止重复登录
|
||||||
@ -102,6 +98,10 @@ func (x *ThunderX) Init(ctx context.Context) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
x.SetTokenResp(token)
|
x.SetTokenResp(token)
|
||||||
|
if token.UserID != "" {
|
||||||
|
x.SetUserID(token.UserID)
|
||||||
|
x.UserAgent = BuildCustomUserAgent(x.DeviceID, ClientID, PackageName, SdkVersion, ClientVersion, PackageName, token.UserID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -137,18 +137,33 @@ func (x *ThunderXExpert) Init(ctx context.Context) (err error) {
|
|||||||
|
|
||||||
DeviceID: func() string {
|
DeviceID: func() string {
|
||||||
if len(x.DeviceID) != 32 {
|
if len(x.DeviceID) != 32 {
|
||||||
return utils.GetMD5EncodeStr(x.DeviceID)
|
if x.LoginType == "user" {
|
||||||
|
return utils.GetMD5EncodeStr(x.Username + x.Password)
|
||||||
|
}
|
||||||
|
return utils.GetMD5EncodeStr(x.ExpertAddition.RefreshToken)
|
||||||
}
|
}
|
||||||
return x.DeviceID
|
return x.DeviceID
|
||||||
}(),
|
}(),
|
||||||
ClientID: x.ClientID,
|
ClientID: x.ClientID,
|
||||||
ClientSecret: x.ClientSecret,
|
ClientSecret: x.ClientSecret,
|
||||||
ClientVersion: x.ClientVersion,
|
ClientVersion: x.ClientVersion,
|
||||||
PackageName: x.PackageName,
|
PackageName: x.PackageName,
|
||||||
UserAgent: x.UserAgent,
|
UserAgent: func() string {
|
||||||
DownloadUserAgent: x.DownloadUserAgent,
|
if x.ExpertAddition.UserAgent != "" {
|
||||||
UseVideoUrl: x.UseVideoUrl,
|
return x.ExpertAddition.UserAgent
|
||||||
|
}
|
||||||
|
if x.LoginType == "user" {
|
||||||
|
return BuildCustomUserAgent(utils.GetMD5EncodeStr(x.Username+x.Password), ClientID, PackageName, SdkVersion, ClientVersion, PackageName, "")
|
||||||
|
}
|
||||||
|
return BuildCustomUserAgent(utils.GetMD5EncodeStr(x.ExpertAddition.RefreshToken), ClientID, PackageName, SdkVersion, ClientVersion, PackageName, "")
|
||||||
|
}(),
|
||||||
|
DownloadUserAgent: func() string {
|
||||||
|
if x.ExpertAddition.DownloadUserAgent != "" {
|
||||||
|
return x.ExpertAddition.DownloadUserAgent
|
||||||
|
}
|
||||||
|
return DownloadUserAgent
|
||||||
|
}(),
|
||||||
|
UseVideoUrl: x.UseVideoUrl,
|
||||||
refreshCTokenCk: func(token string) {
|
refreshCTokenCk: func(token string) {
|
||||||
x.CaptchaToken = token
|
x.CaptchaToken = token
|
||||||
op.MustSaveDriverStorage(x)
|
op.MustSaveDriverStorage(x)
|
||||||
@ -156,8 +171,17 @@ func (x *ThunderXExpert) Init(ctx context.Context) (err error) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if x.CaptchaToken != "" {
|
if x.ExpertAddition.CaptchaToken != "" {
|
||||||
x.SetCaptchaToken(x.CaptchaToken)
|
x.SetCaptchaToken(x.ExpertAddition.CaptchaToken)
|
||||||
|
op.MustSaveDriverStorage(x)
|
||||||
|
}
|
||||||
|
if x.Common.DeviceID != "" {
|
||||||
|
x.ExpertAddition.DeviceID = x.Common.DeviceID
|
||||||
|
op.MustSaveDriverStorage(x)
|
||||||
|
}
|
||||||
|
if x.Common.DownloadUserAgent != "" {
|
||||||
|
x.ExpertAddition.DownloadUserAgent = x.Common.DownloadUserAgent
|
||||||
|
op.MustSaveDriverStorage(x)
|
||||||
}
|
}
|
||||||
x.XunLeiXCommon.UseVideoUrl = x.UseVideoUrl
|
x.XunLeiXCommon.UseVideoUrl = x.UseVideoUrl
|
||||||
x.ExpertAddition.RootFolderID = x.RootFolderID
|
x.ExpertAddition.RootFolderID = x.RootFolderID
|
||||||
@ -177,7 +201,6 @@ func (x *ThunderXExpert) Init(ctx context.Context) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
x.SetTokenResp(token)
|
x.SetTokenResp(token)
|
||||||
|
|
||||||
// 刷新token方法
|
// 刷新token方法
|
||||||
x.SetRefreshTokenFunc(func() error {
|
x.SetRefreshTokenFunc(func() error {
|
||||||
token, err := x.XunLeiXCommon.RefreshToken(x.TokenResp.RefreshToken)
|
token, err := x.XunLeiXCommon.RefreshToken(x.TokenResp.RefreshToken)
|
||||||
@ -208,13 +231,19 @@ func (x *ThunderXExpert) Init(ctx context.Context) (err error) {
|
|||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 更新 UserAgent
|
||||||
|
if x.TokenResp.UserID != "" {
|
||||||
|
x.ExpertAddition.UserAgent = BuildCustomUserAgent(x.ExpertAddition.DeviceID, ClientID, PackageName, SdkVersion, ClientVersion, PackageName, x.TokenResp.UserID)
|
||||||
|
x.SetUserAgent(x.ExpertAddition.UserAgent)
|
||||||
|
op.MustSaveDriverStorage(x)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 仅修改验证码token
|
// 仅修改验证码token
|
||||||
if x.CaptchaToken != "" {
|
if x.CaptchaToken != "" {
|
||||||
x.SetCaptchaToken(x.CaptchaToken)
|
x.SetCaptchaToken(x.CaptchaToken)
|
||||||
}
|
}
|
||||||
x.XunLeiXCommon.UserAgent = x.UserAgent
|
x.XunLeiXCommon.UserAgent = x.ExpertAddition.UserAgent
|
||||||
x.XunLeiXCommon.DownloadUserAgent = x.DownloadUserAgent
|
x.XunLeiXCommon.DownloadUserAgent = x.ExpertAddition.UserAgent
|
||||||
x.XunLeiXCommon.UseVideoUrl = x.UseVideoUrl
|
x.XunLeiXCommon.UseVideoUrl = x.UseVideoUrl
|
||||||
x.ExpertAddition.RootFolderID = x.RootFolderID
|
x.ExpertAddition.RootFolderID = x.RootFolderID
|
||||||
}
|
}
|
||||||
@ -426,17 +455,17 @@ func (xc *XunLeiXCommon) getFiles(ctx context.Context, folderId string) ([]model
|
|||||||
return files, nil
|
return files, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置刷新Token的方法
|
// SetRefreshTokenFunc 设置刷新Token的方法
|
||||||
func (xc *XunLeiXCommon) SetRefreshTokenFunc(fn func() error) {
|
func (xc *XunLeiXCommon) SetRefreshTokenFunc(fn func() error) {
|
||||||
xc.refreshTokenFunc = fn
|
xc.refreshTokenFunc = fn
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置Token
|
// SetTokenResp 设置Token
|
||||||
func (xc *XunLeiXCommon) SetTokenResp(tr *TokenResp) {
|
func (xc *XunLeiXCommon) SetTokenResp(tr *TokenResp) {
|
||||||
xc.TokenResp = tr
|
xc.TokenResp = tr
|
||||||
}
|
}
|
||||||
|
|
||||||
// 携带Authorization和CaptchaToken的请求
|
// Request 携带Authorization和CaptchaToken的请求
|
||||||
func (xc *XunLeiXCommon) Request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
|
func (xc *XunLeiXCommon) Request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
|
||||||
data, err := xc.Common.Request(url, method, func(req *resty.Request) {
|
data, err := xc.Common.Request(url, method, func(req *resty.Request) {
|
||||||
req.SetHeaders(map[string]string{
|
req.SetHeaders(map[string]string{
|
||||||
@ -473,7 +502,7 @@ func (xc *XunLeiXCommon) Request(url string, method string, callback base.ReqCal
|
|||||||
return xc.Request(url, method, callback, resp)
|
return xc.Request(url, method, callback, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 刷新Token
|
// RefreshToken 刷新Token
|
||||||
func (xc *XunLeiXCommon) RefreshToken(refreshToken string) (*TokenResp, error) {
|
func (xc *XunLeiXCommon) RefreshToken(refreshToken string) (*TokenResp, error) {
|
||||||
var resp TokenResp
|
var resp TokenResp
|
||||||
_, err := xc.Common.Request(XLUSER_API_URL+"/auth/token", http.MethodPost, func(req *resty.Request) {
|
_, err := xc.Common.Request(XLUSER_API_URL+"/auth/token", http.MethodPost, func(req *resty.Request) {
|
||||||
@ -491,10 +520,11 @@ func (xc *XunLeiXCommon) RefreshToken(refreshToken string) (*TokenResp, error) {
|
|||||||
if resp.RefreshToken == "" {
|
if resp.RefreshToken == "" {
|
||||||
return nil, errs.EmptyToken
|
return nil, errs.EmptyToken
|
||||||
}
|
}
|
||||||
|
resp.UserID = resp.Sub
|
||||||
return &resp, nil
|
return &resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 登录
|
// Login 登录
|
||||||
func (xc *XunLeiXCommon) Login(username, password string) (*TokenResp, error) {
|
func (xc *XunLeiXCommon) Login(username, password string) (*TokenResp, error) {
|
||||||
url := XLUSER_API_URL + "/auth/signin"
|
url := XLUSER_API_URL + "/auth/signin"
|
||||||
err := xc.RefreshCaptchaTokenInLogin(GetAction(http.MethodPost, url), username)
|
err := xc.RefreshCaptchaTokenInLogin(GetAction(http.MethodPost, url), username)
|
||||||
|
@ -23,7 +23,7 @@ type ExpertAddition struct {
|
|||||||
RefreshToken string `json:"refresh_token" required:"true" help:"login type is refresh_token,this is required"`
|
RefreshToken string `json:"refresh_token" required:"true" help:"login type is refresh_token,this is required"`
|
||||||
|
|
||||||
// 签名方法1
|
// 签名方法1
|
||||||
Algorithms string `json:"algorithms" required:"true" help:"sign type is algorithms,this is required" default:"lHwINjLeqssT28Ym99p5MvR,xvFcxvtqPKCa9Ajf,2ywOP8spKHzfuhZMUYZ9IpsViq0t8vT0,FTBrJism20SHKQ2m2,BHrWJsPwjnr5VeLtOUr2191X9uXhWmt,yu0QgHEjNmDoPNwXN17so2hQlDT83T,OcaMfLMCGZ7oYlvZGIbTqb4U7cCY,jBGGu0GzXOjtCXYwkOBb+c6TZ/Nymv,YLWRjVor2rOuYEL,94wjoPazejyNC+gRpOj+JOm1XXvxa"`
|
Algorithms string `json:"algorithms" required:"true" help:"sign type is algorithms,this is required" default:"kVy0WbPhiE4v6oxXZ88DvoA3Q,lON/AUoZKj8/nBtcE85mVbkOaVdVa,rLGffQrfBKH0BgwQ33yZofvO3Or,FO6HWqw,GbgvyA2,L1NU9QvIQIH7DTRt,y7llk4Y8WfYflt6,iuDp1WPbV3HRZudZtoXChxH4HNVBX5ZALe,8C28RTXmVcco0,X5Xh,7xe25YUgfGgD0xW3ezFS,,CKCR,8EmDjBo6h3eLaK7U6vU2Qys0NsMx,t2TeZBXKqbdP09Arh9C3"`
|
||||||
// 签名方法2
|
// 签名方法2
|
||||||
CaptchaSign string `json:"captcha_sign" required:"true" help:"sign type is captcha_sign,this is required"`
|
CaptchaSign string `json:"captcha_sign" required:"true" help:"sign type is captcha_sign,this is required"`
|
||||||
Timestamp string `json:"timestamp" required:"true" help:"sign type is captcha_sign,this is required"`
|
Timestamp string `json:"timestamp" required:"true" help:"sign type is captcha_sign,this is required"`
|
||||||
@ -32,15 +32,15 @@ type ExpertAddition struct {
|
|||||||
CaptchaToken string `json:"captcha_token"`
|
CaptchaToken string `json:"captcha_token"`
|
||||||
|
|
||||||
// 必要且影响登录,由签名决定
|
// 必要且影响登录,由签名决定
|
||||||
DeviceID string `json:"device_id" required:"true" default:"9aa5c268e7bcfc197a9ad88e2fb330e5"`
|
DeviceID string `json:"device_id" required:"false" default:""`
|
||||||
ClientID string `json:"client_id" required:"true" default:"ZQL_zwA4qhHcoe_2"`
|
ClientID string `json:"client_id" required:"true" default:"ZQL_zwA4qhHcoe_2"`
|
||||||
ClientSecret string `json:"client_secret" required:"true" default:"Og9Vr1L8Ee6bh0olFxFDRg"`
|
ClientSecret string `json:"client_secret" required:"true" default:"Og9Vr1L8Ee6bh0olFxFDRg"`
|
||||||
ClientVersion string `json:"client_version" required:"true" default:"1.05.0.2115"`
|
ClientVersion string `json:"client_version" required:"true" default:"1.06.0.2132"`
|
||||||
PackageName string `json:"package_name" required:"true" default:"com.thunder.downloader"`
|
PackageName string `json:"package_name" required:"true" default:"com.thunder.downloader"`
|
||||||
|
|
||||||
//不影响登录,影响下载速度
|
////不影响登录,影响下载速度
|
||||||
UserAgent string `json:"user_agent" required:"true" default:"ANDROID-com.thunder.downloader/1.05.0.2115 netWorkType/4G appid/40 deviceName/Xiaomi_M2004j7ac deviceModel/M2004J7AC OSVersion/12 protocolVersion/301 platformVersion/10 sdkVersion/220200 Oauth2Client/0.9 (Linux 4_14_186-perf-gdcf98eab238b) (JAVA 0)"`
|
UserAgent string `json:"user_agent" required:"false" default:""`
|
||||||
DownloadUserAgent string `json:"download_user_agent" required:"true" default:"Dalvik/2.1.0 (Linux; U; Android 12; M2004J7AC Build/SP1A.210812.016)"`
|
DownloadUserAgent string `json:"download_user_agent" required:"false" default:""`
|
||||||
|
|
||||||
//优先使用视频链接代替下载链接
|
//优先使用视频链接代替下载链接
|
||||||
UseVideoUrl bool `json:"use_video_url"`
|
UseVideoUrl bool `json:"use_video_url"`
|
||||||
@ -85,7 +85,7 @@ func (i *Addition) GetIdentity() string {
|
|||||||
var config = driver.Config{
|
var config = driver.Config{
|
||||||
Name: "ThunderX",
|
Name: "ThunderX",
|
||||||
LocalSort: true,
|
LocalSort: true,
|
||||||
OnlyProxy: true,
|
OnlyProxy: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
var configExpert = driver.Config{
|
var configExpert = driver.Config{
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
package thunderx
|
package thunderx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/md5"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/alist-org/alist/v3/drivers/base"
|
"github.com/alist-org/alist/v3/drivers/base"
|
||||||
@ -20,6 +22,33 @@ const (
|
|||||||
XLUSER_API_URL = "https://xluser-ssl.xunleix.com/v1"
|
XLUSER_API_URL = "https://xluser-ssl.xunleix.com/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var Algorithms = []string{
|
||||||
|
"kVy0WbPhiE4v6oxXZ88DvoA3Q",
|
||||||
|
"lON/AUoZKj8/nBtcE85mVbkOaVdVa",
|
||||||
|
"rLGffQrfBKH0BgwQ33yZofvO3Or",
|
||||||
|
"FO6HWqw",
|
||||||
|
"GbgvyA2",
|
||||||
|
"L1NU9QvIQIH7DTRt",
|
||||||
|
"y7llk4Y8WfYflt6",
|
||||||
|
"iuDp1WPbV3HRZudZtoXChxH4HNVBX5ZALe",
|
||||||
|
"8C28RTXmVcco0",
|
||||||
|
"X5Xh",
|
||||||
|
"7xe25YUgfGgD0xW3ezFS",
|
||||||
|
"",
|
||||||
|
"CKCR",
|
||||||
|
"8EmDjBo6h3eLaK7U6vU2Qys0NsMx",
|
||||||
|
"t2TeZBXKqbdP09Arh9C3",
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
ClientID = "ZQL_zwA4qhHcoe_2"
|
||||||
|
ClientSecret = "Og9Vr1L8Ee6bh0olFxFDRg"
|
||||||
|
ClientVersion = "1.06.0.2132"
|
||||||
|
PackageName = "com.thunder.downloader"
|
||||||
|
DownloadUserAgent = "Dalvik/2.1.0 (Linux; U; Android 13; M2004J7AC Build/SP1A.210812.016)"
|
||||||
|
SdkVersion = "2.0.3.203100 "
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
FOLDER = "drive#folder"
|
FOLDER = "drive#folder"
|
||||||
FILE = "drive#file"
|
FILE = "drive#file"
|
||||||
@ -42,7 +71,7 @@ type Common struct {
|
|||||||
client *resty.Client
|
client *resty.Client
|
||||||
|
|
||||||
captchaToken string
|
captchaToken string
|
||||||
|
userID string
|
||||||
// 签名相关,二选一
|
// 签名相关,二选一
|
||||||
Algorithms []string
|
Algorithms []string
|
||||||
Timestamp, CaptchaSign string
|
Timestamp, CaptchaSign string
|
||||||
@ -61,6 +90,18 @@ type Common struct {
|
|||||||
refreshCTokenCk func(token string)
|
refreshCTokenCk func(token string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Common) SetDeviceID(deviceID string) {
|
||||||
|
c.DeviceID = deviceID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Common) SetUserID(userID string) {
|
||||||
|
c.userID = userID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Common) SetUserAgent(userAgent string) {
|
||||||
|
c.UserAgent = userAgent
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Common) SetCaptchaToken(captchaToken string) {
|
func (c *Common) SetCaptchaToken(captchaToken string) {
|
||||||
c.captchaToken = captchaToken
|
c.captchaToken = captchaToken
|
||||||
}
|
}
|
||||||
@ -145,7 +186,7 @@ func (c *Common) refreshCaptchaToken(action string, metas map[string]string) err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 只有基础信息的请求
|
// Request 只有基础信息的请求
|
||||||
func (c *Common) Request(url, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
|
func (c *Common) Request(url, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
|
||||||
req := c.client.R().SetHeaders(map[string]string{
|
req := c.client.R().SetHeaders(map[string]string{
|
||||||
"user-agent": c.UserAgent,
|
"user-agent": c.UserAgent,
|
||||||
@ -200,3 +241,57 @@ func getGcid(r io.Reader, size int64) (string, error) {
|
|||||||
}
|
}
|
||||||
return hex.EncodeToString(hash1.Sum(nil)), nil
|
return hex.EncodeToString(hash1.Sum(nil)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generateDeviceSign(deviceID, packageName string) string {
|
||||||
|
|
||||||
|
signatureBase := fmt.Sprintf("%s%s%s%s", deviceID, packageName, "1", "appkey")
|
||||||
|
|
||||||
|
sha1Hash := sha1.New()
|
||||||
|
sha1Hash.Write([]byte(signatureBase))
|
||||||
|
sha1Result := sha1Hash.Sum(nil)
|
||||||
|
|
||||||
|
sha1String := hex.EncodeToString(sha1Result)
|
||||||
|
|
||||||
|
md5Hash := md5.New()
|
||||||
|
md5Hash.Write([]byte(sha1String))
|
||||||
|
md5Result := md5Hash.Sum(nil)
|
||||||
|
|
||||||
|
md5String := hex.EncodeToString(md5Result)
|
||||||
|
|
||||||
|
deviceSign := fmt.Sprintf("div101.%s%s", deviceID, md5String)
|
||||||
|
|
||||||
|
return deviceSign
|
||||||
|
}
|
||||||
|
|
||||||
|
func BuildCustomUserAgent(deviceID, clientID, appName, sdkVersion, clientVersion, packageName, userID string) string {
|
||||||
|
deviceSign := generateDeviceSign(deviceID, packageName)
|
||||||
|
var sb strings.Builder
|
||||||
|
|
||||||
|
sb.WriteString(fmt.Sprintf("ANDROID-%s/%s ", appName, clientVersion))
|
||||||
|
sb.WriteString("protocolVersion/200 ")
|
||||||
|
sb.WriteString("accesstype/ ")
|
||||||
|
sb.WriteString(fmt.Sprintf("clientid/%s ", clientID))
|
||||||
|
sb.WriteString(fmt.Sprintf("clientversion/%s ", clientVersion))
|
||||||
|
sb.WriteString("action_type/ ")
|
||||||
|
sb.WriteString("networktype/WIFI ")
|
||||||
|
sb.WriteString("sessionid/ ")
|
||||||
|
sb.WriteString(fmt.Sprintf("deviceid/%s ", deviceID))
|
||||||
|
sb.WriteString("providername/NONE ")
|
||||||
|
sb.WriteString(fmt.Sprintf("devicesign/%s ", deviceSign))
|
||||||
|
sb.WriteString("refresh_token/ ")
|
||||||
|
sb.WriteString(fmt.Sprintf("sdkversion/%s ", sdkVersion))
|
||||||
|
sb.WriteString(fmt.Sprintf("datetime/%d ", time.Now().UnixMilli()))
|
||||||
|
sb.WriteString(fmt.Sprintf("usrno/%s ", userID))
|
||||||
|
sb.WriteString(fmt.Sprintf("appname/%s ", appName))
|
||||||
|
sb.WriteString(fmt.Sprintf("session_origin/ "))
|
||||||
|
sb.WriteString(fmt.Sprintf("grant_type/ "))
|
||||||
|
sb.WriteString(fmt.Sprintf("appid/ "))
|
||||||
|
sb.WriteString(fmt.Sprintf("clientip/ "))
|
||||||
|
sb.WriteString(fmt.Sprintf("devicename/Xiaomi_M2004j7ac "))
|
||||||
|
sb.WriteString(fmt.Sprintf("osversion/13 "))
|
||||||
|
sb.WriteString(fmt.Sprintf("platformversion/10 "))
|
||||||
|
sb.WriteString(fmt.Sprintf("accessmode/ "))
|
||||||
|
sb.WriteString(fmt.Sprintf("devicemodel/M2004J7AC "))
|
||||||
|
|
||||||
|
return sb.String()
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user