|
@@ -4,6 +4,7 @@ import 'package:dio/dio.dart';
|
|
|
import 'package:get/get.dart';
|
|
|
import 'package:naiyouwl/app/bean/config.dart';
|
|
|
import 'package:naiyouwl/app/const/const.dart';
|
|
|
+import 'package:naiyouwl/app/controller/controllers.dart';
|
|
|
import 'package:yaml/yaml.dart';
|
|
|
import 'package:path/path.dart' as path;
|
|
|
import 'package:flutter_emoji/flutter_emoji.dart';
|
|
@@ -30,7 +31,9 @@ class ConfigController extends GetxController {
|
|
|
var clashCoreApiSecret = ''.obs;
|
|
|
var clashCoreDns = ''.obs;
|
|
|
var clashCoreTunEnable = false.obs;
|
|
|
- var servicePort = 0.obs;
|
|
|
+ var servicePort = 9899.obs;
|
|
|
+ var mixedPort = 9788.obs;
|
|
|
+ var ApiAddressPort = 9799.obs;
|
|
|
Future<void> initConfig() async {
|
|
|
|
|
|
|
|
@@ -51,10 +54,10 @@ class ConfigController extends GetxController {
|
|
|
} else {
|
|
|
config.value = Config.fromJson(_defaultConfig);
|
|
|
}
|
|
|
- bool bg = await isPortOccupied(config.value.servicePort);
|
|
|
- if(bg) {
|
|
|
- config.value.servicePort = await getFreePort();
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
if (config.value.subs.isEmpty) {
|
|
|
if (!await Files.configExample.exists()) {
|
|
|
await Files.assetsExample.copy(Files.configExample.path);
|
|
@@ -63,7 +66,7 @@ class ConfigController extends GetxController {
|
|
|
config.value.selected = 'example.yaml';
|
|
|
}
|
|
|
await save();
|
|
|
- await readClashCoreApi();
|
|
|
+ await makeInitConfig();
|
|
|
}
|
|
|
|
|
|
String nodeToYaml(NodeMode node) {
|
|
@@ -83,10 +86,38 @@ class ConfigController extends GetxController {
|
|
|
return '';
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ Future<void> makeInitConfig() async{
|
|
|
+
|
|
|
+ var mode = controllers.global.modesSelect;
|
|
|
+ var initconfig = '''
|
|
|
+mixed-port: ${mixedPort.value}
|
|
|
+allow-lan: true
|
|
|
+bind-address: '*'
|
|
|
+mode: $mode
|
|
|
+log-level: info
|
|
|
+external-controller: '127.0.0.1:${ApiAddressPort.value}'
|
|
|
+unified-delay: false
|
|
|
+geodata-mode: true
|
|
|
+tcp-concurrent: false
|
|
|
+find-process-mode: strict
|
|
|
+global-client-fingerprint: chrome
|
|
|
+proxies:
|
|
|
+rules:
|
|
|
+ - MATCH,DIRECT
|
|
|
+ ''';
|
|
|
+
|
|
|
+ await Files.makeInitProxyConfig.writeAsString(initconfig);
|
|
|
+ config.value.selected = 'init_proxy.yaml';
|
|
|
+ await readClashCoreApi();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
Future<void> makeClashConfig(List<NodeMode> nodes) async{
|
|
|
- if( Files.makeProxyConfig.existsSync()){
|
|
|
- Files.makeProxyConfig.deleteSync(recursive: true);
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
var stack = "system";
|
|
|
if( Platform.isWindows){
|
|
@@ -97,18 +128,10 @@ class ConfigController extends GetxController {
|
|
|
{
|
|
|
dnsPort = 53;
|
|
|
}
|
|
|
- var mixedport = 9888;
|
|
|
- bool bg = await isPortOccupied(mixedport);
|
|
|
- if(bg) {
|
|
|
- mixedport = await getFreePort();
|
|
|
- }
|
|
|
- var extePort = 9777;
|
|
|
- final ac = await isPortOccupied(extePort);
|
|
|
- if(ac) {
|
|
|
- extePort = await getFreePort();
|
|
|
- }
|
|
|
- var proxies = nodes.map(nodeToYaml).toList();
|
|
|
|
|
|
+
|
|
|
+ var mode = controllers.global.modesSelect;
|
|
|
+ var proxies = nodes.map(nodeToYaml).toList();
|
|
|
var proxyGroups = '''
|
|
|
proxy-groups:
|
|
|
- name: proxy
|
|
@@ -124,12 +147,12 @@ rules:
|
|
|
''';
|
|
|
|
|
|
var initconfig = '''
|
|
|
-mixed-port: $mixedport
|
|
|
+mixed-port: ${mixedPort.value}
|
|
|
allow-lan: true
|
|
|
bind-address: '*'
|
|
|
-mode: Rule
|
|
|
+mode: $mode
|
|
|
log-level: info
|
|
|
-external-controller: '127.0.0.1:$extePort'
|
|
|
+external-controller: '127.0.0.1:${ApiAddressPort.value}'
|
|
|
unified-delay: false
|
|
|
geodata-mode: true
|
|
|
tcp-concurrent: false
|
|
@@ -179,7 +202,7 @@ $rules
|
|
|
|
|
|
await Files.makeProxyConfig.writeAsString(initconfig);
|
|
|
config.value.selected = 'proxy.yaml';
|
|
|
-
|
|
|
+ await readClashCoreApi();
|
|
|
}
|
|
|
|
|
|
Future<void> save() async {
|
|
@@ -187,6 +210,7 @@ $rules
|
|
|
}
|
|
|
|
|
|
Future<void> readClashCoreApi() async {
|
|
|
+
|
|
|
final configStr = await File(path.join(Paths.config.path, config.value.selected)).readAsString();
|
|
|
|
|
|
|
|
@@ -208,6 +232,11 @@ $rules
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ Future<void> setSerivcePort(int port) async {
|
|
|
+ config.value.servicePort = port;
|
|
|
+ await save();
|
|
|
+ config.refresh();
|
|
|
+ }
|
|
|
|
|
|
Future<void> setLanguage(String language) async {
|
|
|
config.value.language = language;
|
|
@@ -302,12 +331,35 @@ $rules
|
|
|
config.refresh();
|
|
|
}
|
|
|
|
|
|
+ Future<void> portDetection() async {
|
|
|
+ bool isOk = await isPortOccupied(mixedPort.value);
|
|
|
+ if(isOk){
|
|
|
+ mixedPort.value = await getFreePort();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ isOk = await isPortOccupied(ApiAddressPort.value);
|
|
|
+ if(isOk){
|
|
|
+ ApiAddressPort.value = await getFreePort();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if(!controllers.service.isRunning){
|
|
|
+ isOk = await isPortOccupied(servicePort.value);
|
|
|
+ if(isOk){
|
|
|
+ servicePort.value = await getFreePort();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
Future<int> getFreePort() async {
|
|
|
var server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
|
|
|
int port = server.port;
|
|
|
await server.close();
|
|
|
return port;
|
|
|
}
|
|
|
+
|
|
|
Future<bool> isPortOccupied(int port) async {
|
|
|
bool isOccupied = false;
|
|
|
ServerSocket? server;
|