feat: windows ico替换成圆角,macos增加tg代理

This commit is contained in:
speakeloudest 2026-01-17 18:59:09 -08:00
parent 5d00bf3404
commit 7017c99f4a
6 changed files with 230 additions and 30 deletions

View File

@ -33,13 +33,22 @@ make windows-release
### 🍎 iOS
> ios-release
- **证书管理**: 开发环境使用automativally模式自动生产环境需要下载hiFastVPN-iOs-Prod的profile
- **证书管理**: 开发环境使用automaticall模式自动生产环境需要下载hiFastVPN-iOs-Prod的profile
- ipa发布后使用 `Transporter.app`上传到苹果后台
- release apk路径在 `dist/对应版本号/*.ipa`,
#### 问题
- ios真机调试出现开发环境flutter运行一会就断开日志没法看并且生成flutter.log文件但在xcode可以正常看到日志
修改mac上的设置 -> 本机网络 -> android studio 开启
### 💻 macOS
> macos-release
- release apk路径在 `dist/对应版本号/*.dmg`,完成公证和dmg封面制作
#### 问题
- 启动过程中遇到 Crash occurred when compiling unknown function in unoptimized JIT mode in unknown pass
1. xcode修改配置 macOS -> signing Certificate -> 选择 sign to Run Locally
2. 使用automaticall
- 启动过程中页面卡在启动页 FFISingboxService - singbox native libs path: "libcore.dylib"
### 🪟 Windows
- 环境需要Inno Setup

View File

@ -1019,11 +1019,11 @@
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "HiFastVPN-iOS-Pord";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
@ -1251,12 +1251,12 @@
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "HiFastVPN-iOS-Pord";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
@ -1309,11 +1309,11 @@
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "HiFastVPN-iOS-Pord";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;

View File

