Enhancements

Fix not correctly handle SOCKS5 nodes in Clash subscriptions.
Add specifying filter script from URL arguments.
Add support for using matchers in include/exclude options.
Rename default configuration files for easier upgrade.
This commit is contained in:
Tindy X 2020-11-08 18:34:26 +08:00
parent 069d1c00f6
commit 74d865ceb0
No known key found for this signature in database
GPG Key ID: C6AD413169968D58
5 changed files with 43 additions and 14 deletions

View File

@ -1362,7 +1362,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
std::string argIncludeRemark = UrlDecode(getUrlArg(argument, "include")), argExcludeRemark = UrlDecode(getUrlArg(argument, "exclude"));
std::string argCustomGroups = urlsafe_base64_decode(getUrlArg(argument, "groups")), argCustomRulesets = urlsafe_base64_decode(getUrlArg(argument, "ruleset")), argExternalConfig = UrlDecode(getUrlArg(argument, "config"));
std::string argDeviceID = getUrlArg(argument, "dev_id"), argFilename = getUrlArg(argument, "filename"), argUpdateInterval = getUrlArg(argument, "interval"), argUpdateStrict = getUrlArg(argument, "strict");
std::string argRenames = UrlDecode(getUrlArg(argument, "rename"));
std::string argRenames = UrlDecode(getUrlArg(argument, "rename")), argFilterScript = UrlDecode(getUrlArg(argument, "filter_script"));
/// switches with default value
tribool argUpload = getUrlArg(argument, "upload"), argEmoji = getUrlArg(argument, "emoji"), argAddEmoji = getUrlArg(argument, "add_emoji"), argRemoveEmoji = getUrlArg(argument, "remove_emoji");
@ -1611,15 +1611,18 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
std::move(insert_nodes.begin(), insert_nodes.end(), std::back_inserter(nodes));
}
//run filter script
if(gFilterScript.size())
std::string filterScript = gFilterScript;
if(authorized && !argFilterScript.empty())
filterScript = argFilterScript;
if(filterScript.size())
{
if(startsWith(gFilterScript, "path:"))
gFilterScript = fileGet(gFilterScript.substr(5), false);
if(startsWith(filterScript, "path:"))
filterScript = fileGet(filterScript.substr(5), false);
duk_context *ctx = duktape_init();
if(ctx)
{
defer(duk_destroy_heap(ctx);)
if(duktape_peval(ctx, gFilterScript) == 0)
if(duktape_peval(ctx, filterScript) == 0)
{
auto filter = [&](const nodeInfo &x)
{

View File

@ -105,6 +105,16 @@ int main(int argc, char *argv[])
#endif // _DEBUG
if(fileExist("pref.yml"))
gPrefPath = "pref.yml";
else if(!fileExist("pref.ini"))
{
if(fileExist("pref.example.yml"))
{
fileCopy("pref.example.yml", "pref.yml");
gPrefPath = "pref.yml";
}
else if(fileExist("pref.example.ini"))
fileCopy("pref.example.ini", "pref.ini");
}
chkArg(argc, argv);
setcd(gPrefPath); //then switch to pref directory
writeLog(0, "SubConverter " VERSION " starting up..", LOG_LEVEL_INFO);

View File

@ -1068,7 +1068,7 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector<nod
node.linkType = SPEEDTEST_MESSAGE_FOUNDSS;
node.proxyStr = ssConstruct(group, ps, server, port, password, cipher, plugin, pluginopts, ss_libev, udp, tfo, scv);
break;
case "socks"_hash:
case "socks5"_hash:
group = SOCKS_DEFAULT_GROUP;
singleproxy["username"] >>= user;
@ -1912,22 +1912,38 @@ void explodeNetchConf(std::string netch, bool ss_libev, bool ssr_libev, const st
}
}
bool applyMatcher(const std::string &rule, std::string &real_rule, const nodeInfo &node);
bool chkIgnore(const nodeInfo &node, string_array &exclude_remarks, string_array &include_remarks)
{
bool excluded = false, included = false;
//std::string remarks = UTF8ToACP(node.remarks);
std::string remarks = node.remarks;
//std::string remarks = node.remarks;
//writeLog(LOG_TYPE_INFO, "Comparing exclude remarks...");
excluded = std::any_of(exclude_remarks.cbegin(), exclude_remarks.cend(), [&remarks](const auto &x)
excluded = std::any_of(exclude_remarks.cbegin(), exclude_remarks.cend(), [&node](const auto &x)
{
return regFind(remarks, x);
std::string real_rule;
if(applyMatcher(x, real_rule, node))
{
if(real_rule.empty()) return true;
return regFind(node.remarks, real_rule);
}
else
return false;
});
if(include_remarks.size() != 0)
{
//writeLog(LOG_TYPE_INFO, "Comparing include remarks...");
included = std::any_of(include_remarks.cbegin(), include_remarks.cend(), [&remarks](const auto &x)
included = std::any_of(include_remarks.cbegin(), include_remarks.cend(), [&node](const auto &x)
{
return regFind(remarks, x);
std::string real_rule;
if(applyMatcher(x, real_rule, node))
{
if(real_rule.empty()) return true;
return regFind(node.remarks, real_rule);
}
else
return false;
});
}
else
@ -2051,6 +2067,7 @@ void explodeSub(std::string sub, bool sslibev, bool ssrlibev, const std::string
}
catch (std::exception &e)
{
writeLog(0, e.what(), LOG_LEVEL_DEBUG);
//ignore
}
@ -2091,7 +2108,6 @@ void filterNodes(std::vector<nodeInfo> &nodes, string_array &exclude_remarks, st
{
int node_index = 0;
std::vector<nodeInfo>::iterator iter = nodes.begin();
/*
while(iter != nodes.end())
{
if(chkIgnore(*iter, exclude_remarks, include_remarks))
@ -2108,8 +2124,7 @@ void filterNodes(std::vector<nodeInfo> &nodes, string_array &exclude_remarks, st
++iter;
}
}
*/
/*
std::vector<std::unique_ptr<pcre2_code, decltype(&pcre2_code_free)>> exclude_patterns, include_patterns;
std::vector<std::unique_ptr<pcre2_match_data, decltype(&pcre2_match_data_free)>> exclude_match_data, include_match_data;
unsigned int i = 0;
@ -2185,6 +2200,7 @@ void filterNodes(std::vector<nodeInfo> &nodes, string_array &exclude_remarks, st
++iter;
}
}
*/
writeLog(LOG_TYPE_INFO, "Filter done.");
}