From a71a7b66f82020c7787724f36d9fe8c4401e5061 Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Tue, 21 Oct 2025 17:00:37 +0800 Subject: [PATCH] opt req Signed-off-by: bggRGjQaUbCoE --- lib/http/member.dart | 19 ++++-- lib/http/search.dart | 10 ++- lib/pages/search_panel/controller.dart | 17 ++++- lib/utils/request_utils.dart | 90 +++++++++++++++++--------- 4 files changed, 99 insertions(+), 37 deletions(-) diff --git a/lib/http/member.dart b/lib/http/member.dart index 808770de..3cc8fbf0 100644 --- a/lib/http/member.dart +++ b/lib/http/member.dart @@ -1,4 +1,3 @@ -import 'dart:convert'; import 'dart:io'; import 'package:PiliPlus/common/constants.dart'; @@ -405,15 +404,25 @@ class MemberHttp { 'timezone_offset': '-480', 'features': 'itemOpusStyle,listOnlyfans', 'platform': 'web', - 'web_location': '333.999', + 'web_location': '333.1387', 'dm_img_list': '[]', 'dm_img_str': dmImgStr, 'dm_cover_img_str': dmCoverImgStr, 'dm_img_inter': '{"ds":[],"wh":[0,0,0],"of":[0,0,0]}', - 'x-bili-device-req-json': jsonEncode({"platform": "web", "device": "pc"}), - 'x-bili-web-req-json': jsonEncode({"spm_id": "333.999"}), + 'x-bili-device-req-json': + '{"platform":"web","device":"pc","spmid":"333.1387"}', }); - var res = await Request().get(Api.memberDynamic, queryParameters: params); + var res = await Request().get( + Api.memberDynamic, + queryParameters: params, + options: Options( + headers: { + 'user-agent': UaType.pc.ua, + 'origin': 'https://space.bilibili.com', + 'referer': 'https://space.bilibili.com/$mid/dynamic', + }, + ), + ); if (res.data['code'] == 0) { try { DynamicsDataModel data = DynamicsDataModel.fromJson(res.data['data']); diff --git a/lib/http/search.dart b/lib/http/search.dart index 5c2f9f60..ddacc36e 100644 --- a/lib/http/search.dart +++ b/lib/http/search.dart @@ -12,6 +12,7 @@ import 'package:PiliPlus/models_new/pgc/pgc_info_model/result.dart'; import 'package:PiliPlus/models_new/search/search_rcmd/data.dart'; import 'package:PiliPlus/models_new/search/search_trending/data.dart'; import 'package:PiliPlus/utils/extension.dart'; +import 'package:PiliPlus/utils/request_utils.dart'; import 'package:PiliPlus/utils/wbi_sign.dart'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; @@ -56,6 +57,8 @@ class SearchHttp { int? pubBegin, int? pubEnd, required String qvId, + String? gaiaVtoken, + required ValueChanged onSuccess, }) async { var params = await WbiSign.makSign({ 'search_type': searchType.name, @@ -78,15 +81,16 @@ class SearchHttp { 'from_spmid': 333.337, 'platform': 'pc', 'source_tag': 3, - 'gaia_vtoken': '', 'qv_id': qvId, 'web_location': 1430654, + 'gaia_vtoken': ?gaiaVtoken, }); var res = await Request().get( Api.searchByType, queryParameters: params, options: Options( headers: { + if (gaiaVtoken != null) 'cookie': 'x-bili-gaia-vtoken=$gaiaVtoken', 'user-agent': UaType.pc.ua, 'origin': 'https://search.bilibili.com', 'referer': @@ -98,7 +102,9 @@ class SearchHttp { if (resData is Map) { if (resData['code'] == 0) { final Map dataData = resData['data']; - if (dataData.containsKey('v_voucher')) { + final vVoucher = dataData['v_voucher']; + if (vVoucher != null) { + RequestUtils.validate(vVoucher, onSuccess); return const Error('触发风控'); } dynamic data; diff --git a/lib/pages/search_panel/controller.dart b/lib/pages/search_panel/controller.dart index 5deca3bb..4fe5eebf 100644 --- a/lib/pages/search_panel/controller.dart +++ b/lib/pages/search_panel/controller.dart @@ -71,12 +71,22 @@ class SearchPanelController, T> @override List? getDataList(R response) { - searchResultController?.count[searchType.index] = response.numResults ?? 0; return response.list; } + @override + bool customHandleResponse(bool isRefresh, Success response) { + if (isRefresh) { + searchResultController?.count[searchType.index] = + response.response.numResults ?? 0; + } + return false; + } + final qvId = Utils.generateRandomString(32); + String? gaiaVtoken; + @override Future> customGetData() => SearchHttp.searchByType( searchType: searchType, @@ -91,6 +101,11 @@ class SearchPanelController, T> pubBegin: pubBegin, pubEnd: pubEnd, qvId: qvId, + gaiaVtoken: gaiaVtoken, + onSuccess: (String gaiaVtoken) { + this.gaiaVtoken = gaiaVtoken; + queryData(page == 1); + }, ); @override diff --git a/lib/utils/request_utils.dart b/lib/utils/request_utils.dart index e21c7ab5..c66437e8 100644 --- a/lib/utils/request_utils.dart +++ b/lib/utils/request_utils.dart @@ -22,6 +22,7 @@ import 'package:PiliPlus/pages/common/multi_select/multi_select_controller.dart' import 'package:PiliPlus/pages/dynamics_tab/controller.dart'; import 'package:PiliPlus/pages/group_panel/view.dart'; import 'package:PiliPlus/pages/later/controller.dart'; +import 'package:PiliPlus/pages/login/geetest/geetest_webview_dialog.dart'; import 'package:PiliPlus/utils/accounts.dart'; import 'package:PiliPlus/utils/context_ext.dart'; import 'package:PiliPlus/utils/extension.dart'; @@ -484,26 +485,32 @@ abstract class RequestUtils { String vVoucher, ValueChanged onSuccess, ) async { + if (Platform.isLinux) { + return; + } + final res = await ValidateHttp.gaiaVgateRegister(vVoucher); if (!res['status']) { SmartDialog.showToast("${res['msg']}"); return; } - if (res['data'] == null) { + final resData = res['data']; + if (resData == null) { SmartDialog.showToast("null data"); return; } CaptchaDataModel captchaData = CaptchaDataModel(); - String? geeGt = res['data']?['geetest']?['gt']; - String? geeChallenge = res['data']?['geetest']?['challenge']; - captchaData.token = res['data']?['token']; + final geetest = resData?['geetest']; + String? gt = geetest?['gt']; + String? challenge = geetest?['challenge']; + captchaData.token = resData?['token']; bool isGeeArgumentValid() { - return geeGt?.isNotEmpty == true && - geeChallenge?.isNotEmpty == true && + return gt?.isNotEmpty == true && + challenge?.isNotEmpty == true && captchaData.token?.isNotEmpty == true; } @@ -512,9 +519,47 @@ abstract class RequestUtils { return; } + Future gaiaVgateValidate() async { + final res = await ValidateHttp.gaiaVgateValidate( + challenge: captchaData.geetest?.challenge, + seccode: captchaData.seccode, + token: captchaData.token, + validate: captchaData.validate, + ); + if (res['status']) { + if (res['data']?['is_valid'] == 1) { + final griskId = res['data']?['grisk_id']; + if (griskId != null) { + onSuccess(griskId); + } + } else { + SmartDialog.showToast('invalid'); + } + } else { + SmartDialog.showToast(res['msg']); + } + } + + if (Utils.isDesktop) { + final json = await Get.dialog>( + GeetestWebviewDialog(gt!, challenge!), + ); + if (json != null) { + captchaData + ..validate = json['geetest_validate'] + ..seccode = json['geetest_seccode'] + ..geetest = GeetestData( + challenge: json['geetest_challenge'], + gt: gt, + ); + gaiaVgateValidate(); + } + return; + } + var registerData = Gt3RegisterData( - challenge: geeChallenge, - gt: geeGt, + challenge: challenge, + gt: gt, success: true, ); @@ -529,28 +574,15 @@ abstract class RequestUtils { if (code == "1") { // 发送 message["result"] 中的数据向 B 端的业务服务接口进行查询 SmartDialog.showToast('验证成功'); + final result = message['result']; captchaData - ..validate = message['result']?['geetest_validate'] - ..seccode = message['result']?['geetest_seccode']; - String? challenge = message['result']?['geetest_challenge']; - final res = await ValidateHttp.gaiaVgateValidate( - challenge: challenge, - seccode: captchaData.seccode, - token: captchaData.token, - validate: captchaData.validate, - ); - if (res['status']) { - if (res['data']?['is_valid'] == 1) { - final griskId = res['data']?['grisk_id']; - if (griskId != null) { - onSuccess(griskId); - } - } else { - SmartDialog.showToast('invalid'); - } - } else { - SmartDialog.showToast(res['msg']); - } + ..validate = result?['geetest_validate'] + ..seccode = result?['geetest_seccode'] + ..geetest = GeetestData( + challenge: result?['geetest_challenge'], + gt: gt!, + ); + gaiaVgateValidate(); } else { // 终端用户完成验证失败,自动重试 If the verification fails, it will be automatically retried. if (kDebugMode) debugPrint("Captcha result code : $code");