diff --git a/.gitignore b/.gitignore index bb95dc7f..eea85fc7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,18 +4,7 @@ node_modules .wireit public -List/domainset/reject.conf -List/domainset/cdn.conf -List/domainset/reject_phishing.conf -List/domainset/reject_sukka.conf -List/domainset/apple_cdn.conf -List/domainset/speedtest.conf -List/non_ip/cdn.conf -List/non_ip/domestic.conf -List/non_ip/apple_cdn.conf -List/ip/telegram.conf -List/ip/reject.conf -List/ip/china_ip.conf -List/internal/ +List +Clash Modules/sukka_local_dns_mapping.sgmodule diff --git a/Build/build-anti-bogus-domain.js b/Build/build-anti-bogus-domain.js index 533d043d..c108d096 100644 --- a/Build/build-anti-bogus-domain.js +++ b/Build/build-anti-bogus-domain.js @@ -4,7 +4,7 @@ const { isIPv4, isIPv6 } = require('net'); const { compareAndWriteFile } = require('./lib/string-array-compare'); const { withBannerArray } = require('./lib/with-banner'); const { fetchRemoteTextAndCreateReadlineInterface, readFileByLine } = require('./lib/fetch-remote-text-by-line'); -const { minifyRules } = require('./lib/minify-rules'); +const { surgeRulesetToClashClassicalTextRuleset } = require('./lib/clash'); (async () => { console.time('Total Time - build-anti-bogus-domain'); @@ -21,7 +21,6 @@ const { minifyRules } = require('./lib/minify-rules'); console.timeEnd('* Download bogus-nxdomain-list'); const filePath = path.resolve(__dirname, '../Source/ip/reject.conf'); - const resultPath = path.resolve(__dirname, '../List/ip/reject.conf'); /** @type {string[]} */ const result = []; @@ -39,24 +38,37 @@ const { minifyRules } = require('./lib/minify-rules'); } } - await compareAndWriteFile( - withBannerArray( - 'Sukka\'s Surge Rules - Anti Bogus Domain', - [ - 'License: AGPL 3.0', - 'Homepage: https://ruleset.skk.moe', - 'GitHub: https://github.com/SukkaW/Surge', - '', - 'This file contains known addresses that are hijacking NXDOMAIN results returned by DNS servers.', - '', - 'Data from:', - ' - https://github.com/felixonmars/dnsmasq-china-list' - ], - new Date(), - minifyRules(result) + const description = [ + 'License: AGPL 3.0', + 'Homepage: https://ruleset.skk.moe', + 'GitHub: https://github.com/SukkaW/Surge', + '', + 'This file contains known addresses that are hijacking NXDOMAIN results returned by DNS servers.', + '', + 'Data from:', + ' - https://github.com/felixonmars/dnsmasq-china-list' + ]; + + await Promise.all([ + compareAndWriteFile( + withBannerArray( + 'Sukka\'s Ruleset - Anti Bogus Domain', + description, + new Date(), + result + ), + path.resolve(__dirname, '../List/ip/reject.conf') ), - resultPath - ); + compareAndWriteFile( + withBannerArray( + 'Sukka\'s Ruleset - Anti Bogus Domain', + description, + new Date(), + surgeRulesetToClashClassicalTextRuleset(result) + ), + path.resolve(__dirname, '../Clash/ip/reject.txt') + ) + ]); console.timeEnd('Total Time - build-anti-bogus-domain'); })(); diff --git a/Build/build-apple-cdn.js b/Build/build-apple-cdn.js index 550ee3da..19986b84 100644 --- a/Build/build-apple-cdn.js +++ b/Build/build-apple-cdn.js @@ -4,48 +4,63 @@ const { compareAndWriteFile } = require('./lib/string-array-compare'); const { withBannerArray } = require('./lib/with-banner'); const { parseFelixDnsmasq } = require('./lib/parse-dnsmasq'); +const { surgeRulesetToClashClassicalTextRuleset, surgeDomainsetToClashDomainset } = require('./lib/clash'); (async () => { console.time('Total Time - build-apple-cdn-conf'); const res = await parseFelixDnsmasq('https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/apple.china.conf'); + const description = [ + 'License: AGPL 3.0', + 'Homepage: https://ruleset.skk.moe', + 'GitHub: https://github.com/SukkaW/Surge', + '', + 'This file contains Apple\'s domains using their China mainland CDN servers.', + '', + 'Data from:', + ' - https://github.com/felixonmars/dnsmasq-china-list' + ]; + + const ruleset = res.map(domain => `DOMAIN-SUFFIX,${domain}`); + const domainset = res.map(i => `.${i}`); + await Promise.all([ compareAndWriteFile( withBannerArray( - 'Sukka\'s Surge Rules - Apple CDN', - [ - 'License: AGPL 3.0', - 'Homepage: https://ruleset.skk.moe', - 'GitHub: https://github.com/SukkaW/Surge', - '', - 'This file contains Apple\'s domains using their China mainland CDN servers.', - '', - 'Data from:', - ' - https://github.com/felixonmars/dnsmasq-china-list' - ], + 'Sukka\'s Ruleset - Apple CDN', + description, new Date(), - res.map(domain => `DOMAIN-SUFFIX,${domain}`) + ruleset ), path.resolve(__dirname, '../List/non_ip/apple_cdn.conf') ), compareAndWriteFile( withBannerArray( - 'Sukka\'s Surge Rules - Apple CDN', - [ - 'License: AGPL 3.0', - 'Homepage: https://ruleset.skk.moe', - 'GitHub: https://github.com/SukkaW/Surge', - '', - 'This file contains Apple\'s domains using their China mainland CDN servers.', - '', - 'Data from:', - ' - https://github.com/felixonmars/dnsmasq-china-list' - ], + 'Sukka\'s Ruleset - Apple CDN', + description, new Date(), - res.map(i => `.${i}`) + surgeRulesetToClashClassicalTextRuleset(ruleset) + ), + path.resolve(__dirname, '../Clash/non_ip/apple_cdn.txt') + ), + compareAndWriteFile( + withBannerArray( + 'Sukka\'s Ruleset - Apple CDN', + description, + new Date(), + domainset ), path.resolve(__dirname, '../List/domainset/apple_cdn.conf') + ), + compareAndWriteFile( + withBannerArray( + 'Sukka\'s Ruleset - Apple CDN', + description, + new Date(), + surgeDomainsetToClashDomainset(domainset) + ), + path.resolve(__dirname, '../Clash/domainset/apple_cdn.txt') ) ]); diff --git a/Build/build-cdn-conf.js b/Build/build-cdn-conf.js index ad9f201e..54cbc1fe 100644 --- a/Build/build-cdn-conf.js +++ b/Build/build-cdn-conf.js @@ -3,10 +3,9 @@ const path = require('path'); const { compareAndWriteFile } = require('./lib/string-array-compare'); const { withBannerArray } = require('./lib/with-banner'); const { minifyRules } = require('./lib/minify-rules'); -const { domainDeduper } = require('./lib/domain-deduper'); -const { processLine } = require('./lib/process-line'); const { fetchRemoteTextAndCreateReadlineInterface, readFileByLine } = require('./lib/fetch-remote-text-by-line'); const Trie = require('./lib/trie'); +const { surgeRulesetToClashClassicalTextRuleset } = require('./lib/clash'); (async () => { console.time('Total Time - build-cdn-conf'); @@ -40,51 +39,33 @@ const Trie = require('./lib/trie'); } } - /** - * Dedupe cdn.conf - */ - /** @type {Set} */ - const cdnDomains = new Set(); - - for await (const line of readFileByLine( - path.resolve(__dirname, '../Source/domainset/cdn.conf') - )) { - const l = processLine(line); - if (l) { - cdnDomains.add(l); - } - } + const description = [ + 'License: AGPL 3.0', + 'Homepage: https://ruleset.skk.moe', + 'GitHub: https://github.com/SukkaW/Surge', + '', + 'This file contains object storage and static assets CDN domains.' + ]; + const ruleset = minifyRules(cdnDomainsList); await Promise.all([ compareAndWriteFile( withBannerArray( - 'Sukka\'s Surge Rules - CDN Domains', - [ - 'License: AGPL 3.0', - 'Homepage: https://ruleset.skk.moe', - 'GitHub: https://github.com/SukkaW/Surge', - '', - 'This file contains object storage and static assets CDN domains.' - ], + 'Sukka\'s Ruleset - CDN Domains', + description, new Date(), - minifyRules(cdnDomainsList) + ruleset ), path.resolve(__dirname, '../List/non_ip/cdn.conf') ), compareAndWriteFile( withBannerArray( - 'Sukka\'s Surge Rules - CDN Domains', - [ - 'License: AGPL 3.0', - 'Homepage: https://ruleset.skk.moe', - 'GitHub: https://github.com/SukkaW/Surge', - '', - 'This file contains object storage and static assets CDN domains.' - ], + 'Sukka\'s Ruleset - CDN Domains', + description, new Date(), - minifyRules(domainDeduper(Array.from(cdnDomains))) + surgeRulesetToClashClassicalTextRuleset(ruleset) ), - path.resolve(__dirname, '../List/domainset/cdn.conf') + path.resolve(__dirname, '../Clash/non_ip/cdn.txt') ) ]); diff --git a/Build/build-chn-cidr.js b/Build/build-chn-cidr.js index bc9b8bba..aa359a91 100644 --- a/Build/build-chn-cidr.js +++ b/Build/build-chn-cidr.js @@ -28,21 +28,38 @@ const EXCLUDE_CIDRS = [ const filteredCidr = excludeCidrs(Array.from(cidr), EXCLUDE_CIDRS, true); console.log('After Merge:', filteredCidr.length); - await compareAndWriteFile( - withBannerArray( - 'Sukka\'s Surge Rules - Mainland China IPv4 CIDR', - [ - 'License: CC BY-SA 2.0', - 'Homepage: https://ruleset.skk.moe', - 'GitHub: https://github.com/SukkaW/Surge', - '', - 'Data from https://misaka.io (misakaio @ GitHub)' - ], - new Date(), - filteredCidr.map(i => `IP-CIDR,${i}`) + await Promise.all([ + compareAndWriteFile( + withBannerArray( + 'Sukka\'s Ruleset - Mainland China IPv4 CIDR', + [ + 'License: CC BY-SA 2.0', + 'Homepage: https://ruleset.skk.moe', + 'GitHub: https://github.com/SukkaW/Surge', + '', + 'Data from https://misaka.io (misakaio @ GitHub)' + ], + new Date(), + filteredCidr.map(i => `IP-CIDR,${i}`) + ), + pathResolve(__dirname, '../List/ip/china_ip.conf') ), - pathResolve(__dirname, '../List/ip/china_ip.conf') - ); + compareAndWriteFile( + withBannerArray( + 'Sukka\'s Ruleset - Mainland China IPv4 CIDR', + [ + 'License: CC BY-SA 2.0', + 'Homepage: https://ruleset.skk.moe', + 'GitHub: https://github.com/SukkaW/Surge', + '', + 'Data from https://misaka.io (misakaio @ GitHub)' + ], + new Date(), + filteredCidr + ), + pathResolve(__dirname, '../Clash/ip/china_ip.txt') + ) + ]); console.timeEnd('Total Time - build-chnroutes-cidr'); })(); diff --git a/Build/build-domestic-ruleset.js b/Build/build-domestic-ruleset.js index f47beafe..769fba34 100644 --- a/Build/build-domestic-ruleset.js +++ b/Build/build-domestic-ruleset.js @@ -6,6 +6,7 @@ const { processLine } = require('./lib/process-line'); const { withBannerArray } = require('./lib/with-banner'); const { compareAndWriteFile } = require('./lib/string-array-compare'); const domainSorter = require('./lib/stable-sort-domain'); +const { surgeRulesetToClashClassicalTextRuleset } = require('./lib/clash'); (async () => { const rl = readFileByLine(path.resolve(__dirname, '../Source/non_ip/domestic.conf')); @@ -25,22 +26,33 @@ const domainSorter = require('./lib/stable-sort-domain'); .map((domain) => `DOMAIN-SUFFIX,${domain}`) ); + const rulesetDescription = [ + 'License: AGPL 3.0', + 'Homepage: https://ruleset.skk.moe', + 'GitHub: https://github.com/SukkaW/Surge', + '', + 'This file contains known addresses that are avaliable in the Mainland China.' + ]; + await Promise.all([ compareAndWriteFile( withBannerArray( - 'Sukka\'s Surge Rules - Domestic Domain', - [ - 'License: AGPL 3.0', - 'Homepage: https://ruleset.skk.moe', - 'GitHub: https://github.com/SukkaW/Surge', - '', - 'This file contains known addresses that are avaliable in the Mainland China.' - ], + 'Sukka\'s Ruleset - Domestic Domains', + rulesetDescription, new Date(), results ), path.resolve(__dirname, '../List/non_ip/domestic.conf') ), + compareAndWriteFile( + withBannerArray( + 'Sukka\'s Ruleset - Domestic Domains', + rulesetDescription, + new Date(), + surgeRulesetToClashClassicalTextRuleset(results) + ), + path.resolve(__dirname, '../Clash/non_ip/domestic.txt') + ), compareAndWriteFile( [ '#!name=[Sukka] Local DNS Mapping', diff --git a/Build/build-phishing-domainset.js b/Build/build-phishing-domainset.js index 615813b1..aabf8c22 100644 --- a/Build/build-phishing-domainset.js +++ b/Build/build-phishing-domainset.js @@ -5,6 +5,7 @@ const { withBannerArray } = require('./lib/with-banner.js'); const { compareAndWriteFile } = require('./lib/string-array-compare'); const { processLine } = require('./lib/process-line.js'); const domainSorter = require('./lib/stable-sort-domain'); +const { surgeDomainsetToClashDomainset } = require('./lib/clash.js'); const WHITELIST_DOMAIN = new Set([ 'w3s.link', @@ -141,21 +142,34 @@ const BLACK_TLD = new Set([ results.sort(domainSorter); - await compareAndWriteFile( - withBannerArray( - 'Sukka\'s Surge Rules - Reject Phishing', - [ - 'License: AGPL 3.0', - 'Homepage: https://ruleset.skk.moe', - 'GitHub: https://github.com/SukkaW/Surge', - '', - 'The domainset supports enhanced phishing protection', - 'Build from:', - ' - https://gitlab.com/malware-filter/phishing-filter' - ], - new Date(), - results + const description = [ + 'License: AGPL 3.0', + 'Homepage: https://ruleset.skk.moe', + 'GitHub: https://github.com/SukkaW/Surge', + '', + 'The domainset supports enhanced phishing protection', + 'Build from:', + ' - https://gitlab.com/malware-filter/phishing-filter' + ]; + + await Promise.all([ + compareAndWriteFile( + withBannerArray( + 'Sukka\'s Ruleset - Reject Phishing', + description, + new Date(), + results + ), + path.resolve(__dirname, '../List/domainset/reject_phishing.conf') ), - path.resolve(__dirname, '../List/domainset/reject_phishing.conf') - ); + compareAndWriteFile( + withBannerArray( + 'Sukka\'s Ruleset - Reject Phishing', + description, + new Date(), + surgeDomainsetToClashDomainset(results) + ), + path.resolve(__dirname, '../Clash/domainset/reject_phishing.txt') + ) + ]); })(); diff --git a/Build/build-reject-domainset.js b/Build/build-reject-domainset.js index 59f50566..29b2e9a3 100644 --- a/Build/build-reject-domainset.js +++ b/Build/build-reject-domainset.js @@ -16,6 +16,7 @@ const { domainDeduper } = require('./lib/domain-deduper'); const createKeywordFilter = require('./lib/aho-corasick'); const { readFileByLine } = require('./lib/fetch-remote-text-by-line'); const domainSorter = require('./lib/stable-sort-domain'); +const { surgeDomainsetToClashDomainset } = require('./lib/clash'); /** Whitelists */ const filterRuleWhitelistDomainSets = new Set(PREDEFINED_WHITELIST); @@ -196,26 +197,38 @@ const domainSuffixSet = new Set(); return acc; }, {}); + const description = [ + 'License: AGPL 3.0', + 'Homepage: https://ruleset.skk.moe', + 'GitHub: https://github.com/SukkaW/Surge', + '', + 'The domainset supports AD blocking, tracking protection, privacy protection, anti-phishing, anti-mining', + '', + 'Build from:', + ...HOSTS.map(host => ` - ${host[0]}`), + ...ADGUARD_FILTERS.map(filter => ` - ${Array.isArray(filter) ? filter[0] : filter}`) + ]; + const domainset = dudupedDominArray.sort(domainSorter); + await Promise.all([ compareAndWriteFile( withBannerArray( - 'Sukka\'s Surge Rules - Reject Base', - [ - 'License: AGPL 3.0', - 'Homepage: https://ruleset.skk.moe', - 'GitHub: https://github.com/SukkaW/Surge', - '', - 'The domainset supports AD blocking, tracking protection, privacy protection, anti-phishing, anti-mining', - '', - 'Build from:', - ...HOSTS.map(host => ` - ${host[0]}`), - ...ADGUARD_FILTERS.map(filter => ` - ${Array.isArray(filter) ? filter[0] : filter}`) - ], + 'Sukka\'s Ruleset - Reject Base', + description, new Date(), - dudupedDominArray.sort(domainSorter) + domainset ), pathResolve(__dirname, '../List/domainset/reject.conf') ), + compareAndWriteFile( + withBannerArray( + 'Sukka\'s Ruleset - Reject Base', + description, + new Date(), + surgeDomainsetToClashDomainset(domainset) + ), + pathResolve(__dirname, '../Clash/domainset/reject.txt') + ), fs.promises.writeFile( pathResolve(__dirname, '../List/internal/reject-stats.txt'), Object.entries(rejectDomainsStats) diff --git a/Build/build-speedtest-domainset.js b/Build/build-speedtest-domainset.js index 1cb54564..c9e13f52 100644 --- a/Build/build-speedtest-domainset.js +++ b/Build/build-speedtest-domainset.js @@ -6,6 +6,7 @@ const { compareAndWriteFile } = require('./lib/string-array-compare'); const domainSorter = require('./lib/stable-sort-domain'); const { Sema } = require('async-sema'); +const { surgeDomainsetToClashDomainset } = require('./lib/clash'); const s = new Sema(2); /** @@ -107,19 +108,31 @@ const querySpeedtestApi = async (keyword) => { } } - const reduped = domainDeduper(Array.from(domains)).sort(domainSorter); + const deduped = domainDeduper(Array.from(domains)).sort(domainSorter); + const description = [ + 'License: AGPL 3.0', + 'Homepage: https://ruleset.skk.moe', + 'GitHub: https://github.com/SukkaW/Surge' + ]; - await compareAndWriteFile( - withBannerArray( - 'Sukka\'s Surge Rules - Speedtest Domains', - [ - 'License: AGPL 3.0', - 'Homepage: https://ruleset.skk.moe', - 'GitHub: https://github.com/SukkaW/Surge' - ], - new Date(), - reduped + await Promise.all([ + compareAndWriteFile( + withBannerArray( + 'Sukka\'s Ruleset - Speedtest Domains', + description, + new Date(), + deduped + ), + path.resolve(__dirname, '../List/domainset/speedtest.conf') ), - path.resolve(__dirname, '../List/domainset/speedtest.conf') - ); + compareAndWriteFile( + withBannerArray( + 'Sukka\'s Ruleset - Speedtest Domains', + description, + new Date(), + surgeDomainsetToClashDomainset(deduped) + ), + path.resolve(__dirname, '../Clash/domainset/speedtest.txt') + ) + ]); })(); diff --git a/Build/build-telegram-cidr.js b/Build/build-telegram-cidr.js index 08bcd88b..ec99a565 100644 --- a/Build/build-telegram-cidr.js +++ b/Build/build-telegram-cidr.js @@ -5,6 +5,7 @@ const { isIPv4, isIPv6 } = require('net'); const { withBannerArray } = require('./lib/with-banner'); const { processLine } = require('./lib/process-line'); const { compareAndWriteFile } = require('./lib/string-array-compare'); +const { surgeRulesetToClashClassicalTextRuleset } = require('./lib/clash'); (async () => { console.time('Total Time - build-telegram-cidr'); @@ -34,21 +35,34 @@ const { compareAndWriteFile } = require('./lib/string-array-compare'); throw new Error('Failed to fetch data!'); } - await compareAndWriteFile( - withBannerArray( - 'Sukka\'s Surge Rules - Telegram IP CIDR', - [ - 'License: AGPL 3.0', - 'Homepage: https://ruleset.skk.moe', - 'GitHub: https://github.com/SukkaW/Surge', - 'Data from:', - ' - https://core.telegram.org/resources/cidr.txt' - ], - date, - results + const description = [ + 'License: AGPL 3.0', + 'Homepage: https://ruleset.skk.moe', + 'GitHub: https://github.com/SukkaW/Surge', + 'Data from:', + ' - https://core.telegram.org/resources/cidr.txt' + ]; + + await Promise.all([ + compareAndWriteFile( + withBannerArray( + 'Sukka\'s Ruleset - Telegram IP CIDR', + description, + date, + results + ), + path.resolve(__dirname, '../List/ip/telegram.conf') ), - path.resolve(__dirname, '../List/ip/telegram.conf') - ); + compareAndWriteFile( + withBannerArray( + 'Sukka\'s Ruleset - Telegram IP CIDR', + description, + date, + surgeRulesetToClashClassicalTextRuleset(results) + ), + path.resolve(__dirname, '../Clash/ip/telegram.txt') + ) + ]); console.timeEnd('Total Time - build-telegram-cidr'); })(); diff --git a/Build/build.js b/Build/build.js new file mode 100644 index 00000000..963838ef --- /dev/null +++ b/Build/build.js @@ -0,0 +1,179 @@ +// @ts-check + +const path = require('path'); +const { PathScurry } = require('path-scurry'); +const { readFileByLine } = require('./lib/fetch-remote-text-by-line'); +const { processLine } = require('./lib/process-line'); +const { compareAndWriteFile } = require('./lib/string-array-compare'); +const { withBannerArray } = require('./lib/with-banner'); +const { domainDeduper } = require('./lib/domain-deduper'); +const { surgeRulesetToClashClassicalTextRuleset, surgeDomainsetToClashDomainset } = require('./lib/clash'); + +const MAGIC_COMMAND_SKIP = '# $ custom_build_script'; +const MAGIC_COMMAND_TITLE = '# $ meta_title '; +const MAGIC_COMMAND_DESCRIPTION = '# $ meta_description '; + +const sourceDir = path.resolve(__dirname, '../Source'); +const outputSurgeDir = path.resolve(__dirname, '../List'); +const outputClashDir = path.resolve(__dirname, '../Clash'); + +(async () => { + /** @type {Promise[]} */ + const promises = []; + + const pw = new PathScurry(sourceDir); + for await (const entry of pw) { + if (entry.isFile()) { + if (path.extname(entry.name) === '.js') { + continue; + } + + const relativePath = entry.relative(); + if (relativePath.startsWith('domainset/')) { + promises.push(transformDomainset(entry.fullpath(), relativePath)); + continue; + } + if ( + relativePath.startsWith('ip/') + || relativePath.startsWith('non_ip/') + ) { + promises.push(transformRuleset(entry.fullpath(), relativePath)); + continue; + } + } + } + + await Promise.all(promises); +})(); + +/** + * @param {string} sourcePath + */ +const processFile = async (sourcePath) => { + /** @type {Set} */ + const lines = new Set(); + + let title = ''; + /** @type {string[]} */ + const descriptions = []; + + for await (const line of readFileByLine(sourcePath)) { + if (line === MAGIC_COMMAND_SKIP) { + return; + } + + if (line.startsWith(MAGIC_COMMAND_TITLE)) { + title = line.slice(MAGIC_COMMAND_TITLE.length).trim(); + continue; + } + + if (line.startsWith(MAGIC_COMMAND_DESCRIPTION)) { + descriptions.push(line.slice(MAGIC_COMMAND_DESCRIPTION.length).trim()); + continue; + } + + const l = processLine(line); + if (l) { + lines.add(l); + } + } + + return /** @type {const} */ ([title, descriptions, lines]); +}; + +/** + * @param {string} sourcePath + * @param {string} relativePath + */ +async function transformDomainset(sourcePath, relativePath) { + const res = await processFile(sourcePath); + if (!res) return; + const [title, descriptions, lines] = res; + + const deduped = domainDeduper(Array.from(lines)); + const description = [ + 'License: AGPL 3.0', + 'Homepage: https://ruleset.skk.moe', + 'GitHub: https://github.com/SukkaW/Surge', + ...( + descriptions.length + ? ['', ...descriptions] + : [] + ) + ]; + + await Promise.all([ + // Surge DOMAIN-SET + compareAndWriteFile( + withBannerArray( + title, + description, + new Date(), + deduped + ), + path.resolve(outputSurgeDir, relativePath) + ), + // Clash domain text + compareAndWriteFile( + withBannerArray( + title, + description, + new Date(), + surgeDomainsetToClashDomainset(deduped) + ), + // change path extname to .txt + path.resolve(outputClashDir, `${relativePath.slice(0, -path.extname(relativePath).length)}.txt`) + ) + ]); +} + +/** + * Output Surge RULE-SET and Clash classical text format + * + * @param {string} sourcePath + * @param {string} relativePath + */ +async function transformRuleset(sourcePath, relativePath) { + const res = await processFile(sourcePath); + if (!res) return; + const [title, descriptions, set] = res; + + const description = [ + 'License: AGPL 3.0', + 'Homepage: https://ruleset.skk.moe', + 'GitHub: https://github.com/SukkaW/Surge', + ...( + descriptions.length + ? ['', ...descriptions] + : [] + ) + ]; + + const lines = Array.from(set); + + const clashSupported = surgeRulesetToClashClassicalTextRuleset(set); + + await Promise.all([ + // Surge RULE-SET + compareAndWriteFile( + withBannerArray( + title, + description, + new Date(), + lines + ), + path.resolve(outputSurgeDir, relativePath) + ), + // Clash domainset + compareAndWriteFile( + withBannerArray( + title, + description, + new Date(), + clashSupported + ), + // change path extname to .txt + path.resolve(outputClashDir, `${relativePath.slice(0, -path.extname(relativePath).length)}.txt`) + ) + ]); +} diff --git a/Build/download-previous-build.js b/Build/download-previous-build.js index 362fd6fd..f95717b2 100644 --- a/Build/download-previous-build.js +++ b/Build/download-previous-build.js @@ -7,6 +7,7 @@ const { tmpdir } = require('os'); const { Readable } = require('stream'); const { pipeline } = require('stream/promises'); const { readFileByLine } = require('./lib/fetch-remote-text-by-line'); +const { isCI } = require('ci-info'); const fileExists = (path) => { return fs.promises.access(path, fs.constants.F_OK) @@ -19,18 +20,22 @@ const fileExists = (path) => { let allFileExists = true; - for await (const line of readFileByLine(resolve(__dirname, '../.gitignore'))) { - if ( - ( - line.startsWith('List/') - || line.startsWith('Modules/') - ) && !line.endsWith('/') - ) { - allFileExists = await fileExists(join(__dirname, '..', line)); - filesList.push(line); + if (isCI) { + allFileExists = false; + } else { + for await (const line of readFileByLine(resolve(__dirname, '../.gitignore'))) { + if ( + ( + // line.startsWith('List/') + line.startsWith('Modules/') + ) && !line.endsWith('/') + ) { + allFileExists = await fileExists(join(__dirname, '..', line)); + filesList.push(line); - if (!allFileExists) { - console.log(`File not exists: ${line}`); + if (!allFileExists) { + console.log(`File not exists: ${line}`); + } } } } diff --git a/Build/lib/clash.js b/Build/lib/clash.js new file mode 100644 index 00000000..5be5a424 --- /dev/null +++ b/Build/lib/clash.js @@ -0,0 +1,34 @@ +// @ts-check +const _Trie = require('mnemonist/trie'); +const Trie = _Trie.default || _Trie; + +const CLASH_SUPPORTED_RULE_TYPE = [ + 'DOMAIN-SUFFIX', + 'DOMAIN-KEYWORD', + 'DOMAIN', + 'SRC-IP-CIDR', + 'GEOIP', + 'IP-CIDR', + 'IP-CIDR6', + 'DST-PORT', + 'SRC-PORT' +]; + +/** + * @param {string[] | Set} rules + */ +const surgeRulesetToClashClassicalTextRuleset = (rules) => { + const trie = Trie.from(rules); + return CLASH_SUPPORTED_RULE_TYPE.map( + type => trie.find(`${type},`) + ).flat(); +}; +module.exports.surgeRulesetToClashClassicalTextRuleset = surgeRulesetToClashClassicalTextRuleset; + +/** + * @param {string[]} domainset + */ +const surgeDomainsetToClashDomainset = (domainset) => { + return domainset.map(i => (i[0] === '.' ? `+${i}` : i)); +}; +module.exports.surgeDomainsetToClashDomainset = surgeDomainsetToClashDomainset; diff --git a/List/domainset/icloud_private_relay.conf b/List/domainset/icloud_private_relay.conf deleted file mode 100644 index 91d680e2..00000000 --- a/List/domainset/icloud_private_relay.conf +++ /dev/null @@ -1,6 +0,0 @@ -mask.icloud.com -mask-h2.icloud.com -mask-api.icloud.com -mask.apple-dns.net -mask-api.fe.apple-dns.net -mask-t.apple-dns.net diff --git a/List/domainset/my_proxy.conf b/List/domainset/my_proxy.conf deleted file mode 100644 index b6141db0..00000000 --- a/List/domainset/my_proxy.conf +++ /dev/null @@ -1 +0,0 @@ -# deprecated diff --git a/List/ip/domestic.conf b/List/ip/domestic.conf deleted file mode 100644 index f7b1fc62..00000000 --- a/List/ip/domestic.conf +++ /dev/null @@ -1,2 +0,0 @@ -# >> Tencent AIA -IP-CIDR,162.14.0.0/18,no-resolve diff --git a/List/non_ip/speedtest.conf b/List/non_ip/speedtest.conf deleted file mode 100644 index 6088f87e..00000000 --- a/List/non_ip/speedtest.conf +++ /dev/null @@ -1 +0,0 @@ -# Deprecated diff --git a/README.md b/README.md index e12db8c3..876f0659 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Surge +# Sukka Ruleset -由 [Sukka](https://skk.moe) 搜集、整理、维护的、个人自用的、仅适用于 [Surge](https://nssurge.com/) 的 Rule Snippet。 +由 [Sukka](https://skk.moe) 搜集、整理、维护的、个人自用的、适用于 [Surge](https://nssurge.com/) 和 [Clash Premium](https://dreamacro.github.io/clash/) 的 Rule Snippet。 ## 条款和协议 @@ -18,6 +18,13 @@ #### 广告拦截 / 隐私保护 / Malware 拦截 / Phiishing 拦截 +- 自动生成 +- 数据来源、白名单域名列表和生成方式,请参考 [`build-reject-domainset.js`](Build/build-reject-domainset.js) +- 仅建议在 Surge for Mac 上使用,移动平台请使用专门的工具(如 ADGuard for Android/iOS)以获得更好的性能 +- 不能替代浏览器广告屏蔽扩展(如 uBlock Origin) + +**Surge** + ```ini RULE-SET,https://ruleset.skk.moe/List/non_ip/reject.conf,REJECT DOMAIN-SET,https://ruleset.skk.moe/List/domainset/reject.conf,REJECT-TINYGIF @@ -25,80 +32,97 @@ DOMAIN-SET,https://ruleset.skk.moe/List/domainset/reject_phishing.conf,REJECT RULE-SET,https://ruleset.skk.moe/List/ip/reject.conf,REJECT-DROP ``` -- 自动生成 -- 数据来源、白名单域名列表和生成方式,请参考 [`build-reject-domainset.js`](Build/build-reject-domainset.js) -- 仅建议在 Surge for Mac 上使用,移动平台请使用专门的工具(如 ADGuard for Android/iOS)以获得更好的性能 -- 不能替代浏览器广告屏蔽扩展(如 uBlock Origin) +**Clash** + + #### 搜狗输入法 -```ini -RULE-SET,https://ruleset.skk.moe/List/non_ip/sogouinput.conf, -``` - - 人工维护 - 该规则组用于避免搜狗输入法将你输入的每一个字符自动收集并通过 `get.sogou.com/q` 等域名回传 - 影响搜狗输入法账号同步、词库更新、问题反馈 +**Surge** + +```ini +RULE-SET,https://ruleset.skk.moe/List/non_ip/sogouinput.conf, +``` + #### 常见静态 CDN +- 自动生成 + 人工维护 +- 包含所有常见静态资源 CDN 域名、对象存储域名 +- 如果你正在使用商业性质的公共代理服务、且你的服务商提供按低倍率结算流量消耗的节点,可使用上述规则组将流量分配给这部分节点 + +**Surge** + ```ini DOMAIN-SET,https://ruleset.skk.moe/List/domainset/cdn.conf,[Replace with your policy] RULE-SET,https://ruleset.skk.moe/List/non_ip/cdn.conf,[Replace with your policy] ``` -- 自动生成 + 人工维护 -- 包含所有常见静态资源 CDN 域名、对象存储域名 -- 如果你正在使用商业性质的公共代理服务、且你的服务商提供按低倍率结算流量消耗的节点,可使用上述规则组将流量分配给这部分节点 - #### 流媒体 +- 人工维护 +- 包含 4gtv、AbemaTV、All4、Amazon Prime Video、Apple TV、Apple Music TV、Bahamut、BBC、Bilibili Intl、DAZN、Deezer、Disney+、Discovery+、DMM、encoreTVB、Fox Now、Fox+、HBO GO/Now/Max/Asia、Hulu、HWTV、JOOX、Jwplayer、KKBOX、KKTV、Line TV、Naver TV、myTV Super、Netflix、niconico、Now E、Paramount+、PBS、Peacock、Pandora、PBS、Pornhub、SoundCloud、PBS、Spotify、TaiwanGood、Tiktok Intl、Twitch、ViuTV、ShowTime、iQiYi Global、Himalaya Podcast、Overcast、WeTV 的规则组 + +**Surge** + ```ini RULE-SET,https://ruleset.skk.moe/List/non_ip/stream.conf,[Replace with your policy] RULE-SET,https://ruleset.skk.moe/List/ip/stream.conf,[Replace with your policy] ``` -- 人工维护 -- 包含 4gtv、AbemaTV、All4、Amazon Prime Video、Apple TV、Apple Music TV、Bahamut、BBC、Bilibili Intl、DAZN、Deezer、Disney+、Discovery+、DMM、encoreTVB、Fox Now、Fox+、HBO GO/Now/Max/Asia、Hulu、HWTV、JOOX、Jwplayer、KKBOX、KKTV、Line TV、Naver TV、myTV Super、Netflix、niconico、Now E、Paramount+、PBS、Peacock、Pandora、PBS、Pornhub、SoundCloud、PBS、Spotify、TaiwanGood、Tiktok Intl、Twitch、ViuTV、ShowTime、iQiYi Global、Himalaya Podcast、Overcast、WeTV 的规则组 - #### Telegram +- 域名规则 人工维护 +- IP CIDR 规则 自动生成(数据来源:[`https://core.telegram.org/resources/cidr.txt`](https://core.telegram.org/resources/cidr.txt)) + +**Surge** + ```ini RULE-SET,https://ruleset.skk.moe/List/non_ip/telegram.conf,[Replace with your policy] RULE-SET,https://ruleset.skk.moe/List/ip/telegram.conf,[Replace with your policy] ``` -- 域名规则 人工维护 -- IP CIDR 规则 自动生成(数据来源:[`https://core.telegram.org/resources/cidr.txt`](https://core.telegram.org/resources/cidr.txt)) - #### Apple CDN -```ini -DOMAIN-SET,https://ruleset.skk.moe/List/domainset/apple_cdn.conf,[Replace with your policy] -``` - - 自动生成 - 规则组包含 Apple, Inc. 在中华人民共和国完成工信部 ICP 备案和公安网备、且在中华人民共和国境内提供 HTTP 服务的域名,如果由于某些原因需要代理其中部分域名,请自行针对域名编写规则、并添加到当前规则组之前。 - 数据来源 [`felixonmars/dnsmasq-china-list`](https://github.com/felixonmars/dnsmasq-china-list/blob/master/apple.china.conf) +**Surge** + +```ini +DOMAIN-SET,https://ruleset.skk.moe/List/domainset/apple_cdn.conf,[Replace with your policy] +``` + #### Apple Service +- 人工维护 + +**Surge** + ```ini RULE-SET,https://ruleset.skk.moe/List/non_ip/apple_services.conf,[Replace with your policy] ``` +#### 网易云音乐 + - 人工维护 -#### 网易云音乐 +**Surge** ```ini RULE-SET,https://ruleset.skk.moe/List/non_ip/neteasemusic.conf,[Replace with your policy] RULE-SET,https://ruleset.skk.moe/List/ip/neteasemusic.conf,[Replace with your policy] ``` +#### Misc + - 人工维护 -#### Misc +**Surge** ```ini RULE-SET,https://ruleset.skk.moe/List/non_ip/domestic.conf,[Replace with your policy] @@ -108,17 +132,17 @@ RULE-SET,https://ruleset.skk.moe/List/non_ip/global.conf,PROXY RULE-SET,https://ruleset.skk.moe/List/ip/domestic.conf,[Replace with your policy] ``` -- 人工维护 - #### chnroute CIDR +- 自动生成 +- [原始数据](https://github.com/misakaio/chnroutes2) 由 Misaka Network, Inc.、DMIT, Inc.、NEROCLOUD Ltd.、Rainbow network Ltd.、MOACK Co., Ltd. 提供,由 Misaka Network, Inc. 整理,以 [CC BY-SA 2.0](https://creativecommons.org/licenses/by-sa/2.0/) 协议发布 + +**Surge** + ```ini RULE-SET,https://ruleset.skk.moe/List/ip/china_ip.conf,[Replace with your policy] ``` -- 自动生成 -- [原始数据](https://github.com/misakaio/chnroutes2) 由 Misaka Network, Inc.、DMIT, Inc.、NEROCLOUD Ltd.、Rainbow network Ltd.、MOACK Co., Ltd. 提供,由 Misaka Network, Inc. 整理,以 [CC BY-SA 2.0](https://creativecommons.org/licenses/by-sa/2.0/) 协议发布 - ## Surge 模块列表 - Sukka URL Rewrite: `https://ruleset.skk.moe/Modules/sukka_url_rewrite.sgmodule` @@ -139,7 +163,9 @@ RULE-SET,https://ruleset.skk.moe/List/ip/china_ip.conf,[Replace with your policy **有适用于 Clash 的规则组吗?** -没有。如果 [Clash Premium 提供了对 `DOMAIN-SET` 格式的支持](https://github.com/Dreamacro/clash/issues/1838),未来可能会有。 +~~没有。如果 [Clash Premium 提供了对 `DOMAIN-SET` 格式的支持](https://github.com/Dreamacro/clash/issues/1838),未来可能会有。~~ + +有。 **有适用于 Shadowrocket、Quantumult X、Loon、V2RayNG 的规则组吗?** diff --git a/Source/domainset/cdn.conf b/Source/domainset/cdn.conf index e5b4814a..6749cdb1 100644 --- a/Source/domainset/cdn.conf +++ b/Source/domainset/cdn.conf @@ -1,3 +1,6 @@ +# $ meta_title Sukka's Ruleset - CDN Domains +# $ meta_description This file contains object storage and static assets CDN domains. + # >> Sukka ruleset.skk.moe pic.skk.moe diff --git a/List/domainset/download.conf b/Source/domainset/download.conf similarity index 88% rename from List/domainset/download.conf rename to Source/domainset/download.conf index 8224ede6..f6547b4b 100644 --- a/List/domainset/download.conf +++ b/Source/domainset/download.conf @@ -1,3 +1,6 @@ +# $ meta_title Sukka's Ruleset - Large Files Hosting Domains +# $ meta_description This file contains domains for software updating & large file hosting. + .1fichier.com .1fichier.info .nitro.download diff --git a/Source/domainset/icloud_private_relay.conf b/Source/domainset/icloud_private_relay.conf new file mode 100644 index 00000000..cfabb238 --- /dev/null +++ b/Source/domainset/icloud_private_relay.conf @@ -0,0 +1,9 @@ +# $ meta_title Sukka's Ruleset - iCloud Private Relay +# $ meta_description This file contains domains for iCloud Private Relay Endpoint. + +mask.icloud.com +mask-h2.icloud.com +mask-api.icloud.com +mask.apple-dns.net +mask-api.fe.apple-dns.net +mask-t.apple-dns.net diff --git a/Source/domainset/reject_sukka.conf b/Source/domainset/reject_sukka.conf index 471ece3e..4d29a2a3 100644 --- a/Source/domainset/reject_sukka.conf +++ b/Source/domainset/reject_sukka.conf @@ -1,3 +1,5 @@ +# $ custom_build_script + # --- Blacklist --- # >> General diff --git a/List/ip/apple_services.conf b/Source/ip/apple_services.conf similarity index 75% rename from List/ip/apple_services.conf rename to Source/ip/apple_services.conf index eb82506f..2857cf4d 100644 --- a/List/ip/apple_services.conf +++ b/Source/ip/apple_services.conf @@ -1,3 +1,6 @@ +# $ meta_title Sukka's Ruleset - Apple IP +# $ meta_description This file contains IPs owned/used by Apple, Inc. + IP-CIDR,17.0.0.0/8,no-resolve IP-CIDR,63.92.224.0/19,no-resolve IP-CIDR,65.199.22.0/23,no-resolve diff --git a/Source/ip/domestic.conf b/Source/ip/domestic.conf new file mode 100644 index 00000000..cacf3084 --- /dev/null +++ b/Source/ip/domestic.conf @@ -0,0 +1,4 @@ +# $ meta_title Sukka's Ruleset - Mainland China Supplement CIDR +# $ meta_description This file contains IPs broadcast inside Mainland China. + +IP-CIDR,162.14.0.0/18,no-resolve diff --git a/List/ip/download.conf b/Source/ip/download.conf similarity index 73% rename from List/ip/download.conf rename to Source/ip/download.conf index c79209aa..69961a22 100644 --- a/List/ip/download.conf +++ b/Source/ip/download.conf @@ -1,3 +1,6 @@ +# $ meta_title Sukka's Ruleset - Large Files Hosting IPs +# $ meta_description This file contains IPs for software updating & large file hosting. + # >> MEGA IP-CIDR,185.206.24.0/22,no-resolve diff --git a/List/ip/neteasemusic.conf b/Source/ip/neteasemusic.conf similarity index 85% rename from List/ip/neteasemusic.conf rename to Source/ip/neteasemusic.conf index 391fa5a7..f829d133 100644 --- a/List/ip/neteasemusic.conf +++ b/Source/ip/neteasemusic.conf @@ -1,4 +1,5 @@ -# >> NeteaseMusic +# $ meta_title Sukka's Ruleset - Netease Music IPs +# $ meta_description This file contains IPs used by Netease Music. IP-CIDR,39.105.63.80/32,no-resolve IP-CIDR,45.254.48.1/32,no-resolve diff --git a/Source/ip/reject.conf b/Source/ip/reject.conf index fd95fe3f..a15f5505 100644 --- a/Source/ip/reject.conf +++ b/Source/ip/reject.conf @@ -1,3 +1,5 @@ +# $ custom_build_script + # --- AD Block --- # >> iQiyi diff --git a/List/ip/stream.conf b/Source/ip/stream.conf similarity index 84% rename from List/ip/stream.conf rename to Source/ip/stream.conf index 1c09ec77..a16a7122 100644 --- a/List/ip/stream.conf +++ b/Source/ip/stream.conf @@ -1,4 +1,5 @@ -# --- Stream Service --- +# $ meta_title Sukka's Ruleset - Stream Services IPs +# $ meta_description This file contains IPs used by popular stream services. # >> Netflix IP-CIDR,23.246.18.0/23,no-resolve diff --git a/List/non_ip/apple_services.conf b/Source/non_ip/apple_services.conf similarity index 76% rename from List/non_ip/apple_services.conf rename to Source/non_ip/apple_services.conf index 560addc6..b73eb77e 100644 --- a/List/non_ip/apple_services.conf +++ b/Source/non_ip/apple_services.conf @@ -1,3 +1,6 @@ +# $ meta_title Sukka's Ruleset - Apple Domains +# $ meta_description This file contains domains of Apple, Inc that doesn't have PoP inside the Mainland China. + # >> Apple DOMAIN-SUFFIX,aaplimg.com DOMAIN-SUFFIX,apple-dns.net diff --git a/Source/non_ip/cdn.conf b/Source/non_ip/cdn.conf index 8d5417d2..4d8cb394 100644 --- a/Source/non_ip/cdn.conf +++ b/Source/non_ip/cdn.conf @@ -1,3 +1,5 @@ +# $ custom_build_script + # >> GitHub Pages DOMAIN-SUFFIX,github.io # >> GitHub diff --git a/List/non_ip/direct.conf b/Source/non_ip/direct.conf similarity index 97% rename from List/non_ip/direct.conf rename to Source/non_ip/direct.conf index 5c42d55a..bbba58c2 100644 --- a/List/non_ip/direct.conf +++ b/Source/non_ip/direct.conf @@ -1,3 +1,6 @@ +# $ meta_title Sukka's Ruleset - Direct Rules +# $ meta_description This file contains domains and process that should not be proxied. + # >> AdGuard DOMAIN,injections.adguard.org DOMAIN,local.adguard.org diff --git a/Source/non_ip/domestic.conf b/Source/non_ip/domestic.conf index 8c263a2a..7dc66cbe 100644 --- a/Source/non_ip/domestic.conf +++ b/Source/non_ip/domestic.conf @@ -1,3 +1,5 @@ +# $ custom_build_script + # >> Akamai DOMAIN-SUFFIX,akadns.net diff --git a/List/non_ip/global.conf b/Source/non_ip/global.conf similarity index 90% rename from List/non_ip/global.conf rename to Source/non_ip/global.conf index 0fc26285..ede16008 100644 --- a/List/non_ip/global.conf +++ b/Source/non_ip/global.conf @@ -1,4 +1,5 @@ -# --- General Global Services --- +# $ meta_title Sukka's Ruleset - General Global Services +# $ meta_description This file contains rules for services that are not available inside the Mainland China. # >> Apple DOMAIN-SUFFIX,appsto.re @@ -90,4 +91,4 @@ DOMAIN-KEYWORD,github USER-AGENT,Roam* -# --- End of General Global Services Section --- \ No newline at end of file +# --- End of General Global Services Section --- diff --git a/List/non_ip/global_plus.conf b/Source/non_ip/global_plus.conf similarity index 94% rename from List/non_ip/global_plus.conf rename to Source/non_ip/global_plus.conf index 40418dee..9b5ca551 100644 --- a/List/non_ip/global_plus.conf +++ b/Source/non_ip/global_plus.conf @@ -1,4 +1,5 @@ -# --- Enhanced Global Services --- +# $ meta_title Sukka's Ruleset - Enhanced Global Services +# $ meta_description This file contains rules for services that are not available inside the Mainland China. # >> Cloudflare DOMAIN-SUFFIX,cloudflareresolve.com diff --git a/List/non_ip/my_direct.conf b/Source/non_ip/my_direct.conf similarity index 84% rename from List/non_ip/my_direct.conf rename to Source/non_ip/my_direct.conf index cb4ed2be..4f09adc3 100644 --- a/List/non_ip/my_direct.conf +++ b/Source/non_ip/my_direct.conf @@ -1,3 +1,5 @@ +# $ meta_title Sukka's Ruleset - Direct + DOMAIN-SUFFIX,torrentmac.net DOMAIN-SUFFIX,download.555mac.com DOMAIN-KEYWORD,mac-torrent-download diff --git a/List/non_ip/my_proxy.conf b/Source/non_ip/my_proxy.conf similarity index 97% rename from List/non_ip/my_proxy.conf rename to Source/non_ip/my_proxy.conf index 0d252f06..e725e8a1 100644 --- a/List/non_ip/my_proxy.conf +++ b/Source/non_ip/my_proxy.conf @@ -1,3 +1,5 @@ +# $ meta_title Sukka's Ruleset - Proxy + DOMAIN-SUFFIX,mikuclub.xyz DOMAIN-SUFFIX,mikuclub.cn DOMAIN-SUFFIX,saucenao.com diff --git a/List/non_ip/my_reject.conf b/Source/non_ip/my_reject.conf similarity index 91% rename from List/non_ip/my_reject.conf rename to Source/non_ip/my_reject.conf index 7e646d5f..8115ab29 100644 --- a/List/non_ip/my_reject.conf +++ b/Source/non_ip/my_reject.conf @@ -1,3 +1,5 @@ +# $ meta_title Sukka's Ruleset - Reject + DOMAIN,download.parallels.com DOMAIN,update.parallels.com DOMAIN,desktop.parallels.com diff --git a/List/non_ip/neteasemusic.conf b/Source/non_ip/neteasemusic.conf similarity index 55% rename from List/non_ip/neteasemusic.conf rename to Source/non_ip/neteasemusic.conf index bcaaf443..1e22e5a9 100644 --- a/List/non_ip/neteasemusic.conf +++ b/Source/non_ip/neteasemusic.conf @@ -1,4 +1,5 @@ -# >> NeteaseMusic +# $ meta_title Sukka's Ruleset - Netease Music +# $ meta_description This file contains rules for Netease Music. USER-AGENT,%E7%BD%91%E6%98%93%E4%BA%91%E9%9F%B3%E4%B9%90 USER-AGENT,NeteaseMusic* diff --git a/List/non_ip/reject-no-drop.conf b/Source/non_ip/reject-no-drop.conf similarity index 67% rename from List/non_ip/reject-no-drop.conf rename to Source/non_ip/reject-no-drop.conf index 9a818913..baadf348 100644 --- a/List/non_ip/reject-no-drop.conf +++ b/Source/non_ip/reject-no-drop.conf @@ -1,3 +1,6 @@ +# $ meta_title Sukka's Ruleset - Reject No Drop +# $ meta_description This file This file contains rules for domain should be used with REJECT-NO-DROP policy. + # Block YouTube QUIC AND,((PROTOCOL,UDP), (DOMAIN-SUFFIX,googlevideo.com)) # Block Bilibili/Douyu P2P CDN diff --git a/List/non_ip/reject.conf b/Source/non_ip/reject.conf similarity index 99% rename from List/non_ip/reject.conf rename to Source/non_ip/reject.conf index 46286acd..d1d9acd6 100644 --- a/List/non_ip/reject.conf +++ b/Source/non_ip/reject.conf @@ -1,3 +1,6 @@ +# $ meta_title Sukka's Ruleset - Reject Domains +# $ meta_description The ruleset supports AD blocking, tracking protection, privacy protection, anti-phishing, anti-mining + # --- Blacklist --- # >> Crypto Coin Hive diff --git a/List/non_ip/sogouinput.conf b/Source/non_ip/sogouinput.conf similarity index 75% rename from List/non_ip/sogouinput.conf rename to Source/non_ip/sogouinput.conf index 5f792d75..79a4ca6a 100644 --- a/List/non_ip/sogouinput.conf +++ b/Source/non_ip/sogouinput.conf @@ -1,4 +1,6 @@ -# >> Sogou Input +# $ meta_title Sukka's Ruleset - Sogou Input +# $ meta_description This file contains rules for Sogou Input. + PROCESS-NAME,SogouInput PROCESS-NAME,SOgouTaskManager PROCESS-NAME,SogouServices diff --git a/List/non_ip/stream.conf b/Source/non_ip/stream.conf similarity index 98% rename from List/non_ip/stream.conf rename to Source/non_ip/stream.conf index 3f9c0bcc..f67c5bf9 100644 --- a/List/non_ip/stream.conf +++ b/Source/non_ip/stream.conf @@ -1,4 +1,5 @@ -# --- Stream Service --- +# $ meta_title Sukka's Ruleset - Stream Services +# $ meta_description This file contains rules for popular stream services. # >> 4gtv DOMAIN-SUFFIX,4gtv.tv diff --git a/List/non_ip/telegram.conf b/Source/non_ip/telegram.conf similarity index 62% rename from List/non_ip/telegram.conf rename to Source/non_ip/telegram.conf index 98154b93..f7befd75 100644 --- a/List/non_ip/telegram.conf +++ b/Source/non_ip/telegram.conf @@ -1,4 +1,6 @@ -# > Telegram +# $ meta_title Sukka's Ruleset - Telegram Domains +# $ meta_description This file contains domains used by Telegram Messenger. + DOMAIN-SUFFIX,t.me DOMAIN-SUFFIX,tx.me DOMAIN-SUFFIX,tdesktop.com diff --git a/package.json b/package.json index 6f88190a..90925889 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "description": "", "scripts": { "build": "wireit", + "build:common": "wireit", "download-previous-build": "wireit", "build:anti-bogus-domain": "wireit", "build:apple-cdn": "wireit", @@ -25,6 +26,12 @@ "download-previous-build": { "command": "node ./Build/download-previous-build.js" }, + "build:common": { + "command": "node ./Build/build.js", + "dependencies": [ + "download-previous-build" + ] + }, "build:anti-bogus-domain": { "command": "node ./Build/build-anti-bogus-domain.js", "dependencies": [ @@ -95,6 +102,7 @@ "build:public": { "command": "node ./Build/build-public.js", "dependencies": [ + "build:common", "build:anti-bogus-domain", "build:apple-cdn", "build:cdn-conf", @@ -118,6 +126,7 @@ }, "build": { "dependencies": [ + "build:common", "build:anti-bogus-domain", "build:apple-cdn", "build:cdn-conf", @@ -145,8 +154,11 @@ "@sukka/listdir": "^0.2.0", "@vercel/fetch-retry": "^5.1.3", "async-sema": "^3.1.1", + "ci-info": "^3.8.0", "cidr-tools-wasm": "^0.0.11", "fs-extra": "^11.1.1", + "mnemonist": "^0.39.5", + "path-scurry": "^1.10.1", "picocolors": "^1.0.0", "table": "^6.8.1", "tar": "^6.1.15", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9a8462cb..2a0dc5cf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,12 +25,21 @@ dependencies: async-sema: specifier: ^3.1.1 version: 3.1.1 + ci-info: + specifier: ^3.8.0 + version: 3.8.0 cidr-tools-wasm: specifier: ^0.0.11 version: 0.0.11 fs-extra: specifier: ^11.1.1 version: 11.1.1 + mnemonist: + specifier: ^0.39.5 + version: 0.39.5 + path-scurry: + specifier: ^1.10.1 + version: 1.10.1 picocolors: specifier: ^1.0.0 version: 1.0.0 @@ -190,15 +199,15 @@ packages: fastq: 1.13.0 dev: true - /@nolyfill/has@1.0.11: - resolution: {integrity: sha512-Q2QNYUzZxW4/FzI57EGuxQF6PVO+LJajvcsRGTj26FU4z5rmXouaTGMas/2OreYupieIGMeI5dNEJwXS/Wy2kQ==} + /@nolyfill/has@1.0.21: + resolution: {integrity: sha512-Sf8iFaegjGp29hQVQjIc+nDR0uWqGkHsFC3jsUigFwGjpafgMaBtL++DpTU9jYAKDJEvslR1szl8qJjNGlhgcw==} engines: {node: '>=12.4.0'} dependencies: - '@nolyfill/shared': 1.0.11 + '@nolyfill/shared': 1.0.21 dev: true - /@nolyfill/shared@1.0.11: - resolution: {integrity: sha512-MVtVsoUIbg93Bs33Nc7JvOv/ePyUjUMXorrTtTdjPpLn2t8HmbklZvk2ur0np0thyI9OWC5mNQHjR2l0kwJUNQ==} + /@nolyfill/shared@1.0.21: + resolution: {integrity: sha512-qDc/NoaFU23E0hhiDPeUrvWzTXIPE+RbvRQtRWSeHHNmCIgYI9HS1jKzNYNJxv4jvZ/1VmM3L6rNVxbj+LBMNA==} dev: true /@remusao/guess-url-type@1.2.1: @@ -459,6 +468,11 @@ packages: engines: {node: '>=10'} dev: false + /ci-info@3.8.0: + resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} + engines: {node: '>=8'} + dev: false + /cidr-tools-wasm@0.0.11: resolution: {integrity: sha512-WUnooVHC+0/uwG+/5QZT6auR2Gzga+BFkwyQiKki8uZnVHOCn3gEt+FVjHg/7pdXsCbzGsDSMGkZ31ZqIkUrrw==} dev: false @@ -964,7 +978,7 @@ packages: /is-core-module@2.12.1: resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==} dependencies: - has: /@nolyfill/has@1.0.11 + has: /@nolyfill/has@1.0.21 dev: true /is-extglob@2.1.1: @@ -1075,6 +1089,11 @@ packages: get-func-name: 2.0.0 dev: true + /lru-cache@10.0.1: + resolution: {integrity: sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==} + engines: {node: 14 || >=16.14} + dev: false + /lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} @@ -1134,6 +1153,12 @@ packages: hasBin: true dev: false + /mnemonist@0.39.5: + resolution: {integrity: sha512-FPUtkhtJ0efmEFGpU14x7jGbTB+s18LrzRL2KgoWz9YvcY3cPomz8tih01GbHwnGk/OmkOKfqd/RAQoc8Lm7DQ==} + dependencies: + obliterator: 2.0.4 + dev: false + /mocha@10.2.0: resolution: {integrity: sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==} engines: {node: '>= 14.0.0'} @@ -1196,6 +1221,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /obliterator@2.0.4: + resolution: {integrity: sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==} + dev: false + /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -1254,6 +1283,14 @@ packages: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} dev: true + /path-scurry@1.10.1: + resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + lru-cache: 10.0.1 + minipass: 5.0.0 + dev: false + /pathval@1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} dev: true