import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:flutter/services.dart'; import 'package:path/path.dart' as path; import 'package:path_provider/path_provider.dart'; import '../../utils/log/logger.dart'; import '../constants/enums.dart'; import 'base_core_api.dart'; import 'windows/vpn_windows_service.dart'; /// Windows 实现 class WindowsCoreApi implements BaseCoreApi { static const _tag = 'WindowsCoreApi'; WindowsCoreApi._() { _initEventChannel(); // 初始化vpn服务 _initVpnService(); } // 创建vpn服务 static final _vpn = VpnWindowsService(); StreamSubscription? _ssStatus; bool _isVpnInited = false; /// 内部构造方法,供 BaseCoreApi 工厂使用 factory WindowsCoreApi.create() => WindowsCoreApi._(); // Windows Method Channel static const MethodChannel _channel = MethodChannel('app.xixi.nomo/core_api'); // Windows 事件流控制器 static final StreamController _eventController = StreamController.broadcast(); // Windows 事件流 static Stream get eventStream => _eventController.stream; // 初始化事件监听 void _initEventChannel() { // 监听来自 Windows 原生端的方法调用 _channel.setMethodCallHandler(_handleMethodCall); } // 处理来自 Windows 原生端的方法调用 Future _handleMethodCall(MethodCall call) async { switch (call.method) { case 'onEventChange': // 原生端发送事件,转发到事件流 final String event = call.arguments as String; _eventController.add(event); return null; default: throw PlatformException( code: 'Unimplemented', message: 'Method ${call.method} not implemented', ); } } void _initVpnService() { if (_isVpnInited) { return; } _isVpnInited = true; // 初始化vpn服务 10秒超时 _vpn.initialize(10, false); // 监听VPN服务状态 _ssStatus = _vpn.onStatusChanged.listen((event) async { switch (event) { case ConnectionState.connecting: // 正在连接 _eventController.add( '{"type":"vpn_status","status":1,"code":0,"message":""}', ); break; // 已经连接 case ConnectionState.connected: _eventController.add( '{"type":"vpn_status","status":2,"code":0,"message":""}', ); break; // 连接错误 case ConnectionState.error: _eventController.add( '{"type":"vpn_status","status":3,"code":0,"message":""}', ); _vpn.stop(); break; // 已经断开 case ConnectionState.disconnected: _eventController.add( '{"type":"vpn_status","status":0,"code":0,"message":""}', ); break; } // TODO: 通知状态变更 }); } @override Future getApps() async { // Windows 不需要获取应用列表 return null; } @override Future getSystemLocale() async { return Platform.localeName; } @override Future connect( String sessionId, int socksPort, String tunnelConfig, String configJson, int remainTime, bool isCountdown, List allowVpnApps, List disallowVpnApps, String accessToken, String aesKey, String aesIv, int locationId, String locationCode, List baseUrls, String params, int peekTimeInterval, ) async { try { String geoPath = await _getGeoDirectory(); log(_tag, 'geoPath: $geoPath'); final selfExecutable = Platform.resolvedExecutable; //List apps = isSplitTunnelEnabled ? splitTunnelApps : []; List allowExes = []; List disallowExes = [selfExecutable]; // 连接vpn Map params = { 'sessionId': sessionId, 'connectOptions': jsonEncode({ 'geoPath': geoPath, 'nodesConfig': configJson, }), 'allowExes': allowExes, 'disallowExes': disallowExes, }; log(_tag, jsonEncode(params)); // 连接vpn _vpn.start(params); return true; } catch (e) { // 通知连接出错 _eventController.add( '{"type":"vpn_status","status":3,"code":0,"message":""}', ); //logger.e('get nodes error: $e'); return false; } } @override Future disconnect() async { // 实现 Windows 断开连接逻辑 await _vpn.stop(); return true; } @override Future getRemoteIp() async { // 实现 Windows 获取远程 IP return await _vpn.getRemoteAddress(); } @override Future getAdvertisingId() async { // Windows 不支持广告 ID return null; } @override Future moveTaskToBack() async { // Windows 不需要此功能 return true; } @override Future isConnected() async { return _vpn.isOnline && _vpn.status == ConnectionState.connected; } @override Future getSimInfo() async { // Windows 不支持 SIM 卡信息 return null; } @override Future getChannel() async { // TODO: 实现 Windows 渠道获取 return 'windows'; } /// 发送事件(供 Windows 实现内部使用) /// /// Windows 原生端可以通过 MethodChannel 发送事件: /// ```cpp /// // C++ 示例 /// flutter::MethodChannel channel( /// messenger, "app.xixi.nomo/core_api", /// &flutter::StandardMethodCodec::GetInstance()); /// /// // 发送 VPN 状态变化 /// channel.InvokeMethod("onEventChange", /// flutter::EncodableValue("{\"type\":\"vpn_status\",\"status\":2}")); /// ``` /// /// 事件 JSON 格式: /// - vpn_status: {"type":"vpn_status","status":0|1|2|3,"code":0,"message":""} /// - status: 0=idle, 1=connecting, 2=connected, 3=error /// - timer_update: {"type":"timer_update","currentTime":123,"mode":"countdown"} /// - boost_result: {"type":"boost_result","locationCode":"US","nodeId":"xxx","success":true} static void sendEvent(String event) { _eventController.add(event); } /// 释放资源 static void dispose() { _eventController.close(); } /// 获取 geo 文件目录 Future _getGeoDirectory() async { try { final appDir = await getApplicationSupportDirectory(); final geoDir = Directory(path.join(appDir.path, 'geo')); return geoDir.path; } catch (_) { return ''; } } }