Skip to content

Commit 77b676a

Browse files
committed
Merge branch 'meta'
2 parents f84e1e7 + 76d4e33 commit 77b676a

File tree

13 files changed

+3063
-313
lines changed

13 files changed

+3063
-313
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@ subconverter.exe
44
cmake-build-debug
55
.idea
66
base/cache
7-
build
7+
build
8+
转换前
9+
转换后

src/generator/config/nodemanip.cpp

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ int addNodes(std::string link, std::vector<Proxy> &allNodes, int groupID, parse_
4141
RegexMatchConfigs &time_rules = *parse_set.time_rules;
4242
string_icase_map *request_headers = parse_set.request_header;
4343
bool &authorized = parse_set.authorized;
44+
string_icase_map custom_headers;
4445

4546
ConfType linkType = ConfType::Unknow;
4647
std::vector<Proxy> nodes;
@@ -142,7 +143,14 @@ int addNodes(std::string link, std::vector<Proxy> &allNodes, int groupID, parse_
142143
writeLog(LOG_TYPE_INFO, "Downloading subscription data...");
143144
if(startsWith(link, "surge:///install-config")) //surge config link
144145
link = urlDecode(getUrlArg(link, "url"));
145-
strSub = webGet(link, proxy, global.cacheSubscription, &extra_headers, request_headers);
146+
// 处理自定义用户代理
147+
if(request_headers)
148+
custom_headers = *request_headers;
149+
if(parse_set.custom_user_agent && !parse_set.custom_user_agent->empty())
150+
{
151+
custom_headers["User-Agent"] = *parse_set.custom_user_agent;
152+
}
153+
strSub = webGet(link, proxy, global.cacheSubscription, &extra_headers, &custom_headers);
146154
/*
147155
if(strSub.size() == 0)
148156
{
@@ -410,6 +418,21 @@ void nodeRename(Proxy &node, const RegexMatchConfigs &rename_array, extra_settin
410418
return;
411419
}
412420

421+
std::string extractEmoji(const std::string &remark)
422+
{
423+
// Extract emoji from the beginning of remark
424+
// Emoji flags are 4-byte sequences starting with 0xF0 0x9F
425+
char emoji_id[2] = {(char)-16, (char)-97};
426+
std::string emoji;
427+
size_t pos = 0;
428+
while(pos + 3 < remark.size() && remark[pos] == emoji_id[0] && remark[pos + 1] == emoji_id[1])
429+
{
430+
emoji.append(remark.substr(pos, 4));
431+
pos += 4;
432+
}
433+
return emoji;
434+
}
435+
413436
std::string removeEmoji(const std::string &orig_remark)
414437
{
415438
char emoji_id[2] = {(char)-16, (char)-97};
@@ -429,6 +452,12 @@ std::string removeEmoji(const std::string &orig_remark)
429452
std::string addEmoji(const Proxy &node, const RegexMatchConfigs &emoji_array, extra_settings &ext)
430453
{
431454
std::string real_rule, ret;
455+
std::string original_emoji = extractEmoji(node.Remark);
456+
457+
if(global.printDbgInfo && !node.Remark.empty())
458+
{
459+
writeLog(LOG_TYPE_RENDER, std::string("addEmoji:input '") + node.Remark + "' originalEmoji='" + original_emoji + "' remove_emoji=" + (ext.remove_emoji ? "true" : "false"), LOG_LEVEL_DEBUG);
460+
}
432461

433462
for(const RegexMatchConfig &x : emoji_array)
434463
{
@@ -446,7 +475,17 @@ std::string addEmoji(const Proxy &node, const RegexMatchConfigs &emoji_array, ex
446475
auto getEmoji = (std::function<std::string(const Proxy&)>) ctx.eval("getEmoji");
447476
ret = getEmoji(node);
448477
if(!ret.empty())
449-
result = ret + " " + node.Remark;
478+
{
479+
// Smart emoji handling: if original emoji equals new emoji, avoid duplication
480+
if(!ext.remove_emoji && !original_emoji.empty() && original_emoji == ret)
481+
{
482+
result = node.Remark; // Keep original remark as-is
483+
}
484+
else
485+
{
486+
result = ret + " " + node.Remark;
487+
}
488+
}
450489
}
451490
catch (qjs::exception)
452491
{
@@ -460,7 +499,22 @@ std::string addEmoji(const Proxy &node, const RegexMatchConfigs &emoji_array, ex
460499
if(x.Replace.empty())
461500
continue;
462501
if(applyMatcher(x.Match, real_rule, node) && real_rule.size() && regFind(node.Remark, real_rule))
502+
{
503+
// Smart emoji handling: if original emoji equals new emoji, avoid duplication
504+
if(!ext.remove_emoji && !original_emoji.empty() && original_emoji == x.Replace)
505+
{
506+
if(global.printDbgInfo)
507+
writeLog(LOG_TYPE_RENDER, std::string("addEmoji:matched_dedup '") + node.Remark + "' newEmoji='" + x.Replace + "' -> keep original", LOG_LEVEL_DEBUG);
508+
return node.Remark; // Keep original remark as-is
509+
}
510+
if(global.printDbgInfo)
511+
writeLog(LOG_TYPE_RENDER, std::string("addEmoji:matched_add '") + node.Remark + "' newEmoji='" + x.Replace + "' -> add emoji", LOG_LEVEL_DEBUG);
463512
return x.Replace + " " + node.Remark;
513+
}
514+
}
515+
if(global.printDbgInfo && !node.Remark.empty())
516+
{
517+
writeLog(LOG_TYPE_RENDER, std::string("addEmoji:no_match '") + node.Remark + "' -> return as-is", LOG_LEVEL_DEBUG);
464518
}
465519
return node.Remark;
466520
}

src/generator/config/nodemanip.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct parse_settings
2424
std::string *sub_info = nullptr;
2525
bool authorized = false;
2626
string_icase_map *request_header = nullptr;
27+
std::string *custom_user_agent = nullptr;
2728
#ifndef NO_JS_RUNTIME
2829
qjs::Runtime *js_runtime = nullptr;
2930
qjs::Context *js_context = nullptr;

src/generator/config/ruleconvert.cpp

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
/// rule type lists
1212
#define basic_types "DOMAIN", "DOMAIN-SUFFIX", "DOMAIN-KEYWORD", "IP-CIDR", "SRC-IP-CIDR", "GEOIP", "MATCH", "FINAL"
13-
string_array ClashRuleTypes = {basic_types, "IP-CIDR6", "SRC-PORT", "DST-PORT", "PROCESS-NAME"};
13+
string_array ClashRuleTypes = {basic_types, "IP-CIDR6", "SRC-PORT", "DST-PORT", "PROCESS-NAME", "DOMAIN-REGEX", "GEOSITE", "IP-SUFFIX", "IP-ASN", "SRC-GEOIP", "SRC-IP-ASN", "SRC-IP-SUFFIX", "IN-PORT", "IN-TYPE", "IN-USER", "IN-NAME", "PROCESS-PATH-REGEX", "PROCESS-PATH", "PROCESS-NAME-REGEX", "UID", "NETWORK", "DSCP", "SUB-RULE", "RULE-SET", "AND", "OR", "NOT"};
1414
string_array Surge2RuleTypes = {basic_types, "IP-CIDR6", "USER-AGENT", "URL-REGEX", "PROCESS-NAME", "IN-PORT", "DEST-PORT", "SRC-IP"};
1515
string_array SurgeRuleTypes = {basic_types, "IP-CIDR6", "USER-AGENT", "URL-REGEX", "AND", "OR", "NOT", "PROCESS-NAME", "IN-PORT", "DEST-PORT", "SRC-IP"};
1616
string_array QuanXRuleTypes = {basic_types, "USER-AGENT", "HOST", "HOST-SUFFIX", "HOST-KEYWORD"};
@@ -133,6 +133,7 @@ void rulesetToClash(YAML::Node &base_rule, std::vector<RulesetContent> &ruleset_
133133

134134
if(!overwrite_original_rules && base_rule[field_name].IsDefined())
135135
rules = base_rule[field_name];
136+
// const std::string rule_match_regex = "^(.*?,.*?)(,.*)(,.*)$";
136137

137138
std::vector<std::string_view> temp(4);
138139
for(RulesetContent &x : ruleset_content_array)
@@ -152,6 +153,8 @@ void rulesetToClash(YAML::Node &base_rule, std::vector<RulesetContent> &ruleset_
152153
if(startsWith(strLine, "FINAL"))
153154
strLine.replace(0, 5, "MATCH");
154155
strLine = transformRuleToCommon(temp, strLine, rule_group);
156+
// if(!startsWith(strLine, "AND") && !startsWith(strLine, "OR") && !startsWith(strLine, "NOT") && count_least(strLine, ',', 3))
157+
// strLine = regReplace(strLine, rule_match_regex, "$1$3$2");
155158
allRules.emplace_back(strLine);
156159
total_rules++;
157160
continue;
@@ -178,6 +181,8 @@ void rulesetToClash(YAML::Node &base_rule, std::vector<RulesetContent> &ruleset_
178181
strLine = trimWhitespace(strLine);
179182
}
180183
strLine = transformRuleToCommon(temp, strLine, rule_group);
184+
// if(!startsWith(strLine, "AND") && !startsWith(strLine, "OR") && !startsWith(strLine, "NOT") && count_least(strLine, ',', 3))
185+
// strLine = regReplace(strLine, rule_match_regex, "$1$3$2");
181186
allRules.emplace_back(strLine);
182187
}
183188
}
@@ -205,6 +210,8 @@ std::string rulesetToClashStr(YAML::Node &base_rule, std::vector<RulesetContent>
205210
}
206211
base_rule.remove(field_name);
207212

213+
// const std::string rule_match_regex = "^(.*?,.*?)(,.*)(,.*)$";
214+
208215
string_view_array temp(4);
209216
for(RulesetContent &x : ruleset_content_array)
210217
{
@@ -223,6 +230,8 @@ std::string rulesetToClashStr(YAML::Node &base_rule, std::vector<RulesetContent>
223230
if(startsWith(strLine, "FINAL"))
224231
strLine.replace(0, 5, "MATCH");
225232
strLine = transformRuleToCommon(temp, strLine, rule_group);
233+
// if(!startsWith(strLine, "AND") && !startsWith(strLine, "OR") && !startsWith(strLine, "NOT") && count_least(strLine, ',', 3))
234+
// strLine = regReplace(strLine, rule_match_regex, "$1$3$2");
226235
output_content += " - " + strLine + "\n";
227236
total_rules++;
228237
continue;
@@ -248,8 +257,27 @@ std::string rulesetToClashStr(YAML::Node &base_rule, std::vector<RulesetContent>
248257
strLine.erase(strLine.find("//"));
249258
strLine = trimWhitespace(strLine);
250259
}
251-
strLine = transformRuleToCommon(temp, strLine, rule_group);
252-
output_content += " - " + strLine + "\n";
260+
261+
//AND & OR & NOT
262+
if(startsWith(strLine, "AND") || startsWith(strLine, "OR") || startsWith(strLine, "NOT"))
263+
{
264+
output_content += " - " + strLine + "," + rule_group + "\n";
265+
}
266+
//SUB-RULE & RULE-SET
267+
else if(startsWith(strLine, "SUB-RULE") || startsWith(strLine, "RULE-SET"))
268+
{
269+
output_content += " - " + strLine + "\n";
270+
}
271+
else
272+
//OTHER
273+
{
274+
strLine = transformRuleToCommon(temp, strLine, rule_group);
275+
output_content += " - " + strLine + "\n";
276+
}
277+
// strLine = transformRuleToCommon(temp, strLine, rule_group);
278+
// if(!startsWith(strLine, "AND") && !startsWith(strLine, "OR") && !startsWith(strLine, "NOT") && count_least(strLine, ',', 3))
279+
// strLine = regReplace(strLine, rule_match_regex, "$1$3$2");
280+
// output_content += " - " + strLine + "\n";
253281
total_rules++;
254282
}
255283
}

0 commit comments

Comments
 (0)