mirror of
https://github.com/asdlokj1qpi233/subconverter.git
synced 2025-10-26 19:32:55 +00:00
Add support for exporting complete Quantumult configuration file
Fix incorrect generation of Quantumult X configuratios. Fix broken group name option. Add external configuration support for customize Quantumult(X) base. Update Travis CI build script. Tweak Emoji match rules. Clean up codes.
This commit is contained in:
19
.travis.yml
19
.travis.yml
@@ -1,11 +1,11 @@
|
|||||||
language: cpp
|
language: cpp
|
||||||
sudo: required
|
os: linux
|
||||||
stages:
|
stages:
|
||||||
- name: deploy
|
- name: deploy
|
||||||
if: branch = master
|
if: branch = master
|
||||||
- name: before_script
|
- name: before_script
|
||||||
if: branch = master
|
if: branch = master
|
||||||
matrix:
|
jobs:
|
||||||
include:
|
include:
|
||||||
- name: "macOS Build"
|
- name: "macOS Build"
|
||||||
os: osx
|
os: osx
|
||||||
@@ -15,9 +15,8 @@ matrix:
|
|||||||
- bash scripts/build.macos.release.sh
|
- bash scripts/build.macos.release.sh
|
||||||
deploy:
|
deploy:
|
||||||
provider: releases
|
provider: releases
|
||||||
api_key: "$GITHUB_OAUTH_TOKEN"
|
token: "$GITHUB_OAUTH_TOKEN"
|
||||||
file: "subconverter_darwin64.tar.gz"
|
file: "subconverter_darwin64.tar.gz"
|
||||||
skip_cleanup: true
|
|
||||||
draft: true
|
draft: true
|
||||||
on:
|
on:
|
||||||
tags: true
|
tags: true
|
||||||
@@ -29,9 +28,8 @@ matrix:
|
|||||||
- mv subconverter_linux64.tar.gz subconverter_linux32.tar.gz
|
- mv subconverter_linux64.tar.gz subconverter_linux32.tar.gz
|
||||||
deploy:
|
deploy:
|
||||||
provider: releases
|
provider: releases
|
||||||
api_key: "$GITHUB_OAUTH_TOKEN"
|
token: "$GITHUB_OAUTH_TOKEN"
|
||||||
file: "subconverter_linux32.tar.gz"
|
file: "subconverter_linux32.tar.gz"
|
||||||
skip_cleanup: true
|
|
||||||
draft: true
|
draft: true
|
||||||
on:
|
on:
|
||||||
tags: true
|
tags: true
|
||||||
@@ -41,9 +39,8 @@ matrix:
|
|||||||
- docker run -v $TRAVIS_BUILD_DIR:/root/workdir alpine:latest /bin/sh -c "apk add bash git && cd /root/workdir && chmod +x scripts/build.alpine.release.sh && bash scripts/build.alpine.release.sh"
|
- docker run -v $TRAVIS_BUILD_DIR:/root/workdir alpine:latest /bin/sh -c "apk add bash git && cd /root/workdir && chmod +x scripts/build.alpine.release.sh && bash scripts/build.alpine.release.sh"
|
||||||
deploy:
|
deploy:
|
||||||
provider: releases
|
provider: releases
|
||||||
api_key: "$GITHUB_OAUTH_TOKEN"
|
token: "$GITHUB_OAUTH_TOKEN"
|
||||||
file: "subconverter_linux64.tar.gz"
|
file: "subconverter_linux64.tar.gz"
|
||||||
skip_cleanup: true
|
|
||||||
draft: true
|
draft: true
|
||||||
on:
|
on:
|
||||||
tags: true
|
tags: true
|
||||||
@@ -56,9 +53,8 @@ matrix:
|
|||||||
- mv subconverter_linux64.tar.gz subconverter_armhf.tar.gz
|
- mv subconverter_linux64.tar.gz subconverter_armhf.tar.gz
|
||||||
deploy:
|
deploy:
|
||||||
provider: releases
|
provider: releases
|
||||||
api_key: "$GITHUB_OAUTH_TOKEN"
|
token: "$GITHUB_OAUTH_TOKEN"
|
||||||
file: "subconverter_armhf.tar.gz"
|
file: "subconverter_armhf.tar.gz"
|
||||||
skip_cleanup: true
|
|
||||||
draft: true
|
draft: true
|
||||||
on:
|
on:
|
||||||
tags: true
|
tags: true
|
||||||
@@ -71,9 +67,8 @@ matrix:
|
|||||||
- mv subconverter_linux64.tar.gz subconverter_aarch64.tar.gz
|
- mv subconverter_linux64.tar.gz subconverter_aarch64.tar.gz
|
||||||
deploy:
|
deploy:
|
||||||
provider: releases
|
provider: releases
|
||||||
api_key: "$GITHUB_OAUTH_TOKEN"
|
token: "$GITHUB_OAUTH_TOKEN"
|
||||||
file: "subconverter_aarch64.tar.gz"
|
file: "subconverter_aarch64.tar.gz"
|
||||||
skip_cleanup: true
|
|
||||||
draft: true
|
draft: true
|
||||||
on:
|
on:
|
||||||
tags: true
|
tags: true
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ clash_rule_base=config/forcerule.yml
|
|||||||
;surge_rule_base=surge.conf
|
;surge_rule_base=surge.conf
|
||||||
;surfboard_rule_base=surfboard.conf
|
;surfboard_rule_base=surfboard.conf
|
||||||
;mellow_rule_base=mellow.conf
|
;mellow_rule_base=mellow.conf
|
||||||
|
;quan_rule_base=quan.conf
|
||||||
|
;quanx_rule_base=quanx.conf
|
||||||
|
|
||||||
;Options for renaming nodes
|
;Options for renaming nodes
|
||||||
;rename=Test-(.*?)-(.*?)-(.*?)\((.*?)\)@\1\4x测试线路_自\2到\3
|
;rename=Test-(.*?)-(.*?)-(.*?)\((.*?)\)@\1\4x测试线路_自\2到\3
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ surfboard_rule_base=surfboard.conf
|
|||||||
;Mellow config base used by the generator, supports local files/URL
|
;Mellow config base used by the generator, supports local files/URL
|
||||||
mellow_rule_base=mellow.conf
|
mellow_rule_base=mellow.conf
|
||||||
|
|
||||||
|
;Quantumult X config base used by the generator, supports local files/URL
|
||||||
|
quan_rule_base=quan.conf
|
||||||
|
|
||||||
;Quantumult X config base used by the generator, supports local files/URL
|
;Quantumult X config base used by the generator, supports local files/URL
|
||||||
quanx_rule_base=quanx.conf
|
quanx_rule_base=quanx.conf
|
||||||
|
|
||||||
@@ -146,8 +149,8 @@ rule=ES,🇪🇸
|
|||||||
rule=EU,🇪🇺
|
rule=EU,🇪🇺
|
||||||
rule=(Finland|芬兰|赫尔辛基),🇫🇮
|
rule=(Finland|芬兰|赫尔辛基),🇫🇮
|
||||||
rule=(FR|France|法国|巴黎),🇫🇷
|
rule=(FR|France|法国|巴黎),🇫🇷
|
||||||
rule=(UK|England|UnitedKingdom|英国|英|伦敦),🇬🇧
|
rule=(UK|England|United.*?Kingdom|英国|英|伦敦),🇬🇧
|
||||||
rule=(HK|HongKong|香港|深港|沪港|呼港|HKT|HKBN|HGC|WTT|CMI|穗港|京港|港),🇭🇰
|
rule=(?i)(HK|Hong.*?Kong|香港|深港|沪港|呼港|HKT|HKBN|HGC|WTT|CMI|穗港|京港|港),🇭🇰
|
||||||
rule=(Indonesia|印尼|印度尼西亚|雅加达),🇮🇩
|
rule=(Indonesia|印尼|印度尼西亚|雅加达),🇮🇩
|
||||||
rule=(Ireland|爱尔兰|都柏林),🇮🇪
|
rule=(Ireland|爱尔兰|都柏林),🇮🇪
|
||||||
rule=(India|印度|孟买),🇮🇳
|
rule=(India|印度|孟买),🇮🇳
|
||||||
|
|||||||
27
base/quan.conf
Normal file
27
base/quan.conf
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
[SERVER]
|
||||||
|
|
||||||
|
[SOURCE]
|
||||||
|
|
||||||
|
[BACKUP-SERVER]
|
||||||
|
|
||||||
|
[SUSPEND-SSID]
|
||||||
|
|
||||||
|
[POLICY]
|
||||||
|
|
||||||
|
[DNS]
|
||||||
|
1.1.1.1
|
||||||
|
|
||||||
|
[REWRITE]
|
||||||
|
|
||||||
|
[URL-REJECTION]
|
||||||
|
|
||||||
|
[TCP]
|
||||||
|
|
||||||
|
[GLOBAL]
|
||||||
|
|
||||||
|
[HOST]
|
||||||
|
|
||||||
|
[STATE]
|
||||||
|
STATE,AUTO
|
||||||
|
|
||||||
|
[MITM]
|
||||||
49
src/main.cpp
49
src/main.cpp
@@ -40,7 +40,7 @@ std::string proxy_ruleset, proxy_subscription;
|
|||||||
|
|
||||||
std::string clash_rule_base;
|
std::string clash_rule_base;
|
||||||
string_array clash_extra_group;
|
string_array clash_extra_group;
|
||||||
std::string surge_rule_base, surfboard_rule_base, mellow_rule_base, quanx_rule_base;
|
std::string surge_rule_base, surfboard_rule_base, mellow_rule_base, quan_rule_base, quanx_rule_base;
|
||||||
std::string surge_ssr_path;
|
std::string surge_ssr_path;
|
||||||
|
|
||||||
//pre-compiled rule bases
|
//pre-compiled rule bases
|
||||||
@@ -172,6 +172,8 @@ void readConf()
|
|||||||
surfboard_rule_base = ini.Get("surfboard_rule_base");
|
surfboard_rule_base = ini.Get("surfboard_rule_base");
|
||||||
if(ini.ItemExist("mellow_rule_base"))
|
if(ini.ItemExist("mellow_rule_base"))
|
||||||
mellow_rule_base = ini.Get("mellow_rule_base");
|
mellow_rule_base = ini.Get("mellow_rule_base");
|
||||||
|
if(ini.ItemExist("quan_rule_base"))
|
||||||
|
quan_rule_base = ini.Get("quan_rule_base");
|
||||||
if(ini.ItemExist("quanx_rule_base"))
|
if(ini.ItemExist("quanx_rule_base"))
|
||||||
quanx_rule_base = ini.Get("quanx_rule_base");
|
quanx_rule_base = ini.Get("quanx_rule_base");
|
||||||
if(ini.ItemExist("append_proxy_type"))
|
if(ini.ItemExist("append_proxy_type"))
|
||||||
@@ -289,6 +291,8 @@ struct ExternalConfig
|
|||||||
std::string surge_rule_base;
|
std::string surge_rule_base;
|
||||||
std::string surfboard_rule_base;
|
std::string surfboard_rule_base;
|
||||||
std::string mellow_rule_base;
|
std::string mellow_rule_base;
|
||||||
|
std::string quan_rule_base;
|
||||||
|
std::string quanx_rule_base;
|
||||||
string_array rename;
|
string_array rename;
|
||||||
string_array emoji;
|
string_array emoji;
|
||||||
bool overwrite_original_rules = false;
|
bool overwrite_original_rules = false;
|
||||||
@@ -305,7 +309,6 @@ int loadExternalConfig(std::string &path, ExternalConfig &ext, std::string proxy
|
|||||||
|
|
||||||
INIReader ini;
|
INIReader ini;
|
||||||
ini.store_isolated_line = true;
|
ini.store_isolated_line = true;
|
||||||
ini.keep_empty_section = false;
|
|
||||||
ini.SetIsolatedItemsSection("custom");
|
ini.SetIsolatedItemsSection("custom");
|
||||||
if(ini.Parse(base_content) != INIREADER_EXCEPTION_NONE)
|
if(ini.Parse(base_content) != INIREADER_EXCEPTION_NONE)
|
||||||
{
|
{
|
||||||
@@ -327,6 +330,10 @@ int loadExternalConfig(std::string &path, ExternalConfig &ext, std::string proxy
|
|||||||
ext.surfboard_rule_base = ini.Get("surfboard_rule_base");
|
ext.surfboard_rule_base = ini.Get("surfboard_rule_base");
|
||||||
if(ini.ItemExist("mellow_rule_base"))
|
if(ini.ItemExist("mellow_rule_base"))
|
||||||
ext.mellow_rule_base = ini.Get("mellow_rule_base");
|
ext.mellow_rule_base = ini.Get("mellow_rule_base");
|
||||||
|
if(ini.ItemExist("quan_rule_base"))
|
||||||
|
ext.quan_rule_base = ini.Get("quan_rule_base");
|
||||||
|
if(ini.ItemExist("quanx_rule_base"))
|
||||||
|
ext.quanx_rule_base = ini.Get("quanx_rule_base");
|
||||||
|
|
||||||
if(ini.ItemExist("overwrite_original_rules"))
|
if(ini.ItemExist("overwrite_original_rules"))
|
||||||
ext.overwrite_original_rules = ini.GetBool("overwrite_original_rules");
|
ext.overwrite_original_rules = ini.GetBool("overwrite_original_rules");
|
||||||
@@ -390,6 +397,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
|||||||
|
|
||||||
//for external configuration
|
//for external configuration
|
||||||
std::string ext_clash_base = clash_rule_base, ext_surge_base = surge_rule_base, ext_mellow_base = mellow_rule_base, ext_surfboard_base = surfboard_rule_base;
|
std::string ext_clash_base = clash_rule_base, ext_surge_base = surge_rule_base, ext_mellow_base = mellow_rule_base, ext_surfboard_base = surfboard_rule_base;
|
||||||
|
std::string ext_quan_base = quan_rule_base, ext_quanx_base = quanx_rule_base;
|
||||||
|
|
||||||
//validate urls
|
//validate urls
|
||||||
if(!url.size())
|
if(!url.size())
|
||||||
@@ -434,6 +442,10 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
|||||||
ext_surfboard_base = extconf.surfboard_rule_base;
|
ext_surfboard_base = extconf.surfboard_rule_base;
|
||||||
if(extconf.mellow_rule_base.size())
|
if(extconf.mellow_rule_base.size())
|
||||||
ext_mellow_base = extconf.mellow_rule_base;
|
ext_mellow_base = extconf.mellow_rule_base;
|
||||||
|
if(extconf.quan_rule_base.size())
|
||||||
|
ext_quan_base = extconf.quan_rule_base;
|
||||||
|
if(extconf.quanx_rule_base.size())
|
||||||
|
ext_quanx_base = extconf.quanx_rule_base;
|
||||||
if(extconf.rename.size())
|
if(extconf.rename.size())
|
||||||
ext.rename_array = extconf.rename;
|
ext.rename_array = extconf.rename;
|
||||||
if(extconf.emoji.size())
|
if(extconf.emoji.size())
|
||||||
@@ -530,10 +542,6 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
|||||||
else
|
else
|
||||||
exclude_remarks = def_exclude_remarks;
|
exclude_remarks = def_exclude_remarks;
|
||||||
|
|
||||||
//check custom group name
|
|
||||||
if(group.size())
|
|
||||||
custom_group = group;
|
|
||||||
|
|
||||||
//start parsing urls
|
//start parsing urls
|
||||||
string_array stream_temp = safe_get_streams(), time_temp = safe_get_times();
|
string_array stream_temp = safe_get_streams(), time_temp = safe_get_times();
|
||||||
for(std::string &x : urls)
|
for(std::string &x : urls)
|
||||||
@@ -554,6 +562,11 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
|||||||
return "No nodes were found!";
|
return "No nodes were found!";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//check custom group name
|
||||||
|
if(group.size())
|
||||||
|
for(nodeInfo &x : nodes)
|
||||||
|
x.group = group;
|
||||||
|
|
||||||
if(subInfo.size() && groupID == 1)
|
if(subInfo.size() && groupID == 1)
|
||||||
extra_headers.emplace("Subscription-UserInfo", subInfo);
|
extra_headers.emplace("Subscription-UserInfo", subInfo);
|
||||||
|
|
||||||
@@ -667,26 +680,34 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
|||||||
else if(target == "quan")
|
else if(target == "quan")
|
||||||
{
|
{
|
||||||
std::cerr<<"Quantumult"<<std::endl;
|
std::cerr<<"Quantumult"<<std::endl;
|
||||||
output_content = netchToQuan(nodes, ext);
|
if(!ext.nodelist)
|
||||||
|
{
|
||||||
|
if(fileExist(ext_quan_base))
|
||||||
|
base_content = fileGet(ext_quan_base, false);
|
||||||
|
else
|
||||||
|
base_content = webGet(ext_quan_base, getSystemProxy());
|
||||||
|
}
|
||||||
|
|
||||||
|
output_content = netchToQuan(nodes, base_content, rca, extra_group, ext);
|
||||||
|
|
||||||
if(upload == "true")
|
if(upload == "true")
|
||||||
uploadGist("quan", upload_path, output_content, false);
|
uploadGist("quan", upload_path, output_content, false);
|
||||||
}
|
}
|
||||||
else if(target == "quanx")
|
else if(target == "quanx")
|
||||||
{
|
{
|
||||||
std::cerr<<"Quantumult X"<<std::endl;
|
std::cerr<<"Quantumult X"<<std::endl;
|
||||||
|
if(!ext.nodelist)
|
||||||
if(fileExist(quanx_rule_base))
|
{
|
||||||
base_content = fileGet(quanx_rule_base, false);
|
if(fileExist(ext_quanx_base))
|
||||||
|
base_content = fileGet(ext_quanx_base, false);
|
||||||
else
|
else
|
||||||
base_content = webGet(quanx_rule_base, getSystemProxy());
|
base_content = webGet(ext_quanx_base, getSystemProxy());
|
||||||
|
}
|
||||||
|
|
||||||
output_content = netchToQuanX(nodes, base_content, rca, extra_group, ext);
|
output_content = netchToQuanX(nodes, base_content, rca, extra_group, ext);
|
||||||
|
|
||||||
if(upload == "true")
|
if(upload == "true")
|
||||||
uploadGist("quanx", upload_path, output_content, false);
|
uploadGist("quanx", upload_path, output_content, false);
|
||||||
|
|
||||||
if(write_managed_config && managed_config_prefix.size())
|
|
||||||
output_content = "#!MANAGED-CONFIG " + managed_config_prefix + "/sub?" + argument + "\n\n" + output_content;
|
|
||||||
}
|
}
|
||||||
else if(target == "ssd")
|
else if(target == "ssd")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include "webget.h"
|
#include "webget.h"
|
||||||
#include "speedtestutil.h"
|
#include "speedtestutil.h"
|
||||||
|
|
||||||
std::string override_conf_port, custom_group;
|
std::string override_conf_port;
|
||||||
int socksport;
|
int socksport;
|
||||||
bool ss_libev, ssr_libev;
|
bool ss_libev, ssr_libev;
|
||||||
extern bool api_mode;
|
extern bool api_mode;
|
||||||
@@ -107,8 +107,6 @@ int addNodes(std::string link, std::vector<nodeInfo> &allNodes, int groupID, std
|
|||||||
if(linkType > 0)
|
if(linkType > 0)
|
||||||
{
|
{
|
||||||
explode(link, ss_libev, ssr_libev, override_conf_port, socksport, node);
|
explode(link, ss_libev, ssr_libev, override_conf_port, socksport, node);
|
||||||
if(custom_group.size() != 0)
|
|
||||||
node.group = custom_group;
|
|
||||||
if(node.linkType == -1)
|
if(node.linkType == -1)
|
||||||
{
|
{
|
||||||
writeLog(LOG_TYPE_ERROR, "No valid link found.");
|
writeLog(LOG_TYPE_ERROR, "No valid link found.");
|
||||||
|
|||||||
@@ -363,6 +363,9 @@ void rulesetToSurge(INIReader &base_rule, std::vector<ruleset_content> &ruleset_
|
|||||||
case -1:
|
case -1:
|
||||||
base_rule.SetCurrentSection("filter_local"); //Quantumult X
|
base_rule.SetCurrentSection("filter_local"); //Quantumult X
|
||||||
break;
|
break;
|
||||||
|
case -2:
|
||||||
|
base_rule.SetCurrentSection("TCP"); //Quantumult
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
base_rule.SetCurrentSection("Rule");
|
base_rule.SetCurrentSection("Rule");
|
||||||
}
|
}
|
||||||
@@ -382,7 +385,7 @@ void rulesetToSurge(INIReader &base_rule, std::vector<ruleset_content> &ruleset_
|
|||||||
if(strLine == "MATCH")
|
if(strLine == "MATCH")
|
||||||
strLine = "FINAL";
|
strLine = "FINAL";
|
||||||
strLine += "," + rule_group;
|
strLine += "," + rule_group;
|
||||||
if(surge_ver == -1)
|
if(surge_ver == -1 || surge_ver == -2)
|
||||||
{
|
{
|
||||||
if(std::count(strLine.begin(), strLine.end(), ',') > 2 && regReplace(strLine, rule_match_regex, "$2") == ",no-resolve")
|
if(std::count(strLine.begin(), strLine.end(), ',') > 2 && regReplace(strLine, rule_match_regex, "$2") == ",no-resolve")
|
||||||
strLine = regReplace(strLine, rule_match_regex, "$1$3$2");
|
strLine = regReplace(strLine, rule_match_regex, "$1$3$2");
|
||||||
@@ -416,13 +419,13 @@ void rulesetToSurge(INIReader &base_rule, std::vector<ruleset_content> &ruleset_
|
|||||||
strStrm<<retrived_rules;
|
strStrm<<retrived_rules;
|
||||||
while(getline(strStrm, strLine, delimiter))
|
while(getline(strStrm, strLine, delimiter))
|
||||||
{
|
{
|
||||||
if(surge_ver == -1 && (strLine.find("IP-CIDR6") == 0 || strLine.find("URL-REGEX") == 0 || strLine.find("PROCESS-NAME") == 0 || strLine.find("AND") == 0 || strLine.find("OR") == 0)) //remove unsupported types
|
if((surge_ver == -1 || surge_ver == -2) && (strLine.find("IP-CIDR6") == 0 || strLine.find("URL-REGEX") == 0 || strLine.find("PROCESS-NAME") == 0 || strLine.find("AND") == 0 || strLine.find("OR") == 0)) //remove unsupported types
|
||||||
continue;
|
continue;
|
||||||
strLine = replace_all_distinct(strLine, "\r", ""); //remove line break
|
strLine = replace_all_distinct(strLine, "\r", ""); //remove line break
|
||||||
if(!strLine.size() || strLine.find("#") == 0 || strLine.find(";") == 0) //remove comments
|
if(!strLine.size() || strLine.find("#") == 0 || strLine.find(";") == 0) //remove comments
|
||||||
continue;
|
continue;
|
||||||
strLine += "," + rule_group;
|
strLine += "," + rule_group;
|
||||||
if(surge_ver == -1)
|
if(surge_ver == -1 || surge_ver == -2)
|
||||||
{
|
{
|
||||||
if(std::count(strLine.begin(), strLine.end(), ',') > 2 && regReplace(strLine, rule_match_regex, "$2") == ",no-resolve")
|
if(std::count(strLine.begin(), strLine.end(), ',') > 2 && regReplace(strLine, rule_match_regex, "$2") == ",no-resolve")
|
||||||
strLine = regReplace(strLine, rule_match_regex, "$1$3$2");
|
strLine = regReplace(strLine, rule_match_regex, "$1$3$2");
|
||||||
@@ -1246,7 +1249,29 @@ std::string netchToVMess(std::vector<nodeInfo> &nodes, extra_settings &ext)
|
|||||||
return base64_encode(allLinks);
|
return base64_encode(allLinks);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string netchToQuan(std::vector<nodeInfo> &nodes, extra_settings &ext)
|
std::string netchToQuan(std::vector<nodeInfo> &nodes, std::string &base_conf, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, extra_settings &ext)
|
||||||
|
{
|
||||||
|
INIReader ini;
|
||||||
|
ini.store_any_line = true;
|
||||||
|
if(!ext.nodelist && ini.Parse(base_conf) != 0)
|
||||||
|
return std::string();
|
||||||
|
|
||||||
|
netchToQuan(nodes, ini, ruleset_content_array, extra_proxy_group, ext);
|
||||||
|
|
||||||
|
if(ext.nodelist)
|
||||||
|
{
|
||||||
|
string_array allnodes;
|
||||||
|
ini.GetAll("SERVER", "{NONAME}", allnodes);
|
||||||
|
std::string allLinks = std::accumulate(allnodes.begin(), allnodes.end(), allnodes[0], [](std::string a, std::string b)
|
||||||
|
{
|
||||||
|
return std::move(a) + "\n" + std::move(b);
|
||||||
|
});
|
||||||
|
return base64_encode(allLinks);
|
||||||
|
}
|
||||||
|
return ini.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void netchToQuan(std::vector<nodeInfo> &nodes, INIReader &ini, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, extra_settings &ext)
|
||||||
{
|
{
|
||||||
rapidjson::Document json;
|
rapidjson::Document json;
|
||||||
std::string type;
|
std::string type;
|
||||||
@@ -1256,6 +1281,7 @@ std::string netchToQuan(std::vector<nodeInfo> &nodes, extra_settings &ext)
|
|||||||
std::string id, aid, transproto, faketype, host, path, quicsecure, quicsecret;
|
std::string id, aid, transproto, faketype, host, path, quicsecure, quicsecret;
|
||||||
std::string proxyStr, allLinks;
|
std::string proxyStr, allLinks;
|
||||||
bool tlssecure;
|
bool tlssecure;
|
||||||
|
std::vector<nodeInfo> nodelist;
|
||||||
|
|
||||||
std::for_each(nodes.begin(), nodes.end(), [ext](nodeInfo &x)
|
std::for_each(nodes.begin(), nodes.end(), [ext](nodeInfo &x)
|
||||||
{
|
{
|
||||||
@@ -1275,6 +1301,8 @@ std::string netchToQuan(std::vector<nodeInfo> &nodes, extra_settings &ext)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ini.SetCurrentSection("SERVER");
|
||||||
|
ini.EraseSection();
|
||||||
for(nodeInfo &x : nodes)
|
for(nodeInfo &x : nodes)
|
||||||
{
|
{
|
||||||
json.Parse(x.proxyStr.data());
|
json.Parse(x.proxyStr.data());
|
||||||
@@ -1309,6 +1337,8 @@ std::string netchToQuan(std::vector<nodeInfo> &nodes, extra_settings &ext)
|
|||||||
proxyStr += ", certificate=0";
|
proxyStr += ", certificate=0";
|
||||||
if(transproto == "ws")
|
if(transproto == "ws")
|
||||||
proxyStr += ", obfs=ws, obfs-path=\"" + path + "\", obfs-header=\"Host: " + host + "\"";
|
proxyStr += ", obfs=ws, obfs-path=\"" + path + "\", obfs-header=\"Host: " + host + "\"";
|
||||||
|
|
||||||
|
if(ext.nodelist)
|
||||||
proxyStr = "vmess://" + urlsafe_base64_encode(proxyStr);
|
proxyStr = "vmess://" + urlsafe_base64_encode(proxyStr);
|
||||||
break;
|
break;
|
||||||
case SPEEDTEST_MESSAGE_FOUNDSSR:
|
case SPEEDTEST_MESSAGE_FOUNDSSR:
|
||||||
@@ -1317,27 +1347,121 @@ std::string netchToQuan(std::vector<nodeInfo> &nodes, extra_settings &ext)
|
|||||||
obfs = GetMember(json, "OBFS");
|
obfs = GetMember(json, "OBFS");
|
||||||
obfsparam = GetMember(json, "OBFSParam");
|
obfsparam = GetMember(json, "OBFSParam");
|
||||||
|
|
||||||
|
if(ext.nodelist)
|
||||||
|
{
|
||||||
proxyStr = "ssr://" + urlsafe_base64_encode(hostname + ":" + port + ":" + protocol + ":" + method + ":" + obfs + ":" + urlsafe_base64_encode(password) \
|
proxyStr = "ssr://" + urlsafe_base64_encode(hostname + ":" + port + ":" + protocol + ":" + method + ":" + obfs + ":" + urlsafe_base64_encode(password) \
|
||||||
+ "/?group=" + urlsafe_base64_encode(x.group) + "&remarks=" + urlsafe_base64_encode(remark) \
|
+ "/?group=" + urlsafe_base64_encode(x.group) + "&remarks=" + urlsafe_base64_encode(remark) \
|
||||||
+ "&obfsparam=" + urlsafe_base64_encode(obfsparam) + "&protoparam=" + urlsafe_base64_encode(protoparam));
|
+ "&obfsparam=" + urlsafe_base64_encode(obfsparam) + "&protoparam=" + urlsafe_base64_encode(protoparam));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
proxyStr = remark + " = shadowsocksr, " + hostname + ", " + port + ", " + method + ", \"" + password + "\", group=" + x.group + ", protocol=" + protocol + ", obfs=" + obfs;
|
||||||
|
if(protoparam.size())
|
||||||
|
proxyStr += ", protocol_param=" + protoparam;
|
||||||
|
if(obfsparam.size())
|
||||||
|
proxyStr += ", obfs_param=" + obfsparam;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SPEEDTEST_MESSAGE_FOUNDSS:
|
case SPEEDTEST_MESSAGE_FOUNDSS:
|
||||||
plugin = GetMember(json, "Plugin");
|
plugin = GetMember(json, "Plugin");
|
||||||
pluginopts = GetMember(json, "PluginOption");
|
pluginopts = GetMember(json, "PluginOption");
|
||||||
|
|
||||||
|
if(ext.nodelist)
|
||||||
|
{
|
||||||
proxyStr = "ss://" + urlsafe_base64_encode(method + ":" + password) + "@" + hostname + ":" + port;
|
proxyStr = "ss://" + urlsafe_base64_encode(method + ":" + password) + "@" + hostname + ":" + port;
|
||||||
if(plugin.size() & pluginopts.size())
|
if(plugin.size() && pluginopts.size())
|
||||||
{
|
{
|
||||||
proxyStr += "/?plugin=" + UrlEncode(plugin + ";" + pluginopts);
|
proxyStr += "/?plugin=" + UrlEncode(plugin + ";" + pluginopts);
|
||||||
}
|
}
|
||||||
proxyStr += "&group=" + urlsafe_base64_encode(x.group) + "#" + UrlEncode(remark);
|
proxyStr += "&group=" + urlsafe_base64_encode(x.group) + "#" + UrlEncode(remark);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
proxyStr = remark + " = shadowsocks, " + hostname + ", " + port + ", " + method + ", \"" + password + "\", group=" + x.group;
|
||||||
|
if(plugin == "simple-obfs" && pluginopts.size())
|
||||||
|
{
|
||||||
|
proxyStr += ", " + replace_all_distinct(pluginopts, ";", ", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
allLinks += proxyStr + "\n";
|
|
||||||
|
ini.Set("{NONAME}", proxyStr);
|
||||||
|
nodelist.emplace_back(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
return base64_encode(allLinks);
|
if(ext.nodelist)
|
||||||
|
return;
|
||||||
|
|
||||||
|
string_array filtered_nodelist;
|
||||||
|
ini.SetCurrentSection("POLICY");
|
||||||
|
ini.EraseSection();
|
||||||
|
|
||||||
|
std::string singlegroup;
|
||||||
|
std::string name, proxies;
|
||||||
|
string_array vArray;
|
||||||
|
for(std::string &x : extra_proxy_group)
|
||||||
|
{
|
||||||
|
eraseElements(filtered_nodelist);
|
||||||
|
unsigned int rules_upper_bound = 0;
|
||||||
|
|
||||||
|
vArray = split(x, "`");
|
||||||
|
if(vArray.size() < 3)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(vArray[1] == "select")
|
||||||
|
{
|
||||||
|
type = "static";
|
||||||
|
rules_upper_bound = vArray.size();
|
||||||
|
}
|
||||||
|
else if(vArray[1] == "url-test")
|
||||||
|
{
|
||||||
|
if(vArray.size() < 5)
|
||||||
|
continue;
|
||||||
|
type = "auto";
|
||||||
|
rules_upper_bound = vArray.size() - 2;
|
||||||
|
}
|
||||||
|
else if(vArray[1] == "fallback")
|
||||||
|
{
|
||||||
|
if(vArray.size() < 5)
|
||||||
|
continue;
|
||||||
|
type = "static";
|
||||||
|
rules_upper_bound = vArray.size() - 2;
|
||||||
|
}
|
||||||
|
else if(vArray[1] == "load-balance")
|
||||||
|
{
|
||||||
|
if(vArray.size() < 5)
|
||||||
|
continue;
|
||||||
|
type = "balance, round-robin";
|
||||||
|
rules_upper_bound = vArray.size() - 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
name = vArray[0];
|
||||||
|
|
||||||
|
for(unsigned int i = 2; i < rules_upper_bound; i++)
|
||||||
|
groupGenerate(vArray[i], nodelist, filtered_nodelist, true);
|
||||||
|
|
||||||
|
if(!filtered_nodelist.size())
|
||||||
|
filtered_nodelist.emplace_back("direct");
|
||||||
|
|
||||||
|
proxies = std::accumulate(std::next(filtered_nodelist.begin()), filtered_nodelist.end(), filtered_nodelist[0], [](std::string a, std::string b)
|
||||||
|
{
|
||||||
|
return std::move(a) + "\n" + std::move(b);
|
||||||
|
});
|
||||||
|
|
||||||
|
singlegroup = name + " : " + type;
|
||||||
|
if(type == "static")
|
||||||
|
singlegroup += ", " + filtered_nodelist[0];
|
||||||
|
singlegroup += "\n" + proxies + "\n";
|
||||||
|
ini.Set("{NONAME}", base64_encode(singlegroup));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ext.enable_rule_generator)
|
||||||
|
rulesetToSurge(ini, ruleset_content_array, -2, ext.overwrite_original_rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string netchToQuanX(std::vector<nodeInfo> &nodes, std::string &base_conf, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, extra_settings &ext)
|
std::string netchToQuanX(std::vector<nodeInfo> &nodes, std::string &base_conf, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, extra_settings &ext)
|
||||||
@@ -1349,7 +1473,7 @@ std::string netchToQuanX(std::vector<nodeInfo> &nodes, std::string &base_conf, s
|
|||||||
|
|
||||||
netchToQuanX(nodes, ini, ruleset_content_array, extra_proxy_group, ext);
|
netchToQuanX(nodes, ini, ruleset_content_array, extra_proxy_group, ext);
|
||||||
|
|
||||||
if(!ext.nodelist)
|
if(ext.nodelist)
|
||||||
{
|
{
|
||||||
string_array allnodes;
|
string_array allnodes;
|
||||||
ini.GetAll("server_local", "{NONAME}", allnodes);
|
ini.GetAll("server_local", "{NONAME}", allnodes);
|
||||||
@@ -1419,11 +1543,15 @@ void netchToQuanX(std::vector<nodeInfo> &nodes, INIReader &ini, std::vector<rule
|
|||||||
method = "chacha20-ietf-poly1305";
|
method = "chacha20-ietf-poly1305";
|
||||||
proxyStr = "vmess = " + hostname + ":" + port + ", method=" + method + ", password=" + id;
|
proxyStr = "vmess = " + hostname + ":" + port + ", method=" + method + ", password=" + id;
|
||||||
if(transproto == "ws")
|
if(transproto == "ws")
|
||||||
proxyStr += ", obfs=ws, obfs-host=" + host + ", obfs-uri=" + path;
|
{
|
||||||
|
if(tlssecure)
|
||||||
|
proxyStr += ", obfs=wss";
|
||||||
|
else
|
||||||
|
proxyStr += ", obfs=ws";
|
||||||
|
proxyStr += ", obfs-host=" + host + ", obfs-uri=" + path;
|
||||||
|
}
|
||||||
else if(tlssecure)
|
else if(tlssecure)
|
||||||
proxyStr += ", obfs=over-tls, obfs-host=" + host;
|
proxyStr += ", obfs=over-tls, obfs-host=" + host;
|
||||||
if(ext.skip_cert_verify)
|
|
||||||
proxyStr += ", certificate=0";
|
|
||||||
break;
|
break;
|
||||||
case SPEEDTEST_MESSAGE_FOUNDSS:
|
case SPEEDTEST_MESSAGE_FOUNDSS:
|
||||||
password = GetMember(json, "Password");
|
password = GetMember(json, "Password");
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ std::string netchToSSR(std::vector<nodeInfo> &nodes, extra_settings &ext);
|
|||||||
std::string netchToVMess(std::vector<nodeInfo> &nodes, extra_settings &ext);
|
std::string netchToVMess(std::vector<nodeInfo> &nodes, extra_settings &ext);
|
||||||
std::string netchToQuanX(std::vector<nodeInfo> &nodes, std::string &base_conf, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, extra_settings &ext);
|
std::string netchToQuanX(std::vector<nodeInfo> &nodes, std::string &base_conf, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, extra_settings &ext);
|
||||||
void netchToQuanX(std::vector<nodeInfo> &nodes, INIReader &ini, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, extra_settings &ext);
|
void netchToQuanX(std::vector<nodeInfo> &nodes, INIReader &ini, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, extra_settings &ext);
|
||||||
std::string netchToQuan(std::vector<nodeInfo> &nodes, extra_settings &ext);
|
std::string netchToQuan(std::vector<nodeInfo> &nodes, std::string &base_conf, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, extra_settings &ext);
|
||||||
|
void netchToQuan(std::vector<nodeInfo> &nodes, INIReader &ini, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, extra_settings &ext);
|
||||||
std::string netchToSSD(std::vector<nodeInfo> &nodes, std::string &group, extra_settings &ext);
|
std::string netchToSSD(std::vector<nodeInfo> &nodes, std::string &group, extra_settings &ext);
|
||||||
std::string buildGistData(std::string name, std::string content);
|
std::string buildGistData(std::string name, std::string content);
|
||||||
int uploadGist(std::string name, std::string path, std::string content, bool writeManageURL);
|
int uploadGist(std::string name, std::string path, std::string content, bool writeManageURL);
|
||||||
|
|||||||
Reference in New Issue
Block a user