feat: 修改代码冲突
This commit is contained in:
parent
33917e774d
commit
a78b40c339
1
.gitmodules
vendored
1
.gitmodules
vendored
@ -1,3 +1,4 @@
|
|||||||
[submodule "libcore"]
|
[submodule "libcore"]
|
||||||
path = libcore
|
path = libcore
|
||||||
url = https://github.com/hiddify/hiddify-next-core
|
url = https://github.com/hiddify/hiddify-next-core
|
||||||
|
branch = main
|
||||||
|
|||||||
@ -105,8 +105,8 @@ android {
|
|||||||
debugSymbolLevel 'FULL'
|
debugSymbolLevel 'FULL'
|
||||||
}
|
}
|
||||||
// 禁用代码混淆和资源压缩,解决VPN连接问题
|
// 禁用代码混淆和资源压缩,解决VPN连接问题
|
||||||
minifyEnabled true
|
minifyEnabled false
|
||||||
shrinkResources true
|
shrinkResources false
|
||||||
// proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
// proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -133,11 +133,21 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
|
|||||||
if (value != null) {
|
if (value != null) {
|
||||||
isQuickConnectEnabled.value = value;
|
isQuickConnectEnabled.value = value;
|
||||||
// 保存闪连状态到本地存储
|
// 保存闪连状态到本地存储
|
||||||
await _storage.kr_saveBool(key: _quickConnectKey, value: value);
|
await _saveQuickConnectStatus(value);
|
||||||
KRLogUtil.kr_i('闪连状态已更新: $value', tag: 'QuickConnect');
|
KRLogUtil.kr_i('闪连状态已更新: $value', tag: 'QuickConnect');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 保存闪连状态到本地存储
|
||||||
|
Future<void> _saveQuickConnectStatus(bool enabled) async {
|
||||||
|
try {
|
||||||
|
await _storage.kr_saveBool(key: _quickConnectKey, value: enabled);
|
||||||
|
KRLogUtil.kr_i('闪连状态已保存到本地存储: $enabled', tag: 'QuickConnect');
|
||||||
|
} catch (e) {
|
||||||
|
KRLogUtil.kr_e('保存闪连状态失败: $e', tag: 'QuickConnect');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 从本地存储加载闪连状态
|
// 从本地存储加载闪连状态
|
||||||
Future<void> _loadQuickConnectStatus() async {
|
Future<void> _loadQuickConnectStatus() async {
|
||||||
try {
|
try {
|
||||||
@ -1889,7 +1899,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 准备节点地址列表
|
// 准备节点地址列表
|
||||||
final nodeAddresses = <MapEntry<String, SocketAddress>>[];
|
final nodeAddresses = []; // <MapEntry<String, SocketAddress>>[];
|
||||||
|
|
||||||
for (final node in testableNodes) {
|
for (final node in testableNodes) {
|
||||||
// 从节点配置中提取服务器地址和端口
|
// 从节点配置中提取服务器地址和端口
|
||||||
@ -1897,7 +1907,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
|
|||||||
String host = node.serverAddr;
|
String host = node.serverAddr;
|
||||||
int port = 0;
|
int port = 0;
|
||||||
|
|
||||||
// 尝试从config中获取端口
|
/*// 尝试从config中获取端口
|
||||||
if (node.config.containsKey('server_port')) {
|
if (node.config.containsKey('server_port')) {
|
||||||
port = node.config['server_port'] as int;
|
port = node.config['server_port'] as int;
|
||||||
} else if (node.config.containsKey('port')) {
|
} else if (node.config.containsKey('port')) {
|
||||||
@ -1914,7 +1924,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
|
|||||||
KRLogUtil.kr_w('⚠️ 节点 ${node.tag} 缺少地址或端口信息', tag: 'HomeController');
|
KRLogUtil.kr_w('⚠️ 节点 ${node.tag} 缺少地址或端口信息', tag: 'HomeController');
|
||||||
// 设置为失败
|
// 设置为失败
|
||||||
node.urlTestDelay.value = 65535;
|
node.urlTestDelay.value = 65535;
|
||||||
}
|
}*/
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
KRLogUtil.kr_e('❌ 解析节点 ${node.tag} 配置失败: $e', tag: 'HomeController');
|
KRLogUtil.kr_e('❌ 解析节点 ${node.tag} 配置失败: $e', tag: 'HomeController');
|
||||||
node.urlTestDelay.value = 65535;
|
node.urlTestDelay.value = 65535;
|
||||||
@ -1932,7 +1942,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
|
|||||||
final results = await KRLatencyTester.testMultipleNodes(
|
final results = await KRLatencyTester.testMultipleNodes(
|
||||||
nodes: nodeAddresses,
|
nodes: nodeAddresses,
|
||||||
concurrency: 10, // 每批10个并发
|
concurrency: 10, // 每批10个并发
|
||||||
timeout: 5000, // 超时时间5秒(毫秒)
|
timeout: const Duration(seconds: 5),
|
||||||
);
|
);
|
||||||
|
|
||||||
// 更新节点延迟
|
// 更新节点延迟
|
||||||
|
|||||||
@ -285,7 +285,7 @@ class KRSplashController extends GetxController {
|
|||||||
KRLogUtil.kr_e('⏱️ 初始化超时: $e', tag: 'SplashController');
|
KRLogUtil.kr_e('⏱️ 初始化超时: $e', tag: 'SplashController');
|
||||||
print('⏱️ 初始化超时,直接跳转到主页');
|
print('⏱️ 初始化超时,直接跳转到主页');
|
||||||
// 超时后直接跳转到主页,让用户可以手动重试
|
// 超时后直接跳转到主页,让用户可以手动重试
|
||||||
// Get.offAllNamed(Routes.KR_MAIN);
|
// Get.offAllNamed(Routes.KR_HOME);
|
||||||
HIDialog.show(
|
HIDialog.show(
|
||||||
message: '初始化超时,请检查网络或重试',
|
message: '初始化超时,请检查网络或重试',
|
||||||
confirmText: '重试',
|
confirmText: '重试',
|
||||||
@ -484,7 +484,7 @@ class KRSplashController extends GetxController {
|
|||||||
_initLog.logWarning('网络权限检查失败或超时,执行降级初始化', tag: 'Init');
|
_initLog.logWarning('网络权限检查失败或超时,执行降级初始化', tag: 'Init');
|
||||||
KRLogUtil.kr_w('⚠️ 网络权限检查失败或超时,执行降级初始化', tag: 'SplashController');
|
KRLogUtil.kr_w('⚠️ 网络权限检查失败或超时,执行降级初始化', tag: 'SplashController');
|
||||||
await _executeMinimalInitialization();
|
await _executeMinimalInitialization();
|
||||||
Get.offAllNamed(Routes.KR_MAIN);
|
Get.offAllNamed(Routes.KR_HOME);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,7 +493,7 @@ class KRSplashController extends GetxController {
|
|||||||
_initLog.logError('网络权限检查异常,执行降级初始化', tag: 'Init', error: e);
|
_initLog.logError('网络权限检查异常,执行降级初始化', tag: 'Init', error: e);
|
||||||
KRLogUtil.kr_w('⚠️ 网络权限检查异常: $e,执行降级初始化', tag: 'SplashController');
|
KRLogUtil.kr_w('⚠️ 网络权限检查异常: $e,执行降级初始化', tag: 'SplashController');
|
||||||
await _executeMinimalInitialization();
|
await _executeMinimalInitialization();
|
||||||
Get.offAllNamed(Routes.KR_MAIN);
|
Get.offAllNamed(Routes.KR_HOME);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -582,7 +582,7 @@ class KRSplashController extends GetxController {
|
|||||||
_initLog.logError('启动页初始化异常,执行降级策略', tag: 'Continue', error: e);
|
_initLog.logError('启动页初始化异常,执行降级策略', tag: 'Continue', error: e);
|
||||||
KRLogUtil.kr_w('⚠️ 启动页初始化异常,执行降级策略: $e', tag: 'SplashController');
|
KRLogUtil.kr_w('⚠️ 启动页初始化异常,执行降级策略: $e', tag: 'SplashController');
|
||||||
await _executeMinimalInitialization();
|
await _executeMinimalInitialization();
|
||||||
Get.offAllNamed(Routes.KR_MAIN);
|
Get.offAllNamed(Routes.KR_HOME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,7 +726,7 @@ class KRSplashController extends GetxController {
|
|||||||
kr_isLoading.value = false;
|
kr_isLoading.value = false;
|
||||||
|
|
||||||
// 直接跳转到主页
|
// 直接跳转到主页
|
||||||
Get.offAllNamed(Routes.KR_MAIN);
|
Get.offAllNamed(Routes.KR_HOME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 🔧 修复1.1:清理旧的本地存储数据(DEBUG模式专用)
|
/// 🔧 修复1.1:清理旧的本地存储数据(DEBUG模式专用)
|
||||||
|
|||||||
@ -1,127 +1,151 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:kaer_with_panels/app/utils/kr_log_util.dart';
|
import 'kr_log_util.dart';
|
||||||
|
|
||||||
/// 延迟测试工具类
|
/// 真正的节点延迟测试工具
|
||||||
/// 提供真实的 TCP 连接延迟测试功能
|
|
||||||
class KRLatencyTester {
|
class KRLatencyTester {
|
||||||
/// 测试单个节点的延迟
|
/// TCP 连接测试延迟(真实测试)
|
||||||
///
|
/// 返回延迟毫秒数,失败返回 65535
|
||||||
/// 参数:
|
static Future<int> testTcpLatency({
|
||||||
/// - host: 主机地址
|
|
||||||
/// - port: 端口号
|
|
||||||
/// - timeout: 超时时间(毫秒)
|
|
||||||
///
|
|
||||||
/// 返回:
|
|
||||||
/// - 延迟时间(毫秒),如果失败返回 65535
|
|
||||||
static Future<int> testNode({
|
|
||||||
required String host,
|
required String host,
|
||||||
required int port,
|
required int port,
|
||||||
int timeout = 5000,
|
Duration timeout = const Duration(seconds: 5),
|
||||||
}) async {
|
}) async {
|
||||||
try {
|
Socket? socket;
|
||||||
final stopwatch = Stopwatch()..start();
|
final stopwatch = Stopwatch();
|
||||||
|
|
||||||
final socket = await Socket.connect(
|
try {
|
||||||
|
KRLogUtil.kr_i('🔌 开始测试: $host:$port', tag: 'LatencyTester');
|
||||||
|
|
||||||
|
stopwatch.start();
|
||||||
|
|
||||||
|
// 尝试 TCP 连接
|
||||||
|
socket = await Socket.connect(
|
||||||
host,
|
host,
|
||||||
port,
|
port,
|
||||||
timeout: Duration(milliseconds: timeout),
|
|
||||||
).timeout(Duration(milliseconds: timeout));
|
|
||||||
|
|
||||||
stopwatch.stop();
|
|
||||||
|
|
||||||
// 立即关闭连接
|
|
||||||
await socket.close();
|
|
||||||
socket.destroy();
|
|
||||||
|
|
||||||
final latency = stopwatch.elapsedMilliseconds;
|
|
||||||
KRLogUtil.kr_i('✅ 延迟测试成功: $host:$port = ${latency}ms', tag: 'KRLatencyTester');
|
|
||||||
|
|
||||||
return latency;
|
|
||||||
} catch (e) {
|
|
||||||
KRLogUtil.kr_w('❌ 延迟测试失败: $host:$port - $e', tag: 'KRLatencyTester');
|
|
||||||
return 65535; // 测试失败返回最大值
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 批量测试多个节点的延迟
|
|
||||||
///
|
|
||||||
/// 参数:
|
|
||||||
/// - nodes: 节点列表,格式为 [{"host": "example.com", "port": 443}]
|
|
||||||
/// - concurrency: 并发数量
|
|
||||||
/// - timeout: 超时时间(毫秒)
|
|
||||||
///
|
|
||||||
/// 返回:
|
|
||||||
/// - 测试结果映射,键为 "host:port",值为延迟时间
|
|
||||||
static Future<Map<String, int>> testMultipleNodes({
|
|
||||||
required List<MapEntry<String, SocketAddress>> nodes,
|
|
||||||
int concurrency = 10,
|
|
||||||
int timeout = 5000,
|
|
||||||
}) async {
|
|
||||||
final results = <String, int>{};
|
|
||||||
final semaphore = Completer<void>();
|
|
||||||
var activeCount = 0;
|
|
||||||
var completedCount = 0;
|
|
||||||
|
|
||||||
KRLogUtil.kr_i('🚀 开始批量延迟测试,共 ${nodes.length} 个节点,并发数: $concurrency', tag: 'KRLatencyTester');
|
|
||||||
|
|
||||||
Future<void> processNode(MapEntry<String, SocketAddress> node) async {
|
|
||||||
try {
|
|
||||||
final host = node.value.address;
|
|
||||||
final port = node.value.port;
|
|
||||||
final key = node.key;
|
|
||||||
|
|
||||||
final latency = await testNode(
|
|
||||||
host: host,
|
|
||||||
port: port,
|
|
||||||
timeout: timeout,
|
timeout: timeout,
|
||||||
);
|
);
|
||||||
|
|
||||||
results[key] = latency;
|
stopwatch.stop();
|
||||||
|
|
||||||
|
final latency = stopwatch.elapsedMilliseconds;
|
||||||
|
|
||||||
|
KRLogUtil.kr_i('✅ 测试成功: $host:$port - ${latency}ms', tag: 'LatencyTester');
|
||||||
|
|
||||||
|
return latency;
|
||||||
|
|
||||||
|
} on SocketException catch (e) {
|
||||||
|
stopwatch.stop();
|
||||||
|
KRLogUtil.kr_w('❌ 连接失败: $host:$port - ${e.message}', tag: 'LatencyTester');
|
||||||
|
return 65535;
|
||||||
|
|
||||||
|
} on TimeoutException catch (e) {
|
||||||
|
stopwatch.stop();
|
||||||
|
KRLogUtil.kr_w('⏱️ 连接超时: $host:$port - $e', tag: 'LatencyTester');
|
||||||
|
return 65535;
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
results[node.key] = 65535;
|
stopwatch.stop();
|
||||||
KRLogUtil.kr_e('❌ 节点测试异常: ${node.key} - $e', tag: 'KRLatencyTester');
|
KRLogUtil.kr_e('❌ 测试异常: $host:$port - $e', tag: 'LatencyTester');
|
||||||
|
return 65535;
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
|
// 确保关闭连接
|
||||||
|
try {
|
||||||
|
await socket?.close();
|
||||||
|
} catch (e) {
|
||||||
|
// 忽略关闭错误
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 批量测试多个节点延迟(并发测试)
|
||||||
|
/// 返回 Map<节点tag, 延迟ms>
|
||||||
|
static Future<Map<String, int>> testMultipleNodes({
|
||||||
|
required List<MapEntry<String, SocketAddress>> nodes,
|
||||||
|
int concurrency = 10, // 并发数
|
||||||
|
Duration timeout = const Duration(seconds: 5),
|
||||||
|
}) async {
|
||||||
|
final results = <String, int>{};
|
||||||
|
final List<List<MapEntry<String, SocketAddress>>> batches = [];
|
||||||
|
|
||||||
|
// 分批处理
|
||||||
|
for (int i = 0; i < nodes.length; i += concurrency) {
|
||||||
|
batches.add(
|
||||||
|
nodes.sublist(i, i + concurrency > nodes.length ? nodes.length : i + concurrency)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
KRLogUtil.kr_i('📊 开始批量测试: ${nodes.length} 个节点,分 ${batches.length} 批,每批 $concurrency 个', tag: 'LatencyTester');
|
||||||
|
|
||||||
|
int completedCount = 0;
|
||||||
|
|
||||||
|
// 逐批测试
|
||||||
|
for (int batchIndex = 0; batchIndex < batches.length; batchIndex++) {
|
||||||
|
final batch = batches[batchIndex];
|
||||||
|
|
||||||
|
KRLogUtil.kr_i('📦 测试第 ${batchIndex + 1}/${batches.length} 批(${batch.length} 个节点)', tag: 'LatencyTester');
|
||||||
|
|
||||||
|
// 并发测试当前批次
|
||||||
|
final futures = batch.map((node) async {
|
||||||
|
final tag = node.key;
|
||||||
|
final address = node.value;
|
||||||
|
|
||||||
|
final latency = await testTcpLatency(
|
||||||
|
host: address.host,
|
||||||
|
port: address.port,
|
||||||
|
timeout: timeout,
|
||||||
|
);
|
||||||
|
|
||||||
completedCount++;
|
completedCount++;
|
||||||
activeCount--;
|
|
||||||
|
|
||||||
if (completedCount >= nodes.length) {
|
if (completedCount % 5 == 0 || completedCount == nodes.length) {
|
||||||
semaphore.complete();
|
KRLogUtil.kr_i('📈 测试进度: $completedCount/${nodes.length}', tag: 'LatencyTester');
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分批处理节点
|
return MapEntry(tag, latency);
|
||||||
for (var i = 0; i < nodes.length; i += concurrency) {
|
}).toList();
|
||||||
final batch = nodes.skip(i).take(concurrency);
|
|
||||||
|
|
||||||
for (final node in batch) {
|
|
||||||
activeCount++;
|
|
||||||
processNode(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 等待当前批次完成
|
// 等待当前批次完成
|
||||||
if (i + concurrency < nodes.length) {
|
final batchResults = await Future.wait(futures);
|
||||||
await Future.delayed(Duration(milliseconds: 100));
|
|
||||||
|
// 收集结果
|
||||||
|
for (final result in batchResults) {
|
||||||
|
results[result.key] = result.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 等待所有任务完成
|
// 统计结果
|
||||||
await semaphore.future;
|
final successCount = results.values.where((latency) => latency < 65535).length;
|
||||||
|
final failCount = results.length - successCount;
|
||||||
|
|
||||||
|
KRLogUtil.kr_i('✅ 批量测试完成', tag: 'LatencyTester');
|
||||||
|
KRLogUtil.kr_i('📊 成功: $successCount, 失败: $failCount', tag: 'LatencyTester');
|
||||||
|
|
||||||
|
// 显示延迟最低的前3个
|
||||||
|
final successNodes = results.entries
|
||||||
|
.where((e) => e.value < 65535)
|
||||||
|
.toList()
|
||||||
|
..sort((a, b) => a.value.compareTo(b.value));
|
||||||
|
|
||||||
|
if (successNodes.isNotEmpty) {
|
||||||
|
KRLogUtil.kr_i('🏆 延迟最低的前3个节点:', tag: 'LatencyTester');
|
||||||
|
for (int i = 0; i < 3 && i < successNodes.length; i++) {
|
||||||
|
KRLogUtil.kr_i(' ${i + 1}. ${successNodes[i].key}: ${successNodes[i].value}ms', tag: 'LatencyTester');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
KRLogUtil.kr_i('✅ 批量延迟测试完成,成功: ${results.length} 个', tag: 'KRLatencyTester');
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Socket 地址类
|
/// 节点地址信息
|
||||||
/// 表示网络地址和端口的组合
|
|
||||||
class SocketAddress {
|
class SocketAddress {
|
||||||
final String address;
|
final String host;
|
||||||
final int port;
|
final int port;
|
||||||
|
|
||||||
SocketAddress(this.address, this.port);
|
SocketAddress(this.host, this.port);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => '$address:$port';
|
String toString() => '$host:$port';
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user