Enhancements

Fix base sing-box configuration.
Add support for adding Clash modes to sing-box configs.
Optimize codes.
This commit is contained in:
Tindy X committed 2023-11-10 18:23:43 +08:00
1 parent 8b45e06d0d
commit 51b65ec437
9 files changed
+306 -98

No files matched your search

+110 -24
View File
@@ -269,30 +269,116 @@ enhanced-mode-by-rule = true
{% if request.target == "singbox" %} {% if request.target == "singbox" %}
{ {
"log": { "log": {
"disabled": false, "disabled": false,
"level": "info", "level": "info",
"output": "box.log", "timestamp": true
"timestamp": true },
}, "dns": {
"dns": {}, "servers": [
"ntp": { {
"enabled": false, "tag": "dns_proxy",
"server": "time.apple.com", "address": "tls://1.1.1.1",
"server_port": 123, "address_resolver": "dns_resolver"
"interval": "30m" },
}, {
"inbounds": [ "tag": "dns_direct",
{ "address": "h3://dns.alidns.com/dns-query",
"type": "socks", "address_resolver": "dns_resolver",
"tag": "socks-in", "detour": "DIRECT"
"listen": "127.0.0.1", },
"listen_port": 2080 {
} "tag": "dns_fakeip",
], "address": "fakeip"
"outbounds": [], },
"route": {}, {
"experimental": {} "tag": "dns_resolver",
"address": "223.5.5.5",
"detour": "DIRECT"
},
{
"tag": "block",
"address": "rcode://success"
}
],
"rules": [
{
"outbound": [
"any"
],
"server": "dns_resolver"
},
{
"geosite": [
"category-ads-all"
],
"server": "dns_block",
"disable_cache": true
},
{
"geosite": [
"geolocation-!cn"
],
"query_type": [
"A",
"AAAA"
],
"server": "dns_fakeip"
},
{
"geosite": [
"geolocation-!cn"
],
"server": "dns_proxy"
}
],
"final": "dns_direct",
"independent_cache": true,
"fakeip": {
"enabled": true,
{% if default(request.singbox.ipv6, "") == "1" %}
"inet6_range": "fc00::\/18",
{% endif %}
"inet4_range": "198.18.0.0\/15"
}
},
"ntp": {
"enabled": true,
"server": "time.apple.com",
"server_port": 123,
"interval": "30m",
"detour": "DIRECT"
},
"inbounds": [
{
"type": "mixed",
"tag": "mixed-in",
{% if bool(default(global.singbox.allow_lan, "")) %}
"listen": "0.0.0.0",
{% else %}
"listen": "127.0.0.1",
{% endif %}
"listen_port": {{ default(global.singbox.mixed_port, "2080") }}
},
{
"type": "tun",
"tag": "tun-in",
"inet4_address": "172.19.0.1/30",
{% if default(request.singbox.ipv6, "") == "1" %}
"inet6_address": "fdfe:dcba:9876::1/126",
{% endif %}
"auto_route": true,
"strict_route": true,
"stack": "mixed",
"sniff": true
}
],
"outbounds": [],
"route": {
"rules": [],
"auto_detect_interface": true
},
"experimental": {}
} }
{% endif %} {% endif %}
+103 -25
View File
@@ -1,26 +1,104 @@
{ {
"log": { "log": {
"disabled": false, "disabled": false,
"level": "info", "level": "info",
"output": "box.log", "timestamp": true
"timestamp": true },
}, "dns": {
"dns": {}, "servers": [
"ntp": { {
"enabled": false, "tag": "dns_proxy",
"server": "time.apple.com", "address": "tls://1.1.1.1",
"server_port": 123, "address_resolver": "dns_resolver"
"interval": "30m" },
}, {
"inbounds": [ "tag": "dns_direct",
{ "address": "h3://dns.alidns.com/dns-query",
"type": "socks", "address_resolver": "dns_resolver",
"tag": "socks-in", "detour": "DIRECT"
"listen": "127.0.0.1", },
"listen_port": 2080 {
} "tag": "dns_fakeip",
], "address": "fakeip"
"outbounds": [], },
"route": {}, {
"experimental": {} "tag": "dns_resolver",
} "address": "223.5.5.5",
"detour": "DIRECT"
},
{
"tag": "block",
"address": "rcode://success"
}
],
"rules": [
{
"outbound": [
"any"
],
"server": "dns_resolver"
},
{
"geosite": [
"category-ads-all"
],
"server": "dns_block",
"disable_cache": true
},
{
"geosite": [
"geolocation-!cn"
],
"query_type": [
"A",
"AAAA"
],
"server": "dns_fakeip"
},
{
"geosite": [
"geolocation-!cn"
],
"server": "dns_proxy"
}
],
"final": "dns_direct",
"independent_cache": true,
"fakeip": {
"enabled": true,
"inet6_range": "fc00::\/18",
"inet4_range": "198.18.0.0\/15"
}
},
"ntp": {
"enabled": true,
"server": "time.apple.com",
"server_port": 123,
"interval": "30m",
"detour": "DIRECT"
},
"inbounds": [
{
"type": "mixed",
"tag": "mixed-in",
"listen": "0.0.0.0",
"listen_port": 2080
},
{
"type": "tun",
"tag": "tun-in",
"inet4_address": "172.19.0.1/30",
"inet6_address": "fdfe:dcba:9876::1/126",
"auto_route": true,
"strict_route": true,
"stack": "mixed",
"sniff": true
}
],
"outbounds": [],
"route": {
"rules": [],
"auto_detect_interface": true
},
"experimental": {}
}
+5
View File
@@ -114,6 +114,9 @@ clash_use_new_field_name=true
; key: value ; key: value
clash_proxies_style=flow clash_proxies_style=flow
;add Clash mode to sing-box rules, and add a GLOBAL group to end of outbounds
singbox_add_clash_modes=true
;Rename remarks with the following patterns. Supports regular expression. ;Rename remarks with the following patterns. Supports regular expression.
;Format: Search_Pattern@Replace_Pattern ;Format: Search_Pattern@Replace_Pattern
;rename_node=IPLC@专线 ;rename_node=IPLC@专线
@@ -226,6 +229,8 @@ clash.http_port=7890
clash.socks_port=7891 clash.socks_port=7891
clash.allow_lan=true clash.allow_lan=true
clash.log_level=info clash.log_level=info
singbox.allow_lan=true
singbox.mixed_port=2080
[aliases] [aliases]
;Aliases for accessing interfaces. Can be used to shorten the URI. ;Aliases for accessing interfaces. Can be used to shorten the URI.
+11
View File
@@ -140,6 +140,9 @@ clash_use_new_field_name = true
# key: value # key: value
clash_proxies_style = "flow" clash_proxies_style = "flow"
# add Clash mode to sing-box rules, and add a GLOBAL group to end of outbounds
singbox_add_clash_modes = true
[[node_pref.rename_node]] [[node_pref.rename_node]]
match = '\(?((x|X)?(\d+)(\.?\d+)?)((\s?倍率?)|(x|X))\)?' match = '\(?((x|X)?(\d+)(\.?\d+)?)((\s?倍率?)|(x|X))\)?'
replace = "$1x" replace = "$1x"
@@ -237,6 +240,14 @@ value = "true"
key = "clash.log_level" key = "clash.log_level"
value = "info" value = "info"
[[template.globals]]
key = "singbox.allow_lan"
value = "true"
[[template.globals]]
key = "singbox.mixed_port"
value = "2080"
[[aliases]] [[aliases]]
uri = "/clash" uri = "/clash"
target = "/sub?target=clash" target = "/sub?target=clash"
+3
View File
@@ -49,6 +49,7 @@ node_pref:
append_sub_userinfo: true append_sub_userinfo: true
clash_use_new_field_name: true clash_use_new_field_name: true
clash_proxies_style: flow clash_proxies_style: flow
singbox_add_clash_modes: true
rename_node: rename_node:
# - {match: "\\(?((x|X)?(\\d+)(\\.?\\d+)?)((\\s?倍率?)|(x|X))\\)?", replace: "$1x"} # - {match: "\\(?((x|X)?(\\d+)(\\.?\\d+)?)((\\s?倍率?)|(x|X))\\)?", replace: "$1x"}
# - {script: "function rename(node){}"} # - {script: "function rename(node){}"}
@@ -106,6 +107,8 @@ template:
- {key: clash.socks_port, value: 7891} - {key: clash.socks_port, value: 7891}
- {key: clash.allow_lan, value: true} - {key: clash.allow_lan, value: true}
- {key: clash.log_level, value: info} - {key: clash.log_level, value: info}
- {key: singbox.allow_lan, value: true}
- {key: singbox.mixed_port, value: 2080}
aliases: aliases:
- {uri: /v, target: /version} - {uri: /v, target: /version}
+9 -1
View File
@@ -487,7 +487,7 @@ void rulesetToSingBox(rapidjson::Document &base_rule, std::vector<RulesetContent
std::string rule_group, retrieved_rules, strLine, final; std::string rule_group, retrieved_rules, strLine, final;
std::stringstream strStrm; std::stringstream strStrm;
size_t total_rules = 0; size_t total_rules = 0;
rapidjson::MemoryPoolAllocator<>& allocator = base_rule.GetAllocator(); auto &allocator = base_rule.GetAllocator();
rapidjson::Value rules(rapidjson::kArrayType); rapidjson::Value rules(rapidjson::kArrayType);
if (!overwrite_original_rules) if (!overwrite_original_rules)
@@ -496,6 +496,14 @@ void rulesetToSingBox(rapidjson::Document &base_rule, std::vector<RulesetContent
rules.Swap(base_rule["route"]["rules"]); rules.Swap(base_rule["route"]["rules"]);
} }
if (global.singBoxAddClashModes)
{
auto global_object = buildObject(allocator, "clash_mode", "Global", "outbound", "GLOBAL");
auto direct_object = buildObject(allocator, "clash_mode", "Direct", "outbound", "DIRECT");
rules.PushBack(global_object, allocator);
rules.PushBack(direct_object, allocator);
}
for(RulesetContent &x : ruleset_content_array) for(RulesetContent &x : ruleset_content_array)
{ {
if(global.maxAllowedRules && total_rules > global.maxAllowedRules) if(global.maxAllowedRules && total_rules > global.maxAllowedRules)
+60 -46
View File
@@ -155,29 +155,29 @@ bool applyMatcher(const std::string &rule, std::string &real_rule, const Proxy &
return true; return true;
} }
void processRemark(std::string &oldremark, std::string &newremark, string_array &remarks_list, bool proc_comma = true) void processRemark(std::string &remark, string_array &remarks_list, bool proc_comma = true)
{ {
// Replace every '=' with '-' in the remark string to avoid parse errors from the clients. // Replace every '=' with '-' in the remark string to avoid parse errors from the clients.
// Surge is tested to yield an error when handling '=' in the remark string, // Surge is tested to yield an error when handling '=' in the remark string,
// not sure if other clients have the same problem. // not sure if other clients have the same problem.
std::replace(oldremark.begin(), oldremark.end(), '=', '-'); std::replace(remark.begin(), remark.end(), '=', '-');
if(proc_comma) if(proc_comma)
{ {
if(oldremark.find(',') != std::string::npos) if(remark.find(',') != std::string::npos)
{ {
oldremark.insert(0, "\""); remark.insert(0, "\"");
oldremark.append("\""); remark.append("\"");
} }
} }
newremark = oldremark; std::string tempRemark = remark;
int cnt = 2; int cnt = 2;
while(std::find(remarks_list.begin(), remarks_list.end(), newremark) != remarks_list.end()) while(std::find(remarks_list.begin(), remarks_list.end(), tempRemark) != remarks_list.end())
{ {
newremark = oldremark + " " + std::to_string(cnt); tempRemark = remark + " " + std::to_string(cnt);
cnt++; cnt++;
} }
oldremark = newremark; remark = tempRemark;
} }
void groupGenerate(const std::string &rule, std::vector<Proxy> &nodelist, string_array &filtered_nodelist, bool add_direct, extra_settings &ext) void groupGenerate(const std::string &rule, std::vector<Proxy> &nodelist, string_array &filtered_nodelist, bool add_direct, extra_settings &ext)
@@ -241,18 +241,18 @@ void proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGr
YAML::Node singleproxy; YAML::Node singleproxy;
std::string type = getProxyTypeName(x.Type); std::string type = getProxyTypeName(x.Type);
std::string remark, pluginopts = replaceAllDistinct(x.PluginOption, ";", "&"); std::string pluginopts = replaceAllDistinct(x.PluginOption, ";", "&");
if(ext.append_proxy_type) if(ext.append_proxy_type)
x.Remark = "[" + type + "] " + x.Remark; x.Remark = "[" + type + "] " + x.Remark;
processRemark(x.Remark, remark, remarks_list, false); processRemark(x.Remark, remarks_list, false);
tribool udp = ext.udp; tribool udp = ext.udp;
tribool scv = ext.skip_cert_verify; tribool scv = ext.skip_cert_verify;
udp.define(x.UDP); udp.define(x.UDP);
scv.define(x.AllowInsecure); scv.define(x.AllowInsecure);
singleproxy["name"] = remark; singleproxy["name"] = x.Remark;
singleproxy["server"] = x.Hostname; singleproxy["server"] = x.Hostname;
singleproxy["port"] = x.Port; singleproxy["port"] = x.Port;
@@ -471,7 +471,7 @@ void proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGr
else else
singleproxy.SetStyle(YAML::EmitterStyle::Flow); singleproxy.SetStyle(YAML::EmitterStyle::Flow);
proxies.push_back(singleproxy); proxies.push_back(singleproxy);
remarks_list.emplace_back(std::move(remark)); remarks_list.emplace_back(x.Remark);
nodelist.emplace_back(x); nodelist.emplace_back(x);
} }
@@ -657,14 +657,13 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
for(Proxy &x : nodes) for(Proxy &x : nodes)
{ {
std::string remark;
if(ext.append_proxy_type) if(ext.append_proxy_type)
{ {
std::string type = getProxyTypeName(x.Type); std::string type = getProxyTypeName(x.Type);
x.Remark = "[" + type + "] " + x.Remark; x.Remark = "[" + type + "] " + x.Remark;
} }
processRemark(x.Remark, remark, remarks_list); processRemark(x.Remark, remarks_list);
std::string &hostname = x.Hostname, &username = x.Username, &password = x.Password, &method = x.EncryptMethod, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &edge = x.Edge, &path = x.Path, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam, &plugin = x.Plugin, &pluginopts = x.PluginOption; std::string &hostname = x.Hostname, &username = x.Username, &password = x.Password, &method = x.EncryptMethod, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &edge = x.Edge, &path = x.Path, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam, &plugin = x.Plugin, &pluginopts = x.PluginOption;
std::string port = std::to_string(x.Port); std::string port = std::to_string(x.Port);
@@ -834,13 +833,13 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
proxy += ", udp-relay=" + udp.get_str(); proxy += ", udp-relay=" + udp.get_str();
if(ext.nodelist) if(ext.nodelist)
output_nodelist += remark + " = " + proxy + "\n"; output_nodelist += x.Remark + " = " + proxy + "\n";
else else
{ {
ini.set("{NONAME}", remark + " = " + proxy); ini.set("{NONAME}", x.Remark + " = " + proxy);
nodelist.emplace_back(x); nodelist.emplace_back(x);
} }
remarks_list.emplace_back(std::move(remark)); remarks_list.emplace_back(x.Remark);
} }
if(ext.nodelist) if(ext.nodelist)
@@ -1083,15 +1082,13 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
ini.erase_section(); ini.erase_section();
for(Proxy &x : nodes) for(Proxy &x : nodes)
{ {
std::string remark = x.Remark;
if(ext.append_proxy_type) if(ext.append_proxy_type)
{ {
std::string type = getProxyTypeName(x.Type); std::string type = getProxyTypeName(x.Type);
x.Remark = "[" + type + "] " + x.Remark; x.Remark = "[" + type + "] " + x.Remark;
} }
processRemark(x.Remark, remark, remarks_list); processRemark(x.Remark, remarks_list);
std::string &hostname = x.Hostname, &method = x.EncryptMethod, &password = x.Password, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &path = x.Path, &edge = x.Edge, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam, &plugin = x.Plugin, &pluginopts = x.PluginOption, &username = x.Username; std::string &hostname = x.Hostname, &method = x.EncryptMethod, &password = x.Password, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &path = x.Path, &edge = x.Edge, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam, &plugin = x.Plugin, &pluginopts = x.PluginOption, &username = x.Username;
std::string port = std::to_string(x.Port); std::string port = std::to_string(x.Port);
@@ -1106,7 +1103,7 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
if(method == "auto") if(method == "auto")
method = "chacha20-ietf-poly1305"; method = "chacha20-ietf-poly1305";
proxyStr = remark + " = vmess, " + hostname + ", " + port + ", " + method + ", \"" + id + "\", group=" + x.Group; proxyStr = x.Remark + " = vmess, " + hostname + ", " + port + ", " + method + ", \"" + id + "\", group=" + x.Group;
if(tlssecure) if(tlssecure)
{ {
proxyStr += ", over-tls=true, tls-host=" + host; proxyStr += ", over-tls=true, tls-host=" + host;
@@ -1128,12 +1125,12 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
if(ext.nodelist) if(ext.nodelist)
{ {
proxyStr = "ssr://" + urlSafeBase64Encode(hostname + ":" + port + ":" + protocol + ":" + method + ":" + obfs + ":" + urlSafeBase64Encode(password) \ proxyStr = "ssr://" + urlSafeBase64Encode(hostname + ":" + port + ":" + protocol + ":" + method + ":" + obfs + ":" + urlSafeBase64Encode(password) \
+ "/?group=" + urlSafeBase64Encode(x.Group) + "&remarks=" + urlSafeBase64Encode(remark) \ + "/?group=" + urlSafeBase64Encode(x.Group) + "&remarks=" + urlSafeBase64Encode(x.Remark) \
+ "&obfsparam=" + urlSafeBase64Encode(obfsparam) + "&protoparam=" + urlSafeBase64Encode(protoparam)); + "&obfsparam=" + urlSafeBase64Encode(obfsparam) + "&protoparam=" + urlSafeBase64Encode(protoparam));
} }
else else
{ {
proxyStr = remark + " = shadowsocksr, " + hostname + ", " + port + ", " + method + ", \"" + password + "\", group=" + x.Group + ", protocol=" + protocol + ", obfs=" + obfs; proxyStr = x.Remark + " = shadowsocksr, " + hostname + ", " + port + ", " + method + ", \"" + password + "\", group=" + x.Group + ", protocol=" + protocol + ", obfs=" + obfs;
if(!protoparam.empty()) if(!protoparam.empty())
proxyStr += ", protocol_param=" + protoparam; proxyStr += ", protocol_param=" + protoparam;
if(!obfsparam.empty()) if(!obfsparam.empty())
@@ -1148,11 +1145,11 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
{ {
proxyStr += "/?plugin=" + urlEncode(plugin + ";" + pluginopts); proxyStr += "/?plugin=" + urlEncode(plugin + ";" + pluginopts);
} }
proxyStr += "&group=" + urlSafeBase64Encode(x.Group) + "#" + urlEncode(remark); proxyStr += "&group=" + urlSafeBase64Encode(x.Group) + "#" + urlEncode(x.Remark);
} }
else else
{ {
proxyStr = remark + " = shadowsocks, " + hostname + ", " + port + ", " + method + ", \"" + password + "\", group=" + x.Group; proxyStr = x.Remark + " = shadowsocks, " + hostname + ", " + port + ", " + method + ", \"" + password + "\", group=" + x.Group;
if(plugin == "obfs-local" && !pluginopts.empty()) if(plugin == "obfs-local" && !pluginopts.empty())
{ {
proxyStr += ", " + replaceAllDistinct(pluginopts, ";", ", "); proxyStr += ", " + replaceAllDistinct(pluginopts, ";", ", ");
@@ -1161,7 +1158,7 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
break; break;
case ProxyType::HTTP: case ProxyType::HTTP:
case ProxyType::HTTPS: case ProxyType::HTTPS:
proxyStr = remark + " = http, upstream-proxy-address=" + hostname + ", upstream-proxy-port=" + port + ", group=" + x.Group; proxyStr = x.Remark + " = http, upstream-proxy-address=" + hostname + ", upstream-proxy-port=" + port + ", group=" + x.Group;
if(!username.empty() && !password.empty()) if(!username.empty() && !password.empty())
proxyStr += ", upstream-proxy-auth=true, upstream-proxy-username=" + username + ", upstream-proxy-password=" + password; proxyStr += ", upstream-proxy-auth=true, upstream-proxy-username=" + username + ", upstream-proxy-password=" + password;
else else
@@ -1180,7 +1177,7 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
proxyStr = "http://" + urlSafeBase64Encode(proxyStr); proxyStr = "http://" + urlSafeBase64Encode(proxyStr);
break; break;
case ProxyType::SOCKS5: case ProxyType::SOCKS5:
proxyStr = remark + " = socks, upstream-proxy-address=" + hostname + ", upstream-proxy-port=" + port + ", group=" + x.Group; proxyStr = x.Remark + " = socks, upstream-proxy-address=" + hostname + ", upstream-proxy-port=" + port + ", group=" + x.Group;
if(!username.empty() && !password.empty()) if(!username.empty() && !password.empty())
proxyStr += ", upstream-proxy-auth=true, upstream-proxy-username=" + username + ", upstream-proxy-password=" + password; proxyStr += ", upstream-proxy-auth=true, upstream-proxy-username=" + username + ", upstream-proxy-password=" + password;
else else
@@ -1203,7 +1200,7 @@ void proxyToQuan(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetC
} }
ini.set("{NONAME}", proxyStr); ini.set("{NONAME}", proxyStr);
remarks_list.emplace_back(std::move(remark)); remarks_list.emplace_back(x.Remark);
nodelist.emplace_back(x); nodelist.emplace_back(x);
} }
@@ -1311,7 +1308,6 @@ std::string proxyToQuanX(std::vector<Proxy> &nodes, const std::string &base_conf
void proxyToQuanX(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetContent> &ruleset_content_array, const ProxyGroupConfigs &extra_proxy_group, extra_settings &ext) void proxyToQuanX(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetContent> &ruleset_content_array, const ProxyGroupConfigs &extra_proxy_group, extra_settings &ext)
{ {
std::string type; std::string type;
std::string remark;
std::string proxyStr; std::string proxyStr;
tribool udp, tfo, scv, tls13; tribool udp, tfo, scv, tls13;
std::vector<Proxy> nodelist; std::vector<Proxy> nodelist;
@@ -1324,7 +1320,7 @@ void proxyToQuanX(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Ruleset
if(ext.append_proxy_type) if(ext.append_proxy_type)
x.Remark = "[" + type + "] " + x.Remark; x.Remark = "[" + type + "] " + x.Remark;
processRemark(x.Remark, remark, remarks_list); processRemark(x.Remark, remarks_list);
std::string &hostname = x.Hostname, &method = x.EncryptMethod, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &path = x.Path, &password = x.Password, &plugin = x.Plugin, &pluginopts = x.PluginOption, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam, &username = x.Username; std::string &hostname = x.Hostname, &method = x.EncryptMethod, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &path = x.Path, &password = x.Password, &plugin = x.Plugin, &pluginopts = x.PluginOption, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam, &username = x.Username;
std::string port = std::to_string(x.Port); std::string port = std::to_string(x.Port);
@@ -1455,10 +1451,10 @@ void proxyToQuanX(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Ruleset
proxyStr += ", udp-relay=" + udp.get_str(); proxyStr += ", udp-relay=" + udp.get_str();
if(tlssecure && !scv.is_undef() && (x.Type != ProxyType::Shadowsocks && x.Type != ProxyType::ShadowsocksR)) if(tlssecure && !scv.is_undef() && (x.Type != ProxyType::Shadowsocks && x.Type != ProxyType::ShadowsocksR))
proxyStr += ", tls-verification=" + scv.reverse().get_str(); proxyStr += ", tls-verification=" + scv.reverse().get_str();
proxyStr += ", tag=" + remark; proxyStr += ", tag=" + x.Remark;
ini.set("{NONAME}", proxyStr); ini.set("{NONAME}", proxyStr);
remarks_list.emplace_back(std::move(remark)); remarks_list.emplace_back(x.Remark);
nodelist.emplace_back(x); nodelist.emplace_back(x);
} }
@@ -1661,7 +1657,7 @@ std::string proxyToMellow(std::vector<Proxy> &nodes, const std::string &base_con
void proxyToMellow(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetContent> &ruleset_content_array, const ProxyGroupConfigs &extra_proxy_group, extra_settings &ext) void proxyToMellow(std::vector<Proxy> &nodes, INIReader &ini, std::vector<RulesetContent> &ruleset_content_array, const ProxyGroupConfigs &extra_proxy_group, extra_settings &ext)
{ {
std::string proxy; std::string proxy;
std::string remark, username, password, method; std::string username, password, method;
std::string plugin, pluginopts; std::string plugin, pluginopts;
std::string id, aid, transproto, faketype, host, path, quicsecure, quicsecret, tlssecure; std::string id, aid, transproto, faketype, host, path, quicsecure, quicsecret, tlssecure;
std::string url; std::string url;
@@ -1679,7 +1675,7 @@ void proxyToMellow(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Rulese
x.Remark = "[" + type + "] " + x.Remark; x.Remark = "[" + type + "] " + x.Remark;
} }
processRemark(x.Remark, remark, remarks_list); processRemark(x.Remark, remarks_list);
std::string &hostname = x.Hostname, port = std::to_string(x.Port); std::string &hostname = x.Hostname, port = std::to_string(x.Port);
@@ -1693,10 +1689,10 @@ void proxyToMellow(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Rulese
case ProxyType::Shadowsocks: case ProxyType::Shadowsocks:
if(!x.Plugin.empty()) if(!x.Plugin.empty())
continue; continue;
proxy = remark + ", ss, ss://" + urlSafeBase64Encode(method + ":" + password) + "@" + hostname + ":" + port; proxy = x.Remark + ", ss, ss://" + urlSafeBase64Encode(method + ":" + password) + "@" + hostname + ":" + port;
break; break;
case ProxyType::VMess: case ProxyType::VMess:
proxy = remark + ", vmess1, vmess1://" + id + "@" + hostname + ":" + port; proxy = x.Remark + ", vmess1, vmess1://" + id + "@" + hostname + ":" + port;
if(!path.empty()) if(!path.empty())
proxy += path; proxy += path;
proxy += "?network=" + transproto; proxy += "?network=" + transproto;
@@ -1729,17 +1725,17 @@ void proxyToMellow(std::vector<Proxy> &nodes, INIReader &ini, std::vector<Rulese
proxy += "&sockopt.tcpfastopen=" + tfo.get_str(); proxy += "&sockopt.tcpfastopen=" + tfo.get_str();
break; break;
case ProxyType::SOCKS5: case ProxyType::SOCKS5:
proxy = remark + ", builtin, socks, address=" + hostname + ", port=" + port + ", user=" + username + ", pass=" + password; proxy = x.Remark + ", builtin, socks, address=" + hostname + ", port=" + port + ", user=" + username + ", pass=" + password;
break; break;
case ProxyType::HTTP: case ProxyType::HTTP:
proxy = remark + ", builtin, http, address=" + hostname + ", port=" + port + ", user=" + username + ", pass=" + password; proxy = x.Remark + ", builtin, http, address=" + hostname + ", port=" + port + ", user=" + username + ", pass=" + password;
break; break;
default: default:
continue; continue;
} }
ini.set("{NONAME}", proxy); ini.set("{NONAME}", proxy);
remarks_list.emplace_back(std::move(remark)); remarks_list.emplace_back(x.Remark);
nodelist.emplace_back(x); nodelist.emplace_back(x);
} }
@@ -1824,8 +1820,7 @@ std::string proxyToLoon(std::vector<Proxy> &nodes, const std::string &base_conf,
std::string type = getProxyTypeName(x.Type); std::string type = getProxyTypeName(x.Type);
x.Remark = "[" + type + "] " + x.Remark; x.Remark = "[" + type + "] " + x.Remark;
} }
std::string remark = x.Remark; processRemark(x.Remark, remarks_list);
processRemark(x.Remark, remark, remarks_list);
std::string &hostname = x.Hostname, &username = x.Username, &password = x.Password, &method = x.EncryptMethod, &plugin = x.Plugin, &pluginopts = x.PluginOption, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &path = x.Path, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam; std::string &hostname = x.Hostname, &username = x.Username, &password = x.Password, &method = x.EncryptMethod, &plugin = x.Plugin, &pluginopts = x.PluginOption, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.Host, &path = x.Path, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &obfsparam = x.OBFSParam;
std::string port = std::to_string(x.Port), aid = std::to_string(x.AlterId); std::string port = std::to_string(x.Port), aid = std::to_string(x.AlterId);
@@ -1931,12 +1926,12 @@ std::string proxyToLoon(std::vector<Proxy> &nodes, const std::string &base_conf,
if(ext.nodelist) if(ext.nodelist)
output_nodelist += remark + " = " + proxy + "\n"; output_nodelist += x.Remark + " = " + proxy + "\n";
else else
{ {
ini.set("{NONAME}", remark + " = " + proxy); ini.set("{NONAME}", x.Remark + " = " + proxy);
nodelist.emplace_back(x); nodelist.emplace_back(x);
remarks_list.emplace_back(std::move(remark)); remarks_list.emplace_back(x.Remark);
} }
} }
@@ -2096,6 +2091,7 @@ void proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::v
rapidjson::Document::AllocatorType &allocator = json.GetAllocator(); rapidjson::Document::AllocatorType &allocator = json.GetAllocator();
rapidjson::Value outbounds(rapidjson::kArrayType), route(rapidjson::kArrayType); rapidjson::Value outbounds(rapidjson::kArrayType), route(rapidjson::kArrayType);
std::vector<Proxy> nodelist; std::vector<Proxy> nodelist;
string_array remarks_list;
auto direct = buildObject(allocator, "type", "direct", "tag", "DIRECT"); auto direct = buildObject(allocator, "type", "direct", "tag", "DIRECT");
outbounds.PushBack(direct, allocator); outbounds.PushBack(direct, allocator);
@@ -2108,6 +2104,8 @@ void proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::v
if (ext.append_proxy_type) if (ext.append_proxy_type)
x.Remark = "[" + type + "] " + x.Remark; x.Remark = "[" + type + "] " + x.Remark;
processRemark(x.Remark, remarks_list, false);
tribool udp = ext.udp, tfo = ext.tfo, scv = ext.skip_cert_verify; tribool udp = ext.udp, tfo = ext.tfo, scv = ext.skip_cert_verify;
udp.define(x.UDP); udp.define(x.UDP);
tfo.define(x.TCPFastOpen); tfo.define(x.TCPFastOpen);
@@ -2118,7 +2116,7 @@ void proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::v
{ {
case ProxyType::Shadowsocks: case ProxyType::Shadowsocks:
{ {
addSingBoxCommonMembers(proxy, x, "ss", allocator); addSingBoxCommonMembers(proxy, x, "shadowsocks", allocator);
proxy.AddMember("method", rapidjson::StringRef(x.EncryptMethod.c_str()), allocator); proxy.AddMember("method", rapidjson::StringRef(x.EncryptMethod.c_str()), allocator);
proxy.AddMember("password", rapidjson::StringRef(x.Password.c_str()), allocator); proxy.AddMember("password", rapidjson::StringRef(x.Password.c_str()), allocator);
if(!x.Plugin.empty() && !x.PluginOption.empty()) if(!x.Plugin.empty() && !x.PluginOption.empty())
@@ -2243,6 +2241,7 @@ void proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::v
proxy.AddMember("tcp_fast_open", buildBooleanValue(tfo), allocator); proxy.AddMember("tcp_fast_open", buildBooleanValue(tfo), allocator);
} }
nodelist.push_back(x); nodelist.push_back(x);
remarks_list.emplace_back(x.Remark);
outbounds.PushBack(proxy, allocator); outbounds.PushBack(proxy, allocator);
} }
for (const ProxyGroupConfig &x: extra_proxy_group) for (const ProxyGroupConfig &x: extra_proxy_group)
@@ -2293,6 +2292,21 @@ void proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::v
} }
outbounds.PushBack(group, allocator); outbounds.PushBack(group, allocator);
} }
if (global.singBoxAddClashModes)
{
auto global_group = rapidjson::Value(rapidjson::kObjectType);
global_group.AddMember("type", "selector", allocator);
global_group.AddMember("tag", "GLOBAL", allocator);
global_group.AddMember("outbounds", rapidjson::Value(rapidjson::kArrayType), allocator);
global_group["outbounds"].PushBack("DIRECT", allocator);
for (auto &x: remarks_list)
{
global_group["outbounds"].PushBack(rapidjson::Value(x.c_str(), allocator), allocator);
}
outbounds.PushBack(global_group, allocator);
}
json | AddMemberOrReplace("outbounds", outbounds, allocator); json | AddMemberOrReplace("outbounds", outbounds, allocator);
} }
+4 -1
View File
@@ -376,6 +376,7 @@ void readYAMLConf(YAML::Node &node)
section["append_sub_userinfo"] >> global.appendUserinfo; section["append_sub_userinfo"] >> global.appendUserinfo;
section["clash_use_new_field_name"] >> global.clashUseNewField; section["clash_use_new_field_name"] >> global.clashUseNewField;
section["clash_proxies_style"] >> global.clashProxiesStyle; section["clash_proxies_style"] >> global.clashProxiesStyle;
section["singbox_add_clash_modes"] >> global.singBoxAddClashModes;
} }
if(section["rename_node"].IsSequence()) if(section["rename_node"].IsSequence())
@@ -634,7 +635,8 @@ void readTOMLConf(toml::value &root)
"filter_deprecated_nodes", global.filterDeprecated, "filter_deprecated_nodes", global.filterDeprecated,
"append_sub_userinfo", global.appendUserinfo, "append_sub_userinfo", global.appendUserinfo,
"clash_use_new_field_name", global.clashUseNewField, "clash_use_new_field_name", global.clashUseNewField,
"clash_proxies_style", global.clashProxiesStyle "clash_proxies_style", global.clashProxiesStyle,
"singbox_add_clash_modes", global.singBoxAddClashModes
); );
auto renameconfs = toml::find_or<std::vector<toml::value>>(section_node_pref, "rename_node", {}); auto renameconfs = toml::find_or<std::vector<toml::value>>(section_node_pref, "rename_node", {});
@@ -878,6 +880,7 @@ void readConf()
ini.get_bool_if_exist("append_sub_userinfo", global.appendUserinfo); ini.get_bool_if_exist("append_sub_userinfo", global.appendUserinfo);
ini.get_bool_if_exist("clash_use_new_field_name", global.clashUseNewField); ini.get_bool_if_exist("clash_use_new_field_name", global.clashUseNewField);
ini.get_if_exist("clash_proxies_style", global.clashProxiesStyle); ini.get_if_exist("clash_proxies_style", global.clashProxiesStyle);
ini.get_bool_if_exist("singbox_add_clash_modes", global.singBoxAddClashModes);
if(ini.item_prefix_exist("rename_node")) if(ini.item_prefix_exist("rename_node"))
{ {
ini.get_all("rename_node", tempArray); ini.get_all("rename_node", tempArray);
+1 -1
View File
@@ -46,7 +46,7 @@ struct Settings
bool addEmoji = false, removeEmoji = false, appendType = false, filterDeprecated = true; bool addEmoji = false, removeEmoji = false, appendType = false, filterDeprecated = true;
tribool UDPFlag, TFOFlag, skipCertVerify, TLS13Flag, enableInsert; tribool UDPFlag, TFOFlag, skipCertVerify, TLS13Flag, enableInsert;
bool enableSort = false, updateStrict = false; bool enableSort = false, updateStrict = false;
bool clashUseNewField = false; bool clashUseNewField = false, singBoxAddClashModes = true;
std::string clashProxiesStyle = "flow"; std::string clashProxiesStyle = "flow";
std::string proxyConfig, proxyRuleset, proxySubscription; std::string proxyConfig, proxyRuleset, proxySubscription;
int updateInterval = 0; int updateInterval = 0;