import 'dart:collection'; class Config { General? general; List? proxies; List? proxyGroups; List? rules; HashMap>? hosts; @override String toString() { String result = ""; if (general != null) { result += "$general\n"; } if (proxies != null && proxies!.isNotEmpty) { result += "[Proxy]\n"; result += proxies!.map((e) => e.toString()).join("\n"); result += "\n\n"; } if (proxyGroups != null && proxyGroups!.isNotEmpty) { result += "[Proxy Group]\n"; result += proxyGroups!.map((e) => e.toString()).join("\n"); result += "\n\n"; } if (rules != null && rules!.isNotEmpty) { result += "[Rule]\n"; result += rules!.map((e) => e.toString()).join("\n"); result += "\n\n"; } if (hosts != null && hosts!.isNotEmpty) { result += "[Host]\n"; result += hosts!.entries .map((e) => "${e.key} = ${e.value.join(", ")}") .join("\n"); result += "\n\n"; } return result; } } class Rule { Rule({required this.typeField, this.filter, required this.target}); String typeField; String? filter; String target; @override String toString() { String result = typeField; if (filter != null) { result += ', $filter'; } result += ', $target'; return result; } } class ProxyGroup { ProxyGroup( {required this.tag, required this.protocol, this.actors, this.healthCheck, this.checkInterval, this.failTimeout, this.failover, this.fallbackCache, this.cacheSize, this.cacheTimeout, this.lastResort, this.healthCheckTimeout, this.healthCheckDelay, this.healthCheckActive, this.delayBase, this.method}); String tag; String protocol; List? actors; /// failover bool? healthCheck; int? checkInterval; int? failTimeout; bool? failover; bool? fallbackCache; int? cacheSize; int? cacheTimeout; String? lastResort; int? healthCheckTimeout; int? healthCheckDelay; int? healthCheckActive; /// tryall int? delayBase; /// static String? method; @override String toString() { String result = tag; result += " = $protocol"; if (actors != null) { result += ", ${actors!.join(", ")}"; } if (healthCheck != null) { result += ", health-check = $healthCheck"; } if (checkInterval != null) { result += ", check-interval = $checkInterval"; } if (failTimeout != null) { result += ", fail-timeout = $failTimeout"; } if (failover != null) { result += ", failover = $failover"; } if (fallbackCache != null) { result += ", fallback-cache = $fallbackCache"; } if (cacheSize != null) { result += ", cache-size = $cacheSize"; } if (cacheTimeout != null) { result += ", cache-timeout = $cacheTimeout"; } if (lastResort != null) { result += ", last-resort = $lastResort"; } if (healthCheckTimeout != null) { result += ", health-check-timeout = $healthCheckTimeout"; } if (healthCheckDelay != null) { result += ", health-check-delay = $healthCheckDelay"; } if (healthCheckActive != null) { result += ", health-check-active = $healthCheckActive"; } if (delayBase != null) { result += ", delay-base = $delayBase"; } if (method != null) { result += ", method = $method"; } return result; } } class Proxy { Proxy( {required this.tag, required this.protocol, this.interface, this.address, this.port, this.encryptMethod, this.password, this.ws, this.tls, this.tlsCert, this.wsPath, this.wsHost, this.sni, this.username, this.amux, this.amuxMax, this.amuxCon, this.quic}); String tag; String protocol; String? interface; /// address String? address; int? port; /// shadowsocks String? encryptMethod; /// shadowsocks, trojan String? password; bool? ws; bool? tls; String? tlsCert; String? wsPath; String? wsHost; /// trojan String? sni; /// vmess String? username; bool? amux; int? amuxMax; int? amuxCon; bool? quic; @override String toString() { String result = tag; result += " = $protocol"; switch (protocol) { case 'direct': case 'drop': case 'reject': return result; } if (address != null && port != null) { result += ", $address, $port"; } if (encryptMethod != null) { result += ", encrypt-method = $encryptMethod"; } if (password != null) { result += ", password = $password"; } if (ws != null) { result += ", ws = $ws"; } if (tls != null) { result += ", tls = $tls"; } if (tlsCert != null) { result += ", tls-cert = $tlsCert"; } if (wsPath != null) { result += ", ws-path = $wsPath"; } if (wsHost != null) { result += ", ws-host = $wsHost"; } if (sni != null) { result += ", sni = $sni"; } if (username != null) { result += ", username = $username"; } if (amux != null) { result += ", amux = $amux"; } if (amuxMax != null) { result += ", amux-max = $amuxMax"; } if (amuxCon != null) { result += ", amux-con = $amuxCon"; } if (quic != null) { result += ", quic = $quic"; } if (interface != null) { result += ", interface = $interface"; } return result; } } class General { General( {this.tun, this.tunFd, this.loglevel, this.logoutput, this.dnsServer, this.dnsInterface, this.alwaysRealIp, this.alwaysFakeIp, this.httpInterface, this.httpPort, this.socksInterface, this.socksPort, this.apiInterface, this.apiPort, this.routingDomainResolve}); Tun? tun; dynamic tunFd; String? loglevel; String? logoutput; List? dnsServer; String? dnsInterface; List? alwaysRealIp; List? alwaysFakeIp; String? httpInterface; int? httpPort; String? socksInterface; int? socksPort; String? apiInterface; int? apiPort; bool? routingDomainResolve; @override String toString() { String result = "[General]\n"; if (tun != null) { result += "tun = $tun\n"; } if (tunFd != null) { result += "tun-fd = $tunFd\n"; } if (loglevel != null) { result += "loglevel = $loglevel\n"; } if (logoutput != null) { result += "logoutput = $logoutput\n"; } if (dnsServer != null) { result += "dns-server = ${dnsServer!.join(", ")}\n"; } if (dnsInterface != null) { result += "dns-interface = $dnsInterface\n"; } if (alwaysRealIp != null) { result += "always-real-ip = ${alwaysRealIp!.join(", ")}\n"; } if (alwaysFakeIp != null) { result += "always-fake-ip = ${alwaysFakeIp!.join(", ")}\n"; } if (routingDomainResolve != null) { result += "routing-domain-resolve = $routingDomainResolve\n"; } if (httpInterface != null) { result += "http-interface = $httpInterface\n"; } if (httpPort != null) { result += "http-port = $httpPort\n"; } if (socksInterface != null) { result += "socks-interface = $socksInterface\n"; } if (socksInterface != null) { result += "socks-port = $socksPort\n"; } if (apiInterface != null) { result += "api-interface = $apiInterface\n"; } if (apiPort != null) { result += "api-port = $apiPort\n"; } return result; } } class Tun { Tun({this.name, this.address, this.netmask, this.gateway, this.mtu}); String? name; String? address; String? netmask; String? gateway; int? mtu; @override String toString() { String result = ""; if (name == 'auto') { result += "auto"; return result; } if (name != null && address != null && netmask != null && gateway != null && mtu != null) { result += ", $name, $address, $netmask, $gateway, $mtu"; } return result; } }