更新扩展连接协议字段并且新增邀请码展示
This commit is contained in:
parent
0d91ce138d
commit
17ea51b583
@ -30,6 +30,15 @@ class KRAppRunData {
|
||||
/// 用户ID(使用响应式变量以便 UI 能监听变化)
|
||||
final Rx<int?> kr_userId = Rx<int?>(null);
|
||||
|
||||
/// 用户邀请码(从用户信息接口获取)
|
||||
final RxString kr_referCode = ''.obs;
|
||||
|
||||
/// 用户余额
|
||||
final RxInt kr_balance = 0.obs;
|
||||
|
||||
/// 佣金
|
||||
final RxInt kr_commission = 0.obs;
|
||||
|
||||
/// 登录类型
|
||||
KRLoginType? kr_loginType;
|
||||
|
||||
@ -146,9 +155,17 @@ class KRAppRunData {
|
||||
// 只有在保存成功后才设置登录状态
|
||||
kr_isLogin.value = true;
|
||||
|
||||
// 设备登录模式不再调用用户信息接口
|
||||
// Socket 连接将在需要时建立
|
||||
KRLogUtil.kr_i('用户信息已保存,跳过用户信息接口调用', tag: 'AppRunData');
|
||||
// 🔧 非游客模式下,调用用户信息接口获取 refer_code 等信息
|
||||
KRLogUtil.kr_i('🔍 [AppRunData] 检查登录模式: account=$account', tag: 'AppRunData');
|
||||
final isDevice = isDeviceLogin();
|
||||
KRLogUtil.kr_i('🔍 [AppRunData] isDeviceLogin: $isDevice', tag: 'AppRunData');
|
||||
|
||||
if (!isDevice) {
|
||||
KRLogUtil.kr_i('✅ [AppRunData] 正常登录模式,开始获取用户详细信息', tag: 'AppRunData');
|
||||
await _fetchUserInfo();
|
||||
} else {
|
||||
KRLogUtil.kr_i('⏭️ [AppRunData] 设备登录模式,跳过用户信息接口调用', tag: 'AppRunData');
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
KRLogUtil.kr_e('保存用户信息失败: $e', tag: 'AppRunData');
|
||||
@ -298,4 +315,41 @@ class KRAppRunData {
|
||||
Future<void> _kr_disconnectSocket() async {
|
||||
await KrSocketService.instance.disconnect();
|
||||
}
|
||||
|
||||
/// 获取用户详细信息(登录后调用)
|
||||
Future<void> _fetchUserInfo() async {
|
||||
try {
|
||||
KRLogUtil.kr_i('📞 [AppRunData] 开始调用用户信息接口 /v1/public/user/info ...', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i('🔐 [AppRunData] 当前 Token: ${kr_token ?? "null"}', tag: 'AppRunData');
|
||||
|
||||
final result = await KRUserApi.kr_getUserInfo();
|
||||
|
||||
result.fold(
|
||||
(error) {
|
||||
KRLogUtil.kr_e('❌ [AppRunData] 获取用户信息失败: ${error.msg} (code: ${error.code})', tag: 'AppRunData');
|
||||
},
|
||||
(userInfo) {
|
||||
KRLogUtil.kr_i('✅ [AppRunData] 获取用户信息成功', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i('📋 [AppRunData] refer_code: "${userInfo.referCode}"', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i('💰 [AppRunData] balance: ${userInfo.balance}', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i('💵 [AppRunData] commission: ${userInfo.commission}', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i('📧 [AppRunData] email: ${userInfo.email}', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i('🆔 [AppRunData] id: ${userInfo.id}', tag: 'AppRunData');
|
||||
|
||||
// 保存到全局状态
|
||||
kr_referCode.value = userInfo.referCode;
|
||||
kr_balance.value = userInfo.balance;
|
||||
kr_commission.value = userInfo.commission;
|
||||
|
||||
KRLogUtil.kr_i('💾 [AppRunData] 用户信息已保存到全局状态:', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i(' - kr_referCode: "${kr_referCode.value}"', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i(' - kr_balance: ${kr_balance.value}', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i(' - kr_commission: ${kr_commission.value}', tag: 'AppRunData');
|
||||
},
|
||||
);
|
||||
} catch (e, stackTrace) {
|
||||
KRLogUtil.kr_e('💥 [AppRunData] 获取用户信息异常: $e', tag: 'AppRunData');
|
||||
KRLogUtil.kr_e('📚 [AppRunData] 错误堆栈: $stackTrace', tag: 'AppRunData');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,19 +41,24 @@ class KROutboundItem {
|
||||
|
||||
tag = nodeListItem.name; // 设置标签
|
||||
serverAddr = nodeListItem.serverAddr; // 设置服务器地址
|
||||
// 将 config 字符串转换为 Map<String, dynamic>
|
||||
city = nodeListItem.city; // 设置城市
|
||||
country = nodeListItem.country; // 设置国家
|
||||
|
||||
// 安全解析 config 字段
|
||||
// 新API格式:config为空,直接使用节点字段构建配置
|
||||
// 旧API格式:config包含JSON配置
|
||||
if (nodeListItem.config.isEmpty) {
|
||||
// 🔧 优先使用直接字段构建配置(新API格式)
|
||||
// 判断条件:如果有 port 和 serverAddr,说明是新格式
|
||||
if (nodeListItem.port > 0 && nodeListItem.serverAddr.isNotEmpty) {
|
||||
print('ℹ️ 节点 ${nodeListItem.name} 使用直接字段构建配置');
|
||||
_buildConfigFromFields(nodeListItem);
|
||||
return;
|
||||
}
|
||||
|
||||
// 兜底:尝试解析 config 字段(旧API格式)
|
||||
if (nodeListItem.config.isEmpty) {
|
||||
print('❌ 节点 ${nodeListItem.name} 缺少配置信息(无port或config)');
|
||||
config = {};
|
||||
return;
|
||||
}
|
||||
|
||||
late Map<String, dynamic> json;
|
||||
try {
|
||||
json = jsonDecode(nodeListItem.config) as Map<String, dynamic>;
|
||||
@ -228,17 +233,31 @@ class KROutboundItem {
|
||||
|
||||
/// 直接从节点字段构建配置(新API格式)
|
||||
void _buildConfigFromFields(KrNodeListItem nodeListItem) {
|
||||
print('🔧 开始构建节点配置 - 协议: ${nodeListItem.protocol}, 名称: ${nodeListItem.name}');
|
||||
print('📋 节点详细信息:');
|
||||
print(' - serverAddr: ${nodeListItem.serverAddr}');
|
||||
print(' - port: ${nodeListItem.port}');
|
||||
print(' - uuid: ${nodeListItem.uuid}');
|
||||
print(' - method: ${nodeListItem.method}');
|
||||
|
||||
switch (nodeListItem.protocol) {
|
||||
case "shadowsocks":
|
||||
// 优先使用 protocols 解析出来的 cipher,其次是 method 字段,最后才是默认值
|
||||
String finalMethod = nodeListItem.method.isNotEmpty
|
||||
? nodeListItem.method
|
||||
: "2022-blake3-aes-256-gcm";
|
||||
|
||||
config = {
|
||||
"type": "shadowsocks",
|
||||
"tag": nodeListItem.name,
|
||||
"server": nodeListItem.serverAddr,
|
||||
"server_port": nodeListItem.port,
|
||||
"method": "chacha20-ietf-poly1305", // 默认加密方法
|
||||
"method": finalMethod,
|
||||
"password": nodeListItem.uuid
|
||||
};
|
||||
print('✅ Shadowsocks 节点配置构建成功: ${nodeListItem.name}');
|
||||
print('📄 使用加密方法: $finalMethod');
|
||||
print('📄 完整配置: $config');
|
||||
break;
|
||||
case "vless":
|
||||
config = {
|
||||
@ -258,6 +277,7 @@ class KROutboundItem {
|
||||
}
|
||||
};
|
||||
print('✅ VLESS 节点配置构建成功: ${nodeListItem.name}');
|
||||
print('📄 完整配置: $config');
|
||||
break;
|
||||
case "vmess":
|
||||
config = {
|
||||
@ -276,6 +296,7 @@ class KROutboundItem {
|
||||
}
|
||||
};
|
||||
print('✅ VMess 节点配置构建成功: ${nodeListItem.name}');
|
||||
print('📄 完整配置: $config');
|
||||
break;
|
||||
case "trojan":
|
||||
config = {
|
||||
@ -292,6 +313,7 @@ class KROutboundItem {
|
||||
}
|
||||
};
|
||||
print('✅ Trojan 节点配置构建成功: ${nodeListItem.name}');
|
||||
print('📄 完整配置: $config');
|
||||
break;
|
||||
case "hysteria2":
|
||||
config = {
|
||||
@ -310,6 +332,7 @@ class KROutboundItem {
|
||||
}
|
||||
};
|
||||
print('✅ Hysteria2 节点配置构建成功: ${nodeListItem.name}');
|
||||
print('📄 完整配置: $config');
|
||||
break;
|
||||
default:
|
||||
print('⚠️ 不支持的协议类型: ${nodeListItem.protocol}');
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import 'dart:convert';
|
||||
import 'package:kaer_with_panels/app/utils/kr_log_util.dart';
|
||||
|
||||
class KRNodeList {
|
||||
@ -54,7 +55,9 @@ class KrNodeListItem {
|
||||
final String relayMode;
|
||||
final String relayNode;
|
||||
final String serverAddr;
|
||||
final int port; // 新增:端口字段
|
||||
final int port; // 端口字段
|
||||
final String method; // 加密方法(用于Shadowsocks等)
|
||||
final String protocols; // 协议配置JSON字符串(新API格式)
|
||||
final int speedLimit;
|
||||
final List<String> tags;
|
||||
final int traffic;
|
||||
@ -81,6 +84,8 @@ class KrNodeListItem {
|
||||
this.relayNode = '',
|
||||
required this.serverAddr,
|
||||
this.port = 0, // 默认值
|
||||
this.method = '', // 默认空字符串
|
||||
this.protocols = '', // 默认空字符串
|
||||
required this.speedLimit,
|
||||
required this.tags,
|
||||
required this.traffic,
|
||||
@ -102,10 +107,33 @@ class KrNodeListItem {
|
||||
factory KrNodeListItem.fromJson(Map<String, dynamic> json) {
|
||||
try {
|
||||
// 支持新旧两种API格式
|
||||
// 新格式: address, port
|
||||
// 最新格式: protocols 字段包含协议配置数组
|
||||
// 新格式: address, port, method(直接字段)
|
||||
// 旧格式: server_addr, config 中包含 port
|
||||
final serverAddr = json['address']?.toString() ?? json['server_addr']?.toString() ?? '';
|
||||
final port = _parseIntSafely(json['port']);
|
||||
int port = _parseIntSafely(json['port']);
|
||||
String method = json['method']?.toString() ?? ''; // 加密方法(Shadowsocks等)
|
||||
final protocols = json['protocols']?.toString() ?? ''; // 协议配置JSON
|
||||
|
||||
// 🔧 如果有 protocols 字段,从中解析 port 和 cipher
|
||||
if (protocols.isNotEmpty) {
|
||||
try {
|
||||
final protocolsList = jsonDecode(protocols) as List;
|
||||
if (protocolsList.isNotEmpty) {
|
||||
final firstProtocol = protocolsList[0] as Map<String, dynamic>;
|
||||
// 优先使用 protocols 中的配置
|
||||
if (firstProtocol['port'] != null) {
|
||||
port = _parseIntSafely(firstProtocol['port']);
|
||||
}
|
||||
if (firstProtocol['cipher'] != null && firstProtocol['cipher'].toString().isNotEmpty) {
|
||||
method = firstProtocol['cipher'].toString();
|
||||
}
|
||||
KRLogUtil.kr_i('从 protocols 解析: port=$port, cipher=$method', tag: 'NodeList');
|
||||
}
|
||||
} catch (e) {
|
||||
KRLogUtil.kr_w('解析 protocols 字段失败: $e', tag: 'NodeList');
|
||||
}
|
||||
}
|
||||
|
||||
return KrNodeListItem(
|
||||
id: _parseIntSafely(json['id']),
|
||||
@ -116,6 +144,8 @@ class KrNodeListItem {
|
||||
relayNode: json['relay_node']?.toString() ?? '',
|
||||
serverAddr: serverAddr,
|
||||
port: port,
|
||||
method: method,
|
||||
protocols: protocols,
|
||||
speedLimit: _parseIntSafely(json['speed_limit']),
|
||||
tags: _parseStringList(json['tags']),
|
||||
traffic: _parseIntSafely(json['traffic']),
|
||||
@ -142,6 +172,8 @@ class KrNodeListItem {
|
||||
protocol: '',
|
||||
serverAddr: '',
|
||||
port: 0,
|
||||
method: '',
|
||||
protocols: '',
|
||||
speedLimit: 0,
|
||||
tags: [],
|
||||
traffic: 0,
|
||||
|
||||
@ -6,7 +6,11 @@ class KRUserInfo {
|
||||
final String avatar;
|
||||
final String areaCode;
|
||||
final String telephone;
|
||||
final int balance;
|
||||
final int balance;
|
||||
final int commission;
|
||||
final int referralPercentage;
|
||||
final bool onlyFirstPurchase;
|
||||
final int giftAmount;
|
||||
|
||||
KRUserInfo({
|
||||
required this.id,
|
||||
@ -16,7 +20,11 @@ class KRUserInfo {
|
||||
this.avatar = '',
|
||||
this.areaCode = '',
|
||||
this.telephone = '',
|
||||
this.balance = 0
|
||||
this.balance = 0,
|
||||
this.commission = 0,
|
||||
this.referralPercentage = 0,
|
||||
this.onlyFirstPurchase = false,
|
||||
this.giftAmount = 0,
|
||||
});
|
||||
|
||||
factory KRUserInfo.fromJson(Map<String, dynamic> json) {
|
||||
@ -28,7 +36,11 @@ class KRUserInfo {
|
||||
avatar: json['avatar'] ?? '',
|
||||
areaCode: json['area_code'] ?? '',
|
||||
telephone: json['telephone'] ?? '',
|
||||
balance: json['balance'] ?? 0,
|
||||
balance: json['balance'] ?? 0,
|
||||
commission: json['commission'] ?? 0,
|
||||
referralPercentage: json['referral_percentage'] ?? 0,
|
||||
onlyFirstPurchase: json['only_first_purchase'] ?? false,
|
||||
giftAmount: json['gift_amount'] ?? 0,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ import 'package:kaer_with_panels/app/common/app_config.dart';
|
||||
import 'package:kaer_with_panels/app/common/app_run_data.dart';
|
||||
import 'package:kaer_with_panels/app/services/api_service/kr_api.user.dart';
|
||||
import 'package:kaer_with_panels/app/utils/kr_common_util.dart';
|
||||
import 'package:kaer_with_panels/app/utils/kr_log_util.dart';
|
||||
import 'package:kaer_with_panels/app/localization/app_translations.dart';
|
||||
import 'package:kaer_with_panels/app/routes/app_pages.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -72,15 +73,31 @@ class KRInviteController extends GetxController {
|
||||
}
|
||||
|
||||
// ⚠️ 已废弃:新版本后端不再提供 kr_getUserInfo 接口
|
||||
// 邀请码现在使用 AppConfig 中的固定值,等待新接口实现
|
||||
// 从 AppRunData 获取邀请码(登录后自动获取)
|
||||
Future<void> _kr_fetchUserInfo() async {
|
||||
try {
|
||||
kr_isLoading.value = true;
|
||||
|
||||
// 使用 AppConfig 中的固定邀请码
|
||||
kr_referCode.value = AppConfig.kr_userReferCode;
|
||||
KRLogUtil.kr_i('🔍 [InviteController] 开始获取邀请码...', tag: 'InviteController');
|
||||
|
||||
// 从 AppRunData 获取用户邀请码(已在登录时获取)
|
||||
final appData = KRAppRunData.getInstance();
|
||||
KRLogUtil.kr_i('📊 [InviteController] AppRunData 状态:', tag: 'InviteController');
|
||||
KRLogUtil.kr_i(' - kr_isLogin: ${appData.kr_isLogin.value}', tag: 'InviteController');
|
||||
KRLogUtil.kr_i(' - kr_account: ${appData.kr_account.value}', tag: 'InviteController');
|
||||
KRLogUtil.kr_i(' - kr_referCode: ${appData.kr_referCode.value}', tag: 'InviteController');
|
||||
KRLogUtil.kr_i(' - kr_balance: ${appData.kr_balance.value}', tag: 'InviteController');
|
||||
KRLogUtil.kr_i(' - kr_commission: ${appData.kr_commission.value}', tag: 'InviteController');
|
||||
|
||||
kr_referCode.value = appData.kr_referCode.value;
|
||||
KRLogUtil.kr_i('📋 [InviteController] 获取到邀请码: "${kr_referCode.value}"', tag: 'InviteController');
|
||||
|
||||
if (kr_referCode.value.isEmpty) {
|
||||
KRLogUtil.kr_w('⚠️ [InviteController] 邀请码为空!', tag: 'InviteController');
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
KRLogUtil.kr_e('❌ [InviteController] 获取邀请码失败: $e', tag: 'InviteController');
|
||||
KRCommonUtil.kr_showToast(e.toString());
|
||||
} finally {
|
||||
kr_isLoading.value = false;
|
||||
|
||||
@ -101,4 +101,7 @@ abstract class Api {
|
||||
|
||||
/// 获取可用支付方式(公开接口)
|
||||
static const String kr_getPublicPaymentMethods = "/v1/public/payment/methods";
|
||||
|
||||
/// 获取用户信息(用于获取邀请码等)
|
||||
static const String kr_getUserInfo = "/v1/public/user/info";
|
||||
}
|
||||
|
||||
@ -83,22 +83,22 @@ class KRUserApi {
|
||||
return right(baseResponse.model);
|
||||
}
|
||||
|
||||
// ⚠️ 已废弃:新版本后端不再提供此接口
|
||||
// Future<Either<HttpError, KRUserInfo>> kr_getUserInfo() async {
|
||||
// final Map<String, dynamic> data = <String, dynamic>{};
|
||||
// BaseResponse<KRUserInfo> baseResponse =
|
||||
// await HttpUtil.getInstance().request<KRUserInfo>(
|
||||
// Api.kr_getUserInfo,
|
||||
// data,
|
||||
// method: HttpMethod.GET,
|
||||
// isShowLoading: false,
|
||||
// );
|
||||
// if (!baseResponse.isSuccess) {
|
||||
// return left(
|
||||
// HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
|
||||
// }
|
||||
// return right(baseResponse.model);
|
||||
// }
|
||||
/// 获取用户信息(包含邀请码、余额、佣金等)
|
||||
static Future<Either<HttpError, KRUserInfo>> kr_getUserInfo() async {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
BaseResponse<KRUserInfo> baseResponse =
|
||||
await HttpUtil.getInstance().request<KRUserInfo>(
|
||||
Api.kr_getUserInfo,
|
||||
data,
|
||||
method: HttpMethod.GET,
|
||||
isShowLoading: false,
|
||||
);
|
||||
if (!baseResponse.isSuccess) {
|
||||
return left(
|
||||
HttpError(msg: baseResponse.retMsg, code: baseResponse.retCode));
|
||||
}
|
||||
return right(baseResponse.model);
|
||||
}
|
||||
|
||||
Future<Either<HttpError, KRAffiliateCount>> kr_getAffiliateCount() async {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
|
||||
@ -405,6 +405,26 @@ class KRSingBoxImp {
|
||||
KRLogUtil.kr_i('💾 开始保存配置文件...', tag: 'SingBox');
|
||||
KRLogUtil.kr_i('📊 出站节点数量: ${outbounds.length}', tag: 'SingBox');
|
||||
|
||||
// 打印每个节点的详细配置
|
||||
for (int i = 0; i < outbounds.length; i++) {
|
||||
final outbound = outbounds[i];
|
||||
KRLogUtil.kr_i('📋 节点[$i] 配置:', tag: 'SingBox');
|
||||
KRLogUtil.kr_i(' - type: ${outbound['type']}', tag: 'SingBox');
|
||||
KRLogUtil.kr_i(' - tag: ${outbound['tag']}', tag: 'SingBox');
|
||||
KRLogUtil.kr_i(' - server: ${outbound['server']}', tag: 'SingBox');
|
||||
KRLogUtil.kr_i(' - server_port: ${outbound['server_port']}', tag: 'SingBox');
|
||||
if (outbound['method'] != null) {
|
||||
KRLogUtil.kr_i(' - method: ${outbound['method']}', tag: 'SingBox');
|
||||
}
|
||||
if (outbound['password'] != null) {
|
||||
KRLogUtil.kr_i(' - password: ${outbound['password']?.toString().substring(0, 8)}...', tag: 'SingBox');
|
||||
}
|
||||
if (outbound['uuid'] != null) {
|
||||
KRLogUtil.kr_i(' - uuid: ${outbound['uuid']?.toString().substring(0, 8)}...', tag: 'SingBox');
|
||||
}
|
||||
KRLogUtil.kr_i(' - 完整配置: ${jsonEncode(outbound)}', tag: 'SingBox');
|
||||
}
|
||||
|
||||
kr_outbounds = outbounds;
|
||||
|
||||
final map = {};
|
||||
@ -415,7 +435,7 @@ class KRSingBoxImp {
|
||||
final mapStr = jsonEncode(map);
|
||||
|
||||
KRLogUtil.kr_i('📄 配置文件内容长度: ${mapStr.length}', tag: 'SingBox');
|
||||
KRLogUtil.kr_i('📄 配置文件前500字符: ${mapStr.substring(0, mapStr.length > 500 ? 500 : mapStr.length)}', tag: 'SingBox');
|
||||
KRLogUtil.kr_i('📄 完整配置文件内容: $mapStr', tag: 'SingBox');
|
||||
|
||||
await file.writeAsString(mapStr);
|
||||
await temp.writeAsString(mapStr);
|
||||
@ -525,35 +545,59 @@ class KRSingBoxImp {
|
||||
|
||||
//// 设置出站模式
|
||||
Future<void> kr_updateConnectionType(KRConnectionType newType) async {
|
||||
if (kr_connectionType.value == newType) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
KRLogUtil.kr_i('🔄 开始更新连接类型...', tag: 'SingBox');
|
||||
KRLogUtil.kr_i('📊 当前类型: ${kr_connectionType.value}', tag: 'SingBox');
|
||||
KRLogUtil.kr_i('📊 新类型: $newType', tag: 'SingBox');
|
||||
|
||||
kr_connectionType.value = newType;
|
||||
if (kr_connectionType.value == newType) {
|
||||
KRLogUtil.kr_i('⚠️ 连接类型相同,无需更新', tag: 'SingBox');
|
||||
return;
|
||||
}
|
||||
|
||||
final oOption = _getConfigOption();
|
||||
kr_connectionType.value = newType;
|
||||
|
||||
var mode = "";
|
||||
switch (newType) {
|
||||
case KRConnectionType.global:
|
||||
mode = "other";
|
||||
break;
|
||||
case KRConnectionType.rule:
|
||||
mode = KRCountryUtil.kr_getCurrentCountryCode();
|
||||
break;
|
||||
// case KRConnectionType.direct:
|
||||
// mode = "direct";
|
||||
// break;
|
||||
}
|
||||
oOption["region"] = mode;
|
||||
final op = SingboxConfigOption.fromJson(oOption);
|
||||
final oOption = _getConfigOption();
|
||||
|
||||
await kr_singBox.changeOptions(op)
|
||||
..map((r) {}).mapLeft((err) {
|
||||
KRLogUtil.kr_e('更新连接类型失败: $err');
|
||||
}).run();
|
||||
if (kr_status.value == SingboxStarted()) {
|
||||
await kr_restart();
|
||||
var mode = "";
|
||||
switch (newType) {
|
||||
case KRConnectionType.global:
|
||||
mode = "other";
|
||||
KRLogUtil.kr_i('🌍 切换到全局代理模式', tag: 'SingBox');
|
||||
break;
|
||||
case KRConnectionType.rule:
|
||||
mode = KRCountryUtil.kr_getCurrentCountryCode();
|
||||
KRLogUtil.kr_i('🎯 切换到规则代理模式: $mode', tag: 'SingBox');
|
||||
break;
|
||||
// case KRConnectionType.direct:
|
||||
// mode = "direct";
|
||||
// break;
|
||||
}
|
||||
oOption["region"] = mode;
|
||||
KRLogUtil.kr_i('📝 更新 region 配置: $mode', tag: 'SingBox');
|
||||
|
||||
final op = SingboxConfigOption.fromJson(oOption);
|
||||
KRLogUtil.kr_i('📄 配置选项: ${oOption.toString()}', tag: 'SingBox');
|
||||
|
||||
await kr_singBox.changeOptions(op)
|
||||
..map((r) {
|
||||
KRLogUtil.kr_i('✅ 连接类型更新成功', tag: 'SingBox');
|
||||
}).mapLeft((err) {
|
||||
KRLogUtil.kr_e('❌ 更新连接类型失败: $err', tag: 'SingBox');
|
||||
throw err;
|
||||
}).run();
|
||||
|
||||
if (kr_status.value == SingboxStarted()) {
|
||||
KRLogUtil.kr_i('🔄 VPN已启动,准备重启以应用新配置...', tag: 'SingBox');
|
||||
await kr_restart();
|
||||
KRLogUtil.kr_i('✅ VPN重启完成', tag: 'SingBox');
|
||||
} else {
|
||||
KRLogUtil.kr_i('ℹ️ VPN未启动,配置已更新', tag: 'SingBox');
|
||||
}
|
||||
} catch (e, stackTrace) {
|
||||
KRLogUtil.kr_e('💥 更新连接类型异常: $e', tag: 'SingBox');
|
||||
KRLogUtil.kr_e('📚 错误堆栈: $stackTrace', tag: 'SingBox');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user