diff --git a/v2rayN/Directory.Build.props b/v2rayN/Directory.Build.props index 6c744bb5..12693e1c 100644 --- a/v2rayN/Directory.Build.props +++ b/v2rayN/Directory.Build.props @@ -1,7 +1,7 @@ - 7.19.2 + 7.19.3 diff --git a/v2rayN/ServiceLib/Global.cs b/v2rayN/ServiceLib/Global.cs index 88a97398..903e4e8e 100644 --- a/v2rayN/ServiceLib/Global.cs +++ b/v2rayN/ServiceLib/Global.cs @@ -95,7 +95,7 @@ public class Global public const string PolicyGroupDefaultAllFilter = $"^(?!.*(?:{PolicyGroupExcludeKeywords})).*$"; - public static readonly List PolicyGroupDefaultFilterList = + public static readonly List PolicyGroupDefaultFilterList = [ // All nodes (exclude traffic/expiry info) PolicyGroupDefaultAllFilter, diff --git a/v2rayN/ServiceLib/Handler/Builder/CoreConfigContextBuilder.cs b/v2rayN/ServiceLib/Handler/Builder/CoreConfigContextBuilder.cs index 1cbfbf14..ddc98a1f 100644 --- a/v2rayN/ServiceLib/Handler/Builder/CoreConfigContextBuilder.cs +++ b/v2rayN/ServiceLib/Handler/Builder/CoreConfigContextBuilder.cs @@ -227,7 +227,7 @@ public class CoreConfigContextBuilder { var result = NodeValidatorResult.Empty(); - if (node.Subid.IsNullOrEmpty()) + if (node.Subid.IsNullOrEmpty() || node.ConfigType == EConfigType.Custom) { return (null, result); } diff --git a/v2rayN/ServiceLib/Handler/Builder/NodeValidator.cs b/v2rayN/ServiceLib/Handler/Builder/NodeValidator.cs index a6adf1c2..65110b2a 100644 --- a/v2rayN/ServiceLib/Handler/Builder/NodeValidator.cs +++ b/v2rayN/ServiceLib/Handler/Builder/NodeValidator.cs @@ -81,7 +81,9 @@ public class NodeValidator { var transportError = ValidateSingboxTransport(item.ConfigType, net); if (transportError != null) + { v.Error(transportError); + } if (!Global.SingboxSupportConfigType.Contains(item.ConfigType)) { diff --git a/v2rayN/ServiceLib/Handler/ConfigHandler.cs b/v2rayN/ServiceLib/Handler/ConfigHandler.cs index 3e16fc3e..d1704b80 100644 --- a/v2rayN/ServiceLib/Handler/ConfigHandler.cs +++ b/v2rayN/ServiceLib/Handler/ConfigHandler.cs @@ -723,8 +723,6 @@ public static class ConfigHandler profileItem.SetProtocolExtra(profileItem.GetProtocolExtra() with { SalamanderPass = profileItem.GetProtocolExtra().SalamanderPass?.TrimEx(), - UpMbps = profileItem.GetProtocolExtra().UpMbps is null or < 0 ? config.HysteriaItem.UpMbps : profileItem.GetProtocolExtra().UpMbps, - DownMbps = profileItem.GetProtocolExtra().DownMbps is null or < 0 ? config.HysteriaItem.DownMbps : profileItem.GetProtocolExtra().DownMbps, HopInterval = profileItem.GetProtocolExtra().HopInterval?.TrimEx(), }); @@ -1042,8 +1040,8 @@ public static class ConfigHandler if (profileItem.StreamSecurity.IsNotEmpty()) { - if (profileItem.StreamSecurity != Global.StreamSecurity - && profileItem.StreamSecurity != Global.StreamSecurityReality) + if (profileItem.StreamSecurity is not Global.StreamSecurity + and not Global.StreamSecurityReality) { profileItem.StreamSecurity = string.Empty; } diff --git a/v2rayN/ServiceLib/Models/ServerTestItem.cs b/v2rayN/ServiceLib/Models/ServerTestItem.cs index f1622a7c..bce76364 100644 --- a/v2rayN/ServiceLib/Models/ServerTestItem.cs +++ b/v2rayN/ServiceLib/Models/ServerTestItem.cs @@ -10,6 +10,6 @@ public class ServerTestItem public bool AllowTest { get; set; } public bool NeedAutoFillRemarks { get; set; } public int QueueNum { get; set; } - public required ProfileItem Profile { get; set; } + public ProfileItem Profile { get; set; } public ECoreType CoreType { get; set; } } diff --git a/v2rayN/ServiceLib/Models/V2rayConfig.cs b/v2rayN/ServiceLib/Models/V2rayConfig.cs index 2393d5fb..6d4eabcb 100644 --- a/v2rayN/ServiceLib/Models/V2rayConfig.cs +++ b/v2rayN/ServiceLib/Models/V2rayConfig.cs @@ -360,6 +360,7 @@ public class TlsSettings4Ray public bool? disableSystemRoot { get; set; } public string? echConfigList { get; set; } public string? echForceQuery { get; set; } + public Sockopt4Ray? echSockopt { get; set; } } public class CertificateSettings4Ray diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxDnsService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxDnsService.cs index afab27d9..f09d3ee9 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxDnsService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxDnsService.cs @@ -243,7 +243,6 @@ public partial class CoreConfigSingboxService if (Utils.IsIpv6(predefined)) { rule.answer = new List { $"*. IN AAAA {predefined}" }; - } else { diff --git a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/CoreConfigV2rayService.cs b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/CoreConfigV2rayService.cs index ca8eeb0d..545e713e 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/CoreConfigV2rayService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/CoreConfigV2rayService.cs @@ -316,16 +316,24 @@ public partial class CoreConfigV2rayService(CoreConfigContext context) SsMethod = Global.None, }); - foreach (var outbound in _coreConfig.outbounds.Where(outbound => outbound.streamSettings?.sockopt?.dialerProxy?.IsNullOrEmpty() ?? true)) + foreach (var outbound in _coreConfig.outbounds + .Where(o => o.streamSettings?.sockopt?.dialerProxy?.IsNullOrEmpty() ?? true)) { - outbound.streamSettings ??= new StreamSettings4Ray(); - outbound.streamSettings.sockopt ??= new Sockopt4Ray(); - outbound.streamSettings.sockopt.dialerProxy = "tun-project-ss"; + outbound.streamSettings ??= new(); + outbound.streamSettings.sockopt ??= new(); + outbound.streamSettings.sockopt.dialerProxy = "tun-protect-ss"; + } + // ech protected + foreach (var outbound in _coreConfig.outbounds + .Where(outbound => outbound.streamSettings?.tlsSettings?.echConfigList?.IsNullOrEmpty() == false)) + { + outbound.streamSettings!.tlsSettings!.echSockopt ??= new(); + outbound.streamSettings.tlsSettings.echSockopt.dialerProxy = "tun-protect-ss"; } _coreConfig.outbounds.Add(new CoreConfigV2rayService(context with { Node = protectNode, - }).BuildProxyOutbound("tun-project-ss")); + }).BuildProxyOutbound("tun-protect-ss")); _coreConfig.routing.rules ??= []; var hasBalancer = _coreConfig.routing.balancers is { Count: > 0 }; diff --git a/v2rayN/ServiceLib/Services/UpdateService.cs b/v2rayN/ServiceLib/Services/UpdateService.cs index d368108c..f9d9a5f8 100644 --- a/v2rayN/ServiceLib/Services/UpdateService.cs +++ b/v2rayN/ServiceLib/Services/UpdateService.cs @@ -363,44 +363,36 @@ public class UpdateService(Config config, Func updateFunc) var geoipFiles = new List(); var geoSiteFiles = new List(); - //Collect used files list + // Collect from routing rules var routingItems = await AppManager.Instance.RoutingItems(); foreach (var routing in routingItems) { var rules = JsonUtils.Deserialize>(routing.RuleSet); foreach (var item in rules ?? []) { - foreach (var ip in item.Ip ?? []) - { - var prefix = "geoip:"; - if (ip.StartsWith(prefix)) - { - geoipFiles.Add(ip.Substring(prefix.Length)); - } - } - - foreach (var domain in item.Domain ?? []) - { - var prefix = "geosite:"; - if (domain.StartsWith(prefix)) - { - geoSiteFiles.Add(domain.Substring(prefix.Length)); - } - } + AddPrefixedItems(item.Ip, "geoip:", geoipFiles); + AddPrefixedItems(item.Domain, "geosite:", geoSiteFiles); } } - //append dns items TODO - geoSiteFiles.Add("google"); - geoSiteFiles.Add("cn"); - geoSiteFiles.Add("geolocation-cn"); - geoSiteFiles.Add("category-ads-all"); + // Collect from DNS configuration + var dnsItem = await AppManager.Instance.GetDNSItem(ECoreType.sing_box); + if (dnsItem != null) + { + ExtractDnsRuleSets(dnsItem.NormalDNS, geoipFiles, geoSiteFiles); + ExtractDnsRuleSets(dnsItem.TunDNS, geoipFiles, geoSiteFiles); + } + // Append default items + geoSiteFiles.AddRange(["google", "cn", "geolocation-cn", "category-ads-all"]); + + // Download files var path = Utils.GetBinPath("srss"); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } + foreach (var item in geoipFiles.Distinct()) { await UpdateSrsFile("geoip", item); @@ -412,6 +404,63 @@ public class UpdateService(Config config, Func updateFunc) } } + private void AddPrefixedItems(List? items, string prefix, List output) + { + if (items == null) + { + return; + } + + foreach (var item in items) + { + if (item.StartsWith(prefix)) + { + output.Add(item.Substring(prefix.Length)); + } + } + } + + private void ExtractDnsRuleSets(string? dnsJson, List geoipFiles, List geoSiteFiles) + { + if (string.IsNullOrEmpty(dnsJson)) + { + return; + } + + try + { + var dns = JsonUtils.Deserialize(dnsJson); + if (dns?.rules != null) + { + foreach (var rule in dns.rules) + { + ExtractSrsRuleSets(rule, geoipFiles, geoSiteFiles); + } + } + } + catch { } + } + + private void ExtractSrsRuleSets(Rule4Sbox? rule, List geoipFiles, List geoSiteFiles) + { + if (rule == null) + { + return; + } + + AddPrefixedItems(rule.rule_set, "geosite-", geoSiteFiles); + AddPrefixedItems(rule.rule_set, "geoip-", geoipFiles); + + // Handle nested rules recursively + if (rule.rules != null) + { + foreach (var nestedRule in rule.rules) + { + ExtractSrsRuleSets(nestedRule, geoipFiles, geoSiteFiles); + } + } + } + private async Task UpdateSrsFile(string type, string srsName) { var srsUrl = string.IsNullOrEmpty(_config.ConstItem.SrsSourceUrl) diff --git a/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs b/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs index 86a807db..dce9c865 100644 --- a/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs @@ -27,10 +27,10 @@ public class AddServerViewModel : MyReactiveObject public string Ports { get; set; } [Reactive] - public int UpMbps { get; set; } + public int? UpMbps { get; set; } [Reactive] - public int DownMbps { get; set; } + public int? DownMbps { get; set; } [Reactive] public string HopInterval { get; set; } @@ -113,8 +113,8 @@ public class AddServerViewModel : MyReactiveObject AlterId = int.TryParse(protocolExtra?.AlterId, out var result) ? result : 0; Flow = protocolExtra?.Flow ?? string.Empty; SalamanderPass = protocolExtra?.SalamanderPass ?? string.Empty; - UpMbps = protocolExtra?.UpMbps ?? _config.HysteriaItem.UpMbps; - DownMbps = protocolExtra?.DownMbps ?? _config.HysteriaItem.DownMbps; + UpMbps = protocolExtra?.UpMbps; + DownMbps = protocolExtra?.DownMbps; HopInterval = protocolExtra?.HopInterval.IsNullOrEmpty() ?? true ? Global.Hysteria2DefaultHopInt.ToString() : protocolExtra.HopInterval; VmessSecurity = protocolExtra?.VmessSecurity?.IsNullOrEmpty() == false ? protocolExtra.VmessSecurity : Global.DefaultSecurity; VlessEncryption = protocolExtra?.VlessEncryption.IsNullOrEmpty() == false ? protocolExtra.VlessEncryption : Global.None; @@ -169,8 +169,8 @@ public class AddServerViewModel : MyReactiveObject AlterId = AlterId > 0 ? AlterId.ToString() : null, Flow = Flow.NullIfEmpty(), SalamanderPass = SalamanderPass.NullIfEmpty(), - UpMbps = UpMbps >= 0 ? UpMbps : null, - DownMbps = DownMbps >= 0 ? DownMbps : null, + UpMbps = UpMbps, + DownMbps = DownMbps, HopInterval = HopInterval.NullIfEmpty(), VmessSecurity = VmessSecurity.NullIfEmpty(), VlessEncryption = VlessEncryption.NullIfEmpty(), diff --git a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs index 8462a2c3..b5bfe71f 100644 --- a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs @@ -22,8 +22,8 @@ public class OptionSettingViewModel : MyReactiveObject [Reactive] public string defUserAgent { get; set; } [Reactive] public string mux4SboxProtocol { get; set; } [Reactive] public bool enableCacheFile4Sbox { get; set; } - [Reactive] public int hyUpMbps { get; set; } - [Reactive] public int hyDownMbps { get; set; } + [Reactive] public int? hyUpMbps { get; set; } + [Reactive] public int? hyDownMbps { get; set; } [Reactive] public bool enableFragment { get; set; } #endregion Core @@ -336,8 +336,8 @@ public class OptionSettingViewModel : MyReactiveObject _config.CoreBasicItem.DefUserAgent = defUserAgent; _config.Mux4SboxItem.Protocol = mux4SboxProtocol; _config.CoreBasicItem.EnableCacheFile4Sbox = enableCacheFile4Sbox; - _config.HysteriaItem.UpMbps = hyUpMbps; - _config.HysteriaItem.DownMbps = hyDownMbps; + _config.HysteriaItem.UpMbps = hyUpMbps ?? 0; + _config.HysteriaItem.DownMbps = hyDownMbps ?? 0; _config.CoreBasicItem.EnableFragment = enableFragment; _config.GuiItem.AutoRun = AutoRun; diff --git a/v2rayN/v2rayN.Desktop/Views/ClashConnectionsView.axaml.cs b/v2rayN/v2rayN.Desktop/Views/ClashConnectionsView.axaml.cs index 23722ad0..4bf5237b 100644 --- a/v2rayN/v2rayN.Desktop/Views/ClashConnectionsView.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/ClashConnectionsView.axaml.cs @@ -8,9 +8,9 @@ public partial class ClashConnectionsView : ReactiveUserControl