mirror of
https://github.com/asdlokj1qpi233/subconverter.git
synced 2026-11-04 02:34:06 +00:00
Enhancements
Fix crash when parsing HTTP nodes in Surge subscriptions. Fix section order problem for various subscriptions. Add more custom settings in external configuration file. Add no-resolve to LAN rules. Update README-cn.md.
This commit is contained in:
8 files changed
+160
-61
No files matched your search
+20
-8
@@ -202,7 +202,7 @@ public:
|
||||
{
|
||||
last_error_index++;
|
||||
lineSize = strLine.size();
|
||||
if(!lineSize || strLine[0] == ';' || strLine[0] == '#') //empty lines and comments are ignored
|
||||
if(!lineSize || strLine[0] == ';' || strLine[0] == '#' || (lineSize >= 2 && strLine[0] == '/' && strLine[1] == '/')) //empty lines and comments are ignored
|
||||
continue;
|
||||
if(strLine[lineSize - 1] == '\r') //remove line break
|
||||
{
|
||||
@@ -240,8 +240,11 @@ public:
|
||||
__SAVE_ERROR_AND_RETURN(INIREADER_EXCEPTION_DUPLICATE); //not allowed, stop
|
||||
}
|
||||
ini_content.emplace(curSection, itemGroup); //insert previous section to content map
|
||||
read_sections.emplace_back(curSection); //add to read sections list
|
||||
read_sections.push_back(curSection); //add to read sections list
|
||||
if(std::count(section_order.cbegin(), section_order.cend(), curSection) == 0)
|
||||
section_order.emplace_back(curSection);
|
||||
}
|
||||
|
||||
eraseElements(itemGroup); //reset section storage
|
||||
curSection = thisSection; //start a new section
|
||||
}
|
||||
@@ -269,6 +272,8 @@ public:
|
||||
}
|
||||
ini_content.emplace(curSection, itemGroup); //insert this section to content map
|
||||
read_sections.emplace_back(curSection); //add to read sections list
|
||||
if(std::count(section_order.cbegin(), section_order.cend(), curSection) == 0)
|
||||
section_order.emplace_back(curSection);
|
||||
}
|
||||
parsed = true;
|
||||
__SAVE_ERROR_AND_RETURN(INIREADER_EXCEPTION_NONE); //all done
|
||||
@@ -409,6 +414,7 @@ public:
|
||||
void EraseAll()
|
||||
{
|
||||
eraseElements(ini_content);
|
||||
eraseElements(section_order);
|
||||
parsed = false;
|
||||
}
|
||||
|
||||
@@ -596,6 +602,7 @@ public:
|
||||
string_multimap mapTemp;
|
||||
mapTemp.insert(std::pair<std::string, std::string>(itemName, itemVal));
|
||||
ini_content.insert(std::pair<std::string, std::multimap<std::string, std::string>>(section, mapTemp));
|
||||
section_order.emplace_back(section);
|
||||
}
|
||||
|
||||
__SAVE_ERROR_AND_RETURN(INIREADER_EXCEPTION_NONE);
|
||||
@@ -690,6 +697,7 @@ public:
|
||||
*/
|
||||
ini_content[newName] = std::move(ini_content[oldName]);
|
||||
ini_content.erase(oldName);
|
||||
std::replace(section_order.begin(), section_order.end(), oldName, newName);
|
||||
__SAVE_ERROR_AND_RETURN(INIREADER_EXCEPTION_NONE);
|
||||
}
|
||||
|
||||
@@ -758,6 +766,7 @@ public:
|
||||
eraseElements(ini_content.at(section));
|
||||
if(cached_section == section)
|
||||
eraseElements(cached_section_content);
|
||||
//section_order.erase(std::find(section_order.begin(), section_order.end(), section));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -779,14 +788,17 @@ public:
|
||||
if(!parsed)
|
||||
return std::string();
|
||||
|
||||
for(auto &x : ini_content)
|
||||
for(auto &x : section_order)
|
||||
{
|
||||
content += "[" + x.first + "]\n";
|
||||
for(auto &y : x.second)
|
||||
content += "[" + x + "]\n";
|
||||
if(ini_content.find(x) != ini_content.end())
|
||||
{
|
||||
if(y.first != "{NONAME}")
|
||||
content += y.first + "=";
|
||||
content += y.second + "\n";
|
||||
for(auto &y : ini_content.at(x))
|
||||
{
|
||||
if(y.first != "{NONAME}")
|
||||
content += y.first + "=";
|
||||
content += y.second + "\n";
|
||||
}
|
||||
}
|
||||
content += "\n";
|
||||
}
|
||||
|
||||
+69
-26
@@ -255,7 +255,19 @@ void readConf()
|
||||
std::cerr<<"Read preference settings completed."<<std::endl;
|
||||
}
|
||||
|
||||
int loadExternalConfig(std::string &path, string_array &custom_proxy_group, string_array &surge_ruleset, std::string proxy)
|
||||
struct ExternalConfig
|
||||
{
|
||||
string_array custom_proxy_group;
|
||||
string_array surge_ruleset;
|
||||
std::string clash_rule_base;
|
||||
std::string surge_rule_base;
|
||||
std::string surfboard_rule_base;
|
||||
std::string mellow_rule_base;
|
||||
bool overwrite_original_rules = true;
|
||||
bool enable_rule_generator = true;
|
||||
};
|
||||
|
||||
int loadExternalConfig(std::string &path, ExternalConfig &ext, std::string proxy)
|
||||
{
|
||||
std::string base_content;
|
||||
if(fileExist(path))
|
||||
@@ -274,15 +286,23 @@ int loadExternalConfig(std::string &path, string_array &custom_proxy_group, stri
|
||||
|
||||
ini.EnterSection("custom");
|
||||
if(ini.ItemPrefixExist("custom_proxy_group"))
|
||||
{
|
||||
eraseElements(custom_proxy_group);
|
||||
ini.GetAll("custom_proxy_group", custom_proxy_group);
|
||||
}
|
||||
ini.GetAll("custom_proxy_group", ext.custom_proxy_group);
|
||||
if(ini.ItemPrefixExist("surge_ruleset"))
|
||||
{
|
||||
eraseElements(surge_ruleset);
|
||||
ini.GetAll("surge_ruleset", surge_ruleset);
|
||||
}
|
||||
ini.GetAll("surge_ruleset", ext.surge_ruleset);
|
||||
|
||||
if(ini.ItemExist("clash_rule_base"))
|
||||
ext.clash_rule_base = ini.Get("clash_rule_base");
|
||||
if(ini.ItemExist("surge_rule_base"))
|
||||
ext.surge_rule_base = ini.Get("surge_rule_base");
|
||||
if(ini.ItemExist("surfboard_rule_base"))
|
||||
ext.surfboard_rule_base = ini.Get("surfboard_rule_base");
|
||||
if(ini.ItemExist("mellow_rule_base"))
|
||||
ext.mellow_rule_base = ini.Get("mellow_rule_base");
|
||||
|
||||
if(ini.ItemExist("overwrite_original_rules"))
|
||||
ext.overwrite_original_rules = ini.GetBool("overwrite_original_rules");
|
||||
if(ini.ItemExist("enable_rule_generator"))
|
||||
ext.enable_rule_generator = ini.GetBool("enable_rule_generator");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -328,6 +348,10 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
string_array extra_group, extra_ruleset, include_remarks, exclude_remarks;
|
||||
std::string groups = urlsafe_base64_decode(getUrlArg(argument, "groups")), ruleset = urlsafe_base64_decode(getUrlArg(argument, "ruleset")), config = UrlDecode(getUrlArg(argument, "config"));
|
||||
std::vector<ruleset_content> rca;
|
||||
extra_settings ext;
|
||||
|
||||
//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;
|
||||
|
||||
if(!url.size())
|
||||
url = default_url;
|
||||
@@ -347,10 +371,30 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
if(config.size())
|
||||
{
|
||||
std::cerr<<"External configuration file provided. Loading...\n";
|
||||
//read predefined data first
|
||||
extra_group = clash_extra_group;
|
||||
extra_ruleset = rulesets;
|
||||
loadExternalConfig(config, extra_group, extra_ruleset, proxy);
|
||||
refreshRulesets(extra_ruleset, rca);
|
||||
//then load external configuration
|
||||
ExternalConfig extconf;
|
||||
loadExternalConfig(config, extconf, proxy);
|
||||
if(extconf.clash_rule_base.size())
|
||||
ext_clash_base = extconf.clash_rule_base;
|
||||
if(extconf.surge_rule_base.size())
|
||||
ext_surge_base = extconf.surge_rule_base;
|
||||
if(extconf.surfboard_rule_base.size())
|
||||
ext_surfboard_base = extconf.surfboard_rule_base;
|
||||
if(extconf.mellow_rule_base.size())
|
||||
ext_mellow_base = extconf.mellow_rule_base;
|
||||
ext.enable_rule_generator = extconf.enable_rule_generator;
|
||||
//load custom group
|
||||
if(extconf.custom_proxy_group.size())
|
||||
extra_group = extconf.custom_proxy_group;
|
||||
//load custom rules
|
||||
if(extconf.overwrite_original_rules)
|
||||
{
|
||||
extra_ruleset = extconf.surge_ruleset;
|
||||
refreshRulesets(extra_ruleset, rca);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -385,7 +429,6 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
}
|
||||
}
|
||||
|
||||
extra_settings ext;
|
||||
if(emoji.size())
|
||||
{
|
||||
ext.add_emoji = ext.remove_emoji = emoji == "true";
|
||||
@@ -437,12 +480,12 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
if(target == "clash" || target == "clashr")
|
||||
{
|
||||
std::cerr<<"Clash"<<((target == "clashr") ? "R" : "")<<std::endl;
|
||||
if(rca.size() || extra_group.size() || update_ruleset_on_request)
|
||||
if(rca.size() || extra_group.size() || update_ruleset_on_request || ext_clash_base != clash_rule_base)
|
||||
{
|
||||
if(fileExist(clash_rule_base))
|
||||
base_content = fileGet(clash_rule_base, false);
|
||||
if(fileExist(ext_clash_base))
|
||||
base_content = fileGet(ext_clash_base, false);
|
||||
else
|
||||
base_content = webGet(clash_rule_base, getSystemProxy());
|
||||
base_content = webGet(ext_clash_base, getSystemProxy());
|
||||
|
||||
output_content = netchToClash(nodes, base_content, rca, extra_group, target == "clashr", ext);
|
||||
}
|
||||
@@ -458,10 +501,10 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
int surge_ver = version.size() ? to_int(version, 3) : 3;
|
||||
std::cerr<<"Surge "<<surge_ver<<std::endl;
|
||||
|
||||
if(fileExist(surge_rule_base))
|
||||
base_content = fileGet(surge_rule_base, false);
|
||||
if(fileExist(ext_surge_base))
|
||||
base_content = fileGet(ext_surge_base, false);
|
||||
else
|
||||
base_content = webGet(surge_rule_base, getSystemProxy());
|
||||
base_content = webGet(ext_surge_base, getSystemProxy());
|
||||
|
||||
output_content = netchToSurge(nodes, base_content, rca, extra_group, surge_ver, ext);
|
||||
if(upload == "true")
|
||||
@@ -474,10 +517,10 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
else if(target == "surfboard")
|
||||
{
|
||||
std::cerr<<"Surfboard"<<std::endl;
|
||||
if(fileExist(surfboard_rule_base))
|
||||
base_content = fileGet(surfboard_rule_base, false);
|
||||
if(fileExist(ext_surfboard_base))
|
||||
base_content = fileGet(ext_surfboard_base, false);
|
||||
else
|
||||
base_content = webGet(surfboard_rule_base, getSystemProxy());
|
||||
base_content = webGet(ext_surfboard_base, getSystemProxy());
|
||||
|
||||
output_content = netchToSurge(nodes, base_content, rca, extra_group, 2, ext);
|
||||
if(upload == "true")
|
||||
@@ -490,12 +533,12 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
else if(target == "mellow")
|
||||
{
|
||||
std::cerr<<"Mellow"<<std::endl;
|
||||
if(rca.size() || extra_group.size() || update_ruleset_on_request)
|
||||
if(rca.size() || extra_group.size() || update_ruleset_on_request || ext_mellow_base != mellow_rule_base)
|
||||
{
|
||||
if(fileExist(mellow_rule_base))
|
||||
base_content = fileGet(mellow_rule_base, false);
|
||||
if(fileExist(ext_mellow_base))
|
||||
base_content = fileGet(ext_mellow_base, false);
|
||||
else
|
||||
base_content = webGet(mellow_rule_base, getSystemProxy());
|
||||
base_content = webGet(ext_mellow_base, getSystemProxy());
|
||||
|
||||
output_content = netchToMellow(nodes, base_content, rca, extra_group, ext);
|
||||
}
|
||||
|
||||
+15
-11
@@ -245,7 +245,7 @@ void explodeVmessConf(std::string content, std::string custom_port, int local_po
|
||||
node.group = V2RAY_DEFAULT_GROUP;
|
||||
node.remarks = add + ":" + port;
|
||||
node.server = add;
|
||||
node.port = stoi(port);
|
||||
node.port = to_int(port);
|
||||
nodes.push_back(node);
|
||||
}
|
||||
return;
|
||||
@@ -320,7 +320,7 @@ void explodeVmessConf(std::string content, std::string custom_port, int local_po
|
||||
node.remarks = ps;
|
||||
node.id = index;
|
||||
node.server = add;
|
||||
node.port = stoi(port);
|
||||
node.port = to_int(port);
|
||||
nodes.push_back(node);
|
||||
}
|
||||
return;
|
||||
@@ -416,7 +416,7 @@ void explodeSSD(std::string link, bool libev, std::string custom_port, int local
|
||||
node.group = group;
|
||||
node.remarks = remarks;
|
||||
node.server = server;
|
||||
node.port = stoi(port);
|
||||
node.port = to_int(port);
|
||||
node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, local_port, libev);
|
||||
node.id = index;
|
||||
nodes.push_back(node);
|
||||
@@ -455,7 +455,7 @@ void explodeSSAndroid(std::string ss, bool libev, std::string custom_port, int l
|
||||
node.group = group;
|
||||
node.remarks = ps;
|
||||
node.server = server;
|
||||
node.port = stoi(port);
|
||||
node.port = to_int(port);
|
||||
node.proxyStr = ssConstruct(server, port, password, method, "", "", ps, local_port, libev);
|
||||
nodes.push_back(node);
|
||||
index++;
|
||||
@@ -482,7 +482,7 @@ void explodeSSConf(std::string content, std::string custom_port, int local_port,
|
||||
node.group = SS_DEFAULT_GROUP;
|
||||
node.remarks = server + ":" + port;
|
||||
node.server = server;
|
||||
node.port = stoi(port);
|
||||
node.port = to_int(port);
|
||||
node.proxyStr = SerializeObject(json);
|
||||
nodes.push_back(node);
|
||||
return;
|
||||
@@ -510,7 +510,7 @@ void explodeSSConf(std::string content, std::string custom_port, int local_port,
|
||||
node.remarks = ps;
|
||||
node.id = index;
|
||||
node.server = server;
|
||||
node.port = stoi(port);
|
||||
node.port = to_int(port);
|
||||
node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, ps, local_port, libev);
|
||||
nodes.push_back(node);
|
||||
index++;
|
||||
@@ -601,7 +601,7 @@ void explodeSSRConf(std::string content, std::string custom_port, int local_port
|
||||
node.group = SSR_DEFAULT_GROUP;
|
||||
node.remarks = server + ":" + port;
|
||||
node.server = server;
|
||||
node.port = stoi(port);
|
||||
node.port = to_int(port);
|
||||
node.proxyStr = SerializeObject(json);
|
||||
nodes.push_back(node);
|
||||
return;
|
||||
@@ -634,7 +634,7 @@ void explodeSSRConf(std::string content, std::string custom_port, int local_port
|
||||
node.remarks = remarks;
|
||||
node.id = index;
|
||||
node.server = server;
|
||||
node.port = stoi(port);
|
||||
node.port = to_int(port);
|
||||
node.proxyStr = ssrConstruct(group, remarks, remarks_base64, server, port, protocol, method, obfs, password, obfsparam, protoparam, local_port, ssr_libev);
|
||||
nodes.push_back(node);
|
||||
index++;
|
||||
@@ -981,7 +981,7 @@ void explodeClash(Node yamlnode, std::string custom_port, int local_port, std::v
|
||||
node.group = group;
|
||||
node.remarks = ps;
|
||||
node.server = server;
|
||||
node.port = stoi(port);
|
||||
node.port = to_int(port);
|
||||
node.id = index;
|
||||
nodes.push_back(node);
|
||||
index++;
|
||||
@@ -1209,6 +1209,8 @@ bool explodeSurge(std::string surge, std::string custom_port, int local_port, st
|
||||
{
|
||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
|
||||
node.group = SOCKS_DEFAULT_GROUP;
|
||||
server = trim(configs[1]);
|
||||
port = custom_port == "" ? trim(configs[2]) : custom_port;
|
||||
if(configs.size() >= 5)
|
||||
{
|
||||
username = trim(configs[2]);
|
||||
@@ -1266,6 +1268,8 @@ bool explodeSurge(std::string surge, std::string custom_port, int local_port, st
|
||||
{
|
||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
|
||||
node.group = HTTP_DEFAULT_GROUP;
|
||||
server = trim(configs[1]);
|
||||
port = custom_port == "" ? trim(configs[2]) : custom_port;
|
||||
if(configs.size() >= 5)
|
||||
{
|
||||
username = trim(configs[2]);
|
||||
@@ -1330,7 +1334,7 @@ bool explodeSurge(std::string surge, std::string custom_port, int local_port, st
|
||||
|
||||
node.remarks = remarks;
|
||||
node.server = server;
|
||||
node.port = stoi(port);
|
||||
node.port = to_int(port);
|
||||
node.id = index;
|
||||
nodes.push_back(node);
|
||||
index++;
|
||||
@@ -1394,7 +1398,7 @@ void explodeSSTap(std::string sstap, std::string custom_port, int local_port, st
|
||||
node.remarks = remarks;
|
||||
node.id = index;
|
||||
node.server = server;
|
||||
node.port = stoi(port);
|
||||
node.port = to_int(port);
|
||||
nodes.push_back(node);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-3
@@ -701,7 +701,8 @@ std::string netchToClash(std::vector<nodeInfo> &nodes, std::string &base_conf, s
|
||||
if(ext.nodelist)
|
||||
return YAML::Dump(yamlnode);
|
||||
|
||||
rulesetToClash(yamlnode, ruleset_content_array);
|
||||
if(ext.enable_rule_generator)
|
||||
rulesetToClash(yamlnode, ruleset_content_array);
|
||||
|
||||
return YAML::Dump(yamlnode);
|
||||
}
|
||||
@@ -866,6 +867,7 @@ std::string netchToSurge(std::vector<nodeInfo> &nodes, std::string &base_conf, s
|
||||
return output_nodelist;
|
||||
|
||||
ini.SetCurrentSection("Proxy Group");
|
||||
ini.EraseSection();
|
||||
for(std::string &x : extra_proxy_group)
|
||||
{
|
||||
eraseElements(filtered_nodelist);
|
||||
@@ -925,7 +927,8 @@ std::string netchToSurge(std::vector<nodeInfo> &nodes, std::string &base_conf, s
|
||||
ini.Set("{NONAME}", vArray[0] + " = " + proxy); //insert order
|
||||
}
|
||||
|
||||
rulesetToSurge(ini, ruleset_content_array, surge_ver);
|
||||
if(ext.enable_rule_generator)
|
||||
rulesetToSurge(ini, ruleset_content_array, surge_ver);
|
||||
|
||||
return ini.ToString();
|
||||
}
|
||||
@@ -1569,7 +1572,8 @@ void netchToMellow(std::vector<nodeInfo> &nodes, INIReader &ini, std::vector<rul
|
||||
ini.Set("{NONAME}", proxy); //insert order
|
||||
}
|
||||
|
||||
rulesetToSurge(ini, ruleset_content_array, 2);
|
||||
if(ext.enable_rule_generator)
|
||||
rulesetToSurge(ini, ruleset_content_array, 2);
|
||||
ini.RenameSection("Rule", "RoutingRule");
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ struct ruleset_content
|
||||
|
||||
struct extra_settings
|
||||
{
|
||||
bool enable_rule_generator = true;
|
||||
bool add_emoji = false;
|
||||
bool remove_emoji = false;
|
||||
bool append_proxy_type = true;
|
||||
|
||||
Reference in new issue
Block a user