Like 0

* Clash Verge Rev - 全局扩展脚本 * 机场独立订阅 / Windows

win_Clash Verge.js Raw
1/**
2 * ============================================================
3 * Clash Verge Rev - 全局扩展脚本
4 * 机场独立订阅 / Windows
5 * ============================================================
6 *
7 * 【更新日志】
8 *
9 * 2026-08-23
10 * ------------------------------------------------------------
11 * 1. 「🚀 节点选择」调整至代理组最顶部
12 * 2. 「♻️ 自动选择」调整至代理组第二位
13 * 3. 「🔯 故障转移」调整至代理组第三位
14 * 4. 优化代理组生成顺序
15 * 5. 优化策略组之间的动态引用关系
16 * 6. 防止策略组引用不存在的策略
17 * 7. 优化节点地区识别,降低单字误判
18 * 8. 保留香港 / 台湾 / 日本 / 新加坡 / 美国 / 其他
19 * 9. 「🌐 其他」仅在存在其他节点时创建
20 * 10. 人工智能继续排除香港节点
21 * 11. 人工智能动态适应实际存在地区
22 * 12. 自动选择动态适应实际存在地区
23 * 13. 故障转移动态适应实际存在地区
24 * 14. 所有测速统一使用 gstatic generate_204
25 * 15. 保留 TUN / DNS / Fake-IP / Sniffer
26 * 16. 保留原有规则集
27 * 17. 保留规则集自动更新
28 * 18. 保留「🌍 海外服务」
29 * 19. 保留「📈 网络测试」
30 * 20. 保留「🪜 代理服务」
31 * 21. 保留「🎯 全球直连」
32 * 22. 保留「🛑 广告拦截」
33 * 23. 保留「🎯 兜底策略」
34 *
35 * ============================================================
36 *
37 * 使用方式:
38 *
39 * 机场订阅直接添加到 Clash Verge Rev。
40 *
41 * 本脚本作为:
42 *
43 * 全局扩展脚本
44 *
45 * 对最终生成的 Clash 配置进行统一修改。
46 *
47 * 不需要填写机场订阅地址。
48 *
49 * ============================================================
50 */
51/* ============================================================
52 * 一、基础配置
53 * ============================================================
54 */
55const GENERAL_CONFIG = {
56 "mode": "rule",
57 "ipv6": true,
58 "log-level": "silent",
59 "allow-lan": true,
60 "mixed-port": 7890,
61 "unified-delay": false,
62 "tcp-concurrent": true,
63 "external-controller-tls": "127.0.0.1:9090",
64 "find-process-mode": "strict",
65 "global-client-fingerprint": "chrome",
66 "profile": {
67 "store-selected": true,
68 "store-fake-ip": true
69 }
70};
71/* ============================================================
72 * 二、统一测速配置
73 * ============================================================
74 */
75const TEST_URL =
76 "https://www.gstatic.com/generate_204";
77const GROUP_INTERVAL = 600;
78const GROUP_TIMEOUT = 5000;
79const GROUP_TOLERANCE = 50;
80const FALLBACK_INTERVAL = 300;
81/* ============================================================
82 * 三、固定策略名称
83 * ============================================================
84 *
85 * 统一集中管理。
86 *
87 * 后续修改名称时只需要修改这里。
88 *
89 * ============================================================
90 */
91const GROUP_NAMES = {
92 NODE_SELECT: "🚀 节点选择",
93 AUTO: "♻️ 自动选择",
94 FALLBACK: "🔯 故障转移",
95 AI: "🤖 人工智能",
96 OVERSEAS: "🌍 海外服务",
97 NETWORK_TEST: "📈 网络测试",
98 PROXY_SERVICE: "🪜 代理服务",
99 DIRECT: "🎯 全球直连",
100 AD_BLOCK: "🛑 广告拦截",
101 FINAL: "🎯 兜底策略"
102};
103/* ============================================================
104 * 四、地区名称
105 * ============================================================
106 */
107const REGION_NAMES = [
108 "🇭🇰 香港",
109 "🇹🇼 台湾",
110 "🇯🇵 日本",
111 "🇸🇬 新加坡",
112 "🇺🇸 美国",
113 "🌐 其他"
114];
115/* ============================================================
116 * 五、Sniffer
117 * ============================================================
118 */
119const SNIFFER_CONFIG = {
120 "enable": true,
121 "parse-pure-ip": true,
122 "sniff": {
123 "HTTP": {
124 "ports": [
125 80,
126 "8080-8880"
127 ],
128 "override-destination": true
129 },
130 "TLS": {
131 "ports": [
132 443,
133 8443
134 ]
135 },
136 "QUIC": {
137 "ports": [
138 443,
139 8443
140 ]
141 }
142 },
143 "skip-domain": [
144 "Mijia Cloud"
145 ]
146};
147/* ============================================================
148 * 六、TUN
149 * ============================================================
150 */
151const TUN_CONFIG = {
152 "enable": true,
153 "stack": "system",
154 "dns-hijack": [
155 "any:53"
156 ],
157 "auto-route": true,
158 "auto-detect-interface": true,
159 "strict-route": true
160};
161/* ============================================================
162 * 七、DNS
163 * ============================================================
164 */
165const DNS_CONFIG = {
166 "enable": true,
167 "ipv6": true,
168 "prefer-h3": true,
169 "listen": "0.0.0.0:53",
170 "fake-ip-range": "198.18.0.1/16",
171 "enhanced-mode": "fake-ip",
172 "fallback": [
173 "8.8.8.8"
174 ],
175 "default-nameserver": [
176 "223.5.5.5",
177 "114.114.114.114"
178 ],
179 "nameserver": [
180 "https://dns.alidns.com/dns-query#h3=true",
181 "https://doh.pub/dns-query"
182 ],
183 "fake-ip-filter": [
184 /* 本地 */
185 "*.lan",
186 "*.localdomain",
187 "*.example",
188 "*.invalid",
189 "*.localhost",
190 "*.test",
191 "*.local",
192 "*.home.arpa",
193 /* 自定义 */
194 "*.woozooo.com",
195 "*.kiid.top",
196 "43.142.112.88",
197 /* 时间同步 */
198 "time.*.com",
199 "time.*.gov",
200 "time.*.edu.cn",
201 "time.*.apple.com",
202 "time-ios.apple.com",
203 "time1.*.com",
204 "time2.*.com",
205 "time3.*.com",
206 "time4.*.com",
207 "time5.*.com",
208 "time6.*.com",
209 "time7.*.com",
210 "ntp.*.com",
211 "ntp1.*.com",
212 "ntp2.*.com",
213 "ntp3.*.com",
214 "ntp4.*.com",
215 "ntp5.*.com",
216 "ntp6.*.com",
217 "ntp7.*.com",
218 "*.time.edu.cn",
219 "*.ntp.org.cn",
220 "+.pool.ntp.org",
221 "time1.cloud.tencent.com",
222 /* 网易云音乐 */
223 "music.163.com",
224 "*.music.163.com",
225 "*.126.net",
226 /* 太和音乐 */
227 "musicapi.taihe.com",
228 "music.taihe.com",
229 /* 酷狗 */
230 "songsearch.kugou.com",
231 "trackercdn.kugou.com",
232 /* 酷我 */
233 "*.kuwo.cn",
234 /* JOOX */
235 "api-jooxtt.sanook.com",
236 "api.joox.com",
237 "joox.com",
238 /* QQ音乐 */
239 "y.qq.com",
240 "*.y.qq.com",
241 "streamoc.music.tc.qq.com",
242 "mobileoc.music.tc.qq.com",
243 "isure.stream.qqmusic.qq.com",
244 "dl.stream.qqmusic.qq.com",
245 "aqqmusic.tc.qq.com",
246 "amobile.music.tc.qq.com",
247 /* 虾米 */
248 "*.xiami.com",
249 /* 咪咕 */
250 "*.music.migu.cn",
251 "music.migu.cn",
252 /* Windows 网络检测 */
253 "+.msftconnecttest.com",
254 "+.msftncsi.com",
255 /* QQ */
256 "localhost.ptlogin2.qq.com",
257 "localhost.sec.qq.com",
258 "+.qq.com",
259 "+.tencent.com",
260 /* Nintendo */
261 "+.srv.nintendo.net",
262 "*.n.n.srv.nintendo.net",
263 /* PlayStation */
264 "+.stun.playstation.net",
265 /* Xbox */
266 "xbox.*.*.microsoft.com",
267 "*.*.xboxlive.com",
268 "xbox.*.microsoft.com",
269 "xnotify.xboxlive.com",
270 /* Battle.net */
271 "+.battlenet.com.cn",
272 /* Wargaming */
273 "+.wotgame.cn",
274 "+.wggames.cn",
275 "+.wowsgame.cn",
276 "+.wargaming.net",
277 /* Go */
278 "proxy.golang.org",
279 /* STUN */
280 "stun.*.*",
281 "stun.*.*.*",
282 "+.stun.*.*",
283 "+.stun.*.*.*",
284 "+.stun.*.*.*.*",
285 "+.stun.*.*.*.*.*",
286 /* Belkin */
287 "heartbeat.belkin.com",
288 /* Linksys */
289 "*.linksys.com",
290 "*.linksyssmartwifi.com",
291 /* ASUS */
292 "*.router.asus.com",
293 /* Apple */
294 "mesu.apple.com",
295 "swscan.apple.com",
296 "swquery.apple.com",
297 "swdownload.apple.com",
298 "swcdn.apple.com",
299 "swdist.apple.com",
300 /* Google */
301 "lens.l.google.com",
302 "stun.l.google.com",
303 /* 游戏 */
304 "na.b.g-tun.com",
305 /* Netflix */
306 "+.nflxvideo.net",
307 /* Square Enix */
308 "*.square-enix.com",
309 "*.finalfantasyxiv.com",
310 "*.ffxiv.com",
311 "*.ff14.sdo.com",
312 "ff.dorado.sdo.com",
313 /* 哔哩哔哩 */
314 "*.mcdn.bilivideo.cn",
315 /* Disney */
316 "+.media.dssott.com",
317 /* Shark007 */
318 "shark007.net",
319 /* 小米 */
320 "Mijia Cloud",
321 /* 招商银行 */
322 "+.cmbchina.com",
323 "+.cmbimg.com",
324 /* AdGuard */
325 "adguardteam.github.io",
326 "adrules.top",
327 "anti-ad.net",
328 "local.adguard.org",
329 "static.adtidy.org",
330 /* 网络 */
331 "+.sandai.net",
332 "+.n0808.com",
333 "+.3gppnetwork.org"
334 ]
335};
336/* ============================================================
337 * 八、节点地区识别
338 * ============================================================
339 *
340 * 注意:
341 *
342 * 不再使用单独的:
343 *
344 * 港
345 * 台
346 * 日
347 * 新
348 * 美
349 *
350 * 作为独立匹配条件。
351 *
352 * 防止机场自定义名称产生误判。
353 *
354 * ============================================================
355 */
356const REGION_PATTERNS = {
357 "🇭🇰 香港":
358 /(?:香港|香港地区|Hong[\s_-]?Kong|HKG|HK|🇭🇰)/i,
359 "🇹🇼 台湾":
360 /(?:台湾|台湾地区|Taiwan|TWN|TW|🇹🇼)/i,
361 "🇯🇵 日本":
362 /(?:日本|日本地区|Japan|JPN|JP|🇯🇵)/i,
363 "🇸🇬 新加坡":
364 /(?:新加坡|狮城|Singapore|Singapura|SGP|SG|🇸🇬)/i,
365 "🇺🇸 美国":
366 /(?:美国|美国地区|United[\s_-]?States|USA|US|America|🇺🇸)/i
367};
368/* ============================================================
369 * 九、节点辅助函数
370 * ============================================================
371 */
372function getProxyName(proxy) {
373 if (!proxy) {
374 return "";
375 }
376 if (typeof proxy === "string") {
377 return proxy;
378 }
379 return proxy.name || "";
380}
381/*
382 * 判断是否为真实代理节点。
383 */
384function isUsableProxy(proxy) {
385 const name =
386 getProxyName(proxy);
387 if (!name) {
388 return false;
389 }
390 const upperName =
391 name.toUpperCase();
392 const excludedNames = [
393 "DIRECT",
394 "REJECT",
395 "REJECT-DROP",
396 "PASS"
397 ];
398 if (
399 excludedNames.indexOf(
400 upperName
401 ) !== -1
402 ) {
403 return false;
404 }
405 return true;
406}
407/*
408 * 获取节点地区。
409 */
410function getRegionName(proxyName) {
411 const regionNames =
412 Object.keys(REGION_PATTERNS);
413 for (
414 let i = 0;
415 i < regionNames.length;
416 i++
417 ) {
418 const regionName =
419 regionNames[i];
420 if (
421 REGION_PATTERNS[
422 regionName
423 ].test(proxyName)
424 ) {
425 return regionName;
426 }
427 }
428 return "🌐 其他";
429}
430/*
431 * 初始化地区节点。
432 */
433function createEmptyRegionNodes() {
434 return {
435 "🇭🇰 香港": [],
436 "🇹🇼 台湾": [],
437 "🇯🇵 日本": [],
438 "🇸🇬 新加坡": [],
439 "🇺🇸 美国": [],
440 "🌐 其他": []
441 };
442}
443/*
444 * 分类节点。
445 */
446function classifyProxies(config) {
447 const regionNodes =
448 createEmptyRegionNodes();
449 const proxies =
450 Array.isArray(config.proxies)
451 ? config.proxies
452 : [];
453 for (
454 let i = 0;
455 i < proxies.length;
456 i++
457 ) {
458 const proxy =
459 proxies[i];
460 if (
461 !isUsableProxy(proxy)
462 ) {
463 continue;
464 }
465 const proxyName =
466 getProxyName(proxy);
467 const regionName =
468 getRegionName(proxyName);
469 regionNodes[
470 regionName
471 ].push(proxyName);
472 }
473 return regionNodes;
474}
475/*
476 * 获取实际存在的地区。
477 */
478function getExistingRegions(
479 regionNodes
480) {
481 const result = [];
482 for (
483 let i = 0;
484 i < REGION_NAMES.length;
485 i++
486 ) {
487 const regionName =
488 REGION_NAMES[i];
489 if (
490 regionNodes[
491 regionName
492 ] &&
493 regionNodes[
494 regionName
495 ].length > 0
496 ) {
497 result.push(regionName);
498 }
499 }
500 return result;
501}
502/* ============================================================
503 * 十、代理组辅助函数
504 * ============================================================
505 */
506/*
507 * 创建地区测速组。
508 */
509function createRegionGroup(
510 name,
511 proxies
512) {
513 return {
514 "name": name,
515 "type": "url-test",
516 "proxies": proxies,
517 "url": TEST_URL,
518 "interval": GROUP_INTERVAL,
519 "timeout": GROUP_TIMEOUT,
520 "lazy": true,
521 "tolerance": GROUP_TOLERANCE,
522 "max-failed-times": 3
523 };
524}
525/*
526 * 创建选择组。
527 */
528function createSelectGroup(
529 name,
530 proxies,
531 disableUdp
532) {
533 const group = {
534 "name": name,
535 "type": "select",
536 "proxies": proxies
537 };
538 if (disableUdp === true) {
539 group["disable-udp"] = true;
540 }
541 return group;
542}
543/*
544 * 判断策略是否存在。
545 */
546function hasGroup(
547 groupNames,
548 name
549) {
550 return (
551 groupNames.indexOf(name) !== -1
552 );
553}
554/*
555 * 创建地区策略。
556 */
557function addExistingRegionGroup(
558 groups,
559 regionNodes,
560 regionName
561) {
562 const proxies =
563 regionNodes[
564 regionName
565 ] || [];
566 if (
567 proxies.length === 0
568 ) {
569 return;
570 }
571 groups.push(
572 createRegionGroup(
573 regionName,
574 proxies
575 )
576 );
577}
578/* ============================================================
579 * 十一、动态创建代理组
580 * ============================================================
581 *
582 * 排序结构:
583 *
584 * ① 🚀 节点选择
585 * ② ♻️ 自动选择
586 * ③ 🔯 故障转移
587 *
588 * ④ 地区策略
589 *
590 * ⑤ 人工智能
591 * ⑥ 海外服务
592 * ⑦ 网络测试
593 * ⑧ 代理服务
594 *
595 * ⑨ 全球直连
596 * ⑩ 广告拦截
597 * ⑪ 兜底策略
598 *
599 * ============================================================
600 */
601function createProxyGroups(config) {
602 const regionNodes =
603 classifyProxies(config);
604 const existingRegions =
605 getExistingRegions(
606 regionNodes
607 );
608 const groups = [];
609 /*
610 * ========================================================
611 * 第一层:核心节点控制
612 * ========================================================
613 */
614 /*
615 * ① 节点选择
616 *
617 * 先预留,后面填充实际策略。
618 */
619 const nodeSelectOptions = [];
620 /*
621 * ② 自动选择
622 */
623 if (
624 existingRegions.length > 0
625 ) {
626 groups.push({
627 "name": GROUP_NAMES.AUTO,
628 "type": "url-test",
629 "proxies": existingRegions,
630 "url": TEST_URL,
631 "interval": GROUP_INTERVAL,
632 "timeout": GROUP_TIMEOUT,
633 "lazy": true,
634 "tolerance": GROUP_TOLERANCE,
635 "max-failed-times": 3
636 });
637 nodeSelectOptions.push(
638 GROUP_NAMES.AUTO
639 );
640 }
641 /*
642 * ③ 故障转移
643 */
644 if (
645 existingRegions.length > 0
646 ) {
647 groups.push({
648 "name": GROUP_NAMES.FALLBACK,
649 "type": "fallback",
650 "proxies": existingRegions,
651 "url": TEST_URL,
652 "interval": FALLBACK_INTERVAL,
653 "timeout": GROUP_TIMEOUT,
654 "lazy": true
655 });
656 nodeSelectOptions.push(
657 GROUP_NAMES.FALLBACK
658 );
659 }
660 /*
661 * 地区加入节点选择。
662 */
663 for (
664 let i = 0;
665 i < existingRegions.length;
666 i++
667 ) {
668 nodeSelectOptions.push(
669 existingRegions[i]
670 );
671 }
672 /*
673 * ① 节点选择
674 *
675 * 最终插入到 groups[0]。
676 */
677 groups.unshift(
678 createSelectGroup(
679 GROUP_NAMES.NODE_SELECT,
680 nodeSelectOptions
681 )
682 );
683 /*
684 * ========================================================
685 * 第二层:地区策略
686 * ========================================================
687 */
688 addExistingRegionGroup(
689 groups,
690 regionNodes,
691 "🇭🇰 香港"
692 );
693 addExistingRegionGroup(
694 groups,
695 regionNodes,
696 "🇹🇼 台湾"
697 );
698 addExistingRegionGroup(
699 groups,
700 regionNodes,
701 "🇯🇵 日本"
702 );
703 addExistingRegionGroup(
704 groups,
705 regionNodes,
706 "🇸🇬 新加坡"
707 );
708 addExistingRegionGroup(
709 groups,
710 regionNodes,
711 "🇺🇸 美国"
712 );
713 addExistingRegionGroup(
714 groups,
715 regionNodes,
716 "🌐 其他"
717 );
718 /*
719 * ========================================================
720 * 第三层:人工智能
721 * ========================================================
722 *
723 * 排除香港。
724 */
725 const aiRegions = [
726 "🇹🇼 台湾",
727 "🇯🇵 日本",
728 "🇸🇬 新加坡",
729 "🇺🇸 美国"
730 ];
731 const aiProxies = [];
732 for (
733 let i = 0;
734 i < aiRegions.length;
735 i++
736 ) {
737 if (
738 existingRegions.indexOf(
739 aiRegions[i]
740 ) !== -1
741 ) {
742 aiProxies.push(
743 aiRegions[i]
744 );
745 }
746 }
747 if (
748 aiProxies.length > 0
749 ) {
750 groups.push({
751 "name": GROUP_NAMES.AI,
752 "type": "url-test",
753 "proxies": aiProxies,
754 "url": TEST_URL,
755 "interval": GROUP_INTERVAL,
756 "timeout": GROUP_TIMEOUT,
757 "lazy": true,
758 "tolerance": GROUP_TOLERANCE,
759 "max-failed-times": 3
760 });
761 }
762 /*
763 * ========================================================
764 * 第四层:海外服务
765 * ========================================================
766 */
767 const overseasOptions = [];
768 overseasOptions.push(
769 GROUP_NAMES.NODE_SELECT
770 );
771 if (
772 hasGroup(
773 existingRegions,
774 GROUP_NAMES.AUTO
775 )
776 ) {
777 overseasOptions.push(
778 GROUP_NAMES.AUTO
779 );
780 }
781 if (
782 hasGroup(
783 existingRegions,
784 GROUP_NAMES.FALLBACK
785 )
786 ) {
787 overseasOptions.push(
788 GROUP_NAMES.FALLBACK
789 );
790 }
791 groups.push(
792 createSelectGroup(
793 GROUP_NAMES.OVERSEAS,
794 overseasOptions
795 )
796 );
797 /*
798 * ========================================================
799 * 第五层:网络测试
800 * ========================================================
801 */
802 const networkTestOptions = [
803 GROUP_NAMES.DIRECT,
804 GROUP_NAMES.NODE_SELECT
805 ];
806 if (
807 existingRegions.length > 0
808 ) {
809 networkTestOptions.push(
810 GROUP_NAMES.AUTO
811 );
812 }
813 groups.push(
814 createSelectGroup(
815 GROUP_NAMES.NETWORK_TEST,
816 networkTestOptions
817 )
818 );
819 /*
820 * ========================================================
821 * 第六层:代理服务
822 * ========================================================
823 */
824 const proxyServiceOptions = [
825 GROUP_NAMES.NODE_SELECT
826 ];
827 if (
828 existingRegions.length > 0
829 ) {
830 proxyServiceOptions.push(
831 GROUP_NAMES.AUTO,
832 GROUP_NAMES.FALLBACK
833 );
834 }
835 proxyServiceOptions.push(
836 GROUP_NAMES.DIRECT
837 );
838 groups.push(
839 createSelectGroup(
840 GROUP_NAMES.PROXY_SERVICE,
841 proxyServiceOptions,
842 true
843 )
844 );
845 /*
846 * ========================================================
847 * 第七层:全球直连
848 * ========================================================
849 */
850 groups.push(
851 createSelectGroup(
852 GROUP_NAMES.DIRECT,
853 [
854 "DIRECT"
855 ]
856 )
857 );
858 /*
859 * ========================================================
860 * 第八层:广告拦截
861 * ========================================================
862 */
863 groups.push(
864 createSelectGroup(
865 GROUP_NAMES.AD_BLOCK,
866 [
867 "REJECT"
868 ]
869 )
870 );
871 /*
872 * ========================================================
873 * 第九层:兜底策略
874 * ========================================================
875 */
876 const finalOptions = [];
877 if (
878 existingRegions.length > 0
879 ) {
880 finalOptions.push(
881 GROUP_NAMES.NODE_SELECT
882 );
883 }
884 finalOptions.push(
885 GROUP_NAMES.DIRECT
886 );
887 groups.push(
888 createSelectGroup(
889 GROUP_NAMES.FINAL,
890 finalOptions,
891 true
892 )
893 );
894 return groups;
895}
896/* ============================================================
897 * 十二、规则集
898 * ============================================================
899 */
900const RULE_PROVIDERS = {
901 "ads": {
902 "type": "http",
903 "behavior": "domain",
904 "format": "text",
905 "path": "./rules/adss.list",
906 "url":
907 "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/ads.list",
908 "interval": 86400
909 },
910 "applications": {
911 "type": "http",
912 "behavior": "classical",
913 "format": "text",
914 "path": "./rules/applicationss.list",
915 "url":
916 "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/applications.list",
917 "interval": 86400
918 },
919 "private": {
920 "type": "http",
921 "behavior": "domain",
922 "format": "text",
923 "path": "./rules/privates.list",
924 "url":
925 "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/private.list",
926 "filter": "^((?!openai).)*$",
927 "interval": 86400
928 },
929 "microsoft-cn": {
930 "type": "http",
931 "behavior": "domain",
932 "format": "text",
933 "path": "./rules/microsoft-cns.list",
934 "url":
935 "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/microsoft-cn.list",
936 "interval": 86400
937 },
938 "openai": {
939 "type": "http",
940 "behavior": "domain",
941 "format": "text",
942 "path": "./rules/openais.list",
943 "url":
944 "https://cdn.jsdelivr.net/gh/DustinWin/ruleset_geodata@refs/heads/mihomo-ruleset/ai.list",
945 "interval": 86400
946 },
947 "apple-cn": {
948 "type": "http",
949 "behavior": "domain",
950 "format": "text",
951 "path": "./rules/apple-cns.list",
952 "url":
953 "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/apple-cn.list",
954 "interval": 86400
955 },
956 "google-cn": {
957 "type": "http",
958 "behavior": "domain",
959 "format": "text",
960 "path": "./rules/google-cns.list",
961 "url":
962 "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/google-cn.list",
963 "interval": 86400
964 },
965 "games-cn": {
966 "type": "http",
967 "behavior": "domain",
968 "format": "text",
969 "path": "./rules/games-cns.list",
970 "url":
971 "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/games-cn.list",
972 "interval": 86400
973 },
974 "networktest": {
975 "type": "http",
976 "behavior": "classical",
977 "format": "text",
978 "path": "./rules/networktests.list",
979 "url":
980 "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/networktest.list",
981 "interval": 86400
982 },
983 "proxy": {
984 "type": "http",
985 "behavior": "domain",
986 "format": "text",
987 "path": "./rules/proxys.list",
988 "url":
989 "https://fastly.jsdelivr.net/gh/y7478729/ruleset_geodata@clash-ruleset/proxy.list",
990 "interval": 86400
991 },
992 "cn": {
993 "type": "http",
994 "behavior": "domain",
995 "format": "text",
996 "path": "./rules/cns.list",
997 "url":
998 "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/cn.list",
999 "interval": 86400
1000 },
1001 "telegramip": {
1002 "type": "http",
1003 "behavior": "ipcidr",
1004 "format": "text",
1005 "path": "./rules/telegramips.list",
1006 "url":
1007 "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/telegramip.list",
1008 "interval": 86400
1009 },
1010 "privateip": {
1011 "type": "http",
1012 "behavior": "ipcidr",
1013 "format": "text",
1014 "path": "./rules/privateips.list",
1015 "url":
1016 "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/privateip.list",
1017 "interval": 86400
1018 },
1019 "cnip": {
1020 "type": "http",
1021 "behavior": "ipcidr",
1022 "format": "text",
1023 "path": "./rules/cnips.list",
1024 "url":
1025 "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@clash-ruleset/cnip.list",
1026 "interval": 86400
1027 }
1028};
1029/* ============================================================
1030 * 十三、规则
1031 * ============================================================
1032 */
1033const RULES = [
1034 /*
1035 * AI
1036 */
1037 "RULE-SET,openai,🤖 人工智能",
1038 /*
1039 * 广告
1040 */
1041 "RULE-SET,ads,🛑 广告拦截",
1042 /*
1043 * 软件
1044 */
1045 "RULE-SET,applications,🎯 全球直连",
1046 /*
1047 * 私有网络
1048 */
1049 "RULE-SET,private,🎯 全球直连",
1050 /*
1051 * Microsoft
1052 */
1053 "RULE-SET,microsoft-cn,🌍 海外服务",
1054 /*
1055 * Apple
1056 */
1057 "RULE-SET,apple-cn,🌍 海外服务",
1058 /*
1059 * Google
1060 */
1061 "RULE-SET,google-cn,🌍 海外服务",
1062 /*
1063 * 游戏
1064 */
1065 "RULE-SET,games-cn,🌍 海外服务",
1066 /*
1067 * 网络测试
1068 */
1069 "RULE-SET,networktest,📈 网络测试",
1070 /*
1071 * 代理域名
1072 */
1073 "RULE-SET,proxy,🪜 代理服务",
1074 /*
1075 * 中国域名
1076 */
1077 "RULE-SET,cn,🎯 全球直连",
1078 /*
1079 * Telegram IP
1080 */
1081 "RULE-SET,telegramip,🌍 海外服务,no-resolve",
1082 /*
1083 * 私有 IP
1084 */
1085 "RULE-SET,privateip,🎯 全球直连,no-resolve",
1086 /*
1087 * 中国 IP
1088 */
1089 "RULE-SET,cnip,🎯 全球直连,no-resolve",
1090 /*
1091 * 最终兜底
1092 */
1093 "MATCH,🎯 兜底策略"
1094];
1095/* ============================================================
1096 * 十四、主函数
1097 * ============================================================
1098 */
1099function main(config) {
1100 /*
1101 * --------------------------------------------------------
1102 * 1. 检查配置
1103 * --------------------------------------------------------
1104 */
1105 const proxyCount =
1106 config &&
1107 Array.isArray(
1108 config.proxies
1109 )
1110 ? config.proxies.length
1111 : 0;
1112 const providerCount =
1113 config &&
1114 config["proxy-providers"] &&
1115 typeof config["proxy-providers"] === "object"
1116 ? Object.keys(
1117 config["proxy-providers"]
1118 ).length
1119 : 0;
1120 /*
1121 * 没有节点,也没有节点提供器。
1122 */
1123 if (
1124 proxyCount === 0 &&
1125 providerCount === 0
1126 ) {
1127 throw new Error(
1128 "当前订阅没有找到任何代理节点或代理集合"
1129 );
1130 }
1131 /*
1132 * --------------------------------------------------------
1133 * 2. 基础配置
1134 * --------------------------------------------------------
1135 */
1136 Object.assign(
1137 config,
1138 GENERAL_CONFIG
1139 );
1140 /*
1141 * --------------------------------------------------------
1142 * 3. Sniffer
1143 * --------------------------------------------------------
1144 */
1145 config["sniffer"] =
1146 SNIFFER_CONFIG;
1147 /*
1148 * --------------------------------------------------------
1149 * 4. TUN
1150 * --------------------------------------------------------
1151 */
1152 config["tun"] =
1153 TUN_CONFIG;
1154 /*
1155 * --------------------------------------------------------
1156 * 5. DNS
1157 * --------------------------------------------------------
1158 */
1159 config["dns"] =
1160 DNS_CONFIG;
1161 /*
1162 * --------------------------------------------------------
1163 * 6. 代理组
1164 * --------------------------------------------------------
1165 */
1166 config["proxy-groups"] =
1167 createProxyGroups(
1168 config
1169 );
1170 /*
1171 * --------------------------------------------------------
1172 * 7. 规则集
1173 * --------------------------------------------------------
1174 */
1175 config["rule-providers"] =
1176 RULE_PROVIDERS;
1177 /*
1178 * --------------------------------------------------------
1179 * 8. 规则
1180 * --------------------------------------------------------
1181 */
1182 config["rules"] =
1183 RULES;
1184 /*
1185 * --------------------------------------------------------
1186 * 9. 返回配置
1187 * --------------------------------------------------------
1188 */
1189 return config;
1190}
1191