cauto 1 سال پیش
والد
کامیت
009b18b7b9
6فایلهای تغییر یافته به همراه75 افزوده شده و 13 حذف شده
  1. 5 1
      lib/app/bean/config.dart
  2. 23 0
      lib/app/bean/config_service.dart
  3. 27 3
      lib/app/controller/config.dart
  4. 15 5
      lib/app/controller/service.dart
  5. 1 1
      macos/Podfile.lock
  6. 4 3
      scripts/init.dart

+ 5 - 1
lib/app/bean/config.dart

@@ -8,6 +8,7 @@ class Config {
     required this.breakConnections,
     required this.subs,
     required this.language,
+    required this.port
   });
   late String selected;
   late int updateInterval;
@@ -16,6 +17,7 @@ class Config {
   late bool startAtLogin;
   late bool breakConnections;
   late String language;
+  late int port;
   late List<ConfigSub> subs;
 
   Config.fromJson(Map<String, dynamic> json) {
@@ -26,6 +28,7 @@ class Config {
     startAtLogin = json['startAtLogin'];
     breakConnections = json['breakConnections'];
     language = json['language'];
+    port = json['port'];
     subs = List.from(json['subs']).map((e) => ConfigSub.fromJson(e)).toList();
   }
 
@@ -38,6 +41,7 @@ class Config {
     data['startAtLogin'] = startAtLogin;
     data['breakConnections'] = breakConnections;
     data['language'] = language;
+    data['port'] = port;
     data['subs'] = subs.map((e) => e.toJson()).toList();
     return data;
   }
@@ -96,7 +100,7 @@ class ConfigSubInfo {
   int? total;
   int? expire;
 
-  ConfigSubInfo.fromJson(Map<dynamic, dynamic> json) {
+  ConfigSubInfo.fromJson(Map<String, dynamic> json) {
     upload = json['upload'];
     download = json['download'];
     total = json['total'];

+ 23 - 0
lib/app/bean/config_service.dart

@@ -0,0 +1,23 @@
+
+class ConfigService {
+  late final port;
+
+  ConfigService({
+    required this.port,
+
+  });
+
+  ConfigService.fromJson(Map<String, dynamic> json) {
+    port = json['port'];
+  }
+
+  Map<String, dynamic> toJson() {
+    final data = <String, dynamic>{};
+    return data;
+  }
+
+  @override
+  String toString() {
+    return toJson().toString();
+  }
+}

+ 27 - 3
lib/app/controller/config.dart

@@ -16,6 +16,7 @@ final Map<String, dynamic> _defaultConfig = {
   'startAtLogin': false,
   'breakConnections': false,
   'language': 'zh_CN',
+  'port': 9899,
   'subs': [],
 };
 
@@ -27,8 +28,10 @@ class ConfigController extends GetxController {
   var clashCoreApiSecret = ''.obs;
   var clashCoreDns = ''.obs;
   var clashCoreTunEnable = false.obs;
-
+  var servicePort = 0.obs;
   Future<void> initConfig() async {
+
+    var port = await getFreePort();
     //dio.addSentry();
     dio = Dio(BaseOptions(baseUrl: clashCoreApiAddress.value));
     if (!await Paths.config.exists()) await Paths.config.create(recursive: true);
@@ -43,6 +46,8 @@ class ConfigController extends GetxController {
     } else {
       config.value = Config.fromJson(_defaultConfig);
     }
+    config.value.port = port;
+
     if (config.value.subs.isEmpty) {
       if (!await Files.configExample.exists()) await Files.assetsExample.copy(Files.configExample.path);
       config.value.subs.add(ConfigSub(name: 'example.yaml', url: '', updateTime: 0));
@@ -119,8 +124,19 @@ class ConfigController extends GetxController {
     sub.updateTime = DateTime.now().millisecondsSinceEpoch ~/ 1000;
     sub.info = null;
     if (subInfo != null) {
-      final info = Map.fromEntries(
-          subInfo.first.split(RegExp(r';\s*')).where((s) => s.isNotEmpty).map((e) => e.split('=')).map((e) => MapEntry(e[0], int.parse(e[1]))));
+      // final info = Map.fromEntries(
+      //     subInfo.first.split(RegExp(r';\s*')).where((s) => s.isNotEmpty).map((e) => e.split('=')).map((e) => MapEntry(e[0], int.parse(e[1]))));
+      final entries = subInfo.first.split(RegExp(r';\s*'))
+          .where((s) => s.isNotEmpty)
+          .map((e) => e.split('='))
+          .toList();
+
+      final info = <String, dynamic>{};
+
+      for (var entry in entries) {
+        info[entry[0]] = int.parse(entry[1]);
+      }
+
       sub.info = ConfigSubInfo.fromJson(info);
     }
     await setSub(sub.name, sub);
@@ -159,4 +175,12 @@ class ConfigController extends GetxController {
     await save();
     config.refresh();
   }
+
+  Future<int> getFreePort() async {
+    var server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
+    int port = server.port;
+    await server.close();
+    return port;
+  }
+
 }

+ 15 - 5
lib/app/controller/service.dart

@@ -24,10 +24,10 @@ import 'package:web_socket_channel/io.dart';
 final headers = {"User-Agent": "naiyou-for-flutter/0.0.1"};
 
 class ServiceController extends GetxController {
-  final dio = Dio(BaseOptions(baseUrl: 'http://127.0.0.1:9899', headers: headers));
+  late final dio ;
 
   var serviceMode = false.obs;
-
+  var servicePort = 0.obs;
   var coreStatus = RunningState.stoped.obs;
   var serviceStatus = RunningState.stoped.obs;
 
@@ -40,11 +40,13 @@ class ServiceController extends GetxController {
   bool get isCanOperationCore =>
       serviceStatus.value == RunningState.running && ![RunningState.starting, RunningState.stopping].contains(coreStatus.value);
 
-  ServiceController() {
-    //dio.addSentry();
-  }
+  ServiceController();
 
   Future<void> startService() async {
+    servicePort.value = await getFreePort();
+    dio = Dio(BaseOptions(baseUrl: 'http://127.0.0.1:${servicePort.value}', headers: headers));
+
+
     serviceStatus.value = RunningState.starting;
     if (Platform.isLinux) {
       await fixBinaryExecutePermissions(Files.assetsClashService);
@@ -158,6 +160,7 @@ class ServiceController extends GetxController {
 
     Future<void> install() async {
       final res = await runAsAdmin(Files.assetsClashService.path, ["stop", "uninstall", "install", "start"]);
+
       log.debug('install', res.stdout, res.stderr);
       if (res.exitCode != 0) throw res.stderr;
       await waitServiceStart();
@@ -239,4 +242,11 @@ class ServiceController extends GetxController {
         BotToast.showText(text: '重启成功');
       }
     }
+
+  Future<int> getFreePort() async {
+    var server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
+    int port = server.port;
+    await server.close();
+    return port;
+  }
 }

+ 1 - 1
macos/Podfile.lock

@@ -94,4 +94,4 @@ SPEC CHECKSUMS:
 
 PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367
 
-COCOAPODS: 1.12.1
+COCOAPODS: 1.13.0

+ 4 - 3
scripts/init.dart

@@ -14,8 +14,9 @@ final binDir = Directory(path.join(assetsPath, 'bin'));
 final depDir = Directory(path.join(assetsPath, 'dep'));
 
 Future downloadLatestClashCore() async {
-  final String clashCoreName = 'clash-${ClashName.platform}-${ClashName.arch}';
-
+  final version = "v1.16.0";
+  final String clashCoreName = 'clash.meta-${ClashName.platform}-${ClashName.arch}-cgo-$version';
+  print(clashCoreName);
   final info = await dio.get('https://api.github.com/repos/MetaCubeX/Clash.Meta/releases');
   final Map<String, dynamic> latest = (info.data['assets'] as List<dynamic>).firstWhere((it) => (it['name'] as String).contains(clashCoreName));
 
@@ -92,7 +93,7 @@ void main() async {
   if (!(await binDir.exists())) await binDir.create();
   if (!(await depDir.exists())) await depDir.create();
 
-  // await downloadLatestClashCore();
+  await downloadLatestClashCore();
   // await downloadLatestClashService();
 
   await downloadCountryMmdb();