Skip to content

Update ALL.txt

Update ALL.txt #38

name: Process WireGuard Configs
on:
push:
paths:
- 'ALL.txt'
workflow_dispatch:
jobs:
process-configs:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install PyYAML
run: pip install pyyaml
- name: Deduplicate, sort, generate Clash configs and WireGuard conf files
shell: python
run: |
import re, os, yaml, zipfile, tempfile, base64
from urllib.parse import unquote
INPUT_FILE = "ALL.txt"
OUTPUT_FILE = "ALL.yaml"
ZIP_FILE = "wireguard_configs.zip"
BASE_CONFIG = {
"name": "Standard",
"mixed-port": 7890,
"socks-port": 7891,
"port": 7892,
"allow-lan": True,
"bind-address": "*",
"mode": "global",
"log-level": "info",
"ipv6": True,
"external-controller": "127.0.0.1:9090",
"external-ui": "ui",
"secret": "",
"unified-delay": True,
"tcp-concurrent": True,
"global-client-fingerprint": "chrome",
"find-process-mode": "strict",
"keep-alive-interval": 15,
"profile": {
"store-selected": True,
"store-fake-ip": False
},
"dns": {
"enable": True,
"ipv6": True,
"listen": "0.0.0.0:5353",
"enhanced-mode": "fake-ip",
"fake-ip-range": "198.18.0.1/16",
"fake-ip-filter": [
"*.local",
"*.lan",
"*.localhost",
"+.stun.*.*",
"+.stun.*.*.*",
"time.*",
"time.*.com",
"connectivitycheck.gstatic.com",
"detectportal.firefox.com",
"captive.apple.com",
"www.msftncsi.com",
"cp.cloudflare.com"
],
"default-nameserver": [
"1.1.1.1", "1.0.0.1", "8.8.8.8", "8.8.4.4",
"9.9.9.9", "149.112.112.112",
"208.67.222.222", "208.67.220.220",
"94.140.14.14", "94.140.15.15",
"64.6.64.6", "64.6.65.6",
"84.200.69.80", "84.200.70.40",
"76.76.19.19", "76.223.122.150",
"8.26.56.26", "8.20.247.20"
],
"nameserver": [
"https://cloudflare-dns.com/dns-query",
"https://1.1.1.1/dns-query",
"https://1.0.0.1/dns-query",
"https://dns.google/dns-query",
"https://8.8.8.8/dns-query",
"https://8.8.4.4/dns-query",
"https://dns.quad9.net/dns-query",
"https://9.9.9.9/dns-query",
"https://149.112.112.112/dns-query",
"https://dns.adguard.com/dns-query",
"https://94.140.14.14/dns-query",
"https://94.140.15.15/dns-query",
"https://doh.opendns.com/dns-query",
"https://208.67.222.222/dns-query",
"https://208.67.220.220/dns-query",
"https://doh.comodo.com/dns-query",
"https://8.26.56.26/dns-query",
"https://8.20.247.20/dns-query",
"https://doh.mullvad.net/dns-query",
"https://doh.dns.mullvad.net/dns-query",
"https://freedns.controld.com/p0",
"https://freedns.controld.com/family",
"tls://1.1.1.1:853", "tls://1.0.0.1:853",
"tls://8.8.8.8:853", "tls://8.8.4.4:853",
"tls://9.9.9.9:853", "tls://149.112.112.112:853",
"tls://94.140.14.14:853", "tls://94.140.15.15:853",
"tls://208.67.222.222:853", "tls://208.67.220.220:853",
"tls://family-filter-dns.cleanbrowsing.org:853",
"tls://adult-filter-dns.cleanbrowsing.org:853",
"tls://security-filter-dns.cleanbrowsing.org:853",
"1.1.1.1", "1.0.0.1", "8.8.8.8", "8.8.4.4",
"9.9.9.9", "149.112.112.112",
"208.67.222.222", "208.67.220.220",
"94.140.14.14", "94.140.15.15",
"64.6.64.6", "64.6.65.6",
"84.200.69.80", "84.200.70.40",
"8.26.56.26", "8.20.247.20",
"76.76.19.19", "76.223.122.150",
"208.67.222.123", "208.67.220.123",
"195.46.39.39", "195.46.39.40",
"38.132.106.139", "194.187.251.67"
]
},
"proxies": [],
"proxy-groups": [
{
"name": "PROXY",
"type": "select",
"proxies": ["Fallback", "Auto", "Load Balance"]
},
{
"name": "Load Balance",
"type": "load-balance",
"strategy": "consistent-hashing",
"url": "http://www.gstatic.com/generate_204",
"interval": 60,
"tolerance": 50,
"lazy": True,
"proxies": []
},
{
"name": "Auto",
"type": "url-test",
"url": "http://www.gstatic.com/generate_204",
"interval": 60,
"tolerance": 50,
"lazy": True,
"proxies": []
},
{
"name": "Fallback",
"type": "fallback",
"url": "http://www.gstatic.com/generate_204",
"interval": 60,
"lazy": True,
"proxies": []
}
],
"rules": ["MATCH,PROXY"]
}
def decode_base64_key(key):
key = key.strip()
padding = 4 - len(key) % 4
if padding != 4:
key += '=' * padding
try:
decoded = base64.b64decode(key)
return base64.b64encode(decoded).decode('ascii')
except:
return key
def parse_wireguard_config(line):
decoded = unquote(line)
match = re.match(r'wireguard://([^@]+)@([^:]+):(\d+)\?(.+?)(?:#(.+))?$', decoded)
if not match:
return None
private_key = decode_base64_key(match.group(1))
address = match.group(2)
port = int(match.group(3))
params = match.group(4)
params_dict = {}
for param in params.split('&'):
if '=' in param:
key, value = param.split('=', 1)
params_dict[key] = value
public_key = decode_base64_key(params_dict.get('publickey', ''))
preshared_key = decode_base64_key(params_dict.get('presharedkey', ''))
addresses_raw = params_dict.get('address', '')
addresses = []
for addr in addresses_raw.split(','):
addr = addr.strip()
if addr:
addresses.append(addr)
reserved_raw = params_dict.get('reserved', '0,0,0')
reserved = []
for r in reserved_raw.split(','):
r = r.strip()
if r:
reserved.append(int(r))
return {
'private_key': private_key,
'address': address,
'port': port,
'public_key': public_key,
'preshared_key': preshared_key,
'addresses': addresses,
'reserved': reserved,
'endpoint': f"{address}:{port}"
}
def generate_proxy_name(endpoint, index):
safe_name = re.sub(r'[^a-zA-Z0-9\-]', '-', endpoint)
return f"WG-{safe_name}-{index}"
def generate_conf_content(config):
conf = f"""[Interface]
PrivateKey = {config['private_key']}
Address = {', '.join(config['addresses'])}
DNS = 1.1.1.1, 1.0.0.1, 2606:4700:4700::1111, 2606:4700:4700::1001
MTU = 1420
Jc = 6
Jmin = 10
Jmax = 50
S1 = 0
S2 = 0
S3 = 14
I1 = <r 2><b 0x858000010001000000000669636c6f756403636f6d0000010001c00c000100010000105a00044d583737>
H1 = 1
H2 = 2
H3 = 3
H4 = 4
[Peer]
PublicKey = {config['public_key']}
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = {config['endpoint']}
PersistentKeepalive = 10
"""
if config['preshared_key']:
conf = conf.replace('[Peer]\n', f'[Peer]\nPresharedKey = {config["preshared_key"]}\n')
return conf.strip() + '\n'
def write_yaml(config, filepath):
class CustomDumper(yaml.Dumper):
def increase_indent(self, flow=False, indentless=False):
return super(CustomDumper, self).increase_indent(flow, False)
with open(filepath, 'w', encoding='utf-8') as f:
yaml.dump(config, f, Dumper=CustomDumper,
default_flow_style=False,
allow_unicode=True,
sort_keys=False,
indent=2)
if not os.path.exists(INPUT_FILE):
print(f"File {INPUT_FILE} not found!")
exit(1)
seen_endpoints = set()
parsed_configs = []
with open(INPUT_FILE, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if not line.startswith("wireguard://"):
continue
match = re.search(r'@([^?#]+)', line)
if not match:
continue
endpoint = match.group(1)
if endpoint not in seen_endpoints:
seen_endpoints.add(endpoint)
config = parse_wireguard_config(line)
if config:
parsed_configs.append(config)
if parsed_configs:
parsed_configs.sort(key=lambda x: x['endpoint'])
with open(INPUT_FILE, 'w', encoding='utf-8') as f:
for config in parsed_configs:
f.write(f"wireguard://{config['private_key']}@{config['endpoint']}?publickey={config['public_key']}&address={','.join(config['addresses'])}&mtu=1420\n")
print(f"{INPUT_FILE}: {len(parsed_configs)} unique configs written")
proxies = []
proxy_names = []
with tempfile.TemporaryDirectory() as tmpdir:
for idx, config in enumerate(parsed_configs, 1):
conf_name = f"@DeltaKroneckerGithub ({idx}).conf"
conf_path = os.path.join(tmpdir, conf_name)
conf_content = generate_conf_content(config)
with open(conf_path, 'w', encoding='utf-8') as f:
f.write(conf_content)
proxy_name = generate_proxy_name(config['endpoint'], idx)
proxy_names.append(proxy_name)
proxy = {
'name': proxy_name,
'type': 'wireguard',
'server': config['address'],
'port': config['port'],
'private-key': config['private_key'],
'public-key': config['public_key'],
'mtu': 1420,
'udp': True,
'reserved': config['reserved'],
'workers': 4,
'persistent-keepalive': 10
}
if config['addresses']:
for addr in config['addresses']:
addr_clean = addr.strip().split('/')[0] if '/' in addr else addr.strip()
if ':' in addr_clean:
proxy['ipv6'] = addr_clean
else:
proxy['ip'] = addr_clean
proxies.append(proxy)
if os.path.exists(ZIP_FILE):
os.remove(ZIP_FILE)
with zipfile.ZipFile(ZIP_FILE, 'w', zipfile.ZIP_DEFLATED) as zipf:
for i in range(1, len(parsed_configs) + 1):
conf_file = f"@DeltaKroneckerGithub ({i}).conf"
conf_path = os.path.join(tmpdir, conf_file)
if os.path.exists(conf_path):
zipf.write(conf_path, conf_file)
output_config = BASE_CONFIG.copy()
output_config['proxies'] = proxies
for group in output_config['proxy-groups']:
if group['name'] in ['Load Balance', 'Auto', 'Fallback']:
group['proxies'] = proxy_names.copy()
write_yaml(output_config, OUTPUT_FILE)
print(f"Generated {OUTPUT_FILE} with {len(proxies)} WireGuard proxies")
print(f"Generated {ZIP_FILE} with {len(parsed_configs)} WireGuard config files")
- name: Commit and push changes
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
git diff --staged --quiet || git commit -m "Deduplicate, sort, generate Clash config and WireGuard conf files"
git push