alroyso 1 year ago
parent
commit
1f612872fa

+ 26 - 0
lib/modes/clash/app.dart

@@ -0,0 +1,26 @@
+import 'bash.dart';
+import 'dns.dart';
+import 'groups.dart';
+import 'proxies.dart';
+import 'rules.dart';
+import 'tun.dart';
+
+class AppConfig {
+  final BasicConfig basicConfig;
+  final DNSConfig dnsConfig;
+  final TunConfig tunConfig;
+  final List<ProxyConfig> proxies;
+  final List<ProxyGroup> proxyGroups;
+  final List<Rule> rules;
+
+  AppConfig({
+    required this.basicConfig,
+    required this.dnsConfig,
+    required this.proxies,
+    required this.proxyGroups,
+    required this.rules,
+    required this.tunConfig,
+  });
+
+// 解析整个配置文件的方法
+}

+ 77 - 0
lib/modes/clash/bash.dart

@@ -0,0 +1,77 @@
+class BasicConfig {
+  final int mixedPort;
+  final bool allowLan;
+  final String bindAddress;
+  final String mode;
+  final String logLevel;
+  final String externalController;
+  final bool unifiedDelay;
+  final bool geodataMode;
+  final bool tcpConcurrent;
+  final String findProcessMode;
+  final String globalClientFingerprint;
+
+  BasicConfig({
+    required this.mixedPort,
+    required this.allowLan,
+    required this.bindAddress,
+    required this.mode,
+    required this.logLevel,
+    required this.externalController,
+    required this.unifiedDelay,
+    required this.geodataMode,
+    required this.tcpConcurrent,
+    required this.findProcessMode,
+    required this.globalClientFingerprint,
+  });
+
+// 可以添加一个方法来从Map或JSON解析创建BasicConfig实例
+  factory BasicConfig.fromMap(Map<String, dynamic> map) {
+    return BasicConfig(
+      mixedPort: map['mixed-port'],
+      allowLan: map['allow-lan'],
+      bindAddress: map['bind-address'],
+      mode: map['mode'],
+      logLevel: map['log-level'],
+      externalController: map['external-controller'],
+      unifiedDelay: map['unified-delay'],
+      geodataMode: map['geodata-mode'],
+      tcpConcurrent: map['tcp-concurrent'],
+      findProcessMode: map['find-process-mode'],
+      globalClientFingerprint: map['global-client-fingerprint'],
+    );
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'mixed-port': mixedPort,
+      'allow-lan': allowLan,
+      'bind-address': bindAddress,
+      'mode': mode,
+      'log-level': logLevel,
+      'external-controller': externalController,
+      'unified-delay': unifiedDelay,
+      'geodata-mode': geodataMode,
+      'tcp-concurrent': tcpConcurrent,
+      'find-process-mode': findProcessMode,
+      'global-client-fingerprint': globalClientFingerprint,
+    };
+  }
+
+  String toYaml() {
+    return '''
+mixed-port: $mixedPort
+allow-lan: $allowLan
+bind-address: '$bindAddress'
+mode: $mode
+log-level: $logLevel
+external-controller: '$externalController'
+unified-delay: $unifiedDelay
+geodata-mode: $geodataMode
+tcp-concurrent: $tcpConcurrent
+find-process-mode: $findProcessMode
+global-client-fingerprint: $globalClientFingerprint
+''';
+  }
+
+}

+ 75 - 0
lib/modes/clash/dns.dart

