feat: 初始化并发问题处理
This commit is contained in:
@@ -28,13 +28,10 @@ class KROutboundItem {
|
||||
|
||||
/// URL
|
||||
String url = "";
|
||||
@override
|
||||
String toString() {
|
||||
return 'KROutboundItem(tag: $tag, country: $country, delay: ${urlTestDelay.value}ms)';
|
||||
}
|
||||
|
||||
/// 服务器类型
|
||||
|
||||
/// 构造函数,接受 KrNodeListItem 对象并初始化 KROutboundItem
|
||||
/// 构造函数,接受 KrItem 对象并初始化 KROutboundItem
|
||||
KROutboundItem(KrNodeListItem nodeListItem) {
|
||||
id = nodeListItem.id.toString();
|
||||
protocol = nodeListItem.protocol;
|
||||
@@ -84,13 +81,13 @@ class KROutboundItem {
|
||||
case "vless":
|
||||
final securityConfig =
|
||||
json["security_config"] as Map<String, dynamic>? ?? {};
|
||||
|
||||
|
||||
// 智能设置 server_name
|
||||
String serverName = securityConfig["sni"] ?? "";
|
||||
if (serverName.isEmpty) {
|
||||
serverName = nodeListItem.serverAddr;
|
||||
}
|
||||
|
||||
|
||||
config = {
|
||||
"type": "vless",
|
||||
"tag": nodeListItem.name,
|
||||
@@ -115,13 +112,13 @@ class KROutboundItem {
|
||||
case "vmess":
|
||||
final securityConfig =
|
||||
json["security_config"] as Map<String, dynamic>? ?? {};
|
||||
|
||||
|
||||
// 智能设置 server_name
|
||||
String serverName = securityConfig["sni"] ?? "";
|
||||
if (serverName.isEmpty) {
|
||||
serverName = nodeListItem.serverAddr;
|
||||
}
|
||||
|
||||
|
||||
config = {
|
||||
"type": "vmess",
|
||||
"tag": nodeListItem.name,
|
||||
@@ -152,7 +149,7 @@ class KROutboundItem {
|
||||
break;
|
||||
case "hysteria":
|
||||
case "hysteria2":
|
||||
// 后端的 "hysteria" 实际上是 Hysteria2 协议
|
||||
// 后端的 "hysteria" 实际上是 Hysteria2 协议
|
||||
final securityConfig =
|
||||
json["security_config"] as Map<String, dynamic>? ?? {};
|
||||
config = {
|
||||
@@ -177,14 +174,14 @@ class KROutboundItem {
|
||||
case "trojan":
|
||||
final securityConfig =
|
||||
json["security_config"] as Map<String, dynamic>? ?? {};
|
||||
|
||||
|
||||
// 智能设置 server_name
|
||||
String serverName = securityConfig["sni"] ?? "";
|
||||
if (serverName.isEmpty) {
|
||||
// 如果没有配置 SNI,使用服务器地址
|
||||
serverName = nodeListItem.serverAddr;
|
||||
}
|
||||
|
||||
|
||||
config = {
|
||||
"type": "trojan",
|
||||
"tag": nodeListItem.name,
|
||||
@@ -274,6 +271,7 @@ class KROutboundItem {
|
||||
// 🔧 尝试从 config 字段解析 transport 配置
|
||||
Map<String, dynamic>? transportConfig;
|
||||
Map<String, dynamic>? securityConfig;
|
||||
int actualPort = nodeListItem.port; // 🔧 使用局部变量存储实际端口
|
||||
|
||||
// 🔧 关键修复:优先从 protocols 字段解析配置
|
||||
if (nodeListItem.protocols.isNotEmpty) {
|
||||
@@ -307,6 +305,28 @@ class KROutboundItem {
|
||||
}
|
||||
|
||||
if (matchedProtocol != null) {
|
||||
// 🔧 关键修复:只在顶层端口为0时,才使用 protocols 中的端口
|
||||
// 这样可以保留顶层的正确端口(如 53441),不被 protocols 数组中的端口(如 287)覆盖
|
||||
if (actualPort == 0 && matchedProtocol['port'] != null) {
|
||||
// 安全解析端口号
|
||||
int protocolPort = 0;
|
||||
final portValue = matchedProtocol['port'];
|
||||
if (portValue is int) {
|
||||
protocolPort = portValue;
|
||||
} else if (portValue is String) {
|
||||
protocolPort = int.tryParse(portValue) ?? 0;
|
||||
}
|
||||
|
||||
if (protocolPort > 0) {
|
||||
actualPort = protocolPort;
|
||||
if (kDebugMode) {
|
||||
print(' ✅ 从 protocols 使用端口: $protocolPort (顶层端口为0)');
|
||||
}
|
||||
}
|
||||
} else if (kDebugMode && matchedProtocol['port'] != null) {
|
||||
print(' ✅ 保留顶层端口: $actualPort (protocols中的端口: ${matchedProtocol['port']})');
|
||||
}
|
||||
|
||||
// 提取 transport 配置
|
||||
if (matchedProtocol['network'] != null || matchedProtocol['transport'] != null) {
|
||||
final network = matchedProtocol['network'] ?? matchedProtocol['transport'];
|
||||
@@ -402,7 +422,7 @@ class KROutboundItem {
|
||||
|
||||
switch (nodeListItem.protocol) {
|
||||
case "shadowsocks":
|
||||
// 优先使用 protocols 解析出来的 cipher,其次是 method 字段,最后才是默认值
|
||||
// 优先使用 protocols 解析出来的 cipher,其次是 method 字段,最后才是默认值
|
||||
String finalMethod = nodeListItem.method.isNotEmpty
|
||||
? nodeListItem.method
|
||||
: "2022-blake3-aes-256-gcm";
|
||||
@@ -411,22 +431,21 @@ class KROutboundItem {
|
||||
"type": "shadowsocks",
|
||||
"tag": nodeListItem.name,
|
||||
"server": nodeListItem.serverAddr,
|
||||
"server_port": nodeListItem.port,
|
||||
"server_port": actualPort,
|
||||
"method": finalMethod,
|
||||
"password": nodeListItem.uuid
|
||||
};
|
||||
if (kDebugMode) {
|
||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
print('✅ Shadowsocks 节点配置构建成功: ${nodeListItem.name}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📄 使用加密方法: $finalMethod');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📄 完整配置: $config');
|
||||
print('📄 完整配置 JSON:');
|
||||
print(jsonEncode(config));
|
||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
}
|
||||
break;
|
||||
case "vless":
|
||||
// 判断是否为域名(非IP地址)
|
||||
// 判断是否为域名(非IP地址)
|
||||
final bool isDomain = !RegExp(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$')
|
||||
.hasMatch(nodeListItem.serverAddr);
|
||||
|
||||
@@ -436,17 +455,25 @@ class KROutboundItem {
|
||||
serverName = securityConfig['sni'].toString();
|
||||
}
|
||||
|
||||
// 🔧 关键修复:根据 security_config 判断是否启用 TLS
|
||||
final bool vlessTlsEnabled = securityConfig?['tls_enabled'] ?? false;
|
||||
// 🔧 关键修复:智能判断是否启用 TLS
|
||||
// 1. 优先使用 securityConfig['tls_enabled']
|
||||
// 2. 如果没有明确配置,根据端口和域名智能判断
|
||||
bool vlessTlsEnabled = securityConfig?['tls_enabled'] ?? true; // 默认启用 TLS
|
||||
|
||||
// 如果端口是标准非TLS端口(80, 8080等),则禁用 TLS
|
||||
if (nodeListItem.port == 80 || nodeListItem.port == 8080) {
|
||||
vlessTlsEnabled = false;
|
||||
}
|
||||
|
||||
if (kDebugMode) {
|
||||
print('🔐 VLESS TLS 状态: enabled=$vlessTlsEnabled');
|
||||
print('🔐 VLESS TLS 状态: enabled=$vlessTlsEnabled (port=${nodeListItem.port}, isDomain=$isDomain)');
|
||||
}
|
||||
|
||||
config = {
|
||||
"type": "vless",
|
||||
"tag": nodeListItem.name,
|
||||
"server": nodeListItem.serverAddr,
|
||||
"server_port": nodeListItem.port,
|
||||
"server_port": actualPort,
|
||||
"uuid": nodeListItem.uuid,
|
||||
if (transportConfig != null) "transport": transportConfig,
|
||||
if (vlessTlsEnabled) "tls": {
|
||||
@@ -460,14 +487,27 @@ class KROutboundItem {
|
||||
}
|
||||
};
|
||||
if (kDebugMode) {
|
||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
print('✅ VLESS 节点配置构建成功: ${nodeListItem.name}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📄 完整配置: $config');
|
||||
print('📋 原始节点信息:');
|
||||
print(' - serverAddr: ${nodeListItem.serverAddr}');
|
||||
print(' - port: ${nodeListItem.port}');
|
||||
print(' - uuid: ${nodeListItem.uuid}');
|
||||
print(' - protocols: ${nodeListItem.protocols}');
|
||||
print('🔐 安全配置:');
|
||||
print(' - TLS 启用: $vlessTlsEnabled');
|
||||
print(' - 是域名: $isDomain');
|
||||
print(' - server_name: $serverName');
|
||||
print(' - securityConfig: $securityConfig');
|
||||
print('📡 传输配置:');
|
||||
print(' - transportConfig: $transportConfig');
|
||||
print('📄 最终生成的完整配置 JSON:');
|
||||
print(jsonEncode(config));
|
||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
}
|
||||
break;
|
||||
case "vmess":
|
||||
// 判断是否为域名(非IP地址)
|
||||
// 判断是否为域名(非IP地址)
|
||||
final bool isDomain = !RegExp(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$')
|
||||
.hasMatch(nodeListItem.serverAddr);
|
||||
|
||||
@@ -477,17 +517,25 @@ class KROutboundItem {
|
||||
serverName = securityConfig['sni'].toString();
|
||||
}
|
||||
|
||||
// 🔧 关键修复:根据 security_config 判断是否启用 TLS
|
||||
final bool tlsEnabled = securityConfig?['tls_enabled'] ?? false;
|
||||
// 🔧 关键修复:智能判断是否启用 TLS
|
||||
// 1. 优先使用 securityConfig['tls_enabled']
|
||||
// 2. 如果没有明确配置,根据端口和域名智能判断
|
||||
bool tlsEnabled = securityConfig?['tls_enabled'] ?? true; // 默认启用 TLS
|
||||
|
||||
// 如果端口是标准非TLS端口(80, 8080等),则禁用 TLS
|
||||
if (nodeListItem.port == 80 || nodeListItem.port == 8080) {
|
||||
tlsEnabled = false;
|
||||
}
|
||||
|
||||
if (kDebugMode) {
|
||||
print('🔐 TLS 状态: enabled=$tlsEnabled');
|
||||
print('🔐 VMess TLS 状态: enabled=$tlsEnabled (port=${nodeListItem.port}, isDomain=$isDomain)');
|
||||
}
|
||||
|
||||
config = {
|
||||
"type": "vmess",
|
||||
"tag": nodeListItem.name,
|
||||
"server": nodeListItem.serverAddr,
|
||||
"server_port": nodeListItem.port,
|
||||
"server_port": actualPort,
|
||||
"uuid": nodeListItem.uuid,
|
||||
"alter_id": 0,
|
||||
"security": "auto",
|
||||
@@ -503,14 +551,27 @@ class KROutboundItem {
|
||||
}
|
||||
};
|
||||
if (kDebugMode) {
|
||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
print('✅ VMess 节点配置构建成功: ${nodeListItem.name}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📄 完整配置: $config');
|
||||
print('📋 原始节点信息:');
|
||||
print(' - serverAddr: ${nodeListItem.serverAddr}');
|
||||
print(' - port: ${nodeListItem.port}');
|
||||
print(' - uuid: ${nodeListItem.uuid}');
|
||||
print(' - protocols: ${nodeListItem.protocols}');
|
||||
print('🔐 安全配置:');
|
||||
print(' - TLS 启用: $tlsEnabled');
|
||||
print(' - 是域名: $isDomain');
|
||||
print(' - server_name: $serverName');
|
||||
print(' - securityConfig: $securityConfig');
|
||||
print('📡 传输配置:');
|
||||
print(' - transportConfig: $transportConfig');
|
||||
print('📄 最终生成的完整配置 JSON:');
|
||||
print(jsonEncode(config));
|
||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
}
|
||||
break;
|
||||
case "trojan":
|
||||
// 判断是否为域名(非IP地址)
|
||||
// 判断是否为域名(非IP地址)
|
||||
final bool isDomain = !RegExp(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$')
|
||||
.hasMatch(nodeListItem.serverAddr);
|
||||
|
||||
@@ -524,7 +585,7 @@ class KROutboundItem {
|
||||
"type": "trojan",
|
||||
"tag": nodeListItem.name,
|
||||
"server": nodeListItem.serverAddr,
|
||||
"server_port": nodeListItem.port,
|
||||
"server_port": actualPort,
|
||||
"password": nodeListItem.uuid,
|
||||
if (transportConfig != null) "transport": transportConfig,
|
||||
"tls": {
|
||||
@@ -546,7 +607,7 @@ class KROutboundItem {
|
||||
break;
|
||||
case "hysteria":
|
||||
case "hysteria2":
|
||||
// 后端的 "hysteria" 实际上是 Hysteria2 协议
|
||||
// 后端的 "hysteria" 实际上是 Hysteria2 协议
|
||||
if (kDebugMode) {
|
||||
print('🔍 构建 Hysteria2 节点: ${nodeListItem.name}');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user