Compare commits

...

4 commits

Author SHA1 Message Date
DHR60
77dbea9b6d
Merge c53d9c118a into 64c7fea2bc 2025-10-07 12:20:15 +00:00
2dust
c53d9c118a Use enum 2025-10-07 20:20:06 +08:00
2dust
64c7fea2bc Update Directory.Packages.props
Some checks are pending
release Linux / build (Release) (push) Waiting to run
release macOS / build (Release) (push) Waiting to run
release Windows desktop (Avalonia UI) / build (Release) (push) Waiting to run
release Windows / build (Release) (push) Waiting to run
2025-10-07 19:17:35 +08:00
DHR60
4301415b4c Add rule type selection to routing rules 2025-09-23 17:59:18 +08:00
12 changed files with 84 additions and 17 deletions

View file

@ -12,8 +12,8 @@
<PackageVersion Include="Avalonia.ReactiveUI" Version="11.3.7" /> <PackageVersion Include="Avalonia.ReactiveUI" Version="11.3.7" />
<PackageVersion Include="CliWrap" Version="3.9.0" /> <PackageVersion Include="CliWrap" Version="3.9.0" />
<PackageVersion Include="Downloader" Version="4.0.3" /> <PackageVersion Include="Downloader" Version="4.0.3" />
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.3.0" /> <PackageVersion Include="H.NotifyIcon.Wpf" Version="2.3.1" />
<PackageVersion Include="MaterialDesignThemes" Version="5.2.1" /> <PackageVersion Include="MaterialDesignThemes" Version="5.3.0" />
<PackageVersion Include="MessageBox.Avalonia" Version="3.2.0" /> <PackageVersion Include="MessageBox.Avalonia" Version="3.2.0" />
<PackageVersion Include="QRCoder" Version="1.6.0" /> <PackageVersion Include="QRCoder" Version="1.6.0" />
<PackageVersion Include="ReactiveUI" Version="20.4.1" /> <PackageVersion Include="ReactiveUI" Version="20.4.1" />

View file

@ -0,0 +1,8 @@
namespace ServiceLib.Enums;
public enum ERuleType
{
ALL = 0,
Routing = 1,
DNS = 2,
}

View file

@ -15,4 +15,5 @@ public class RulesItem
public List<string>? Process { get; set; } public List<string>? Process { get; set; }
public bool Enabled { get; set; } = true; public bool Enabled { get; set; } = true;
public string? Remarks { get; set; } public string? Remarks { get; set; }
public ERuleType? RuleType { get; set; }
} }

View file

@ -253,6 +253,11 @@ public partial class CoreConfigSingboxService
continue; continue;
} }
if (item.RuleType == ERuleType.Routing)
{
continue;
}
var rule = new Rule4Sbox(); var rule = new Rule4Sbox();
var validDomains = item.Domain.Count(it => ParseV2Domain(it, rule)); var validDomains = item.Domain.Count(it => ParseV2Domain(it, rule));
if (validDomains <= 0) if (validDomains <= 0)

View file

@ -136,16 +136,24 @@ public partial class CoreConfigSingboxService
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet); var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
foreach (var item1 in rules ?? []) foreach (var item1 in rules ?? [])
{ {
if (item1.Enabled) if (!item1.Enabled)
{ {
continue;
}
if (item1.RuleType == ERuleType.DNS)
{
continue;
}
await GenRoutingUserRule(item1, singboxConfig); await GenRoutingUserRule(item1, singboxConfig);
if (item1.Ip != null && item1.Ip.Count > 0)
if (item1.Ip?.Count > 0)
{ {
ipRules.Add(item1); ipRules.Add(item1);
} }
} }
} }
}
if (_config.RoutingBasicItem.DomainStrategy == Global.IPIfNonMatch) if (_config.RoutingBasicItem.DomainStrategy == Global.IPIfNonMatch)
{ {
singboxConfig.route.rules.Add(resolveRule); singboxConfig.route.rules.Add(resolveRule);

View file

@ -142,6 +142,11 @@ public partial class CoreConfigV2rayService
continue; continue;
} }
if (item.RuleType == ERuleType.Routing)
{
continue;
}
foreach (var domain in item.Domain) foreach (var domain in item.Domain)
{ {
if (domain.StartsWith('#')) if (domain.StartsWith('#'))

View file

@ -20,15 +20,22 @@ public partial class CoreConfigV2rayService
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet); var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
foreach (var item in rules) foreach (var item in rules)
{ {
if (item.Enabled) if (!item.Enabled)
{ {
continue;
}
if (item.RuleType == ERuleType.DNS)
{
continue;
}
var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item)); var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item));
await GenRoutingUserRule(item2, v2rayConfig); await GenRoutingUserRule(item2, v2rayConfig);
} }
} }
} }
} }
}
catch (Exception ex) catch (Exception ex)
{ {
Logging.SaveLog(_tag, ex); Logging.SaveLog(_tag, ex);

View file

@ -21,6 +21,9 @@ public class RoutingRuleDetailsViewModel : MyReactiveObject
[Reactive] [Reactive]
public string Process { get; set; } public string Process { get; set; }
[Reactive]
public string? RuleType { get; set; }
[Reactive] [Reactive]
public bool AutoSort { get; set; } public bool AutoSort { get; set; }
@ -51,6 +54,7 @@ public class RoutingRuleDetailsViewModel : MyReactiveObject
Domain = Utils.List2String(SelectedSource.Domain, true); Domain = Utils.List2String(SelectedSource.Domain, true);
IP = Utils.List2String(SelectedSource.Ip, true); IP = Utils.List2String(SelectedSource.Ip, true);
Process = Utils.List2String(SelectedSource.Process, true); Process = Utils.List2String(SelectedSource.Process, true);
RuleType = SelectedSource.RuleType?.ToString();
} }
private async Task SaveRulesAsync() private async Task SaveRulesAsync()
@ -73,6 +77,7 @@ public class RoutingRuleDetailsViewModel : MyReactiveObject
} }
SelectedSource.Protocol = ProtocolItems?.ToList(); SelectedSource.Protocol = ProtocolItems?.ToList();
SelectedSource.InboundTag = InboundTagItems?.ToList(); SelectedSource.InboundTag = InboundTagItems?.ToList();
SelectedSource.RuleType = RuleType.IsNullOrEmpty() ? null : (ERuleType)Enum.Parse(typeof(ERuleType), RuleType);
var hasRule = SelectedSource.Domain?.Count > 0 var hasRule = SelectedSource.Domain?.Count > 0
|| SelectedSource.Ip?.Count > 0 || SelectedSource.Ip?.Count > 0