@@ -0,0 +1,75 @@
+class DNSConfig {
+  final bool enable;
+  final String listen;
+  final bool ipv6;
+  final String enhancedMode;
+  final List<String> defaultNameserver;
+  final List<String> nameserver;
+  final List<String> proxyServerNameserver;
+  final Map<String, List<String>> nameserverPolicy;
+
+  DNSConfig({
+    required this.enable,
+    required this.listen,
+    required this.ipv6,
+    required this.enhancedMode,
+    required this.defaultNameserver,
+    required this.nameserver,
+    required this.proxyServerNameserver,
+    required this.nameserverPolicy,
+  });
+
+// 同样可以添加解析方法
+  factory DNSConfig.fromMap(Map<String, dynamic> map) {
+    return DNSConfig(
+      enable: map['enable'],
+      listen: map['listen'],
+      ipv6: map['ipv6'],
+      enhancedMode: map['enhanced-mode'],
+      defaultNameserver: List<String>.from(map['default-nameserver']),
+      nameserver: List<String>.from(map['nameserver']),
+      proxyServerNameserver: List<String>.from(map['proxy-server-nameserver']),
+      nameserverPolicy: Map.from(map['nameserver-policy']).map((key, value) => MapEntry(key, List<String>.from(value))),
+    );
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'enable': enable,
+      'listen': listen,
+      'ipv6': ipv6,
+      'enhanced-mode': enhancedMode,
+      'default-nameserver': defaultNameserver,
+      'nameserver': nameserver,
+      'proxy-server-nameserver': proxyServerNameserver,
+      'nameserver-policy': nameserverPolicy.map((key, value) => MapEntry(key, value)),
+    };
+  }
+
+  String toYaml() {
+    return '''
+dns:
+  enable: $enable
+  listen: '$listen'
+  ipv6: $ipv6
+  enhanced-mode: $enhancedMode
+  default-nameserver:
+    ${defaultNameserver.map((ns) => '    - $ns').join('\n')}
+  nameserver:
+    ${nameserver.map((ns) => '    - $ns').join('\n')}
+  proxy-server-nameserver:
+    ${proxyServerNameserver.map((ns) => '    - $ns').join('\n')}
+  nameserver-policy:
+    ${_mapToYaml(nameserverPolicy)}
+''';
+  }
+
+  String _mapToYaml(Map<String, List<String>> map) {
+    var yamlString = '';
+    map.forEach((key, value) {
+      yamlString += '    "$key":\n      ${value.map((v) => '- $v').join('\n      ')}\n';
+    });
+    return yamlString;
+  }
+
+}

+ 37 - 0
lib/modes/clash/groups.dart

@@ -0,0 +1,37 @@
+class ProxyGroup {
+  final String name;
+  final String type;
+  final List<String> proxies;
+
+  ProxyGroup({
+    required this.name,
+    required this.type,
+    required this.proxies,
+  });
+
+  factory ProxyGroup.fromMap(Map<String, dynamic> map) {
+    return ProxyGroup(
+      name: map['name'],
+      type: map['type'],
+      proxies: List<String>.from(map['proxies']),
+    );
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'name': name,
+      'type': type,
+      'proxies': proxies,
+    };
+  }
+
+  String toYaml() {
+    var proxiesYaml = proxies.map((p) => '    - $p').join('\n');
+    return '''
+  - name: $name
+    type: $type
+    proxies:
+$proxiesYaml
+''';
+  }
+}

+ 110 - 0
lib/modes/clash/proxies.dart

