Compare commits

...

11 Commits

Author SHA1 Message Date
dom
22fc256d8a fix #2351
Signed-off-by: dom <githubaccount56556@proton.me>
2026-06-08 11:45:26 +08:00
dom
01a1cb2dce fix #2350
Signed-off-by: dom <githubaccount56556@proton.me>
2026-06-08 10:25:08 +08:00
dom
b4fd362333 fix #2342
Signed-off-by: dom <githubaccount56556@proton.me>
2026-06-08 10:06:08 +08:00
dom
ccc7cd0453 upgrade deps
Signed-off-by: dom <githubaccount56556@proton.me>
2026-06-08 09:50:39 +08:00
My-Responsitories
b67756c152 fix: mob geetest (#2341)
* fix: mob geetest

* geetest ios patch

---------

Co-authored-by: dom <githubaccount56556@proton.me>
2026-06-07 10:54:44 +08:00
dom
3b9403a329 fix #2305
Signed-off-by: dom <githubaccount56556@proton.me>
2026-06-06 12:03:12 +08:00
dom
c44e92dcc8 update patch
Signed-off-by: dom <githubaccount56556@proton.me>
2026-06-06 09:41:52 +08:00
dom
14d1c37df5 flutter 3.44.1
Signed-off-by: dom <githubaccount56556@proton.me>
2026-06-06 09:37:11 +08:00
dom
78b3df4019 validate cookie on login
Signed-off-by: dom <githubaccount56556@proton.me>
2026-06-06 08:55:38 +08:00
dom
9acb32aaeb opt logout main
Signed-off-by: dom <githubaccount56556@proton.me>
2026-06-06 08:54:38 +08:00
dom
50070997de fix #2308
Signed-off-by: dom <githubaccount56556@proton.me>
2026-06-05 20:36:39 +08:00
22 changed files with 367 additions and 357 deletions

2
.fvmrc
View File

@@ -1,3 +1,3 @@
{
"flutter": "3.44.0"
"flutter": "3.44.1"
}

View File

@@ -81,7 +81,6 @@ jobs:
- name: Apply Patch
shell: pwsh
run: lib/scripts/patch.ps1 android
continue-on-error: true
- name: Write key
if: github.event_name == 'workflow_dispatch'

View File

@@ -33,7 +33,6 @@ jobs:
- name: Apply Patch
shell: pwsh
run: lib/scripts/patch.ps1 iOS
continue-on-error: true
- name: Build iOS
run: |

View File

@@ -54,7 +54,6 @@ jobs:
- name: Apply Patch
shell: pwsh
run: lib/scripts/patch.ps1 Linux
continue-on-error: true
#TODO: deb and rpm packages need to be build
- name: Build Linux

View File

@@ -33,7 +33,6 @@ jobs:
- name: Apply Patch
shell: pwsh
run: lib/scripts/patch.ps1 macOS
continue-on-error: true
- name: Build Mac
run: flutter build macos --release --dart-define-from-file=pili_release.json

View File

@@ -29,7 +29,6 @@ jobs:
- name: Apply Patch
shell: pwsh
run: lib/scripts/patch.ps1 windows
continue-on-error: true
- name: Add fastforge and Inno Setup
run: |

View File

@@ -2,7 +2,7 @@ import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:flutter/material.dart';
class CustomToast extends StatelessWidget {
const CustomToast({super.key, required this.msg});
const CustomToast(this.msg, {super.key});
final String msg;
@@ -12,13 +12,13 @@ class CustomToast extends StatelessWidget {
Widget build(BuildContext context) {
final colorScheme = ColorScheme.of(context);
return Container(
margin: EdgeInsets.only(
margin: .only(
bottom: MediaQuery.viewPaddingOf(context).bottom + 30,
),
padding: const EdgeInsets.symmetric(horizontal: 17, vertical: 10),
padding: const .symmetric(horizontal: 17, vertical: 10),
decoration: BoxDecoration(
color: colorScheme.primaryContainer.withValues(alpha: toastOpacity),
borderRadius: const BorderRadius.all(Radius.circular(20)),
borderRadius: const .all(.circular(20)),
),
child: Text(
msg,
@@ -32,7 +32,7 @@ class CustomToast extends StatelessWidget {
}
class LoadingWidget extends StatelessWidget {
const LoadingWidget({super.key, required this.msg});
const LoadingWidget(this.msg, {super.key});
///loading msg
final String msg;
@@ -42,14 +42,14 @@ class LoadingWidget extends StatelessWidget {
final theme = Theme.of(context);
final onSurfaceVariant = theme.colorScheme.onSurfaceVariant;
return Container(
padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 20),
padding: const .symmetric(horizontal: 30, vertical: 20),
decoration: BoxDecoration(
color: theme.dialogTheme.backgroundColor,
borderRadius: const BorderRadius.all(Radius.circular(15)),
borderRadius: const .all(.circular(15)),
),
child: Column(
spacing: 20,
mainAxisSize: MainAxisSize.min,
mainAxisSize: .min,
children: [
//loading animation
CircularProgressIndicator(
@@ -63,3 +63,34 @@ class LoadingWidget extends StatelessWidget {
);
}
}
class NotifyWarning extends StatelessWidget {
const NotifyWarning(this.msg, {super.key});
final String msg;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final onSurfaceVariant = theme.colorScheme.onSurfaceVariant;
return Container(
decoration: BoxDecoration(
borderRadius: const .all(.circular(8)),
color: theme.dialogTheme.backgroundColor,
),
padding: const .symmetric(horizontal: 20, vertical: 10),
child: Column(
spacing: 5,
mainAxisSize: .min,
children: [
Icon(
Icons.warning_amber_rounded,
size: 22,
color: onSurfaceVariant,
),
Text(msg, style: TextStyle(color: onSurfaceVariant)),
],
),
);
}
}

View File

@@ -278,8 +278,11 @@ class MyApp extends StatelessWidget {
getPages: Routes.getPages,
defaultTransition: Pref.pageTransition,
builder: FlutterSmartDialog.init(
toastBuilder: (msg) => CustomToast(msg: msg),
loadingBuilder: (msg) => LoadingWidget(msg: msg),
toastBuilder: CustomToast.new,
loadingBuilder: LoadingWidget.new,
notifyStyle: const FlutterSmartNotifyStyle(
warningBuilder: NotifyWarning.new,
),
builder: _builder,
),
navigatorObservers: [

View File

@@ -19,7 +19,6 @@ import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:gt3_flutter_plugin/gt3_flutter_plugin.dart';
class LoginPageController extends GetxController
with GetSingleTickerProviderStateMixin {
@@ -34,8 +33,6 @@ class LoginPageController extends GetxController
late final TabController tabController;
late final Gt3FlutterPlugin captcha = Gt3FlutterPlugin();
late final CaptchaDataModel captchaData = CaptchaDataModel();
late final RxInt qrCodeLeftTime = 180.obs;
late final RxString statusQRCode = ''.obs;
@@ -125,115 +122,33 @@ class LoginPageController extends GetxController
String geeChallenge,
VoidCallback onSuccess,
) {
void updateCaptchaData(Map json) {
captchaData
..validate = json['geetest_validate']
..seccode = json['geetest_seccode']
..geetest = GeetestData(
challenge: json['geetest_challenge'],
gt: geeGt,
);
SmartDialog.showToast('验证成功');
onSuccess();
}
GeetestWebviewDialog.geetest(geeGt, geeChallenge).then((res) {
if (res is Map) {
captchaData
..validate = res['geetest_validate']
..seccode = res['geetest_seccode']
..geetest = GeetestData(
challenge: res['geetest_challenge'],
gt: geeGt,
);
SmartDialog.showToast('验证成功');
onSuccess();
}
});
}
if (PlatformUtils.isDesktop) {
showDialog<Map<String, dynamic>>(
context: Get.context!,
builder: (context) => GeetestWebviewDialog(geeGt, geeChallenge),
).then((res) {
if (res != null) {
updateCaptchaData(res);
}
});
} else {
final registerData = Gt3RegisterData(
challenge: geeChallenge,
gt: geeGt,
success: true,
);
captcha
..addEventHandler(
onShow: (Map<String, dynamic> message) {},
onClose: (Map<String, dynamic> message) {
SmartDialog.showToast('关闭验证');
},
onResult: (Map<String, dynamic> message) {
if (kDebugMode) debugPrint("Captcha result: $message");
final String code = message["code"];
if (code == "1") {
// 发送 message["result"] 中的数据向 B 端的业务服务接口进行查询
updateCaptchaData(message['result']);
} else {
// 终端用户完成验证失败,自动重试 If the verification fails, it will be automatically retried.
if (kDebugMode) debugPrint("Captcha result code : $code");
}
},
onError: (Map<String, dynamic> message) {
SmartDialog.showToast("Captcha onError: $message");
String code = message["code"];
// 处理验证中返回的错误 Handling errors returned in verification
if (Platform.isAndroid) {
// Android 平台
if (code == "-2") {
// Dart 调用异常 Call exception
} else if (code == "-1") {
// Gt3RegisterData 参数不合法 Parameter is invalid
} else if (code == "201") {
// 网络无法访问 Network inaccessible
} else if (code == "202") {
// Json 解析错误 Analysis error
} else if (code == "204") {
// WebView 加载超时,请检查是否混淆极验 SDK Load timed out
} else if (code == "204_1") {
// WebView 加载前端页面错误,请查看日志 Error loading front-end page, please check the log
} else if (code == "204_2") {
// WebView 加载 SSLError
} else if (code == "206") {
// gettype 接口错误或返回为 null API error or return null
} else if (code == "207") {
// getphp 接口错误或返回为 null API error or return null
} else if (code == "208") {
// ajax 接口错误或返回为 null API error or return null
} else {
// 更多错误码参考开发文档 More error codes refer to the development document
// https://docs.geetest.com/sensebot/apirefer/errorcode/android
}
}
if (Platform.isIOS) {
// iOS 平台
if (code == "-1009") {
// 网络无法访问 Network inaccessible
} else if (code == "-1004") {
// 无法查找到 HOST Unable to find HOST
} else if (code == "-1002") {
// 非法的 URL Illegal URL
} else if (code == "-1001") {
// 网络超时 Network timeout
} else if (code == "-999") {
// 请求被意外中断, 一般由用户进行取消操作导致 The interrupted request was usually caused by the user cancelling the operation
} else if (code == "-21") {
// 使用了重复的 challenge Duplicate challenges are used
// 检查获取 challenge 是否进行了缓存 Check if the fetch challenge is cached
} else if (code == "-20") {
// 尝试过多, 重新引导用户触发验证即可 Try too many times, lead the user to request verification again
} else if (code == "-10") {
// 预判断时被封禁, 不会再进行图形验证 Banned during pre-judgment, and no more image captcha verification
} else if (code == "-2") {
// Dart 调用异常 Call exception
} else if (code == "-1") {
// Gt3RegisterData 参数不合法 Parameter is invalid
} else {
// 更多错误码参考开发文档 More error codes refer to the development document
// https://docs.geetest.com/sensebot/apirefer/errorcode/ios
}
}
},
)
..startCaptcha(registerData);
}
static String validateCookie(String cookie) {
return cookie
.split(';')
.where((e) {
try {
Cookie.fromSetCookieValue(e.trim());
} catch (_) {
return false;
}
return true;
})
.join(';');
}
// cookie登录
@@ -247,7 +162,7 @@ class LoginPageController extends GetxController
"/x/member/web/account",
options: Options(
headers: {
"cookie": cookieTextController.text,
"cookie": validateCookie(cookieTextController.text),
},
extra: {'account': AnonymousAccount()},
),

View File

@@ -1,5 +1,5 @@
import 'dart:convert' show jsonDecode, jsonEncode;
import 'dart:io' show Platform, Directory, File;
import 'dart:convert' show base64, jsonDecode, jsonEncode, utf8;
import 'dart:io' show Platform;
import 'package:PiliPlus/http/browser_ua.dart';
import 'package:PiliPlus/http/init.dart';
@@ -20,6 +20,13 @@ class GeetestWebviewDialog extends StatefulWidget {
@override
State<GeetestWebviewDialog> createState() => _GeetestWebviewDialogState();
static Future geetest(String gt, String challenge) {
return showDialog(
context: Get.context!,
builder: (context) => GeetestWebviewDialog(gt, challenge),
);
}
}
class _GeetestWebviewDialogState extends State<GeetestWebviewDialog> {
@@ -30,6 +37,9 @@ class _GeetestWebviewDialogState extends State<GeetestWebviewDialog> {
Webview? _linuxWebview;
late bool _linuxWebviewLoading = true;
String _showJs(String response) =>
't=Geetest($response).onSuccess(()=>R("success",t.getValidate())).onError(o=>R("error",o)).onClose(o=>R("close",o));t.onReady(()=>t.verify())';
@override
void initState() {
super.initState();
@@ -122,6 +132,8 @@ class _GeetestWebviewDialogState extends State<GeetestWebviewDialog> {
}
} else if (msgStr.startsWith("error:")) {
debugPrint('geetest error: $msgStr');
} else if (msgStr.startsWith('close:')) {
Get.back();
}
});
@@ -136,27 +148,15 @@ class _GeetestWebviewDialogState extends State<GeetestWebviewDialog> {
<!DOCTYPE html><html><head></head><body>
<script src="$_geetestJsUri"></script>
<script>
function R(n,o){
window.webkit.messageHandlers.msgToNative.postMessage(n + ':' + JSON.stringify(o));
}
let t=Geetest($response).onSuccess(()=>R("success",t.getValidate())).onError((o)=>R("error",o));
t.onReady(()=>t.verify());
R=(n,o)=>webkit.messageHandlers.msgToNative.postMessage(n+':'+JSON.stringify(o))
${_showJs(response)}
</script>
</body></html>
''';
final tempDir = Directory.systemTemp;
final file = File(
'${tempDir.path}/geetest_${DateTime.now().millisecondsSinceEpoch}.html',
_linuxWebview!.launch(
'data:text/html;base64,${base64.encode(utf8.encode(html))}',
);
await file.writeAsString(html);
if (!mounted) {
_closeLinuxWebview();
return;
}
_linuxWebview!.launch('file://${file.path}');
if (mounted) {
setState(() {
@@ -205,7 +205,7 @@ class _GeetestWebviewDialogState extends State<GeetestWebviewDialog> {
return AlertDialog(
title: const Text('验证码'),
content: SizedBox(
width: 300,
width: 320,
height: 400,
child: InAppWebView(
webViewEnvironment: webViewEnvironment,
@@ -217,11 +217,31 @@ class _GeetestWebviewDialogState extends State<GeetestWebviewDialog> {
algorithmicDarkeningAllowed: true,
useShouldOverrideUrlLoading: true,
userAgent: BrowserUa.mob,
mixedContentMode: MixedContentMode.MIXED_CONTENT_ALWAYS_ALLOW,
mixedContentMode: .MIXED_CONTENT_ALWAYS_ALLOW,
incognito: true,
allowFileAccess: false,
allowsLinkPreview: false,
allowContentAccess: false,
useOnDownloadStart: false,
geolocationEnabled: false,
thirdPartyCookiesEnabled: false,
enterpriseAuthenticationAppLinkPolicyEnabled: false,
saveFormData: false,
safeBrowsingEnabled: false,
isFraudulentWebsiteWarningEnabled: false,
domStorageEnabled: false,
databaseEnabled: false,
cacheEnabled: false,
cacheMode: .LOAD_NO_CACHE,
horizontalScrollBarEnabled: false,
verticalScrollBarEnabled: false,
overScrollMode: .NEVER,
),
initialData: InAppWebViewInitialData(
data:
'<!DOCTYPE html><html><head></head><body><script src="$_geetestJsUri"></script><script>function R(n,o){flutter_inappwebview.callHandler(n,o)}</script></body></html>',
'<!DOCTYPE html><html><head><meta name="viewport" content="width=device-width"></head><body><script src="$_geetestJsUri"></script><script>R=flutter_inappwebview.callHandler</script></body></html>',
),
onWebViewCreated: (ctr) {
ctr
@@ -242,16 +262,17 @@ class _GeetestWebviewDialogState extends State<GeetestWebviewDialog> {
callback: (args) {
debugPrint('geetest error: $args');
},
)
..addJavaScriptHandler(
handlerName: 'close',
callback: (args) => Get.back(),
);
},
onLoadStop: (ctr, _) async {
final config = await _future;
if (!mounted) return;
if (config case Success(:final response)) {
ctr.evaluateJavascript(
source:
'let t=Geetest($response).onSuccess(()=>R("success",t.getValidate())).onError((o)=>R("error",o));t.onReady(()=>t.verify());',
);
ctr.evaluateJavascript(source: _showJs(response));
} else {
config.toast();
Get.back();

View File

@@ -11,7 +11,6 @@ import 'package:PiliPlus/services/account_service.dart';
import 'package:PiliPlus/utils/accounts.dart';
import 'package:PiliPlus/utils/accounts/account.dart';
import 'package:PiliPlus/utils/extension/scroll_controller_ext.dart';
import 'package:PiliPlus/utils/login_utils.dart';
import 'package:PiliPlus/utils/storage.dart';
import 'package:PiliPlus/utils/storage_key.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
@@ -112,20 +111,22 @@ class MineController extends CommonDataController<FavFolderData, FavFolderData>
..face.value = response.face!
..isLogin.value = true;
} else {
LoginUtils.onLogoutMain();
_onLogoutMain();
return;
}
} else {
final errMsg = res.toString();
SmartDialog.showToast(errMsg);
if (errMsg == '账号未登录') {
LoginUtils.onLogoutMain();
_onLogoutMain();
return;
}
}
queryUserStatOwner();
}
void _onLogoutMain() => Accounts.deleteAll({Accounts.main});
Future<void> queryUserStatOwner() async {
final res = await UserHttp.userStatOwner();
if (res case Success(:final response)) {

View File

@@ -1,5 +1,4 @@
import 'package:PiliPlus/models/common/account_type.dart';
import 'package:PiliPlus/pages/login/controller.dart';
import 'package:PiliPlus/pages/setting/models/model.dart';
import 'package:PiliPlus/utils/accounts.dart';
import 'package:PiliPlus/utils/accounts/api_type.dart';
@@ -20,14 +19,6 @@ List<SettingsModel> get privacySettings => [
subtitle: '已拉黑用户',
leading: const Icon(Icons.block),
),
NormalModel(
onTap: (context, setState) {
LoginPageController.switchAccountDialog(context);
},
leading: const Icon(Icons.switch_account_outlined),
title: '切换账号',
subtitle: '播放进度信息跟随视频取流',
),
NormalModel(
onTap: (context, setState) {
showDialog(

View File

@@ -47,7 +47,7 @@ class _SettingPageState extends State<SettingPage> {
static const List<_SettingsModel> _items = [
_SettingsModel(
type: SettingType.privacySetting,
subtitle: '黑名单、无痕模式',
subtitle: '黑名单',
icon: Icon(Icons.privacy_tip_outlined),
),
_SettingsModel(
@@ -190,7 +190,7 @@ class _SettingPageState extends State<SettingPage> {
ListTile(
onTap: () => LoginPageController.switchAccountDialog(context),
leading: const Icon(Icons.switch_account_outlined),
title: Text('设置账号模式', style: titleStyle),
title: Text('切换账号', style: titleStyle),
),
Obx(
() => _noAccount.value

View File

@@ -915,16 +915,16 @@ class ReplyItemGrpc extends StatelessWidget {
},
);
if (urlKeys.isNotEmpty) {
List<String> unmatchedItems = urlKeys
.where((url) => !matchedUrls.contains(url))
.toList();
if (unmatchedItems.isNotEmpty) {
for (final patternStr in unmatchedItems) {
addUrl(patternStr, content.urls[patternStr]!);
}
}
}
// if (urlKeys.isNotEmpty) {
// List<String> unmatchedItems = urlKeys
// .where((url) => !matchedUrls.contains(url))
// .toList();
// if (unmatchedItems.isNotEmpty) {
// for (final patternStr in unmatchedItems) {
// addUrl(patternStr, content.urls[patternStr]!);
// }
// }
// }
if (!hasNote && replyControl.isNote && replyControl.isNoteV2) {
final Color color;

View File

@@ -9,7 +9,7 @@ index 58ba68b7c..a6bb398ac 100644
-import 'package:flutter/gestures.dart' show HorizontalDragGestureRecognizer;
+import 'package:flutter/gestures.dart'
+ show HorizontalDragGestureRecognizer, DeviceGestureSettings;
import 'package:flutter/material.dart' ;
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -142,6 +143,10 @@ class SlideDragGestureRecognizer extends HorizontalDragGestureRecognizer {

View File

@@ -0,0 +1,146 @@
diff --git a/lib/pages/login/geetest/geetest_plugin.dart b/lib/pages/login/geetest/geetest_plugin.dart
new file mode 100644
index 000000000..2823c2188
--- /dev/null
+++ b/lib/pages/login/geetest/geetest_plugin.dart
@@ -0,0 +1,110 @@
+import 'dart:async' show Completer;
+import 'dart:io' show Platform;
+
+import 'package:flutter/foundation.dart' show kDebugMode, debugPrint;
+import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
+import 'package:gt3_flutter_plugin/gt3_flutter_plugin.dart';
+
+abstract final class GeetestPlugin {
+ static Future geetest(String gt, String challenge) {
+ final completer = Completer();
+ void complete([result]) {
+ if (!completer.isCompleted) {
+ completer.complete(result);
+ }
+ }
+
+ final registerData = Gt3RegisterData(
+ challenge: challenge,
+ gt: gt,
+ success: true,
+ );
+
+ Gt3FlutterPlugin()
+ ..addEventHandler(
+ onShow: (Map<String, dynamic> message) {},
+ onClose: (Map<String, dynamic> message) {
+ SmartDialog.showToast('关闭验证');
+ complete();
+ },
+ onResult: (Map<String, dynamic> message) {
+ if (kDebugMode) debugPrint("Captcha result: $message");
+ final String code = message["code"];
+ if (code == "1") {
+ // 发送 message["result"] 中的数据向 B 端的业务服务接口进行查询
+ complete(message['result']);
+ return;
+ } else {
+ // 终端用户完成验证失败,自动重试 If the verification fails, it will be automatically retried.
+ if (kDebugMode) debugPrint("Captcha result code : $code");
+ }
+ complete();
+ },
+ onError: (Map<String, dynamic> message) {
+ SmartDialog.showToast("Captcha onError: $message");
+ String code = message["code"];
+ // 处理验证中返回的错误 Handling errors returned in verification
+ if (Platform.isAndroid) {
+ // Android 平台
+ if (code == "-2") {
+ // Dart 调用异常 Call exception
+ } else if (code == "-1") {
+ // Gt3RegisterData 参数不合法 Parameter is invalid
+ } else if (code == "201") {
+ // 网络无法访问 Network inaccessible
+ } else if (code == "202") {
+ // Json 解析错误 Analysis error
+ } else if (code == "204") {
+ // WebView 加载超时,请检查是否混淆极验 SDK Load timed out
+ } else if (code == "204_1") {
+ // WebView 加载前端页面错误,请查看日志 Error loading front-end page, please check the log
+ } else if (code == "204_2") {
+ // WebView 加载 SSLError
+ } else if (code == "206") {
+ // gettype 接口错误或返回为 null API error or return null
+ } else if (code == "207") {
+ // getphp 接口错误或返回为 null API error or return null
+ } else if (code == "208") {
+ // ajax 接口错误或返回为 null API error or return null
+ } else {
+ // 更多错误码参考开发文档 More error codes refer to the development document
+ // https://docs.geetest.com/sensebot/apirefer/errorcode/android
+ }
+ }
+
+ if (Platform.isIOS) {
+ // iOS 平台
+ if (code == "-1009") {
+ // 网络无法访问 Network inaccessible
+ } else if (code == "-1004") {
+ // 无法查找到 HOST Unable to find HOST
+ } else if (code == "-1002") {
+ // 非法的 URL Illegal URL
+ } else if (code == "-1001") {
+ // 网络超时 Network timeout
+ } else if (code == "-999") {
+ // 请求被意外中断, 一般由用户进行取消操作导致 The interrupted request was usually caused by the user cancelling the operation
+ } else if (code == "-21") {
+ // 使用了重复的 challenge Duplicate challenges are used
+ // 检查获取 challenge 是否进行了缓存 Check if the fetch challenge is cached
+ } else if (code == "-20") {
+ // 尝试过多, 重新引导用户触发验证即可 Try too many times, lead the user to request verification again
+ } else if (code == "-10") {
+ // 预判断时被封禁, 不会再进行图形验证 Banned during pre-judgment, and no more image captcha verification
+ } else if (code == "-2") {
+ // Dart 调用异常 Call exception
+ } else if (code == "-1") {
+ // Gt3RegisterData 参数不合法 Parameter is invalid
+ } else {
+ // 更多错误码参考开发文档 More error codes refer to the development document
+ // https://docs.geetest.com/sensebot/apirefer/errorcode/ios
+ }
+ }
+ complete();
+ },
+ )
+ ..startCaptcha(registerData);
+
+ return completer.future;
+ }
+}
diff --git a/lib/pages/login/geetest/geetest_webview_dialog.dart b/lib/pages/login/geetest/geetest_webview_dialog.dart
index 7a0461170..da032af1a 100644
--- a/lib/pages/login/geetest/geetest_webview_dialog.dart
+++ b/lib/pages/login/geetest/geetest_webview_dialog.dart
@@ -1,3 +1,5 @@
+import 'package:PiliPlus/pages/login/geetest/geetest_plugin.dart';
+
import 'dart:convert' show base64, jsonDecode, jsonEncode, utf8;
import 'dart:io' show Platform;
@@ -22,6 +24,7 @@ class GeetestWebviewDialog extends StatefulWidget {
State<GeetestWebviewDialog> createState() => _GeetestWebviewDialogState();
static Future geetest(String gt, String challenge) {
+ return GeetestPlugin.geetest(gt, challenge);
return showDialog(
context: Get.context!,
builder: (context) => GeetestWebviewDialog(gt, challenge),
diff --git a/pubspec.yaml b/pubspec.yaml
index 1ec95f9f1..e29e474e0 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -34,6 +34,7 @@ dependencies:
sdk: flutter
flutter_localizations:
sdk: flutter
+ gt3_flutter_plugin: ^0.1.0
app_links: ^7.1.1
archive: ^4.0.0

View File

@@ -0,0 +1,13 @@
diff --git a/packages/flutter/lib/src/material/navigation_drawer.dart b/packages/flutter/lib/src/material/navigation_drawer.dart
index 8a16764cb0c..6b8545c3781 100644
--- a/packages/flutter/lib/src/material/navigation_drawer.dart
+++ b/packages/flutter/lib/src/material/navigation_drawer.dart
@@ -410,7 +410,7 @@ class _NavigationDestinationBuilder extends StatelessWidget {
child: _NavigationDestinationSemantics(
child: SizedBox(
height: navigationDrawerTheme.tileHeight ?? defaults.tileHeight,
- child: inkWell,
+ child: Material(type: MaterialType.transparency, child: inkWell),
),
),
);

View File

@@ -26,6 +26,9 @@ $ImageAnimPatch = "lib/scripts/image_anim.patch"
$LayoutBuilderPatch = "lib/scripts/layout_builder.patch"
# https://github.com/bggRGjQaUbCoE/PiliPlus/issues/2308
$NavigationDrawerPatch = "lib/scripts/navigation_drawer.patch"
# TODO: remove
# https://github.com/flutter/flutter/issues/90223
$ModalBarrierPatch = "lib/scripts/modal_barrier.patch"
@@ -34,11 +37,17 @@ $ModalBarrierPatch = "lib/scripts/modal_barrier.patch"
# https://github.com/flutter/flutter/issues/182466
$MouseCursorPatch = "lib/scripts/mouse_cursor.patch"
$GeetestIOSPatch = "lib/scripts/geetest_ios.patch"
if ($platform.ToLower() -eq "ios") {
git apply $BottomSheetIOSPiliPlusPatch
if ($LASTEXITCODE -eq 0) {
Write-Host "$BottomSheetIOSPiliPlusPatch applied"
}
git apply $GeetestIOSPatch
if ($LASTEXITCODE -eq 0) {
Write-Host "$GeetestIOSPatch applied"
}
}
Set-Location $env:FLUTTER_ROOT
@@ -46,7 +55,7 @@ Set-Location $env:FLUTTER_ROOT
$picks = @()
$reverts = @()
$patches = @($ModalBarrierPatch, $TextSelectionPatch, $MouseCursorPatch,
$ImageAnimPatch, $LayoutBuilderPatch)
$ImageAnimPatch, $LayoutBuilderPatch, $NavigationDrawerPatch)
switch ($platform.ToLower()) {
"android" {
@@ -103,12 +112,7 @@ foreach ($patch in $patches) {
# TODO: remove
if ($platform.ToLower() -eq "android") {
git stash
git cherry-pick 625275cfae17b27c9049b0740a9ef67d626b3b1c -X ours
git reset --soft HEAD~1
git stash pop
git restore DEPS
"f84bd039a0692e5cab5383a8de29bc41151a4dfd" | Set-Content -Path .\bin\internal\engine.version
"df67bb3b55323961184ae7117cc91c054f36a42c" | Set-Content -Path .\bin\internal\engine.version
Remove-Item -Path ".\bin\cache" -Recurse -Force
flutter --version
}

View File

@@ -67,11 +67,16 @@ abstract final class LoginUtils {
}
} else {
// 获取用户信息失败
await Accounts.deleteAll({account});
SmartDialog.showNotify(
msg: '登录失败请检查cookie是否正确${res.toString()}',
notifyType: NotifyType.warning,
);
final errMsg = res.toString();
if (errMsg == '账号未登录') {
await Accounts.deleteAll({account});
SmartDialog.showNotify(
msg: '登录失败请检查cookie是否正确$errMsg',
notifyType: .warning,
);
} else {
SmartDialog.showToast(errMsg);
}
}
}

View File

@@ -1,6 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
@@ -43,7 +42,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show LengthLimitingTextInputFormatter;
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:gt3_flutter_plugin/gt3_flutter_plugin.dart';
abstract final class RequestUtils {
static Future<void> syncHistoryStatus() async {
@@ -574,118 +572,17 @@ abstract final class RequestUtils {
}
}
if (PlatformUtils.isDesktop) {
final json = await showDialog<Map<String, dynamic>>(
context: Get.context!,
builder: (context) => 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;
final json = await GeetestWebviewDialog.geetest(gt!, challenge!);
if (json is Map) {
captchaData
..validate = json['geetest_validate']
..seccode = json['geetest_seccode']
..geetest = GeetestData(
challenge: json['geetest_challenge'],
gt: gt,
);
gaiaVgateValidate();
}
final registerData = Gt3RegisterData(
challenge: challenge,
gt: gt,
success: true,
);
Gt3FlutterPlugin()
..addEventHandler(
onClose: (Map<String, dynamic> message) {
SmartDialog.showToast('关闭验证');
},
onResult: (Map<String, dynamic> message) {
if (kDebugMode) debugPrint("Captcha result: $message");
String code = message["code"];
if (code == "1") {
// 发送 message["result"] 中的数据向 B 端的业务服务接口进行查询
SmartDialog.showToast('验证成功');
final result = message['result'];
captchaData
..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");
}
},
onError: (Map<String, dynamic> message) {
SmartDialog.showToast("Captcha onError: $message");
String code = message["code"];
// 处理验证中返回的错误 Handling errors returned in verification
if (Platform.isAndroid) {
// Android 平台
if (code == "-2") {
// Dart 调用异常 Call exception
} else if (code == "-1") {
// Gt3RegisterData 参数不合法 Parameter is invalid
} else if (code == "201") {
// 网络无法访问 Network inaccessible
} else if (code == "202") {
// Json 解析错误 Analysis error
} else if (code == "204") {
// WebView 加载超时,请检查是否混淆极验 SDK Load timed out
} else if (code == "204_1") {
// WebView 加载前端页面错误,请查看日志 Error loading front-end page, please check the log
} else if (code == "204_2") {
// WebView 加载 SSLError
} else if (code == "206") {
// gettype 接口错误或返回为 null API error or return null
} else if (code == "207") {
// getphp 接口错误或返回为 null API error or return null
} else if (code == "208") {
// ajax 接口错误或返回为 null API error or return null
} else {
// 更多错误码参考开发文档 More error codes refer to the development document
// https://docs.geetest.com/sensebot/apirefer/errorcode/android
}
}
if (Platform.isIOS) {
// iOS 平台
if (code == "-1009") {
// 网络无法访问 Network inaccessible
} else if (code == "-1004") {
// 无法查找到 HOST Unable to find HOST
} else if (code == "-1002") {
// 非法的 URL Illegal URL
} else if (code == "-1001") {
// 网络超时 Network timeout
} else if (code == "-999") {
// 请求被意外中断, 一般由用户进行取消操作导致 The interrupted request was usually caused by the user cancelling the operation
} else if (code == "-21") {
// 使用了重复的 challenge Duplicate challenges are used
// 检查获取 challenge 是否进行了缓存 Check if the fetch challenge is cached
} else if (code == "-20") {
// 尝试过多, 重新引导用户触发验证即可 Try too many times, lead the user to request verification again
} else if (code == "-10") {
// 预判断时被封禁, 不会再进行图形验证 Banned during pre-judgment, and no more image captcha verification
} else if (code == "-2") {
// Dart 调用异常 Call exception
} else if (code == "-1") {
// Gt3RegisterData 参数不合法 Parameter is invalid
} else {
// 更多错误码参考开发文档 More error codes refer to the development document
// https://docs.geetest.com/sensebot/apirefer/errorcode/ios
}
}
},
)
..startCaptcha(registerData);
}
static Future<void> showUserRealName(String mid) async {

View File

@@ -207,7 +207,7 @@ packages:
description:
path: cached_network_image
ref: develop
resolved-ref: "37404435c857ed20ab530a758fd7b1f182b20b0e"
resolved-ref: "5b79ff9f53a9a55b57d4d6fc52eb529fdfdb30d7"
url: "https://github.com/bggRGjQaUbCoE/flutter_cached_network_image_ce.git"
source: git
version: "4.6.4"
@@ -215,26 +215,17 @@ packages:
dependency: transitive
description:
path: cached_network_image_platform_interface
ref: HEAD
resolved-ref: "26bc080bc4464483ddde4e850f8c53dc98b07ac0"
url: "https://github.com/My-Responsitories/flutter_cached_network_image_ce"
ref: "5b79ff9f53a9a55b57d4d6fc52eb529fdfdb30d7"
resolved-ref: "5b79ff9f53a9a55b57d4d6fc52eb529fdfdb30d7"
url: "https://github.com/bggRGjQaUbCoE/flutter_cached_network_image_ce.git"
source: git
version: "5.2.0"
cached_network_image_web_ce:
dependency: transitive
description:
path: cached_network_image_web
ref: HEAD
resolved-ref: "26bc080bc4464483ddde4e850f8c53dc98b07ac0"
url: "https://github.com/My-Responsitories/flutter_cached_network_image_ce"
source: git
version: "2.1.1"
canvas_danmaku:
dependency: "direct main"
description:
path: "."
ref: main
resolved-ref: b442c6c8309a17d8b9d395d08eadc401b42f4f8f
resolved-ref: "697d4516df2fc3ba7417c7ce9aba079d34ba13e5"
url: "https://github.com/bggRGjQaUbCoE/canvas_danmaku.git"
source: git
version: "0.2.6"
@@ -380,10 +371,10 @@ packages:
dependency: transitive
description:
name: dbus
sha256: d0c98dcd4f5169878b6cf8f6e0a52403a9dff371a3e2f019697accbf6f44a270
sha256: "0ce9b0a839e6dee59a37a623d2fc26a35bbbe6404213e419b0d6411023d62645"
url: "https://pub.dev"
source: hosted
version: "0.7.12"
version: "0.7.14"
desktop_webview_window:
dependency: "direct main"
description:
@@ -629,7 +620,7 @@ packages:
description:
path: flutter_inappwebview_android
ref: "v6.1.5"
resolved-ref: "553d323316cc1ef5d1b73077fe42be864e3e096d"
resolved-ref: "0bfa46dfff87f0d9e9d5e13cbd5c4a7c7310f8c9"
url: "https://github.com/bggRGjQaUbCoE/flutter_inappwebview.git"
source: git
version: "1.1.3"
@@ -674,12 +665,13 @@ packages:
source: hosted
version: "1.1.2"
flutter_inappwebview_windows:
dependency: transitive
dependency: "direct overridden"
description:
name: flutter_inappwebview_windows
sha256: "8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055"
url: "https://pub.dev"
source: hosted
path: flutter_inappwebview_windows
ref: "v6.1.5"
resolved-ref: "0bfa46dfff87f0d9e9d5e13cbd5c4a7c7310f8c9"
url: "https://github.com/bggRGjQaUbCoE/flutter_inappwebview.git"
source: git
version: "0.6.0"
flutter_launcher_icons:
dependency: "direct dev"
@@ -796,14 +788,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.2"
gt3_flutter_plugin:
dependency: "direct main"
description:
name: gt3_flutter_plugin
sha256: "9cf4070f3f1811b7aa7a1daebdec5886dbda8e64f932a713dab21d8128d7dad2"
url: "https://pub.dev"
source: hosted
version: "0.1.1"
gtk:
dependency: transitive
description:
@@ -1131,8 +1115,8 @@ packages:
description:
path: media_kit
ref: "version_1.2.5"
resolved-ref: "4f0f72e5bf21349bc251bf52761628faeae3f233"
url: "https://github.com/My-Responsitories/media-kit.git"
resolved-ref: "4660bd0743d5643d49093af70f8bcd404f787f9c"
url: "https://github.com/bggRGjQaUbCoE/media-kit.git"
source: git
version: "1.1.11"
media_kit_libs_android_video:
@@ -1140,16 +1124,16 @@ packages:
description:
path: "libs/android/media_kit_libs_android_video"
ref: "version_1.2.5"
resolved-ref: "4f0f72e5bf21349bc251bf52761628faeae3f233"
url: "https://github.com/My-Responsitories/media-kit.git"
resolved-ref: "4660bd0743d5643d49093af70f8bcd404f787f9c"
url: "https://github.com/bggRGjQaUbCoE/media-kit.git"
source: git
version: "1.3.7"
media_kit_libs_ios_video:
dependency: "direct overridden"
description:
path: "libs/ios/media_kit_libs_ios_video"
ref: dev
resolved-ref: "547999bfb8b5cae9f9aca6125f46fd7cb500e994"
ref: "version_1.2.5"
resolved-ref: "4660bd0743d5643d49093af70f8bcd404f787f9c"
url: "https://github.com/bggRGjQaUbCoE/media-kit.git"
source: git
version: "1.1.4"
@@ -1174,8 +1158,8 @@ packages:
description:
path: "libs/universal/media_kit_libs_video"
ref: "version_1.2.5"
resolved-ref: "4f0f72e5bf21349bc251bf52761628faeae3f233"
url: "https://github.com/My-Responsitories/media-kit.git"
resolved-ref: "4660bd0743d5643d49093af70f8bcd404f787f9c"
url: "https://github.com/bggRGjQaUbCoE/media-kit.git"
source: git
version: "1.0.5"
media_kit_libs_windows_video:
@@ -1183,8 +1167,8 @@ packages:
description:
path: "libs/windows/media_kit_libs_windows_video"
ref: "version_1.2.5"
resolved-ref: "4f0f72e5bf21349bc251bf52761628faeae3f233"
url: "https://github.com/My-Responsitories/media-kit.git"
resolved-ref: "4660bd0743d5643d49093af70f8bcd404f787f9c"
url: "https://github.com/bggRGjQaUbCoE/media-kit.git"
source: git
version: "1.0.10"
media_kit_native_event_loop:
@@ -1192,8 +1176,8 @@ packages:
description:
path: media_kit_native_event_loop
ref: "version_1.2.5"
resolved-ref: "4f0f72e5bf21349bc251bf52761628faeae3f233"
url: "https://github.com/My-Responsitories/media-kit.git"
resolved-ref: "4660bd0743d5643d49093af70f8bcd404f787f9c"
url: "https://github.com/bggRGjQaUbCoE/media-kit.git"
source: git
version: "1.0.9"
media_kit_video:
@@ -1201,8 +1185,8 @@ packages:
description:
path: media_kit_video
ref: "version_1.2.5"
resolved-ref: "4f0f72e5bf21349bc251bf52761628faeae3f233"
url: "https://github.com/My-Responsitories/media-kit.git"
resolved-ref: "4660bd0743d5643d49093af70f8bcd404f787f9c"
url: "https://github.com/bggRGjQaUbCoE/media-kit.git"
source: git
version: "1.2.5"
menu_base:
@@ -2001,4 +1985,4 @@ packages:
version: "3.1.3"
sdks:
dart: ">=3.12.0 <4.0.0"
flutter: "3.44.0"
flutter: "3.44.1"

View File

@@ -21,7 +21,7 @@ version: 2.0.8+1
environment:
sdk: ">=3.12.0"
flutter: 3.44.0
flutter: 3.44.1
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
@@ -112,7 +112,6 @@ dependencies:
git:
url: https://github.com/bggRGjQaUbCoE/getx.git
ref: version_4.7.2
gt3_flutter_plugin: ^0.1.0
hive_ce: ^2.19.3
html: ^0.15.4
http2: ^2.3.1
@@ -180,40 +179,45 @@ dependency_overrides:
url: https://github.com/bggRGjQaUbCoE/flutter_inappwebview.git
path: flutter_inappwebview_android
ref: v6.1.5
flutter_inappwebview_windows:
git:
url: https://github.com/bggRGjQaUbCoE/flutter_inappwebview.git
path: flutter_inappwebview_windows
ref: v6.1.5
flutter_volume_controller: ^2.0.0
media_kit:
git:
url: https://github.com/My-Responsitories/media-kit.git
url: https://github.com/bggRGjQaUbCoE/media-kit.git
path: media_kit
ref: version_1.2.5
media_kit_libs_android_video:
git:
url: https://github.com/My-Responsitories/media-kit.git
url: https://github.com/bggRGjQaUbCoE/media-kit.git
path: libs/android/media_kit_libs_android_video
ref: version_1.2.5
media_kit_libs_ios_video:
git:
url: https://github.com/bggRGjQaUbCoE/media-kit.git
path: libs/ios/media_kit_libs_ios_video
ref: dev
ref: version_1.2.5
media_kit_libs_video:
git:
url: https://github.com/My-Responsitories/media-kit.git
url: https://github.com/bggRGjQaUbCoE/media-kit.git
path: libs/universal/media_kit_libs_video
ref: version_1.2.5
media_kit_libs_windows_video:
git:
url: https://github.com/My-Responsitories/media-kit.git
url: https://github.com/bggRGjQaUbCoE/media-kit.git
path: libs/windows/media_kit_libs_windows_video
ref: version_1.2.5
media_kit_native_event_loop:
git:
url: https://github.com/My-Responsitories/media-kit.git
url: https://github.com/bggRGjQaUbCoE/media-kit.git
path: media_kit_native_event_loop
ref: version_1.2.5
media_kit_video:
git:
url: https://github.com/My-Responsitories/media-kit.git
url: https://github.com/bggRGjQaUbCoE/media-kit.git
path: media_kit_video
ref: version_1.2.5
screen_brightness_android: