Skip to main content

Clash-verge 全局脚本配置

// Define main function (script entry)
function main(config) {

    // ============================================================
    // 1. 初始化基础配置
    // ============================================================

    if (!Array.isArray(config["proxy-groups"])) {
        config["proxy-groups"] = [];
    }

    if (!Array.isArray(config.proxies)) {
        config.proxies = [];
    }

    if (!Array.isArray(config.rules)) {
        config.rules = [];
    }

    if (!config.dns) {
        config.dns = {};
    }

    if (!Array.isArray(config.dns["fake-ip-filter"])) {
        config.dns["fake-ip-filter"] = [];
    }

    if (!config.tun) {
        config.tun = {};
    }

    if (!Array.isArray(config.tun["route-exclude-address"])) {
        config.tun["route-exclude-address"] = [];
    }


    // ============================================================
    // 2. 清理本脚本之前生成的策略组
    //
    // 防止脚本重复执行后产生重复策略组
    // ============================================================

    const managedGroups = new Set([
        "Lzc",
        "AdsPower",
        "Claude",
        "ChatGPT",
        "Gemini",
        "IPCheck"
    ]);

    config["proxy-groups"] = config["proxy-groups"].filter(
        group => !managedGroups.has(group.name)
    );


    // ============================================================
    // 3. 清理旧 Lzc-Node
    // ============================================================

    config.proxies = config.proxies.filter(
        proxy => proxy.name !== "Lzc-Node"
    );


    // ============================================================
    // 4. 获取原配置所有策略组和节点
    //
    // 注意:
    // 这里只获取原始配置中的策略组与节点。
    // 自定义策略组之间不互相引用,避免递归。
    // ============================================================

    const groupNames = config["proxy-groups"]
        .map(group => group.name)
        .filter(Boolean);

    const nodeNames = config.proxies
        .map(proxy => proxy.name)
        .filter(Boolean);

    const availableOptions = [
        ...new Set([
            ...groupNames,
            ...nodeNames,
            "DIRECT",
            "REJECT"
        ])
    ];


    // ============================================================
    // 5. Lazycat
    // ============================================================

    const LzcNode = {
        name: "Lzc-Node",
        type: "http",
        server: "127.0.0.1",
        port: 31085
    };

    config.proxies.push(LzcNode);

    const LzcGroup = {
        name: "Lzc",
        type: "select",
        icon: "https://developer.lazycat.cloud/manage/assets/logo-BVvfUYI1.png",
        proxies: [
            "DIRECT",
            "Lzc-Node"
        ]
    };


    // ============================================================
    // 6. Claude
    // ============================================================

    const ClaudeGroup = {
        name: "Claude",
        type: "select",
        icon: "https://cdn.jsdelivr.net/gh/selfhst/icons@main/png/claude.png",
        proxies: availableOptions
    };


    // ============================================================
    // 7. ChatGPT
    // ============================================================

    const ChatGPTGroup = {
        name: "ChatGPT",
        type: "select",
        icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/png/chatgpt.png",
        proxies: availableOptions
    };


    // ============================================================
    // 8. Gemini
    // ============================================================

    const GeminiGroup = {
        name: "Gemini",
        type: "select",
        icon: "https://cdn.jsdelivr.net/gh/selfhst/icons@main/png/google-gemini.png",
        proxies: availableOptions
    };


    // ============================================================
    // 9. IPCheck
    // ============================================================

    const IPCheckGroup = {
        name: "IPCheck",
        type: "select",
        icon: "https://ippure.com/favicon.ico",
        proxies: availableOptions
    };


    // ============================================================
    // 10. AdsPower
    //
    // AdsPower 是 SunBrowser 普通流量的默认出口。
    //
    // ChatGPT / Claude / Gemini / IPCheck 等明确规则
    // 会优先于 AdsPower。
    // ============================================================

    const AdsPowerGroup = {
        name: "AdsPower",
        type: "select",
        icon: "https://www.adspower.com/favicon.ico",
        proxies: [
            "DIRECT",
            ...availableOptions.filter(
                option =>
                    option !== "DIRECT" &&
                    option !== "REJECT"
            ),
            "REJECT"
        ]
    };


    // ============================================================
    // 11. 自定义策略组顺序
    //
    // 最终 UI 顺序:
    //
    // 原有策略组
    // ↓
    // IPCheck
    // Lzc
    // Claude
    // ChatGPT
    // Gemini
    // AdsPower
    // ============================================================

    config["proxy-groups"].push(
        IPCheckGroup,
        LzcGroup,
        ClaudeGroup,
        ChatGPTGroup,
        GeminiGroup,
        AdsPowerGroup
    );


    // ============================================================
    // 12. AdsPower 自身规则
    //
    // 注意:
    // SunBrowser.exe 不在这里!
    //
    // SunBrowser 的 PROCESS-NAME 规则必须放在
    // ChatGPT / Claude / Gemini / IPCheck 等域名规则之后,
    // 否则会提前截获整个浏览器流量。
    // ============================================================

    const adspower_rules = [

        // AdsPower Local API
        "DOMAIN,local.adspower.net,DIRECT",

        // Localhost
        "IP-CIDR,127.0.0.0/8,DIRECT,no-resolve",

        // AdsPower 主程序
        "PROCESS-NAME,AdsPower Global.exe,AdsPower",

        // 旧版本兼容
        "PROCESS-NAME,AdsPower.exe,AdsPower",

        // AdsPower 其他相关进程
        "PROCESS-NAME-REGEX,.*[Aa]ds[Pp]ower.*,AdsPower",

        // AdsPower 官方服务
        "DOMAIN-SUFFIX,adspower.com,AdsPower",
        "DOMAIN-SUFFIX,adspower.net,AdsPower"
    ];


    // ============================================================
    // 13. Claude Rules
    // ============================================================

    const claude_rules = [
        "DOMAIN,api.anthropic.com,Claude",
        "DOMAIN-SUFFIX,anthropic.com,Claude",
        "DOMAIN-SUFFIX,claude.ai,Claude",
        "DOMAIN-SUFFIX,claudeusercontent.com,Claude",

        // Analytics / Telemetry
        "DOMAIN-SUFFIX,segment.io,Claude",
        "DOMAIN-SUFFIX,segment.com,Claude"
    ];


    // ============================================================
    // 14. ChatGPT / OpenAI Rules
    // ============================================================

    const chatgpt_rules = [

        // ChatGPT
        "DOMAIN-SUFFIX,chatgpt.com,ChatGPT",

        // OpenAI
        "DOMAIN-SUFFIX,openai.com,ChatGPT",

        // Static Assets
        "DOMAIN-SUFFIX,oaistatic.com,ChatGPT",

        // 用户上传 / 生成内容
        "DOMAIN-SUFFIX,oaiusercontent.com,ChatGPT",

        // Statsig
        "DOMAIN-SUFFIX,oaistatsig.com,ChatGPT",

        // Merge CDN
        "DOMAIN-SUFFIX,openaimerge.com,ChatGPT",

        // Auth
        "DOMAIN-SUFFIX,auth.openai.com,ChatGPT"
    ];


    // ============================================================
    // 15. Gemini Rules
    //
    // 不匹配整个 google.com / googleapis.com
    // 避免把 Google 全家桶都拖进 Gemini。
    // ============================================================

    const gemini_rules = [

        // Gemini Web
        "DOMAIN,gemini.google.com,Gemini",

        // Google AI Studio
        "DOMAIN,aistudio.google.com,Gemini",

        // Gemini API
        "DOMAIN,generativelanguage.googleapis.com,Gemini",

        // Google AI Developer
        "DOMAIN-SUFFIX,ai.google.dev,Gemini"
    ];


    // ============================================================
    // 16. IPCheck Rules
    // ============================================================

    const ipcheck_rules = [

        // IPPure
        "DOMAIN-SUFFIX,ippure.com,IPCheck",

        // Ping0
        "DOMAIN-SUFFIX,ping0.cc,IPCheck",

        // IP125
        "DOMAIN-SUFFIX,ip125.com,IPCheck",

        // IP138
        "DOMAIN-SUFFIX,ip138.com,IPCheck",
        "DOMAIN-SUFFIX,ipshudi.com,IPCheck",

        // IP.SB
        "DOMAIN-SUFFIX,ip.sb,IPCheck",

        // IPInfo
        "DOMAIN-SUFFIX,ipinfo.io,IPCheck",

        // IP API
        "DOMAIN-SUFFIX,ipapi.co,IPCheck",
        "DOMAIN-SUFFIX,ip-api.com,IPCheck",

        // ifconfig
        "DOMAIN-SUFFIX,ifconfig.co,IPCheck",
        "DOMAIN-SUFFIX,ifconfig.me,IPCheck",

        // ipify
        "DOMAIN-SUFFIX,ipify.org,IPCheck",

        // icanhazip
        "DOMAIN-SUFFIX,icanhazip.com,IPCheck",

        // IP Location
        "DOMAIN-SUFFIX,iplocation.net,IPCheck",

        // What Is My IP
        "DOMAIN-SUFFIX,whatismyip.com,IPCheck",
        "DOMAIN-SUFFIX,whatismyipaddress.com,IPCheck",

        // BrowserLeaks
        "DOMAIN-SUFFIX,browserleaks.com,IPCheck",

        // IPLeak
        "DOMAIN-SUFFIX,ipleak.net,IPCheck",

        // DNS Leak Test
        "DOMAIN-SUFFIX,dnsleaktest.com,IPCheck",

        // Whoer
        "DOMAIN-SUFFIX,whoer.net,IPCheck",

        // IPHey
        "DOMAIN-SUFFIX,iphey.com,IPCheck",

        // Scamalytics
        "DOMAIN-SUFFIX,scamalytics.com,IPCheck",

        // IPQualityScore
        "DOMAIN-SUFFIX,ipqualityscore.com,IPCheck",

        // IP2Location
        "DOMAIN-SUFFIX,ip2location.com,IPCheck",

        // IPv6 Test
        "DOMAIN-SUFFIX,test-ipv6.com,IPCheck"
    ];


    // ============================================================
    // 17. Lazycat Rules
    // ============================================================

    const lzc_rules = [
        "IP-CIDR,2000::6666/128,DIRECT",
        "IP-CIDR,6.6.6.6/32,DIRECT",

        "DOMAIN-SUFFIX,heiyu.space,Lzc",

        "DOMAIN-SUFFIX,lazycat.cloud,DIRECT",

        "IP-CIDR,fc03:1136:3800::/40,Lzc",

        "PROCESS-NAME-REGEX,.*lzc-core.*,DIRECT",

        "PROCESS-NAME-REGEX,.*懒猫微服.*,DIRECT",

        "PROCESS-NAME,cloud.lazycat.client,DIRECT",

        "DOMAIN-SUFFIX,lazycatmicroserver.com,DIRECT"
    ];


    // ============================================================
    // 18. SunBrowser Fallback
    //
    // 极其重要:
    //
    // 这条必须位于
    //
    // IPCheck
    // Claude
    // ChatGPT
    // Gemini
    // Lazycat
    //
    // 等具体规则之后。
    //
    // 逻辑:
    //
    // SunBrowser → chatgpt.com
    //      命中 ChatGPT
    //
    // SunBrowser → claude.ai
    //      命中 Claude
    //
    // SunBrowser → gemini.google.com
    //      命中 Gemini
    //
    // SunBrowser → ippure.com
    //      命中 IPCheck
    //
    // SunBrowser → 普通网站
    //      最后命中 AdsPower
    //
    // ============================================================

    const sunbrowser_fallback_rules = [
        "PROCESS-NAME,SunBrowser.exe,AdsPower"
    ];


    // ============================================================
    // 19. Rules 优先级
    //
    // Mihomo 使用 First Match。
    //
    // 顺序:
    //
    // AdsPower 自身程序
    // ↓
    // IPCheck
    // ↓
    // Lazycat
    // ↓
    // Claude
    // ↓
    // ChatGPT
    // ↓
    // Gemini
    // ↓
    // SunBrowser → AdsPower Fallback
    // ↓
    // 原配置 Rules
    //
    // ============================================================

    const customRules = [

        // AdsPower 主程序 / Local API
        ...adspower_rules,

        // 特定业务规则
        ...ipcheck_rules,
        ...lzc_rules,
        ...claude_rules,
        ...chatgpt_rules,
        ...gemini_rules,

        // SunBrowser 最后兜底
        ...sunbrowser_fallback_rules
    ];


    // 规则去重
    config.rules = [
        ...new Set([
            ...customRules,
            ...config.rules
        ])
    ];


    // ============================================================
    // 20. DNS Fake-IP Filter
    // ============================================================

    const fakeIpFilters = [

        // --------------------------------------------------------
        // Lazycat
        // --------------------------------------------------------
        "+.heiyu.space",
        "+.lazycat.cloud",


        // --------------------------------------------------------
        // Claude
        // --------------------------------------------------------
        "+.claude.ai",
        "+.anthropic.com",
        "+.claudeusercontent.com",
        "+.segment.io",
        "+.segment.com",


        // --------------------------------------------------------
        // ChatGPT
        // --------------------------------------------------------
        "+.chatgpt.com",
        "+.openai.com",
        "+.oaistatic.com",
        "+.oaiusercontent.com",
        "+.oaistatsig.com",
        "+.openaimerge.com",


        // --------------------------------------------------------
        // Gemini
        // --------------------------------------------------------
        "gemini.google.com",
        "aistudio.google.com",
        "generativelanguage.googleapis.com",


        // --------------------------------------------------------
        // AdsPower
        // --------------------------------------------------------
        "local.adspower.net",
        "+.adspower.com",
        "+.adspower.net",


        // --------------------------------------------------------
        // IPCheck
        // --------------------------------------------------------
        "+.ippure.com",
        "+.ping0.cc",
        "+.ip125.com",
        "+.ip138.com",
        "+.ipshudi.com",
        "+.ip.sb",
        "+.ipinfo.io",
        "+.ipapi.co",
        "+.ip-api.com",
        "+.ifconfig.co",
        "+.ifconfig.me",
        "+.ipify.org",
        "+.icanhazip.com",
        "+.iplocation.net",
        "+.whatismyip.com",
        "+.whatismyipaddress.com",
        "+.browserleaks.com",
        "+.ipleak.net",
        "+.dnsleaktest.com",
        "+.whoer.net",
        "+.iphey.com",
        "+.scamalytics.com",
        "+.ipqualityscore.com",
        "+.ip2location.com",
        "+.test-ipv6.com"
    ];


    config.dns["fake-ip-filter"] = [
        ...new Set([
            ...config.dns["fake-ip-filter"],
            ...fakeIpFilters
        ])
    ];


    // ============================================================
    // 21. TUN Route Exclude
    // ============================================================

    const routeExclude = [
        "6.6.6.6/32",
        "2000::6666/128",
        "183.136.206.164/32"
    ];


    config.tun["route-exclude-address"] = [
        ...new Set([
            ...config.tun["route-exclude-address"],
            ...routeExclude
        ])
    ];


    // ============================================================
    // Done
    // ============================================================

    console.log(
        "Merge Success: IPCheck + Lazycat + Claude + ChatGPT + Gemini + AdsPower Loaded"
    );

    return config;
}