mirror of
https://github.com/MetaCubeX/subconverter.git
synced 2025-11-04 18:19:42 +08:00
Enhancements
Add support for adding proxy provider to custom group in Clash configurations. Add and, or, bool as template function. Add support for any amount of argument for template function join. inja: Add variadic function callback support.
This commit is contained in:
parent
80d16f3130
commit
0a7e1cac97
@ -181,6 +181,7 @@ surge_ruleset=!!import:snippets/rulesets.txt
|
|||||||
|
|
||||||
;custom_proxy_group=g1hk`select`!!GROUPID=0!!(HGC|HKBN|PCCW|HKT|hk|港)
|
;custom_proxy_group=g1hk`select`!!GROUPID=0!!(HGC|HKBN|PCCW|HKT|hk|港)
|
||||||
;custom_proxy_group=sstw`select`!!GROUP=V2RayProvider!!(深台|彰化|新北|台|tw)
|
;custom_proxy_group=sstw`select`!!GROUP=V2RayProvider!!(深台|彰化|新北|台|tw)
|
||||||
|
;custom_proxy_group=provider`select`!!PROVIDER=prov1,prov2,prov3`fallback_nodes
|
||||||
|
|
||||||
;Also supports using script for filtering nodes. A "filter" function with one argument which is an array of all available nodes should be defined in the script.
|
;Also supports using script for filtering nodes. A "filter" function with one argument which is an array of all available nodes should be defined in the script.
|
||||||
;custom_proxy_group=script`select`script:/path/to/script.js
|
;custom_proxy_group=script`select`script:/path/to/script.js
|
||||||
|
|||||||
@ -1813,6 +1813,8 @@ struct Bytecode {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define INJA_VARARGS (unsigned int) (~0) // use special number for VARARGS functions
|
||||||
|
|
||||||
namespace inja {
|
namespace inja {
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
@ -1873,10 +1875,16 @@ class FunctionStorage {
|
|||||||
if (it == m_map.end()) {
|
if (it == m_map.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const FunctionData* var_func = nullptr;
|
||||||
for (auto &&i: it->second) {
|
for (auto &&i: it->second) {
|
||||||
if (i.num_args == num_args) return &i;
|
if (i.num_args == num_args) {
|
||||||
|
return &i; // function with precise number of argument(s) should always be used first
|
||||||
|
} else if (i.num_args == INJA_VARARGS) {
|
||||||
|
var_func = &i; // store the VARARGS function for later use
|
||||||
}
|
}
|
||||||
return nullptr;
|
}
|
||||||
|
return var_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, std::vector<FunctionData>> m_map;
|
std::map<std::string, std::vector<FunctionData>> m_map;
|
||||||
@ -2218,6 +2226,7 @@ class Lexer {
|
|||||||
if (std::isalpha(ch)) {
|
if (std::isalpha(ch)) {
|
||||||
return scan_id();
|
return scan_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case ',':
|
case ',':
|
||||||
return make_token(Token::Kind::Comma);
|
return make_token(Token::Kind::Comma);
|
||||||
@ -3221,7 +3230,7 @@ class Renderer {
|
|||||||
}
|
}
|
||||||
case Bytecode::Op::Push: {
|
case Bytecode::Op::Push: {
|
||||||
try{m_stack.emplace_back(*get_imm(bc));}
|
try{m_stack.emplace_back(*get_imm(bc));}
|
||||||
catch(std::exception &e){m_stack.emplace_back(json());}
|
catch(std::exception&){m_stack.emplace_back(json());}
|
||||||
//m_stack.emplace_back(*get_imm(bc));
|
//m_stack.emplace_back(*get_imm(bc));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3418,8 +3427,9 @@ class Renderer {
|
|||||||
bool result = false;
|
bool result = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const std::string pointer = "/" + [](std::string str){std::string new_value = "/", old_value = ".";for(std::string::size_type pos(0); pos != std::string::npos; pos += new_value.length()){if((pos = str.find(old_value, pos)) != std::string::npos)str.replace(pos, old_value.length(), new_value);else break;}return str;}(name);
|
std::string ptr;
|
||||||
data.at(json::json_pointer(pointer));
|
convert_dot_to_json_pointer(name, ptr);
|
||||||
|
data.at(json::json_pointer(ptr));
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
catch (json::out_of_range &e)
|
catch (json::out_of_range &e)
|
||||||
|
|||||||
@ -1266,11 +1266,13 @@ void netchToClash(std::vector<nodeInfo> &nodes, YAML::Node &yamlnode, string_arr
|
|||||||
yamlnode["Proxy"] = proxies;
|
yamlnode["Proxy"] = proxies;
|
||||||
|
|
||||||
std::string groupname;
|
std::string groupname;
|
||||||
|
string_array providers;
|
||||||
|
|
||||||
for(std::string &x : extra_proxy_group)
|
for(std::string &x : extra_proxy_group)
|
||||||
{
|
{
|
||||||
singlegroup.reset();
|
singlegroup.reset();
|
||||||
eraseElements(filtered_nodelist);
|
eraseElements(filtered_nodelist);
|
||||||
|
eraseElements(providers);
|
||||||
replace_flag = false;
|
replace_flag = false;
|
||||||
unsigned int rules_upper_bound = 0;
|
unsigned int rules_upper_bound = 0;
|
||||||
|
|
||||||
@ -1304,12 +1306,26 @@ void netchToClash(std::vector<nodeInfo> &nodes, YAML::Node &yamlnode, string_arr
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(unsigned int i = 2; i < rules_upper_bound; i++)
|
for(unsigned int i = 2; i < rules_upper_bound; i++)
|
||||||
|
{
|
||||||
|
if(startsWith(vArray[i], "!!PROVIDER="))
|
||||||
|
{
|
||||||
|
string_array list = split(vArray[i].substr(11), ",");
|
||||||
|
providers.reserve(providers.size() + list.size());
|
||||||
|
std::move(list.begin(), list.end(), std::back_inserter(providers));
|
||||||
|
}
|
||||||
|
else
|
||||||
groupGenerate(vArray[i], nodelist, filtered_nodelist, true);
|
groupGenerate(vArray[i], nodelist, filtered_nodelist, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(providers.size())
|
||||||
|
singlegroup["use"] = providers;
|
||||||
|
else
|
||||||
|
{
|
||||||
if(!filtered_nodelist.size())
|
if(!filtered_nodelist.size())
|
||||||
filtered_nodelist.emplace_back("DIRECT");
|
filtered_nodelist.emplace_back("DIRECT");
|
||||||
|
|
||||||
singlegroup["proxies"] = filtered_nodelist;
|
singlegroup["proxies"] = filtered_nodelist;
|
||||||
|
}
|
||||||
//singlegroup.SetStyle(YAML::EmitterStyle::Flow);
|
//singlegroup.SetStyle(YAML::EmitterStyle::Flow);
|
||||||
|
|
||||||
for(unsigned int i = 0; i < original_groups.size(); i++)
|
for(unsigned int i = 0; i < original_groups.size(); i++)
|
||||||
|
|||||||
@ -14,7 +14,8 @@ extern std::string managed_config_prefix;
|
|||||||
|
|
||||||
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;
|
||||||
|
inja::convert_dot_to_json_pointer(path, pointer);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
json[nlohmann::json::json_pointer(pointer)] = value;
|
json[nlohmann::json::json_pointer(pointer)] = value;
|
||||||
@ -97,21 +98,17 @@ int render_template(const std::string &content, const template_args &vars, std::
|
|||||||
parse_json_pointer(data, dest + "." + std::to_string(index), vArray[index]);
|
parse_json_pointer(data, dest + "." + std::to_string(index), vArray[index]);
|
||||||
return std::string();
|
return std::string();
|
||||||
});
|
});
|
||||||
m_callbacks.add_callback("join", 2, [](inja::Arguments &args)
|
m_callbacks.add_callback("join", INJA_VARARGS, [](inja::Arguments &args)
|
||||||
{
|
{
|
||||||
std::string str1 = args.at(0)->get<std::string>(), str2 = args.at(1)->get<std::string>();
|
std::string result;
|
||||||
return std::move(str1) + std::move(str2);
|
for(auto iter = args.begin(); iter != args.end(); iter++)
|
||||||
});
|
result += (*iter)->get<std::string>();
|
||||||
m_callbacks.add_callback("join", 3, [](inja::Arguments &args)
|
return result;
|
||||||
{
|
|
||||||
std::string str1 = args.at(0)->get<std::string>(), str2 = args.at(1)->get<std::string>(), str3 = args.at(2)->get<std::string>();
|
|
||||||
return std::move(str1) + std::move(str2) + std::move(str3);
|
|
||||||
});
|
});
|
||||||
m_callbacks.add_callback("append", 2, [&data](inja::Arguments &args)
|
m_callbacks.add_callback("append", 2, [&data](inja::Arguments &args)
|
||||||
{
|
{
|
||||||
std::string path = args.at(0)->get<std::string>(), value = args.at(1)->get<std::string>();
|
std::string path = args.at(0)->get<std::string>(), value = args.at(1)->get<std::string>(), pointer, output_content;
|
||||||
std::string pointer = "/" + replace_all_distinct(path, ".", "/");
|
inja::convert_dot_to_json_pointer(path, pointer);
|
||||||
std::string output_content;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
output_content = data[nlohmann::json::json_pointer(pointer)].get<std::string>();
|
output_content = data[nlohmann::json::json_pointer(pointer)].get<std::string>();
|
||||||
@ -136,6 +133,32 @@ int render_template(const std::string &content, const template_args &vars, std::
|
|||||||
{
|
{
|
||||||
return endsWith(args.at(0)->get<std::string>(), args.at(1)->get<std::string>());
|
return endsWith(args.at(0)->get<std::string>(), args.at(1)->get<std::string>());
|
||||||
});
|
});
|
||||||
|
m_callbacks.add_callback("or", INJA_VARARGS, [](inja::Arguments &args)
|
||||||
|
{
|
||||||
|
for(auto iter = args.begin(); iter != args.end(); iter++)
|
||||||
|
if((*iter)->get<int>())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
m_callbacks.add_callback("and", INJA_VARARGS, [](inja::Arguments &args)
|
||||||
|
{
|
||||||
|
for(auto iter = args.begin(); iter != args.end(); iter++)
|
||||||
|
if(!(*iter)->get<int>())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
m_callbacks.add_callback("bool", 1, [](inja::Arguments &args)
|
||||||
|
{
|
||||||
|
std::string value = args.at(0)->get<std::string>();
|
||||||
|
std::transform(value.begin(), value.end(), value.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||||
|
switch(hash_(value))
|
||||||
|
{
|
||||||
|
case "true"_hash:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
m_callbacks.add_callback("fetch", 1, template_webGet);
|
m_callbacks.add_callback("fetch", 1, template_webGet);
|
||||||
m_callbacks.add_callback("parseHostname", 1, parseHostname);
|
m_callbacks.add_callback("parseHostname", 1, parseHostname);
|
||||||
m_parser_config.include_scope_limit = true;
|
m_parser_config.include_scope_limit = true;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user