/* ============================================================ * 一、基础配置 * ============================================================ */ const GENERAL_CONFIG = { "mode": "rule", "ipv6": true, "log-level": "silent", "allow-lan": true, "mixed-port": 7890, "unified-delay": false, "tcp-concurrent": true, "external-controller-tls": "127.0.0.1:9090", "find-process-mode": "strict", "global-client-fingerprint": "chrome", "profile": { "store-selected": true, "store-fake-ip": true } }; /* ============================================================ * 二、统一测速配置 * ============================================================ */ const TEST_URL = "https://www.gstatic.com/generate_204"; const GROUP_INTERVAL = 600; const GROUP_TIMEOUT = 5000; const GROUP_TOLERANCE = 50; const FALLBACK_INTERVAL = 300; /* ============================================================ * 三、固定策略名称 * ============================================================ * * 统一集中管理。 * * 后续修改名称时只需要修改这里。 * * ============================================================ */ const GROUP_NAMES = { NODE_SELECT: "🚀 节点选择", AUTO: "♻️ 自动选择", FALLBACK: "🔯 故障转移", AI: "🤖 人工智能", OVERSEAS: "🌍 海外服务", NETWORK_TEST: "📈 网络测试", PROXY_SERVICE: "🪜 代理服务", DIRECT: "🎯 全球直连", AD_BLOCK: "🛑 广告拦截", FINAL: "🎯 兜底策略" }; /* ============================================================ * 四、地区名称 * ============================================================ */ const REGION_NAMES = [ "🇭🇰 香港", "🇹🇼 台湾", "🇯🇵 日本", "🇸🇬 新加坡", "🇺🇸 美国", "🌐 其他" ]; /* ============================================================ * 五、Sniffer * ============================================================ */ const SNIFFER_CONFIG = { "enable": true, "parse-pure-ip": true, "sniff": { "HTTP": { "ports": [ 80, "8080-8880" ], "override-destination": true }, "TLS": { "ports": [ 443, 8443 ] }, "QUIC": { "ports": [ 443, 8443 ] } }, "skip-domain": [ "Mijia Cloud" ] }; /* ============================================================ * 六、TUN * ============================================================ */ const TUN_CONFIG = { "enable": true, "stack": "system", "dns-hijack": [ "any:53" ], "auto-route": true, "auto-detect-interface": true, "strict-route": true }; /* ============================================================ * 七、DNS * ============================================================ */ const DNS_CONFIG = { "enable": true, "ipv6": true, "prefer-h3": true, "listen": "0.0.0.0:53", "fake-ip-range": "198.18.0.1/16", "enhanced-mode": "fake-ip", "fallback": [ "8.8.8.8" ], "default-nameserver": [ "223.5.5.5", "114.114.114.114" ], "nameserver": [ "https://dns.alidns.com/dns-query#h3=true", "https://doh.pub/dns-query" ], "fake-ip-filter": [ /* 本地 */ "*.lan", "*.localdomain", "*.example", "*.invalid", "*.localhost", "*.test", "*.local", "*.home.arpa", /* 自定义 */ "*.woozooo.com", "*.kiid.top", "43.142.112.88", /* 时间同步 */ "time.*.com", "time.*.gov", "time.*.edu.cn", "time.*.apple.com", "time-ios.apple.com", "time1.*.com", "time2.*.com", "time3.*.com", "time4.*.com", "time5.*.com", "time6.*.com", "time7.*.com", "ntp.*.com", "ntp1.*.com", "ntp2.*.com", "ntp3.*.com", "ntp4.*.com", "ntp5.*.com", "ntp6.*.com", "ntp7.*.com", "*.time.edu.cn", "*.ntp.org.cn", "+.pool.ntp.org", "time1.cloud.tencent.com", /* 网易云音乐 */ "music.163.com", "*.music.163.com", "*.126.net", /* 太和音乐 */ "musicapi.taihe.com", "music.taihe.com", /* 酷狗 */ "songsearch.kugou.com", "trackercdn.kugou.com", /* 酷我 */ "*.kuwo.cn", /* JOOX */ "api-jooxtt.sanook.com", "api.joox.com", "joox.com", /* QQ音乐 */ "y.qq.com", "*.y.qq.com", "streamoc.music.tc.qq.com", "mobileoc.music.tc.qq.com", "isure.stream.qqmusic.qq.com", "dl.stream.qqmusic.qq.com", "aqqmusic.tc.qq.com", "amobile.music.tc.qq.com", /* 虾米 */ "*.xiami.com", /* 咪咕 */ "*.music.migu.cn", "music.migu.cn", /* Windows 网络检测 */ "+.msftconnecttest.com", "+.msftncsi.com", /* QQ */ "localhost.ptlogin2.qq.com", "localhost.sec.qq.com", "+.qq.com", "+.tencent.com", /* Nintendo */ "+.srv.nintendo.net", "*.n.n.srv.nintendo.net", /* PlayStation */ "+.stun.playstation.net", /* Xbox */ "xbox.*.*.microsoft.com", "*.*.xboxlive.com", "xbox.*.microsoft.com", "xnotify.xboxlive.com", /* Battle.net */ "+.battlenet.com.cn", /* Wargaming */ "+.wotgame.cn", "+.wggames.cn", "+.wowsgame.cn", "+.wargaming.net", /* Go */ "proxy.golang.org", /* STUN */ "stun.*.*", "stun.*.*.*", "+.stun.*.*", "+.stun.*.*.*", "+.stun.*.*.*.*", "+.stun.*.*.*.*.*", /* Belkin */ "heartbeat.belkin.com", /* Linksys */ "*.linksys.com", "*.linksyssmartwifi.com", /* ASUS */ "*.router.asus.com", /* Apple */ "mesu.apple.com", "swscan.apple.com", "swquery.apple.com", "swdownload.apple.com", "swcdn.apple.com", "swdist.apple.com", /* Google */ "lens.l.google.com", "stun.l.google.com", /* 游戏 */ "na.b.g-tun.com", /* Netflix */ "+.nflxvideo.net", /* Square Enix */ "*.square-enix.com", "*.finalfantasyxiv.com", "*.ffxiv.com", "*.ff14.sdo.com", "ff.dorado.sdo.com", /* 哔哩哔哩 */ "*.mcdn.bilivideo.cn", /* Disney */ "+.media.dssott.com", /* Shark007 */ "shark007.net", /* 小米 */ "Mijia Cloud", /* 招商银行 */ "+.cmbchina.com", "+.cmbimg.com", /* AdGuard */ "adguardteam.github.io", "adrules.top", "anti-ad.net", "local.adguard.org", "static.adtidy.org", /* 网络 */ "+.sandai.net", "+.n0808.com", "+.3gppnetwork.org" ] }; /* ============================================================ * 八、节点地区识别 * ============================================================ * * 注意: * * 不再使用单独的: * * 港 * 台 * 日 * 新 * 美 * * 作为独立匹配条件。 * * 防止机场自定义名称产生误判。 * * ============================================================ */ const REGION_PATTERNS = { "🇭🇰 香港": /(?:香港|香港地区|Hong[\s_-]?Kong|HKG|HK|🇭🇰)/i, "🇹🇼 台湾": /(?:台湾|台湾地区|Taiwan|TWN|TW|🇹🇼)/i, "🇯🇵 日本": /(?:日本|日本地区|Japan|JPN|JP|🇯🇵)/i, "🇸🇬 新加坡": /(?:新加坡|狮城|Singapore|Singapura|SGP|SG|🇸🇬)/i, "🇺🇸 美国": /(?:美国|美国地区|United[\s_-]?States|USA|US|America|🇺🇸)/i }; /* ============================================================ * 九、节点辅助函数 * ============================================================ */ function getProxyName(proxy) { if (!proxy) { return ""; } if (typeof proxy === "string") { return proxy; } return proxy.name || ""; } /* * 判断是否为真实代理节点。 */ function isUsableProxy(proxy) { const name = getProxyName(proxy); if (!name) { return false; } const upperName = name.toUpperCase(); const excludedNames = [ "DIRECT", "REJECT", "REJECT-DROP", "PASS" ]; if ( excludedNames.indexOf( upperName ) !== -1 ) { return false; } return true; } /* * 获取节点地区。 */ function getRegionName(proxyName) { const regionNames = Object.keys(REGION_PATTERNS); for ( let i = 0; i < regionNames.length; i++ ) { const regionName = regionNames[i]; if ( REGION_PATTERNS[ regionName ].test(proxyName) ) { return regionName; } } return "🌐 其他"; } /* * 初始化地区节点。 */ function createEmptyRegionNodes() { return { "🇭🇰 香港": [], "🇹🇼 台湾": [], "🇯🇵 日本": [], "🇸🇬 新加坡": [], "🇺🇸 美国": [], "🌐 其他": [] }; } /* * 分类节点。 */ function classifyProxies(config) { const regionNodes = createEmptyRegionNodes(); const proxies = Array.isArray(config.proxies) ? config.proxies : []; for ( let i = 0; i < proxies.length; i++ ) { const proxy = proxies[i]; if ( !isUsableProxy(proxy) ) { continue; } const proxyName = getProxyName(proxy); const regionName = getRegionName(proxyName); regionNodes[ regionName ].push(proxyName); } return regionNodes; } /* * 获取实际存在的地区。 */ function getExistingRegions( regionNodes ) { const result = []; for ( let i = 0; i < REGION_NAMES.length; i++ ) { const regionName = REGION_NAMES[i]; if ( regionNodes[ regionName ] && regionNodes[ regionName ].length > 0 ) { result.push(regionName); } } return result; } /* ============================================================ * 十、代理组辅助函数 * ============================================================ */ /* * 创建地区测速组。 */ function createRegionGroup( name, proxies ) { return { "name": name, "type": "url-test", "proxies": proxies, "url": TEST_URL, "interval": GROUP_INTERVAL, "timeout": GROUP_TIMEOUT, "lazy": true, "tolerance": GROUP_TOLERANCE, "max-failed-times": 3 }; } /* * 创建选择组。 */ function createSelectGroup( name, proxies, disableUdp ) { const group = { "name": name, "type": "select", "proxies": proxies }; if (disableUdp === true) { group["disable-udp"] = true; } return group; } /* * 判断策略是否存在。 */ function hasGroup( groupNames, name ) { return ( groupNames.indexOf(name) !== -1 ); } /* * 创建地区策略。 */ function addExistingRegionGroup( groups, regionNodes, regionName ) { const proxies = regionNodes[ regionName ] || []; if ( proxies.length === 0 ) { return; } groups.push( createRegionGroup( regionName, proxies ) ); } /* ============================================================ * 十一、动态创建代理组 * ============================================================ * * 排序结构: * * ① 🚀 节点选择 * ② ♻️ 自动选择 * ③ 🔯 故障转移 * * ④ 地区策略 * * ⑤ 人工智能 * ⑥ 海外服务 * ⑦ 网络测试 * ⑧ 代理服务 * * ⑨ 全球直连 * ⑩ 广告拦截 * ⑪ 兜底策略 * * ============================================================ */ function createProxyGroups(config) { const regionNodes = classifyProxies(config); const existingRegions = getExistingRegions( regionNodes ); const groups = []; /* * ======================================================== * 第一层:核心节点控制 * ======================================================== */ /* * ① 节点选择 * * 先预留,后面填充实际策略。 */ const nodeSelectOptions = []; /* * ② 自动选择 */ if ( existingRegions.length > 0 ) { groups.push({ "name": GROUP_NAMES.AUTO, "type": "url-test", "proxies": existingRegions, "url": TEST_URL, "interval": GROUP_INTERVAL, "timeout": GROUP_TIMEOUT, "lazy": true, "tolerance": GROUP_TOLERANCE, "max-failed-times": 3 }); nodeSelectOptions.push( GROUP_NAMES.AUTO ); } /* * ③ 故障转移 */ if ( existingRegions.length > 0 ) { groups.push({ "name": GROUP_NAMES.FALLBACK, "type": "fallback", "proxies": existingRegions, "url": TEST_URL, "interval": FALLBACK_INTERVAL, "timeout": GROUP_TIMEOUT, "lazy": true }); nodeSelectOptions.push( GROUP_NAMES.FALLBACK ); } /* * 地区加入节点选择。 */ for ( let i = 0; i < existingRegions.length; i++ ) { nodeSelectOptions.push( existingRegions[i] ); } /* * ① 节点选择 * * 最终插入到 groups[0]。 */ groups.unshift( createSelectGroup( GROUP_NAMES.NODE_SELECT, nodeSelectOptions ) ); /* * ======================================================== * 第二层:地区策略 * ======================================================== */ addExistingRegionGroup( groups, regionNodes, "🇭🇰 香港" ); addExistingRegionGroup( groups, regionNodes, "🇹🇼 台湾" ); addExistingRegionGroup( groups, regionNodes, "🇯🇵 日本" ); addExistingRegionGroup( groups, regionNodes, "🇸🇬 新加坡" ); addExistingRegionGroup( groups, regionNodes, "🇺🇸 美国" ); addExistingRegionGroup( groups, regionNodes, "🌐 其他" ); /* * ======================================================== * 第三层:人工智能 * ======================================================== * * 排除香港。 */ const aiRegions = [ "🇹🇼 台湾", "🇯🇵 日本", "🇸🇬 新加坡", "🇺🇸 美国" ]; const aiProxies = []; for ( let i = 0; i < aiRegions.length; i++ ) { if ( existingRegions.indexOf( aiRegions[i] ) !== -1 ) { aiProxies.push( aiRegions[i] ); } } if ( aiProxies.length > 0 ) { groups.push({ "name": GROUP_NAMES.AI, "type": "url-test", "proxies": aiProxies, "url": TEST_URL, "interval": GROUP_INTERVAL, "timeout": GROUP_TIMEOUT, "lazy": true, "tolerance": GROUP_TOLERANCE, "max-failed-times": 3 }); } /* * ======================================================== * 第四层:海外服务 * ======================================================== */ const overseasOptions = []; overseasOptions.push( GROUP_NAMES.NODE_SELECT ); if ( hasGroup( existingRegions, GROUP_NAMES.AUTO ) ) { overseasOptions.push( GROUP_NAMES.AUTO ); } if ( hasGroup( existingRegions, GROUP_NAMES.FALLBACK ) ) { overseasOptions.push( GROUP_NAMES.FALLBACK ); } groups.push( createSelectGroup( GROUP_NAMES.OVERSEAS, overseasOptions ) ); /* * ======================================================== * 第五层:网络测试 * ======================================================== */ const networkTestOptions = [ GROUP_NAMES.DIRECT, GROUP_NAMES.NODE_SELECT ]; if ( existingRegions.length > 0 ) { networkTestOptions.push( GROUP_NAMES.AUTO ); } groups.push( createSelectGroup( GROUP_NAMES.NETWORK_TEST, networkTestOptions ) ); /* * ======================================================== * 第六层:代理服务 * ======================================================== */ const proxyServiceOptions = [ GROUP_NAMES.NODE_SELECT ]; if ( existingRegions.length > 0 ) { proxyServiceOptions.push( GROUP_NAMES.AUTO, GROUP_NAMES.FALLBACK ); } proxyServiceOptions.push( GROUP_NAMES.DIRECT ); groups.push( createSelectGroup( GROUP_NAMES.PROXY_SERVICE, proxyServiceOptions, true ) ); /* * ======================================================== * 第七层:全球直连 * ======================================================== */ groups.push( createSelectGroup( GROUP_NAMES.DIRECT, [ "DIRECT" ] ) ); /* * ======================================================== * 第八层:广告拦截 * ======================================================== */ groups.push( createSelectGroup( GROUP_NAMES.AD_BLOCK, [ "REJECT" ] ) ); /* * ======================================================== * 第九层:兜底策略 * ======================================================== */ const finalOptions = []; if ( existingRegions.length > 0 ) { finalOptions.push( GROUP_NAMES.NODE_SELECT ); } finalOptions.push( GROUP_NAMES.DIRECT ); groups.push( createSelectGroup( GROUP_NAMES.FINAL, finalOptions, true ) ); return groups; } /* ============================================================ * 十二、规则集 * ============================================================ */ const RULE_PROVIDERS = { "ads": { "type": "http", "behavior": "domain", "format": "text", "path": "./rules/adss.list", "url": "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/ads.list", "interval": 86400 }, "applications": { "type": "http", "behavior": "classical", "format": "text", "path": "./rules/applicationss.list", "url": "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/applications.list", "interval": 86400 }, "private": { "type": "http", "behavior": "domain", "format": "text", "path": "./rules/privates.list", "url": "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/private.list", "filter": "^((?!openai).)*$", "interval": 86400 }, "microsoft-cn": { "type": "http", "behavior": "domain", "format": "text", "path": "./rules/microsoft-cns.list", "url": "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/microsoft-cn.list", "interval": 86400 }, "openai": { "type": "http", "behavior": "domain", "format": "text", "path": "./rules/openais.list", "url": "https://cdn.jsdelivr.net/gh/DustinWin/ruleset_geodata@refs/heads/mihomo-ruleset/ai.list", "interval": 86400 }, "apple-cn": { "type": "http", "behavior": "domain", "format": "text", "path": "./rules/apple-cns.list", "url": "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/apple-cn.list", "interval": 86400 }, "google-cn": { "type": "http", "behavior": "domain", "format": "text", "path": "./rules/google-cns.list", "url": "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/google-cn.list", "interval": 86400 }, "games-cn": { "type": "http", "behavior": "domain", "format": "text", "path": "./rules/games-cns.list", "url": "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/games-cn.list", "interval": 86400 }, "networktest": { "type": "http", "behavior": "classical", "format": "text", "path": "./rules/networktests.list", "url": "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/networktest.list", "interval": 86400 }, "proxy": { "type": "http", "behavior": "domain", "format": "text", "path": "./rules/proxys.list", "url": "https://fastly.jsdelivr.net/gh/y7478729/ruleset_geodata@clash-ruleset/proxy.list", "interval": 86400 }, "cn": { "type": "http", "behavior": "domain", "format": "text", "path": "./rules/cns.list", "url": "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/cn.list", "interval": 86400 }, "telegramip": { "type": "http", "behavior": "ipcidr", "format": "text", "path": "./rules/telegramips.list", "url": "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/telegramip.list", "interval": 86400 }, "privateip": { "type": "http", "behavior": "ipcidr", "format": "text", "path": "./rules/privateips.list", "url": "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/privateip.list", "interval": 86400 }, "cnip": { "type": "http", "behavior": "ipcidr", "format": "text", "path": "./rules/cnips.list", "url": "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/cnip.list", "interval": 86400 } }; /* ============================================================ * 十三、规则 * ============================================================ */ const RULES = [ /* * AI */ "RULE-SET,openai,🤖 人工智能", /* * 广告 */ "RULE-SET,ads,🛑 广告拦截", /* * 软件 */ "RULE-SET,applications,🎯 全球直连", /* * 私有网络 */ "RULE-SET,private,🎯 全球直连", /* * Microsoft */ "RULE-SET,microsoft-cn,🌍 海外服务", /* * Apple */ "RULE-SET,apple-cn,🌍 海外服务", /* * Google */ "RULE-SET,google-cn,🌍 海外服务", /* * 游戏 */ "RULE-SET,games-cn,🌍 海外服务", /* * 网络测试 */ "RULE-SET,networktest,📈 网络测试", /* * 代理域名 */ "RULE-SET,proxy,🪜 代理服务", /* * 中国域名 */ "RULE-SET,cn,🎯 全球直连", /* * Telegram IP */ "RULE-SET,telegramip,🌍 海外服务,no-resolve", /* * 私有 IP */ "RULE-SET,privateip,🎯 全球直连,no-resolve", /* * 中国 IP */ "RULE-SET,cnip,🎯 全球直连,no-resolve", /* * 最终兜底 */ "MATCH,🎯 兜底策略" ]; /* ============================================================ * 十四、主函数 * ============================================================ */ function main(config) { /* * -------------------------------------------------------- * 1. 检查配置 * -------------------------------------------------------- */ const proxyCount = config && Array.isArray( config.proxies ) ? config.proxies.length : 0; const providerCount = config && config["proxy-providers"] && typeof config["proxy-providers"] === "object" ? Object.keys( config["proxy-providers"] ).length : 0; /* * 没有节点,也没有节点提供器。 */ if ( proxyCount === 0 && providerCount === 0 ) { throw new Error( "当前订阅没有找到任何代理节点或代理集合" ); } /* * -------------------------------------------------------- * 2. 基础配置 * -------------------------------------------------------- */ Object.assign( config, GENERAL_CONFIG ); /* * -------------------------------------------------------- * 3. Sniffer * -------------------------------------------------------- */ config["sniffer"] = SNIFFER_CONFIG; /* * -------------------------------------------------------- * 4. TUN * -------------------------------------------------------- */ config["tun"] = TUN_CONFIG; /* * -------------------------------------------------------- * 5. DNS * -------------------------------------------------------- */ config["dns"] = DNS_CONFIG; /* * -------------------------------------------------------- * 6. 代理组 * -------------------------------------------------------- */ config["proxy-groups"] = createProxyGroups( config ); /* * -------------------------------------------------------- * 7. 规则集 * -------------------------------------------------------- */ config["rule-providers"] = RULE_PROVIDERS; /* * -------------------------------------------------------- * 8. 规则 * -------------------------------------------------------- */ config["rules"] = RULES; /* * -------------------------------------------------------- * 9. 返回配置 * -------------------------------------------------------- */ return config; }