Compare commits

..

8 commits

Author SHA1 Message Date
DHR60
e14a85c144
Merge f7409053cd into b5800f7dfc 2026-02-15 09:01:35 +00:00
DHR60
f7409053cd Node test with sub chain 2026-02-15 17:01:09 +08:00
DHR60
a03e38fb16 Fix 2026-02-15 16:48:44 +08:00
DHR60
84a1eb8445 Optimize ProfileItem acquisition speed 2026-02-15 16:48:44 +08:00
DHR60
f900ce7f3f Fix 2026-02-15 16:48:44 +08:00
DHR60
a89471da92 Support sing-box 1.11 DNS 2026-02-07 21:17:29 +08:00
DHR60
b53101ce58 Update tag naming 2026-02-07 21:17:29 +08:00
DHR60
c3223e1fc4 Refactor core config gen 2026-02-07 21:17:29 +08:00
6 changed files with 38 additions and 30 deletions

View file

@ -215,7 +215,7 @@ public class CertPemManager
using var client = new TcpClient(); using var client = new TcpClient();
await client.ConnectAsync(domain, port > 0 ? port : 443, cts.Token); await client.ConnectAsync(domain, port > 0 ? port : 443, cts.Token);
await using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate); using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate);
var sslOptions = new SslClientAuthenticationOptions var sslOptions = new SslClientAuthenticationOptions
{ {
@ -262,7 +262,7 @@ public class CertPemManager
using var client = new TcpClient(); using var client = new TcpClient();
await client.ConnectAsync(domain, port > 0 ? port : 443, cts.Token); await client.ConnectAsync(domain, port > 0 ? port : 443, cts.Token);
await using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate); using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate);
var sslOptions = new SslClientAuthenticationOptions var sslOptions = new SslClientAuthenticationOptions
{ {
@ -280,7 +280,11 @@ public class CertPemManager
var chain = new X509Chain(); var chain = new X509Chain();
chain.Build(certChain); chain.Build(certChain);
pemList.AddRange(chain.ChainElements.Select(element => ExportCertToPem(element.Certificate))); foreach (var element in chain.ChainElements)
{
var pem = ExportCertToPem(element.Certificate);
pemList.Add(pem);
}
return (pemList, null); return (pemList, null);
} }

View file

