mirror of
https://github.com/asdlokj1qpi233/subconverter.git
synced 2025-10-27 20:03:01 +00:00
Enhancements
Add exprtimental support for generating Mellow configuration. Add proxy customization for downloading rulesets and subscriptions. Add more customizations in manage URL arguments. Optimize codes. INIReader: Fix line break remove not working.
This commit is contained in:
@@ -146,7 +146,7 @@ public:
|
||||
continue;
|
||||
if(strLine[lineSize - 1] == '\r') //remove line break
|
||||
{
|
||||
strLine.replace(lineSize - 1, 0, "");
|
||||
strLine = strLine.substr(0, lineSize - 1);
|
||||
lineSize--;
|
||||
}
|
||||
if(strLine.find("=") != strLine.npos) //is an item
|
||||
@@ -354,7 +354,7 @@ public:
|
||||
/**
|
||||
* @brief Retrieve all items in the given section.
|
||||
*/
|
||||
int GetItems(std::string section, std::multimap<std::string, std::string> &data)
|
||||
int GetItems(std::string section, string_multimap &data)
|
||||
{
|
||||
if(!parsed || !SectionExist(section))
|
||||
return -1;
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
extern bool print_debug_info;
|
||||
|
||||
void writeLog(int type, std::string content)
|
||||
{
|
||||
//placeholder
|
||||
if(print_debug_info)
|
||||
std::cerr<<"[DEBUG] "<<content<<"\n";
|
||||
}
|
||||
|
||||
100
main.cpp
100
main.cpp
@@ -21,6 +21,7 @@ std::vector<ruleset_content> ruleset_content_array;
|
||||
std::string listen_address = "127.0.0.1", default_url, managed_config_prefix;
|
||||
int listen_port = 25500, max_pending_connections = 10, max_concurrent_threads = 4;
|
||||
bool api_mode = true, write_managed_config = false, update_ruleset_on_request = false, overwrite_original_rules = true;
|
||||
bool print_debug_info = false;
|
||||
extern std::string custom_group;
|
||||
|
||||
//safety lock for multi-thread
|
||||
@@ -29,14 +30,12 @@ std::mutex on_configuring;
|
||||
|
||||
//preferences
|
||||
string_array renames, emojis;
|
||||
bool add_emoji = false, remove_old_emoji = false;
|
||||
bool add_emoji = false, remove_old_emoji = false, append_proxy_type = true;
|
||||
std::string proxy_ruleset, proxy_subscription;
|
||||
|
||||
//clash custom
|
||||
std::string clash_rule_base;
|
||||
string_array clash_extra_group;
|
||||
|
||||
//surge custom
|
||||
std::string surge_rule_base, surfboard_rule_base;
|
||||
std::string surge_rule_base, surfboard_rule_base, mellow_rule_base;
|
||||
|
||||
void setcd(char *argv[])
|
||||
{
|
||||
@@ -65,8 +64,17 @@ std::string refreshRulesets()
|
||||
guarded_mutex guard(on_configuring);
|
||||
eraseElements(ruleset_content_array);
|
||||
string_array vArray;
|
||||
std::string rule_group, rule_url, proxy = getSystemProxy();
|
||||
std::string rule_group, rule_url;
|
||||
ruleset_content rc;
|
||||
|
||||
std::string proxy;
|
||||
if(proxy_ruleset == "SYSTEM")
|
||||
proxy = getSystemProxy();
|
||||
else if(proxy_ruleset == "NONE")
|
||||
proxy = "";
|
||||
else
|
||||
proxy = proxy_ruleset;
|
||||
|
||||
for(std::string &x : rulesets)
|
||||
{
|
||||
/*
|
||||
@@ -137,6 +145,14 @@ void readConf()
|
||||
surge_rule_base = ini.Get("surge_rule_base");
|
||||
if(ini.ItemExist("surfboard_rule_base"))
|
||||
surfboard_rule_base = ini.Get("surfboard_rule_base");
|
||||
if(ini.ItemExist("mellow_rule_base"))
|
||||
mellow_rule_base = ini.Get("mellow_rule_base");
|
||||
if(ini.ItemExist("append_proxy_type"))
|
||||
append_proxy_type = ini.GetBool("append_proxy_type");
|
||||
if(ini.ItemExist("proxy_ruleset"))
|
||||
proxy_ruleset = ini.Get("proxy_ruleset");
|
||||
if(ini.ItemExist("proxy_subscription"))
|
||||
proxy_subscription = ini.Get("proxy_subscription");
|
||||
if(ini.ItemPrefixExist("rename_node"))
|
||||
ini.GetAll("rename_node", renames);
|
||||
|
||||
@@ -181,6 +197,8 @@ void readConf()
|
||||
listen_port = ini.GetInt("port");
|
||||
|
||||
ini.EnterSection("advanced");
|
||||
if(ini.ItemExist("print_debug_info"))
|
||||
print_debug_info = ini.GetBool("print_debug_info");
|
||||
if(ini.ItemExist("max_pending_connections"))
|
||||
max_pending_connections = ini.GetInt("max_pending_connections");
|
||||
if(ini.ItemExist("max_concurrent_threads"))
|
||||
@@ -192,9 +210,34 @@ void readConf()
|
||||
|
||||
std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
{
|
||||
std::string target = getUrlArg(argument, "target"), url = UrlDecode(getUrlArg(argument, "url")), include = UrlDecode(getUrlArg(argument, "regex"));
|
||||
std::string target = getUrlArg(argument, "target"), url = UrlDecode(getUrlArg(argument, "url")), include = UrlDecode(getUrlArg(argument, "regex")), emoji = getUrlArg(argument, "emoji");
|
||||
std::string group = UrlDecode(getUrlArg(argument, "group")), upload = getUrlArg(argument, "upload"), upload_path = getUrlArg(argument, "upload_path"), version = getUrlArg(argument, "ver");
|
||||
std::string append_type = getUrlArg(argument, "append_type");
|
||||
std::string base_content, output_content;
|
||||
|
||||
extra_settings ext;
|
||||
if(emoji == "true")
|
||||
{
|
||||
ext.add_emoji = ext.remove_emoji = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ext.add_emoji = add_emoji;
|
||||
ext.remove_emoji = remove_old_emoji;
|
||||
}
|
||||
if(append_type.size())
|
||||
ext.append_proxy_type = append_type == "true";
|
||||
else
|
||||
ext.append_proxy_type = append_proxy_type;
|
||||
|
||||
std::string proxy;
|
||||
if(proxy_subscription == "SYSTEM")
|
||||
proxy = getSystemProxy();
|
||||
else if(proxy_subscription == "NONE")
|
||||
proxy = "";
|
||||
else
|
||||
proxy = proxy_subscription;
|
||||
|
||||
if(!url.size())
|
||||
url = default_url;
|
||||
if(!url.size() || !target.size())
|
||||
@@ -207,15 +250,15 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
int groupID = 0;
|
||||
if(include.size())
|
||||
{
|
||||
eraseElements(def_include_remarks);
|
||||
def_include_remarks.emplace_back(include);
|
||||
eraseElements(ext.include_remarks);
|
||||
ext.include_remarks.emplace_back(include);
|
||||
}
|
||||
if(group.size())
|
||||
custom_group = group;
|
||||
for(std::string &x : urls)
|
||||
{
|
||||
std::cerr<<"Fetching node data from url '"<<x<<"'."<<std::endl;
|
||||
addNodes(x, nodes, groupID);
|
||||
addNodes(x, nodes, groupID, proxy);
|
||||
groupID++;
|
||||
}
|
||||
if(!nodes.size())
|
||||
@@ -232,7 +275,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
|
||||
if(update_ruleset_on_request)
|
||||
refreshRulesets();
|
||||
output_content = netchToClash(nodes, base_content, ruleset_content_array, clash_extra_group, target == "clashr");
|
||||
output_content = netchToClash(nodes, base_content, ruleset_content_array, clash_extra_group, target == "clashr", ext);
|
||||
if(upload == "true")
|
||||
uploadGist("clash", upload_path, output_content, false);
|
||||
return output_content;
|
||||
@@ -246,7 +289,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
else
|
||||
base_content = webGet(surge_rule_base, getSystemProxy());
|
||||
|
||||
output_content = netchToSurge(nodes, base_content, ruleset_content_array, clash_extra_group, surge_ver);
|
||||
output_content = netchToSurge(nodes, base_content, ruleset_content_array, clash_extra_group, surge_ver, ext);
|
||||
if(upload == "true")
|
||||
uploadGist("surge" + version, upload_path, output_content, true);
|
||||
|
||||
@@ -262,7 +305,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
else
|
||||
base_content = webGet(surfboard_rule_base, getSystemProxy());
|
||||
|
||||
output_content = netchToSurge(nodes, base_content, ruleset_content_array, clash_extra_group, 2);
|
||||
output_content = netchToSurge(nodes, base_content, ruleset_content_array, clash_extra_group, 2, ext);
|
||||
if(upload == "true")
|
||||
uploadGist("surfboard", upload_path, output_content, true);
|
||||
|
||||
@@ -270,10 +313,24 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
output_content = "#!MANAGED-CONFIG " + managed_config_prefix + "/sub?" + argument + "\n\n" + output_content;
|
||||
return output_content;
|
||||
}
|
||||
else if(target == "mellow")
|
||||
{
|
||||
std::cerr<<"Mellow"<<std::endl;
|
||||
if(fileExist(mellow_rule_base))
|
||||
base_content = fileGet(mellow_rule_base, false);
|
||||
else
|
||||
base_content = webGet(mellow_rule_base, getSystemProxy());
|
||||
|
||||
output_content = netchToMellow(nodes, base_content, ruleset_content_array, clash_extra_group, ext);
|
||||
if(upload == "true")
|
||||
uploadGist("mellow", upload_path, output_content, true);
|
||||
|
||||
return output_content;
|
||||
}
|
||||
else if(target == "ss")
|
||||
{
|
||||
std::cerr<<"SS"<<std::endl;
|
||||
output_content = netchToSS(nodes);
|
||||
output_content = netchToSS(nodes, ext);
|
||||
if(upload == "true")
|
||||
uploadGist("ss", upload_path, output_content, false);
|
||||
return output_content;
|
||||
@@ -281,7 +338,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
else if(target == "ssr")
|
||||
{
|
||||
std::cerr<<"SSR"<<std::endl;
|
||||
output_content = netchToSSR(nodes);
|
||||
output_content = netchToSSR(nodes, ext);
|
||||
if(upload == "true")
|
||||
uploadGist("ssr", upload_path, output_content, false);
|
||||
return output_content;
|
||||
@@ -289,7 +346,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
else if(target == "v2ray")
|
||||
{
|
||||
std::cerr<<"v2rayN"<<std::endl;
|
||||
output_content = netchToVMess(nodes);
|
||||
output_content = netchToVMess(nodes, ext);
|
||||
if(upload == "true")
|
||||
uploadGist("v2ray", upload_path, output_content, false);
|
||||
return output_content;
|
||||
@@ -297,7 +354,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
else if(target == "quan")
|
||||
{
|
||||
std::cerr<<"Quantumult"<<std::endl;
|
||||
output_content = netchToQuan(nodes);
|
||||
output_content = netchToQuan(nodes, ext);
|
||||
if(upload == "true")
|
||||
uploadGist("quan", upload_path, output_content, false);
|
||||
return output_content;
|
||||
@@ -305,7 +362,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
else if(target == "quanx")
|
||||
{
|
||||
std::cerr<<"Quantumult X"<<std::endl;
|
||||
output_content = netchToQuanX(nodes);
|
||||
output_content = netchToQuanX(nodes, ext);
|
||||
if(upload == "true")
|
||||
uploadGist("quanx", upload_path, output_content, false);
|
||||
return output_content;
|
||||
@@ -313,7 +370,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
else if(target == "ssd")
|
||||
{
|
||||
std::cerr<<"SSD"<<std::endl;
|
||||
output_content = netchToSSD(nodes, group);
|
||||
output_content = netchToSSD(nodes, group, ext);
|
||||
if(upload == "true")
|
||||
uploadGist("ssd", upload_path, output_content, false);
|
||||
return output_content;
|
||||
@@ -377,6 +434,11 @@ int main(int argc, char *argv[])
|
||||
return subconverter(argument + "&target=surfboard", postdata);
|
||||
});
|
||||
|
||||
append_response("GET", "/mellow", "text/plain;charset=utf-8", [](RESPONSE_CALLBACK_ARGS) -> std::string
|
||||
{
|
||||
return subconverter(argument + "&target=mellow", postdata);
|
||||
});
|
||||
|
||||
append_response("GET", "/ss", "text/plain", [](RESPONSE_CALLBACK_ARGS) -> std::string
|
||||
{
|
||||
return subconverter(argument + "&target=ss", postdata);
|
||||
|
||||
27
mellow.conf
Normal file
27
mellow.conf
Normal file
@@ -0,0 +1,27 @@
|
||||
[Endpoint]
|
||||
DIRECT, builtin, freedom, domainStrategy=UseIP
|
||||
REJECT, builtin, blackhole
|
||||
Dns-Out, builtin, dns
|
||||
|
||||
[Routing]
|
||||
domainStrategy = IPIfNonMatch
|
||||
|
||||
[Dns]
|
||||
hijack = Dns-Out
|
||||
clientIp = 114.114.114.114
|
||||
|
||||
[DnsServer]
|
||||
localhost
|
||||
223.5.5.5
|
||||
8.8.8.8, 53, Remote
|
||||
8.8.4.4
|
||||
|
||||
[DnsRule]
|
||||
DOMAIN-KEYWORD, geosite:geolocation-!cn, Remote
|
||||
DOMAIN-SUFFIX, google.com, Remote
|
||||
|
||||
[DnsHost]
|
||||
doubleclick.net = 127.0.0.1
|
||||
|
||||
[Log]
|
||||
loglevel = warning
|
||||
@@ -21,7 +21,7 @@ void copyNodes(std::vector<nodeInfo> *source, std::vector<nodeInfo> *dest)
|
||||
}
|
||||
}
|
||||
|
||||
void addNodes(std::string link, std::vector<nodeInfo> &allNodes, int groupID)
|
||||
void addNodes(std::string link, std::vector<nodeInfo> &allNodes, int groupID, std::string proxy)
|
||||
{
|
||||
int linkType = -1;
|
||||
std::vector<nodeInfo> nodes;
|
||||
@@ -51,7 +51,8 @@ void addNodes(std::string link, std::vector<nodeInfo> &allNodes, int groupID)
|
||||
writeLog(LOG_TYPE_INFO, "Downloading subscription data...");
|
||||
if(strFind(link, "surge:///install-config")) //surge config link
|
||||
link = UrlDecode(getUrlArg(link, "url"));
|
||||
strSub = webGet(link);
|
||||
strSub = webGet(link, proxy);
|
||||
/*
|
||||
if(strSub.size() == 0)
|
||||
{
|
||||
//try to get it again with system proxy
|
||||
@@ -64,6 +65,7 @@ void addNodes(std::string link, std::vector<nodeInfo> &allNodes, int groupID)
|
||||
else
|
||||
writeLog(LOG_TYPE_WARN, "No system proxy is set. Skipping.");
|
||||
}
|
||||
*/
|
||||
if(strSub.size())
|
||||
{
|
||||
writeLog(LOG_TYPE_INFO, "Parsing subscription data...");
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
|
||||
#include "nodeinfo.h"
|
||||
|
||||
void addNodes(std::string link, std::vector<nodeInfo> &allNodes, int groupID);
|
||||
void addNodes(std::string link, std::vector<nodeInfo> &allNodes, int groupID, std::string proxy = "");
|
||||
|
||||
#endif // NODEMANIP_H_INCLUDED
|
||||
|
||||
12
pref.ini
12
pref.ini
@@ -21,6 +21,17 @@ surge_rule_base=surge.conf
|
||||
;Surfboard config base used by the generator, supports local files/URL
|
||||
surfboard_rule_base=surfboard.conf
|
||||
|
||||
;Mellow config base used by the generator, supports local files/URL
|
||||
mellow_rule_base=mellow.conf
|
||||
|
||||
;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_ruleset=SYSTEM
|
||||
proxy_subscription=NONE
|
||||
|
||||
;Append a proxy type string ([SS] [SSR] [VMess]) to node remark.
|
||||
append_proxy_type=false
|
||||
|
||||
;Rename remarks with the following patterns. Supports regular expression.
|
||||
;Format: Search_Pattern@Replace_Pattern
|
||||
;rename_node=IPLC@专线
|
||||
@@ -217,5 +228,6 @@ listen=0.0.0.0
|
||||
port=25500
|
||||
|
||||
[advanced]
|
||||
print_debug_info=false
|
||||
max_pending_connections=10240
|
||||
max_concurrent_threads=4
|
||||
|
||||
279
subexport.cpp
279
subexport.cpp
@@ -332,7 +332,7 @@ void rulesetToSurge(INIReader &base_rule, std::vector<ruleset_content> &ruleset_
|
||||
}
|
||||
}
|
||||
|
||||
std::string netchToClash(std::vector<nodeInfo> &nodes, std::string &base_conf, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, bool clashR)
|
||||
std::string netchToClash(std::vector<nodeInfo> &nodes, std::string &base_conf, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, bool clashR, extra_settings &ext)
|
||||
{
|
||||
YAML::Node yamlnode, proxies, singleproxy, singlegroup, original_groups;
|
||||
rapidjson::Document json;
|
||||
@@ -359,7 +359,16 @@ std::string netchToClash(std::vector<nodeInfo> &nodes, std::string &base_conf, s
|
||||
singleproxy.reset();
|
||||
json.Parse(x.proxyStr.data());
|
||||
type = GetMember(json, "Type");
|
||||
remark = x.remarks = addEmoji("[" + type + "]" + trim(removeEmoji(nodeRename(x.remarks))));
|
||||
|
||||
x.remarks = nodeRename(x.remarks);
|
||||
if(ext.remove_emoji)
|
||||
x.remarks = trim(removeEmoji(x.remarks));
|
||||
if(ext.append_proxy_type)
|
||||
x.remarks = "[" + type + "]" + x.remarks;
|
||||
if(ext.add_emoji)
|
||||
x.remarks = addEmoji(x.remarks);
|
||||
remark = x.remarks;
|
||||
|
||||
while(std::count(remarks_list.begin(), remarks_list.end(), remark) > 0)
|
||||
remark = x.remarks = x.remarks + "$";
|
||||
hostname = GetMember(json, "Hostname");
|
||||
@@ -530,7 +539,7 @@ std::string netchToClash(std::vector<nodeInfo> &nodes, std::string &base_conf, s
|
||||
return to_string(yamlnode);
|
||||
}
|
||||
|
||||
std::string netchToSurge(std::vector<nodeInfo> &nodes, std::string &base_conf, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, int surge_ver)
|
||||
std::string netchToSurge(std::vector<nodeInfo> &nodes, std::string &base_conf, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, int surge_ver, extra_settings &ext)
|
||||
{
|
||||
rapidjson::Document json;
|
||||
INIReader ini;
|
||||
@@ -554,7 +563,16 @@ std::string netchToSurge(std::vector<nodeInfo> &nodes, std::string &base_conf, s
|
||||
{
|
||||
json.Parse(x.proxyStr.data());
|
||||
type = GetMember(json, "Type");
|
||||
remark = x.remarks = addEmoji("[" + type + "]" + trim(removeEmoji(nodeRename(x.remarks))));
|
||||
|
||||
x.remarks = nodeRename(x.remarks);
|
||||
if(ext.remove_emoji)
|
||||
x.remarks = trim(removeEmoji(x.remarks));
|
||||
if(ext.append_proxy_type)
|
||||
x.remarks = "[" + type + "]" + x.remarks;
|
||||
if(ext.add_emoji)
|
||||
x.remarks = addEmoji(x.remarks);
|
||||
remark = x.remarks;
|
||||
|
||||
while(std::count(remarks_list.begin(), remarks_list.end(), remark) > 0)
|
||||
remark = x.remarks = x.remarks + "$";
|
||||
hostname = GetMember(json, "Hostname");
|
||||
@@ -681,8 +699,8 @@ std::string netchToSurge(std::vector<nodeInfo> &nodes, std::string &base_conf, s
|
||||
filtered_nodelist.emplace_back("DIRECT");
|
||||
|
||||
proxy = vArray[1];
|
||||
for(std::string &x : filtered_nodelist)
|
||||
proxy += "," + x;
|
||||
for(std::string &y : filtered_nodelist)
|
||||
proxy += "," + y;
|
||||
if(vArray[1] == "url-test" || vArray[1] == "fallback" || vArray[1] == "load-balance")
|
||||
proxy += ",url=" + url;
|
||||
|
||||
@@ -694,17 +712,25 @@ std::string netchToSurge(std::vector<nodeInfo> &nodes, std::string &base_conf, s
|
||||
return ini.ToString();
|
||||
}
|
||||
|
||||
std::string netchToSS(std::vector<nodeInfo> &nodes)
|
||||
std::string netchToSS(std::vector<nodeInfo> &nodes, extra_settings &ext)
|
||||
{
|
||||
rapidjson::Document json;
|
||||
std::string remark, hostname, port, password, method;
|
||||
std::string plugin, pluginopts;
|
||||
std::string protocol, protoparam, obfs, obfsparam;
|
||||
std::string proxyStr, allLinks;
|
||||
|
||||
for(nodeInfo &x : nodes)
|
||||
{
|
||||
json.Parse(x.proxyStr.data());
|
||||
remark = x.remarks = addEmoji(trim(removeEmoji(nodeRename(x.remarks))));
|
||||
|
||||
x.remarks = nodeRename(x.remarks);
|
||||
if(ext.remove_emoji)
|
||||
x.remarks = trim(removeEmoji(x.remarks));
|
||||
if(ext.add_emoji)
|
||||
x.remarks = addEmoji(x.remarks);
|
||||
remark = x.remarks;
|
||||
|
||||
hostname = GetMember(json, "Hostname");
|
||||
port = std::__cxx11::to_string((unsigned short)stoi(GetMember(json, "Port")));
|
||||
password = GetMember(json, "Password");
|
||||
@@ -739,7 +765,7 @@ std::string netchToSS(std::vector<nodeInfo> &nodes)
|
||||
return base64_encode(allLinks);
|
||||
}
|
||||
|
||||
std::string netchToSSR(std::vector<nodeInfo> &nodes)
|
||||
std::string netchToSSR(std::vector<nodeInfo> &nodes, extra_settings &ext)
|
||||
{
|
||||
rapidjson::Document json;
|
||||
std::string remark, hostname, port, password, method;
|
||||
@@ -748,7 +774,14 @@ std::string netchToSSR(std::vector<nodeInfo> &nodes)
|
||||
for(nodeInfo &x : nodes)
|
||||
{
|
||||
json.Parse(x.proxyStr.data());
|
||||
remark = x.remarks = addEmoji(trim(removeEmoji(nodeRename(x.remarks))));
|
||||
|
||||
x.remarks = nodeRename(x.remarks);
|
||||
if(ext.remove_emoji)
|
||||
x.remarks = trim(removeEmoji(x.remarks));
|
||||
if(ext.add_emoji)
|
||||
x.remarks = addEmoji(x.remarks);
|
||||
remark = x.remarks;
|
||||
|
||||
hostname = GetMember(json, "Hostname");
|
||||
port = std::__cxx11::to_string((unsigned short)stoi(GetMember(json, "Port")));
|
||||
password = GetMember(json, "Password");
|
||||
@@ -779,7 +812,7 @@ std::string netchToSSR(std::vector<nodeInfo> &nodes)
|
||||
return base64_encode(allLinks);
|
||||
}
|
||||
|
||||
std::string netchToVMess(std::vector<nodeInfo> &nodes)
|
||||
std::string netchToVMess(std::vector<nodeInfo> &nodes, extra_settings &ext)
|
||||
{
|
||||
rapidjson::Document json;
|
||||
std::string remark, hostname, port, method;
|
||||
@@ -789,7 +822,14 @@ std::string netchToVMess(std::vector<nodeInfo> &nodes)
|
||||
for(nodeInfo &x : nodes)
|
||||
{
|
||||
json.Parse(x.proxyStr.data());
|
||||
remark = x.remarks = addEmoji(trim(removeEmoji(nodeRename(x.remarks))));
|
||||
|
||||
x.remarks = nodeRename(x.remarks);
|
||||
if(ext.remove_emoji)
|
||||
x.remarks = trim(removeEmoji(x.remarks));
|
||||
if(ext.add_emoji)
|
||||
x.remarks = addEmoji(x.remarks);
|
||||
remark = x.remarks;
|
||||
|
||||
hostname = GetMember(json, "Hostname");
|
||||
port = std::__cxx11::to_string((unsigned short)stoi(GetMember(json, "Port")));
|
||||
method = GetMember(json, "EncryptMethod");
|
||||
@@ -815,9 +855,10 @@ std::string netchToVMess(std::vector<nodeInfo> &nodes)
|
||||
return base64_encode(allLinks);
|
||||
}
|
||||
|
||||
std::string netchToQuan(std::vector<nodeInfo> &nodes)
|
||||
std::string netchToQuan(std::vector<nodeInfo> &nodes, extra_settings &ext)
|
||||
{
|
||||
rapidjson::Document json;
|
||||
std::string type;
|
||||
std::string remark, hostname, port, method, password;
|
||||
std::string plugin, pluginopts;
|
||||
std::string protocol, protoparam, obfs, obfsparam;
|
||||
@@ -827,7 +868,17 @@ std::string netchToQuan(std::vector<nodeInfo> &nodes)
|
||||
for(nodeInfo &x : nodes)
|
||||
{
|
||||
json.Parse(x.proxyStr.data());
|
||||
remark = x.remarks = addEmoji(trim(removeEmoji(nodeRename(x.remarks))));
|
||||
type = GetMember(json, "Type");
|
||||
|
||||
x.remarks = nodeRename(x.remarks);
|
||||
if(ext.remove_emoji)
|
||||
x.remarks = trim(removeEmoji(x.remarks));
|
||||
if(ext.append_proxy_type)
|
||||
x.remarks = "[" + type + "]" + x.remarks;
|
||||
if(ext.add_emoji)
|
||||
x.remarks = addEmoji(x.remarks);
|
||||
remark = x.remarks;
|
||||
|
||||
hostname = GetMember(json, "Hostname");
|
||||
port = std::__cxx11::to_string((unsigned short)stoi(GetMember(json, "Port")));
|
||||
method = GetMember(json, "EncryptMethod");
|
||||
@@ -882,9 +933,10 @@ std::string netchToQuan(std::vector<nodeInfo> &nodes)
|
||||
return allLinks;
|
||||
}
|
||||
|
||||
std::string netchToQuanX(std::vector<nodeInfo> &nodes)
|
||||
std::string netchToQuanX(std::vector<nodeInfo> &nodes, extra_settings &ext)
|
||||
{
|
||||
rapidjson::Document json;
|
||||
std::string type;
|
||||
std::string remark, hostname, port, method;
|
||||
std::string password, plugin, pluginopts;
|
||||
std::string id, aid, transproto, host, path;
|
||||
@@ -893,7 +945,17 @@ std::string netchToQuanX(std::vector<nodeInfo> &nodes)
|
||||
for(nodeInfo &x : nodes)
|
||||
{
|
||||
json.Parse(x.proxyStr.data());
|
||||
remark = x.remarks = addEmoji(trim(removeEmoji(nodeRename(x.remarks))));
|
||||
type = GetMember(json, "Type");
|
||||
|
||||
x.remarks = nodeRename(x.remarks);
|
||||
if(ext.remove_emoji)
|
||||
x.remarks = trim(removeEmoji(x.remarks));
|
||||
if(ext.append_proxy_type)
|
||||
x.remarks = "[" + type + "]" + x.remarks;
|
||||
if(ext.add_emoji)
|
||||
x.remarks = addEmoji(x.remarks);
|
||||
remark = x.remarks;
|
||||
|
||||
hostname = GetMember(json, "Hostname");
|
||||
port = std::__cxx11::to_string((unsigned short)stoi(GetMember(json, "Port")));
|
||||
method = GetMember(json, "EncryptMethod");
|
||||
@@ -942,7 +1004,7 @@ std::string netchToQuanX(std::vector<nodeInfo> &nodes)
|
||||
return allLinks;
|
||||
}
|
||||
|
||||
std::string netchToSSD(std::vector<nodeInfo> &nodes, std::string &group)
|
||||
std::string netchToSSD(std::vector<nodeInfo> &nodes, std::string &group, extra_settings &ext)
|
||||
{
|
||||
rapidjson::Document json;
|
||||
rapidjson::StringBuffer sb;
|
||||
@@ -970,7 +1032,14 @@ std::string netchToSSD(std::vector<nodeInfo> &nodes, std::string &group)
|
||||
for(nodeInfo &x : nodes)
|
||||
{
|
||||
json.Parse(x.proxyStr.data());
|
||||
remark = x.remarks = addEmoji(trim(removeEmoji(nodeRename(x.remarks))));
|
||||
|
||||
x.remarks = nodeRename(x.remarks);
|
||||
if(ext.remove_emoji)
|
||||
x.remarks = trim(removeEmoji(x.remarks));
|
||||
if(ext.add_emoji)
|
||||
x.remarks = addEmoji(x.remarks);
|
||||
remark = x.remarks;
|
||||
|
||||
hostname = GetMember(json, "Hostname");
|
||||
port = (unsigned short)stoi(GetMember(json, "Port"));
|
||||
password = GetMember(json, "Password");
|
||||
@@ -1036,6 +1105,179 @@ std::string netchToSSD(std::vector<nodeInfo> &nodes, std::string &group)
|
||||
return "ssd://" + base64_encode(sb.GetString());
|
||||
}
|
||||
|
||||
std::string netchToMellow(std::vector<nodeInfo> &nodes, std::string &base_conf, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, extra_settings &ext)
|
||||
{
|
||||
rapidjson::Document json;
|
||||
INIReader ini;
|
||||
std::string proxy;
|
||||
std::string type, remark, hostname, port, username, password, method;
|
||||
std::string plugin, pluginopts;
|
||||
std::string id, aid, transproto, faketype, host, path, quicsecure, quicsecret, tlssecure;
|
||||
std::string url, group;
|
||||
std::vector<nodeInfo> nodelist;
|
||||
string_array vArray, remarks_list, filtered_nodelist;
|
||||
|
||||
ini.store_any_line = true;
|
||||
if(ini.Parse(base_conf) != 0)
|
||||
return std::string();
|
||||
|
||||
ini.SetCurrentSection("Endpoint");
|
||||
for(nodeInfo &x : nodes)
|
||||
{
|
||||
json.Parse(x.proxyStr.data());
|
||||
type = GetMember(json, "Type");
|
||||
|
||||
x.remarks = nodeRename(x.remarks);
|
||||
if(ext.remove_emoji)
|
||||
x.remarks = trim(removeEmoji(x.remarks));
|
||||
if(ext.append_proxy_type)
|
||||
x.remarks = "[" + type + "]" + x.remarks;
|
||||
if(ext.add_emoji)
|
||||
x.remarks = addEmoji(x.remarks);
|
||||
remark = x.remarks;
|
||||
|
||||
while(std::count(remarks_list.begin(), remarks_list.end(), remark) > 0)
|
||||
remark = x.remarks = x.remarks + "$";
|
||||
hostname = GetMember(json, "Hostname");
|
||||
port = std::__cxx11::to_string((unsigned short)stoi(GetMember(json, "Port")));
|
||||
username = GetMember(json, "Username");
|
||||
password = GetMember(json, "Password");
|
||||
method = GetMember(json, "EncryptMethod");
|
||||
|
||||
if(x.linkType == SPEEDTEST_MESSAGE_FOUNDSS && GetMember(json, "Plugin") == "")
|
||||
{
|
||||
proxy = remark + ", ss, ss://" + urlsafe_base64_encode(method + ":" + password) + "@" + hostname + ":" + port;
|
||||
}
|
||||
else if(x.linkType == SPEEDTEST_MESSAGE_FOUNDVMESS)
|
||||
{
|
||||
id = GetMember(json, "UserID");
|
||||
aid = GetMember(json, "AlterID");
|
||||
transproto = GetMember(json, "TransferProtocol");
|
||||
host = GetMember(json, "Host");
|
||||
path = GetMember(json, "Path");
|
||||
faketype = GetMember(json, "FakeType");
|
||||
tlssecure = GetMember(json, "TLSSecure");
|
||||
|
||||
proxy = remark + ", vmess1, vmess1://" + id + "@" + hostname + ":" + port;
|
||||
if(path.size())
|
||||
proxy += path;
|
||||
proxy += "?network=" + transproto;
|
||||
if(transproto == "ws")
|
||||
{
|
||||
proxy += "&ws.host=" + UrlEncode(host);
|
||||
}
|
||||
proxy += "&tls=" + tlssecure;
|
||||
}
|
||||
else if(x.linkType == SPEEDTEST_MESSAGE_FOUNDSOCKS)
|
||||
{
|
||||
proxy = remark + ", builtin, socks, address=" + hostname + ", port=" + port + ", user=" + username + ", pass=" + password;
|
||||
}
|
||||
else if(type == "HTTP")
|
||||
{
|
||||
proxy = remark + ", builtin, http, address=" + hostname + ", port=" + port + ", user=" + username + ", pass=" + password;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
ini.Set("{NONAME}", proxy);
|
||||
remarks_list.emplace_back(remark);
|
||||
nodelist.emplace_back(x);
|
||||
}
|
||||
|
||||
ini.SetCurrentSection("EndpointGroup");
|
||||
|
||||
for(std::string &x : extra_proxy_group)
|
||||
{
|
||||
eraseElements(filtered_nodelist);
|
||||
unsigned int rules_upper_bound = 0;
|
||||
url = "";
|
||||
proxy = "";
|
||||
|
||||
vArray = split(x, "`");
|
||||
if(vArray.size() < 3)
|
||||
continue;
|
||||
|
||||
if(vArray[1] == "select")
|
||||
{
|
||||
rules_upper_bound = vArray.size();
|
||||
}
|
||||
else if(vArray[1] == "url-test" || vArray[1] == "fallback" || vArray[1] == "load-balance")
|
||||
{
|
||||
if(vArray.size() < 5)
|
||||
continue;
|
||||
rules_upper_bound = vArray.size() - 2;
|
||||
url = vArray[vArray.size() - 2];
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
for(unsigned int i = 2; i < rules_upper_bound; i++)
|
||||
{
|
||||
if(vArray[i].find("[]") == 0)
|
||||
{
|
||||
filtered_nodelist.emplace_back(vArray[i].substr(2));
|
||||
}
|
||||
else if(vArray[i].find("!!GROUP=") == 0)
|
||||
{
|
||||
group = vArray[i].substr(8);
|
||||
for(nodeInfo &y : nodelist)
|
||||
{
|
||||
if(regFind(y.group, group) && std::find(filtered_nodelist.begin(), filtered_nodelist.end(), y.remarks) == filtered_nodelist.end())
|
||||
filtered_nodelist.emplace_back(y.remarks);
|
||||
}
|
||||
}
|
||||
else if(vArray[i].find("!!GROUPID=") == 0)
|
||||
{
|
||||
group = vArray[i].substr(10);
|
||||
for(nodeInfo &y : nodelist)
|
||||
{
|
||||
if(y.groupID == stoi(group) && std::find(filtered_nodelist.begin(), filtered_nodelist.end(), y.remarks) == filtered_nodelist.end())
|
||||
filtered_nodelist.emplace_back(y.remarks);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(nodeInfo &y : nodelist)
|
||||
{
|
||||
if(regFind(y.remarks, vArray[i]) && std::find(filtered_nodelist.begin(), filtered_nodelist.end(), y.remarks) == filtered_nodelist.end())
|
||||
filtered_nodelist.emplace_back(y.remarks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!filtered_nodelist.size())
|
||||
filtered_nodelist.emplace_back("DIRECT");
|
||||
|
||||
//don't process these for now
|
||||
/*
|
||||
proxy = vArray[1];
|
||||
for(std::string &x : filtered_nodelist)
|
||||
proxy += "," + x;
|
||||
if(vArray[1] == "url-test" || vArray[1] == "fallback" || vArray[1] == "load-balance")
|
||||
proxy += ",url=" + url;
|
||||
*/
|
||||
|
||||
proxy = vArray[0] + ", ";
|
||||
for(std::string &y : filtered_nodelist)
|
||||
proxy += "\"" + y + "\":";
|
||||
proxy = proxy.substr(0, proxy.size() - 1);
|
||||
proxy += ", latency, interval=300, timeout=6"; //use hard-coded values for now
|
||||
|
||||
ini.Set("{NONAME}", proxy); //insert order
|
||||
}
|
||||
|
||||
rulesetToSurge(ini, ruleset_content_array, 2);
|
||||
|
||||
string_multimap rules;
|
||||
ini.GetItems("Rules", rules);
|
||||
ini.EraseSection("Rules");
|
||||
ini.SetCurrentSection("RoutingRule");
|
||||
for(auto &x : rules)
|
||||
ini.Set("{NONAME}", x.second);
|
||||
|
||||
return ini.ToString();
|
||||
}
|
||||
|
||||
std::string buildGistData(std::string name, std::string content)
|
||||
{
|
||||
rapidjson::StringBuffer sb;
|
||||
@@ -1121,6 +1363,7 @@ int uploadGist(std::string name, std::string path, std::string content, bool wri
|
||||
GetMember(json, "id", id);
|
||||
if(json.HasMember("owner"))
|
||||
GetMember(json["owner"], "login", username);
|
||||
url = "https://gist.githubusercontent.com/" + username + "/" + id + "/raw/" + path;
|
||||
std::cerr<<"Writing to Gist success!\nGenerator: "<<name<<"\nPath: "<<path<<"\nRaw URL: "<<url<<"\nGist owner: "<<username<<"\n";
|
||||
|
||||
ini.EraseSection();
|
||||
|
||||
25
subexport.h
25
subexport.h
@@ -10,15 +10,24 @@ struct ruleset_content
|
||||
std::string rule_content;
|
||||
};
|
||||
|
||||
struct extra_settings
|
||||
{
|
||||
bool add_emoji = false;
|
||||
bool remove_emoji = false;
|
||||
bool append_proxy_type = true;
|
||||
string_array include_remarks;
|
||||
};
|
||||
|
||||
std::string netchToClash(std::vector<nodeInfo> &nodes, std::string &base_conf, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, bool clashR);
|
||||
std::string netchToSurge(std::vector<nodeInfo> &nodes, std::string &base_conf, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, int surge_ver);
|
||||
std::string netchToSS(std::vector<nodeInfo> &nodes);
|
||||
std::string netchToSSR(std::vector<nodeInfo> &nodes);
|
||||
std::string netchToVMess(std::vector<nodeInfo> &nodes);
|
||||
std::string netchToQuanX(std::vector<nodeInfo> &nodes);
|
||||
std::string netchToQuan(std::vector<nodeInfo> &nodes);
|
||||
std::string netchToSSD(std::vector<nodeInfo> &nodes, std::string &group);
|
||||
|
||||
std::string netchToClash(std::vector<nodeInfo> &nodes, std::string &base_conf, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, bool clashR, extra_settings &ext);
|
||||
std::string netchToSurge(std::vector<nodeInfo> &nodes, std::string &base_conf, std::vector<ruleset_content> &ruleset_content_array, string_array &extra_proxy_group, int surge_ver, extra_settings &ext);
|
||||
std::string netchToMellow(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 netchToSS(std::vector<nodeInfo> &nodes, extra_settings &ext);
|
||||
std::string netchToSSR(std::vector<nodeInfo> &nodes, extra_settings &ext);
|
||||
std::string netchToVMess(std::vector<nodeInfo> &nodes, extra_settings &ext);
|
||||
std::string netchToQuanX(std::vector<nodeInfo> &nodes, extra_settings &ext);
|
||||
std::string netchToQuan(std::vector<nodeInfo> &nodes, 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);
|
||||
int uploadGist(std::string name, std::string path, std::string content, bool writeManageURL);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user