├── sub ├── shadowrocket.txt ├── shadowrocket_base64.txt ├── merged_proxies.yaml ├── merged_proxies_new.yaml ├── merged_warp_proxies.yaml └── merged_warp_proxies_new.yaml ├── requirements.txt ├── urls ├── sb_urls.txt ├── ss_urls.txt ├── naiverproxy_urls.txt ├── xray_urls.txt ├── hysteria_urls.txt ├── hysteria2_urls.txt ├── clash_urls.txt └── clash_new_urls.txt ├── ReadMe.md ├── .github └── workflows │ └── merge.yml ├── templates ├── clash_template.yaml └── clash_warp_template.yaml ├── meta_merge.py └── merge.py /sub/shadowrocket.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sub/shadowrocket_base64.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | PyYAML==6.0.1 2 | -------------------------------------------------------------------------------- /urls/sb_urls.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/Alvin9999/pac2/master/singbox/1/config.json 2 | https://raw.githubusercontent.com/Alvin9999/pac2/master/singbox/config.json -------------------------------------------------------------------------------- /urls/ss_urls.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/Alvin9999/pac2/master/ssr-wj/ssconfig.txt 2 | https://raw.githubusercontent.com/Alvin9999/pac2/master/ssr-wj/1/ssconfig.txt -------------------------------------------------------------------------------- /urls/naiverproxy_urls.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/Alvin9999/PAC/master/naiveproxy/1/config.json 2 | https://raw.githubusercontent.com/Alvin9999/PAC/master/naiveproxy/config.json -------------------------------------------------------------------------------- /urls/xray_urls.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/Alvin9999/pac2/master/xray/1/config.json 2 | https://raw.githubusercontent.com/Alvin9999/pac2/master/xray/2/config.json 3 | https://raw.githubusercontent.com/Alvin9999/pac2/master/xray/3/config.json 4 | https://raw.githubusercontent.com/Alvin9999/pac2/master/xray/config.json -------------------------------------------------------------------------------- /urls/hysteria_urls.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/Alvin9999/pac2/master/hysteria/1/config.json 2 | https://raw.githubusercontent.com/Alvin9999/pac2/master/hysteria/13/config.json 3 | https://raw.githubusercontent.com/Alvin9999/pac2/master/hysteria/2/config.json 4 | https://raw.githubusercontent.com/Alvin9999/pac2/master/hysteria/config.json -------------------------------------------------------------------------------- /urls/hysteria2_urls.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/Alvin9999/pac2/master/hysteria2/config.json 2 | https://raw.githubusercontent.com/Alvin9999/pac2/master/hysteria2/1/config.json 3 | https://raw.githubusercontent.com/Alvin9999/pac2/master/hysteria2/2/config.json 4 | https://raw.githubusercontent.com/Alvin9999/pac2/master/hysteria2/13/config.json -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | **不含hysteria2节点** 7 | ``` 8 | https://raw.githubusercontent.com/nolevo/meta/main/sub/merged_proxies.yaml 9 | ``` 10 | **含hysteria2节点** 11 | ``` 12 | https://raw.githubusercontent.com/nolevo/meta/main/sub/merged_proxies_new.yaml 13 | ``` 14 | 15 | **通用链接 shadowrocket-nekoray** 16 | 17 | ``` 18 | https://raw.githubusercontent.com/nolevo/meta/main/sub/shadowrocket.txt 19 | ``` 20 | 21 | 22 | ## 致谢 23 | [Alvin9999](https://github.com/Alvin9999/pac2/tree/master) 24 | 25 | -------------------------------------------------------------------------------- /urls/clash_urls.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta/1/config.yaml 2 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta/config.yaml 3 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta/13/config.yaml 4 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta/15/config.yaml 5 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta/2/config.yaml 6 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta/3/config.yaml 7 | https://raw.githubusercontent.com/Alvin9999/pac2/master/quick/4/config.yaml 8 | https://raw.githubusercontent.com/Alvin9999/pac2/master/quick/3/config.yaml 9 | https://raw.githubusercontent.com/Alvin9999/pac2/master/quick/1/config.yaml 10 | https://raw.githubusercontent.com/Alvin9999/pac2/master/quick/config.yaml 11 | -------------------------------------------------------------------------------- /.github/workflows/merge.yml: -------------------------------------------------------------------------------- 1 | name: Merge Script 2 | 3 | on: 4 | push: 5 | branches: 6 | - main # 替换为你的默认分支 7 | schedule: 8 | - cron: '0 0,8,18 * * *' # 每6h一次 9 | workflow_dispatch: # 触发手动事件 10 | jobs: 11 | merge: 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: Checkout repository 16 | uses: actions/checkout@v2 17 | 18 | - name: Set up Python 19 | uses: actions/setup-python@v2 20 | with: 21 | python-version: 3.11 # 替换为你的 Python 版本 22 | 23 | - name: Install dependencies 24 | run: pip install -r requirements.txt 25 | 26 | - name: Run merge script 27 | run: python meta_merge.py # 替换为你的 merge.py 脚本名称 28 | 29 | - name: Run shadowrocket merge script 30 | run: python merge.py # 替换为你的 merge.py 脚本名称 31 | - name: Commit Changes 32 | run: | 33 | git config core.ignorecase false 34 | git config --local user.email "vvv123456789123@gmail.com" 35 | git config --local user.name "vvv" 36 | git add . 37 | git commit -m "Updated at $(date '+%Y-%m-%d %H:%M:%S')" 38 | git push 39 | -------------------------------------------------------------------------------- /sub/merged_proxies.yaml: -------------------------------------------------------------------------------- 1 | port: 7890 2 | allow-lan: true 3 | mode: rule 4 | log-level: info 5 | unified-delay: true 6 | global-client-fingerprint: chrome 7 | dns: 8 | enable: true 9 | listen: :53 10 | ipv6: true 11 | enhanced-mode: fake-ip 12 | fake-ip-range: 198.18.0.1/16 13 | default-nameserver: 14 | - 223.5.5.5 15 | - 8.8.8.8 16 | nameserver: 17 | - https://dns.alidns.com/dns-query 18 | - https://doh.pub/dns-query 19 | fallback: 20 | - https://1.0.0.1/dns-query 21 | - tls://dns.google 22 | fallback-filter: 23 | geoip: true 24 | geoip-code: CN 25 | ipcidr: 26 | - 240.0.0.0/4 27 | proxies: 28 | - name: '111' 29 | type: trojan 30 | server: 127.0.0.1 31 | port: 9090 32 | password: 72ac875a-f5b9-461e-a7a4-942b468b0d83 33 | udp: true 34 | sni: gw.alicdn.com 35 | skip-cert-verify: true 36 | proxy-groups: 37 | - name: 节点选择 38 | type: select 39 | proxies: 40 | - 自动选择 41 | - DIRECT 42 | - 111 43 | - name: 自动选择 44 | type: url-test 45 | url: http://www.gstatic.com/generate_204 46 | interval: 300 47 | tolerance: 50 48 | proxies: 49 | - 111 50 | rules: 51 | - DOMAIN,clash.razord.top,DIRECT 52 | - DOMAIN,yacd.haishan.me,DIRECT 53 | - GEOIP,LAN,DIRECT 54 | - GEOIP,CN,DIRECT 55 | - MATCH,节点选择 56 | -------------------------------------------------------------------------------- /sub/merged_proxies_new.yaml: -------------------------------------------------------------------------------- 1 | port: 7890 2 | allow-lan: true 3 | mode: rule 4 | log-level: info 5 | unified-delay: true 6 | global-client-fingerprint: chrome 7 | dns: 8 | enable: true 9 | listen: :53 10 | ipv6: true 11 | enhanced-mode: fake-ip 12 | fake-ip-range: 198.18.0.1/16 13 | default-nameserver: 14 | - 223.5.5.5 15 | - 8.8.8.8 16 | nameserver: 17 | - https://dns.alidns.com/dns-query 18 | - https://doh.pub/dns-query 19 | fallback: 20 | - https://1.0.0.1/dns-query 21 | - tls://dns.google 22 | fallback-filter: 23 | geoip: true 24 | geoip-code: CN 25 | ipcidr: 26 | - 240.0.0.0/4 27 | proxies: 28 | - name: '111' 29 | type: trojan 30 | server: 127.0.0.1 31 | port: 9090 32 | password: 72ac875a-f5b9-461e-a7a4-942b468b0d83 33 | udp: true 34 | sni: gw.alicdn.com 35 | skip-cert-verify: true 36 | proxy-groups: 37 | - name: 节点选择 38 | type: select 39 | proxies: 40 | - 自动选择 41 | - DIRECT 42 | - 111 43 | - name: 自动选择 44 | type: url-test 45 | url: http://www.gstatic.com/generate_204 46 | interval: 300 47 | tolerance: 50 48 | proxies: 49 | - 111 50 | rules: 51 | - DOMAIN,clash.razord.top,DIRECT 52 | - DOMAIN,yacd.haishan.me,DIRECT 53 | - GEOIP,LAN,DIRECT 54 | - GEOIP,CN,DIRECT 55 | - MATCH,节点选择 56 | -------------------------------------------------------------------------------- /templates/clash_template.yaml: -------------------------------------------------------------------------------- 1 | port: 7890 2 | allow-lan: true 3 | mode: rule 4 | log-level: info 5 | unified-delay: true 6 | global-client-fingerprint: chrome 7 | dns: 8 | enable: true 9 | listen: :53 10 | ipv6: true 11 | enhanced-mode: fake-ip 12 | fake-ip-range: 198.18.0.1/16 13 | default-nameserver: 14 | - 223.5.5.5 15 | - 8.8.8.8 16 | nameserver: 17 | - https://dns.alidns.com/dns-query 18 | - https://doh.pub/dns-query 19 | fallback: 20 | - https://1.0.0.1/dns-query 21 | - tls://dns.google 22 | fallback-filter: 23 | geoip: true 24 | geoip-code: CN 25 | ipcidr: 26 | - 240.0.0.0/4 27 | proxies: 28 | - { name: '111', type: trojan, server: 127.0.0.1, port: 9090, password: 72ac875a-f5b9-461e-a7a4-942b468b0d83, udp: true, sni: gw.alicdn.com, skip-cert-verify: true } 29 | proxy-groups: 30 | - name: 节点选择 31 | type: select 32 | proxies: 33 | - 自动选择 34 | - DIRECT 35 | - 111 36 | 37 | - name: 自动选择 38 | type: url-test 39 | url: http://www.gstatic.com/generate_204 40 | interval: 300 41 | tolerance: 50 42 | proxies: 43 | - 111 44 | 45 | rules: 46 | - DOMAIN,clash.razord.top,DIRECT 47 | - DOMAIN,yacd.haishan.me,DIRECT 48 | - GEOIP,LAN,DIRECT 49 | - GEOIP,CN,DIRECT 50 | - MATCH,节点选择 51 | -------------------------------------------------------------------------------- /urls/clash_new_urls.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta2/1/config.yaml 2 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta2/config.yaml 3 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta2/13/config.yaml 4 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta2/15/config.yaml 5 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta2/2/config.yaml 6 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta2/3/config.yaml 7 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta/1/config.yaml 8 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta/config.yaml 9 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta/13/config.yaml 10 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta/15/config.yaml 11 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta/2/config.yaml 12 | https://raw.githubusercontent.com/Alvin9999/pac2/master/clash.meta/3/config.yaml 13 | https://raw.githubusercontent.com/Alvin9999/pac2/master/quick/4/config.yaml 14 | https://raw.githubusercontent.com/Alvin9999/pac2/master/quick/3/config.yaml 15 | https://raw.githubusercontent.com/Alvin9999/pac2/master/quick/1/config.yaml 16 | https://raw.githubusercontent.com/Alvin9999/pac2/master/quick/config.yaml 17 | -------------------------------------------------------------------------------- /sub/merged_warp_proxies.yaml: -------------------------------------------------------------------------------- 1 | port: 7890 2 | allow-lan: true 3 | mode: rule 4 | log-level: info 5 | unified-delay: true 6 | global-client-fingerprint: chrome 7 | dns: 8 | enable: true 9 | listen: :53 10 | ipv6: true 11 | enhanced-mode: fake-ip 12 | fake-ip-range: 198.18.0.1/16 13 | default-nameserver: 14 | - 223.5.5.5 15 | - 8.8.8.8 16 | nameserver: 17 | - https://dns.alidns.com/dns-query 18 | - https://doh.pub/dns-query 19 | fallback: 20 | - https://1.0.0.1/dns-query 21 | - tls://dns.google 22 | fallback-filter: 23 | geoip: true 24 | geoip-code: CN 25 | ipcidr: 26 | - 240.0.0.0/4 27 | proxies: 28 | - name: TW 29 | type: trojan 30 | server: a 31 | port: 1 32 | password: 72ac875a-f5b9-461e-a7a4-942b468b0d83 33 | udp: true 34 | sni: gw.alicdn.com 35 | skip-cert-verify: true 36 | - name: WARP 37 | type: wireguard 38 | server: engage.cloudflareclient.com 39 | port: 2408 40 | ip: 172.16.0.2 41 | ipv6: 2606:4700:110:87c0:ba32:773a:8d44:e353 42 | private-key: +HpHpY/KjSv5hJdGrN2ok1A6CKhCmTQv5Unwyul9S1g= 43 | public-key: bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo= 44 | udp: true 45 | reserved: 46 | - 0 47 | - 0 48 | - 0 49 | remote-dns-resolve: true 50 | dns: 51 | - 1.1.1.1 52 | - 8.8.8.8 53 | dialer-proxy: WARP前置节点 54 | proxy-groups: 55 | - name: 节点选择 56 | type: select 57 | proxies: 58 | - TW 59 | - WARP 60 | - 自动选择 61 | - 负载均衡 62 | - 手动选择 63 | - DIRECT 64 | - name: WARP前置节点 65 | type: select 66 | proxies: 67 | - 自动选择 68 | - 负载均衡 69 | - 手动选择 70 | - name: 自动选择 71 | type: url-test 72 | url: http://www.gstatic.com/generate_204 73 | interval: 300 74 | tolerance: 50 75 | proxies: 76 | - TW 77 | - name: 手动选择 78 | type: select 79 | proxies: 80 | - TW 81 | - name: 负载均衡 82 | type: load-balance 83 | proxies: 84 | - TW 85 | url: http://www.gstatic.com/generate_204 86 | interval: 300 87 | strategy: round-robin 88 | rules: 89 | - DOMAIN,clash.razord.top,DIRECT 90 | - DOMAIN,yacd.haishan.me,DIRECT 91 | - GEOIP,LAN,DIRECT 92 | - GEOIP,CN,DIRECT 93 | - MATCH,节点选择 94 | -------------------------------------------------------------------------------- /sub/merged_warp_proxies_new.yaml: -------------------------------------------------------------------------------- 1 | port: 7890 2 | allow-lan: true 3 | mode: rule 4 | log-level: info 5 | unified-delay: true 6 | global-client-fingerprint: chrome 7 | dns: 8 | enable: true 9 | listen: :53 10 | ipv6: true 11 | enhanced-mode: fake-ip 12 | fake-ip-range: 198.18.0.1/16 13 | default-nameserver: 14 | - 223.5.5.5 15 | - 8.8.8.8 16 | nameserver: 17 | - https://dns.alidns.com/dns-query 18 | - https://doh.pub/dns-query 19 | fallback: 20 | - https://1.0.0.1/dns-query 21 | - tls://dns.google 22 | fallback-filter: 23 | geoip: true 24 | geoip-code: CN 25 | ipcidr: 26 | - 240.0.0.0/4 27 | proxies: 28 | - name: TW 29 | type: trojan 30 | server: a 31 | port: 1 32 | password: 72ac875a-f5b9-461e-a7a4-942b468b0d83 33 | udp: true 34 | sni: gw.alicdn.com 35 | skip-cert-verify: true 36 | - name: WARP 37 | type: wireguard 38 | server: engage.cloudflareclient.com 39 | port: 2408 40 | ip: 172.16.0.2 41 | ipv6: 2606:4700:110:87c0:ba32:773a:8d44:e353 42 | private-key: +HpHpY/KjSv5hJdGrN2ok1A6CKhCmTQv5Unwyul9S1g= 43 | public-key: bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo= 44 | udp: true 45 | reserved: 46 | - 0 47 | - 0 48 | - 0 49 | remote-dns-resolve: true 50 | dns: 51 | - 1.1.1.1 52 | - 8.8.8.8 53 | dialer-proxy: WARP前置节点 54 | proxy-groups: 55 | - name: 节点选择 56 | type: select 57 | proxies: 58 | - TW 59 | - WARP 60 | - 自动选择 61 | - 负载均衡 62 | - 手动选择 63 | - DIRECT 64 | - name: WARP前置节点 65 | type: select 66 | proxies: 67 | - 自动选择 68 | - 负载均衡 69 | - 手动选择 70 | - name: 自动选择 71 | type: url-test 72 | url: http://www.gstatic.com/generate_204 73 | interval: 300 74 | tolerance: 50 75 | proxies: 76 | - TW 77 | - name: 手动选择 78 | type: select 79 | proxies: 80 | - TW 81 | - name: 负载均衡 82 | type: load-balance 83 | proxies: 84 | - TW 85 | url: http://www.gstatic.com/generate_204 86 | interval: 300 87 | strategy: round-robin 88 | rules: 89 | - DOMAIN,clash.razord.top,DIRECT 90 | - DOMAIN,yacd.haishan.me,DIRECT 91 | - GEOIP,LAN,DIRECT 92 | - GEOIP,CN,DIRECT 93 | - MATCH,节点选择 94 | -------------------------------------------------------------------------------- /templates/clash_warp_template.yaml: -------------------------------------------------------------------------------- 1 | port: 7890 2 | allow-lan: true 3 | mode: rule 4 | log-level: info 5 | unified-delay: true 6 | global-client-fingerprint: chrome 7 | dns: 8 | enable: true 9 | listen: :53 10 | ipv6: true 11 | enhanced-mode: fake-ip 12 | fake-ip-range: 198.18.0.1/16 13 | default-nameserver: 14 | - 223.5.5.5 15 | - 8.8.8.8 16 | nameserver: 17 | - https://dns.alidns.com/dns-query 18 | - https://doh.pub/dns-query 19 | fallback: 20 | - https://1.0.0.1/dns-query 21 | - tls://dns.google 22 | fallback-filter: 23 | geoip: true 24 | geoip-code: CN 25 | ipcidr: 26 | - 240.0.0.0/4 27 | proxies: 28 | - name: TW 29 | type: trojan 30 | server: a 31 | port: 1 32 | password: 72ac875a-f5b9-461e-a7a4-942b468b0d83 33 | udp: true 34 | sni: gw.alicdn.com 35 | skip-cert-verify: true 36 | 37 | - name: WARP 38 | type: wireguard 39 | server: engage.cloudflareclient.com 40 | port: 2408 41 | ip: 172.16.0.2 42 | ipv6: 2606:4700:110:87c0:ba32:773a:8d44:e353 43 | private-key: +HpHpY/KjSv5hJdGrN2ok1A6CKhCmTQv5Unwyul9S1g= 44 | public-key: bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo= 45 | udp: true 46 | reserved: [0,0,0] 47 | remote-dns-resolve: true 48 | dns: [ 1.1.1.1, 8.8.8.8 ] 49 | dialer-proxy: "WARP前置节点" 50 | 51 | proxy-groups: 52 | - name: 节点选择 53 | type: select 54 | proxies: 55 | - TW 56 | - WARP 57 | - 自动选择 58 | - 负载均衡 59 | - 手动选择 60 | - DIRECT 61 | - name: WARP前置节点 62 | type: select 63 | proxies: 64 | - 自动选择 65 | - 负载均衡 66 | - 手动选择 67 | 68 | - name: 自动选择 69 | type: url-test 70 | url: http://www.gstatic.com/generate_204 71 | interval: 300 72 | tolerance: 50 73 | proxies: 74 | - TW 75 | 76 | - name: 手动选择 77 | type: select 78 | proxies: 79 | - TW 80 | 81 | - name: 负载均衡 82 | type: load-balance #负载均衡 83 | proxies: 84 | - TW 85 | url: 'http://www.gstatic.com/generate_204' 86 | interval: 300 87 | #lazy: true 88 | #disable-udp: true 89 | strategy: round-robin #作为前置节点⽤这个⽐较好 90 | 91 | 92 | rules: 93 | - DOMAIN,clash.razord.top,DIRECT 94 | - DOMAIN,yacd.haishan.me,DIRECT 95 | - GEOIP,LAN,DIRECT 96 | - GEOIP,CN,DIRECT 97 | - MATCH,节点选择 98 | -------------------------------------------------------------------------------- /meta_merge.py: -------------------------------------------------------------------------------- 1 | import yaml 2 | import json 3 | import urllib.request 4 | import logging 5 | 6 | # 提取节点 7 | def process_urls(url_file, processor): 8 | try: 9 | with open(url_file, 'r') as file: 10 | urls = file.read().splitlines() 11 | 12 | for index, url in enumerate(urls): 13 | try: 14 | response = urllib.request.urlopen(url) 15 | data = response.read().decode('utf-8') 16 | processor(data, index) 17 | except Exception as e: 18 | logging.error(f"Error processing URL {url}: {e}") 19 | except Exception as e: 20 | logging.error(f"Error reading file {url_file}: {e}") 21 | #提取clash节点 22 | def process_clash(data, index): 23 | content = yaml.safe_load(data) 24 | proxies = content.get('proxies', []) 25 | for i, proxy in enumerate(proxies): 26 | proxy['name'] = f"{proxy['type']}_{index}{i+1}" 27 | merged_proxies.extend(proxies) 28 | # 处理sb,待办 29 | def process_sb(data, index): 30 | try: 31 | json_data = json.loads(data) 32 | # 处理 shadowtls 数据 33 | 34 | # 提取所需字段 35 | method = json_data["outbounds"][0]["method"] 36 | password = json_data["outbounds"][0]["password"] 37 | server = json_data["outbounds"][1]["server"] 38 | server_port = json_data["outbounds"][1]["server_port"] 39 | server_name = json_data["outbounds"][1]["tls"]["server_name"] 40 | shadowtls_password = json_data["outbounds"][1]["password"] 41 | version = json_data["outbounds"][1]["version"] 42 | name = f"shadowtls_{index}" 43 | # 创建当前网址的proxy字典 44 | proxy = { 45 | "name": name, 46 | "type": "ss", 47 | "server": server, 48 | "port": server_port, 49 | "cipher": method, 50 | "password": password, 51 | "plugin": "shadow-tls", 52 | "client-fingerprint": "chrome", 53 | "plugin-opts": { 54 | "host": server_name, 55 | "password": shadowtls_password, 56 | "version": int(version) 57 | } 58 | } 59 | 60 | # 将当前proxy字典添加到所有proxies列表中 61 | merged_proxies.append(proxy) 62 | 63 | except Exception as e: 64 | logging.error(f"Error processing shadowtls data for index {index}: {e}") 65 | 66 | def process_hysteria(data, index): 67 | try: 68 | json_data = json.loads(data) 69 | # 处理 hysteria 数据 70 | # 提取所需字段 71 | auth = json_data["auth_str"] 72 | server_ports = json_data["server"] 73 | server_ports_slt = server_ports.split(":") 74 | server = server_ports_slt[0] 75 | ports = server_ports_slt[1] 76 | ports_slt = ports.split(",") 77 | server_port = int(ports_slt[0]) 78 | if len(ports_slt) > 1: 79 | mport = ports_slt[1] 80 | else: 81 | mport = server_port 82 | fast_open = json_data["fast_open"] 83 | insecure = json_data["insecure"] 84 | server_name = json_data["server_name"] 85 | alpn = json_data["alpn"] 86 | protocol = json_data["protocol"] 87 | name = f"hysteria_{index}" 88 | 89 | # 创建当前网址的proxy字典 90 | proxy = { 91 | "name": name, 92 | "type": "hysteria", 93 | "server": server, 94 | "port": server_port, 95 | "ports": mport, 96 | "auth_str": auth, 97 | "up": 80, 98 | "down": 100, 99 | "fast-open": fast_open, 100 | "protocol": protocol, 101 | "sni": server_name, 102 | "skip-cert-verify": insecure, 103 | "alpn": [alpn] 104 | } 105 | 106 | # 将当前proxy字典添加到所有proxies列表中 107 | merged_proxies.append(proxy) 108 | 109 | except Exception as e: 110 | logging.error(f"Error processing hysteria data for index {index}: {e}") 111 | # 处理hysteria2 112 | def process_hysteria2(data, index): 113 | try: 114 | json_data = json.loads(data) 115 | # 处理 hysteria2 数据 116 | # 提取所需字段 117 | auth = json_data["auth"] 118 | server_ports = json_data["server"] 119 | server_ports_slt = server_ports.split(":") 120 | server = server_ports_slt[0] 121 | ports = server_ports_slt[1] 122 | ports_slt = ports.split(",") 123 | server_port = int(ports_slt[0]) 124 | fast_open = json_data["fastOpen"] 125 | insecure = json_data["tls"]["insecure"] 126 | sni = json_data["tls"]["sni"] 127 | name = f"hysteria2_{index}" 128 | 129 | # 创建当前网址的proxy字典 130 | proxy = { 131 | "name": name, 132 | "type": "hysteria2", 133 | "server": server, 134 | "port": server_port, 135 | "password": auth, 136 | "fast-open": fast_open, 137 | "sni": sni, 138 | "skip-cert-verify": insecure 139 | } 140 | 141 | # 将当前proxy字典添加到所有proxies列表中 142 | merged_proxies.append(proxy) 143 | 144 | except Exception as e: 145 | logging.error(f"Error processing hysteria2 data for index {index}: {e}") 146 | 147 | #处理xray 148 | def process_xray(data, index): 149 | try: 150 | json_data = json.loads(data) 151 | # 处理 xray 数据 152 | protocol = json_data["outbounds"][0]["protocol"] 153 | #vless操作 154 | if protocol == "vless": 155 | # 提取所需字段 156 | server = json_data["outbounds"][0]["settings"]["vnext"][0]["address"] 157 | port = json_data["outbounds"][0]["settings"]["vnext"][0]["port"] 158 | uuid = json_data["outbounds"][0]["settings"]["vnext"][0]["users"][0]["id"] 159 | istls = True 160 | flow = json_data["outbounds"][0]["settings"]["vnext"][0]["users"][0]["flow"] 161 | # 传输方式 162 | network = json_data["outbounds"][0]["streamSettings"]["network"] 163 | publicKey = json_data["outbounds"][0]["streamSettings"]["realitySettings"]["publicKey"] 164 | shortId = json_data["outbounds"][0]["streamSettings"]["realitySettings"]["shortId"] 165 | serverName = json_data["outbounds"][0]["streamSettings"]["realitySettings"]["serverName"] 166 | fingerprint = json_data["outbounds"][0]["streamSettings"]["realitySettings"]["fingerprint"] 167 | # udp转发 168 | isudp = True 169 | name = f"reality_{index}" 170 | 171 | # 根据network判断tcp 172 | if network == "tcp": 173 | proxy = { 174 | "name": name, 175 | "type": protocol, 176 | "server": server, 177 | "port": port, 178 | "uuid": uuid, 179 | "network": network, 180 | "tls": istls, 181 | "udp": isudp, 182 | "flow": flow, 183 | "client-fingerprint": fingerprint, 184 | "servername": serverName, 185 | "reality-opts":{ 186 | "public-key": publicKey, 187 | "short-id": shortId} 188 | } 189 | 190 | # 根据network判断grpc 191 | elif network == "grpc": 192 | serviceName = json_data["outbounds"][0]["streamSettings"]["grpcSettings"]["serviceName"] 193 | 194 | # 创建当前网址的proxy字典 195 | proxy = { 196 | "name": name, 197 | "type": protocol, 198 | "server": server, 199 | "port": port, 200 | "uuid": uuid, 201 | "network": network, 202 | "tls": istls, 203 | "udp": isudp, 204 | "flow": flow, 205 | "client-fingerprint": fingerprint, 206 | "servername": serverName, 207 | "grpc-opts":{ 208 | "grpc-service-name": serviceName 209 | }, 210 | "reality-opts":{ 211 | "public-key": publicKey, 212 | "short-id": shortId} 213 | } 214 | 215 | # 将当前proxy字典添加到所有proxies列表中 216 | merged_proxies.append(proxy) 217 | except Exception as e: 218 | logging.error(f"Error processing xray data for index {index}: {e}") 219 | 220 | def update_proxy_groups(config_data, merged_proxies): 221 | for group in config_data['proxy-groups']: 222 | if group['name'] in ['自动选择', '节点选择']: 223 | group['proxies'].extend(proxy['name'] for proxy in merged_proxies) 224 | 225 | def update_warp_proxy_groups(config_warp_data, merged_proxies): 226 | for group in config_warp_data['proxy-groups']: 227 | if group['name'] in ['自动选择', '手动选择', '负载均衡']: 228 | group['proxies'].extend(proxy['name'] for proxy in merged_proxies) 229 | # 定义一个空列表用于存储合并后的代理配置 230 | merged_proxies = [] 231 | 232 | # 处理 clash URLs 233 | process_urls('./urls/clash_new_urls.txt', process_clash) 234 | 235 | # 处理 shadowtls URLs 236 | process_urls('./urls/sb_urls.txt', process_sb) 237 | 238 | # 处理 hysteria URLs 239 | process_urls('./urls/hysteria_urls.txt', process_hysteria) 240 | 241 | # 处理 hysteria2 URLs 242 | process_urls('./urls/hysteria2_urls.txt', process_hysteria2) 243 | 244 | # 处理 xray URLs 245 | process_urls('./urls/xray_urls.txt', process_xray) 246 | 247 | # 读取普通的配置文件内容 248 | with open('./templates/clash_template.yaml', 'r', encoding='utf-8') as file: 249 | config_data = yaml.safe_load(file) 250 | 251 | # 读取warp配置文件内容 252 | with open('./templates/clash_warp_template.yaml', 'r', encoding='utf-8') as file: 253 | config_warp_data = yaml.safe_load(file) 254 | 255 | # 添加合并后的代理到proxies部分 256 | config_data['proxies'].extend(merged_proxies) 257 | config_warp_data['proxies'].extend(merged_proxies) 258 | 259 | # 更新自动选择和节点选择的proxies的name部分 260 | update_proxy_groups(config_data, merged_proxies) 261 | update_warp_proxy_groups(config_warp_data, merged_proxies) 262 | 263 | # 将更新后的数据写入到一个YAML文件中,并指定编码格式为UTF-8 264 | with open('./sub/merged_proxies_new.yaml', 'w', encoding='utf-8') as file: 265 | yaml.dump(config_data, file, sort_keys=False, allow_unicode=True) 266 | 267 | with open('./sub/merged_warp_proxies_new.yaml', 'w', encoding='utf-8') as file: 268 | yaml.dump(config_warp_data, file, sort_keys=False, allow_unicode=True) 269 | 270 | print("聚合完成") 271 | 272 | # 处理其他 273 | merged_proxies = [] 274 | 275 | # 处理 clash URLs 276 | process_urls('./urls/clash_urls.txt', process_clash) 277 | 278 | # 处理 shadowtls URLs 279 | process_urls('./urls/sb_urls.txt', process_sb) 280 | 281 | # 处理 hysteria URLs 282 | process_urls('./urls/hysteria_urls.txt', process_hysteria) 283 | 284 | # 处理 hysteria2 URLs 285 | #process_urls('./urls/hysteria2_urls.txt', process_hysteria2) 286 | 287 | # 处理 xray URLs 288 | process_urls('./urls/xray_urls.txt', process_xray) 289 | 290 | # 读取普通的配置文件内容 291 | with open('./templates/clash_template.yaml', 'r', encoding='utf-8') as file: 292 | config_data = yaml.safe_load(file) 293 | 294 | # 读取warp配置文件内容 295 | with open('./templates/clash_warp_template.yaml', 'r', encoding='utf-8') as file: 296 | config_warp_data = yaml.safe_load(file) 297 | 298 | # 添加合并后的代理到proxies部分 299 | config_data['proxies'].extend(merged_proxies) 300 | config_warp_data['proxies'].extend(merged_proxies) 301 | 302 | # 更新自动选择和节点选择的proxies的name部分 303 | update_proxy_groups(config_data, merged_proxies) 304 | update_warp_proxy_groups(config_warp_data, merged_proxies) 305 | 306 | # 将更新后的数据写入到一个YAML文件中,并指定编码格式为UTF-8 307 | with open('./sub/merged_proxies.yaml', 'w', encoding='utf-8') as file: 308 | yaml.dump(config_data, file, sort_keys=False, allow_unicode=True) 309 | 310 | with open('./sub/merged_warp_proxies.yaml', 'w', encoding='utf-8') as file: 311 | yaml.dump(config_warp_data, file, sort_keys=False, allow_unicode=True) 312 | 313 | print("聚合完成") 314 | -------------------------------------------------------------------------------- /merge.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import json 3 | import urllib.request 4 | import yaml 5 | import codecs 6 | import logging 7 | 8 | # 提取节点 9 | def process_urls(url_file, processor): 10 | try: 11 | with open(url_file, 'r') as file: 12 | urls = file.read().splitlines() 13 | 14 | for index, url in enumerate(urls): 15 | try: 16 | response = urllib.request.urlopen(url) 17 | data = response.read().decode('utf-8') 18 | processor(data, index) 19 | except Exception as e: 20 | logging.error(f"Error processing URL {url}: {e}") 21 | except Exception as e: 22 | logging.error(f"Error reading file {url_file}: {e}") 23 | #提取clash节点 24 | def process_clash(data, index): 25 | # 解析YAML格式的内容 26 | content = yaml.safe_load(data) 27 | 28 | # 提取proxies部分并合并到merged_proxies中 29 | proxies = content.get('proxies', []) 30 | 31 | for proxy in proxies: 32 | # 如果类型是vless 33 | if proxy['type'] == 'vless' : 34 | server = proxy.get("server", "") 35 | port = int(proxy.get("port", 443)) 36 | udp = proxy.get("udp", "") 37 | uuid = proxy.get("uuid", "") 38 | network = proxy.get("network", "") 39 | tls = int(proxy.get("tls", 0)) 40 | xudp = proxy.get("xudp", "") 41 | sni = proxy.get("servername", "") 42 | flow = proxy.get("flow", "") 43 | publicKey = proxy.get('reality-opts', {}).get('public-key', '') 44 | short_id = proxy.get('reality-opts', {}).get('short-id', '') 45 | fp = proxy.get("client-fingerprint", "") 46 | insecure = int(proxy.get("skip-cert-verify", 0)) 47 | grpc_serviceName = proxy.get('grpc-opts', {}).get('grpc-service-name', '') 48 | 49 | ws_path = proxy.get('ws-opts', {}).get('path', '') 50 | ws_headers_host = proxy.get('ws-opts', {}).get('headers', {}).get('Host', '') 51 | if tls == 0: 52 | security = 'none' 53 | elif tls == 1 and publicKey != '': 54 | security = 'reality' 55 | else: 56 | security = 'tls' 57 | vless_meta = f"vless://{uuid}@{server}:{port}?security={security}&allowInsecure{insecure}&flow={flow}&type={network}&fp={fp}&pbk={publicKey}&sid={short_id}&sni={sni}&serviceName={grpc_serviceName}&path={ws_path}&host={ws_headers_host}#vless_meta_{index}" 58 | 59 | merged_proxies.append(vless_meta) 60 | 61 | if proxy['type'] == 'vmess' : 62 | server = proxy.get("server", "") 63 | port = int(proxy.get("port", 443)) 64 | uuid = proxy.get("uuid", "") 65 | #cipher = proxy.get("cipher", "") 66 | alterId = proxy.get("alterId", "") 67 | network = proxy.get("network", "") 68 | tls = int(proxy.get("tls", 0)) 69 | if tls == 0: 70 | security = "none" 71 | elif tls == 1: 72 | security = "tls" 73 | sni = proxy.get("servername", "") 74 | ws_path = proxy.get('ws-opts', {}).get('path', '') 75 | ws_headers_host = proxy.get('ws-opts', {}).get('headers', {}).get('Host', '') 76 | 77 | vmess_meta = f"vmess://{uuid}@{server}:{port}?security={security}&allowInsecure{insecure}&type={network}&fp={fp}&sni={sni}&path={ws_path}&host={ws_headers_host}#vmess_meta_{index}" 78 | 79 | merged_proxies.append(vmess_meta) 80 | 81 | elif proxy['type'] == 'tuic': 82 | server = proxy.get("server", "") 83 | port = int(proxy.get("port", 443)) 84 | uuid = proxy.get("uuid", "") 85 | password = proxy.get("password", "") 86 | sni = proxy.get("sni", "") 87 | insecure = int(proxy.get("skip-cert-verify", 0)) 88 | udp_relay_mode = proxy.get("udp-relay-mode", "naive") 89 | congestion = proxy.get("congestion-controller", "bbr") 90 | alpn = proxy.get("alpn", [])[0] if proxy.get("alpn") and len(proxy["alpn"]) > 0 else None 91 | #tuic_meta_neko = f"tuic://{server}:{port}?uuid={uuid}&version=5&password={password}&insecure={insecure}&alpn={alpn}&mode={udp_relay_mode}" 92 | tuic_meta = f"tuic://{uuid}:{password}@{server}:{port}?sni={sni}&congestion_control={congestion}&udp_relay_mode={udp_relay_mode}&alpn={alpn}&allow_insecure={insecure}" 93 | merged_proxies.append(tuic_meta) 94 | 95 | elif proxy['type'] == "hysteria2": 96 | server = proxy.get("server", "") 97 | port = int(proxy.get("port", 443)) 98 | auth = proxy.get("password", "") 99 | obfs = proxy.get("obfs", "") 100 | obfs_password = proxy.get("obfs-password","") 101 | sni = proxy.get("sni", "") 102 | insecure = int(proxy.get("skip-cert-verify", 0)) 103 | hy2_meta = f"hysteria2://{auth}@{server}:{port}?insecure={insecure}&sni={sni}&obfs={obfs}&obfs-password={obfs_password}#hysteria2_meta_{index}" 104 | merged_proxies.append(hy2_meta) 105 | 106 | elif proxy['type'] == 'hysteria': 107 | server = proxy.get("server", "") 108 | port = int(proxy.get("port", 443)) 109 | ports = proxy.get("port", "") 110 | protocol = proxy.get("protocol", "udp") 111 | up_mbps = 50 112 | down_mbps = 80 113 | alpn = proxy.get("alpn", [])[0] if proxy.get("alpn") and len(proxy["alpn"]) > 0 else None 114 | obfs = proxy.get("obfs", "") 115 | insecure = int(proxy.get("skip-cert-verify", 0)) 116 | sni = proxy.get("sni", "") 117 | fast_open = int(proxy.get("fast_open", 1)) 118 | auth = proxy.get("auth-str", "") 119 | # 生成URL 120 | hysteria_meta = f"hysteria://{server}:{port}?peer={sni}&auth={auth}&insecure={insecure}&upmbps={up_mbps}&downmbps={down_mbps}&alpn={alpn}&mport={ports}&obfs={obfs}&protocol={protocol}&fastopen={fast_open}#hysteria_meta_{index}" 121 | merged_proxies.append(hysteria_meta) 122 | 123 | elif proxy['type'] == 'ssr': 124 | server = proxy.get("server", "") 125 | port = int(proxy.get("port", 443)) 126 | password = proxy.get("password", "") 127 | password = base64.b64encode(password.encode()).decode() 128 | cipher = proxy.get("cipher", "") 129 | obfs = proxy.get("obfs", "") 130 | protocol = proxy.get("protocol", "") 131 | protocol_param = proxy.get("protocol-param", "") 132 | protocol_param = base64.b64encode(protocol_param.encode()).decode() 133 | obfs_param = proxy.get("obfs-param", "") 134 | obfs_param = base64.b64encode(obfs_param.encode()).decode() 135 | # 生成URL 136 | ssr_source=f"{server}:{port}:{protocol}:{cipher}:{obfs}:{password}/?obfsparam={obfs_param}&protoparam={protocol_param}&remarks=ssr_meta_{index}&protoparam{protocol_param}=&obfsparam={obfs_param}" 137 | 138 | ssr_source=base64.b64encode(ssr_source.encode()).decode() 139 | ssr_meta = f"ssr://{ssr_source}" 140 | merged_proxies.append(ssr_meta) 141 | #目前仅支持最原始版本ss,无插件支持 142 | elif proxy['type'] == 'ss': 143 | server = proxy.get("server", "") 144 | port = int(proxy.get("port", 443)) 145 | password = proxy.get("password", "") 146 | cipher = proxy.get("cipher", "") 147 | # 生成URL 148 | ss_source=f"{cipher}:{password}@{server}:{port}" 149 | 150 | ss_source=base64.b64encode(ss_source.encode()).decode() 151 | ss_meta = f"ss://{ss_source}" 152 | merged_proxies.append(ss_meta) 153 | def process_naive(data, index): 154 | try: 155 | json_data = json.loads(data) 156 | 157 | proxy_str = json_data["proxy"] 158 | #proxy_str = proxy_str.replace("https://", "") 159 | naiveproxy = base64.b64encode(proxy_str.encode()).decode() 160 | merged_proxies.append(naiveproxy) 161 | 162 | 163 | except Exception as e: 164 | logging.error(f"Error processing naive data for index {index}: {e}") 165 | #处理sing-box节点,待办 166 | def process_sb(data, index): 167 | try: 168 | json_data = json.loads(data) 169 | # 处理 shadowtls 数据 170 | server = json_data["outbounds"][1].get("server", "") 171 | server_port = json_data["outbounds"][1].get("server_port", "") 172 | method = json_data["outbounds"][0].get("method", "") 173 | password = json_data["outbounds"][0].get("password", "") 174 | version = int(json_data["outbounds"][1].get("version", 0)) 175 | host = json_data["outbounds"][1]["tls"].get("server_name", "") 176 | shadowtls_password = json_data["outbounds"][1].get("password", "") 177 | 178 | ss = f"{method}:{password}@{server}:{server_port}" 179 | shadowtls = f'{{"version": "{version}", "host": "{host}","password":{shadowtls_password}}}' 180 | shadowtls_proxy = "ss://"+base64.b64encode(ss.encode()).decode()+"?shadow-tls="+base64.b64encode(shadowtls.encode()).decode()+f"#shadowtls{index}" 181 | 182 | merged_proxies.append(shadowtls_proxy) 183 | 184 | except Exception as e: 185 | logging.error(f"Error processing shadowtls data for index {index}: {e}") 186 | #hysteria 187 | def process_hysteria(data, index): 188 | try: 189 | json_data = json.loads(data) 190 | # 处理 hysteria 数据 191 | # 提取字段值 192 | server = json_data.get("server", "") 193 | protocol = json_data.get("protocol", "") 194 | up_mbps = json_data.get("up_mbps", "") 195 | down_mbps = json_data.get("down_mbps", "") 196 | alpn = json_data.get("alpn", "") 197 | obfs = json_data.get("obfs", "") 198 | insecure = int(json_data.get("insecure", 0)) 199 | server_name = json_data.get("server_name", "") 200 | fast_open = int(json_data.get("fast_open", 0)) 201 | auth = json_data.get("auth_str", "") 202 | # 生成URL 203 | hysteria = f"hysteria://{server}?peer={server_name}&auth={auth}&insecure={insecure}&upmbps={up_mbps}&downmbps={down_mbps}&alpn={alpn}&obfs={obfs}&protocol={protocol}&fastopen={fast_open}#hysteria_{index}" 204 | merged_proxies.append(hysteria) 205 | 206 | 207 | except Exception as e: 208 | logging.error(f"Error processing hysteria data for index {index}: {e}") 209 | # 处理hysteria2 210 | def process_hysteria2(data, index): 211 | try: 212 | json_data = json.loads(data) 213 | # 处理 hysteria2 数据 214 | # 提取字段值 215 | server = json_data["server"] 216 | insecure = int(json_data["tls"]["insecure"]) 217 | sni = json_data["tls"]["sni"] 218 | auth = json_data["auth"] 219 | # 生成URL 220 | hysteria2 = f"hysteria2://{auth}@{server}?insecure={insecure}&sni={sni}#hysteria2_{index}" 221 | 222 | merged_proxies.append(hysteria2) 223 | except Exception as e: 224 | logging.error(f"Error processing hysteria2 data for index {index}: {e}") 225 | 226 | #处理xray 227 | def process_xray(data, index): 228 | try: 229 | json_data = json.loads(data) 230 | # 处理 xray 数据 231 | protocol = json_data["outbounds"][0].get("protocol") 232 | 233 | if protocol == "vless": 234 | vnext = json_data["outbounds"][0]["settings"]["vnext"] 235 | 236 | if vnext: 237 | server = vnext[0].get("address", "") 238 | port = vnext[0].get("port", "") 239 | users = vnext[0]["users"] 240 | 241 | if users: 242 | user = users[0] 243 | uuid = user.get("id", "") 244 | flow = user.get("flow", "") 245 | 246 | stream_settings = json_data["outbounds"][0].get("streamSettings", {}) 247 | network = stream_settings.get("network", "") 248 | security = stream_settings.get("security", "") 249 | reality_settings = stream_settings.get("realitySettings", {}) 250 | 251 | publicKey = reality_settings.get("publicKey", "") 252 | short_id = reality_settings.get("shortId", "") 253 | sni = reality_settings.get("serverName", "") 254 | #tls 255 | tls_settings = stream_settings.get("tlsSettings", {}) 256 | sni = tls_settings.get("serverName", sni) 257 | insecure = int(tls_settings.get("allowInsecure", 0)) 258 | 259 | fp = reality_settings.get("fingerprint", "") 260 | fp = tls_settings.get("fingerprint", fp) 261 | spx = reality_settings.get("spiderX", "") 262 | 263 | grpc_settings = stream_settings.get("grpcSettings", {}) 264 | grpc_serviceName = grpc_settings.get("serviceName", "") 265 | 266 | ws_settings = stream_settings.get("wsSettings", {}) 267 | ws_path = ws_settings.get("path", "") 268 | ws_headers_host = ws_settings.get("headers", {}).get("Host", "") 269 | 270 | xray_proxy = f"vless://{uuid}@{server}:{port}?security={security}&allowInsecure={insecure}&flow={flow}&type={network}&fp={fp}&pbk={publicKey}&sid={short_id}&sni={sni}&serviceName={grpc_serviceName}&path={ws_path}&host={ws_headers_host}#vless_{index}" 271 | 272 | # 将当前proxy字典添加到所有proxies列表中 273 | merged_proxies.append(xray_proxy) 274 | # 不支持插件 275 | if protocol == "shadowsocks": 276 | server = json_data["outbounds"][0]["settings"]["servers"]["address"] 277 | method = json_data["outbounds"][0]["settings"]["servers"]["method"] 278 | password = json_data["outbounds"][0]["settings"]["servers"]["password"] 279 | port = json_data["outbounds"][0]["settings"]["servers"]["port"] 280 | # 生成URL 281 | ss_source=f"{method}:{password}@{server}:{port}" 282 | ss_source=base64.b64encode(ss_source.encode()).decode() 283 | xray_proxy = f"ss://{ss_source}" 284 | 285 | # 将当前proxy字典添加到所有proxies列表中 286 | merged_proxies.append(xray_proxy) 287 | except Exception as e: 288 | logging.error(f"Error processing xray data for index {index}: {e}") 289 | 290 | # 定义一个空列表用于存储合并后的代理配置 291 | merged_proxies = [] 292 | 293 | # 处理 clash URLs 294 | process_urls('./urls/clash_new_urls.txt', process_clash) 295 | 296 | # 处理 shadowtls URLs 297 | process_urls('./urls/sb_urls.txt', process_sb) 298 | 299 | # 处理 naive URLs 300 | process_urls('./urls/naiverproxy_urls.txt', process_naive) 301 | 302 | # 处理 hysteria URLs 303 | process_urls('./urls/hysteria_urls.txt', process_hysteria) 304 | 305 | # 处理 hysteria2 URLs 306 | process_urls('./urls/hysteria2_urls.txt', process_hysteria2) 307 | 308 | # 处理 xray URLs 309 | process_urls('./urls/xray_urls.txt', process_xray) 310 | 311 | # 将结果写入文件 312 | try: 313 | with open("./sub/shadowrocket.txt", "w") as file: 314 | for proxy in merged_proxies: 315 | file.write(proxy + "\n") 316 | except Exception as e: 317 | print(f"Error writing to file: {e}") 318 | 319 | try: 320 | with open("./sub/shadowrocket.txt", "r") as file: 321 | content = file.read() 322 | encoded_content = base64.b64encode(content.encode("utf-8")).decode("utf-8") 323 | 324 | with open("./sub/shadowrocket_base64.txt", "w") as encoded_file: 325 | encoded_file.write(encoded_content) 326 | 327 | print("Content successfully encoded and written to file.") 328 | except Exception as e: 329 | print(f"Error encoding file content: {e}") 330 | 331 | --------------------------------------------------------------------------------