feat: debug
Build Android APK / 编译 libcore.aar (push) Has been cancelled
Build Android APK / 编译 Android APK (release) (push) Has been cancelled
Build Android APK / 创建 GitHub Release (push) Has been cancelled
Build Multi-Platform / 编译 libcore (iOS/tvOS) (push) Has been cancelled
Build Windows / 编译 libcore (Windows) (push) Has been cancelled
Build Windows / build (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Android) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Windows) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (macOS) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Linux) (push) Has been cancelled
Build Multi-Platform / 构建 Android APK (push) Has been cancelled
Build Multi-Platform / 构建 macOS (push) Has been cancelled
Build Multi-Platform / 构建 Linux (push) Has been cancelled
Build Multi-Platform / 构建 iOS (push) Has been cancelled
Build Multi-Platform / 创建 Release (push) Has been cancelled
Build Multi-Platform / 构建 Windows (push) Has been cancelled
Build Android APK / 编译 libcore.aar (push) Has been cancelled
Build Android APK / 编译 Android APK (release) (push) Has been cancelled
Build Android APK / 创建 GitHub Release (push) Has been cancelled
Build Multi-Platform / 编译 libcore (iOS/tvOS) (push) Has been cancelled
Build Windows / 编译 libcore (Windows) (push) Has been cancelled
Build Windows / build (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Android) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Windows) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (macOS) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Linux) (push) Has been cancelled
Build Multi-Platform / 构建 Android APK (push) Has been cancelled
Build Multi-Platform / 构建 macOS (push) Has been cancelled
Build Multi-Platform / 构建 Linux (push) Has been cancelled
Build Multi-Platform / 构建 iOS (push) Has been cancelled
Build Multi-Platform / 创建 Release (push) Has been cancelled
Build Multi-Platform / 构建 Windows (push) Has been cancelled
This commit is contained in:
@@ -609,6 +609,8 @@ class KRSingBoxImp {
|
||||
|
||||
/// 订阅分组数据流
|
||||
void _kr_subscribeToGroups() {
|
||||
KRLogUtil.kr_i('🛰 启动分组监听 watchActiveGroups / watchGroups', tag: 'SingBox');
|
||||
|
||||
// 取消之前的分组订阅
|
||||
for (var sub in _kr_subscriptions) {
|
||||
if (sub.hashCode.toString().contains('Groups')) {
|
||||
@@ -1423,6 +1425,87 @@ class KRSingBoxImp {
|
||||
}
|
||||
}
|
||||
|
||||
/// 🌍 国家级节点选择
|
||||
/// 如果传入 'auto',则调用原有 kr_selectOutbound('auto')
|
||||
/// 否则根据国家名筛选该国节点,自动选择延迟最低的节点
|
||||
Future<void> kr_selectCountry(String country) async {
|
||||
KRLogUtil.kr_i('🌎 [v2.1] 开始选择国家: $country', tag: 'SingBox');
|
||||
|
||||
if (country == 'auto') {
|
||||
KRLogUtil.kr_i('🌀 国家为 auto,执行自动节点选择逻辑', tag: 'SingBox');
|
||||
await kr_selectOutbound('auto');
|
||||
return;
|
||||
}
|
||||
|
||||
if (kr_activeGroups.isEmpty) {
|
||||
KRLogUtil.kr_w('⚠️ kr_activeGroups 当前为空,无法进行国家选择', tag: 'SingBox');
|
||||
return;
|
||||
}
|
||||
|
||||
/*final selectGroup = kr_activeGroups.firstWhere(
|
||||
(group) => group.tag == 'select',
|
||||
orElse: () => throw Exception('未找到 "select" 组'),
|
||||
);
|
||||
|
||||
final countryNodes = selectGroup.items.where((item) {
|
||||
final nodeCountry = item.options?['country'] ?? '';
|
||||
return nodeCountry.toString().toLowerCase() == country.toLowerCase();
|
||||
}).toList();
|
||||
|
||||
if (countryNodes.isEmpty) {
|
||||
KRLogUtil.kr_w('⚠️ 未找到该国家的节点: $country', tag: 'SingBox');
|
||||
for (var item in selectGroup.items) {
|
||||
KRLogUtil.kr_d(
|
||||
' 可用节点: ${item.tag} (${item.options?['country'] ?? '未知'})',
|
||||
tag: 'SingBox',
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
KRLogUtil.kr_i('🇨🇭 找到 ${countryNodes.length} 个属于 "$country" 的节点', tag: 'SingBox');
|
||||
|
||||
// 按延迟排序(无延迟则 9999)
|
||||
countryNodes.sort((a, b) =>
|
||||
(a.urlTestDelay ?? 9999).compareTo(b.urlTestDelay ?? 9999));
|
||||
|
||||
final fastestNode = countryNodes.first;
|
||||
final selectedTag = fastestNode.tag;
|
||||
final delay = fastestNode.urlTestDelay ?? -1;
|
||||
|
||||
KRLogUtil.kr_i('✅ 选中该国家最快节点: $selectedTag (${delay}ms)', tag: 'SingBox');
|
||||
|
||||
try {
|
||||
await KRSecureStorage().kr_saveData(key: 'selected_country', value: country);
|
||||
await KRSecureStorage().kr_saveData(key: _keySelectedNode, value: selectedTag);
|
||||
} catch (e) {
|
||||
KRLogUtil.kr_w('⚠️ 保存国家/节点信息失败: $e', tag: 'SingBox');
|
||||
}
|
||||
|
||||
try {
|
||||
await _kr_ensureCommandClientInitialized();
|
||||
await _kr_selectOutboundWithRetry('select', selectedTag,
|
||||
maxAttempts: 3, initialDelay: 100);
|
||||
KRLogUtil.kr_i('✅ 国家内节点切换成功: $selectedTag', tag: 'SingBox');
|
||||
} catch (e) {
|
||||
KRLogUtil.kr_e('❌ 国家内节点选择失败: $e', tag: 'SingBox');
|
||||
rethrow;
|
||||
}
|
||||
|
||||
_nodeSelectionTimer?.cancel();
|
||||
KRLogUtil.kr_i('🔁 启动定时器防止节点被 auto 覆盖', tag: 'SingBox');
|
||||
_nodeSelectionTimer =
|
||||
Timer.periodic(const Duration(seconds: 20), (timer) async {
|
||||
try {
|
||||
await kr_singBox.selectOutbound('select', selectedTag).run();
|
||||
KRLogUtil.kr_d('🔁 定时确认国家内节点: $selectedTag', tag: 'SingBox');
|
||||
} catch (e) {
|
||||
KRLogUtil.kr_w('🔁 定时确认失败: $e', tag: 'SingBox');
|
||||
}
|
||||
});*/
|
||||
}
|
||||
|
||||
|
||||
/// 配合文件地址
|
||||
|
||||
Directory get directory =>
|
||||
|
||||
Reference in New Issue
Block a user