From 54b0cc44ff6395095b5404dabae859f1d5e1f0f4 Mon Sep 17 00:00:00 2001 From: Rust Date: Sat, 1 Nov 2025 11:49:17 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3vless=E5=8D=8F=E8=AE=AE?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 5cbb1654e22841b5078829e926946def1a10201e) --- lib/app/model/business/kr_outbound_item.dart | 82 ++++++++++++++++++-- 1 file changed, 74 insertions(+), 8 deletions(-) diff --git a/lib/app/model/business/kr_outbound_item.dart b/lib/app/model/business/kr_outbound_item.dart index fa00045..9933e0f 100755 --- a/lib/app/model/business/kr_outbound_item.dart +++ b/lib/app/model/business/kr_outbound_item.dart @@ -251,7 +251,9 @@ 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} 个协议'); @@ -314,17 +316,49 @@ class KROutboundItem { final tlsEnabled = security == 'tls' || security == 'reality'; securityConfig = { - 'tls_enabled': tlsEnabled, // ← 新增:记录 TLS 是否启用 + 'tls_enabled': tlsEnabled, + 'security_type': security, // 🔧 新增:记录安全类型(tls/reality) '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) { + } catch (e, stackTrace) { print('⚠️ 解析 protocols 字段失败: $e'); + print('📍 堆栈跟踪: $stackTrace'); } + } else { + print('❌ protocols 字段为空,跳过解析'); } // 兜底:尝试从 config 字段解析(旧API格式) @@ -373,15 +407,33 @@ class KROutboundItem { final bool isDomain = !RegExp(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$') .hasMatch(nodeListItem.serverAddr); - // 🔧 优先使用 security_config 中的 SNI + // 🔧 检测是否是 Reality 协议 + final bool isReality = securityConfig?['security_type'] == 'reality'; + final bool vlessTlsEnabled = securityConfig?['tls_enabled'] ?? false; + + // 🔧 确定 server_name:Reality 使用 reality_server_name,普通 TLS 使用 sni String serverName = nodeListItem.serverAddr; - if (securityConfig != null && securityConfig['sni'] != null && securityConfig['sni'].toString().isNotEmpty) { + 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) { serverName = securityConfig['sni'].toString(); } - // 🔧 关键修复:根据 security_config 判断是否启用 TLS - final bool vlessTlsEnabled = securityConfig?['tls_enabled'] ?? false; - print('🔐 VLESS TLS 状态: enabled=$vlessTlsEnabled'); + 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'; config = { "type": "vless", @@ -389,11 +441,25 @@ 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, - if (isDomain) "server_name": serverName, + // 🔧 修复:Reality 必须有 server_name,普通 TLS 在域名时需要 + if (isReality || 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"