@@ -0,0 +1,110 @@
+class ProxyConfig {
+  final String name;
+  final String type;
+  final String server;
+  final int port;
+  final String password;
+  final bool udp;
+  // vless
+  final String? flow;
+  final String? servername;
+  final bool? tls;
+  final Reality? realityOpts;
+  // V2Ray/VLESS特定属性
+  final String? uuid;
+  final int? alterId;
+  // Shadowsocks特定属性
+  final String? cipher;
+  ProxyConfig({
+    required this.name,
+    required this.type,
+    required this.server,
+    required this.port,
+    required this.password,
+    required this.udp,
+    this.flow,
+    this.servername,
+    this.tls,
+    this.realityOpts, // 新增字段
+    this.uuid,
+    this.alterId,
+    this.cipher
+  });
+
+  // 更新解析方法
+  factory ProxyConfig.fromMap(Map<String, dynamic> map) {
+    return ProxyConfig(
+      name: map['name'],
+      type: map['type'],
+      server: map['server'],
+      port: map['port'],
+      password: map['password'],
+      udp: map['udp'],
+      flow: map['flow'],
+      servername: map['servername'],
+      tls: map['tls'],
+      realityOpts: map['reality-opts'] != null ? Reality.fromMap(map['reality-opts']) : null,
+      uuid: map['uuid'],
+      alterId: map['alterId'],
+      cipher:map['cipher']
+    );
+  }
+
+  // 更新 JSON 序列化方法
+  Map<String, dynamic> toJson() {
+    return {
+      'name': name,
+      'type': type,
+      'server': server,
+      'port': port,
+      'password': password,
+      'udp': udp,
+      'flow': flow,
+      'servername': servername,
+      'tls': tls,
+      'reality-opts': realityOpts?.toJson(),
+      'uuid': uuid,
+      'alterId': alterId,
+      'cipher' : cipher
+    };
+  }
+
+  String toYaml() {
+    return '''
+- name: $name
+  type: $type
+  server: $server
+  port: $port
+  password: $password
+  udp: $udp
+  flow: $flow
+  servername: $servername
+  tls: $tls ?? ''
+  ${realityOpts?.toYaml() ?? ''}
+  uuid: $uuid ?? ''
+  alterId: $alterId ?? ''
+  cipher : $cipher ?? ''
+''';
+  }
+}
+class Reality {
+  final String? publicKey;
+
+  Reality({this.publicKey});
+
+  factory Reality.fromMap(Map<String, dynamic> map) {
+    return Reality(
+      publicKey: map['public-key'] as String?,
+    );
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'public-key': publicKey,
+    };
+  }
+
+  String toYaml() {
+    return publicKey != null ? 'reality-opts:\n  public-key: $publicKey' : '';
+  }
+}

+ 40 - 0
lib/modes/clash/rules.dart

@@ -0,0 +1,40 @@
+/*
+  - GEOSITE,geolocation-!cn,proxy
+  - GEOSITE,cn,DIRECT
+  - GEOIP,CN,DIRECT
+  - MATCH,proxy
+*/
+
+class Rule {
+  final String type;
+  final String condition;
+  final String action;
+
+  Rule({
+    required this.type,
+    required this.condition,
+    required this.action,
+  });
+
+  factory Rule.fromMap(Map<String, dynamic> map) {
+    return Rule(
+      type: map['type'],
+      condition: map['condition'],
+      action: map['action'],
+    );
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'type': type,
+      'condition': condition,
+      'action': action,
+    };
+  }
+
+  String toYaml() {
+    return '''
+  - $type,$condition,$action
+''';
+  }
+}

+ 47 - 0
lib/modes/clash/tun.dart

@@ -0,0 +1,47 @@
+class TunConfig {
+  final bool enable;
+  final String stack;
+  final List<String> dnsHijack;
+  final bool autoRoute;
+  final bool autoDetectInterface;
+
+  TunConfig({
+    required this.enable,
+    required this.stack,
+    required this.dnsHijack,
+    required this.autoRoute,
+    required this.autoDetectInterface,
+  });
+
+  factory TunConfig.fromMap(Map<String, dynamic> map) {
+    return TunConfig(
+      enable: map['enable'] ?? false,
+      stack: map['stack'] ?? 'system',
+      dnsHijack: List<String>.from(map['dns-hijack'] ?? []),
+      autoRoute: map['auto-route'] ?? false,
+      autoDetectInterface: map['auto-detect-interface'] ?? false,
+    );
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'enable': enable,
+      'stack': stack,
+      'dns-hijack': dnsHijack,
+      'auto-route': autoRoute,
+      'auto-detect-interface': autoDetectInterface,
+    };
+  }
+
+  String toYaml() {
+    return '''
+tun:
+  enable: $enable
+  stack: $stack
+  dns-hijack:
+    ${dnsHijack.map((item) => '    - $item').join('\n')}
+  auto-route: $autoRoute
+  auto-detect-interface: $autoDetectInterface
+''';
+  }
+}