@ -22,6 +22,7 @@ import '../../utils/kr_country_util.dart';
import '../../utils/kr_log_util.dart';
import '../../utils/kr_secure_storage.dart';
import '../../utils/kr_windows_dns_util.dart';
import '../../utils/kr_macos_proxy_util.dart';
import '../../common/app_run_data.dart';
import '../../common/app_config.dart';
import 'package:flutter/foundation.dart';
@ -297,6 +298,21 @@ class KRSingBoxImp {
KRLogUtil.kr_i('⏳ Windows 文件系统同步等待完成', tag: 'SingBox');
}
// 🍎 macOS
if (Platform.isMacOS) {
KRLogUtil.kr_i('🍎 macOS 平台,初始化时清理系统代理残留...', tag: 'SingBox');
try {
//
KRMacosProxyUtil.disableSocks5().then((_) {
KRLogUtil.kr_i('✅ macOS 系统代理残留清理完成', tag: 'SingBox');
}).catchError((e) {
KRLogUtil.kr_w('⚠️ macOS 系统代理清理异常: $e', tag: 'SingBox');
});
} catch (e) {
KRLogUtil.kr_w('⚠️ macOS 系统代理清理尝试失败: $e', tag: 'SingBox');
}
}
// setup() workingDir data 访
// libcore Setup() os.Chdir(workingPath)使 "./data"
// os.Chdir() 访
@ -1555,6 +1571,19 @@ class KRSingBoxImp {
throw err;
}).run();
// 🔑 macOS SOCKS5
if (Platform.isMacOS) {
KRLogUtil.kr_i('🍎 macOS 平台,开启系统 SOCKS5 代理...', tag: 'SingBox');
try {
await KRMacosProxyUtil.enableSocks5(
host: '127.0.0.1',
port: kr_port,
);
} catch (e) {
KRLogUtil.kr_w('⚠️ macOS 系统代理开启失败: $e', tag: 'SingBox');
}
}
//
//
// 1.
@ -1751,6 +1780,16 @@ class KRSingBoxImp {
// libcore status stream Stopped
KRLogUtil.kr_i('✅ SingBox 停止请求已发送', tag: 'SingBox');
// 🍎 macOS SOCKS5
if (Platform.isMacOS) {
KRLogUtil.kr_i('🍎 macOS 平台,关闭系统 SOCKS5 代理...', tag: 'SingBox');
try {
await KRMacosProxyUtil.disableSocks5();
} catch (e) {
KRLogUtil.kr_e('❌ macOS 系统代理关闭失败: $e', tag: 'SingBox');
}
}
} catch (e, stackTrace) {
KRLogUtil.kr_e('停止服务时出错: $e');
KRLogUtil.kr_e('错误堆栈: $stackTrace');

View File

@ -0,0 +1,113 @@
import 'dart:io';
import 'kr_log_util.dart';
/// macOS
///
/// 使 `networksetup` macOS SOCKS5
class KRMacosProxyUtil {
///
KRMacosProxyUtil._();
///
static Future<List<String>> _listNetworkServices() async {
try {
final r = await Process.run('networksetup', ['-listallnetworkservices']);
if (r.exitCode != 0) {
KRLogUtil.kr_e('列出网络服务失败: ${r.stderr}', tag: 'MacosProxy');
return [];
}
final lines = (r.stdout as String).split('\n').map((e) => e.trim()).toList();
//
return lines
.where((l) => l.isNotEmpty && !l.toLowerCase().contains('an asterisk'))
.skip(1)
.toList();
} catch (e) {
KRLogUtil.kr_e('列出网络服务异常: $e', tag: 'MacosProxy');
return [];
}
}
/// SOCKS5
static Future<void> enableSocks5({
required String host,
required int port,
}) async {
if (!Platform.isMacOS) return;
final services = await _listNetworkServices();
if (services.isEmpty) {
KRLogUtil.kr_w('未找到可用的网络服务', tag: 'MacosProxy');
return;
}
for (final service in services) {
try {
// 1) SOCKS5
final r1 = await Process.run('networksetup', [
'-setsocksfirewallproxy',
service,
host,
port.toString(),
]);
if (r1.exitCode != 0) {
KRLogUtil.kr_w('服务 [$service] 设置 SOCKS5 代理失败: ${r1.stderr}', tag: 'MacosProxy');
continue;
}
// 2) SOCKS5
final r2 = await Process.run('networksetup', [
'-setsocksfirewallproxystate',
service,
'on',
]);
if (r2.exitCode != 0) {
KRLogUtil.kr_w('服务 [$service] 启用 SOCKS5 代理失败: ${r2.stderr}', tag: 'MacosProxy');
continue;
}
KRLogUtil.kr_i('✅ 服务 [$service] SOCKS5 代理已启用: $host:$port', tag: 'MacosProxy');
} catch (e) {
KRLogUtil.kr_e('服务 [$service] 启用代理异常: $e', tag: 'MacosProxy');
}
}
}
/// SOCKS5
static Future<void> disableSocks5() async {
if (!Platform.isMacOS) return;
final services = await _listNetworkServices();
if (services.isEmpty) return;
for (final service in services) {
try {
final r = await Process.run('networksetup', [
'-setsocksfirewallproxystate',
service,
'off',
]);
if (r.exitCode == 0) {
KRLogUtil.kr_i('✅ 服务 [$service] SOCKS5 代理已关闭', tag: 'MacosProxy');
} else {
KRLogUtil.kr_w('服务 [$service] 关闭 SOCKS5 代理失败: ${r.stderr}', tag: 'MacosProxy');
}
} catch (e) {
KRLogUtil.kr_e('服务 [$service] 关闭代理异常: $e', tag: 'MacosProxy');
}
}
}
/// SOCKS5 ()
static Future<String> getSocks5Status(String serviceName) async {
try {
final r = await Process.run('networksetup', ['-getsocksfirewallproxy', serviceName]);
return r.stdout as String;
} catch (e) {
return '获取状态失败: $e';
}
}
}

View File

@ -3,6 +3,7 @@ import 'dart:convert';
import 'dart:ffi';
import 'dart:io';
import 'dart:isolate';
import 'package:flutter/foundation.dart';
import 'package:kaer_with_panels/utils/isolate_worker.dart';
import 'package:ffi/ffi.dart';
import 'package:fpdart/fpdart.dart';
@ -31,32 +32,80 @@ class FFISingboxService with InfraLogger implements SingboxService {
Stream<List<SingboxOutboundGroup>>? _outboundsStream;
static SingboxNativeLibrary _gen() {
String fullPath = "";
if (Platform.environment.containsKey('FLUTTER_TEST')) {
fullPath = "libcore";
}
if (Platform.isWindows) {
fullPath = p.join(fullPath, "libcore.dll");
} else if (Platform.isMacOS) {
fullPath = p.join(fullPath, "libcore.dylib");
} else {
fullPath = p.join(fullPath, "libcore.so");
}
String fullPath = _getLibraryPath();
_logger.debug('singbox native libs path: "$fullPath"');
final lib = DynamicLibrary.open(fullPath);
return SingboxNativeLibrary(lib);
}
static String _getLibraryPath() {
String libName;
if (Platform.isWindows) {
libName = "libcore.dll";
} else if (Platform.isMacOS) {
libName = "libcore.dylib";
} else {
libName = "libcore.so";
}
//
if (Platform.environment.containsKey('FLUTTER_TEST')) {
return p.join("libcore", libName);
}
// 🔧 使
//
final devPath = p.join("libcore", "bin", libName);
if (kDebugMode) {
print('🔍 [FFI] 检查开发环境路径: $devPath');
print('🔍 [FFI] 当前工作目录: ${Directory.current.path}');
print('🔍 [FFI] 文件是否存在: ${File(devPath).existsSync()}');
}
if (File(devPath).existsSync()) {
if (kDebugMode) {
print('✅ [FFI] 使用开发环境路径: $devPath');
}
return devPath;
}
// 使bundle中的路径
if (kDebugMode) {
print('⚠️ [FFI] 开发环境路径不存在,使用生产环境路径: $libName');
}
return libName;
}
@override
Future<void> init() async {
if (kDebugMode) {
print('🚀 [FFI] init() 开始');
}
loggy.debug("initializing");
_box.setupOnce(NativeApi.initializeApiDLData);
// setupOnce worker isolate _ffiLoadLibrary
// isolate
if (kDebugMode) {
print('⏭️ [FFI] 跳过主 isolate 中的 setupOnce将在 worker isolate 中执行)');
}
if (kDebugMode) {
print('📡 [FFI] 创建 ReceivePort');
}
_statusReceiver = ReceivePort('service status receiver');
if (kDebugMode) {
print('🔄 [FFI] 设置状态流');
}
final source = _statusReceiver.asBroadcastStream().map((event) => jsonDecode(event as String)).map(SingboxStatus.fromEvent);
_status = ValueConnectableStream.seeded(
source,
const SingboxStopped(),
).autoConnect();
if (kDebugMode) {
print('✅ [FFI] init() 完成');
}
}
@override
@ -495,17 +544,7 @@ class FFISingboxService with InfraLogger implements SingboxService {
}
SingboxNativeLibrary _ffiLoadLibrary() {
String fullPath = "";
if (Platform.environment.containsKey('FLUTTER_TEST')) {
fullPath = "libcore";
}
if (Platform.isWindows) {
fullPath = p.join(fullPath, "libcore.dll");
} else if (Platform.isMacOS) {
fullPath = p.join(fullPath, "libcore.dylib");
} else {
fullPath = p.join(fullPath, "libcore.so");
}
final fullPath = FFISingboxService._getLibraryPath();
final lib = DynamicLibrary.open(fullPath);
final box = SingboxNativeLibrary(lib);
box.setupOnce(NativeApi.initializeApiDLData);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB