• 橙柚

    我看昨天黑白公益站开了注册码,而且价格还蛮实惠的,应该有好多佬友进去了,但是会碰到网络问题,那是因为黑白公益站的节点校验要求比较高,所以建议直接直连,但是liunxdo登陆又需要过墙,导致出现了网络互锁的问题,该怎么办呢!

    刚刚看看到淇淇佬(@ouyangqiqi)说有打赏,重赏之下必有勇夫,直接上教程,需要使用clash verge

    一、笨笨方法

    - 在登陆黑与白公益站 和 黑与白福利站的时候,关闭系统代理,这样就会自动走本地直连,一般都是正常访问的

    - 然后在需要登陆linuxdo的时候,会卡在一个回调linuxdo的登陆连接页面,是没有内容的,这个时候打开clash verge的代理,刷新页面就可以授权了,然后就成功了

    一、clash分流方法

    图片

    复制如下内容进去(包含其他公益站的分流:薄荷、anyrouter、chy、烁、muyuan、46w、、、、 不要说我白嫖怪呀 ^-^)

    下面脚本还是有点问题,我直接给出自己珍藏多年的配置文件吧。

    保证没问题 :script.js文件 =》 Script.zip (10.4 KB)

    简洁版如下(已修改):```
    // =========================
    // 这里粘贴远程 Script.js 内容
    // 注意:把远程脚本里的 function main(config)
    // 改成 function remoteMain(config)
    const EXCLUDE_PATTERN = /(拒绝|直连|群|邀请|返利|循环|官网|客服|网站|网址|获取|订阅|流量|到期|机场|下次|版本|官址|备用|过期|已用|联系|邮箱|工单|贩卖|通知|倒卖|防止|国内|地址|频道|无法|说明|使用|提示|特别|访问|支持|教程|关注|更新|作者|加入|超时|收藏|福利|好友|失联|选择|剩余|公益|发布|通路|登录|禁止|定时|渠道|牢记|永久|余额|阁下|本站|刷新|导航|⚠️|@|https?:\/\/|\.com\b|com\/|USE|USED|TOTAL|EXPIRE|EMAIL|Panel|Channel|Author|traffic)/i;

    const FLAG_EMOJI_PATTERN = /^((?:�[�-�]){2})\s*/;

    const DIGITS_PATTERN = /\d+/g;
    const NATURAL_SORT_PAD_WIDTH = 16;

    const GITHUB_RAW_HOST = "raw.githubusercontent.com";
    const GITHUB_PROXY_PREFIX = "https://v6.gh-proxy.org/";

    const POLICY_MAIN = "节点选择";
    const POLICY_DIRECT = "DIRECT";
    const NAME_AUTO = "自动选择";
    const NAME_BALANCE = "负载均衡";

    const GROUP_NAME = {
    all: "全部节点",
    other: "其他节点",
    global: "GLOBAL",
    };

    const ICON_BASE_URL = "https://fastly.jsdelivr.net/gh/Koolson/Qure@master/IconSet/Color/";
    const ICON = {
    global: ICON_BASE_URL + "Global.png",
    select: ICON_BASE_URL + "Proxy.png",
    all: ICON_BASE_URL + "Area.png",
    auto: ICON_BASE_URL + "Auto.png",
    balance: ICON_BASE_URL + "Round_Robin.png",
    other: ICON_BASE_URL + "World_Map.png",
    hk: ICON_BASE_URL + "Hong_Kong.png",
    tw: ICON_BASE_URL + "Taiwan.png",
    jp: ICON_BASE_URL + "Japan.png",
    kr: ICON_BASE_URL + "Korea.png",
    sg: ICON_BASE_URL + "Singapore.png",
    us: ICON_BASE_URL + "United_States.png",
    eu: ICON_BASE_URL + "European_Union.png",
    };

    const SERVICES = [
    { name: "AI", icon: ICON_BASE_URL + "ChatGPT.png" },
    { name: "YouTube", icon: ICON_BASE_URL + "YouTube.png" },
    { name: "Google", icon: ICON_BASE_URL + "Google_Search.png" },
    { name: "GitHub", icon: ICON_BASE_URL + "GitHub.png" },
    { name: "Microsoft", icon: ICON_BASE_URL + "Microsoft.png" },
    { name: "Apple", icon: ICON_BASE_URL + "Apple.png" },
    { name: "Telegram", icon: ICON_BASE_URL + "Telegram.png" },
    { name: "Cloudflare", icon: ICON_BASE_URL + "Cloudflare.png" },
    { name: "Twitter", icon: ICON_BASE_URL + "Twitter.png" },
    { name: "Instagram", icon: ICON_BASE_URL + "Instagram.png" },
    { name: "Spotify", icon: ICON_BASE_URL + "Spotify.png" },
    { name: "TikTok", icon: ICON_BASE_URL + "TikTok.png" },
    { name: "Netflix", icon: ICON_BASE_URL + "Netflix.png" },
    ];

    const DNS_DEFAULT = ["223.5.5.5", "119.29.29.29"];
    const DNS_CN = [
    "https://dns.alidns.com/dns-query#DIRECT",
    "https://doh.pub/dns-query#DIRECT",
    ];
    const DNS_HOSPITAL = ["10.1.201.98"];
    const DNS_GLOBAL = [
    "https://dns.cloudflare.com/dns-query#" + POLICY_MAIN,
    "https://dns.google/dns-query#" + POLICY_MAIN,
    ];

    const REGIONS = [
    {
    name: "香港节点", icon: ICON.hk,
    pattern: /(香港|深港|沪港|🇭🇰|\bHK\b|\bHKG\b|Hong\s?Kong|Hongkong|HKBN|HKT|PCCW|WTT|CMHK|HGC|Hutchison|Three\s?HK|3HK|Netvigator|iCable)/i,
    },
    {
    name: "台湾节点", icon: ICON.tw,
    pattern: /(台湾|福台|台灣|台北|新北|桃园|桃園|台中|台南|高雄|🇹🇼|\bTW\b|\bTWN\b|\bTPE\b|\bTSA\b|\bKHH\b|Taiwan|Taipei|New\s?Taipei|Taoyuan|Taichung|Tainan|Kaohsiung|中华电信|中華電信|\bCHT\b|Chunghwa|HiNet|Hinet|Seednet)/i,
    },
    {
    name: "日本节点", icon: ICON.jp,
    pattern: /(日本|沪日|东京|東京|大阪|🇯🇵|\bJP\b|\bJPN\b|Japan|Tokyo|Osaka|\bNRT\b|\bHND\b|\bKIX\b|\bCTS\b|\bFUK\b|\bNGO\b|SoftBank|KDDI|\bIIJ\b|IIJmio|Rakuten|楽天|Biglobe)/i,
    },
    {
    name: "韩国节点", icon: ICON.kr,
    pattern: /(韩国|韓國|🇰🇷|首尔|首爾|\bKR\b|\bKOR\b|Korea|Seoul|\bICN\b)/i,
    },
    {
    name: "新加坡节点", icon: ICON.sg,
    pattern: /(新加坡|狮城|獅城|🇸🇬|\bSG\b|\bSGP\b|Singapore|\bSIN\b|\bXSP\b)/i,
    },
    {
    name: "美国节点", icon: ICON.us,
    pattern: /(美国|美國|洛杉矶|洛杉磯|纽约|紐約|西雅图|西雅圖|圣何塞|聖何塞|旧金山|舊金山|芝加哥|达拉斯|達拉斯|硅谷|矽谷|夏威夷|新泽西|新澤西|马纳萨斯|馬納薩斯|🇺🇸|\bUS\b|\bUSA\b|United\s?States|America|Los\s?Angeles|\bLA\b|New\s?York|\bNYC\b|Seattle|San\s?Jose|San\s?Francisco|\bSFO\b|Chicago|Dallas|Silicon\s?Valley|Hawaii|Hawaiian|New\s?Jersey|\bNJ\b|Manassas|\bSJC\b|\bJFK\b|\bEWR\b|\bBOS\b|\bLAX\b|\bORD\b|\bATL\b|\bDFW\b|\bDAL\b|\bMIA\b|\bSEA\b|\bIAD\b|\bLAS\b|\bPHX\b|\bDEN\b|\bHOU\b|AT&T|\bATT\b|Verizon|T-?Mobile|Frontier|Comcast|Xfinity|Charter|Spectrum|\bCox\b)/i,
    },
    {
    name: "欧洲节点", icon: ICON.eu,
    pattern: /(奥地利|奧地利|京德|比利时|比利時|保加利亚|保加利亞|克罗地亚|克羅地亞|塞浦路斯|捷克|丹麦|丹麥|爱沙尼亚|愛沙尼亞|芬兰|芬蘭|法国|法國|德国|德國|希腊|希臘|匈牙利|爱尔兰|愛爾蘭|意大利|義大利|拉脱维亚|拉脫維亞|立陶宛|卢森堡|盧森堡|荷兰|荷蘭|波兰|波蘭|葡萄牙|罗马尼亚|羅馬尼亞|斯洛伐克|斯洛文尼亚|斯洛文尼亞|西班牙|瑞典|英国|英國|瑞士|欧洲|歐洲|🇦🇹|🇧🇪|🇧🇬|🇭🇷|🇨🇾|🇨🇿|🇩🇰|🇪🇪|🇫🇮|🇫🇷|🇩🇪|🇬🇷|🇭🇺|🇮🇪|🇮🇹|🇱🇻|🇱🇹|🇱🇺|🇳🇱|🇵🇱|🇵🇹|🇷🇴|🇸🇰|🇸🇮|🇪🇸|🇸🇪|🇬🇧|🇨🇭|\bEU\b|Europe|\bCDG\b|\bFRA\b|\bAMS\b|\bMAD\b|\bBCN\b|\bFCO\b|\bMUC\b|\bBRU\b|\bLHR\b|\bLGW\b|\bMAN\b|\bVIE\b|\bZRH\b|\bARN\b|\bCPH\b|\bWAW\b|\bPRG\b|\bHEL\b|\bDUB\b)/i,
    },
    ];

    const OTHER_NODE_EXCLUDE_FILTER = "(?i)" + REGIONS.map(function (region) {
    return region.pattern.source;
    }).join("|");

    const HEALTH_CHECK_BASE = {
    url: "https://www.gstatic.com/generate_204",
    interval: 300,
    timeout: 3000,
    lazy: true,
    "max-failed-times": 2,
    };
    const SELECT_BASE = { type: "select" };
    const URLTEST_BASE = Object.assign({}, HEALTH_CHECK_BASE, { type: "url-test", tolerance: 100 });
    const BALANCE_BASE = Object.assign({}, HEALTH_CHECK_BASE, { type: "load-balance", strategy: "sticky-sessions" });

    const RULESET_META_BASE = "https://" + GITHUB_RAW_HOST + "/MetaCubeX/meta-rules-dat/meta/geo/";
    const RULESET_DUSTIN_BASE = "https://" + GITHUB_RAW_HOST + "/DustinWin/ruleset_geodata/mihomo-ruleset/";

    const RULESET_URL = {
    private_domain: RULESET_META_BASE + "geosite/private.mrs",
    private_ip: RULESET_META_BASE + "geoip/private.mrs",
    fakeip_filter: RULESET_DUSTIN_BASE + "fakeip-filter.mrs",
    DownloadApps: "https://" + GITHUB_RAW_HOST + "/AIsouler/MyClash/main/Rules/DownloadApps.txt",
    captcha: "https://" + GITHUB_RAW_HOST + "/funianshengsheng/MihomoScript/main/rule/Captcha.mrs",
    webrtc: "https://" + GITHUB_RAW_HOST + "/funianshengsheng/MihomoScript/main/rule/WebRTC.list",
    speedtest_domain: RULESET_META_BASE + "geosite/ookla-speedtest.mrs",
    ai: RULESET_DUSTIN_BASE + "ai.mrs",
    gfw: RULESET_DUSTIN_BASE + "gfw.mrs",
    github_domain: RULESET_META_BASE + "geosite/github.mrs",
    youtube_domain: RULESET_META_BASE + "geosite/youtube.mrs",
    googlefcm: RULESET_META_BASE + "geosite/googlefcm.mrs",
    google_domain: RULESET_META_BASE + "geosite/google.mrs",
    google_ip: RULESET_META_BASE + "geoip/google.mrs",
    onedrive_domain: RULESET_META_BASE + "geosite/onedrive.mrs",
    microsoft_domain: RULESET_META_BASE + "geosite/microsoft.mrs",
    appletv_domain: RULESET_META_BASE + "geosite/apple-tvplus.mrs",
    apple_domain: RULESET_META_BASE + "geosite/apple.mrs",
    telegram_domain: RULESET_META_BASE + "geosite/telegram.mrs",
    telegram_ip: RULESET_META_BASE + "geoip/telegram.mrs",
    tiktok_domain: RULESET_META_BASE + "geosite/tiktok.mrs",
    twitter_domain: RULESET_META_BASE + "geosite/twitter.mrs",
    twitter_ip: RULESET_META_BASE + "geoip/twitter.mrs",
    instagram_domain: RULESET_META_BASE + "geosite/instagram.mrs",
    netflix_domain: RULESET_META_BASE + "geosite/netflix.mrs",
    netflix_ip: RULESET_META_BASE + "geoip/netflix.mrs",
    disney_domain: RULESET_META_BASE + "geosite/disney.mrs",
    spotify_domain: RULESET_META_BASE + "geosite/spotify.mrs",
    paypal_domain: RULESET_META_BASE + "geosite/paypal.mrs",
    cloudflare_domain: RULESET_META_BASE + "geosite/cloudflare.mrs",
    "geolocation-!cn": RULESET_META_BASE + "geosite/geolocation-!cn.mrs",
    geolocation_cn: RULESET_META_BASE + "geosite/geolocation-cn.mrs",
    add_direct_domain: "https://" + GITHUB_RAW_HOST + "/Seven1echo/Yaml/refs/heads/main/rules/Seven1_Direct_Domain.mrs",
    cn_additional_domain: "https://static-file-global.353355.xyz/rules/cn-additional-list.mrs",
    cn_domain: RULESET_META_BASE + "geosite/cn.mrs",
    cn_ip: RULESET_META_BASE + "geoip/cn.mrs",
    };

    const RULE_DEFS = [
    { name: "private_domain", behavior: "domain", policy: POLICY_DIRECT, dns: "system" },
    { name: "private_ip", behavior: "ipcidr", policy: POLICY_DIRECT, noResolve: true },
    // { name: "webrtc", behavior: "classical", policy: "REJECT", format: "text" },
    { raw: AND,((DST-PORT,443),(NETWORK,UDP),(NOT,((RULE-SET,cn_ip))),(NOT,((RULE-SET,cn_domain)))),REJECT },
    { name: "DownloadApps", behavior: "classical", policy: POLICY_DIRECT, format: "text" },
    { name: "speedtest_domain", behavior: "domain", policy: POLICY_MAIN },
    { name: "captcha", behavior: "domain", policy: "AI" },
    { name: "ai", behavior: "domain", policy: "AI" },
    { raw: "DOMAIN-SUFFIX,anyrouter.top,AI" },
    { name: "github_domain", behavior: "domain", policy: "GitHub" },
    { name: "youtube_domain", behavior: "domain", policy: "YouTube" },
    { name: "googlefcm", behavior: "domain", policy: POLICY_DIRECT },
    { name: "google_domain", behavior: "domain", policy: "Google" },
    { name: "google_ip", behavior: "ipcidr", policy: "Google", noResolve: true },
    { name: "onedrive_domain", behavior: "domain", policy: "Microsoft" },
    { name: "microsoft_domain", behavior: "domain", policy: "Microsoft" },
    { name: "appletv_domain", behavior: "domain", policy: "Apple" },
    { name: "apple_domain", behavior: "domain", policy: "Apple" },
    { name: "telegram_domain", behavior: "domain", policy: "Telegram" },
    { name: "telegram_ip", behavior: "ipcidr", policy: "Telegram", noResolve: true },
    { name: "tiktok_domain", behavior: "domain", policy: "TikTok" },
    { name: "twitter_domain", behavior: "domain", policy: "Twitter" },
    { name: "twitter_ip", behavior: "ipcidr", policy: "Twitter", noResolve: true },
    { name: "instagram_domain", behavior: "domain", policy: "Instagram" },
    { name: "netflix_domain", behavior: "domain", policy: "Netflix" },
    { name: "netflix_ip", behavior: "ipcidr", policy: "Netflix", noResolve: true },
    { name: "disney_domain", behavior: "domain", policy: POLICY_MAIN },
    { name: "spotify_domain", behavior: "domain", policy: "Spotify" },
    { name: "paypal_domain", behavior: "domain", policy: POLICY_MAIN },
    { name: "cloudflare_domain", behavior: "domain", policy: "Cloudflare" },
    { name: "geolocation-!cn", behavior: "domain", policy: POLICY_MAIN },
    { name: "gfw", behavior: "domain", policy: POLICY_MAIN },
    { name: "add_direct_domain", behavior: "domain", policy: POLICY_DIRECT },
    { name: "cn_additional_domain", behavior: "domain", policy: POLICY_DIRECT },
    { name: "geolocation_cn", behavior: "domain", policy: POLICY_DIRECT },
    { name: "cn_domain", behavior: "domain", policy: POLICY_DIRECT },
    { name: "cn_ip", behavior: "ipcidr", policy: POLICY_DIRECT, noResolve: true },
    { name: "fakeip_filter", behavior: "domain", policy: null },
    { raw: "MATCH," + POLICY_MAIN },
    ];

    const POLICY_DNS = {
    [POLICY_DIRECT]: DNS_CN,
    };

    const BASE_CONFIG = {
    "mixed-port": 7894,
    mode: "rule",
    "allow-lan": true,
    "bind-address": "*",
    "tcp-concurrent": true,
    "inbound-tfo": true,
    "unified-delay": true,
    "log-level": "silent",
    ipv6: false,
    "find-process-mode": "strict",
    "etag-support": true,
    "keep-alive-idle": 600,
    "keep-alive-interval": 60,
    "external-controller": "127.0.0.1:9090",
    "external-ui-name": "zashboard",
    "external-ui": "ui",
    "external-ui-url": "https://github.com/Zephyruso/zashboard/releases/latest/download/dist-no-fonts.zip",
    secret: "",
    profile: { "store-selected": true, "store-fake-ip": true },
    ntp: { enable: true, server: "ntp.aliyun.com", port: 123, interval: 60, "write-to-system": false },
    experimental: { "quic-go-disable-gso": true, "quic-go-disable-ecn": true },
    tun: {
    enable: true,
    stack: "gvisor",
    mtu: 1480,
    "dns-hijack": ["udp://any:53", "tcp://any:53"],
    "auto-detect-interface": true,
    "auto-route": true,
    "auto-redirect": true,
    "strict-route": true,
    // "route-exclude-cidr": ["192.168.0.0/16", "10.0.0.0/8", "172.16.0.0/12", "224.0.0.0/4"],
    "route-exclude-address": [
    "10.0.0.0/8",
    "172.16.0.0/12",
    "192.168.0.0/16",
    "224.0.0.0/4",
    ],
    "disable-icmp-forwarding": true,
    "endpoint-independent-nat": true,
    "udp-timeout": 60,
    gso: true,
    "gso-max-size": 65536,
    },
    sniffer: {
    enable: true,
    "override-destination": true,
    "parse-pure-ip": true,
    "force-dns-mapping": true,
    sniff: {
    QUIC: { ports: [443, 8443] },
    TLS: { ports: [443, 8443] },
    HTTP: { ports: [80, "8080-8880"] },
    },
    "force-domain": [
    "+.googlevideo.com", "+.youtube.com", "+.ytimg.com", "+.googlecdn.com",
    "+.netflix.com", "+.nflxvideo.net",
    "+.cloudfront.net", "+.cloudflare.net", "+.fastly.net",
    "+.akamaized.net", "+.akamai.net",
    "+.telegram.org", "+.t.me", "+.tdesktop.com",
    "+.cdn-telegram.org", "+.telegram-cdn.org", "+.cdn.telegram.org",
    "+.tiktokcdn.com", "+.tiktokv.com",
    "+.amazonaws.com", "+.media.dssott.com",
    ],
    "skip-domain": [
    "localhost", "+.lan", "+.local", "+.arpa", "+.invalid", "+.test",
    "+.push.apple.com", "+.apple.com", "+.icloud.com",
    "dlg.io.mi.com", "+.mi.com", "+.xiaomi.com", "+.market.xiaomi.com",
    "+.wechat.com", "+.qq.com", "+.qpic.cn", "+.wechatapp.com",
    "+.oray.com", "+.sunlogin.net",
    "+.pvp.net", "+.riotgames.com",
    "cloudflare-ech.com", "+.openai.*",
    ],
    "skip-src-address": ["127.0.0.0/8", "::1/128"],
    "skip-dst-address": ["rule-set:private_ip", "rule-set:cn_ip", "rule-set:telegram_ip"],
    },
    hosts: {
    "dns.alidns.com": ["223.5.5.5", "223.6.6.6"],
    "doh.pub": ["1.12.12.12", "120.53.53.53"],
    "dns.cloudflare.com": ["1.1.1.1", "1.0.0.1"],
    "dns.google": ["8.8.8.8", "8.8.4.4"],
    "services.googleapis.cn": ["services.googleapis.com"],
    "google.cn": ["google.com"],
    "cn.bing.com": ["global.bing.com"],
    "+.mcdn.bilivideo.com": ["0.0.0.0"],
    "+.mcdn.bilivideo.cn": ["0.0.0.0"],
    },
    };

    function isPlainObject(value) {
    return value !== null && typeof value === "object" && !Array.isArray(value);
    }

    function compareStrings(a, b) {
    return a < b ? -1 : a > b ? 1 : 0;
    }

    function naturalSortKey(text) {
    return text.replace(DIGITS_PATTERN, function (digits) {
    return digits.padStart(NATURAL_SORT_PAD_WIDTH, "0");
    });
    }

    function getRegionIndex(nodeName) {
    let matchedIndex = -1;
    let matchedPosition = -1;
    for (let i = 0; i < REGIONS.length; i++) {
    const pattern = REGIONS[i].pattern;
    pattern.lastIndex = 0;
    const match = pattern.exec(nodeName);
    if (match && match.index > matchedPosition) {
    matchedPosition = match.index;
    matchedIndex = i;
    }
    }
    return matchedIndex;
    }

    // function processProxies(rawProxies) {
    // const seenNames = new Set();
    // const sortEntries = [];

    // for (let i = 0; i < rawProxies.length; i++) {
    // const proxy = rawProxies[i];
    // const name = proxy && typeof proxy.name === "string" ? proxy.name.trim() : "";
    // // if (!name || seenNames.has(name) || EXCLUDE_PATTERN.test(name)) continue;
    // if (!name || seenNames.has(name)) continue;
    // seenNames.add(name);

    // const flagMatch = FLAG_EMOJI_PATTERN.exec(name);
    // sortEntries.push({
    // proxy: proxy.name === name ? proxy : Object.assign({}, proxy, { name: name }),
    // name: name,
    // flag: flagMatch ? flagMatch[1] : "",
    // sortKey: naturalSortKey(flagMatch ? name.slice(flagMatch[0].length) : name),
    // regionIndex: getRegionIndex(name),
    // });
    // }

    // sortEntries.sort(function (entryA, entryB) {
    // return compareStrings(entryA.flag, entryB.flag) || compareStrings(entryA.sortKey, entryB.sortKey);
    // });

    // const regionBuckets = REGIONS.map(function () { return []; });
    // const otherBucket = [];
    // const proxies = [];
    // const proxyNames = [];

    // for (let j = 0; j < sortEntries.length; j++) {
    // const entry = sortEntries[j];
    // proxies.push(entry.proxy);
    // proxyNames.push(entry.name);
    // if (entry.regionIndex >= 0) {
    // regionBuckets[entry.regionIndex].push(entry.name);
    // } else {
    // otherBucket.push(entry.name);
    // }
    // }

    // return {
    // proxies: proxies,
    // proxyNames: proxyNames,
    // regionBuckets: regionBuckets,
    // otherBucket: otherBucket,
    // };
    // }

    // const MAX_NODES_PER_REGION = 30;
    // const MAX_OTHER_NODES = 30;

    // 优先保留的节点关键词:命中这些关键词的节点会排在前面
    // 可以填机场名、倍率、专线、入口、节点编号、地区运营商等关键词
    const PREFERRED_NODE_KEYWORDS = [
    // "专线",
    // "IEPL",
    // "IPLC",
    // "低倍率",
    // "01",
    // "02",
    ];

    // 已知经常 timeout 或不想保留的节点关键词
    const BAD_NODE_KEYWORDS = [
    // "倍率高",
    // "游戏",
    // "家宽",
    // "实验",
    // "备用",
    ];

    function hasKeyword(text, keywords) {
    if (!text || !keywords || !keywords.length) return false;

    for (let i = 0; i < keywords.length; i++) {
    const keyword = keywords[i];
    if (keyword && text.indexOf(keyword) !== -1) {
    return true;
    }
    }

    return false;
    }

    function processProxies(rawProxies) {
    const nameCount = new Map();
    const sortEntries = [];

    for (let i = 0; i < rawProxies.length; i++) {
    const proxy = rawProxies[i];
    const originalName = proxy && typeof proxy.name === "string" ? proxy.name.trim() : "";

    if (!originalName) continue;

    // 只保留真实代理节点,避免公告、流量、到期信息等伪节点进入配置
    if (!proxy.type || !proxy.server || proxy.port == null) continue;

    // 已知坏节点直接排除
    if (hasKeyword(originalName, BAD_NODE_KEYWORDS)) continue;

    const count = (nameCount.get(originalName) || 0) + 1;
    nameCount.set(originalName, count);

    const finalName = count === 1 ? originalName : originalName + " #" + count;
    const finalProxy = Object.assign({}, proxy, { name: finalName });

    const flagMatch = FLAG_EMOJI_PATTERN.exec(finalName);
    const regionIndex = getRegionIndex(finalName);

    sortEntries.push({
    proxy: finalProxy,
    name: finalName,
    flag: flagMatch ? flagMatch[1] : "",
    sortKey: naturalSortKey(flagMatch ? finalName.slice(flagMatch[0].length) : finalName),
    regionIndex: regionIndex,
    preferred: hasKeyword(finalName, PREFERRED_NODE_KEYWORDS) ? 1 : 0,
    });
    }

    // 排序逻辑:
    // 1. 优选节点在前
    // 2. 同等优先级下按旗帜排序
    // 3. 再按自然名称排序
    sortEntries.sort(function (entryA, entryB) {
    return (entryB.preferred - entryA.preferred)
    || compareStrings(entryA.flag, entryB.flag)
    || compareStrings(entryA.sortKey, entryB.sortKey);
    });

    const regionBuckets = REGIONS.map(function () { return []; });
    const otherBucket = [];
    const proxies = [];
    const proxyNames = [];

    const regionCount = REGIONS.map(function () { return 0; });
    let otherCount = 0;

    for (let j = 0; j < sortEntries.length; j++) {
    const entry = sortEntries[j];

    // 取消节点限制
    // if (entry.regionIndex >= 0) {
    // if (regionCount[entry.regionIndex] >= MAX_NODES_PER_REGION) {
    // continue;
    // }

    // regionCount[entry.regionIndex]++;
    // regionBuckets[entry.regionIndex].push(entry.name);
    // } else {
    // if (otherCount >= MAX_OTHER_NODES) {
    // continue;
    // }

    // otherCount++;
    // otherBucket.push(entry.name);
    // }
    if (entry.regionIndex >= 0) {
    regionBuckets[entry.regionIndex].push(entry.name);
    } else {
    otherBucket.push(entry.name);
    }

    proxies.push(entry.proxy);
    proxyNames.push(entry.name);
    }

    return {
    proxies: proxies,
    proxyNames: proxyNames,
    regionBuckets: regionBuckets,
    otherBucket: otherBucket,
    };
    }

    // function processProxies(rawProxies) {
    // const nameCount = new Map();
    // const sortEntries = [];

    // for (let i = 0; i < rawProxies.length; i++) {
    // const proxy = rawProxies[i];
    // const originalName = proxy && typeof proxy.name === "string" ? proxy.name.trim() : "";

    // if (!originalName) continue;
    // if (!proxy.type || !proxy.server || proxy.port == null) continue;

    // const count = (nameCount.get(originalName) || 0) + 1;
    // nameCount.set(originalName, count);

    // const finalName = count === 1 ? originalName : originalName + " #" + count;
    // const finalProxy = Object.assign({}, proxy, { name: finalName });

    // const flagMatch = FLAG_EMOJI_PATTERN.exec(finalName);

    // sortEntries.push({
    // proxy: finalProxy,
    // name: finalName,
    // flag: flagMatch ? flagMatch[1] : "",
    // sortKey: naturalSortKey(flagMatch ? finalName.slice(flagMatch[0].length) : finalName),
    // regionIndex: getRegionIndex(finalName),
    // });
    // }

    // sortEntries.sort(function (entryA, entryB) {
    // return compareStrings(entryA.flag, entryB.flag) || compareStrings(entryA.sortKey, entryB.sortKey);
    // });

    // const regionBuckets = REGIONS.map(function () { return []; });
    // const otherBucket = [];
    // const proxies = [];
    // const proxyNames = [];

    // for (let j = 0; j < sortEntries.length; j++) {
    // const entry = sortEntries[j];
    // proxies.push(entry.proxy);
    // proxyNames.push(entry.name);

    // if (entry.regionIndex >= 0) {
    // regionBuckets[entry.regionIndex].push(entry.name);
    // } else {
    // otherBucket.push(entry.name);
    // }
    // }

    // return {
    // proxies: proxies,
    // proxyNames: proxyNames,
    // regionBuckets: regionBuckets,
    // otherBucket: otherBucket,
    // };
    // }

    function makeRuleProvider(rulesetName, behavior, format) {
    const rawUrl = RULESET_URL[rulesetName];
    if (!rawUrl) throw new Error("未找到规则集 URL: " + rulesetName);

    const isGithubUrl = rawUrl.indexOf(GITHUB_RAW_HOST) !== -1;
    const fileExt = format === "text" ? "txt" : format;
    const provider = {
    type: "http",
    format: format,
    behavior: behavior,
    interval: 86400,
    url: isGithubUrl ? GITHUB_PROXY_PREFIX + rawUrl : rawUrl,
    path: "./ruleset/" + rulesetName + "." + fileExt,
    };
    if (isGithubUrl) provider.proxy = POLICY_MAIN;
    return provider;
    }

    function buildRuleArtifacts() {
    const ruleProviders = {};
    const rules = [];
    // const nameserverPolicy = { "+.arpa": "system" };
    const nameserverPolicy = {
    "+.arpa": "system",
    "+.sschospital.cn": DNS_HOSPITAL,
    };

    for (let i = 0; i < RULE_DEFS.length; i++) {
    const ruleDef = RULE_DEFS[i];

    if (ruleDef.raw != null) {
    rules.push(ruleDef.raw);
    continue;
    }

    const rulesetName = ruleDef.name;
    const behavior = ruleDef.behavior;
    const policy = ruleDef.policy;
    const format = ruleDef.format != null ? ruleDef.format : "mrs";

    ruleProviders[rulesetName] = makeRuleProvider(rulesetName, behavior, format);

    if (policy) {
    rules.push(ruleDef.noResolve
    ? "RULE-SET," + rulesetName + "," + policy + ",no-resolve"
    : "RULE-SET," + rulesetName + "," + policy);
    }

    if (behavior === "domain") {
    const rulesetRef = "rule-set:" + rulesetName;
    let nameserver = ruleDef.dns;
    if (nameserver == null && policy) {
    nameserver = POLICY_DNS[policy] || DNS_GLOBAL;
    }
    if (nameserver) nameserverPolicy[rulesetRef] = nameserver;
    }
    }

    const fakeIpFilter = ["rule-set:private_domain", "rule-set:fakeip_filter", "rule-set:cn_domain"];

    return {
    ruleProviders: ruleProviders,
    rules: rules,
    nameserverPolicy: nameserverPolicy,
    fakeIpFilter: fakeIpFilter,
    };
    }

    const RULE_ARTIFACTS = buildRuleArtifacts();

    function attachProxyProviders(group, providerNames, filter, excludeFilter) {
    if (providerNames && providerNames.length) {
    group.use = providerNames.slice();
    if (filter) group.filter = filter;
    if (excludeFilter) group["exclude-filter"] = excludeFilter;
    }
    return group;
    }

    function makeNodeGroup(baseConfig, name, icon, members, providerNames, filter, excludeFilter) {
    const group = Object.assign({}, baseConfig, { name: name });
    if (icon) group.icon = icon;
    if (members && members.length) group.proxies = members.slice();
    attachProxyProviders(group, providerNames, filter, excludeFilter);
    return group;
    }

    function makeRegionContainerGroup(name, icon, members, providerNames, filter, excludeFilter, autoGroupName, balanceGroupName) {
    const proxies = [autoGroupName, balanceGroupName];
    for (let i = 0; i < members.length; i++) proxies.push(members[i]);

    const group = Object.assign({}, SELECT_BASE, { name: name, icon: icon, proxies: proxies });
    attachProxyProviders(group, providerNames, filter, excludeFilter);
    return group;
    }

    function buildGroups(proxyData, providerNames) {
    const proxyNames = proxyData.proxyNames;
    const regionBuckets = proxyData.regionBuckets;
    const otherBucket = proxyData.otherBucket;
    const hasProxyProviders = providerNames.length > 0;

    const regionSelectNames = [];
    const allGroups = [];

    for (let i = 0; i < REGIONS.length; i++) {
    const region = REGIONS[i];
    const members = regionBuckets[i];
    if (!members.length && !hasProxyProviders) continue;

    const regionFilter = hasProxyProviders ? "(?i)" + region.pattern.source : null;
    const autoGroupName = region.name + "-" + NAME_AUTO;
    const balanceGroupName = region.name + "-" + NAME_BALANCE;

    const autoGroup = makeNodeGroup(URLTEST_BASE, autoGroupName, ICON.auto, members, providerNames, regionFilter, null);
    const balanceGroup = makeNodeGroup(BALANCE_BASE, balanceGroupName, ICON.balance, members, providerNames, regionFilter, null);
    autoGroup.hidden = true;
    balanceGroup.hidden = true;

    allGroups.push(autoGroup, balanceGroup);
    allGroups.push(makeRegionContainerGroup(
    region.name, region.icon, members, providerNames, regionFilter, null, autoGroupName, balanceGroupName
    ));
    regionSelectNames.push(region.name);
    }

    const hasOtherNodes = otherBucket.length > 0 || hasProxyProviders;
    if (hasOtherNodes) {
    const otherExcludeFilter = hasProxyProviders ? OTHER_NODE_EXCLUDE_FILTER : null;
    const otherAutoName = GROUP_NAME.other + "-" + NAME_AUTO;
    const otherBalanceName = GROUP_NAME.other + "-" + NAME_BALANCE;

    const otherAutoGroup = makeNodeGroup(URLTEST_BASE, otherAutoName, ICON.auto, otherBucket, providerNames, null, otherExcludeFilter);
    const otherBalanceGroup = makeNodeGroup(BALANCE_BASE, otherBalanceName, ICON.balance, otherBucket, providerNames, null, otherExcludeFilter);
    otherAutoGroup.hidden = true;
    otherBalanceGroup.hidden = true;

    allGroups.push(otherAutoGroup, otherBalanceGroup);
    allGroups.push(makeRegionContainerGroup(
    GROUP_NAME.other, ICON.other, otherBucket, providerNames, null, otherExcludeFilter, otherAutoName, otherBalanceName
    ));
    }

    const globalAutoGroup = makeNodeGroup(URLTEST_BASE, NAME_AUTO, ICON.auto, proxyNames, providerNames, null, null);
    const globalBalanceGroup = makeNodeGroup(BALANCE_BASE, NAME_BALANCE, ICON.balance, proxyNames, providerNames, null, null);
    globalAutoGroup.hidden = true;
    globalBalanceGroup.hidden = true;

    const allNodesGroup = makeNodeGroup(SELECT_BASE, GROUP_NAME.all, ICON.all, proxyNames, providerNames, null, null);

    const mainGroupProxies = [NAME_AUTO, NAME_BALANCE, GROUP_NAME.all].concat(regionSelectNames);
    if (hasOtherNodes) mainGroupProxies.push(GROUP_NAME.other);
    const mainGroup = Object.assign({}, SELECT_BASE, {
    name: POLICY_MAIN, icon: ICON.select, proxies: mainGroupProxies,
    });

    // const serviceProxyOptions = [POLICY_MAIN].concat(regionSelectNames);
    // 服务组只能继承主入口
    // 效果:
    // AI → 节点选择
    // Google → 节点选择
    // YouTube → 节点选择
    // GitHub → 节点选择
    // Microsoft → 节点选择
    // ……
    // 现有 Google → 台湾节点、AI → 日本节点 等历史选择将失效,不能再绕过主入口。
    const serviceProxyOptions = [POLICY_MAIN];

    const serviceGroups = [];
    for (let s = 0; s < SERVICES.length; s++) {
    const service = SERVICES[s];
    serviceGroups.push(Object.assign({}, SELECT_BASE, {
    name: service.name, icon: service.icon, proxies: serviceProxyOptions.slice(),
    }));
    }

    const orderedGroups = [mainGroup, allNodesGroup]
    .concat(serviceGroups)
    .concat([globalAutoGroup, globalBalanceGroup])
    .concat(allGroups);

    // const allGroupNames = [];
    // for (let g = 0; g < orderedGroups.length; g++) allGroupNames.push(orderedGroups[g].name);
    // const globalGroup = Object.assign({}, SELECT_BASE, {
    // name: GROUP_NAME.global, icon: ICON.global, proxies: allGroupNames,
    // });

    // GLOBAL 也只允许进入主入口
    const globalGroup = Object.assign({}, SELECT_BASE, {
    name: GROUP_NAME.global,
    icon: ICON.global,
    proxies: [POLICY_MAIN],
    });

    return [globalGroup].concat(orderedGroups);
    }

    function buildDNS(nameserverPolicy, fakeIpFilter) {
    return {
    enable: true,
    listen: "0.0.0.0:7874",
    ipv6: false,
    "prefer-h3": false,
    "tls-version": { min: "1.2", max: "1.3" },
    "enhanced-mode": "fake-ip",
    "fake-ip-range": "198.18.0.1/16",
    "fake-ip-ttl": 1,
    "fake-ip-filter-mode": "blacklist",
    "fake-ip-filter": fakeIpFilter,
    "respect-rules": true,
    "use-hosts": true,
    "use-system-hosts": true,
    "cache-algorithm": "arc",
    "cache-size": 2048,
    "default-nameserver": DNS_DEFAULT,
    "proxy-server-nameserver": DNS_CN,
    "direct-nameserver": DNS_DEFAULT,
    "direct-nameserver-follow-policy": true,
    nameserver: DNS_GLOBAL,
    "nameserver-policy": nameserverPolicy,
    };
    }

    function remoteMain(config) {
    const inputConfig = isPlainObject(config) ? config : {};

    const rawProxies = Array.isArray(inputConfig.proxies) ? inputConfig.proxies : [];
    const proxyProviders = inputConfig["proxy-providers"];
    const providerNames = isPlainObject(proxyProviders) ? Object.keys(proxyProviders) : [];

    delete inputConfig["global-client-fingerprint"];

    const proxyData = processProxies(rawProxies);

    Object.assign(inputConfig, BASE_CONFIG, {
    proxies: proxyData.proxies,
    "proxy-groups": buildGroups(proxyData, providerNames),
    rules: RULE_ARTIFACTS.rules,
    "rule-providers": RULE_ARTIFACTS.ruleProviders,
    dns: buildDNS(RULE_ARTIFACTS.nameserverPolicy, RULE_ARTIFACTS.fakeIpFilter),
    });

    return inputConfig;
    }
    // =========================

    function main(config) {

    // 先执行远程脚本
    if (typeof remoteMain === "function") {
    config = remoteMain(config);
    }

    // 手工域名规则统一进入 节点选择
    // const proxyGroup = getProxyGroup(config);
    const proxyGroup = POLICY_MAIN;
    const prependRule = [
    // 本地域名直连
    "DOMAIN-SUFFIX,hybgzs.com,DIRECT",
    "DOMAIN-SUFFIX,muyuan.do,DIRECT",
    "DOMAIN-SUFFIX,sschospital.cn,DIRECT",
    "DOMAIN-SUFFIX,pp.ua,DIRECT",
    "DOMAIN-SUFFIX,sharedchat.cc,DIRECT",
    "DOMAIN-SUFFIX,x666.me,DIRECT",
    "DOMAIN-SUFFIX,codekey.cc,DIRECT",
    "DOMAIN-SUFFIX,torchai.ai,DIRECT",
    "DOMAIN-SUFFIX,h-e.top,DIRECT",
    "DOMAIN-SUFFIX,lyclaude.site,DIRECT",
    "DOMAIN-SUFFIX,2020111.xyz,DIRECT",
    "DOMAIN-SUFFIX,super-nb.me,DIRECT",
    "DOMAIN-SUFFIX,fengwind.com,DIRECT",
    "DOMAIN-SUFFIX,46w.net,DIRECT",
    "DOMAIN-SUFFIX,jianzhile.vip,DIRECT",

    // 特定域名直连
    "DOMAIN,a-ocnfniawgw.cn-shanghai.fcapp.run,DIRECT",

    // 内网 IP 段直连
    "IP-CIDR,10.0.0.0/8,DIRECT,no-resolve",
    "IP-CIDR,172.16.0.0/12,DIRECT,no-resolve",
    "IP-CIDR,192.168.0.0/16,DIRECT,no-resolve",
    "IP-CIDR,100.64.0.0/10,DIRECT,no-resolve",
    "IP-CIDR,10.1.255.239/32,DIRECT,no-resolve",
    // Gemini / Google 自动走当前订阅代理分组
    DOMAIN-SUFFIX,gemini.google.com,${proxyGroup},
    DOMAIN-SUFFIX,bard.google.com,${proxyGroup},
    DOMAIN-SUFFIX,google.com,${proxyGroup},
    DOMAIN-SUFFIX,googleapis.com,${proxyGroup},
    DOMAIN-SUFFIX,gstatic.com,${proxyGroup},
    DOMAIN-SUFFIX,googleusercontent.com,${proxyGroup},
    DOMAIN-SUFFIX,ggpht.com,${proxyGroup},
    DOMAIN-SUFFIX,gvt1.com,${proxyGroup},
    DOMAIN-SUFFIX,googlevideo.com,${proxyGroup},
    DOMAIN-SUFFIX,youtube.com,${proxyGroup},
    DOMAIN-SUFFIX,ytimg.com,${proxyGroup},
    // =========================
    // ChatGPT / OpenAI 自动走当前订阅代理分组
    // =========================
    DOMAIN-SUFFIX,openai.com,${proxyGroup},
    DOMAIN-SUFFIX,chatgpt.com,${proxyGroup},
    DOMAIN-SUFFIX,oaistatic.com,${proxyGroup},
    DOMAIN-SUFFIX,oaiusercontent.com,${proxyGroup},
    DOMAIN-SUFFIX,ai.com,${proxyGroup},
    DOMAIN-SUFFIX,auth0.com,${proxyGroup},
    DOMAIN-SUFFIX,arkoselabs.com,${proxyGroup},
    DOMAIN-SUFFIX,intercom.io,${proxyGroup},
    DOMAIN-SUFFIX,intercomcdn.com,${proxyGroup},
    DOMAIN-SUFFIX,sentry.io,${proxyGroup},
    DOMAIN-SUFFIX,stripe.com,${proxyGroup},

    // =========================
    // Claude / Anthropic 自动走当前订阅代理分组
    // =========================
    DOMAIN-SUFFIX,claude.ai,${proxyGroup},
    DOMAIN-SUFFIX,anthropic.com,${proxyGroup},
    DOMAIN-SUFFIX,usefathom.com,${proxyGroup},

    // =========================
    // api 自动走当前订阅代理分组
    // =========================
    DOMAIN,api.krill-ai.net,${proxyGroup},
    DOMAIN-SUFFIX,anyrouter.top,${proxyGroup},
    DOMAIN-SUFFIX,linux.do,${proxyGroup},
    ];
    const oldRules = config["rules"] || [];
    config["rules"] = prependRule.concat(oldRules);
    return config;
    }

    主楼
  • 欧阳淇淇

    感谢分享,1000LDC奉上

    https://linux.do/t/topic/1997190

    #1
  • moon

    用个浏览器插件的vpn 就没问题 这个是最简单的了

    #2
  • whlhl2011

    谢谢分享,非常有用,这个问题也一直困扰我

    #3
  • 大肥皂泡

    刚刚注册的,礼貌询问现在有什么模型可用吗?

    #4
  • Theo

    图片

    图片

    我也来提供一个小白的方式:直接编辑规则,不编辑文件

    #5
  • Homeland

    吃低保的到现在也没攒够LDC,眼睁睁看着注册机会用不了干着急 ^-^

    #6
  • 田馥甄

    是不是多了一个符号

    图片

    #7
  • Fly

    语法依然错误,反复修改依然用不了

    #8
  • 浅语

    不用这么麻烦吧,linuxdo也可以直连吧,走doh就行 【更新】OAIFree 这个域名换了个方式跟大家见面 - 教程 - IDC Flare

    #9
  • 长安

    你这个太复杂了,谷歌浏览器设置安全填写https://xyz.ddd.oaifree.com/query-dns

    图片

    #10
  • GlowQuest

    图片

    #11
  • zhp1818

    网站能够正常进入 但是公益站一直提示被访问拦截 怎么能够访问这个福利站 获取点额度呀

    图片

    #12
  • Niuma

    https://xyz.ddd.oaifree.com/query-dns

    设置了没用啊难搞~!~分流的方法也是了,也失效

    #13
  • ok_good_yes

    图片

    奇怪,我昨天和早上还能进,突然就这样的,昨天还很流畅,今天早上进去很卡,然后就这样了

    #14

发表回复

登录后回复