@ -23,7 +23,7 @@ public partial class CoreConfigSingboxService
} }
// Process outbounds // Process outbounds
var customOutboundsNode = fullConfigTemplateNode["outbounds"] is JsonArray outbounds ? outbounds : []; var customOutboundsNode = fullConfigTemplateNode["outbounds"] is JsonArray outbounds ? outbounds : new JsonArray();
foreach (var outbound in _coreConfig.outbounds) foreach (var outbound in _coreConfig.outbounds)
{ {
if (outbound.type.ToLower() is "direct" or "block") if (outbound.type.ToLower() is "direct" or "block")
@ -44,7 +44,7 @@ public partial class CoreConfigSingboxService
// Process endpoints // Process endpoints
if (_coreConfig.endpoints != null && _coreConfig.endpoints.Count > 0) if (_coreConfig.endpoints != null && _coreConfig.endpoints.Count > 0)
{ {
var customEndpointsNode = fullConfigTemplateNode["endpoints"] is JsonArray endpoints ? endpoints : []; var customEndpointsNode = fullConfigTemplateNode["endpoints"] is JsonArray endpoints ? endpoints : new JsonArray();
foreach (var endpoint in _coreConfig.endpoints) foreach (var endpoint in _coreConfig.endpoints)
{ {
if (endpoint.detour.IsNullOrEmpty() && !fullConfigTemplate.ProxyDetour.IsNullOrEmpty()) if (endpoint.detour.IsNullOrEmpty() && !fullConfigTemplate.ProxyDetour.IsNullOrEmpty())

View file

@ -433,17 +433,15 @@ public partial class CoreConfigSingboxService
{ {
GenDnsProtectCustom(); GenDnsProtectCustom();
_coreConfig.dns?.servers?.RemoveAll(s => s.tag == Global.SingboxLocalDNSTag); var localDnsServer = _coreConfig.dns?.servers?.FirstOrDefault(s => s.tag == Global.SingboxLocalDNSTag);
var dnsItem = context.RawDnsItem; if (localDnsServer == null)
var localDnsServer = new Server4Sbox()
{ {
address = string.IsNullOrEmpty(dnsItem?.DomainDNSAddress) return;
? Global.DomainPureIPDNSAddress.FirstOrDefault() }
: dnsItem?.DomainDNSAddress, localDnsServer.type = null;
tag = Global.SingboxLocalDNSTag, localDnsServer.server = null;
detour = Global.DirectTag, var dnsItem = context.RawDnsItem;
}; localDnsServer.address = string.IsNullOrEmpty(dnsItem?.DomainDNSAddress) ? Global.DomainPureIPDNSAddress.FirstOrDefault() : dnsItem?.DomainDNSAddress;
_coreConfig.dns?.servers?.Add(localDnsServer);
} }
private Rule4Sbox BuildProtectDomainRule() private Rule4Sbox BuildProtectDomainRule()

View file

@ -19,12 +19,9 @@ public partial class CoreConfigV2rayService
// Handle balancer and rules modifications (for multiple load scenarios) // Handle balancer and rules modifications (for multiple load scenarios)
if (_coreConfig.routing?.balancers?.Count > 0) if (_coreConfig.routing?.balancers?.Count > 0)
{ {
var balancer = var balancer = _coreConfig.routing.balancers.First();
_coreConfig.routing.balancers.FirstOrDefault(b => b.tag == Global.ProxyTag + Global.BalancerTagSuffix, null);
// Modify existing rules in custom config // Modify existing rules in custom config
if (balancer != null)
{
var rulesNode = fullConfigTemplateNode["routing"]?["rules"]; var rulesNode = fullConfigTemplateNode["routing"]?["rules"];
if (rulesNode != null) if (rulesNode != null)
{ {
@ -37,7 +34,6 @@ public partial class CoreConfigV2rayService
} }
} }
} }
}
// Ensure routing node exists // Ensure routing node exists
if (fullConfigTemplateNode["routing"] == null) if (fullConfigTemplateNode["routing"] == null)
@ -101,8 +97,8 @@ public partial class CoreConfigV2rayService
continue; continue;
} }
} }
else if (!fullConfigTemplate.ProxyDetour.IsNullOrEmpty() else if ((!fullConfigTemplate.ProxyDetour.IsNullOrEmpty())
&& (outbound.streamSettings?.sockopt?.dialerProxy.IsNullOrEmpty() ?? true)) && ((outbound.streamSettings?.sockopt?.dialerProxy.IsNullOrEmpty() ?? true) == true))
{ {
var outboundAddress = outbound.settings?.servers?.FirstOrDefault()?.address var outboundAddress = outbound.settings?.servers?.FirstOrDefault()?.address
?? outbound.settings?.vnext?.FirstOrDefault()?.address ?? outbound.settings?.vnext?.FirstOrDefault()?.address

View file

@ -39,9 +39,9 @@ public partial class CoreConfigV2rayService
.ToList() ?? []; .ToList() ?? [];
if (balancerTagList.Count > 0) if (balancerTagList.Count > 0)
{ {
foreach (var rulesItem in _coreConfig.routing.rules.Where(r => balancerTagList.Contains(r.outboundTag + Global.BalancerTagSuffix))) foreach (var rulesItem in _coreConfig.routing.rules.Where(r => balancerTagList.Contains(r.outboundTag)))
{ {
rulesItem.balancerTag = rulesItem.outboundTag + Global.BalancerTagSuffix; rulesItem.balancerTag = rulesItem.outboundTag;
rulesItem.outboundTag = null; rulesItem.outboundTag = null;
} }
} }

View file

@ -247,6 +247,11 @@ public class AddServerViewModel : MyReactiveObject
{ {
serverName = SelectedSource.Address; serverName = SelectedSource.Address;
} }
if (!Utils.IsDomain(serverName))
{
UpdateCertTip(ResUI.ServerNameMustBeValidDomain);
return;
}
if (SelectedSource.Port > 0) if (SelectedSource.Port > 0)
{ {
domain += $":{SelectedSource.Port}"; domain += $":{SelectedSource.Port}";
@ -272,6 +277,11 @@ public class AddServerViewModel : MyReactiveObject
{ {
serverName = SelectedSource.Address; serverName = SelectedSource.Address;
} }
if (!Utils.IsDomain(serverName))
{
UpdateCertTip(ResUI.ServerNameMustBeValidDomain);
return;
}
if (SelectedSource.Port > 0) if (SelectedSource.Port > 0)
{ {
domain += $":{SelectedSource.Port}"; domain += $":{SelectedSource.Port}";