class ClashConfig { final String logLevel; final bool? ipv6; final bool? allowLan; final String? bindAddress; final String mode; final int mixedPort; final String? externalController; final bool? unifiedDelay; final bool? geodataMode; final bool? tcpConcurrent; final String? findProcessMode; final String? globalClientFingerprint; final Map? profile; final Sniffer? sniffer; final DNS? dns; final Tun? tun; final List>? proxies; final List? proxyGroups; final List? rules; ClashConfig({ required this.logLevel, this.ipv6, this.allowLan, this.bindAddress, required this.mode, required this.mixedPort, this.externalController, this.unifiedDelay, this.geodataMode, this.tcpConcurrent, this.findProcessMode, this.globalClientFingerprint, this.profile, this.sniffer, this.dns, this.tun, this.proxies, this.proxyGroups, this.rules, }); factory ClashConfig.fromJson(Map json) { return ClashConfig( logLevel: json['log-level'], ipv6: json['ipv6'], allowLan: json['allow-lan'], bindAddress: json['bind-address'], mode: json['mode'], mixedPort: json['mixed-port'], externalController: json['external-controller'], unifiedDelay: json['unified-delay'], geodataMode: json['geodata-mode'], tcpConcurrent: json['tcp-concurrent'], findProcessMode: json['find-process-mode'], globalClientFingerprint: json['global-client-fingerprint'], profile: json['profile'] != null ? Map.from(json['profile']) : null, sniffer: json['sniffer'] != null ? Sniffer.fromJson(json['sniffer']) : null, dns: DNS.fromJson(json['dns']), tun: json['tun'] != null ? Tun.fromJson(json['tun']) : null, proxies: List>.from(json['proxies']), proxyGroups: (json['proxy-groups'] as List) .map((e) => ProxyGroup.fromJson(e)) .toList(), rules: List.from(json['rules']), ); } Map toJson() { return { 'log-level': logLevel, if (ipv6 != null) 'ipv6': ipv6, if (allowLan != null) 'allow-lan': allowLan, if (bindAddress != null) 'bind-address': bindAddress, 'mode': mode, 'mixed-port': mixedPort, if (externalController != null) 'external-controller': externalController, if (unifiedDelay != null) 'unified-delay': unifiedDelay, if (geodataMode != null) 'geodata-mode': geodataMode, if (tcpConcurrent != null) 'tcp-concurrent': tcpConcurrent, if (findProcessMode != null) 'find-process-mode': findProcessMode, if (globalClientFingerprint != null) 'global-client-fingerprint': globalClientFingerprint, if (profile != null) 'profile': profile, if (sniffer != null) 'sniffer': sniffer!.toJson(), if (dns != null) 'dns': dns?.toJson(), if (tun != null) 'tun': tun!.toJson(), if (proxies != null) 'proxies': proxies, if (proxyGroups != null)'proxy-groups': proxyGroups?.map((e) => e.toJson()).toList(), 'rules': rules, }; } } class BaseProxy { final String name; final String server; final int port; final bool? udp; BaseProxy({ required this.name, required this.server, required this.port, this.udp, }); Map toJson() { return { 'name': name, 'server': server, 'port': port, if (udp != null) 'udp': udp, }; } } class SSProxy extends BaseProxy { final String type; final String password; final String cipher; final String? plugin; final Map? pluginOpts; SSProxy({ required String name, required String server, required int port, bool? udp, required this.type, required this.password, required this.cipher, this.plugin, this.pluginOpts, }) : super(name: name, server: server, port: port, udp: udp); factory SSProxy.fromJson(Map json) { return SSProxy( name: json['name'], server: json['server'], port: json['port'], udp: json['udp'], type: json['type'], password: json['password'], cipher: json['cipher'], plugin: json['plugin'], pluginOpts: json['plugin-opts'], ); } Map toJson() { return { 'name': name, 'type': type, 'server': server, 'port': port, 'password': password, 'cipher': cipher, if (udp != null) 'udp': udp, if (plugin != null) 'plugin': plugin, if (pluginOpts != null) 'plugin-opts': pluginOpts, }; } } class VlessProxy extends BaseProxy { final String uuid; final String? flow; final bool tls; final String? servername; final String network; final Map? smux; final List? alpn; final String? fingerprint; final String? clientFingerprint; final bool? skipCertVerify; final Map? realityOpts; VlessProxy({ required String name, required String server, required int port, bool? udp, required this.uuid, this.flow, required this.tls, this.servername, required this.network, this.smux, this.alpn, this.fingerprint, this.clientFingerprint, this.skipCertVerify, this.realityOpts, }) : super(name: name, server: server, port: port, udp: udp); factory VlessProxy.fromJson(Map json) { return VlessProxy( name: json['name'], server: json['server'], port: json['port'], udp: json['udp'] ?? false, uuid: json['uuid'], flow: json['flow'], tls: json['tls'], servername: json['servername'], network: json['network'], smux: json['smux'], alpn: json['alpn']?.cast(), fingerprint: json['fingerprint'], clientFingerprint: json['client-fingerprint'], skipCertVerify: json['skip-cert-verify'], realityOpts: json['reality-opts'], ); } Map toJson() { return { 'name': name, 'type': 'vless', 'server': server, 'port': port, 'udp': udp, 'uuid': uuid, if (flow != null) 'flow': flow, 'tls': tls, if (servername != null) 'servername': servername, 'network': network, if (smux != null) 'smux': smux, if (alpn != null) 'alpn': alpn, if (fingerprint != null) 'fingerprint': fingerprint, if (clientFingerprint != null) 'client-fingerprint': clientFingerprint, if (skipCertVerify != null) 'skip-cert-verify': skipCertVerify, if (realityOpts != null) 'reality-opts': realityOpts, }; } } class VmessProxy extends BaseProxy { final String uuid; final int? alterId; final String? cipher; final String? network; final Map? wsOpts; final String? servername; final bool? skipCertVerify; final List? alpn; VmessProxy({ required String name, required String server, required int port, bool? udp, required this.uuid, this.alterId, this.cipher, this.network = 'tcp', this.wsOpts, this.servername, this.skipCertVerify, this.alpn, }) : super(name: name, server: server, port: port, udp: udp); factory VmessProxy.fromJson(Map json) { return VmessProxy( name: json['name'], server: json['server'], port: json['port'], udp: json['udp'], uuid: json['uuid'], alterId: json['alterId'], cipher: json['cipher'], network: json['network'] ?? 'tcp', wsOpts: json['ws-opts'], servername: json['servername'], skipCertVerify: json['skip-cert-verify'], alpn: json['alpn']?.cast(), ); } Map toJson() { return { 'name': name, 'type': 'vmess', 'server': server, 'port': port, 'uuid': uuid, 'udp': udp, if (alterId != null) 'alterId': alterId, if (cipher != null) 'cipher': cipher, 'network': network, if (wsOpts != null) 'ws-opts': wsOpts, if (servername != null) 'servername': servername, if (skipCertVerify != null) 'skip-cert-verify': skipCertVerify, if (alpn != null) 'alpn': alpn, }; } } class TrojanProxy extends BaseProxy { final String password; final String? sni; final String? network; final String? clientFingerprint; final String? fingerprint; final bool? skipCertVerify; TrojanProxy({ required String name, required String server, required int port, bool? udp, required this.password, this.sni, this.network, this.clientFingerprint, this.fingerprint, this.skipCertVerify, }) : super(name: name, server: server, port: port, udp: udp); factory TrojanProxy.fromJson(Map json) { return TrojanProxy( name: json['name'], server: json['server'], port: json['port'], udp: json['udp'], password: json['password'], sni: json['sni'], network: json['network'], clientFingerprint: json['client-fingerprint'], fingerprint: json['fingerprint'], skipCertVerify: json['skip-cert-verify'], ); } Map toJson() { return { 'name': name, 'type': 'trojan', 'server': server, 'port': port, 'password': password, 'udp': udp, if (sni != null) 'sni': sni, if (network != null) 'network': network, if (clientFingerprint != null) 'client-fingerprint': clientFingerprint, if (fingerprint != null) 'fingerprint': fingerprint, if (skipCertVerify != null) 'skip-cert-verify': skipCertVerify, }; } } class ProxyGroup { final String name; final String type; final List proxies; ProxyGroup({ required this.name, required this.type, required this.proxies, }); factory ProxyGroup.fromJson(Map json) { return ProxyGroup( name: json['name'], type: json['type'], proxies: List.from(json['proxies']), ); } Map toJson() { return { 'name': name, 'type': type, 'proxies': proxies, }; } } class DNS { final bool enable; final String listen; final bool ipv6; final String enhancedMode; final List? fakeIpFilter; final List nameserver; final List proxyServerNameserver; final Map> nameserverPolicy; DNS({ required this.enable, required this.listen, required this.ipv6, required this.enhancedMode, this.fakeIpFilter, required this.nameserver, required this.proxyServerNameserver, required this.nameserverPolicy, }); factory DNS.fromJson(Map json) { return DNS( enable: json['enable'], listen: json['listen'], ipv6: json['ipv6'], enhancedMode: json['enhanced-mode'], fakeIpFilter: json['fake-ip-filter'] != null ? List.from(json['fake-ip-filter']) : null, nameserver: List.from(json['nameserver']), proxyServerNameserver: List.from(json['proxy-server-nameserver']), nameserverPolicy: Map>.from(json['nameserver-policy'].map( (key, value) => MapEntry(key, List.from(value)), )), ); } Map toJson() { final Map data = { 'enable': enable, 'listen': listen, 'ipv6': ipv6, 'enhanced-mode': enhancedMode, 'nameserver': nameserver, 'proxy-server-nameserver': proxyServerNameserver, 'nameserver-policy': nameserverPolicy, }; if (fakeIpFilter != null) { data['fake-ip-filter'] = fakeIpFilter; } return data; } } class Sniffer { final bool enable; final Map> sniff; final List skipDomain; Sniffer({ required this.enable, required this.sniff, required this.skipDomain, }); factory Sniffer.fromJson(Map json) { return Sniffer( enable: json['enable'], sniff: Map>.from(json['sniff']), skipDomain: List.from(json['skip-domain']), ); } Map toJson() { return { 'enable': enable, 'sniff': sniff, 'skip-domain': skipDomain, }; } } class Tun { final bool enable; final String stack; final bool autoRoute; final bool autoRedirect; final bool autoDetectInterface; final List dnsHijack; Tun({ required this.enable, required this.stack, required this.autoRoute, required this.autoRedirect, required this.autoDetectInterface, required this.dnsHijack, }); factory Tun.fromJson(Map json) { return Tun( enable: json['enable'], stack: json['stack'], autoRoute: json['auto-route'], autoRedirect: json['auto-redirect'], autoDetectInterface: json['auto-detect-interface'], dnsHijack: List.from(json['dns-hijack']), ); } Map toJson() { return { 'enable': enable, 'stack': stack, 'auto-route': autoRoute, 'auto-redirect': autoRedirect, 'auto-detect-interface': autoDetectInterface, 'dns-hijack': dnsHijack, }; } } // 示例用法 final sniffer = Sniffer( enable: true, sniff: { 'HTTP': { 'ports': [80, '8080-8880'], 'override-destination': true, }, 'TLS': { 'ports': [443, 8443], }, 'QUIC': { 'ports': [443, 8443], }, }, skipDomain: ['Mijia Cloud'], );