diff --git a/lib/app/model/business/kr_outbound_item.dart b/lib/app/model/business/kr_outbound_item.dart index 9933e0f..fa00045 100755 --- a/lib/app/model/business/kr_outbound_item.dart +++ b/lib/app/model/business/kr_outbound_item.dart @@ -251,9 +251,7 @@ class KROutboundItem { Map? securityConfig; // 🔧 关键修复:优先从 protocols 字段解析配置 - print('🔍 检查 protocols 字段: isEmpty=${nodeListItem.protocols.isEmpty}, length=${nodeListItem.protocols.length}'); if (nodeListItem.protocols.isNotEmpty) { - print('✅ protocols 字段不为空,开始解析...'); try { final protocolsList = jsonDecode(nodeListItem.protocols) as List; print('📄 解析到 protocols 数组,共 ${protocolsList.length} 个协议'); @@ -316,49 +314,17 @@ class KROutboundItem { final tlsEnabled = security == 'tls' || security == 'reality'; securityConfig = { - 'tls_enabled': tlsEnabled, - 'security_type': security, // 🔧 新增:记录安全类型(tls/reality) + 'tls_enabled': tlsEnabled, // ← 新增:记录 TLS 是否启用 'sni': matchedProtocol['sni'] ?? matchedProtocol['server_name'], 'allow_insecure': matchedProtocol['allow_insecure'] ?? matchedProtocol['insecure'] ?? true, 'fingerprint': matchedProtocol['fingerprint'] ?? 'chrome', }; - - // 🔧 新增:如果是 Reality,提取 Reality 特定配置 - if (security == 'reality') { - securityConfig['reality_enabled'] = true; - securityConfig['reality_public_key'] = matchedProtocol['reality_public_key'] ?? ''; - securityConfig['reality_short_id'] = matchedProtocol['reality_short_id'] ?? ''; - securityConfig['reality_server_name'] = matchedProtocol['reality_server_addr'] ?? matchedProtocol['reality_server_name'] ?? ''; - - print(' 🔒 Reality 配置:'); - print(' - public_key: ${securityConfig['reality_public_key']}'); - print(' - short_id: ${securityConfig['reality_short_id']}'); - print(' - server_name: ${securityConfig['reality_server_name']}'); - } - print(' ✅ Security config: security=$security, tls_enabled=$tlsEnabled, config=$securityConfig'); } - - // 🔧 新增:提取 flow 字段(VLESS xtls-rprx-vision 等需要) - if (matchedProtocol['flow'] != null && matchedProtocol['flow'].toString().isNotEmpty) { - securityConfig ??= {}; - securityConfig['flow'] = matchedProtocol['flow'].toString(); - print(' 📊 Flow: ${securityConfig['flow']}'); - } - - // 🔧 新增:提取 encryption 字段(VLESS 需要) - if (matchedProtocol['encryption'] != null) { - securityConfig ??= {}; - securityConfig['encryption'] = matchedProtocol['encryption'].toString(); - print(' 🔐 Encryption: ${securityConfig['encryption']}'); - } } - } catch (e, stackTrace) { + } catch (e) { print('⚠️ 解析 protocols 字段失败: $e'); - print('📍 堆栈跟踪: $stackTrace'); } - } else { - print('❌ protocols 字段为空,跳过解析'); } // 兜底:尝试从 config 字段解析(旧API格式) @@ -407,33 +373,15 @@ class KROutboundItem { final bool isDomain = !RegExp(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$') .hasMatch(nodeListItem.serverAddr); - // 🔧 检测是否是 Reality 协议 - final bool isReality = securityConfig?['security_type'] == 'reality'; - final bool vlessTlsEnabled = securityConfig?['tls_enabled'] ?? false; - - // 🔧 确定 server_name:Reality 使用 reality_server_name,普通 TLS 使用 sni + // 🔧 优先使用 security_config 中的 SNI String serverName = nodeListItem.serverAddr; - if (isReality && securityConfig?['reality_server_name'] != null && securityConfig!['reality_server_name'].toString().isNotEmpty) { - serverName = securityConfig['reality_server_name'].toString(); - print('🔒 Reality server_name: $serverName'); - } else if (securityConfig != null && securityConfig['sni'] != null && securityConfig['sni'].toString().isNotEmpty) { + if (securityConfig != null && securityConfig['sni'] != null && securityConfig['sni'].toString().isNotEmpty) { serverName = securityConfig['sni'].toString(); } - print('🔐 VLESS 配置: TLS=$vlessTlsEnabled, Reality=$isReality, isDomain=$isDomain'); - print('🔐 Server Name: $serverName'); - if (isReality) { - print('🔒 Reality 详细配置:'); - print(' - public_key: ${securityConfig?['reality_public_key']}'); - print(' - short_id: ${securityConfig?['reality_short_id']}'); - print(' - server_name: ${securityConfig?['reality_server_name']}'); - print(' - flow: ${securityConfig?['flow']}'); - } - - // 🔧 检查是否有 flow(vision 等流控) - final bool hasFlow = securityConfig?['flow'] != null && - securityConfig!['flow'].toString().isNotEmpty && - securityConfig['flow'].toString() != 'none'; + // 🔧 关键修复:根据 security_config 判断是否启用 TLS + final bool vlessTlsEnabled = securityConfig?['tls_enabled'] ?? false; + print('🔐 VLESS TLS 状态: enabled=$vlessTlsEnabled'); config = { "type": "vless", @@ -441,25 +389,11 @@ class KROutboundItem { "server": nodeListItem.serverAddr, "server_port": nodeListItem.port, "uuid": nodeListItem.uuid, - // 🔧 新增:flow 字段(xtls-rprx-vision 等) - if (hasFlow) - "flow": securityConfig['flow'].toString(), - // 🔧 关键修复:packet_encoding 和 flow 互斥 - // 只有在没有 flow 时才添加 packet_encoding - if (!hasFlow) - "packet_encoding": "", if (transportConfig != null) "transport": transportConfig, if (vlessTlsEnabled) "tls": { "enabled": true, - // 🔧 修复:Reality 必须有 server_name,普通 TLS 在域名时需要 - if (isReality || isDomain) "server_name": serverName, + if (isDomain) "server_name": serverName, "insecure": securityConfig?['allow_insecure'] ?? true, - // 🔧 新增:Reality 配置块 - if (isReality) "reality": { - "enabled": true, - "public_key": securityConfig?['reality_public_key'] ?? '', - "short_id": securityConfig?['reality_short_id'] ?? '', - }, "utls": { "enabled": true, "fingerprint": securityConfig?['fingerprint'] ?? "chrome" diff --git a/lib/app/modules/kr_invite/views/kr_invite_view.dart b/lib/app/modules/kr_invite/views/kr_invite_view.dart index 09ba1f5..0e26002 100755 --- a/lib/app/modules/kr_invite/views/kr_invite_view.dart +++ b/lib/app/modules/kr_invite/views/kr_invite_view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:kaer_with_panels/app/common/app_config.dart'; import 'package:kaer_with_panels/app/localization/app_translations.dart'; import 'package:kaer_with_panels/app/widgets/kr_local_image.dart'; import '../controllers/kr_invite_controller.dart'; diff --git a/lib/app/modules/kr_main/controllers/kr_main_controller.dart b/lib/app/modules/kr_main/controllers/kr_main_controller.dart index 488dd06..418dd43 100755 --- a/lib/app/modules/kr_main/controllers/kr_main_controller.dart +++ b/lib/app/modules/kr_main/controllers/kr_main_controller.dart @@ -6,6 +6,10 @@ import 'package:kaer_with_panels/app/modules/kr_statistics/views/kr_statistics_v import 'package:kaer_with_panels/app/modules/kr_user_info/views/kr_user_info_view.dart'; import 'package:kaer_with_panels/app/modules/kr_user_info/controllers/kr_user_info_controller.dart'; import 'package:kaer_with_panels/app/widgets/kr_keep_alive_wrapper.dart'; +import 'package:kaer_with_panels/app/common/app_run_data.dart'; +import 'package:kaer_with_panels/app/localization/app_translations.dart'; +import 'package:kaer_with_panels/app/widgets/dialogs/kr_dialog.dart'; +import 'package:kaer_with_panels/app/routes/app_pages.dart'; import '../../../widgets/kr_language_switch_dialog.dart'; @@ -56,9 +60,38 @@ class KRMainController extends GetxController { /// 到哪个页面,具体传值查看MainRoutes的枚举类 kr_setPage(int index) { + // 🔒 检查邀请页面(index=1)是否需要登录 + if (index == 1) { + final appRunData = KRAppRunData.getInstance(); + final isDeviceLogin = appRunData.isDeviceLogin(); + final isLoggedIn = appRunData.kr_isLogin.value && !isDeviceLogin; + + // 如果是游客模式,弹出登录提示对话框,不切换页面 + if (!isLoggedIn) { + KRDialog.show( + title: AppTranslations.kr_dialog.deviceLoginBindingTitle, + message: AppTranslations.kr_dialog.deviceLoginBindingMessage, + confirmText: AppTranslations.kr_dialog.kr_ok, + cancelText: AppTranslations.kr_dialog.kr_cancel, + onConfirm: () { + Get.back(); // 关闭对话框 + // 延迟后跳转到登录页面 + Future.delayed(const Duration(milliseconds: 300), () { + Get.toNamed(Routes.MR_LOGIN); + }); + }, + onCancel: () { + Get.back(); // 关闭对话框 + }, + ); + return; // 不切换页面 + } + } + + // 正常切换页面 kr_currentIndex.value = index; pageController.jumpToPage(index); - + // 监控页面进入 if (index == MainRoutes.USER_CENTER.i) { final userInfoController = Get.find();