From 31b5b4ca0cd540bddd78ff950ea4c272fb1500c4 Mon Sep 17 00:00:00 2001 From: DHR60 Date: Wed, 8 Oct 2025 10:40:26 +0800 Subject: [PATCH] Add rule type selection to routing rules (#8007) * Add rule type selection to routing rules * Use enum --------- Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com> --- v2rayN/ServiceLib/Enums/ERuleType.cs | 8 ++++++++ v2rayN/ServiceLib/Models/RulesItem.cs | 1 + .../CoreConfig/Singbox/SingboxDnsService.cs | 5 +++++ .../Singbox/SingboxRoutingService.cs | 20 +++++++++++++------ .../CoreConfig/V2ray/V2rayDnsService.cs | 5 +++++ .../CoreConfig/V2ray/V2rayRoutingService.cs | 13 +++++++++--- .../ViewModels/RoutingRuleDetailsViewModel.cs | 5 +++++ .../Views/RoutingRuleDetailsWindow.axaml | 18 ++++++++++++++--- .../Views/RoutingRuleDetailsWindow.axaml.cs | 2 ++ .../Views/RoutingRuleDetailsWindow.xaml | 18 ++++++++++++++--- .../Views/RoutingRuleDetailsWindow.xaml.cs | 2 ++ 11 files changed, 82 insertions(+), 15 deletions(-) create mode 100644 v2rayN/ServiceLib/Enums/ERuleType.cs diff --git a/v2rayN/ServiceLib/Enums/ERuleType.cs b/v2rayN/ServiceLib/Enums/ERuleType.cs new file mode 100644 index 00000000..7455bf2a --- /dev/null +++ b/v2rayN/ServiceLib/Enums/ERuleType.cs @@ -0,0 +1,8 @@ +namespace ServiceLib.Enums; + +public enum ERuleType +{ + ALL = 0, + Routing = 1, + DNS = 2, +} diff --git a/v2rayN/ServiceLib/Models/RulesItem.cs b/v2rayN/ServiceLib/Models/RulesItem.cs index 2aedae08..5a5cf529 100644 --- a/v2rayN/ServiceLib/Models/RulesItem.cs +++ b/v2rayN/ServiceLib/Models/RulesItem.cs @@ -15,4 +15,5 @@ public class RulesItem public List? Process { get; set; } public bool Enabled { get; set; } = true; public string? Remarks { get; set; } + public ERuleType? RuleType { get; set; } } diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxDnsService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxDnsService.cs index 10c82eed..ba5560f0 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxDnsService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxDnsService.cs @@ -253,6 +253,11 @@ public partial class CoreConfigSingboxService continue; } + if (item.RuleType == ERuleType.Routing) + { + continue; + } + var rule = new Rule4Sbox(); var validDomains = item.Domain.Count(it => ParseV2Domain(it, rule)); if (validDomains <= 0) diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs index 3994e21b..ea0fb073 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs @@ -136,13 +136,21 @@ public partial class CoreConfigSingboxService var rules = JsonUtils.Deserialize>(routing.RuleSet); foreach (var item1 in rules ?? []) { - if (item1.Enabled) + if (!item1.Enabled) { - await GenRoutingUserRule(item1, singboxConfig); - if (item1.Ip != null && item1.Ip.Count > 0) - { - ipRules.Add(item1); - } + continue; + } + + if (item1.RuleType == ERuleType.DNS) + { + continue; + } + + await GenRoutingUserRule(item1, singboxConfig); + + if (item1.Ip?.Count > 0) + { + ipRules.Add(item1); } } } diff --git a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayDnsService.cs b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayDnsService.cs index 744286d4..59525135 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayDnsService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayDnsService.cs @@ -142,6 +142,11 @@ public partial class CoreConfigV2rayService continue; } + if (item.RuleType == ERuleType.Routing) + { + continue; + } + foreach (var domain in item.Domain) { if (domain.StartsWith('#')) diff --git a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayRoutingService.cs b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayRoutingService.cs index e4a67410..d2fb2b62 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayRoutingService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayRoutingService.cs @@ -20,11 +20,18 @@ public partial class CoreConfigV2rayService var rules = JsonUtils.Deserialize>(routing.RuleSet); foreach (var item in rules) { - if (item.Enabled) + if (!item.Enabled) { - var item2 = JsonUtils.Deserialize(JsonUtils.Serialize(item)); - await GenRoutingUserRule(item2, v2rayConfig); + continue; } + + if (item.RuleType == ERuleType.DNS) + { + continue; + } + + var item2 = JsonUtils.Deserialize(JsonUtils.Serialize(item)); + await GenRoutingUserRule(item2, v2rayConfig); } } } diff --git a/v2rayN/ServiceLib/ViewModels/RoutingRuleDetailsViewModel.cs b/v2rayN/ServiceLib/ViewModels/RoutingRuleDetailsViewModel.cs index 758aa8fe..36b1babf 100644 --- a/v2rayN/ServiceLib/ViewModels/RoutingRuleDetailsViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/RoutingRuleDetailsViewModel.cs @@ -21,6 +21,9 @@ public class RoutingRuleDetailsViewModel : MyReactiveObject [Reactive] public string Process { get; set; } + [Reactive] + public string? RuleType { get; set; } + [Reactive] public bool AutoSort { get; set; } @@ -51,6 +54,7 @@ public class RoutingRuleDetailsViewModel : MyReactiveObject Domain = Utils.List2String(SelectedSource.Domain, true); IP = Utils.List2String(SelectedSource.Ip, true); Process = Utils.List2String(SelectedSource.Process, true); + RuleType = SelectedSource.RuleType?.ToString(); } private async Task SaveRulesAsync() @@ -73,6 +77,7 @@ public class RoutingRuleDetailsViewModel : MyReactiveObject } SelectedSource.Protocol = ProtocolItems?.ToList(); SelectedSource.InboundTag = InboundTagItems?.ToList(); + SelectedSource.RuleType = RuleType.IsNullOrEmpty() ? null : (ERuleType)Enum.Parse(typeof(ERuleType), RuleType); var hasRule = SelectedSource.Domain?.Count > 0 || SelectedSource.Ip?.Count > 0 diff --git a/v2rayN/v2rayN.Desktop/Views/RoutingRuleDetailsWindow.axaml b/v2rayN/v2rayN.Desktop/Views/RoutingRuleDetailsWindow.axaml index dd0ac331..61c561a1 100644 --- a/v2rayN/v2rayN.Desktop/Views/RoutingRuleDetailsWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/RoutingRuleDetailsWindow.axaml @@ -32,13 +32,25 @@ Width="300" Margin="{StaticResource Margin4}" HorizontalAlignment="Left" /> - + VerticalAlignment="Center" + Orientation="Horizontal"> + + + + (); if (!rulesItem.Id.IsNullOrEmpty()) { @@ -53,6 +54,7 @@ public partial class RoutingRuleDetailsWindow : WindowBase vm.IP, v => v.txtIP.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Process, v => v.txtProcess.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.AutoSort, v => v.chkAutoSort.IsChecked).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.RuleType, v => v.cmbRuleType.SelectedValue).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); }); diff --git a/v2rayN/v2rayN/Views/RoutingRuleDetailsWindow.xaml b/v2rayN/v2rayN/Views/RoutingRuleDetailsWindow.xaml index f24a38d7..af7f0a50 100644 --- a/v2rayN/v2rayN/Views/RoutingRuleDetailsWindow.xaml +++ b/v2rayN/v2rayN/Views/RoutingRuleDetailsWindow.xaml @@ -48,13 +48,25 @@ Margin="{StaticResource Margin4}" HorizontalAlignment="Left" Style="{StaticResource DefTextBox}" /> - + VerticalAlignment="Center" + Orientation="Horizontal"> + + + (); if (!rulesItem.Id.IsNullOrEmpty()) { @@ -45,6 +46,7 @@ public partial class RoutingRuleDetailsWindow this.Bind(ViewModel, vm => vm.IP, v => v.txtIP.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Process, v => v.txtProcess.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.AutoSort, v => v.chkAutoSort.IsChecked).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.RuleType, v => v.cmbRuleType.Text).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); });