forked from REIJI007/AdBlock_Rule_For_Clash
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathadblock_rule_generator_yaml.ps1
153 lines (135 loc) · 6.29 KB
/
adblock_rule_generator_yaml.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# Title: AdBlock_Rule_For_Clash
# Description: 适用于Clash的域名拦截规则集,每20分钟更新一次,确保即时同步上游减少误杀
# Homepage: https://github.com/REIJI007/AdBlock_Rule_For_Clash
# LICENSE1: https://github.com/REIJI007/AdBlock_Rule_For_Clash/blob/main/LICENSE-GPL 3.0
# LICENSE2: https://github.com/REIJI007/AdBlock_Rule_For_Clash/blob/main/LICENSE-CC-BY-NC-SA 4.0
# 定义广告过滤器URL列表
$urlList = @(
"https://raw.githubusercontent.com/hagezi/dns-blocklists/main/adblock/ultimate.txt",
"https://raw.githubusercontent.com/Cats-Team/AdRules/main/adblock_plus.txt",
"https://raw.githubusercontent.com/TG-Twilight/AWAvenue-Ads-Rule/main/AWAvenue-Ads-Rule.txt",
"https://big.oisd.nl"
)
# 日志文件路径
$logFilePath = "$PSScriptRoot/adblock_log.txt"
# 创建两个HashSet来存储唯一的规则和排除的域名
$uniqueRules = [System.Collections.Generic.HashSet[string]]::new()
$excludedDomains = [System.Collections.Generic.HashSet[string]]::new()
# 创建WebClient对象用于下载规则
$webClient = New-Object System.Net.WebClient
$webClient.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
# DNS规范验证函数
function Is-ValidDNSDomain($domain) {
if ($domain.Length -gt 253) { return $false }
$labels = $domain -split "\."
foreach ($label in $labels) {
if ($label.Length -eq 0 -or $label.Length -gt 63) { return $false }
if ($label -notmatch "^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$") {
return $false
}
}
$tld = $labels[-1]
if ($tld -notmatch "^[a-zA-Z]{2,}$") { return $false }
return $true
}
foreach ($url in $urlList) {
Write-Host "正在处理: $url"
Add-Content -Path $logFilePath -Value "正在处理: $url"
try {
# 读取并拆分内容为行
$content = $webClient.DownloadString($url)
$lines = $content -split "`n"
foreach ($line in $lines) {
# 直接处理以 @@ 开头的规则,提取域名并加入白名单
if ($line.StartsWith('@@')) {
$domains = $line -replace '^@@', '' -split '[^\w.-]+'
foreach ($domain in $domains) {
if (-not [string]::IsNullOrWhiteSpace($domain) -and $domain -match '[\w-]+(\.[[\w-]+)+') {
$excludedDomains.Add($domain.Trim()) | Out-Null
}
}
}
else {
# 匹配 Adblock/Easylist 格式的规则
if ($line -match '^\|\|([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})\^$') {
$domain = $Matches[1]
$uniqueRules.Add($domain) | Out-Null
}
# 匹配 Hosts 文件格式的 IPv4 规则
elseif ($line -match '^(0\.0\.0\.0|127\.0\.0\.1)\s+([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$') {
$domain = $Matches[2]
$uniqueRules.Add($domain) | Out-Null
}
# 匹配 Hosts 文件格式的 IPv6 规则(以 ::1 或 :: 开头)
elseif ($line -match '^::(1)?\s+([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$') {
$domain = $Matches[2]
$uniqueRules.Add($domain) | Out-Null
}
# 匹配 Dnsmasq address=/域名/格式的规则
elseif ($line -match '^address=/([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/$') {
$domain = $Matches[1]
$uniqueRules.Add($domain) | Out-Null
}
# 匹配 Dnsmasq server=/域名/的规则
elseif ($line -match '^server=/([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/$') {
$domain = $Matches[1]
$uniqueRules.Add($domain) | Out-Null
}
# 匹配通配符规则
elseif ($line -match '^\|\|([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})\^$') {
$domain = $Matches[1]
$uniqueRules.Add($domain) | Out-Null
}
# 处理纯域名行
elseif ($line -match '^([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$') {
$domain = $Matches[1]
$uniqueRules.Add($domain) | Out-Null
}
}
}
}
catch {
Write-Host "处理 $url 时出错: $_"
Add-Content -Path $logFilePath -Value "处理 $url 时出错: $_"
}
}
# 在写入文件之前进行DNS规范验证
$validRules = [System.Collections.Generic.HashSet[string]]::new()
$validExcludedDomains = [System.Collections.Generic.HashSet[string]]::new()
foreach ($domain in $uniqueRules) {
if (Is-ValidDNSDomain($domain)) {
$validRules.Add($domain) | Out-Null
}
}
foreach ($domain in $excludedDomains) {
if (Is-ValidDNSDomain($domain)) {
$validExcludedDomains.Add($domain) | Out-Null
}
}
# 排除所有白名单规则中的域名
$finalRules = $validRules | Where-Object { -not $validExcludedDomains.Contains($_) }
# 对规则进行排序并格式化
$formattedRules = $finalRules | Sort-Object | ForEach-Object {"- '$_'"}
# 统计生成的规则条目数量
$ruleCount = $finalRules.Count
# 获取当前时间并转换为东八区时间
$generationTime = (Get-Date).ToUniversalTime().AddHours(8).ToString("yyyy-MM-dd HH:mm:ss")
# 创建文本格式的字符串
$textContent = @"
# Title: AdBlock_Rule_For_Clash
# Description: 适用于Clash的域名拦截规则集,每20分钟更新一次,确保即时同步上游减少误杀
# Homepage: https://github.com/REIJI007/AdBlock_Rule_For_Clash
# LICENSE1: https://github.com/REIJI007/AdBlock_Rule_For_Clash/blob/main/LICENSE-GPL 3.0
# LICENSE2: https://github.com/REIJI007/AdBlock_Rule_For_Clash/blob/main/LICENSE-CC-BY-NC-SA 4.0
# Generated on: $generationTime
# Generated AdBlock rules
# Total entries: $ruleCount
payload:
$($formattedRules -join "`n")
"@
# 定义输出文件路径
$outputPath = "$PSScriptRoot/adblock_reject.yaml"
$textContent | Out-File -FilePath $outputPath -Encoding utf8
# 输出生成的有效规则总数
Write-Host "生成的有效规则总数: $ruleCount"
Add-Content -Path $logFilePath -Value "Total entries: $ruleCount"