Enhancements

Add experimental async ruleset fetching.
Optimize codes.
This commit is contained in:
Tindy X committed 2020-03-20 01:37:32 +08:00
1 parent b9fb6b8d7d
commit 0bc341f7ea
11 files changed
+306 -328

No files matched your search

+1
View File
@@ -92,3 +92,4 @@ advanced:
cache_subscription: 60 cache_subscription: 60
cache_config: 300 cache_config: 300
cache_ruleset: 21600 cache_ruleset: 21600
async_fetch_ruleset: false
+1
View File
@@ -178,3 +178,4 @@ enable_cache=false
cache_subscription=60 cache_subscription=60
cache_config=300 cache_config=300
cache_ruleset=21600 cache_ruleset=21600
async_fetch_ruleset=false
+35 -81
View File
@@ -24,7 +24,7 @@ std::vector<ruleset_content> ruleset_content_array;
std::string listen_address = "127.0.0.1", default_url, insert_url, managed_config_prefix; std::string listen_address = "127.0.0.1", default_url, insert_url, managed_config_prefix;
int listen_port = 25500, max_pending_connections = 10, max_concurrent_threads = 4; int listen_port = 25500, max_pending_connections = 10, max_concurrent_threads = 4;
bool api_mode = true, write_managed_config = false, enable_rule_generator = true, update_ruleset_on_request = false, overwrite_original_rules = true; bool api_mode = true, write_managed_config = false, enable_rule_generator = true, update_ruleset_on_request = false, overwrite_original_rules = true;
bool print_debug_info = false, cfw_child_process = false, append_userinfo = true, enable_base_gen = false; bool print_debug_info = false, cfw_child_process = false, append_userinfo = true, enable_base_gen = false, async_fetch_ruleset = false;
std::string access_token; std::string access_token;
extern std::string custom_group; extern std::string custom_group;
extern int global_log_level; extern int global_log_level;
@@ -71,6 +71,16 @@ template <typename T> T safe_as (const YAML::Node& node)
return T(); return T();
}; };
std::string parseProxy(const std::string &source)
{
std::string proxy = source;
if(source == "SYSTEM")
proxy = getSystemProxy();
else if(source == "NONE")
proxy = "";
return proxy;
}
std::string getRuleset(RESPONSE_CALLBACK_ARGS) std::string getRuleset(RESPONSE_CALLBACK_ARGS)
{ {
std::string url = urlsafe_base64_decode(getUrlArg(argument, "url")), type = getUrlArg(argument, "type"), group = urlsafe_base64_decode(getUrlArg(argument, "group")); std::string url = urlsafe_base64_decode(getUrlArg(argument, "url")), type = getUrlArg(argument, "type"), group = urlsafe_base64_decode(getUrlArg(argument, "group"));
@@ -82,13 +92,7 @@ std::string getRuleset(RESPONSE_CALLBACK_ARGS)
return "Invalid request!"; return "Invalid request!";
} }
std::string proxy; std::string proxy = parseProxy(proxy_ruleset);
if(proxy_ruleset == "SYSTEM")
proxy = getSystemProxy();
else if(proxy_ruleset == "NONE")
proxy = "";
else
proxy = proxy_ruleset;
if(fileExist(url)) if(fileExist(url))
output_content = fileGet(url, true); output_content = fileGet(url, true);
@@ -158,13 +162,7 @@ int importItems(string_array &target)
path = x.substr(x.find(":") + 1); path = x.substr(x.find(":") + 1);
writeLog(0, "Trying to import items from " + path); writeLog(0, "Trying to import items from " + path);
std::string proxy; std::string proxy = parseProxy(proxy_config);
if(proxy_ruleset == "SYSTEM")
proxy = getSystemProxy();
else if(proxy_ruleset == "NONE")
proxy = "";
else
proxy = proxy_ruleset;
if(fileExist(path)) if(fileExist(path))
content = fileGet(path, api_mode); content = fileGet(path, api_mode);
@@ -331,13 +329,7 @@ void refreshRulesets(string_array &ruleset_list, std::vector<ruleset_content> &r
std::string rule_group, rule_url, dummy; std::string rule_group, rule_url, dummy;
ruleset_content rc; ruleset_content rc;
std::string proxy; std::string proxy = parseProxy(proxy_ruleset);
if(proxy_ruleset == "SYSTEM")
proxy = getSystemProxy();
else if(proxy_ruleset == "NONE")
proxy = "";
else
proxy = proxy_ruleset;
for(std::string &x : ruleset_list) for(std::string &x : ruleset_list)
{ {
@@ -356,7 +348,7 @@ void refreshRulesets(string_array &ruleset_list, std::vector<ruleset_content> &r
{ {
writeLog(0, "Adding rule '" + rule_url.substr(2) + "," + rule_group + "'.", LOG_LEVEL_INFO); writeLog(0, "Adding rule '" + rule_url.substr(2) + "," + rule_group + "'.", LOG_LEVEL_INFO);
//std::cerr<<"Adding rule '"<<rule_url.substr(2)<<","<<rule_group<<"'."<<std::endl; //std::cerr<<"Adding rule '"<<rule_url.substr(2)<<","<<rule_group<<"'."<<std::endl;
rc = {rule_group, "", rule_url}; rc = {rule_group, "", std::move(std::async(std::launch::async, [rule_url](){return rule_url;}))};
rca.emplace_back(rc); rca.emplace_back(rc);
continue; continue;
} }
@@ -364,22 +356,28 @@ void refreshRulesets(string_array &ruleset_list, std::vector<ruleset_content> &r
{ {
//std::cerr<<"Updating ruleset url '"<<rule_url<<"' with group '"<<rule_group<<"'."<<std::endl; //std::cerr<<"Updating ruleset url '"<<rule_url<<"' with group '"<<rule_group<<"'."<<std::endl;
writeLog(0, "Updating ruleset url '" + rule_url + "' with group '" + rule_group + "'.", LOG_LEVEL_INFO); writeLog(0, "Updating ruleset url '" + rule_url + "' with group '" + rule_group + "'.", LOG_LEVEL_INFO);
/*
if(fileExist(rule_url)) if(fileExist(rule_url))
{ {
rc = {rule_group, rule_url, fileGet(rule_url)}; rc = {rule_group, rule_url, fileGet(rule_url)};
} }
else if(startsWith(rule_url, "http://") || startsWith(rule_url, "https://") || startsWith(rule_url, "data:")) else if(startsWith(rule_url, "https://") || startsWith(rule_url, "http://") || startsWith(rule_url, "data:"))
{ {
rc = {rule_group, rule_url, webGet(rule_url, proxy, dummy, cache_ruleset)}; rc = {rule_group, rule_url, webGet(rule_url, proxy, dummy, cache_ruleset)};
} }
else else
continue; continue;
*/
rc = {rule_group, rule_url, fetchFileAsync(rule_url, proxy, cache_ruleset)};
} }
if(rc.rule_content.size()) rca.emplace_back(rc);
/*
if(rc.rule_content.get().size())
rca.emplace_back(rc); rca.emplace_back(rc);
else else
//std::cerr<<"Warning: No data was fetched from this link. Skipping..."<<std::endl; //std::cerr<<"Warning: No data was fetched from this link. Skipping..."<<std::endl;
writeLog(0, "Warning: No data was fetched from ruleset '" + rule_url + "'. Skipping...", LOG_LEVEL_WARNING); writeLog(0, "Warning: No data was fetched from ruleset '" + rule_url + "'. Skipping...", LOG_LEVEL_WARNING);
*/
} }
} }
@@ -567,6 +565,7 @@ void readYAMLConf(YAML::Node &node)
else else
cache_subscription = cache_config = cache_ruleset = 0; //disable cache cache_subscription = cache_config = cache_ruleset = 0; //disable cache
} }
node["advanced"]["async_fetch_ruleset"] >> async_fetch_ruleset;
} }
} }
@@ -806,6 +805,8 @@ void readConf()
else else
cache_subscription = cache_config = cache_ruleset = 0; //disable cache cache_subscription = cache_config = cache_ruleset = 0; //disable cache
} }
if(ini.ItemExist("async_fetch_ruleset"))
async_fetch_ruleset = ini.GetBool("async_fetch_ruleset");
//std::cerr<<"Read preference settings completed."<<std::endl; //std::cerr<<"Read preference settings completed."<<std::endl;
writeLog(0, "Read preference settings completed.", LOG_LEVEL_INFO); writeLog(0, "Read preference settings completed.", LOG_LEVEL_INFO);
@@ -865,13 +866,7 @@ int loadExternalYAML(YAML::Node &node, ExternalConfig &ext)
int loadExternalConfig(std::string &path, ExternalConfig &ext) int loadExternalConfig(std::string &path, ExternalConfig &ext)
{ {
std::string base_content, dummy; std::string base_content, dummy;
std::string proxy; std::string proxy = parseProxy(proxy_config);
if(proxy_config == "SYSTEM")
proxy = getSystemProxy();
else if(proxy_config == "NONE")
proxy = "";
else
proxy = proxy_config;
if(fileExist(path)) if(fileExist(path))
base_content = fileGet(path, api_mode); base_content = fileGet(path, api_mode);
@@ -1027,13 +1022,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
readConf(); readConf();
//check for proxy settings //check for proxy settings
std::string proxy; std::string proxy = parseProxy(proxy_subscription);
if(proxy_subscription == "SYSTEM")
proxy = getSystemProxy();
else if(proxy_subscription == "NONE")
proxy = "";
else
proxy = proxy_subscription;
ext.emoji_array = safe_get_emojis(); ext.emoji_array = safe_get_emojis();
ext.rename_array = safe_get_renames(); ext.rename_array = safe_get_renames();
@@ -1448,13 +1437,7 @@ std::string simpleToClashR(RESPONSE_CALLBACK_ARGS)
extra_settings ext = {true, overwrite_original_rules, safe_get_renames(), safe_get_emojis(), add_emoji, remove_old_emoji, append_proxy_type, udp_flag, tfo_flag, false, do_sort, scv_flag, filter_deprecated, clash_use_new_field_name, "", "", ""}; extra_settings ext = {true, overwrite_original_rules, safe_get_renames(), safe_get_emojis(), add_emoji, remove_old_emoji, append_proxy_type, udp_flag, tfo_flag, false, do_sort, scv_flag, filter_deprecated, clash_use_new_field_name, "", "", ""};
std::string proxy; std::string proxy = parseProxy(proxy_subscription);
if(proxy_subscription == "SYSTEM")
proxy = getSystemProxy();
else if(proxy_subscription == "NONE")
proxy = "";
else
proxy = proxy_subscription;
include_remarks = def_include_remarks; include_remarks = def_include_remarks;
exclude_remarks = def_exclude_remarks; exclude_remarks = def_exclude_remarks;
@@ -1513,13 +1496,7 @@ std::string surgeConfToClash(RESPONSE_CALLBACK_ARGS)
return "Please insert your subscription link instead of clicking the default link."; return "Please insert your subscription link instead of clicking the default link.";
} }
std::string proxy; std::string proxy = parseProxy(proxy_config);
if(proxy_config == "SYSTEM")
proxy = getSystemProxy();
else if(proxy_config == "NONE")
proxy = "";
else
proxy = proxy_config;
if(fileExist(url)) if(fileExist(url))
base_content = fileGet(url); base_content = fileGet(url);
@@ -1543,12 +1520,7 @@ std::string surgeConfToClash(RESPONSE_CALLBACK_ARGS)
return errmsg; return errmsg;
} }
if(proxy_subscription == "SYSTEM") proxy = parseProxy(proxy_subscription);
proxy = getSystemProxy();
else if(proxy_subscription == "NONE")
proxy = "";
else
proxy = proxy_subscription;
//scan groups first, get potential policy-path //scan groups first, get potential policy-path
string_multimap section; string_multimap section;
@@ -1753,13 +1725,7 @@ std::string getScript(RESPONSE_CALLBACK_ARGS)
std::string url = urlsafe_base64_decode(getUrlArg(argument, "url")), dev_id = getUrlArg(argument, "id"); std::string url = urlsafe_base64_decode(getUrlArg(argument, "url")), dev_id = getUrlArg(argument, "id");
std::string output_content, dummy; std::string output_content, dummy;
std::string proxy; std::string proxy = parseProxy(proxy_config);
if(proxy_config == "SYSTEM")
proxy = getSystemProxy();
else if(proxy_config == "NONE")
proxy = "";
else
proxy = proxy_config;
if(fileExist(url)) if(fileExist(url))
output_content = fileGet(url, true); output_content = fileGet(url, true);
@@ -1785,13 +1751,7 @@ std::string getRewriteRemote(RESPONSE_CALLBACK_ARGS)
std::string url = urlsafe_base64_decode(getUrlArg(argument, "url")), dev_id = getUrlArg(argument, "id"); std::string url = urlsafe_base64_decode(getUrlArg(argument, "url")), dev_id = getUrlArg(argument, "id");
std::string output_content, dummy; std::string output_content, dummy;
std::string proxy; std::string proxy = parseProxy(proxy_config);
if(proxy_config == "SYSTEM")
proxy = getSystemProxy();
else if(proxy_config == "NONE")
proxy = "";
else
proxy = proxy_config;
if(fileExist(url)) if(fileExist(url))
output_content = fileGet(url, true); output_content = fileGet(url, true);
@@ -1974,13 +1934,7 @@ int simpleGenerator()
else else
{ {
//check for proxy settings //check for proxy settings
std::string proxy; std::string proxy = parseProxy(proxy_subscription);
if(proxy_subscription == "SYSTEM")
proxy = getSystemProxy();
else if(proxy_subscription == "NONE")
proxy = "";
else
proxy = proxy_subscription;
content = webGet(url, proxy); content = webGet(url, proxy);
} }
if(content.empty()) if(content.empty())
@@ -2016,7 +1970,7 @@ int simpleGenerator()
fileWrite(path, content, true); fileWrite(path, content, true);
for(auto &y : headers) for(auto &y : headers)
{ {
if(regMatch(y.first, "(?i)Subscription-UserInfo")) if(y.first == "Subscription-UserInfo")
{ {
std::cerr<<"User Info for artifact '"<<x<<"': "<<subInfoToMessage(y.second)<<"\n"; std::cerr<<"User Info for artifact '"<<x<<"': "<<subInfoToMessage(y.second)<<"\n";
break; break;
+8 -8
View File
@@ -44,28 +44,28 @@ void writeLog(int type, std::string content, int level)
*/ */
if(level > global_log_level) if(level > global_log_level)
return; return;
std::cerr<<getTime(2)<<" ["<<getpid()<<"]"; //std::cerr<<getTime(2)<<" ["<<getpid()<<"]";
switch(level) switch(level)
{ {
case LOG_LEVEL_VERBOSE: case LOG_LEVEL_VERBOSE:
std::cerr<<"[VERB]"; std::cerr<<getTime(2)<<" ["<<getpid()<<"]"<<"[VERB]"<<" "<<content<<"\n";
break; break;
case LOG_LEVEL_DEBUG: case LOG_LEVEL_DEBUG:
std::cerr<<"[DEBG]"; std::cerr<<getTime(2)<<" ["<<getpid()<<"]"<<"[DEBG]"<<" "<<content<<"\n";
break; break;
case LOG_LEVEL_INFO: case LOG_LEVEL_INFO:
std::cerr<<"[INFO]"; std::cerr<<getTime(2)<<" ["<<getpid()<<"]"<<"[INFO]"<<" "<<content<<"\n";
break; break;
case LOG_LEVEL_WARNING: case LOG_LEVEL_WARNING:
std::cerr<<"[WARN]"; std::cerr<<getTime(2)<<" ["<<getpid()<<"]"<<"[WARN]"<<" "<<content<<"\n";
break; break;
case LOG_LEVEL_ERROR: case LOG_LEVEL_ERROR:
std::cerr<<"[ERRO]"; std::cerr<<getTime(2)<<" ["<<getpid()<<"]"<<"[ERRO]"<<" "<<content<<"\n";
break; break;
case LOG_LEVEL_FATAL: case LOG_LEVEL_FATAL:
std::cerr<<"[FATL]"; std::cerr<<getTime(2)<<" ["<<getpid()<<"]"<<"[FATL]"<<" "<<content<<"\n";
break; break;
} }
std::cerr<<" "<<content<<"\n"; //std::cerr<<" "<<content<<"\n";
} }
+17
View File
@@ -1,3 +1,6 @@
#include <future>
#include <thread>
#include "webget.h"
#include "multithread.h" #include "multithread.h"
//safety lock for multi-thread //safety lock for multi-thread
@@ -67,3 +70,17 @@ void safe_set_times(string_array &data)
guarded_mutex guard(on_time); guarded_mutex guard(on_time);
time_rules.swap(data); time_rules.swap(data);
} }
std::shared_future<std::string> fetchFileAsync(const std::string &path, const std::string &proxy, int cache_ttl, bool async)
{
std::shared_future<std::string> retVal;
if(fileExist(path))
retVal = std::move(std::async(std::launch::async, [path](){return fileGet(path, true);}));
else if(startsWith(path, "https://") || startsWith(path, "http://"))
retVal = std::move(std::async(std::launch::async, [path, proxy, cache_ttl](){return webGet(path, proxy, cache_ttl);}));
else
return std::move(std::async(std::launch::async, [](){return std::string();}));
if(!async)
retVal.wait();
return retVal;
}
+2
View File
@@ -2,6 +2,7 @@
#define MULTITHREAD_H_INCLUDED #define MULTITHREAD_H_INCLUDED
#include <mutex> #include <mutex>
#include <future>
#include <yaml-cpp/yaml.h> #include <yaml-cpp/yaml.h>
@@ -20,5 +21,6 @@ void safe_set_emojis(string_array &data);
void safe_set_renames(string_array &data); void safe_set_renames(string_array &data);
void safe_set_streams(string_array &data); void safe_set_streams(string_array &data);
void safe_set_times(string_array &data); void safe_set_times(string_array &data);
std::shared_future<std::string> fetchFileAsync(const std::string &path, const std::string &proxy, int cache_ttl, bool async = false);
#endif // MULTITHREAD_H_INCLUDED #endif // MULTITHREAD_H_INCLUDED
+231 -236
View File
@@ -118,6 +118,7 @@ void explodeVmessConf(std::string content, const std::string &custom_port, int l
json.Parse(content.data()); json.Parse(content.data());
if(json.HasParseError()) if(json.HasParseError())
return; return;
/*
if(json.HasMember("outbounds")) //single config if(json.HasMember("outbounds")) //single config
{ {
if(json["outbounds"].Size() > 0 && json["outbounds"][0].HasMember("settings") && json["outbounds"][0]["settings"].HasMember("vnext") && json["outbounds"][0]["settings"]["vnext"].Size() > 0) if(json["outbounds"].Size() > 0 && json["outbounds"][0].HasMember("settings") && json["outbounds"][0]["settings"].HasMember("vnext") && json["outbounds"][0]["settings"]["vnext"].Size() > 0)
@@ -142,6 +143,7 @@ void explodeVmessConf(std::string content, const std::string &custom_port, int l
} }
return; return;
} }
*/
//read all subscribe remark as group name //read all subscribe remark as group name
for(unsigned int i = 0; i < json["subItem"].Size(); i++) for(unsigned int i = 0; i < json["subItem"].Size(); i++)
subdata.insert(std::pair<std::string, std::string>(json["subItem"][i]["id"].GetString(), json["subItem"][i]["remarks"].GetString())); subdata.insert(std::pair<std::string, std::string>(json["subItem"][i]["id"].GetString(), json["subItem"][i]["remarks"].GetString()));
@@ -369,6 +371,7 @@ void explodeSSConf(std::string content, const std::string &custom_port, int loca
json.Parse(content.data()); json.Parse(content.data());
if(json.HasParseError()) if(json.HasParseError())
return; return;
/*
if(json.HasMember("local_port") && json.HasMember("local_address")) //single libev config if(json.HasMember("local_port") && json.HasMember("local_address")) //single libev config
{ {
server = GetMember(json, "server"); server = GetMember(json, "server");
@@ -384,6 +387,7 @@ void explodeSSConf(std::string content, const std::string &custom_port, int loca
nodes.push_back(node); nodes.push_back(node);
return; return;
} }
*/
for(unsigned int i = 0; i < json["configs"].Size(); i++) for(unsigned int i = 0; i < json["configs"].Size(); i++)
{ {
json["configs"][i]["remarks"] >> ps; json["configs"][i]["remarks"] >> ps;
@@ -480,6 +484,7 @@ void explodeSSRConf(std::string content, const std::string &custom_port, int loc
json.Parse(content.data()); json.Parse(content.data());
if(json.HasParseError()) if(json.HasParseError())
return; return;
/*
if(json.HasMember("local_port") && json.HasMember("local_address")) //single libev config if(json.HasMember("local_port") && json.HasMember("local_address")) //single libev config
{ {
method = GetMember(json, "method"); method = GetMember(json, "method");
@@ -503,6 +508,7 @@ void explodeSSRConf(std::string content, const std::string &custom_port, int loc
nodes.push_back(node); nodes.push_back(node);
return; return;
} }
*/
for(unsigned int i = 0; i < json["configs"].Size(); i++) for(unsigned int i = 0; i < json["configs"].Size(); i++)
{ {
json["configs"][i]["group"] >> group; json["configs"][i]["group"] >> group;
@@ -715,16 +721,16 @@ void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::s
password = GetMember(json, "Password"); password = GetMember(json, "Password");
if(remark.empty()) if(remark.empty())
remark = address + ":" + port; remark = address + ":" + port;
if(type == "SS") switch(hash_(type))
{ {
case "SS"_hash:
plugin = GetMember(json, "Plugin"); plugin = GetMember(json, "Plugin");
pluginopts = GetMember(json, "PluginOption"); pluginopts = GetMember(json, "PluginOption");
node.group = SS_DEFAULT_GROUP; node.group = SS_DEFAULT_GROUP;
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
node.proxyStr = ssConstruct(address, port, password, method, plugin, pluginopts, remark, local_port, ss_libev); node.proxyStr = ssConstruct(address, port, password, method, plugin, pluginopts, remark, local_port, ss_libev);
} break;
else if(type == "SSR") case "SSR"_hash:
{
protocol = GetMember(json, "Protocol"); protocol = GetMember(json, "Protocol");
obfs = GetMember(json, "OBFS"); obfs = GetMember(json, "OBFS");
if(find(ss_ciphers.begin(), ss_ciphers.end(), method) != ss_ciphers.end() && (obfs.empty() || obfs == "plain") && (protocol.empty() || protocol == "origin")) if(find(ss_ciphers.begin(), ss_ciphers.end(), method) != ss_ciphers.end() && (obfs.empty() || obfs == "plain") && (protocol.empty() || protocol == "origin"))
@@ -743,9 +749,8 @@ void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::s
node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR; node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR;
node.proxyStr = ssrConstruct(SSR_DEFAULT_GROUP, remark, base64_encode(remark), address, port, protocol, method, obfs, password, obfsparam, protoparam, local_port, ssr_libev); node.proxyStr = ssrConstruct(SSR_DEFAULT_GROUP, remark, base64_encode(remark), address, port, protocol, method, obfs, password, obfsparam, protoparam, local_port, ssr_libev);
} }
} break;
else if(type == "VMess") case "VMess"_hash:
{
id = GetMember(json, "UserID"); id = GetMember(json, "UserID");
aid = GetMember(json, "AlterID"); aid = GetMember(json, "AlterID");
transprot = GetMember(json, "TransferProtocol"); transprot = GetMember(json, "TransferProtocol");
@@ -757,16 +762,15 @@ void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::s
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
node.group = V2RAY_DEFAULT_GROUP; node.group = V2RAY_DEFAULT_GROUP;
node.proxyStr = vmessConstruct(address, port, faketype, id, aid, transprot, method, path, host, edge, tls, local_port); node.proxyStr = vmessConstruct(address, port, faketype, id, aid, transprot, method, path, host, edge, tls, local_port);
} break;
else if(type == "Socks5") case "Socks5"_hash:
{
username = GetMember(json, "Username"); username = GetMember(json, "Username");
node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS; node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
node.group = SOCKS_DEFAULT_GROUP; node.group = SOCKS_DEFAULT_GROUP;
node.proxyStr = socksConstruct(remark, address, port, username, password); node.proxyStr = socksConstruct(remark, address, port, username, password);
} default:
else
return; return;
}
node.remarks = remark; node.remarks = remark;
node.server = address; node.server = address;
@@ -794,8 +798,9 @@ void explodeClash(Node yamlnode, const std::string &custom_port, int local_port,
port = custom_port.empty() ? safe_as<std::string>(singleproxy["port"]) : custom_port; port = custom_port.empty() ? safe_as<std::string>(singleproxy["port"]) : custom_port;
if(port.empty()) if(port.empty())
continue; continue;
if(proxytype == "vmess") switch(hash_(proxytype))
{ {
case "vmess"_hash:
group = V2RAY_DEFAULT_GROUP; group = V2RAY_DEFAULT_GROUP;
singleproxy["uuid"] >> id; singleproxy["uuid"] >> id;
@@ -818,9 +823,8 @@ void explodeClash(Node yamlnode, const std::string &custom_port, int local_port,
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
node.proxyStr = vmessConstruct(server, port, type, id, aid, net, cipher, path, host, edge, tls, local_port); node.proxyStr = vmessConstruct(server, port, type, id, aid, net, cipher, path, host, edge, tls, local_port);
} break;
else if(proxytype == "ss") case "ss"_hash:
{
group = SS_DEFAULT_GROUP; group = SS_DEFAULT_GROUP;
singleproxy["cipher"] >> cipher; singleproxy["cipher"] >> cipher;
@@ -871,16 +875,15 @@ void explodeClash(Node yamlnode, const std::string &custom_port, int local_port,
if(singleproxy["obfs-host"].IsDefined()) if(singleproxy["obfs-host"].IsDefined())
singleproxy["obfs-host"] >> pluginopts_host; singleproxy["obfs-host"] >> pluginopts_host;
} }
else
plugin.clear();
if(plugin == "simple-obfs") switch(hash_(plugin))
{ {
case "simple-obfs"_hash:
case "obfs-local"_hash:
pluginopts = "obfs=" + pluginopts_mode; pluginopts = "obfs=" + pluginopts_mode;
pluginopts += pluginopts_host.empty() ? "" : ";obfs-host=" + pluginopts_host; pluginopts += pluginopts_host.empty() ? "" : ";obfs-host=" + pluginopts_host;
} break;
else if(plugin == "v2ray-plugin") case "v2ray-plugin"_hash:
{
pluginopts = "mode=" + pluginopts_mode + ";" + tls + pluginopts_mux; pluginopts = "mode=" + pluginopts_mode + ";" + tls + pluginopts_mux;
if(pluginopts_host.size()) if(pluginopts_host.size())
pluginopts += "host=" + pluginopts_host + ";"; pluginopts += "host=" + pluginopts_host + ";";
@@ -888,9 +891,8 @@ void explodeClash(Node yamlnode, const std::string &custom_port, int local_port,
pluginopts += "path=" + path + ";"; pluginopts += "path=" + path + ";";
if(pluginopts_mux.size()) if(pluginopts_mux.size())
pluginopts += "mux=" + pluginopts_mux + ";"; pluginopts += "mux=" + pluginopts_mux + ";";
break;
} }
else
pluginopts.clear();
//support for go-shadowsocks2 //support for go-shadowsocks2
if(cipher == "AEAD_CHACHA20_POLY1305") if(cipher == "AEAD_CHACHA20_POLY1305")
@@ -903,27 +905,17 @@ void explodeClash(Node yamlnode, const std::string &custom_port, int local_port,
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
node.proxyStr = ssConstruct(server, port, password, cipher, plugin, pluginopts, ps, local_port, ss_libev); node.proxyStr = ssConstruct(server, port, password, cipher, plugin, pluginopts, ps, local_port, ss_libev);
} break;
else if(proxytype == "socks") case "socks"_hash:
{
group = SOCKS_DEFAULT_GROUP; group = SOCKS_DEFAULT_GROUP;
if(singleproxy["username"].IsDefined() && singleproxy["password"].IsDefined()) singleproxy["username"] >> user;
{ singleproxy["password"] >> password;
singleproxy["username"] >> user;
singleproxy["password"] >> password;
}
else
{
user.clear();
password.clear();
}
node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS; node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
node.proxyStr = socksConstruct(ps, server, port, user, password); node.proxyStr = socksConstruct(ps, server, port, user, password);
} break;
else if(proxytype == "ssr") case "ssr"_hash:
{
group = SSR_DEFAULT_GROUP; group = SSR_DEFAULT_GROUP;
singleproxy["cipher"] >> cipher; singleproxy["cipher"] >> cipher;
@@ -935,27 +927,27 @@ void explodeClash(Node yamlnode, const std::string &custom_port, int local_port,
node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR; node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR;
node.proxyStr = ssrConstruct(group, ps, base64_encode(ps), server, port, protocol, cipher, obfs, password, obfsparam, protoparam, local_port, ssr_libev); node.proxyStr = ssrConstruct(group, ps, base64_encode(ps), server, port, protocol, cipher, obfs, password, obfsparam, protoparam, local_port, ssr_libev);
} break;
else if(proxytype == "http") case "http"_hash:
{
group = HTTP_DEFAULT_GROUP; group = HTTP_DEFAULT_GROUP;
if(singleproxy["username"].IsDefined() && singleproxy["password"].IsDefined()) singleproxy["username"] >> user;
{ singleproxy["password"] >> password;
singleproxy["username"] >> user;
singleproxy["password"] >> password;
}
else
{
user.clear();
password.clear();
}
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP; node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
node.proxyStr = httpConstruct(ps, server, port, user, password); node.proxyStr = httpConstruct(ps, server, port, user, password);
} break;
else case "trojan"_hash:
group = TROJAN_DEFAULT_GROUP;
singleproxy["password"] >> password;
singleproxy["sni"] >> host;
node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN;
node.proxyStr = trojanConstruct(ps, server, port, password, host, true);
break;
default:
continue; continue;
}
node.group = group; node.group = group;
node.remarks = ps; node.remarks = ps;
@@ -1024,27 +1016,31 @@ void explodeKitsunebi(std::string kit, const std::string &custom_port, int local
{ {
std::string add, port, type, id, aid = "0", net = "tcp", path, host, tls, cipher = "auto", remarks; std::string add, port, type, id, aid = "0", net = "tcp", path, host, tls, cipher = "auto", remarks;
std::string addition; std::string addition;
string_size pos;
string_array userinfo; string_array userinfo;
kit = kit.substr(9); kit = kit.substr(9);
if(strFind(kit, "#")) pos = kit.find("#");
if(pos != kit.npos)
{ {
remarks = kit.substr(kit.find("#") + 1); remarks = kit.substr(pos + 1);
kit = kit.substr(0, kit.find("#")); kit = kit.substr(0, pos);
} }
addition = kit.substr(kit.find("?") + 1); pos = kit.find("?");
kit = kit.substr(0, kit.find("?")); addition = kit.substr(pos + 1);
kit = kit.substr(0, pos);
userinfo = split(regReplace(kit, "(.*?)@(.*):(.*)", "$1,$2,$3"), ","); userinfo = split(regReplace(kit, "(.*?)@(.*):(.*)", "$1,$2,$3"), ",");
if(userinfo.size() != 3) if(userinfo.size() != 3)
return; return;
id = userinfo[0]; id = userinfo[0];
add = userinfo[1]; add = userinfo[1];
if(strFind(userinfo[2], "/")) pos = userinfo[2].find("/");
if(pos != userinfo[2].npos)
{ {
port = userinfo[2].substr(0, userinfo[2].find("/")); port = userinfo[2].substr(0, pos);
path = userinfo[2].substr(userinfo[2].find("/")); path = userinfo[2].substr(pos);
} }
else else
{ {
@@ -1106,8 +1102,9 @@ bool explodeSurge(std::string surge, const std::string &custom_port, int local_p
configs = split(regReplace(x.second, proxystr, "$2"), ","); configs = split(regReplace(x.second, proxystr, "$2"), ",");
if(configs.size() < 2 || configs[0] == "direct") if(configs.size() < 2 || configs[0] == "direct")
continue; continue;
if(configs[0] == "custom") //surge 2 style custom proxy switch(hash_(configs[0]))
{ {
case "custom"_hash: //surge 2 style custom proxy
//remove module detection to speed up parsing and compatible with broken module //remove module detection to speed up parsing and compatible with broken module
/* /*
mod_url = trim(configs[5]); mod_url = trim(configs[5]);
@@ -1158,9 +1155,8 @@ bool explodeSurge(std::string surge, const std::string &custom_port, int local_p
} }
//else //else
// continue; // continue;
} break;
else if(configs[0] == "ss") //surge 3 style ss proxy case "ss"_hash: //surge 3 style ss proxy
{
server = trim(configs[1]); server = trim(configs[1]);
port = custom_port.empty() ? trim(configs[2]) : custom_port; port = custom_port.empty() ? trim(configs[2]) : custom_port;
@@ -1192,9 +1188,8 @@ bool explodeSurge(std::string surge, const std::string &custom_port, int local_p
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
node.group = SS_DEFAULT_GROUP; node.group = SS_DEFAULT_GROUP;
node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, local_port, libev); node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, local_port, libev);
} break;
else if(configs[0] == "socks5") //surge 3 style socks5 proxy case "socks5"_hash: //surge 3 style socks5 proxy
{
node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS; node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
node.group = SOCKS_DEFAULT_GROUP; node.group = SOCKS_DEFAULT_GROUP;
server = trim(configs[1]); server = trim(configs[1]);
@@ -1205,9 +1200,8 @@ bool explodeSurge(std::string surge, const std::string &custom_port, int local_p
password = trim(configs[3]); password = trim(configs[3]);
} }
node.proxyStr = socksConstruct(remarks, server, port, username, password); node.proxyStr = socksConstruct(remarks, server, port, username, password);
} break;
else if(configs[0] == "vmess") //surge 4 style vmess proxy case "vmess"_hash: //surge 4 style vmess proxy
{
server = trim(configs[1]); server = trim(configs[1]);
port = custom_port.empty() ? trim(configs[2]) : custom_port; port = custom_port.empty() ? trim(configs[2]) : custom_port;
net = "tcp"; net = "tcp";
@@ -1247,9 +1241,8 @@ bool explodeSurge(std::string surge, const std::string &custom_port, int local_p
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
node.group = V2RAY_DEFAULT_GROUP; node.group = V2RAY_DEFAULT_GROUP;
node.proxyStr = vmessConstruct(server, port, "", id, "0", net, method, path, host, edge, tls, local_port); node.proxyStr = vmessConstruct(server, port, "", id, "0", net, method, path, host, edge, tls, local_port);
} break;
else if(configs[0] == "http") //http proxy case "http"_hash: //http proxy
{
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP; node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
node.group = HTTP_DEFAULT_GROUP; node.group = HTTP_DEFAULT_GROUP;
server = trim(configs[1]); server = trim(configs[1]);
@@ -1260,9 +1253,8 @@ bool explodeSurge(std::string surge, const std::string &custom_port, int local_p
password = trim(configs[3]); password = trim(configs[3]);
} }
node.proxyStr = httpConstruct(remarks, server, port, username, password); node.proxyStr = httpConstruct(remarks, server, port, username, password);
} break;
else if(configs[0] == "trojan") // surge 4 style trojan proxy case "trojan"_hash: // surge 4 style trojan proxy
{
node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN; node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN;
node.group = TROJAN_DEFAULT_GROUP; node.group = TROJAN_DEFAULT_GROUP;
server = trim(configs[1]); server = trim(configs[1]);
@@ -1282,166 +1274,168 @@ bool explodeSurge(std::string surge, const std::string &custom_port, int local_p
host = server; host = server;
node.proxyStr = trojanConstruct(remarks, server, port, password, host, false); node.proxyStr = trojanConstruct(remarks, server, port, password, host, false);
} break;
else if(remarks == "shadowsocks") //quantumult x style ss/ssr link default:
{ switch(hash_(remarks))
server = trim(configs[0].substr(0, configs[0].rfind(":")));
port = custom_port.empty() ? trim(configs[0].substr(configs[0].rfind(":") + 1)) : custom_port;
for(i = 1; i < configs.size(); i++)
{ {
vArray = split(trim(configs[i]), "="); case "shadowsocks"_hash: //quantumult x style ss/ssr link
if(vArray.size() != 2) server = trim(configs[0].substr(0, configs[0].rfind(":")));
continue; port = custom_port.empty() ? trim(configs[0].substr(configs[0].rfind(":") + 1)) : custom_port;
itemName = trim(vArray[0]);
itemVal = trim(vArray[1]); for(i = 1; i < configs.size(); i++)
switch(hash_(itemName))
{ {
case "method"_hash: method = itemVal; break; vArray = split(trim(configs[i]), "=");
case "password"_hash: id = itemVal; break; if(vArray.size() != 2)
case "tag"_hash: remarks = itemVal; break; continue;
case "ssr-protocol"_hash: protocol = itemVal; break; itemName = trim(vArray[0]);
case "ssr-protocol-param"_hash: protoparam = itemVal; break; itemVal = trim(vArray[1]);
case "obfs"_hash: switch(hash_(itemName))
plugin = "simple-obfs"; {
pluginopts_mode = itemVal; case "method"_hash: method = itemVal; break;
break; case "password"_hash: id = itemVal; break;
case "obfs-host"_hash: pluginopts_host = itemVal; break; case "tag"_hash: remarks = itemVal; break;
default: continue; case "ssr-protocol"_hash: protocol = itemVal; break;
case "ssr-protocol-param"_hash: protoparam = itemVal; break;
case "obfs"_hash:
plugin = "simple-obfs";
pluginopts_mode = itemVal;
break;
case "obfs-host"_hash: pluginopts_host = itemVal; break;
default: continue;
}
} }
} if(remarks.empty())
if(remarks.empty()) remarks = server + ":" + port;
remarks = server + ":" + port; if(plugin.size())
if(plugin.size())
{
pluginopts = "obfs=" + pluginopts_mode;
if(pluginopts_host.size())
pluginopts += ";obfs-host=" + pluginopts_host;
}
if(protocol.size())
{
node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR;
node.group = SSR_DEFAULT_GROUP;
node.proxyStr = ssrConstruct(node.group, remarks, base64_encode(remarks), server, port, protocol, method, pluginopts_mode, password, pluginopts_host, protoparam, local_port, libev);
}
else
{
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
node.group = SS_DEFAULT_GROUP;
node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, local_port, libev);
}
}
else if(remarks == "vmess") //quantumult x style vmess link
{
server = trim(configs[0].substr(0, configs[0].rfind(":")));
port = custom_port.empty() ? trim(configs[0].substr(configs[0].rfind(":") + 1)) : custom_port;
net = "tcp";
for(i = 1; i < configs.size(); i++)
{
vArray = split(trim(configs[i]), "=");
if(vArray.size() != 2)
continue;
itemName = trim(vArray[0]);
itemVal = trim(vArray[1]);
switch(hash_(itemName))
{ {
case "method"_hash: method = itemVal; break; pluginopts = "obfs=" + pluginopts_mode;
case "password"_hash: id = itemVal; break; if(pluginopts_host.size())
case "tag"_hash: remarks = itemVal; break; pluginopts += ";obfs-host=" + pluginopts_host;
case "obfs"_hash:
switch(hash_(itemVal))
{
case "ws"_hash: net = "ws"; break;
case "over-tls"_hash: tls = "tls"; break;
}
break;
case "obfs-host"_hash: host = itemVal; break;
case "obfs-uri"_hash: path = itemVal; break;
case "over-tls"_hash: tls = itemVal == "true" ? "tls" : ""; break;
default: continue;
} }
}
if(remarks.empty())
remarks = server + ":" + port;
if(host.empty() && !isIPv4(server) && !isIPv6(server)) if(protocol.size())
host = server;
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
node.group = V2RAY_DEFAULT_GROUP;
node.proxyStr = vmessConstruct(server, port, "", id, "0", net, method, path, host, "", tls, local_port);
}
else if(remarks == "trojan") //quantumult x style trojan link
{
server = trim(configs[0].substr(0, configs[0].rfind(":")));
port = custom_port.empty() ? trim(configs[0].substr(configs[0].rfind(":") + 1)) : custom_port;
for(i = 1; i < configs.size(); i++)
{
vArray = split(trim(configs[i]), "=");
if(vArray.size() != 2)
continue;
itemName = trim(vArray[0]);
itemVal = trim(vArray[1]);
switch(hash_(itemName))
{ {
case "password"_hash: password = itemVal; break; node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR;
case "tag"_hash: remarks = itemVal; break; node.group = SSR_DEFAULT_GROUP;
case "over-tls"_hash: tls = itemVal; break; node.proxyStr = ssrConstruct(node.group, remarks, base64_encode(remarks), server, port, protocol, method, pluginopts_mode, password, pluginopts_host, protoparam, local_port, libev);
case "tls-host"_hash: host = itemVal; break;
default: continue;
} }
} else
if(remarks.empty())
remarks = server + ":" + port;
if(host.empty() && !isIPv4(server) && !isIPv6(server))
host = server;
node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN;
node.group = TROJAN_DEFAULT_GROUP;
node.proxyStr = trojanConstruct(remarks, server, port, password, host, tls == "true");
}
else if(remarks == "http") //quantumult x style http links
{
server = trim(configs[0].substr(0, configs[0].rfind(":")));
port = custom_port.empty() ? trim(configs[0].substr(configs[0].rfind(":") + 1)) : custom_port;
for(i = 1; i < configs.size(); i++)
{
vArray = split(trim(configs[i]), "=");
if(vArray.size() != 2)
continue;
itemName = trim(vArray[0]);
itemVal = trim(vArray[1]);
switch(hash_(itemName))
{ {
case "username"_hash: username = itemVal; break; node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
case "password"_hash: password = itemVal; break; node.group = SS_DEFAULT_GROUP;
case "tag"_hash: remarks = itemVal; break; node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, local_port, libev);
case "over-tls"_hash: tls = itemVal; break;
default: continue;
} }
break;
case "vmess"_hash: //quantumult x style vmess link
server = trim(configs[0].substr(0, configs[0].rfind(":")));
port = custom_port.empty() ? trim(configs[0].substr(configs[0].rfind(":") + 1)) : custom_port;
net = "tcp";
for(i = 1; i < configs.size(); i++)
{
vArray = split(trim(configs[i]), "=");
if(vArray.size() != 2)
continue;
itemName = trim(vArray[0]);
itemVal = trim(vArray[1]);
switch(hash_(itemName))
{
case "method"_hash: method = itemVal; break;
case "password"_hash: id = itemVal; break;
case "tag"_hash: remarks = itemVal; break;
case "obfs"_hash:
switch(hash_(itemVal))
{
case "ws"_hash: net = "ws"; break;
case "over-tls"_hash: tls = "tls"; break;
}
break;
case "obfs-host"_hash: host = itemVal; break;
case "obfs-uri"_hash: path = itemVal; break;
case "over-tls"_hash: tls = itemVal == "true" ? "tls" : ""; break;
default: continue;
}
}
if(remarks.empty())
remarks = server + ":" + port;
if(host.empty() && !isIPv4(server) && !isIPv6(server))
host = server;
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
node.group = V2RAY_DEFAULT_GROUP;
node.proxyStr = vmessConstruct(server, port, "", id, "0", net, method, path, host, "", tls, local_port);
break;
case "trojan"_hash: //quantumult x style trojan link
server = trim(configs[0].substr(0, configs[0].rfind(":")));
port = custom_port.empty() ? trim(configs[0].substr(configs[0].rfind(":") + 1)) : custom_port;
for(i = 1; i < configs.size(); i++)
{
vArray = split(trim(configs[i]), "=");
if(vArray.size() != 2)
continue;
itemName = trim(vArray[0]);
itemVal = trim(vArray[1]);
switch(hash_(itemName))
{
case "password"_hash: password = itemVal; break;
case "tag"_hash: remarks = itemVal; break;
case "over-tls"_hash: tls = itemVal; break;
case "tls-host"_hash: host = itemVal; break;
default: continue;
}
}
if(remarks.empty())
remarks = server + ":" + port;
if(host.empty() && !isIPv4(server) && !isIPv6(server))
host = server;
node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN;
node.group = TROJAN_DEFAULT_GROUP;
node.proxyStr = trojanConstruct(remarks, server, port, password, host, tls == "true");
break;
case "http"_hash: //quantumult x style http links
server = trim(configs[0].substr(0, configs[0].rfind(":")));
port = custom_port.empty() ? trim(configs[0].substr(configs[0].rfind(":") + 1)) : custom_port;
for(i = 1; i < configs.size(); i++)
{
vArray = split(trim(configs[i]), "=");
if(vArray.size() != 2)
continue;
itemName = trim(vArray[0]);
itemVal = trim(vArray[1]);
switch(hash_(itemName))
{
case "username"_hash: username = itemVal; break;
case "password"_hash: password = itemVal; break;
case "tag"_hash: remarks = itemVal; break;
case "over-tls"_hash: tls = itemVal; break;
default: continue;
}
}
if(remarks.empty())
remarks = server + ":" + port;
if(host.empty() && !isIPv4(server) && !isIPv6(server))
host = server;
if(username == "none")
username.clear();
if(password == "none")
password.clear();
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
node.group = HTTP_DEFAULT_GROUP;
node.proxyStr = httpConstruct(remarks, server, port, username, password, tls == "true");
break;
default:
continue;
} }
if(remarks.empty()) break;
remarks = server + ":" + port;
if(host.empty() && !isIPv4(server) && !isIPv6(server))
host = server;
if(username == "none")
username.clear();
if(password == "none")
password.clear();
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
node.group = HTTP_DEFAULT_GROUP;
node.proxyStr = httpConstruct(remarks, server, port, username, password, tls == "true");
} }
else
continue;
node.remarks = remarks; node.remarks = remarks;
node.server = server; node.server = server;
@@ -1479,14 +1473,14 @@ void explodeSSTap(std::string sstap, const std::string &custom_port, int local_p
json["configs"][i]["password"] >> pass; json["configs"][i]["password"] >> pass;
json["configs"][i]["type"] >> configType; json["configs"][i]["type"] >> configType;
if(configType == "5") //socks 5 switch(to_int(configType, 0))
{ {
case 5: //socks 5
json["configs"][i]["username"] >> user; json["configs"][i]["username"] >> user;
node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS; node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
node.proxyStr = socksConstruct(remarks, server, port, user, pass); node.proxyStr = socksConstruct(remarks, server, port, user, pass);
} break;
else if(configType == "6") //ss/ssr case 6: //ss/ssr
{
json["configs"][i]["protocol"] >> protocol; json["configs"][i]["protocol"] >> protocol;
json["configs"][i]["obfs"] >> obfs; json["configs"][i]["obfs"] >> obfs;
json["configs"][i]["method"] >> cipher; json["configs"][i]["method"] >> cipher;
@@ -1502,9 +1496,10 @@ void explodeSSTap(std::string sstap, const std::string &custom_port, int local_p
node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR; node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR;
node.proxyStr = ssrConstruct(group, remarks, base64_encode(remarks), server, port, protocol, cipher, obfs, pass, obfsparam, protoparam, local_port, ssr_libev); node.proxyStr = ssrConstruct(group, remarks, base64_encode(remarks), server, port, protocol, cipher, obfs, pass, obfsparam, protoparam, local_port, ssr_libev);
} }
} break;
else default:
continue; continue;
}
node.group = group; node.group = group;
node.remarks = remarks; node.remarks = remarks;
@@ -1807,7 +1802,7 @@ void filterNodes(std::vector<nodeInfo> &nodes, string_array &exclude_remarks, st
writeLog(LOG_TYPE_INFO, "Filter done."); writeLog(LOG_TYPE_INFO, "Filter done.");
} }
static inline unsigned long long streamToInt(std::string stream) static inline unsigned long long streamToInt(const std::string &stream)
{ {
if(!stream.size()) if(!stream.size())
return 0; return 0;
@@ -1827,9 +1822,9 @@ static inline unsigned long long streamToInt(std::string stream)
return (unsigned long long)streamval; return (unsigned long long)streamval;
} }
static inline double percentToDouble(std::string percent) static inline double percentToDouble(const std::string &percent)
{ {
return stof(percent.erase(percent.size() - 1)) / 100.0; return stof(percent.substr(0, percent.size() - 1)) / 100.0;
} }
time_t dateStringToTimestamp(std::string date) time_t dateStringToTimestamp(std::string date)
+2 -2
View File
@@ -407,7 +407,7 @@ void rulesetToClash(YAML::Node &base_rule, std::vector<ruleset_content> &ruleset
for(ruleset_content &x : ruleset_content_array) for(ruleset_content &x : ruleset_content_array)
{ {
rule_group = x.rule_group; rule_group = x.rule_group;
retrived_rules = x.rule_content; retrived_rules = x.rule_content.get();
if(retrived_rules.find("[]") == 0) if(retrived_rules.find("[]") == 0)
{ {
strLine = retrived_rules.substr(2); strLine = retrived_rules.substr(2);
@@ -494,7 +494,7 @@ void rulesetToSurge(INIReader &base_rule, std::vector<ruleset_content> &ruleset_
for(ruleset_content &x : ruleset_content_array) for(ruleset_content &x : ruleset_content_array)
{ {
rule_group = x.rule_group; rule_group = x.rule_group;
retrived_rules = x.rule_content; retrived_rules = x.rule_content.get();
if(retrived_rules.find("[]") == 0) if(retrived_rules.find("[]") == 0)
{ {
strLine = retrived_rules.substr(2); strLine = retrived_rules.substr(2);
+2 -1
View File
@@ -3,6 +3,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <future>
#include "misc.h" #include "misc.h"
#include "ini_reader.h" #include "ini_reader.h"
@@ -12,7 +13,7 @@ struct ruleset_content
{ {
std::string rule_group; std::string rule_group;
std::string rule_path; std::string rule_path;
std::string rule_content; std::shared_future<std::string> rule_content;
}; };
struct extra_settings struct extra_settings
+6
View File
@@ -167,6 +167,12 @@ std::string webGet(std::string url, std::string proxy)
return webGet(url, proxy, dummy); return webGet(url, proxy, dummy);
} }
std::string webGet(std::string url, std::string proxy, unsigned int cache_ttl)
{
std::string dummy;
return webGet(url, proxy, dummy, cache_ttl);
}
int curlPost(std::string url, std::string data, std::string proxy, std::string auth_token, std::string *retData) int curlPost(std::string url, std::string data, std::string proxy, std::string auth_token, std::string *retData)
{ {
CURL *curl_handle; CURL *curl_handle;
+1
View File
@@ -10,6 +10,7 @@
#include "misc.h" #include "misc.h"
std::string webGet(std::string url, std::string proxy); std::string webGet(std::string url, std::string proxy);
std::string webGet(std::string url, std::string proxy, unsigned int cache_ttl);
std::string webGet(std::string url, std::string proxy, std::string &response_headers, unsigned int cache_ttl = 0); std::string webGet(std::string url, std::string proxy, std::string &response_headers, unsigned int cache_ttl = 0);
int webPost(std::string url, std::string data, std::string proxy, std::string auth_token, std::string *retData); int webPost(std::string url, std::string data, std::string proxy, std::string auth_token, std::string *retData);
int webPatch(std::string url, std::string data, std::string proxy, std::string auth_token, std::string *retData); int webPatch(std::string url, std::string data, std::string proxy, std::string auth_token, std::string *retData);