mirror of
https://github.com/asdlokj1qpi233/subconverter.git
synced 2026-11-03 10:12:50 +00:00
Enhancements
Add "auto" target to automatically determine target and other options by User-Agent. inja: Update to latest version.
This commit is contained in:
4 files changed
+5442
-3321
No files matched your search
+100
-4
@@ -94,6 +94,97 @@ const string_array quanx_rule_type = {basic_types, "USER-AGENT", "HOST", "HOST-S
|
||||
const std::map<std::string, ruleset_type> ruleset_types = {{"clash-domain:", RULESET_CLASH_DOMAIN}, {"clash-ipcidr:", RULESET_CLASH_IPCIDR}, {"clash-classic:", RULESET_CLASH_CLASSICAL}, \
|
||||
{"quanx:", RULESET_QUANX}, {"surge:", RULESET_SURGE}};
|
||||
|
||||
struct UAProfile
|
||||
{
|
||||
std::string head;
|
||||
std::string version_match;
|
||||
std::string version_target;
|
||||
std::string target;
|
||||
tribool clash_new_name;
|
||||
int surge_ver = -1;
|
||||
};
|
||||
|
||||
const std::vector<UAProfile> UAMatchList = {
|
||||
{"ClashForAndroid","\\/([0-9.]+)","2.0","clash",true},
|
||||
{"ClashForAndroid","\\/([0-9.]+)R","","clashr",false},
|
||||
{"ClashForAndroid","","","clash",false},
|
||||
{"ClashforWindows","\\/([0-9.]+)","0.11","clash",true},
|
||||
{"ClashforWindows","","","clash",false},
|
||||
{"ClashX Pro","","","clash",true},
|
||||
{"ClashX","\\/([0-9.]+)","0.13","clash",true},
|
||||
{"Clash","","","clash",true},
|
||||
{"Kitsunebi","","","v2ray"},
|
||||
{"LoonWidget","","","loon"},
|
||||
{"Pharos","","","mixed"},
|
||||
{"Potatso","","","mixed"},
|
||||
{"Quantumult%20X","","","quanx"},
|
||||
{"Quantumult","","","quan"},
|
||||
{"Qv2ray","","","v2ray"},
|
||||
{"Shadowrocket","","","mixed"},
|
||||
{"Surfboard","","","surfboard"},
|
||||
{"Surge","\\/([0-9.]+).*x86","906","surge",false,4}, /// Surge for Mac (supports VMess)
|
||||
{"Surge","\\/([0-9.]+).*x86","368","surge",false,3}, /// Surge for Mac (supports new rule types and Shadowsocks without plugin)
|
||||
{"Surge","\\/([0-9.]+)","1419","surge",false,4}, /// Surge iOS 4 (first version)
|
||||
{"Surge","\\/([0-9.]+)","900","surge",false,3}, /// Surge iOS 3 (approx)
|
||||
{"Surge","","","surge",false,2}, /// any version of Surge as fallback
|
||||
{"Trojan-Qt5","","","trojan"},
|
||||
{"V2rayU","","","v2ray"},
|
||||
{"V2RayX","","","v2ray"}
|
||||
};
|
||||
|
||||
bool verGreaterEqual(const std::string &src_ver, const std::string &target_ver)
|
||||
{
|
||||
int part_src, part_target;
|
||||
string_size src_pos_beg = 0, src_pos_end = 0, target_pos_beg = 0, target_pos_end = 0;
|
||||
while(true)
|
||||
{
|
||||
src_pos_end = src_ver.find('.', src_pos_beg);
|
||||
if(src_pos_end == src_ver.npos)
|
||||
src_pos_end = src_ver.size();
|
||||
part_src = std::stoi(src_ver.substr(src_pos_beg, src_pos_end - src_pos_beg));
|
||||
target_pos_end = target_ver.find('.', target_pos_beg);
|
||||
if(target_pos_end == target_ver.npos)
|
||||
target_pos_end = target_ver.size();
|
||||
part_target = std::stoi(target_ver.substr(target_pos_beg, target_pos_end - target_pos_beg));
|
||||
if(part_src > part_target)
|
||||
break;
|
||||
else if(part_src < part_target)
|
||||
return false;
|
||||
else if(src_pos_end >= src_ver.size() - 1 || target_pos_end >= target_ver.size() - 1)
|
||||
break;
|
||||
src_pos_beg = src_pos_end + 1;
|
||||
target_pos_beg = target_pos_end + 1;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void matchUserAgent(const std::string &user_agent, std::string &target, tribool &clash_new_name, int &surge_ver)
|
||||
{
|
||||
if(user_agent.empty())
|
||||
return;
|
||||
for(const UAProfile &x : UAMatchList)
|
||||
{
|
||||
if(startsWith(user_agent, x.head))
|
||||
{
|
||||
if(!x.version_match.empty())
|
||||
{
|
||||
std::string version;
|
||||
if(regGetMatch(user_agent, x.version_match, 2, 0, &version))
|
||||
continue;
|
||||
if(!x.version_target.empty() && !verGreaterEqual(version, x.version_target))
|
||||
continue;
|
||||
}
|
||||
target = x.target;
|
||||
clash_new_name = x.clash_new_name;
|
||||
if(x.surge_ver != -1)
|
||||
surge_ver = x.surge_ver;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
std::string convertRuleset(const std::string &content, int type)
|
||||
{
|
||||
/// Target: Surge type,pattern[,flag]
|
||||
@@ -1268,7 +1359,12 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
std::string &argument = request.argument;
|
||||
int *status_code = &response.status_code;
|
||||
|
||||
std::string target = getUrlArg(argument, "target");
|
||||
std::string target = getUrlArg(argument, "target"), version = getUrlArg(argument, "ver");
|
||||
tribool clash_new_field = getUrlArg(argument, "new_name");
|
||||
int surge_ver = version.size() ? to_int(version, 3) : 3;
|
||||
if(target == "auto")
|
||||
matchUserAgent(request.headers["X-User-Agent"], target, clash_new_field, surge_ver);
|
||||
|
||||
switch(hash_(target))
|
||||
{
|
||||
case "clash"_hash: case "clashr"_hash: case "surge"_hash: case "quan"_hash: case "quanx"_hash: case "loon"_hash: case "surfboard"_hash: case "mellow"_hash: case "ss"_hash: case "ssd"_hash: case "ssr"_hash: case "sssub"_hash: case "v2ray"_hash: case "trojan"_hash: case "mixed"_hash:
|
||||
@@ -1283,7 +1379,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
|
||||
/// string values
|
||||
std::string url = UrlDecode(getUrlArg(argument, "url"));
|
||||
std::string group = UrlDecode(getUrlArg(argument, "group")), upload_path = getUrlArg(argument, "upload_path"), version = getUrlArg(argument, "ver");
|
||||
std::string group = UrlDecode(getUrlArg(argument, "group")), upload_path = getUrlArg(argument, "upload_path");
|
||||
std::string include = UrlDecode(getUrlArg(argument, "include")), exclude = UrlDecode(getUrlArg(argument, "exclude"));
|
||||
std::string groups = urlsafe_base64_decode(getUrlArg(argument, "groups")), ruleset = urlsafe_base64_decode(getUrlArg(argument, "ruleset")), config = UrlDecode(getUrlArg(argument, "config"));
|
||||
std::string dev_id = getUrlArg(argument, "dev_id"), filename = getUrlArg(argument, "filename"), interval_str = getUrlArg(argument, "interval"), strict_str = getUrlArg(argument, "strict");
|
||||
@@ -1293,7 +1389,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
tribool upload = getUrlArg(argument, "upload"), emoji = getUrlArg(argument, "emoji"), emoji_add = getUrlArg(argument, "add_emoji"), emoji_remove = getUrlArg(argument, "remove_emoji");
|
||||
tribool append_type = getUrlArg(argument, "append_type"), tfo = getUrlArg(argument, "tfo"), udp = getUrlArg(argument, "udp"), nodelist = getUrlArg(argument, "list");
|
||||
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_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 prepend_insert = getUrlArg(argument, "prepend"), classical = getUrlArg(argument, "classic"), tls13 = getUrlArg(argument, "tls13");
|
||||
|
||||
@@ -1632,7 +1728,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
uploadGist(target, upload_path, output_content, false);
|
||||
break;
|
||||
case "surge"_hash:
|
||||
surge_ver = version.size() ? to_int(version, 3) : 3;
|
||||
|
||||
writeLog(0, "Generate target: Surge " + std::to_string(surge_ver), LOG_LEVEL_INFO);
|
||||
|
||||
if(ext.nodelist)
|
||||
|
||||
+14
-5
@@ -13,6 +13,14 @@
|
||||
|
||||
extern std::string managed_config_prefix;
|
||||
|
||||
namespace inja
|
||||
{
|
||||
void convert_dot_to_json_pointer(nonstd::string_view dot, std::string& out)
|
||||
{
|
||||
out = std::move(JsonNode(dot, 0).ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void parse_json_pointer(nlohmann::json &json, const std::string &path, const std::string &value)
|
||||
{
|
||||
std::string pointer;
|
||||
@@ -52,6 +60,7 @@ int render_template(const std::string &content, const template_args &vars, std::
|
||||
inja::FunctionStorage m_callbacks;
|
||||
inja::TemplateStorage m_included_templates;
|
||||
inja::ParserConfig m_parser_config;
|
||||
inja::RenderConfig m_render_config;
|
||||
|
||||
m_lexer_config.trim_blocks = true;
|
||||
m_lexer_config.lstrip_blocks = true;
|
||||
@@ -99,7 +108,7 @@ int render_template(const std::string &content, const template_args &vars, std::
|
||||
parse_json_pointer(data, dest + "." + std::to_string(index), vArray[index]);
|
||||
return std::string();
|
||||
});
|
||||
m_callbacks.add_callback("join", INJA_VARARGS, [](inja::Arguments &args)
|
||||
m_callbacks.add_callback("join", -1, [](inja::Arguments &args)
|
||||
{
|
||||
std::string result;
|
||||
for(auto iter = args.begin(); iter != args.end(); iter++)
|
||||
@@ -134,14 +143,14 @@ 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>());
|
||||
});
|
||||
m_callbacks.add_callback("or", INJA_VARARGS, [](inja::Arguments &args)
|
||||
m_callbacks.add_callback("or", -1, [](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)
|
||||
m_callbacks.add_callback("and", -1, [](inja::Arguments &args)
|
||||
{
|
||||
for(auto iter = args.begin(); iter != args.end(); iter++)
|
||||
if(!(*iter)->get<int>())
|
||||
@@ -169,8 +178,8 @@ int render_template(const std::string &content, const template_args &vars, std::
|
||||
m_parser_config.include_scope_limit = true;
|
||||
m_parser_config.include_scope = include_scope;
|
||||
|
||||
inja::Parser parser(m_parser_config, m_lexer_config, m_included_templates);
|
||||
inja::Renderer renderer(m_included_templates, m_callbacks);
|
||||
inja::Parser parser(m_parser_config, m_lexer_config, m_included_templates, m_callbacks);
|
||||
inja::Renderer renderer(m_render_config, m_included_templates, m_callbacks);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user