Moved 'AUTO' and 'FALLBACK' entries to appear after static proxy names and other load balancing options in proxy group definitions for improved logical grouping and consistency.
727 lines
20 KiB
JavaScript
727 lines
20 KiB
JavaScript
// from https://github.com/xixu-me/META
|
|
|
|
// ################################################### this section can be flexibly customized ###################################################
|
|
|
|
// Number of STATIC proxy groups (for IP-sensitive services)
|
|
const STATIC_PROXY_COUNT = 3;
|
|
|
|
// Routing rules are matched in order from top to bottom, with the rule at the top of the list taking precedence over the rules below it.
|
|
const services = [
|
|
// Media & Content
|
|
{ name: "bilibili", tld: "com" },
|
|
{ name: "Medium", tld: "com" },
|
|
{ name: "Netflix", tld: "com" },
|
|
{ name: "Sora", domain: "sora.chatgpt.com" },
|
|
{ name: "Spotify", tld: "com" },
|
|
{ name: "YouTube", tld: "com" },
|
|
|
|
// AI/LLM Services
|
|
{ name: "Anthropic", tld: "com" },
|
|
{ name: "Gemini", tld: "google", alias: "Google-Gemini" },
|
|
{ name: "NotebookLM", tld: "google", alias: "Google-NotebookLM" },
|
|
{ name: "OpenAI", tld: "com" },
|
|
{ name: "Perplexity", tld: "ai" },
|
|
{ name: "xAI", tld: "ai", sld: "x" },
|
|
|
|
// Social Media & Communication
|
|
{ name: "Mastodon", tld: "social" },
|
|
{ name: "rednote", domain: "xiaohongshu.com", alias: "Xiaohongshu" },
|
|
{ name: "Telegram", tld: "org" },
|
|
{ name: "X", tld: "com" },
|
|
|
|
// Financial Services
|
|
{ name: "Binance", tld: "com" },
|
|
{ name: "Bybit", tld: "com" },
|
|
{ name: "OKX", tld: "com" },
|
|
{ name: "Pi", tld: "com", sld: "minepi" },
|
|
|
|
// Technology Companies
|
|
{ name: "Apple", tld: "com" },
|
|
{ name: "Google", tld: "google", sld: "about" },
|
|
{ name: "Microsoft", tld: "com" },
|
|
|
|
// Infrastructure
|
|
{ name: "Speedtest", tld: "net" },
|
|
{ name: "Xget", domain: "xuc.xi-xu.me" },
|
|
{ name: "Cloudflare", tld: "com" },
|
|
];
|
|
|
|
const LOCATION_ICON_SET_URL = "https://img.icons8.com/color/144/";
|
|
|
|
const locations = [
|
|
{
|
|
name: "Argentina 🇦🇷",
|
|
icon: `${LOCATION_ICON_SET_URL}argentina`,
|
|
filter: "(?i)\u963f\u6839\u5ef7|Argentina|ARG|AR|argentina|arg|ar|🇦🇷",
|
|
},
|
|
{
|
|
name: "Canada 🇨🇦",
|
|
icon: `${LOCATION_ICON_SET_URL}canada`,
|
|
filter: "(?i)\u52a0\u62ff\u5927|Canada|CAN|CA|canada|ca|🇨🇦",
|
|
},
|
|
{
|
|
name: "Finland 🇫🇮",
|
|
icon: `${LOCATION_ICON_SET_URL}finland`,
|
|
filter: "(?i)\u82ac\u5170|Finland|FIN|FI|finland|fin|fi|🇫🇮",
|
|
},
|
|
{
|
|
name: "France 🇫🇷",
|
|
icon: `${LOCATION_ICON_SET_URL}france`,
|
|
filter: "(?i)\u6cd5\u56fd|France|FR|france|fr|🇫🇷",
|
|
},
|
|
{
|
|
name: "Germany 🇩🇪",
|
|
icon: `${LOCATION_ICON_SET_URL}germany`,
|
|
filter: "(?i)\u5fb7\u56fd|Germany|GER|DE|germany|ger|de|🇩🇪",
|
|
},
|
|
{
|
|
name: "Hong Kong, China 🇭🇰",
|
|
icon: `${LOCATION_ICON_SET_URL}hongkong-circular`,
|
|
filter: "(?i)\u9999\u6e2f|Hong Kong|HK|hong kong|hk|🇭🇰",
|
|
},
|
|
{
|
|
name: "Iraq 🇮🇶",
|
|
icon: `${LOCATION_ICON_SET_URL}iraq`,
|
|
filter: "(?i)\u4f0a\u62c9\u514b|Iraq|IQ|iraq|iq|🇮🇶",
|
|
},
|
|
{
|
|
name: "Japan 🇯🇵",
|
|
icon: `${LOCATION_ICON_SET_URL}japan`,
|
|
filter: "(?i)\u65e5\u672c|Japan|JP|japan|jp|🇯🇵",
|
|
},
|
|
{
|
|
name: "Korea 🇰🇷",
|
|
icon: `${LOCATION_ICON_SET_URL}south-korea`,
|
|
filter: "(?i)\u97e9\u56fd|Korea|KR|korea|kr|🇰🇷",
|
|
},
|
|
{
|
|
name: "Russia 🇷🇺",
|
|
icon: `${LOCATION_ICON_SET_URL}russian-federation`,
|
|
filter:
|
|
"(?i)\u4fc4\u7f57\u65af|Russia Federation|Russia|RU|russia federation|russia|ru|🇷🇺",
|
|
},
|
|
{
|
|
name: "Singapore 🇸🇬",
|
|
icon: `${LOCATION_ICON_SET_URL}singapore`,
|
|
filter: "(?i)\u65b0\u52a0\u5761|Singapore|SG|singapore|sg|🇸🇬",
|
|
},
|
|
{
|
|
name: "Taiwan, China 🇨🇳",
|
|
icon: `${LOCATION_ICON_SET_URL}china-circular`,
|
|
filter: "(?i)\u53f0\u6e7e|Taiwan|TW|taiwan|tw|\uD83C\uDDF9\uD83C\uDDFC",
|
|
},
|
|
{
|
|
name: "Thailand 🇹🇭",
|
|
icon: `${LOCATION_ICON_SET_URL}thailand`,
|
|
filter: "(?i)\u6cf0\u56fd|Thailand|TH|thailand|th|🇹🇭",
|
|
},
|
|
{
|
|
name: "Türkiye 🇹🇷",
|
|
icon: `${LOCATION_ICON_SET_URL}turkey`,
|
|
filter:
|
|
"(?i)\u571f\u8033\u5176|Türkiye|Turkey|TUR|TR|türkiye|turkey|tur|tr|🇹🇷",
|
|
},
|
|
{
|
|
name: "Ukraine 🇺🇦",
|
|
icon: `${LOCATION_ICON_SET_URL}ukraine`,
|
|
filter: "(?i)\u4e4c\u514b\u5170|Ukraine|UKR|UA|ukraine|ukr|ua|🇺🇦",
|
|
},
|
|
{
|
|
name: "United Kingdom 🇬🇧",
|
|
icon: `${LOCATION_ICON_SET_URL}great-britain`,
|
|
filter:
|
|
"(?i)\u82f1\u56fd|United Kingdom|Great Britain|UK|GB|united kingdom|great britain|uk|gb|🇬🇧",
|
|
},
|
|
{
|
|
name: "United States 🇺🇸",
|
|
icon: `${LOCATION_ICON_SET_URL}usa`,
|
|
filter:
|
|
"(?i)\u7f8e\u56fd|United States of America|United States|USA|US|united states of america|united states|usa|us|🇺🇸",
|
|
},
|
|
{
|
|
name: "Global 🌐",
|
|
icon: "https://img.icons8.com/?size=144&id=3685&format=png&color=7bbbe9",
|
|
filter: "(?i)Global|GL|global|gl|Cloudflare|CF|cloudflare|cf|🌐",
|
|
},
|
|
];
|
|
|
|
// ####################################### DO NOT MODIFY THE CODE BELOW UNLESS YOU KNOW WHAT YOU ARE DOING #######################################
|
|
|
|
function extractFavicon(domain) {
|
|
return `https://t1.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=https://${domain}&size=128`;
|
|
}
|
|
|
|
// General Configuration
|
|
|
|
const generalConfig = {
|
|
"allow-lan": false,
|
|
mode: "rule",
|
|
"log-level": "info",
|
|
ipv6: true,
|
|
"find-process-mode": "strict",
|
|
"external-controller": "",
|
|
profile: {
|
|
"store-selected": true,
|
|
"store-fake-ip": true,
|
|
},
|
|
"unified-delay": true,
|
|
"tcp-concurrent": true,
|
|
"global-client-fingerprint": "chrome",
|
|
"global-ua": "\u0063\u006c\u0061\u0073\u0068.\u006D\u0065\u0074\u0061",
|
|
"etag-support": true,
|
|
};
|
|
|
|
// DNS
|
|
|
|
const chineseNameservers = [
|
|
"https://doh.pub/dns-query",
|
|
"https://dns.alidns.com/dns-query",
|
|
];
|
|
|
|
const internationalNameservers = [
|
|
"quic://unfiltered.adguard-dns.com:784",
|
|
"https://dns.google/dns-query",
|
|
"https://doh.dns.sb/dns-query",
|
|
"https://dns.quad9.net/dns-query",
|
|
"https://doh.opendns.com/dns-query",
|
|
"https://dns.mullvad.net/dns-query",
|
|
"https://doh.umbrella.com/dns-query",
|
|
"https://wikimedia-dns.org/dns-query",
|
|
"https://doh.dns.apple.com/dns-query",
|
|
"https://cloudflare-dns.com/dns-query",
|
|
"https://common.dot.dns.yandex.net/dns-query",
|
|
"https://unfiltered.adguard-dns.com/dns-query",
|
|
];
|
|
|
|
const adguardDefaultNameservers = [
|
|
"quic://dns.adguard-dns.com:784",
|
|
"https://dns.adguard-dns.com/dns-query",
|
|
];
|
|
|
|
const adguardFamilyNameservers = [
|
|
"quic://family.adguard-dns.com:784",
|
|
"https://family.adguard-dns.com/dns-query",
|
|
];
|
|
|
|
const dns = {
|
|
enable: true,
|
|
"prefer-h3": false,
|
|
"use-hosts": true,
|
|
"use-system-hosts": false,
|
|
"respect-rules": true,
|
|
listen: "0.0.0.0:1053",
|
|
ipv6: true,
|
|
"enhanced-mode": "fake-ip",
|
|
"fake-ip-range": "198.18.0.1/16",
|
|
"fake-ip-filter-mode": "blacklist",
|
|
"fake-ip-filter": [
|
|
"rule-set:fake-ip-filter",
|
|
"rule-set:direct",
|
|
"rule-set:private",
|
|
"rule-set:connectivity-check",
|
|
],
|
|
"default-nameserver": [
|
|
"119.29.29.29",
|
|
"223.5.5.5",
|
|
"223.6.6.6",
|
|
"8.8.8.8",
|
|
"8.8.4.4",
|
|
"1.1.1.1",
|
|
"1.0.0.1",
|
|
"9.9.9.9",
|
|
"149.112.112.112",
|
|
"208.67.222.222",
|
|
"208.67.220.220",
|
|
],
|
|
"proxy-server-nameserver": chineseNameservers,
|
|
"nameserver-policy": {
|
|
"rule-set:private,direct,geolocation-cn": chineseNameservers,
|
|
"rule-set:proxy": internationalNameservers,
|
|
},
|
|
nameserver: [
|
|
...chineseNameservers,
|
|
...internationalNameservers,
|
|
// ...adguardDefaultNameservers,
|
|
// ...adguardFamilyNameservers,
|
|
],
|
|
};
|
|
|
|
// Hosts
|
|
|
|
const hosts = {};
|
|
|
|
// Domain Sniffing
|
|
|
|
const sniffer = {
|
|
enable: false,
|
|
};
|
|
|
|
// TUN
|
|
|
|
const tun = {
|
|
enable: true,
|
|
stack: "mixed",
|
|
"auto-route": true,
|
|
"auto-redirect": true,
|
|
"auto-detect-interface": true,
|
|
"strict-route": true,
|
|
"dns-hijack": ["any:53", "tcp://any:53"],
|
|
};
|
|
|
|
// Proxy Groups
|
|
|
|
const proxyGroupDefaults = {
|
|
url: "https://www.gstatic.com/generate_204",
|
|
interval: 300,
|
|
lazy: true,
|
|
timeout: 5000,
|
|
"max-failed-times": 5,
|
|
};
|
|
|
|
// Generate STATIC proxy group names
|
|
function generateStaticProxyNames() {
|
|
if (STATIC_PROXY_COUNT === 1) {
|
|
return ["STATIC"];
|
|
}
|
|
return Array.from(
|
|
{ length: STATIC_PROXY_COUNT },
|
|
(_, i) => `STATIC-${i + 1}`
|
|
);
|
|
}
|
|
|
|
const staticProxyNames = generateStaticProxyNames();
|
|
|
|
const serviceProxyGroupProxies = [
|
|
"PROXY",
|
|
...staticProxyNames,
|
|
"AUTO",
|
|
"DIRECT",
|
|
"Mainland China 🇨🇳",
|
|
...locations.map(({ name }) => name),
|
|
];
|
|
|
|
const locationPolicyProxyGroupDefaults = {
|
|
...proxyGroupDefaults,
|
|
proxies: ["REJECT"],
|
|
"include-all": true,
|
|
};
|
|
|
|
const SERVICE_ICON_SET_URL =
|
|
"https://cdn.jsdelivr.net/gh/xixu-me/favicons@assets/favicons/";
|
|
|
|
function getServiceIcon(service) {
|
|
if (service.icon) return service.icon;
|
|
if (service.domain) return extractFavicon(service.domain);
|
|
if (service.tld) {
|
|
const secondLevelDomain = service.sld || service.name.toLowerCase();
|
|
return `${SERVICE_ICON_SET_URL}${secondLevelDomain}.${service.tld}.png`;
|
|
}
|
|
console.warn(`No icon configuration for service: ${service.name}`);
|
|
return null;
|
|
}
|
|
|
|
services.forEach((service) => {
|
|
service.icon = getServiceIcon(service);
|
|
});
|
|
|
|
function generateServiceProxyGroups(items, defaultConfig) {
|
|
return items.map(({ name, icon }) => ({
|
|
...defaultConfig,
|
|
name,
|
|
icon,
|
|
type: "select",
|
|
proxies: serviceProxyGroupProxies,
|
|
}));
|
|
}
|
|
|
|
function generateLocationPolicyProxyGroups(
|
|
items,
|
|
defaultConfig,
|
|
type,
|
|
extraProps = {}
|
|
) {
|
|
const getStrategyName = (type, strategy) => {
|
|
switch (type) {
|
|
case "url-test":
|
|
return "AUTO";
|
|
case "fallback":
|
|
return "FALLBACK";
|
|
case "load-balance":
|
|
switch (strategy) {
|
|
case "consistent-hashing":
|
|
return "LOAD BALANCING (consistent hashing)";
|
|
case "round-robin":
|
|
return "LOAD BALANCING (round-robin)";
|
|
case "sticky-sessions":
|
|
return "LOAD BALANCING (sticky sessions)";
|
|
default:
|
|
return "LOAD BALANCING";
|
|
}
|
|
default:
|
|
return type.toUpperCase();
|
|
}
|
|
};
|
|
return items.map(({ name, icon, filter }) => {
|
|
const strategyName = getStrategyName(type, extraProps.strategy);
|
|
const emoji = name.split(" ").pop();
|
|
const newName = `${strategyName} ${emoji}`;
|
|
return {
|
|
...defaultConfig,
|
|
name: newName,
|
|
type,
|
|
icon,
|
|
filter,
|
|
hidden: true,
|
|
...extraProps,
|
|
};
|
|
});
|
|
}
|
|
|
|
function generateLocationSelectProxyGroups() {
|
|
return locations.map(({ name, icon }) => ({
|
|
...proxyGroupDefaults,
|
|
name,
|
|
type: "select",
|
|
icon,
|
|
proxies: [
|
|
`LOAD BALANCING (consistent hashing) ${name.split(" ").pop()}`,
|
|
`LOAD BALANCING (round-robin) ${name.split(" ").pop()}`,
|
|
`LOAD BALANCING (sticky sessions) ${name.split(" ").pop()}`,
|
|
`FALLBACK ${name.split(" ").pop()}`,
|
|
`AUTO ${name.split(" ").pop()}`,
|
|
],
|
|
}));
|
|
}
|
|
|
|
const BASE_ICON_SET_URL =
|
|
"https://cdn.jsdelivr.net/gh/Koolson/Qure@master/IconSet/Color/";
|
|
|
|
// Generate STATIC proxy groups
|
|
function generateStaticProxyGroups(defaultConfig) {
|
|
return staticProxyNames.map((name, index) => ({
|
|
...defaultConfig,
|
|
name,
|
|
type: "select",
|
|
"include-all": true,
|
|
icon: `${BASE_ICON_SET_URL}Static.png`,
|
|
}));
|
|
}
|
|
|
|
const proxyGroups = [
|
|
{
|
|
...proxyGroupDefaults,
|
|
name: "PROXY",
|
|
type: "select",
|
|
proxies: [
|
|
...staticProxyNames,
|
|
"AUTO",
|
|
"Mainland China 🇨🇳",
|
|
...locations.map(({ name }) => name),
|
|
],
|
|
icon: `${BASE_ICON_SET_URL}Proxy.png`,
|
|
},
|
|
{
|
|
...proxyGroupDefaults,
|
|
name: "AUTO",
|
|
type: "url-test",
|
|
tolerance: 50,
|
|
"include-all": true,
|
|
icon: `${BASE_ICON_SET_URL}Auto.png`,
|
|
hidden: true,
|
|
},
|
|
...generateStaticProxyGroups(proxyGroupDefaults),
|
|
...generateServiceProxyGroups(services, proxyGroupDefaults),
|
|
{
|
|
...proxyGroupDefaults,
|
|
name: "Others",
|
|
type: "select",
|
|
proxies: [...serviceProxyGroupProxies],
|
|
icon: `${BASE_ICON_SET_URL}Final.png`,
|
|
},
|
|
{
|
|
...proxyGroupDefaults,
|
|
name: "Advertising",
|
|
type: "select",
|
|
proxies: ["REJECT", "DIRECT", ...staticProxyNames],
|
|
icon: `${BASE_ICON_SET_URL}Advertising.png`,
|
|
},
|
|
{
|
|
...locationPolicyProxyGroupDefaults,
|
|
name: "Mainland China 🇨🇳",
|
|
type: "select",
|
|
icon: `${LOCATION_ICON_SET_URL}china`,
|
|
proxies: ["DIRECT"],
|
|
"include-all": true,
|
|
filter:
|
|
"(?i)\u5927\u9646|\u4e2d\u56fd|\u7535\u4fe1|\u79fb\u52a8|\u8054\u901a|Mainland|China|CN|mainland|china|cn|🇨🇳",
|
|
},
|
|
...generateLocationPolicyProxyGroups(
|
|
locations,
|
|
locationPolicyProxyGroupDefaults,
|
|
"url-test",
|
|
{
|
|
tolerance: 50,
|
|
}
|
|
),
|
|
...generateLocationPolicyProxyGroups(
|
|
locations,
|
|
locationPolicyProxyGroupDefaults,
|
|
"fallback"
|
|
),
|
|
...generateLocationPolicyProxyGroups(
|
|
locations,
|
|
locationPolicyProxyGroupDefaults,
|
|
"load-balance",
|
|
{
|
|
strategy: "round-robin",
|
|
}
|
|
),
|
|
...generateLocationPolicyProxyGroups(
|
|
locations,
|
|
locationPolicyProxyGroupDefaults,
|
|
"load-balance",
|
|
{
|
|
strategy: "consistent-hashing",
|
|
}
|
|
),
|
|
...generateLocationPolicyProxyGroups(
|
|
locations,
|
|
locationPolicyProxyGroupDefaults,
|
|
"load-balance",
|
|
{
|
|
strategy: "sticky-sessions",
|
|
}
|
|
),
|
|
...generateLocationSelectProxyGroups(),
|
|
];
|
|
|
|
// Routing Rules
|
|
|
|
function generateServiceRules(services) {
|
|
return services.map(({ name }) => `RULE-SET,${name.toLowerCase()},${name}`);
|
|
}
|
|
|
|
const rules = [
|
|
"RULE-SET,applications,DIRECT",
|
|
"RULE-SET,win-phonelink,DIRECT",
|
|
"RULE-SET,lancidr,DIRECT,no-resolve",
|
|
"RULE-SET,private,DIRECT",
|
|
...generateServiceRules(services),
|
|
"RULE-SET,reject,Advertising",
|
|
"RULE-SET,win-spy,Advertising",
|
|
"RULE-SET,direct,Mainland China 🇨🇳",
|
|
"RULE-SET,proxy,PROXY",
|
|
"RULE-SET,telegramcidr,Telegram",
|
|
"RULE-SET,xcidr,X",
|
|
"RULE-SET,googlecidr,Google",
|
|
"RULE-SET,cloudflarecidr,Cloudflare",
|
|
"RULE-SET,cncidr,Mainland China 🇨🇳",
|
|
"MATCH,Others",
|
|
];
|
|
|
|
// Rule Providers
|
|
|
|
const ruleProviderDefaults = {
|
|
type: "http",
|
|
interval: 14400,
|
|
};
|
|
|
|
function generateServiceRuleProviders(services, defaultConfig) {
|
|
return services.reduce((acc, { name, alias }) => {
|
|
const ruleName = alias || name;
|
|
acc[name.toLowerCase()] = {
|
|
...defaultConfig,
|
|
format: "mrs",
|
|
behavior: "domain",
|
|
url: `https://cdn.jsdelivr.net/gh/xixu-me/RFM@universal/${ruleName.toLowerCase()}.mrs`,
|
|
path: `./rulesets/${name.toLowerCase()}.mrs`,
|
|
};
|
|
return acc;
|
|
}, {});
|
|
}
|
|
|
|
const ruleProviders = {
|
|
"fake-ip-filter": {
|
|
...ruleProviderDefaults,
|
|
format: "mrs",
|
|
behavior: "domain",
|
|
url: "https://cdn.jsdelivr.net/gh/xixu-me/RFM@basic/fake-ip-filter.mrs",
|
|
path: "./rulesets/fake-ip-filter.mrs",
|
|
},
|
|
"connectivity-check": {
|
|
...ruleProviderDefaults,
|
|
format: "mrs",
|
|
behavior: "domain",
|
|
url: "https://cdn.jsdelivr.net/gh/xixu-me/RFM@universal/connectivity-check.mrs",
|
|
path: "./rulesets/connectivity-check.mrs",
|
|
},
|
|
applications: {
|
|
...ruleProviderDefaults,
|
|
format: "yaml",
|
|
behavior: "classical",
|
|
url: "https://cdn.jsdelivr.net/gh/xixu-me/RFM@basic/applications.yaml",
|
|
path: "./rulesets/applications.yaml",
|
|
},
|
|
"win-phonelink": {
|
|
...ruleProviderDefaults,
|
|
format: "yaml",
|
|
behavior: "classical",
|
|
url: "https://cdn.jsdelivr.net/gh/xixu-me/RFM@fixed/win-phonelink.yaml",
|
|
path: "./rulesets/win-phonelink.yaml",
|
|
},
|
|
lancidr: {
|
|
...ruleProviderDefaults,
|
|
format: "mrs",
|
|
behavior: "ipcidr",
|
|
url: "https://cdn.jsdelivr.net/gh/xixu-me/RFM@basic/lancidr.mrs",
|
|
path: "./rulesets/lancidr.mrs",
|
|
},
|
|
cncidr: {
|
|
...ruleProviderDefaults,
|
|
format: "mrs",
|
|
behavior: "ipcidr",
|
|
url: "https://cdn.jsdelivr.net/gh/xixu-me/RFM@basic/cncidr.mrs",
|
|
path: "./rulesets/cncidr.mrs",
|
|
},
|
|
cloudflarecidr: {
|
|
...ruleProviderDefaults,
|
|
format: "mrs",
|
|
behavior: "ipcidr",
|
|
url: "https://cdn.jsdelivr.net/gh/xixu-me/RFM@basic/cloudflarecidr.mrs",
|
|
path: "./rulesets/cloudflarecidr.mrs",
|
|
},
|
|
googlecidr: {
|
|
...ruleProviderDefaults,
|
|
format: "mrs",
|
|
behavior: "ipcidr",
|
|
url: "https://cdn.jsdelivr.net/gh/xixu-me/RFM@basic/googlecidr.mrs",
|
|
path: "./rulesets/googlecidr.mrs",
|
|
},
|
|
telegramcidr: {
|
|
...ruleProviderDefaults,
|
|
format: "mrs",
|
|
behavior: "ipcidr",
|
|
url: "https://cdn.jsdelivr.net/gh/xixu-me/RFM@basic/telegramcidr.mrs",
|
|
path: "./rulesets/telegramcidr.mrs",
|
|
},
|
|
xcidr: {
|
|
...ruleProviderDefaults,
|
|
format: "mrs",
|
|
behavior: "ipcidr",
|
|
url: "https://cdn.jsdelivr.net/gh/xixu-me/RFM@basic/xcidr.mrs",
|
|
path: "./rulesets/xcidr.mrs",
|
|
},
|
|
private: {
|
|
...ruleProviderDefaults,
|
|
format: "mrs",
|
|
behavior: "domain",
|
|
url: "https://cdn.jsdelivr.net/gh/xixu-me/RFM@basic/private.mrs",
|
|
path: "./rulesets/private.mrs",
|
|
},
|
|
direct: {
|
|
...ruleProviderDefaults,
|
|
format: "mrs",
|
|
behavior: "domain",
|
|
url: "https://cdn.jsdelivr.net/gh/xixu-me/RFM@basic/direct.mrs",
|
|
path: "./rulesets/direct.mrs",
|
|
},
|
|
proxy: {
|
|
...ruleProviderDefaults,
|
|
format: "mrs",
|
|
behavior: "domain",
|
|
url: "https://cdn.jsdelivr.net/gh/xixu-me/RFM@basic/proxy.mrs",
|
|
path: "./rulesets/proxy.mrs",
|
|
},
|
|
"geolocation-cn": {
|
|
...ruleProviderDefaults,
|
|
format: "mrs",
|
|
behavior: "domain",
|
|
url: "https://cdn.jsdelivr.net/gh/xixu-me/RFM@universal/geolocation-cn.mrs",
|
|
path: "./rulesets/geolocation-cn.mrs",
|
|
},
|
|
reject: {
|
|
...ruleProviderDefaults,
|
|
format: "mrs",
|
|
behavior: "domain",
|
|
url: "https://cdn.jsdelivr.net/gh/xixu-me/RFM@basic/reject.mrs",
|
|
path: "./rulesets/reject.mrs",
|
|
},
|
|
"win-spy": {
|
|
...ruleProviderDefaults,
|
|
format: "mrs",
|
|
behavior: "domain",
|
|
url: "https://cdn.jsdelivr.net/gh/xixu-me/RFM@universal/win-spy.mrs",
|
|
path: "./rulesets/win-spy.mrs",
|
|
},
|
|
...generateServiceRuleProviders(services, ruleProviderDefaults),
|
|
};
|
|
|
|
// generate configuration using the above settings
|
|
|
|
function validateOriginalConfig(config) {
|
|
if (!config)
|
|
throw new Error("Configuration object cannot be null or undefined");
|
|
const proxyCount = Array.isArray(config.proxies) ? config.proxies.length : 0;
|
|
const proxyProviderCount = Object.keys(
|
|
config["proxy-providers"] || {}
|
|
).length;
|
|
if (proxyCount === 0 && proxyProviderCount === 0)
|
|
throw new Error(
|
|
"The original configuration must contain a non-empty proxies array (see https://wiki.\u006D\u0065\u0074\u0061\u0063\u0075\u0062\u0065\u0078.one/en/config/proxies/) or a proxy-providers object with at least one property (see https://wiki.\u006D\u0065\u0074\u0061\u0063\u0075\u0062\u0065\u0078.one/en/config/proxy-providers/)"
|
|
);
|
|
if (proxyCount > 0) {
|
|
config.proxies.forEach((proxy, index) => {
|
|
if (!proxy.name || !proxy.type || !proxy.server || !proxy.port) {
|
|
throw new Error(
|
|
`Invalid proxy number ${
|
|
index + 1
|
|
} configuration (see https://wiki.\u006D\u0065\u0074\u0061\u0063\u0075\u0062\u0065\u0078.one/en/config/proxies/)`
|
|
);
|
|
}
|
|
});
|
|
console.log(
|
|
`The original configuration contains ${proxyCount} proxies, which will be preserved`
|
|
);
|
|
}
|
|
if (proxyProviderCount > 0) {
|
|
Object.entries(config["proxy-providers"]).forEach(
|
|
([name, provider], index) => {
|
|
if (!provider.type || (provider.type === "http" && !provider.url)) {
|
|
throw new Error(
|
|
`Invalid proxy provider number ${
|
|
index + 1
|
|
} configuration (see https://wiki.\u006D\u0065\u0074\u0061\u0063\u0075\u0062\u0065\u0078.one/en/config/proxy-providers/)`
|
|
);
|
|
}
|
|
}
|
|
);
|
|
console.log(
|
|
`The original configuration contains ${proxyProviderCount} proxy providers, which will be preserved`
|
|
);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function main(config) {
|
|
try {
|
|
validateOriginalConfig(config);
|
|
Object.assign(config, generalConfig, {
|
|
dns,
|
|
hosts,
|
|
sniffer,
|
|
tun,
|
|
"proxy-groups": proxyGroups,
|
|
rules,
|
|
"rule-providers": ruleProviders,
|
|
});
|
|
console.log("The generated configuration is as follows");
|
|
console.log(config);
|
|
return config;
|
|
} catch (error) {
|
|
console.error(
|
|
`An error occurred during configuration generation: ${error.message}`
|
|
);
|
|
return { error: error.message, originalConfig: config };
|
|
}
|
|
}
|