diff --git a/tools/subconverter/generate.ini b/tools/subconverter/generate.ini new file mode 100644 index 0000000..3a1931b --- /dev/null +++ b/tools/subconverter/generate.ini @@ -0,0 +1,9 @@ +[test] +path=../../temp/clash_config.yaml +target=clash +ver=4 +url=../../temp/clash.yaml + +[test_profile] +path=output.yml +profile=profiles/example_profile.ini diff --git a/tools/subconverter/gistconf.ini b/tools/subconverter/gistconf.ini new file mode 100644 index 0000000..03c68b6 --- /dev/null +++ b/tools/subconverter/gistconf.ini @@ -0,0 +1,3 @@ +[common] +;uncomment the following line and enter your token to enable upload function +;token = your_personal_token_here diff --git a/tools/subconverter/pref.example.ini b/tools/subconverter/pref.example.ini new file mode 100644 index 0000000..cbfb12f --- /dev/null +++ b/tools/subconverter/pref.example.ini @@ -0,0 +1,276 @@ +[common] +;API mode, set to true to prevent loading local subscriptions or serving local files directly +api_mode=false + +;Access token used for performing critical action through Web interface +api_access_token=password + +;Default URLs, used when no URL is provided in request, use "|" to separate multiple subscription links, supports local files/URL +default_url= + +;Insert subscription links to requests. Can be used to add node(s) to all exported subscriptions. +enable_insert=true +;URLs to insert to subscription links, use "|" to separate multiple subscription links, supports local files/URL +insert_url= +;Prepend inserted URLs to subscription links. Nodes in insert_url will be added to groups first with non-group-specific match pattern. +prepend_insert_url=true + +;Exclude nodes which remarks match the following patterns. Supports regular expression. +exclude_remarks=(到期|剩余流量|时间|官网|产品|平台) +;exclude_remarks=(other rule) + +;Only include nodes which remarks match the following patterns. Supports regular expression. +;include_remarks=V3.*港 + +;Enable script support for filtering nodes +enable_filter=false +;Script used for filtering nodes. Supports inline script and script path. A "filter" function with 1 argument which is a node should be defined in the script. +;Example: Inline script: Set value to content of script. Replace all line break with "\n". +; Script path: Set value to "path:/path/to/script.js". +;filter_script=function filter(node) {\n const info = JSON.parse(node.ProxyInfo);\n if(info.EncryptMethod.includes('chacha20'))\n return true;\n return false;\n} + +;Setting an external config file as default when none is specified, supports local files/URL +;default_external_config=config/example_external_config.ini + +;The file scope limit of the 'rule_base' options in external configs. +base_path=base + +;Clash config base used by the generator, supports local files/URL +clash_rule_base=base/all_base.tpl + +;Surge config base used by the generator, supports local files/URL +surge_rule_base=base/all_base.tpl + +;Surfboard config base used by the generator, supports local files/URL +surfboard_rule_base=base/all_base.tpl + +;Mellow config base used by the generator, supports local files/URL +mellow_rule_base=base/all_base.tpl + +;Quantumult config base used by the generator, supports local files/URL +quan_rule_base=base/all_base.tpl + +;Quantumult X config base used by the generator, supports local files/URL +quanx_rule_base=base/all_base.tpl + +;Loon config base used by the generator, supports local files/URL +loon_rule_base=base/all_base.tpl + +;Shadowsocks Android config base used by the generator, supports local files/URL +sssub_rule_base=base/all_base.tpl + +;Proxy used to download configs, rulesets or subscriptions, set to NONE or empty to disable it, set to SYSTEM to use system proxy. +;Accept cURL-supported proxies (http:// https:// socks4a:// socks5://) +;Additional support for CORS proxy ( https://github.com/Rob--W/cors-anywhere https://github.com/Zibri/cloudflare-cors-anywhere etc.), prefix the address with "cors:" to recognize the address as CORS proxy. +;Example: http://127.0.0.1:80 socks5://example.com:1080 cors:https://cors-anywhere.herokuapp.com/ +proxy_config=SYSTEM +proxy_ruleset=SYSTEM +proxy_subscription=NONE + +;Append a proxy type string ([SS] [SSR] [VMess]) to node remark. +append_proxy_type=false + +[userinfo] +;Rules to extract stream data from node +;Format: full_match_regex|new_format_regex +;where new_format_regex should be like "total=$1&left=$2&used=$3" +stream_rule=^剩余流量:(.*?)\|总流量:(.*)$|total=$2&left=$1 +stream_rule=^剩余流量:(.*?) (.*)$|total=$1&left=$2 +stream_rule=^Bandwidth: (.*?)/(.*)$|used=$1&total=$2 +stream_rule=^\[.*?\]剩余(.*?)@(?:.*)$|total=$1 +stream_rule=^.*?流量:(.*?) 剩:(?:.*)$|total=$1 + +;Rules to extract expire time data from node +;Format: full_match_regex|new_format_regex +;where new_format_regex should follow this example: yyyy:mm:dd:hh:mm:ss +time_rule=^过期时间:(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)$|$1:$2:$3:$4:$5:$6 +time_rule=^到期时间(:|:)(\d+)-(\d+)-(\d+)$|$1:$2:$3:0:0:0 +time_rule=^Smart Access expire: (\d+)/(\d+)/(\d+)$|$1:$2:$3:0:0:0 +time_rule=^.*?流量:(?:.*?) 剩:(.*)$|left=$1d + +[node_pref] +;udp_flag=false +;tcp_fast_open_flag=false +;skip_cert_verify_flag=false +;tls13_flag=false + +sort_flag=false +;Script used for sorting nodes. A "compare" function with 2 arguments which are the 2 nodes to be compared should be defined in the script. Supports inline script and script path. +;Examples can be seen at the filter_script option in [common] section. +;sort_script=function compare(node_a, node_b) {\n const info_a = JSON.parse(node_a.ProxyInfo);\n const info_b = JSON.parse(node_b.ProxyInfo);\n return info_a.Remark > info_b.Remark;\n} + +filter_deprecated_nodes=false +append_sub_userinfo=true +clash_use_new_field_name=true + +;Generate style of the proxies section of Clash subscriptions. +;Supported styles: block, flow, compact +;Block: - name: name1 Flow: - {name: name1, key: value} Compact: [{name: name1, key: value},{name: name2, key: value}] +; key: value - {name: name2, key: value} +; - name: name2 +; key: value +clash_proxies_style=flow + +;Rename remarks with the following patterns. Supports regular expression. +;Format: Search_Pattern@Replace_Pattern +;rename_node=IPLC@专线 +;rename_node=RELAY@中转 +;rename_node=BGP-@ +;rename_node=!!script:function rename(node) {\n const info = JSON.parse(node.ProxyInfo);\n const geoinfo = JSON.parse(geoip(info.Hostname));\n if(geoinfo.country_code == "CN")\n return "CN " + node.Remark;\n} +;rename_node=!!script:path:/path/to/script.js + +rename_node=!!import:snippets/rename_node.txt + +[managed_config] +;Append a '#!MANAGED-CONFIG' info to Surge configurations +write_managed_config=true + +;Address prefix for MANAGED-CONFIG info, without the trailing "/". +;This address will also be used for generating /getruleset, /qx-rewrite, /qx-script addresses. +managed_config_prefix=http://127.0.0.1:25500 + +;Managed config update interval in seconds, determine how long the config will be updated. +config_update_interval=86400 + +;If config_update_strict is set to true, Surge will require a force update after the interval. +config_update_strict=false + +;Device ID to be written to rewrite scripts for some version of Quantumult X +quanx_device_id= + +[surge_external_proxy] +;surge_ssr_path=/usr/bin/ssr-local +resolve_hostname=true + +[emojis] +add_emoji=true +remove_old_emoji=true + +;Rule to add emojis. Supports regular expression. +;Format: Remark_Search_Pattern,emoji + +;rule=(流量|时间|应急|过期|Bandwidth|expire),🏳️‍🌈 +;rule=AC,🇦🇨 +;rule=!!script:function getEmoji(node) {\n const info = JSON.parse(node.ProxyInfo);\n const geoinfo = JSON.parse(geoip(info.Hostname));\n if(geoinfo.country_code == "CN")\n return "🏳️‍🌈";\n} +;rule=!!script:path:/path/to/script/.js + +rule=!!import:snippets/emoji.txt + +[rulesets] +;Enable generating rules with rulesets +enabled=true + +;Overwrite the existing rules in rule_base +overwrite_original_rules=false + +;Perform a ruleset update on request +update_ruleset_on_request=false + +;Ruleset addresses, supports local files/URL +;Format: Group name,[type:]URL[,interval] +; Group name,[]Rule +;where "type" supports the following value: surge, quanx, clash-domain, clash-ipcidr, clash-classic +;type defaults to surge if omitted + +;ruleset=DIRECT,https://raw.githubusercontent.com/DivineEngine/Profiles/master/Surge/Ruleset/Guard/Unbreak.list,86400 +;ruleset=🎯 全球直连,rules/LocalAreaNetwork.list +;ruleset=DIRECT,surge:rules/LocalAreaNetwork.list +;ruleset=Advertising,quanx:https://raw.githubusercontent.com/DivineEngine/Profiles/master/Quantumult/Filter/Guard/Advertising.list,86400 +;ruleset=Domestic Services,clash-domain:https://ruleset.dev/clash_domestic_services_domains,86400 +;ruleset=Domestic Services,clash-ipcidr:https://ruleset.dev/clash_domestic_services_ips,86400 +;ruleset=DIRECT,clash-classic:https://raw.githubusercontent.com/DivineEngine/Profiles/master/Clash/RuleSet/China.yaml,86400 +;ruleset=🎯 全球直连,[]GEOIP,CN +;ruleset=🐟 漏网之鱼,[]FINAL + +ruleset=!!import:snippets/rulesets.txt + +[proxy_groups] +;Generate Clash Proxy Group with the following patterns. Node filtering rule supports regular expression. +;Format: Group_Name`select`Rule_1`Rule_2`... +; Group_Name`url-test|fallback|load-balance`Rule_1`Rule_2`...`test_url`interval[,timeout][,tolerance] +;Rule with "[]" prefix will be added directly. + +;custom_proxy_group=Proxy`select`.*`[]AUTO`[]DIRECT`.* +;custom_proxy_group=UrlTest`url-test`.*`http://www.gstatic.com/generate_204`300,5,100 +;custom_proxy_group=FallBack`fallback`.*`http://www.gstatic.com/generate_204`300,5 +;custom_proxy_group=LoadBalance`load-balance`.*`http://www.gstatic.com/generate_204`300,,100 +;custom_proxy_group=SSID`ssid`default_group`celluar=group0,ssid1=group1,ssid2=group2 + +;custom_proxy_group=g1`select`!!GROUPID=0 +;custom_proxy_group=g2`select`!!GROUPID=1 +;custom_proxy_group=v2ray`select`!!GROUP=V2RayProvider + +;custom_proxy_group=g1hk`select`!!GROUPID=0!!(HGC|HKBN|PCCW|HKT|hk|港) +;custom_proxy_group=sstw`select`!!GROUP=V2RayProvider!!(深台|彰化|新北|台|tw) +;custom_proxy_group=provider`select`!!PROVIDER=prov1,prov2,prov3`fallback_nodes + +;Also supports using script for filtering nodes. A "filter" function with one argument which is an array of all available nodes should be defined in the script. +;custom_proxy_group=script`select`script:/path/to/script.js + +;for forcerule.yml +;custom_proxy_group=!!import:snippets/groups_forcerule.txt + +;for Surge rulesets +custom_proxy_group=!!import:snippets/groups.txt + +[template] +;The file scope limit of 'include' statement inside the templates. +template_path= + +;The following settings will be added to the "global" scope of the template variables +;Value of 'clash.http_port' can be accessed with 'global.clash.http_port' in the template. +clash.http_port=7890 +clash.socks_port=7891 +clash.allow_lan=true +clash.log_level=info + +[aliases] +;Aliases for accessing interfaces. Can be used to shorten the URI. +;All arguments passed when accessing the alias name will be appended to the arguments of the alias target. +;Format: uri=target +/v=/version +/clash=/sub?target=clash +/clashr=/sub?target=clashr +/surge=/sub?target=surge +/quan=/sub?target=quan +/quanx=/sub?target=quanx +/mellow=/sub?target=mellow +/surfboard=/sub?target=surfboard +/loon=/sub?target=loon +/ss=/sub?target=ss +/ssd=/sub?target=ssd +/sssub=/sub?target=sssub +/ssr=/sub?target=ssr +/v2ray=/sub?target=v2ray +/trojan=/sub?target=trojan + +[tasks] +;Tasks to be run regularly during server execution. +;Format: Name`Cron_Expression`JS_Path`Timeout_in_seconds +;task=tick`0/10 * * * * ?`tick.js`3 + +[server] +;Address to bind on for Web Server +listen=0.0.0.0 + +;Port to bind on for Web Server +port=25500 + +;Root folder for web server, keep empty to disable +serve_file_root= + +[advanced] +log_level=info +print_debug_info=false +max_pending_connections=10240 +max_concurrent_threads=2 +max_allowed_rulesets=0 +max_allowed_rules=0 +max_allowed_download_size=0 +enable_cache=false +cache_subscription=60 +cache_config=300 +cache_ruleset=21600 +script_clean_context=true +async_fetch_ruleset=false +skip_failed_links=false diff --git a/tools/subconverter/pref.example.toml b/tools/subconverter/pref.example.toml new file mode 100644 index 0000000..cb352a8 --- /dev/null +++ b/tools/subconverter/pref.example.toml @@ -0,0 +1,322 @@ +version = 1 +[common] +# API mode, set to true to prevent loading local subscriptions or serving local files directly +api_mode = false + +# Access token used for performing critical action through Web interface +api_access_token = "password" + +# Default URLs, used when no URL is provided in request, use "|" to separate multiple subscription links, supports local files/URL +default_url = [] + +# Insert subscription links to requests. Can be used to add node(s) to all exported subscriptions. +enable_insert = true +# URLs to insert before subscription links, can be used to add node(s) to all exported subscriptions, supports local files/URL +insert_url = [""] +# Prepend inserted URLs to subscription links. Nodes in insert_url will be added to groups first with non-group-specific match pattern. +prepend_insert_url = true + +# Exclude nodes which remarks match the following patterns. Supports regular expression. +exclude_remarks = ["(到期|剩余流量|时间|官网|产品)"] + +# Only include nodes which remarks match the following patterns. Supports regular expression. +#include_remarks = ["V3.*港"] + +# Enable script support for filtering nodes +enable_filter = false +# Script used for filtering nodes. Supports inline script and script path. A "filter" function with 1 argument which is a node should be defined in the script. +# Example: Inline script: Set value to content of script. +# Script path: Set value to "path:/path/to/script.js". +#filter_script = ''' +#function filter(node) { +# const info = JSON.parse(node.ProxyInfo); +# if(info.EncryptMethod.includes('chacha20')) +# return true; +# return false; +#} +#''' + +# Setting an external config file as default when none is specified, supports local files/URL +# default_external_config = "config/example_external_config.toml" + +# The file scope limit of the 'rule_base' options in external configs. +base_path = "base" + +# Clash config base used by the generator, supports local files/URL +clash_rule_base = "base/all_base.tpl" + +# Surge config base used by the generator, supports local files/URL +surge_rule_base = "base/all_base.tpl" + +# Surfboard config base used by the generator, supports local files/URL +surfboard_rule_base = "base/all_base.tpl" + +# Mellow config base used by the generator, supports local files/URL +mellow_rule_base = "base/all_base.tpl" + +# Quantumult config base used by the generator, supports local files/URL +quan_rule_base = "base/all_base.tpl" + +# Quantumult X config base used by the generator, supports local files/URL +quanx_rule_base = "base/all_base.tpl" + +# Loon config base used by the generator, supports local files/URL +loon_rule_base = "base/all_base.tpl" + +# Shadowsocks Android config base used by the generator, supports local files/URL +sssub_rule_base = "base/all_base.tpl" + +# Proxy used to download rulesets or subscriptions, set to NONE or empty to disable it, set to SYSTEM to use system proxy. +# Accept cURL-supported proxies (http:// https:// socks4a:// socks5://) + +proxy_config = "SYSTEM" +proxy_ruleset = "SYSTEM" +proxy_subscription = "NONE" + +# Append a proxy type string ([SS] [SSR] [VMess]) to node remark. +append_proxy_type = false + +[[userinfo.stream_rule]] +# Rules to extract stream data from node +# Format: full_match_regex|new_format_regex +# where new_format_regex should be like "total=$1&left=$2&used=$3" +match = '^剩余流量:(.*?)\|总流量:(.*)$' +replace = 'total=$2&left=$1' + +[[userinfo.stream_rule]] +match = '^剩余流量:(.*?) (.*)$' +replace = 'total=$1&left=$2' + +[[userinfo.stream_rule]] +match = '^Bandwidth: (.*?)/(.*)$' +replace = 'used=$1&total=$2' + +[[userinfo.stream_rule]] +match = '^.*剩余(.*?)(?:\s*?)@(?:.*)$' +replace = 'total=$1' + +[[userinfo.time_rule]] +# Rules to extract expire time data from node +# Format: full_match_regex|new_format_regex +# where new_format_regex should follow this example: yyyy:mm:dd:hh:mm:ss +match = '^过期时间:(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)$' +replace = '$1:$2:$3:$4:$5:$6' + +[[userinfo.time_rule]] +match = '^到期时间:(\d+)-(\d+)-(\d+)$' +replace = '$1:$2:$3:0:0:0' + +[[userinfo.time_rule]] +match = '^Smart Access expire: (\d+)/(\d+)/(\d+)$' +replace = '$1:$2:$3:0:0:0' + +[node_pref] +udp_flag = true +tcp_fast_open_flag = false +skip_cert_verify_flag = true +tls13_flag = false + +sort_flag = false +# Script used for sorting nodes. A "compare" function with 2 arguments which are the 2 nodes to be compared should be defined in the script. Supports inline script and script path. +# Examples can be seen at the filter_script option in [common] section. +#sort_script = ''' +#function compare(node_a, node_b) { +# return info_a.Remark > info_b.Remark; +#} +#''' + +filter_deprecated_nodes = false +append_sub_userinfo = true +clash_use_new_field_name = true + +# Generate style of the proxies section of Clash subscriptions. +# Supported styles: block, flow, compact +# Block: - name: name1 Flow: - {name: name1, key: value} Compact: [{name: name1, key: value},{name: name2, key: value}] +# key: value - {name: name2, key: value} +# - name: name2 +# key: value +clash_proxies_style = "flow" + +[[node_pref.rename_node]] +match = '\(?((x|X)?(\d+)(\.?\d+)?)((\s?倍率?)|(x|X))\)?' +replace = "$1x" + +[managed_config] +# Append a '#!MANAGED-CONFIG' info to Surge configurations +write_managed_config = true + +# Address prefix for MANAGED-CONFIG info, without the trailing "/". +managed_config_prefix = "http://127.0.0.1:25500" + +# Managed config update interval in seconds, determine how long the config will be updated. +config_update_interval = 86400 + +# If config_update_strict is set to true, Surge will require a force update after the interval. +config_update_strict = false + +# Device ID to be written to rewrite scripts for some version of Quantumult X +quanx_device_id = "" + +[surge_external_proxy] +#surge_ssr_path = "/usr/bin/ssr-local" +resolve_hostname = true + +[emojis] +add_emoji = false +remove_old_emoji = true + +[[emojis.emoji]] +#match = '(流量|时间|应急)' +#emoji = '🏳️‍🌈' +import = "snippets/emoji.toml" + +# [[custom_groups]] +# name = "Auto" +# type = "url-test" +# rule = [".*"] +# url = "http://www.gstatic.com/generate_204" +# interval = 300 +# tolerance = 150 +# lazy = true + +# [[custom_groups]] +# name = "Proxy" +# type = "select" +# rule = [".*", "[]DIRECT"] +# disable_udp = false + +# [[custom_groups]] +# name = "LoadBalance" +# type = "load-balance" +# rule = [".*", "[]Proxy", "[]DIRECT"] +# interval = 100 +# strategy = "consistent-hashing" +# url = "http://www.gstatic.com/generate_204" + +[[custom_groups]] +import = "snippets/groups.toml" + +[ruleset] +# Enable generating rules with rulesets +enabled = true + +# Overwrite the existing rules in rule_base +overwrite_original_rules = false + +# Perform a ruleset update on request +update_ruleset_on_request = false + +# [[rulesets]] +# group = "Proxy" +# ruleset = "https://raw.githubusercontent.com/DivineEngine/Profiles/master/Surge/Ruleset/Unbreak.list" +# type = "surge-ruleset" +# interval = 86400 + +[[rulesets]] +import = "snippets/rulesets.toml" + +[template] +template_path = "" + +[[template.globals]] +key = "clash.http_port" +value = "7890" + +[[template.globals]] +key = "clash.socks_port" +value = "7891" + +[[template.globals]] +key = "clash.allow_lan" +value = "true" + +[[template.globals]] +key = "clash.log_level" +value = "info" + +[[aliases]] +uri = "/clash" +target = "/sub?target=clash" + +[[aliases]] +uri = "/clashr" +target = "/sub?target=clashr" + +[[aliases]] +uri = "/surge" +target = "/sub?target=surge" + +[[aliases]] +uri = "/quan" +target = "/sub?target=quan" + +[[aliases]] +uri = "/quanx" +target = "/sub?target=quanx" + +[[aliases]] +uri = "/mellow" +target = "/sub?target=mellow" + +[[aliases]] +uri = "/surfboard" +target = "/sub?target=surfboard" + +[[aliases]] +uri = "/loon" +target = "/sub?target=loon" + +[[aliases]] +uri = "/ss" +target = "/sub?target=ss" + +[[aliases]] +uri = "/ssd" +target = "/sub?target=ssd" + +[[aliases]] +uri = "/sssub" +target = "/sub?target=sssub" + +[[aliases]] +uri = "/ssr" +target = "/sub?target=ssr" + +[[aliases]] +uri = "/v2ray" +target = "/sub?target=v2ray" + +[[aliases]] +uri = "/trojan" +target = "/sub?target=trojan" + +[[aliases]] +uri = "/test" +target = "/render?path=templates/test.tpl" + +#[[tasks]] +#name = "tick" +#cronexp = "0/10 * * * * ?" +#path = "tick.js" +#timeout = 3 + +[server] +listen = "0.0.0.0" +port = 25500 +serve_file_root = "web" + +[advanced] +log_level = "debug" +print_debug_info = true +max_pending_connections = 10240 +max_concurrent_threads = 4 +max_allowed_rulesets = 64 +max_allowed_rules = 0 +max_allowed_download_size = 0 +enable_cache = true +cache_subscription = 60 +cache_config = 300 +cache_ruleset = 21600 +script_clean_context = true +async_fetch_ruleset = false +skip_failed_links = true diff --git a/tools/subconverter/subconverter b/tools/subconverter/subconverter new file mode 100644 index 0000000..15359a7 Binary files /dev/null and b/tools/subconverter/subconverter differ