Add ECH config support to profile and UI

Introduces EchConfigList and EchForceQuery fields to ProfileItem and V2rayConfig models, updates related handlers and services to process these fields, and extends the AddServerWindow UI to allow user input for ECH configuration. Also adds localization entries for the new fields and updates extension methods for string handling.
This commit is contained in:
2dust
2026-01-07 11:34:13 +08:00
parent bc36cf8a47
commit 4562d4cf00
22 changed files with 172 additions and 24 deletions
@@ -157,13 +157,13 @@ public partial class CoreConfigSingboxService
new Rule4Sbox
{
server = Global.SingboxRemoteDNSTag,
strategy = simpleDNSItem.SingboxStrategy4Proxy.IsNullOrEmpty() ? null : simpleDNSItem.SingboxStrategy4Proxy,
strategy = simpleDNSItem.SingboxStrategy4Proxy.NullIfEmpty(),
clash_mode = ERuleMode.Global.ToString()
},
new Rule4Sbox
{
server = Global.SingboxDirectDNSTag,
strategy = simpleDNSItem.SingboxStrategy4Direct.IsNullOrEmpty() ? null : simpleDNSItem.SingboxStrategy4Direct,
strategy = simpleDNSItem.SingboxStrategy4Direct.NullIfEmpty(),
clash_mode = ERuleMode.Direct.ToString()
}
});
@@ -354,7 +354,7 @@ public partial class CoreConfigSingboxService
case nameof(ETransport.h2):
transport.type = nameof(ETransport.http);
transport.host = node.RequestHost.IsNullOrEmpty() ? null : Utils.String2List(node.RequestHost);
transport.path = node.Path.IsNullOrEmpty() ? null : node.Path;
transport.path = node.Path.NullIfEmpty();
break;
case nameof(ETransport.tcp): //http
@@ -362,7 +362,7 @@ public partial class CoreConfigSingboxService
{
transport.type = nameof(ETransport.http);
transport.host = node.RequestHost.IsNullOrEmpty() ? null : Utils.String2List(node.RequestHost);
transport.path = node.Path.IsNullOrEmpty() ? null : node.Path;
transport.path = node.Path.NullIfEmpty();
}
break;
@@ -396,7 +396,7 @@ public partial class CoreConfigSingboxService
}
}
transport.path = wsPath.IsNullOrEmpty() ? null : wsPath;
transport.path = wsPath.NullIfEmpty();
if (node.RequestHost.IsNotEmpty())
{
transport.headers = new()
@@ -408,8 +408,8 @@ public partial class CoreConfigSingboxService
case nameof(ETransport.httpupgrade):
transport.type = nameof(ETransport.httpupgrade);
transport.path = node.Path.IsNullOrEmpty() ? null : node.Path;
transport.host = node.RequestHost.IsNullOrEmpty() ? null : node.RequestHost;
transport.path = node.Path.NullIfEmpty();
transport.host = node.RequestHost.NullIfEmpty();
break;
@@ -113,7 +113,7 @@ public partial class CoreConfigSingboxService
clash_mode = ERuleMode.Global.ToString()
});
var domainStrategy = _config.RoutingBasicItem.DomainStrategy4Singbox.IsNullOrEmpty() ? null : _config.RoutingBasicItem.DomainStrategy4Singbox;
var domainStrategy = _config.RoutingBasicItem.DomainStrategy4Singbox.NullIfEmpty();
var defaultRouting = await ConfigHandler.GetDefaultRouting(_config);
if (defaultRouting.DomainStrategy4Singbox.IsNotEmpty())
{
@@ -272,7 +272,9 @@ public partial class CoreConfigV2rayService
{
allowInsecure = Utils.ToBool(node.AllowInsecure.IsNullOrEmpty() ? _config.CoreBasicItem.DefAllowInsecure.ToString().ToLower() : node.AllowInsecure),
alpn = node.GetAlpn(),
fingerprint = node.Fingerprint.IsNullOrEmpty() ? _config.CoreBasicItem.DefFingerprint : node.Fingerprint
fingerprint = node.Fingerprint.IsNullOrEmpty() ? _config.CoreBasicItem.DefFingerprint : node.Fingerprint,
echConfigList = node.EchConfigList.NullIfEmpty(),
echForceQuery = node.EchForceQuery.NullIfEmpty()
};
if (sni.IsNotEmpty())
{
@@ -340,7 +342,7 @@ public partial class CoreConfigV2rayService
kcpSettings.header = new Header4Ray
{
type = node.HeaderType,
domain = host.IsNullOrEmpty() ? null : host
domain = host.NullIfEmpty()
};
if (path.IsNotEmpty())
{
@@ -450,7 +452,7 @@ public partial class CoreConfigV2rayService
case nameof(ETransport.grpc):
GrpcSettings4Ray grpcSettings = new()
{
authority = host.IsNullOrEmpty() ? null : host,
authority = host.NullIfEmpty(),
serviceName = path,
multiMode = node.HeaderType == Global.GrpcMultiMode,
idle_timeout = _config.GrpcItem.IdleTimeout,