diff --git a/Build/build-reject-domainset.ts b/Build/build-reject-domainset.ts index f61e4b23..c57cf4f0 100644 --- a/Build/build-reject-domainset.ts +++ b/Build/build-reject-domainset.ts @@ -50,11 +50,11 @@ export const buildRejectDomainSet = task(require.main === module, __filename)(as ...ADGUARD_FILTERS.map(filter => ` - ${Array.isArray(filter) ? filter[0] : filter}`) ]; - const rejectOutput = new DomainsetOutput(span, 'reject') + const rejectDomainsetOutput = new DomainsetOutput(span, 'reject') .withTitle('Sukka\'s Ruleset - Reject Base') .withDescription(rejectBaseDescription); - const rejectExtraOutput = new DomainsetOutput(span, 'reject_extra') + const rejectExtraDomainsetOutput = new DomainsetOutput(span, 'reject_extra') .withTitle('Sukka\'s Ruleset - Reject Extra') .withDescription([ ...SHARED_DESCRIPTION, @@ -67,7 +67,7 @@ export const buildRejectDomainSet = task(require.main === module, __filename)(as ...ADGUARD_FILTERS_EXTRA.map(filter => ` - ${filter[0]}`) ]); - const rejectPhisingOutput = new DomainsetOutput(span, 'reject_phishing') + const rejectPhisingDomainsetOutput = new DomainsetOutput(span, 'reject_phishing') .withTitle('Sukka\'s Ruleset - Reject Phishing') .withDescription([ ...SHARED_DESCRIPTION, @@ -79,6 +79,16 @@ export const buildRejectDomainSet = task(require.main === module, __filename)(as ...PHISHING_DOMAIN_LISTS_EXTRA.map(domainList => ` - ${domainList[0]}`) ]); + const rejectNonIpRulesetOutput = new RulesetOutput(span, 'reject', 'non_ip') + .withTitle('Sukka\'s Ruleset - Reject Non-IP') + .withDescription([ + ...SHARED_DESCRIPTION, + '', + 'The ruleset supports AD blocking, tracking protection, privacy protection, anti-phishing, anti-mining', + '', + 'The file contains wildcard domains from data source mentioned in /domainset/reject file' + ]); + const rejectIPOutput = new RulesetOutput(span, 'reject', 'ip') .withTitle('Sukka\'s Ruleset - Anti Bogus Domain') .withDescription([ @@ -98,22 +108,25 @@ export const buildRejectDomainSet = task(require.main === module, __filename)(as // Collect DOMAIN, DOMAIN-SUFFIX, and DOMAIN-KEYWORD from non_ip/reject.conf for deduplication // DOMAIN-WILDCARD is not really useful for deduplication, it is only included in AdGuardHome output // It is faster to add base than add others first then whitelist - rejectOutput.addFromRuleset(readLocalRejectRulesetPromise); - rejectExtraOutput.addFromRuleset(readLocalRejectRulesetPromise); + rejectDomainsetOutput.addFromRuleset(readLocalRejectRulesetPromise); + rejectExtraDomainsetOutput.addFromRuleset(readLocalRejectRulesetPromise); - rejectOutput.addFromDomainset(readLocalRejectDomainsetPromise); - rejectExtraOutput.addFromDomainset(readLocalRejectDomainsetPromise); - rejectPhisingOutput.addFromDomainset(readLocalRejectDomainsetPromise); + rejectNonIpRulesetOutput.addFromRuleset(readLocalRejectRulesetPromise); - rejectExtraOutput.addFromDomainset(readLocalRejectExtraDomainsetPromise); + rejectDomainsetOutput.addFromDomainset(readLocalRejectDomainsetPromise); + rejectExtraDomainsetOutput.addFromDomainset(readLocalRejectDomainsetPromise); + rejectPhisingDomainsetOutput.addFromDomainset(readLocalRejectDomainsetPromise); + + rejectExtraDomainsetOutput.addFromDomainset(readLocalRejectExtraDomainsetPromise); rejectIPOutput.addFromRuleset(readLocalRejectIpListPromise); - const appendArrayToRejectOutput = (source: MaybePromise | Iterable | string[]>) => rejectOutput.addFromDomainset(source); - const appendArrayToRejectExtraOutput = (source: MaybePromise | Iterable | string[]>) => rejectExtraOutput.addFromDomainset(source); + const appendArrayToRejectOutput = (source: MaybePromise | Iterable | string[]>) => rejectDomainsetOutput.addFromDomainset(source); + const appendArrayToRejectExtraOutput = (source: MaybePromise | Iterable | string[]>) => rejectExtraDomainsetOutput.addFromDomainset(source); /** Whitelists */ const filterRuleWhitelistDomainSets = new Set(PREDEFINED_WHITELIST); + const filterRuleWhiteKeywords = new Set(); // Parse from AdGuard Filters await span @@ -127,34 +140,49 @@ export const buildRejectDomainSet = task(require.main === module, __filename)(as domainListsDownloads.map(task => task(childSpan).then(appendArrayToRejectOutput)), domainListsExtraDownloads.map(task => task(childSpan).then(appendArrayToRejectExtraOutput)), - rejectPhisingOutput.addFromDomainset(getPhishingDomains(childSpan)), + rejectPhisingDomainsetOutput.addFromDomainset(getPhishingDomains(childSpan)), adguardFiltersDownloads.map( - task => task(childSpan).then(({ whiteDomains, whiteDomainSuffixes, blackDomains, blackDomainSuffixes, blackIPs }) => { + task => task(childSpan).then(({ whiteDomains, whiteDomainSuffixes, blackDomains, blackDomainSuffixes, blackIPs, blackWildcard, whiteKeyword, blackKeyword }) => { addArrayElementsToSet(filterRuleWhitelistDomainSets, whiteDomains); addArrayElementsToSet(filterRuleWhitelistDomainSets, whiteDomainSuffixes, suffix => '.' + suffix); - rejectOutput.bulkAddDomain(blackDomains); - rejectOutput.bulkAddDomainSuffix(blackDomainSuffixes); + addArrayElementsToSet(filterRuleWhiteKeywords, whiteKeyword); + + rejectDomainsetOutput.bulkAddDomain(blackDomains); + rejectDomainsetOutput.bulkAddDomainSuffix(blackDomainSuffixes); + + rejectDomainsetOutput.bulkAddDomainKeyword(blackKeyword); + + rejectNonIpRulesetOutput.bulkAddDomainWildcard(blackWildcard); + rejectIPOutput.bulkAddAnyCIDR(blackIPs, false); }) ), adguardFiltersExtraDownloads.map( - task => task(childSpan).then(({ whiteDomains, whiteDomainSuffixes, blackDomains, blackDomainSuffixes, blackIPs }) => { + task => task(childSpan).then(({ whiteDomains, whiteDomainSuffixes, blackDomains, blackDomainSuffixes, blackIPs, blackWildcard, whiteKeyword, blackKeyword }) => { addArrayElementsToSet(filterRuleWhitelistDomainSets, whiteDomains); addArrayElementsToSet(filterRuleWhitelistDomainSets, whiteDomainSuffixes, suffix => '.' + suffix); + addArrayElementsToSet(filterRuleWhiteKeywords, whiteKeyword); + + rejectExtraDomainsetOutput.bulkAddDomain(blackDomains); + rejectExtraDomainsetOutput.bulkAddDomainSuffix(blackDomainSuffixes); + + rejectExtraDomainsetOutput.bulkAddDomainKeyword(blackKeyword); - rejectExtraOutput.bulkAddDomain(blackDomains); - rejectExtraOutput.bulkAddDomainSuffix(blackDomainSuffixes); rejectIPOutput.bulkAddAnyCIDR(blackIPs, false); + + rejectNonIpRulesetOutput.bulkAddDomainWildcard(blackWildcard); }) ), adguardFiltersWhitelistsDownloads.map( - task => task(childSpan).then(({ whiteDomains, whiteDomainSuffixes, blackDomains, blackDomainSuffixes }) => { + task => task(childSpan).then(({ whiteDomains, whiteDomainSuffixes, blackDomains, blackDomainSuffixes, whiteKeyword, blackKeyword }) => { addArrayElementsToSet(filterRuleWhitelistDomainSets, whiteDomains); addArrayElementsToSet(filterRuleWhitelistDomainSets, whiteDomainSuffixes, suffix => '.' + suffix); addArrayElementsToSet(filterRuleWhitelistDomainSets, blackDomains); addArrayElementsToSet(filterRuleWhitelistDomainSets, blackDomainSuffixes, suffix => '.' + suffix); + addArrayElementsToSet(filterRuleWhiteKeywords, whiteKeyword); + addArrayElementsToSet(filterRuleWhiteKeywords, blackKeyword); }) ), @@ -185,29 +213,45 @@ export const buildRejectDomainSet = task(require.main === module, __filename)(as } await Promise.all([ - rejectOutput.done(), - rejectExtraOutput.done(), - rejectPhisingOutput.done(), - rejectIPOutput.done() + rejectDomainsetOutput.done(), + rejectExtraDomainsetOutput.done(), + rejectPhisingDomainsetOutput.done(), + rejectIPOutput.done(), + rejectNonIpRulesetOutput.done() ]); // whitelist span.traceChildSync('whitelist', () => { for (const domain of filterRuleWhitelistDomainSets) { - rejectOutput.whitelistDomain(domain); - rejectExtraOutput.whitelistDomain(domain); - rejectPhisingOutput.whitelistDomain(domain); + rejectDomainsetOutput.whitelistDomain(domain); + rejectExtraDomainsetOutput.whitelistDomain(domain); + rejectPhisingDomainsetOutput.whitelistDomain(domain); + rejectNonIpRulesetOutput.whitelistDomain(domain); } - rejectOutput.domainTrie.dump(arg => rejectExtraOutput.whitelistDomain(arg)); - rejectOutput.domainTrie.dump(arg => rejectPhisingOutput.whitelistDomain(arg)); + // we use "whitelistKeyword" method, this will be used to create kwfilter internally + for (const keyword of filterRuleWhiteKeywords) { + rejectDomainsetOutput.whitelistKeyword(keyword); + rejectExtraDomainsetOutput.whitelistKeyword(keyword); + rejectPhisingDomainsetOutput.whitelistKeyword(keyword); + rejectNonIpRulesetOutput.whitelistKeyword(keyword); + } + + rejectDomainsetOutput.domainTrie.dump(arg => { + rejectExtraDomainsetOutput.whitelistDomain(arg); + rejectPhisingDomainsetOutput.whitelistDomain(arg); + + // e.g. .data.microsort.com can strip waston*.event.data.microsort.com + rejectNonIpRulesetOutput.wildcardTrie.whitelist(arg); + }); }); await Promise.all([ - rejectOutput.write(), - rejectExtraOutput.write(), - rejectPhisingOutput.write(), - rejectIPOutput.write() + rejectDomainsetOutput.write(), + rejectExtraDomainsetOutput.write(), + rejectPhisingDomainsetOutput.write(), + rejectIPOutput.write(), + rejectNonIpRulesetOutput.write() ]); // we are going to re-use rejectOutput's domainTrie and mutate it @@ -218,7 +262,7 @@ export const buildRejectDomainSet = task(require.main === module, __filename)(as 'The AdGuardHome ruleset supports AD blocking, tracking protection, privacy protection, anti-mining' ]); - rejectOutputAdGuardHome.domainTrie = rejectOutput.domainTrie; + rejectOutputAdGuardHome.domainTrie = rejectDomainsetOutput.domainTrie; await rejectOutputAdGuardHome // .addFromRuleset(readLocalMyRejectRulesetPromise) diff --git a/Build/lib/parse-filter/filters.ts b/Build/lib/parse-filter/filters.ts index decfd3c3..b4f39bb3 100644 --- a/Build/lib/parse-filter/filters.ts +++ b/Build/lib/parse-filter/filters.ts @@ -15,6 +15,9 @@ const enum ParseType { BlackIncludeSubdomain = 2, ErrorMessage = 10, BlackIP = 20, + BlackWildcard = 30, + BlackKeyword = 40, + WhiteKeyword = 50, Null = 1000, NotParsed = 2000 } @@ -28,7 +31,19 @@ export function processFilterRulesWithPreload( ) { const downloadPromise = fetchAssets(filterRulesUrl, fallbackUrls); - return (span: Span) => span.traceChildAsync>(`process filter rules: ${filterRulesUrl}`, async (span) => { + return (span: Span) => span.traceChildAsync< + Record< + 'whiteDomains' + | 'whiteDomainSuffixes' + | 'blackDomains' + | 'blackDomainSuffixes' + | 'blackIPs' + | 'blackWildcard' + | 'whiteKeyword' + | 'blackKeyword', + string[] + > + >(`process filter rules: ${filterRulesUrl}`, async (span) => { const filterRules = await span.traceChildPromise('download', downloadPromise); const whiteDomains = new Set(); @@ -40,6 +55,10 @@ export function processFilterRulesWithPreload( const warningMessages: string[] = []; const blackIPs: string[] = []; + const blackWildcard = new Set(); + + const whiteKeyword = new Set(); + const blackKeyword = new Set(); const MUTABLE_PARSE_LINE_RESULT: [string, ParseType] = ['', ParseType.NotParsed]; /** @@ -83,6 +102,15 @@ export function processFilterRulesWithPreload( case ParseType.BlackIP: blackIPs.push(hostname); break; + case ParseType.BlackWildcard: + blackWildcard.add(hostname); + break; + case ParseType.BlackKeyword: + blackKeyword.add(hostname); + break; + case ParseType.WhiteKeyword: + whiteKeyword.add(hostname); + break; default: break; } @@ -113,7 +141,10 @@ export function processFilterRulesWithPreload( whiteDomainSuffixes: Array.from(whiteDomainSuffixes), blackDomains: Array.from(blackDomains), blackDomainSuffixes: Array.from(blackDomainSuffixes), - blackIPs + blackIPs, + blackWildcard: Array.from(blackWildcard), + whiteKeyword: Array.from(whiteKeyword), + blackKeyword: Array.from(blackKeyword) }; }); } @@ -482,6 +513,7 @@ export function parse($line: string, result: [string, ParseType], includeThirdPa } const parsed = tldts.parse(sliced, looseTldtsOpt); + const hostname = parsed.hostname; /** * We can exclude wildcard in TLD @@ -495,15 +527,21 @@ export function parse($line: string, result: [string, ParseType], includeThirdPa * * This also exclude non standard TLD like `.tor`, `.onion`, `.dn42`, etc. */ - if (!parsed.publicSuffix || !parsed.isIcann || !parsed.hostname || !parsed.domain) { + if (!parsed.publicSuffix || !parsed.isIcann || !hostname || !parsed.domain) { result[1] = ParseType.Null; return result; } // no wildcard, we can safely normalize it˝ - if (!parsed.hostname.includes('*')) { + if (!hostname.includes('*')) { + if (hostname.charCodeAt(0) === 45) { // 45 `-` + result[0] = hostname; + result[1] = white ? ParseType.WhiteKeyword : ParseType.BlackKeyword; + return result; + } + if (white) { - result[0] = parsed.hostname; + result[0] = hostname; result[1] = includeAllSubDomain ? ParseType.WhiteIncludeSubdomain : ParseType.WhiteAbsolute; return result; } @@ -522,14 +560,46 @@ export function parse($line: string, result: [string, ParseType], includeThirdPa } } - result[0] = parsed.hostname; + result[0] = hostname; result[1] = includeAllSubDomain ? ParseType.BlackIncludeSubdomain : ParseType.BlackAbsolute; return result; } - result[0] = `[parse-filter E0010] (${white ? 'white' : 'black'}) invalid domain: ${JSON.stringify({ - line, sliced, sliceStart, sliceEnd, parsed - })}`; - result[1] = ParseType.ErrorMessage; + // now we only have wildcard domain left + if (white) { + // we don't support wildcard in whitelist + // result[1] = ParseType.Null; + // return result; + result[0] = `[parse-filter E0021] wildcard whitelist not supported: ${JSON.stringify({ + line, sliced, sliceStart, sliceEnd, parsed + })}`; + result[1] = ParseType.ErrorMessage; + return result; + } + + for (let i = 0, len = hostname.length; i < len; i++) { + const char = hostname.charCodeAt(i); + + if ( + (char >= 97 && char <= 122) // 97-122 `a-z` + || char === 46 // 46 `.` + || char === 45 // 45 `-` + || (char >= 48 && char <= 57) // 48-57 `0-9` + || char === 42 // 42 `*` + || char === 95 // 95 `_` + // || (char >= 65 && char <= 90) // 65-90 `A-Z` + ) { + continue; + } + + result[0] = `[parse-filter E0020] (black) invalid wildcard domain: ${JSON.stringify({ + line, sliced, sliceStart, sliceEnd, parsed + })}`; + result[1] = ParseType.ErrorMessage; + return result; + } + + result[0] = hostname; + result[1] = ParseType.BlackWildcard; return result; } diff --git a/Build/lib/rules/base.ts b/Build/lib/rules/base.ts index 5d68dc50..9ec4d389 100644 --- a/Build/lib/rules/base.ts +++ b/Build/lib/rules/base.ts @@ -17,8 +17,12 @@ export class FileOutput { protected strategies: BaseWriteStrategy[] = []; public domainTrie = new HostnameSmolTrie(null); + public wildcardTrie: HostnameSmolTrie = new HostnameSmolTrie(null); + protected domainKeywords = new Set(); - protected domainWildcard = new Set(); + + private whitelistKeywords = new Set(); + protected userAgent = new Set(); protected processName = new Set(); protected processPath = new Set(); @@ -43,6 +47,12 @@ export class FileOutput { whitelistDomain = (domain: string) => { this.domainTrie.whitelist(domain); + this.wildcardTrie.whitelist(domain); + return this; + }; + + whitelistKeyword = (keyword: string) => { + this.whitelistKeywords.add(keyword); return this; }; @@ -112,6 +122,20 @@ export class FileOutput { return this; } + bulkAddDomainKeyword(keywords: string[]) { + for (let i = 0, len = keywords.length; i < len; i++) { + this.domainKeywords.add(keywords[i]); + } + return this; + } + + bulkAddDomainWildcard(domains: string[]) { + for (let i = 0, len = domains.length; i < len; i++) { + this.wildcardTrie.add(domains[i]); + } + return this; + } + addIPASN(asn: string) { this.ipasn.add(asn); return this; @@ -161,7 +185,7 @@ export class FileOutput { this.addDomainKeyword(value); break; case 'DOMAIN-WILDCARD': - this.domainWildcard.add(value); + this.wildcardTrie.add(value); break; case 'USER-AGENT': this.userAgent.add(value); @@ -318,7 +342,11 @@ export class FileOutput { this.strategiesWritten = true; - const kwfilter = createKeywordFilter(Array.from(this.domainKeywords)); + // We use both DOMAIN-KEYWORD and whitelisted keyword to whitelist DOMAIN and DOMAIN-SUFFIX + const kwfilter = createKeywordFilter( + Array.from(this.domainKeywords) + .concat(Array.from(this.whitelistKeywords)) + ); if (this.strategies.filter(not(false)).length === 0) { throw new Error('No strategies to write ' + this.id); @@ -330,6 +358,8 @@ export class FileOutput { return; } + this.wildcardTrie.whitelist(domain, includeAllSubdomain); + for (let i = 0; i < strategiesLen; i++) { const strategy = this.strategies[i]; if (includeAllSubdomain) { @@ -340,14 +370,27 @@ export class FileOutput { } }, true); - for (let i = 0, len = this.strategies.length; i < len; i++) { + // Now, we whitelisted out DOMAIN-KEYWORD + const whiteKwfilter = createKeywordFilter(Array.from(this.whitelistKeywords)); + const whitelistedKeywords = Array.from(this.domainKeywords).filter(kw => !whiteKwfilter(kw)); + + this.wildcardTrie.dumpWithoutDot((wildcard) => { + if (kwfilter(wildcard)) { + return; + } + + for (let i = 0; i < strategiesLen; i++) { + const strategy = this.strategies[i]; + strategy.writeDomainWildcard(wildcard); + } + }); + + for (let i = 0; i < strategiesLen; i++) { const strategy = this.strategies[i]; - if (this.domainKeywords.size) { + if (whitelistedKeywords.length) { strategy.writeDomainKeywords(this.domainKeywords); } - if (this.domainWildcard.size) { - strategy.writeDomainWildcards(this.domainWildcard); - } + if (this.protocol.size) { strategy.writeProtocols(this.protocol); } diff --git a/Build/lib/writing-strategy/adguardhome.ts b/Build/lib/writing-strategy/adguardhome.ts index 37792ee2..fed4fa11 100644 --- a/Build/lib/writing-strategy/adguardhome.ts +++ b/Build/lib/writing-strategy/adguardhome.ts @@ -52,14 +52,12 @@ export class AdGuardHome extends BaseWriteStrategy { } } - writeDomainWildcards(wildcards: Set): void { - for (const wildcard of wildcards) { - const processed = wildcard.replaceAll('?', '*'); - if (processed.startsWith('*.')) { - this.result.push(`||${processed.slice(2)}^`); - } else { - this.result.push(`|${processed}^`); - } + writeDomainWildcard(wildcard: string): void { + const processed = wildcard.replaceAll('?', '*'); + if (processed.startsWith('*.')) { + this.result.push(`||${processed.slice(2)}^`); + } else { + this.result.push(`|${processed}^`); } } diff --git a/Build/lib/writing-strategy/base.ts b/Build/lib/writing-strategy/base.ts index 98a67f21..a2c61f5c 100644 --- a/Build/lib/writing-strategy/base.ts +++ b/Build/lib/writing-strategy/base.ts @@ -30,7 +30,7 @@ export abstract class BaseWriteStrategy { abstract writeDomain(domain: string): void; abstract writeDomainSuffix(domain: string): void; abstract writeDomainKeywords(keyword: Set): void; - abstract writeDomainWildcards(wildcard: Set): void; + abstract writeDomainWildcard(wildcard: string): void; abstract writeUserAgents(userAgent: Set): void; abstract writeProcessNames(processName: Set): void; abstract writeProcessPaths(processPath: Set): void; diff --git a/Build/lib/writing-strategy/clash.ts b/Build/lib/writing-strategy/clash.ts index 569b8aad..339b1937 100644 --- a/Build/lib/writing-strategy/clash.ts +++ b/Build/lib/writing-strategy/clash.ts @@ -30,7 +30,7 @@ export class ClashDomainSet extends BaseWriteStrategy { } writeDomainKeywords = noop; - writeDomainWildcards = noop; + writeDomainWildcard = noop; writeUserAgents = noop; writeProcessNames = noop; writeProcessPaths = noop; @@ -64,7 +64,7 @@ export class ClashIPSet extends BaseWriteStrategy { writeDomain = notSupported('writeDomain'); writeDomainSuffix = notSupported('writeDomainSuffix'); writeDomainKeywords = notSupported('writeDomainKeywords'); - writeDomainWildcards = notSupported('writeDomainWildcards'); + writeDomainWildcard = notSupported('writeDomainWildcards'); writeUserAgents = notSupported('writeUserAgents'); writeProcessNames = notSupported('writeProcessNames'); writeProcessPaths = notSupported('writeProcessPaths'); @@ -111,8 +111,8 @@ export class ClashClassicRuleSet extends BaseWriteStrategy { appendSetElementsToArray(this.result, keyword, i => `DOMAIN-KEYWORD,${i}`); } - writeDomainWildcards(wildcard: Set): void { - appendSetElementsToArray(this.result, wildcard, i => `DOMAIN-REGEX,${ClashClassicRuleSet.domainWildCardToRegex(i)}`); + writeDomainWildcard(wildcard: string): void { + this.result.push(`DOMAIN-REGEX,${ClashClassicRuleSet.domainWildCardToRegex(wildcard)}`); } writeUserAgents = noop; diff --git a/Build/lib/writing-strategy/legacy-clash-premium.ts b/Build/lib/writing-strategy/legacy-clash-premium.ts index ac2a5ee9..3ef9d2a6 100644 --- a/Build/lib/writing-strategy/legacy-clash-premium.ts +++ b/Build/lib/writing-strategy/legacy-clash-premium.ts @@ -14,6 +14,6 @@ export class LegacyClashPremiumClassicRuleSet extends ClashClassicRuleSet { super(type, outputDir); } - override writeDomainWildcards = noop; + override writeDomainWildcard = noop; override writeIpAsns = noop; } diff --git a/Build/lib/writing-strategy/singbox.ts b/Build/lib/writing-strategy/singbox.ts index 60a6a860..e3b9b7ef 100644 --- a/Build/lib/writing-strategy/singbox.ts +++ b/Build/lib/writing-strategy/singbox.ts @@ -71,11 +71,9 @@ export class SingboxSource extends BaseWriteStrategy { ); } - writeDomainWildcards(wildcard: Set): void { - appendArrayInPlace( - this.singbox.domain_regex ??= [], - Array.from(wildcard, SingboxSource.domainWildCardToRegex) - ); + writeDomainWildcard(wildcard: string): void { + this.singbox.domain_regex ??= []; + this.singbox.domain_regex.push(SingboxSource.domainWildCardToRegex(wildcard)); } writeUserAgents = noop; diff --git a/Build/lib/writing-strategy/surfboard.ts b/Build/lib/writing-strategy/surfboard.ts index aace48f3..c3f27a18 100644 --- a/Build/lib/writing-strategy/surfboard.ts +++ b/Build/lib/writing-strategy/surfboard.ts @@ -12,7 +12,7 @@ export class SurfboardRuleSet extends SurgeRuleSet { super(type, outputDir); } - override writeDomainWildcards = noop; + override writeDomainWildcard = noop; override writeUserAgents = noop; override writeUrlRegexes = noop; override writeIpAsns = noop; diff --git a/Build/lib/writing-strategy/surge.ts b/Build/lib/writing-strategy/surge.ts index 109a2347..04051754 100644 --- a/Build/lib/writing-strategy/surge.ts +++ b/Build/lib/writing-strategy/surge.ts @@ -33,7 +33,7 @@ export class SurgeDomainSet extends BaseWriteStrategy { } writeDomainKeywords = noop; - writeDomainWildcards = noop; + writeDomainWildcard = noop; writeUserAgents = noop; writeProcessNames = noop; writeProcessPaths = noop; @@ -78,8 +78,8 @@ export class SurgeRuleSet extends BaseWriteStrategy { appendSetElementsToArray(this.result, keyword, i => `DOMAIN-KEYWORD,${i}`); } - writeDomainWildcards(wildcard: Set): void { - appendSetElementsToArray(this.result, wildcard, i => `DOMAIN-WILDCARD,${i}`); + writeDomainWildcard(wildcard: string): void { + this.result.push(`DOMAIN-WILDCARD,${wildcard}`); } writeUserAgents(userAgent: Set): void { @@ -176,7 +176,7 @@ export class SurgeMitmSgmodule extends BaseWriteStrategy { writeDomainSuffix = noop; writeDomainKeywords = noop; - writeDomainWildcards = noop; + writeDomainWildcard = noop; writeUserAgents = noop; writeProcessNames = noop; writeProcessPaths = noop; diff --git a/Source/non_ip/reject.conf b/Source/non_ip/reject.conf index 8e9115ef..546daadf 100644 --- a/Source/non_ip/reject.conf +++ b/Source/non_ip/reject.conf @@ -1,5 +1,5 @@ -# $ meta_title Sukka's Ruleset - Reject Domains -# $ meta_description The ruleset supports AD blocking, tracking protection, privacy protection, anti-phishing, anti-mining +# Sukka's Ruleset - Reject Domains +# $ custom_build_script # $ skip_dedupe_src enforce some blocking to reduce file size DOMAIN,this_rule_set_is_made_by_sukkaw.skk.moe