mirror of
https://github.com/asdlokj1qpi233/subconverter.git
synced 2026-11-04 02:34:06 +00:00
Enhancements
Fix exporting useless info in Clash HTTP/SOCKS 5 nodes. Add support for exporting Clash classical rule-provider. Optimize codes. Update build script.
This commit is contained in:
6 files changed
+159
-95
No files matched your search
@@ -30,7 +30,7 @@ jobs:
|
|||||||
- name: Docker buildx image and push on master branch
|
- name: Docker buildx image and push on master branch
|
||||||
if: github.ref == 'refs/heads/master'
|
if: github.ref == 'refs/heads/master'
|
||||||
run: |
|
run: |
|
||||||
docker buildx build --output "type=image,push=true" --platform=linux/amd64,linux/arm/v7,linux/arm64 --tag tindy2013/subconverter:latest scripts/
|
docker buildx build --output "type=image,push=true" --platform=linux/amd64,linux/arm/v7,linux/arm64,linux/386 --tag tindy2013/subconverter:latest scripts/
|
||||||
|
|
||||||
- name: Replace tag without `v`
|
- name: Replace tag without `v`
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
@@ -44,5 +44,5 @@ jobs:
|
|||||||
- name: Docker buildx image and push on release
|
- name: Docker buildx image and push on release
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
run: |
|
run: |
|
||||||
docker buildx build --output "type=image,push=true" --platform=linux/amd64,linux/arm/v7,linux/arm64 --tag tindy2013/subconverter:${{steps.version.outputs.result}} scripts/
|
docker buildx build --output "type=image,push=true" --platform=linux/amd64,linux/arm/v7,linux/arm64,linux/386 --tag tindy2013/subconverter:${{steps.version.outputs.result}} scripts/
|
||||||
docker buildx build --output "type=image,push=true" --platform=linux/amd64,linux/arm/v7,linux/arm64 --tag tindy2013/subconverter:latest scripts/
|
docker buildx build --output "type=image,push=true" --platform=linux/amd64,linux/arm/v7,linux/arm64,linux/386 --tag tindy2013/subconverter:latest scripts/
|
||||||
+61
-43
@@ -103,17 +103,18 @@ std::string parseProxy(const std::string &source)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define basic_types "DOMAIN", "DOMAIN-SUFFIX", "DOMAIN-KEYWORD", "IP-CIDR", "SRC-IP-CIDR", "GEOIP", "MATCH", "FINAL"
|
#define basic_types "DOMAIN", "DOMAIN-SUFFIX", "DOMAIN-KEYWORD", "IP-CIDR", "SRC-IP-CIDR", "GEOIP", "MATCH", "FINAL"
|
||||||
|
const string_array clash_rule_type = {basic_types, "IP-CIDR6", "SRC-PORT", "DST-PORT"};
|
||||||
const string_array surge_rule_type = {basic_types, "IP-CIDR6", "USER-AGENT", "URL-REGEX", "AND", "OR", "NOT", "PROCESS-NAME", "IN-PORT", "DEST-PORT", "SRC-IP"};
|
const string_array surge_rule_type = {basic_types, "IP-CIDR6", "USER-AGENT", "URL-REGEX", "AND", "OR", "NOT", "PROCESS-NAME", "IN-PORT", "DEST-PORT", "SRC-IP"};
|
||||||
const string_array quanx_rule_type = {basic_types, "USER-AGENT", "HOST", "HOST-SUFFIX", "HOST-KEYWORD"};
|
const string_array quanx_rule_type = {basic_types, "USER-AGENT", "HOST", "HOST-SUFFIX", "HOST-KEYWORD"};
|
||||||
|
|
||||||
std::string getRuleset(RESPONSE_CALLBACK_ARGS)
|
std::string getRuleset(RESPONSE_CALLBACK_ARGS)
|
||||||
{
|
{
|
||||||
/// type: 1 for Surge, 2 for Quantumult X, 3 for Clash domain rule-provider, 4 for Clash ipcidr rule-provider, 5 for Surge DOMAIN-SET
|
/// type: 1 for Surge, 2 for Quantumult X, 3 for Clash domain rule-provider, 4 for Clash ipcidr rule-provider, 5 for Surge DOMAIN-SET, 6 for Clash classical ruleset
|
||||||
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"));
|
||||||
std::string output_content, dummy;
|
std::string output_content, dummy;
|
||||||
int type_int = to_int(type, 0);
|
int type_int = to_int(type, 0);
|
||||||
|
|
||||||
if(!url.size() || !type.size() || (type_int == 2 && !group.size()) || (type_int < 1 && type_int > 5))
|
if(!url.size() || !type.size() || (type_int == 2 && !group.size()) || (type_int < 1 && type_int > 6))
|
||||||
{
|
{
|
||||||
*status_code = 400;
|
*status_code = 400;
|
||||||
return "Invalid request!";
|
return "Invalid request!";
|
||||||
@@ -136,11 +137,31 @@ std::string getRuleset(RESPONSE_CALLBACK_ARGS)
|
|||||||
|
|
||||||
ss << output_content;
|
ss << output_content;
|
||||||
char delimiter = count(output_content.begin(), output_content.end(), '\n') < 1 ? '\r' : '\n';
|
char delimiter = count(output_content.begin(), output_content.end(), '\n') < 1 ? '\r' : '\n';
|
||||||
std::string::size_type lineSize;
|
std::string::size_type lineSize, posb, pose;
|
||||||
|
auto filterLine = [&]()
|
||||||
|
{
|
||||||
|
posb = 0;
|
||||||
|
pose = strLine.find(',');
|
||||||
|
if(pose == strLine.npos)
|
||||||
|
return 1;
|
||||||
|
posb = pose + 1;
|
||||||
|
pose = strLine.find(',', posb);
|
||||||
|
if(pose == strLine.npos)
|
||||||
|
{
|
||||||
|
pose = strLine.size();
|
||||||
|
if(strLine[pose - 1] == '\r')
|
||||||
|
pose--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pose -= posb + 1;
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
lineSize = output_content.size();
|
||||||
output_content.clear();
|
output_content.clear();
|
||||||
|
output_content.reserve(lineSize);
|
||||||
|
|
||||||
if(type_int == 3 || type_int == 4)
|
if(type_int == 3 || type_int == 4 || type_int == 6)
|
||||||
output_content = "payload:\n";
|
output_content = "payload:\n";
|
||||||
|
|
||||||
while(getline(ss, strLine, delimiter))
|
while(getline(ss, strLine, delimiter))
|
||||||
@@ -158,51 +179,35 @@ std::string getRuleset(RESPONSE_CALLBACK_ARGS)
|
|||||||
case 3:
|
case 3:
|
||||||
if(!startsWith(strLine, "DOMAIN-SUFFIX,") && !startsWith(strLine, "DOMAIN,"))
|
if(!startsWith(strLine, "DOMAIN-SUFFIX,") && !startsWith(strLine, "DOMAIN,"))
|
||||||
continue;
|
continue;
|
||||||
vArray = split(strLine, ",");
|
if(filterLine())
|
||||||
if(vArray.size() < 2)
|
|
||||||
continue;
|
continue;
|
||||||
vArray[1] = regTrim(vArray[1]);
|
output_content += " - '";
|
||||||
switch(hash_(vArray[0]))
|
if(strLine[posb - 2] == 'X')
|
||||||
{
|
output_content += "+.";
|
||||||
case "DOMAIN-SUFFIX"_hash:
|
output_content += strLine.substr(posb, pose);
|
||||||
strLine = " - '+." + vArray[1] + "'";
|
output_content += "'\n";
|
||||||
break;
|
|
||||||
case "DOMAIN"_hash:
|
|
||||||
strLine = " - '" + vArray[1] + "'";
|
|
||||||
break;
|
|
||||||
//case "DOMAIN_KEYWORD"_hash:
|
|
||||||
//strLine = " - '." + vArray[1] + ".*'";
|
|
||||||
//break;
|
|
||||||
}
|
|
||||||
output_content += strLine + "\n";
|
|
||||||
continue;
|
continue;
|
||||||
case 4:
|
case 4:
|
||||||
if(!startsWith(strLine, "IP-CIDR,") && !startsWith(strLine, "IP-CIDR6,"))
|
if(!startsWith(strLine, "IP-CIDR,") && !startsWith(strLine, "IP-CIDR6,"))
|
||||||
continue;
|
continue;
|
||||||
vArray = split(strLine, ",");
|
if(filterLine())
|
||||||
if(vArray.size() < 2)
|
|
||||||
continue;
|
continue;
|
||||||
output_content += " - '" + vArray[1] + "'\n";
|
output_content += " - '";
|
||||||
|
output_content += strLine.substr(posb, pose);
|
||||||
|
output_content += "'\n";
|
||||||
continue;
|
continue;
|
||||||
case 5:
|
case 5:
|
||||||
if(!startsWith(strLine, "DOMAIN-SUFFIX,") && !startsWith(strLine, "DOMAIN,"))
|
if(!startsWith(strLine, "DOMAIN-SUFFIX,") && !startsWith(strLine, "DOMAIN,"))
|
||||||
continue;
|
continue;
|
||||||
vArray = split(strLine, ",");
|
if(filterLine())
|
||||||
if(vArray.size() < 2)
|
|
||||||
continue;
|
continue;
|
||||||
vArray[1] = regTrim(vArray[1]);
|
output_content += strLine.substr(posb, pose);
|
||||||
switch(hash_(vArray[0]))
|
output_content += '\n';
|
||||||
{
|
|
||||||
case "DOMAIN-SUFFIX"_hash:
|
|
||||||
case "DOMAIN"_hash:
|
|
||||||
strLine = vArray[1];
|
|
||||||
break;
|
|
||||||
//case "DOMAIN_KEYWORD"_hash:
|
|
||||||
//strLine = " - '." + vArray[1] + ".*'";
|
|
||||||
//break;
|
|
||||||
}
|
|
||||||
output_content += strLine + "\n";
|
|
||||||
continue;
|
continue;
|
||||||
|
case 6:
|
||||||
|
if(!std::any_of(clash_rule_type.begin(), clash_rule_type.end(), [&strLine](std::string type){return startsWith(strLine, type);}))
|
||||||
|
continue;
|
||||||
|
output_content += " - ";
|
||||||
}
|
}
|
||||||
|
|
||||||
lineSize = strLine.size();
|
lineSize = strLine.size();
|
||||||
@@ -225,13 +230,25 @@ std::string getRuleset(RESPONSE_CALLBACK_ARGS)
|
|||||||
strLine = regReplace(strLine, rule_match_regex, "$1$3");
|
strLine = regReplace(strLine, rule_match_regex, "$1$3");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output_content += strLine + "\n";
|
output_content += strLine;
|
||||||
|
output_content += '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type_int == 3 && output_content == "payload:\n")
|
if(output_content == "payload:\n")
|
||||||
output_content += " - '--placeholder--'";
|
{
|
||||||
if(type_int == 4 && output_content == "payload:\n")
|
switch(type_int)
|
||||||
output_content += " - '0.0.0.0/32'";
|
{
|
||||||
|
case 3:
|
||||||
|
output_content += " - '--placeholder--'";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
output_content += " - '0.0.0.0/32'";
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
output_content += " - 'DOMAIN,--placeholder--'";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return output_content;
|
return output_content;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1185,7 +1202,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
|||||||
tribool sort_flag = getUrlArg(argument, "sort"), use_sort_script = getUrlArg(argument, "sort_script");
|
tribool sort_flag = getUrlArg(argument, "sort"), use_sort_script = getUrlArg(argument, "sort_script");
|
||||||
tribool clash_new_field = getUrlArg(argument, "new_name"), clash_script = getUrlArg(argument, "script"), add_insert = getUrlArg(argument, "insert");
|
tribool clash_new_field = getUrlArg(argument, "new_name"), clash_script = getUrlArg(argument, "script"), add_insert = getUrlArg(argument, "insert");
|
||||||
tribool scv = getUrlArg(argument, "scv"), fdn = getUrlArg(argument, "fdn"), expand = getUrlArg(argument, "expand"), append_sub_userinfo = getUrlArg(argument, "append_info");
|
tribool scv = getUrlArg(argument, "scv"), fdn = getUrlArg(argument, "fdn"), expand = getUrlArg(argument, "expand"), append_sub_userinfo = getUrlArg(argument, "append_info");
|
||||||
tribool prepend_insert = getUrlArg(argument, "prepend");
|
tribool prepend_insert = getUrlArg(argument, "prepend"), classical = getUrlArg(argument, "classic");
|
||||||
|
|
||||||
std::string base_content, output_content;
|
std::string base_content, output_content;
|
||||||
string_array extra_group, extra_ruleset, include_remarks = def_include_remarks, exclude_remarks = def_exclude_remarks;
|
string_array extra_group, extra_ruleset, include_remarks = def_include_remarks, exclude_remarks = def_exclude_remarks;
|
||||||
@@ -1274,6 +1291,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
|||||||
ext.filter_deprecated = fdn.get(filter_deprecated);
|
ext.filter_deprecated = fdn.get(filter_deprecated);
|
||||||
ext.clash_new_field_name = clash_new_field.get(clash_use_new_field_name);
|
ext.clash_new_field_name = clash_new_field.get(clash_use_new_field_name);
|
||||||
ext.clash_script = clash_script.get();
|
ext.clash_script = clash_script.get();
|
||||||
|
ext.clash_classical_ruleset = classical.get();
|
||||||
if(!expand)
|
if(!expand)
|
||||||
ext.clash_new_field_name = true;
|
ext.clash_new_field_name = true;
|
||||||
else
|
else
|
||||||
|
|||||||
+48
-29
@@ -1010,31 +1010,42 @@ void preprocessNodes(std::vector<nodeInfo> &nodes, extra_settings &ext)
|
|||||||
bool failed = true;
|
bool failed = true;
|
||||||
if(ext.sort_script.size())
|
if(ext.sort_script.size())
|
||||||
{
|
{
|
||||||
duk_context *ctx = duktape_init();
|
try
|
||||||
if(ctx)
|
|
||||||
{
|
{
|
||||||
defer(duk_destroy_heap(ctx);)
|
duk_context *ctx = duktape_init();
|
||||||
if(duktape_peval(ctx, ext.sort_script) == 0)
|
if(ctx)
|
||||||
{
|
{
|
||||||
auto comparer = [&](const nodeInfo &a, const nodeInfo &b)
|
defer(duk_destroy_heap(ctx);)
|
||||||
|
if(duktape_peval(ctx, ext.sort_script) == 0)
|
||||||
{
|
{
|
||||||
duk_get_global_string(ctx, "compare");
|
auto comparer = [&](const nodeInfo &a, const nodeInfo &b)
|
||||||
/// push 2 nodeinfo
|
{
|
||||||
duktape_push_nodeinfo(ctx, a);
|
if(a.linkType < 1 || a.linkType > 5)
|
||||||
duktape_push_nodeinfo(ctx, b);
|
return 1;
|
||||||
/// call function
|
if(b.linkType < 1 || b.linkType > 5)
|
||||||
duk_pcall(ctx, 2);
|
return 0;
|
||||||
return duktape_get_res_int(ctx);
|
duk_get_global_string(ctx, "compare");
|
||||||
};
|
/// push 2 nodeinfo
|
||||||
std::sort(nodes.begin(), nodes.end(), comparer);
|
duktape_push_nodeinfo(ctx, a);
|
||||||
failed = false;
|
duktape_push_nodeinfo(ctx, b);
|
||||||
}
|
/// call function
|
||||||
else
|
duk_pcall(ctx, 2);
|
||||||
{
|
return duktape_get_res_int(ctx);
|
||||||
writeLog(0, "Error when trying to parse script:\n" + duktape_get_err_stack(ctx), LOG_LEVEL_ERROR);
|
};
|
||||||
duk_pop(ctx); /// pop err
|
std::sort(nodes.begin(), nodes.end(), comparer);
|
||||||
|
failed = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writeLog(0, "Error when trying to parse script:\n" + duktape_get_err_stack(ctx), LOG_LEVEL_ERROR);
|
||||||
|
duk_pop(ctx); /// pop err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (std::exception&)
|
||||||
|
{
|
||||||
|
//failed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(failed) std::sort(nodes.begin(), nodes.end(), [](const nodeInfo &a, const nodeInfo &b)
|
if(failed) std::sort(nodes.begin(), nodes.end(), [](const nodeInfo &a, const nodeInfo &b)
|
||||||
{
|
{
|
||||||
@@ -1184,19 +1195,27 @@ void netchToClash(std::vector<nodeInfo> &nodes, YAML::Node &yamlnode, string_arr
|
|||||||
break;
|
break;
|
||||||
case SPEEDTEST_MESSAGE_FOUNDSOCKS:
|
case SPEEDTEST_MESSAGE_FOUNDSOCKS:
|
||||||
singleproxy["type"] = "socks5";
|
singleproxy["type"] = "socks5";
|
||||||
singleproxy["username"] = username;
|
if(!username.empty())
|
||||||
singleproxy["password"] = password;
|
singleproxy["username"] = username;
|
||||||
if(std::all_of(password.begin(), password.end(), ::isdigit) && !password.empty())
|
if(!password.empty())
|
||||||
singleproxy["password"].SetTag("str");
|
{
|
||||||
|
singleproxy["password"] = password;
|
||||||
|
if(std::all_of(password.begin(), password.end(), ::isdigit))
|
||||||
|
singleproxy["password"].SetTag("str");
|
||||||
|
}
|
||||||
if(scv)
|
if(scv)
|
||||||
singleproxy["skip-cert-verify"] = true;
|
singleproxy["skip-cert-verify"] = true;
|
||||||
break;
|
break;
|
||||||
case SPEEDTEST_MESSAGE_FOUNDHTTP:
|
case SPEEDTEST_MESSAGE_FOUNDHTTP:
|
||||||
singleproxy["type"] = "http";
|
singleproxy["type"] = "http";
|
||||||
singleproxy["username"] = username;
|
if(!username.empty())
|
||||||
singleproxy["password"] = password;
|
singleproxy["username"] = username;
|
||||||
if(std::all_of(password.begin(), password.end(), ::isdigit) && !password.empty())
|
if(!password.empty())
|
||||||
singleproxy["password"].SetTag("str");
|
{
|
||||||
|
singleproxy["password"] = password;
|
||||||
|
if(std::all_of(password.begin(), password.end(), ::isdigit))
|
||||||
|
singleproxy["password"].SetTag("str");
|
||||||
|
}
|
||||||
singleproxy["tls"] = type == "HTTPS";
|
singleproxy["tls"] = type == "HTTPS";
|
||||||
if(scv)
|
if(scv)
|
||||||
singleproxy["skip-cert-verify"] = true;
|
singleproxy["skip-cert-verify"] = true;
|
||||||
@@ -1348,7 +1367,7 @@ std::string netchToClash(std::vector<nodeInfo> &nodes, std::string &base_conf, s
|
|||||||
{
|
{
|
||||||
if(yamlnode["mode"].IsDefined())
|
if(yamlnode["mode"].IsDefined())
|
||||||
yamlnode["mode"] = ext.clash_script ? "Script" : "Rule";
|
yamlnode["mode"] = ext.clash_script ? "Script" : "Rule";
|
||||||
renderClashScript(yamlnode, ruleset_content_array, ext.managed_config_prefix, ext.clash_script, ext.overwrite_original_rules);
|
renderClashScript(yamlnode, ruleset_content_array, ext.managed_config_prefix, ext.clash_script, ext.overwrite_original_rules, ext.clash_classical_ruleset);
|
||||||
return YAML::Dump(yamlnode);
|
return YAML::Dump(yamlnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ struct extra_settings
|
|||||||
tribool udp = false;
|
tribool udp = false;
|
||||||
tribool tfo = false;
|
tribool tfo = false;
|
||||||
tribool skip_cert_verify = false;
|
tribool skip_cert_verify = false;
|
||||||
|
bool clash_classical_ruleset = false;
|
||||||
std::string sort_script;
|
std::string sort_script;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+45
-19
@@ -11,6 +11,13 @@
|
|||||||
|
|
||||||
extern std::string managed_config_prefix;
|
extern std::string managed_config_prefix;
|
||||||
|
|
||||||
|
template <typename T> T safe_as (const YAML::Node& node)
|
||||||
|
{
|
||||||
|
if(node.IsDefined() && !node.IsNull())
|
||||||
|
return node.as<T>();
|
||||||
|
return T();
|
||||||
|
};
|
||||||
|
|
||||||
static inline void parse_json_pointer(nlohmann::json &json, const std::string &path, const std::string &value)
|
static inline void parse_json_pointer(nlohmann::json &json, const std::string &path, const std::string &value)
|
||||||
{
|
{
|
||||||
std::string pointer = "/" + replace_all_distinct(path, ".", "/");
|
std::string pointer = "/" + replace_all_distinct(path, ".", "/");
|
||||||
@@ -177,12 +184,14 @@ const std::string clash_script_template = R"(def main(ctx, md):
|
|||||||
return geoips[key]
|
return geoips[key]
|
||||||
return "{{ match_group }}")";
|
return "{{ match_group }}")";
|
||||||
|
|
||||||
const std::string clash_script_group_template = R"({% if rule.has_domain == "true" %} if ctx.rule_providers["{{ rule.name }}_domain"].match(md):
|
const std::string clash_script_group_template = R"({% if rule.has_domain == "false" and rule.has_ipcidr == "false" %} if ctx.rule_providers["{{ rule.name }}_classical"].match(md):
|
||||||
|
ctx.log('[Script] matched {{ rule.group }} rule')
|
||||||
|
return "{{ rule.group }}"{% else %}{% if rule.has_domain == "true" %} if ctx.rule_providers["{{ rule.name }}_domain"].match(md):
|
||||||
ctx.log('[Script] matched {{ rule.group }} DOMAIN rule')
|
ctx.log('[Script] matched {{ rule.group }} DOMAIN rule')
|
||||||
return "{{ rule.group }}"{% endif %}
|
return "{{ rule.group }}"{% endif %}
|
||||||
{% if rule.has_ipcidr == "true" %} if ctx.rule_providers["{{ rule.name }}_ipcidr"].match(md):
|
{% if rule.has_ipcidr == "true" %} if ctx.rule_providers["{{ rule.name }}_ipcidr"].match(md):
|
||||||
ctx.log('[Script] matched {{ rule.group }} IP rule')
|
ctx.log('[Script] matched {{ rule.group }} IP rule')
|
||||||
return "{{ rule.group }}"{% endif %})";
|
return "{{ rule.group }}"{% endif %}{% endif %})";
|
||||||
|
|
||||||
const std::string clash_script_keyword_template = R"( keywords = [{{ rule.keyword }}]
|
const std::string clash_script_keyword_template = R"( keywords = [{{ rule.keyword }}]
|
||||||
for keyword in keywords:
|
for keyword in keywords:
|
||||||
@@ -190,7 +199,7 @@ const std::string clash_script_keyword_template = R"( keywords = [{{ rule.keywo
|
|||||||
ctx.log('[Script] matched {{ rule.group }} DOMAIN-KEYWORD rule')
|
ctx.log('[Script] matched {{ rule.group }} DOMAIN-KEYWORD rule')
|
||||||
return "{{ rule.group }}")";
|
return "{{ rule.group }}")";
|
||||||
|
|
||||||
int renderClashScript(YAML::Node &base_rule, std::vector<ruleset_content> &ruleset_content_array, std::string remote_path_prefix, bool script, bool overwrite_original_rules)
|
int renderClashScript(YAML::Node &base_rule, std::vector<ruleset_content> &ruleset_content_array, std::string remote_path_prefix, bool script, bool overwrite_original_rules, bool clash_classical_ruleset)
|
||||||
{
|
{
|
||||||
nlohmann::json data;
|
nlohmann::json data;
|
||||||
std::string match_group, geoips, retrieved_rules;
|
std::string match_group, geoips, retrieved_rules;
|
||||||
@@ -199,10 +208,10 @@ int renderClashScript(YAML::Node &base_rule, std::vector<ruleset_content> &rules
|
|||||||
string_array vArray, groups;
|
string_array vArray, groups;
|
||||||
string_map keywords, urls, names;
|
string_map keywords, urls, names;
|
||||||
std::map<std::string, bool> has_domain, has_ipcidr;
|
std::map<std::string, bool> has_domain, has_ipcidr;
|
||||||
YAML::Node rules;
|
string_array rules;
|
||||||
|
|
||||||
if(!overwrite_original_rules && base_rule["rules"].IsDefined())
|
if(!overwrite_original_rules && base_rule["rules"].IsDefined())
|
||||||
rules = base_rule["rules"];
|
rules = safe_as<string_array>(base_rule["rules"]);
|
||||||
|
|
||||||
for(ruleset_content &x : ruleset_content_array)
|
for(ruleset_content &x : ruleset_content_array)
|
||||||
{
|
{
|
||||||
@@ -229,7 +238,7 @@ int renderClashScript(YAML::Node &base_rule, std::vector<ruleset_content> &rules
|
|||||||
strLine += "," + rule_group;
|
strLine += "," + rule_group;
|
||||||
if(std::count(strLine.begin(), strLine.end(), ',') > 2)
|
if(std::count(strLine.begin(), strLine.end(), ',') > 2)
|
||||||
strLine = regReplace(strLine, "^(.*?,.*?)(,.*)(,.*)$", "$1$3$2");
|
strLine = regReplace(strLine, "^(.*?,.*?)(,.*)(,.*)$", "$1$3$2");
|
||||||
rules.push_back(strLine);
|
rules.emplace_back(strLine);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -241,6 +250,13 @@ int renderClashScript(YAML::Node &base_rule, std::vector<ruleset_content> &rules
|
|||||||
rule_name = std::to_string(hash_(rule_path));
|
rule_name = std::to_string(hash_(rule_path));
|
||||||
names[rule_name] = rule_group;
|
names[rule_name] = rule_group;
|
||||||
urls[rule_name] = rule_path;
|
urls[rule_name] = rule_path;
|
||||||
|
if(clash_classical_ruleset)
|
||||||
|
{
|
||||||
|
groups.emplace_back(rule_name);
|
||||||
|
if(!script)
|
||||||
|
rules.emplace_back("RULE-SET," + rule_group + "_" + rule_name + "_classical," + rule_group);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
@@ -286,7 +302,7 @@ int renderClashScript(YAML::Node &base_rule, std::vector<ruleset_content> &rules
|
|||||||
strLine += "," + rule_group;
|
strLine += "," + rule_group;
|
||||||
if(std::count(strLine.begin(), strLine.end(), ',') > 2)
|
if(std::count(strLine.begin(), strLine.end(), ',') > 2)
|
||||||
strLine = regReplace(strLine, "^(.*?,.*?)(,.*)(,.*)$", "$1$3$2");
|
strLine = regReplace(strLine, "^(.*?,.*?)(,.*)(,.*)$", "$1$3$2");
|
||||||
rules.push_back(strLine);
|
rules.emplace_back(strLine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(startsWith(strLine, "DOMAIN,") || startsWith(strLine, "DOMAIN-SUFFIX,"))
|
else if(startsWith(strLine, "DOMAIN,") || startsWith(strLine, "DOMAIN-SUFFIX,"))
|
||||||
@@ -295,9 +311,9 @@ int renderClashScript(YAML::Node &base_rule, std::vector<ruleset_content> &rules
|
|||||||
has_ipcidr[rule_name] = true;
|
has_ipcidr[rule_name] = true;
|
||||||
}
|
}
|
||||||
if(has_domain[rule_name] && !script)
|
if(has_domain[rule_name] && !script)
|
||||||
rules.push_back("RULE-SET," + rule_group + "_" + rule_name + "_domain," + rule_group);
|
rules.emplace_back("RULE-SET," + rule_group + "_" + rule_name + "_domain," + rule_group);
|
||||||
if(has_ipcidr[rule_name] && !script)
|
if(has_ipcidr[rule_name] && !script)
|
||||||
rules.push_back("RULE-SET," + rule_group + "_" + rule_name + "_ipcidr," + rule_group);
|
rules.emplace_back("RULE-SET," + rule_group + "_" + rule_name + "_ipcidr," + rule_group);
|
||||||
if(std::find(groups.begin(), groups.end(), rule_name) == groups.end())
|
if(std::find(groups.begin(), groups.end(), rule_name) == groups.end())
|
||||||
groups.emplace_back(rule_name);
|
groups.emplace_back(rule_name);
|
||||||
}
|
}
|
||||||
@@ -308,19 +324,29 @@ int renderClashScript(YAML::Node &base_rule, std::vector<ruleset_content> &rules
|
|||||||
std::string json_path = "rules." + std::to_string(index) + ".";
|
std::string json_path = "rules." + std::to_string(index) + ".";
|
||||||
std::string url = urls[x], keyword = keywords[x], name = names[x];
|
std::string url = urls[x], keyword = keywords[x], name = names[x];
|
||||||
bool group_has_domain = has_domain[x], group_has_ipcidr = has_ipcidr[x];
|
bool group_has_domain = has_domain[x], group_has_ipcidr = has_ipcidr[x];
|
||||||
if(group_has_domain)
|
if(clash_classical_ruleset)
|
||||||
{
|
{
|
||||||
base_rule["rule-providers"][name + "_" + x + "_domain"]["type"] = "http";
|
base_rule["rule-providers"][name + "_" + x + "_classical"]["type"] = "http";
|
||||||
base_rule["rule-providers"][name + "_" + x + "_domain"]["behavior"] = "domain";
|
base_rule["rule-providers"][name + "_" + x + "_classical"]["behavior"] = "classical";
|
||||||
base_rule["rule-providers"][name + "_" + x + "_domain"]["url"] = remote_path_prefix + "/getruleset?type=3&url=" + urlsafe_base64_encode(url);
|
base_rule["rule-providers"][name + "_" + x + "_classical"]["url"] = remote_path_prefix + "/getruleset?type=6&url=" + urlsafe_base64_encode(url);
|
||||||
base_rule["rule-providers"][name + "_" + x + "_domain"]["path"] = "./rule-providers_" + x + "_domain.yaml";
|
base_rule["rule-providers"][name + "_" + x + "_classical"]["path"] = "./providers/rule-provider_" + x + "_classical.yaml";
|
||||||
}
|
}
|
||||||
if(group_has_ipcidr)
|
else
|
||||||
{
|
{
|
||||||
base_rule["rule-providers"][name + "_" + x + "_ipcidr"]["type"] = "http";
|
if(group_has_domain)
|
||||||
base_rule["rule-providers"][name + "_" + x + "_ipcidr"]["behavior"] = "ipcidr";
|
{
|
||||||
base_rule["rule-providers"][name + "_" + x + "_ipcidr"]["url"] = remote_path_prefix + "/getruleset?type=4&url=" + urlsafe_base64_encode(url);
|
base_rule["rule-providers"][name + "_" + x + "_domain"]["type"] = "http";
|
||||||
base_rule["rule-providers"][name + "_" + x + "_ipcidr"]["path"] = "./rule-providers_" + x + "_ipcidr.yaml";
|
base_rule["rule-providers"][name + "_" + x + "_domain"]["behavior"] = "domain";
|
||||||
|
base_rule["rule-providers"][name + "_" + x + "_domain"]["url"] = remote_path_prefix + "/getruleset?type=3&url=" + urlsafe_base64_encode(url);
|
||||||
|
base_rule["rule-providers"][name + "_" + x + "_domain"]["path"] = "./providers/rule-provider_" + x + "_domain.yaml";
|
||||||
|
}
|
||||||
|
if(group_has_ipcidr)
|
||||||
|
{
|
||||||
|
base_rule["rule-providers"][name + "_" + x + "_ipcidr"]["type"] = "http";
|
||||||
|
base_rule["rule-providers"][name + "_" + x + "_ipcidr"]["behavior"] = "ipcidr";
|
||||||
|
base_rule["rule-providers"][name + "_" + x + "_ipcidr"]["url"] = remote_path_prefix + "/getruleset?type=4&url=" + urlsafe_base64_encode(url);
|
||||||
|
base_rule["rule-providers"][name + "_" + x + "_ipcidr"]["path"] = "./providers/rule-provider_" + x + "_ipcidr.yaml";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(script)
|
if(script)
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -16,6 +16,6 @@ struct template_args
|
|||||||
};
|
};
|
||||||
|
|
||||||
int render_template(const std::string &content, const template_args &vars, std::string &output, const std::string &include_scope = "template");
|
int render_template(const std::string &content, const template_args &vars, std::string &output, const std::string &include_scope = "template");
|
||||||
int renderClashScript(YAML::Node &base_rule, std::vector<ruleset_content> &ruleset_content_array, std::string remote_path_prefix, bool script, bool overwrite_original_rules);
|
int renderClashScript(YAML::Node &base_rule, std::vector<ruleset_content> &ruleset_content_array, std::string remote_path_prefix, bool script, bool overwrite_original_rules, bool clash_classic_ruleset);
|
||||||
|
|
||||||
#endif // TEMPLATES_H_INCLUDED
|
#endif // TEMPLATES_H_INCLUDED
|
||||||
Reference in new issue
Block a user