View file

@ -32,13 +32,25 @@
Width="300" Width="300"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" /> HorizontalAlignment="Left" />
<ToggleSwitch <StackPanel
x:Name="togEnabled"
Grid.Row="0" Grid.Row="0"
Grid.Column="2" Grid.Column="2"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Center"
Orientation="Horizontal">
<ToggleSwitch
x:Name="togEnabled"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center" /> VerticalAlignment="Center" />
<ComboBox
x:Name="cmbRuleType"
Width="300"
Margin="{StaticResource Margin4}"
MaxDropDownHeight="1000" />
</StackPanel>
<TextBlock <TextBlock
Grid.Row="1" Grid.Row="1"

View file

@ -28,6 +28,7 @@ public partial class RoutingRuleDetailsWindow : WindowBase<RoutingRuleDetailsVie
clbProtocol.ItemsSource = Global.RuleProtocols; clbProtocol.ItemsSource = Global.RuleProtocols;
clbInboundTag.ItemsSource = Global.InboundTags; clbInboundTag.ItemsSource = Global.InboundTags;
cmbNetwork.ItemsSource = Global.RuleNetworks; cmbNetwork.ItemsSource = Global.RuleNetworks;
cmbRuleType.ItemsSource = Utils.GetEnumNames<ERuleType>();
if (!rulesItem.Id.IsNullOrEmpty()) if (!rulesItem.Id.IsNullOrEmpty())
{ {
@ -53,6 +54,7 @@ public partial class RoutingRuleDetailsWindow : WindowBase<RoutingRuleDetailsVie
this.Bind(ViewModel, vm => vm.IP, v => v.txtIP.Text).DisposeWith(disposables); 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.Process, v => v.txtProcess.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.AutoSort, v => v.chkAutoSort.IsChecked).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); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
}); });

View file

@ -48,13 +48,25 @@
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" /> Style="{StaticResource DefTextBox}" />
<ToggleButton <StackPanel
x:Name="togEnabled"
Grid.Row="0" Grid.Row="0"
Grid.Column="2" Grid.Column="2"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Center"
Orientation="Horizontal">
<ToggleButton
x:Name="togEnabled"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center" /> VerticalAlignment="Center" />
<ComboBox
x:Name="cmbRuleType"
Width="200"
Margin="{StaticResource Margin4}"
MaxDropDownHeight="1000"
Style="{StaticResource DefComboBox}" />
</StackPanel>
<TextBlock <TextBlock
Grid.Row="1" Grid.Row="1"

View file

@ -21,6 +21,7 @@ public partial class RoutingRuleDetailsWindow
clbProtocol.ItemsSource = Global.RuleProtocols; clbProtocol.ItemsSource = Global.RuleProtocols;
clbInboundTag.ItemsSource = Global.InboundTags; clbInboundTag.ItemsSource = Global.InboundTags;
cmbNetwork.ItemsSource = Global.RuleNetworks; cmbNetwork.ItemsSource = Global.RuleNetworks;
cmbRuleType.ItemsSource = Utils.GetEnumNames<ERuleType>();
if (!rulesItem.Id.IsNullOrEmpty()) 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.IP, v => v.txtIP.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Process, v => v.txtProcess.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.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); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
}); });