Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(thunderBrowser): add automatically generate UserAgent #6692

Merged
merged 1 commit into from
Jul 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 71 additions & 47 deletions drivers/thunder_browser/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package thunder_browser

import (
"context"
"errors"
"fmt"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/internal/op"
"github.com/alist-org/alist/v3/pkg/utils"
Expand Down Expand Up @@ -53,33 +53,17 @@ func (x *ThunderBrowser) Init(ctx context.Context) (err error) {
if x.XunLeiBrowserCommon == nil {
x.XunLeiBrowserCommon = &XunLeiBrowserCommon{
Common: &Common{
client: base.NewRestyClient(),
Algorithms: []string{
"x+I5XiTByg",
"6QU1x5DqGAV3JKg6h",
"VI1vL1WXr7st0es",
"n+/3yhlrnKs4ewhLgZhZ5ITpt554",
"UOip2PE7BLIEov/ZX6VOnsz",
"Q70h9lpViNCOC8sGVkar9o22LhBTjfP",
"IVHFuB1JcMlaZHnW",
"bKE",
"HZRbwxOiQx+diNopi6Nu",
"fwyasXgYL3rP314331b",
"LWxXAiSW4",
"UlWIjv1HGrC6Ngmt4Nohx",
"FOa+Lc0bxTDpTwIh2",
"0+RY",
"xmRVMqokHHpvsiH0",
},
client: base.NewRestyClient(),
Algorithms: Algorithms,
DeviceID: utils.GetMD5EncodeStr(x.Username + x.Password),
ClientID: "ZUBzD9J_XPXfn7f7",
ClientSecret: "yESVmHecEe6F0aou69vl-g",
ClientVersion: "1.0.7.1938",
PackageName: "com.xunlei.browser",
UserAgent: "ANDROID-com.xunlei.browser/1.0.7.1938 netWorkType/5G appid/22062 deviceName/Xiaomi_M2004j7ac deviceModel/M2004J7AC OSVersion/12 protocolVersion/301 platformVersion/10 sdkVersion/233100 Oauth2Client/0.9 (Linux 4_14_186-perf-gddfs8vbb238b) (JAVA 0)",
DownloadUserAgent: "AndroidDownloadManager/12 (Linux; U; Android 12; M2004J7AC Build/SP1A.210812.016)",
ClientID: ClientID,
ClientSecret: ClientSecret,
ClientVersion: ClientVersion,
PackageName: PackageName,
UserAgent: BuildCustomUserAgent(utils.GetMD5EncodeStr(x.Username+x.Password), PackageName, SdkVersion, ClientVersion, PackageName),
DownloadUserAgent: DownloadUserAgent,
UseVideoUrl: x.UseVideoUrl,

RemoveWay: x.Addition.RemoveWay,
refreshCTokenCk: func(token string) {
x.CaptchaToken = token
op.MustSaveDriverStorage(x)
Expand Down Expand Up @@ -107,6 +91,9 @@ func (x *ThunderBrowser) Init(ctx context.Context) (err error) {
if ctoekn != "" {
x.SetCaptchaToken(ctoekn)
}
if x.DeviceID == "" {
x.SetDeviceID(utils.GetMD5EncodeStr(x.Username + x.Password))
}
x.XunLeiBrowserCommon.UseVideoUrl = x.UseVideoUrl
x.Addition.RootFolderID = x.RootFolderID
// 防止重复登录
Expand Down Expand Up @@ -170,30 +157,58 @@ func (x *ThunderBrowserExpert) Init(ctx context.Context) (err error) {
x.XunLeiBrowserCommon = &XunLeiBrowserCommon{
Common: &Common{
client: base.NewRestyClient(),

DeviceID: func() string {
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
}(),
ClientID: x.ClientID,
ClientSecret: x.ClientSecret,
ClientVersion: x.ClientVersion,
PackageName: x.PackageName,
UserAgent: x.UserAgent,
DownloadUserAgent: x.DownloadUserAgent,
UseVideoUrl: x.UseVideoUrl,

ClientID: x.ClientID,
ClientSecret: x.ClientSecret,
ClientVersion: x.ClientVersion,
PackageName: x.PackageName,
UserAgent: func() string {
if x.ExpertAddition.UserAgent != "" {
return x.ExpertAddition.UserAgent
}
if x.LoginType == "user" {
return BuildCustomUserAgent(utils.GetMD5EncodeStr(x.Username+x.Password), x.PackageName, SdkVersion, x.ClientVersion, x.PackageName)
}
return BuildCustomUserAgent(utils.GetMD5EncodeStr(x.ExpertAddition.RefreshToken), x.PackageName, SdkVersion, x.ClientVersion, x.PackageName)
}(),
DownloadUserAgent: func() string {
if x.ExpertAddition.DownloadUserAgent != "" {
return x.ExpertAddition.DownloadUserAgent
}
return DownloadUserAgent
}(),
UseVideoUrl: x.UseVideoUrl,
RemoveWay: x.ExpertAddition.RemoveWay,
refreshCTokenCk: func(token string) {
x.CaptchaToken = token
op.MustSaveDriverStorage(x)
},
},
}

if x.CaptchaToken != "" {
x.SetCaptchaToken(x.CaptchaToken)
if x.ExpertAddition.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.UserAgent != "" {
x.ExpertAddition.UserAgent = x.Common.UserAgent
op.MustSaveDriverStorage(x)
}
if x.Common.DownloadUserAgent != "" {
x.ExpertAddition.DownloadUserAgent = x.Common.DownloadUserAgent
op.MustSaveDriverStorage(x)
}
x.XunLeiBrowserCommon.UseVideoUrl = x.UseVideoUrl
x.ExpertAddition.RootFolderID = x.RootFolderID
Expand Down Expand Up @@ -488,7 +503,8 @@ func (xc *XunLeiBrowserCommon) Remove(ctx context.Context, obj model.Obj) error
}
}

if xc.RemoveWay == "delete" && obj.GetPath() == ThunderDriveFileID {
// 先判断是否是特殊情况
if obj.GetPath() == ThunderDriveFileID {
_, err := xc.Request(FILE_API_URL+"/{fileID}/trash", http.MethodPatch, func(r *resty.Request) {
r.SetContext(ctx)
r.SetPathParam("fileID", obj.GetID())
Expand All @@ -503,12 +519,20 @@ func (xc *XunLeiBrowserCommon) Remove(ctx context.Context, obj model.Obj) error
return err
}

_, err := xc.Request(FILE_API_URL+":batchTrash", http.MethodPost, func(r *resty.Request) {
r.SetContext(ctx)
r.SetBody(&js)
}, nil)
return err

// 根据用户选择的删除方式进行删除
if xc.RemoveWay == "delete" {
_, err := xc.Request(FILE_API_URL+":batchDelete", http.MethodPost, func(r *resty.Request) {
r.SetContext(ctx)
r.SetBody(&js)
}, nil)
return err
} else {
_, err := xc.Request(FILE_API_URL+":batchTrash", http.MethodPost, func(r *resty.Request) {
r.SetContext(ctx)
r.SetBody(&js)
}, nil)
return err
}
}

func (xc *XunLeiBrowserCommon) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
Expand Down Expand Up @@ -756,7 +780,7 @@ func (xc *XunLeiBrowserCommon) RefreshToken(refreshToken string) (*TokenResp, er
}

if resp.RefreshToken == "" {
return nil, errs.EmptyToken
return nil, errors.New("refresh token is empty")
}
return &resp, nil
}
Expand All @@ -775,7 +799,7 @@ func (xc *XunLeiBrowserCommon) GetSafeAccessToken(safePassword string) (string,
}

if resp.Token == "" {
return "", errs.EmptyToken
return "", errors.New("SafePassword is incorrect ")
}
return resp.Token, nil
}
Expand Down
20 changes: 10 additions & 10 deletions drivers/thunder_browser/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ type ExpertAddition struct {
SignType string `json:"sign_type" type:"select" options:"algorithms,captcha_sign" default:"algorithms"`

// 登录方式1
Username string `json:"username" required:"true" help:"login type is user,this is required"`
Password string `json:"password" required:"true" help:"login type is user,this is required"`
SafePassword string `json:"safe_password" required:"false" help:"login type is user,this is required"` // 超级保险箱密码
Username string `json:"username" required:"true" help:"login type is user,this is required"`
Password string `json:"password" required:"true" help:"login type is user,this is required"`
// 登录方式2
RefreshToken string `json:"refresh_token" required:"true" help:"login type is refresh_token,this is required"`

SafePassword string `json:"safe_password" required:"true" help:"super safe password"` // 超级保险箱密码

// 签名方法1
Algorithms string `json:"algorithms" required:"true" help:"sign type is algorithms,this is required" default:"x+I5XiTByg,6QU1x5DqGAV3JKg6h,VI1vL1WXr7st0es,n+/3yhlrnKs4ewhLgZhZ5ITpt554,UOip2PE7BLIEov/ZX6VOnsz,Q70h9lpViNCOC8sGVkar9o22LhBTjfP,IVHFuB1JcMlaZHnW,bKE,HZRbwxOiQx+diNopi6Nu,fwyasXgYL3rP314331b,LWxXAiSW4,UlWIjv1HGrC6Ngmt4Nohx,FOa+Lc0bxTDpTwIh2,0+RY,xmRVMqokHHpvsiH0"`
Algorithms string `json:"algorithms" required:"true" help:"sign type is algorithms,this is required" default:"p+ExqPV,LwdwKlprzv7cQBQmxN5,vc08P1NwUBnbGsl58LzTW,VVNeXaXmZ8HH1SJEnp6YpVFSFU,pNAOJ,CNChvyDehAmUR1TDodfOusBAx,MS98NnX4Np8nxvEh6Ulv+SMMKMzKvD34C7lGWbb,9MpFF21GnVOYku0NM9Y/hzsK471UCUZ2o+,EY1QfeA06fXlw9wZNoZaXEED5zZPvNWI,,sciE,FIPqgQDUUW1e0GkiBFd5w7mCQ,zW,75XFdEO0Gi"`
// 签名方法2
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"`
Expand All @@ -33,15 +34,15 @@ type ExpertAddition struct {
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:"ZUBzD9J_XPXfn7f7"`
ClientSecret string `json:"client_secret" required:"true" default:"yESVmHecEe6F0aou69vl-g"`
ClientVersion string `json:"client_version" required:"true" default:"1.0.7.1938"`
ClientVersion string `json:"client_version" required:"true" default:"1.0.8.2215"`
PackageName string `json:"package_name" required:"true" default:"com.xunlei.browser"`

// 不影响登录,影响下载速度
UserAgent string `json:"user_agent" required:"true" default:"ANDROID-com.xunlei.browser/1.0.7.1938 netWorkType/5G appid/22062 deviceName/Xiaomi_M2004j7ac deviceModel/M2004J7AC OSVersion/12 protocolVersion/301 platformVersion/10 sdkVersion/233100 Oauth2Client/0.9 (Linux 4_14_186-perf-gddfs8vbb238b) (JAVA 0)"`
DownloadUserAgent string `json:"download_user_agent" required:"true" default:"AndroidDownloadManager/12 (Linux; U; Android 12; M2004J7AC Build/SP1A.210812.016)"`
UserAgent string `json:"user_agent" required:"false" default:""`
DownloadUserAgent string `json:"download_user_agent" required:"false" default:""`

// 优先使用视频链接代替下载链接
UseVideoUrl bool `json:"use_video_url"`
Expand Down Expand Up @@ -76,7 +77,7 @@ type Addition struct {
driver.RootID
Username string `json:"username" required:"true"`
Password string `json:"password" required:"true"`
SafePassword string `json:"safe_password" required:"false"` // 超级保险箱密码
SafePassword string `json:"safe_password" required:"true"` // 超级保险箱密码
CaptchaToken string `json:"captcha_token"`
UseVideoUrl bool `json:"use_video_url" default:"false"`
RemoveWay string `json:"remove_way" required:"true" type:"select" options:"trash,delete"`
Expand All @@ -90,7 +91,6 @@ func (i *Addition) GetIdentity() string {
var config = driver.Config{
Name: "ThunderBrowser",
LocalSort: true,
OnlyProxy: true,
}

var configExpert = driver.Config{
Expand Down
69 changes: 69 additions & 0 deletions drivers/thunder_browser/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"io"
"net/http"
"regexp"
"strings"
"time"

"github.com/alist-org/alist/v3/drivers/base"
Expand All @@ -21,6 +22,32 @@ const (
XLUSER_API_URL = "https://xluser-ssl.xunlei.com/v1"
)

var Algorithms = []string{
"p+ExqPV",
"LwdwKlprzv7cQBQmxN5",
"vc08P1NwUBnbGsl58LzTW",
"VVNeXaXmZ8HH1SJEnp6YpVFSFU",
"pNAOJ",
"CNChvyDehAmUR1TDodfOusBAx",
"MS98NnX4Np8nxvEh6Ulv+SMMKMzKvD34C7lGWbb",
"9MpFF21GnVOYku0NM9Y/hzsK471UCUZ2o+",
"EY1QfeA06fXlw9wZNoZaXEED5zZPvNWI",
"",
"sciE",
"FIPqgQDUUW1e0GkiBFd5w7mCQ",
"zW",
"75XFdEO0Gi",
}

const (
ClientID = "ZUBzD9J_XPXfn7f7"
ClientSecret = "yESVmHecEe6F0aou69vl-g"
ClientVersion = "1.0.8.2215"
PackageName = "com.xunlei.browser"
DownloadUserAgent = "AndroidDownloadManager/13 (Linux; U; Android 13; M2004J7AC Build/SP1A.210812.016)"
SdkVersion = "2.0.3.262"
)

const (
FOLDER = "drive#folder"
FILE = "drive#file"
Expand Down Expand Up @@ -74,6 +101,10 @@ type Common struct {
refreshCTokenCk func(token string)
}

func (c *Common) SetDeviceID(deviceID string) {
c.DeviceID = deviceID
}

func (c *Common) SetCaptchaToken(captchaToken string) {
c.captchaToken = captchaToken
}
Expand Down Expand Up @@ -247,3 +278,41 @@ func EncryptPassword(password string) string {
// 将哈希值转换为十六进制字符串
return hex.EncodeToString(hash[:])
}

func generateDeviceSign(deviceID, packageName string) string {

signatureBase := fmt.Sprintf("%s%s%s%s", deviceID, packageName, "22062", "a5d7416858147a4ab99573872ffccef8")

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, appName, sdkVersion, clientVersion, packageName string) string {
//deviceSign := generateDeviceSign(deviceID, packageName)
var sb strings.Builder

sb.WriteString(fmt.Sprintf("ANDROID-%s/%s ", appName, clientVersion))
sb.WriteString("networkType/WIFI ")
sb.WriteString(fmt.Sprintf("appid/%s ", "22062"))
sb.WriteString(fmt.Sprintf("deviceName/Xiaomi_M2004j7ac "))
sb.WriteString(fmt.Sprintf("deviceModel/M2004J7AC "))
sb.WriteString(fmt.Sprintf("OSVersion/13 "))
sb.WriteString(fmt.Sprintf("protocolVersion/301 "))
sb.WriteString(fmt.Sprintf("platformversion/10 "))
sb.WriteString(fmt.Sprintf("sdkVersion/%s ", sdkVersion))
sb.WriteString(fmt.Sprintf("Oauth2Client/0.9 (Linux 4_9_337-perf-sn-uotan-gd9d488809c3d) (JAVA 0) "))
return sb.String()
}
Loading