The outbound tag of the route rule can enter a config remarks

https://github.com/2dust/v2rayN/issues/7537
pull/7579/head
2dust 2025-07-13 20:25:53 +08:00
parent 916055d8bd
commit e21c0b4d62
13 changed files with 160 additions and 59 deletions

View File

@ -2724,6 +2724,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Can fill in the configuration remarks, please make sure it exist and are unique 的本地化字符串。
/// </summary>
public static string TbRuleOutboundTagTip {
get {
return ResourceManager.GetString("TbRuleOutboundTagTip", resourceCulture);
}
}
/// <summary>
/// 查找类似 Encryption method (security) 的本地化字符串。
/// </summary>

View File

@ -1392,4 +1392,7 @@
<data name="TbSettingsIPAPIUrl" xml:space="preserve">
<value>URL آزمایش اطلاعات اتصال فعلی</value>
</data>
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
</data>
</root>

View File

@ -1392,4 +1392,7 @@
<data name="TbSettingsIPAPIUrl" xml:space="preserve">
<value>Current connection info test URL</value>
</data>
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
</data>
</root>

View File

@ -1392,4 +1392,7 @@
<data name="TbSettingsIPAPIUrl" xml:space="preserve">
<value>Current connection info test URL</value>
</data>
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
</data>
</root>

View File

@ -1392,4 +1392,7 @@
<data name="TbSettingsIPAPIUrl" xml:space="preserve">
<value>URL для тестирования текущего соединения</value>
</data>
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
</data>
</root>

View File

@ -1389,4 +1389,7 @@
<data name="TbSettingsIPAPIUrl" xml:space="preserve">
<value>当前连接信息测试地址</value>
</data>
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>可以填写配置文件别名,请确保存在并唯一</value>
</data>
</root>

View File

@ -1389,4 +1389,7 @@
<data name="TbSettingsIPAPIUrl" xml:space="preserve">
<value>目前連接資訊測試地址</value>
</data>
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>可以填寫設定檔別名,請確保存在並唯一</value>
</data>
</root>

View File

@ -1166,7 +1166,7 @@ public class CoreConfigSingboxService
{
if (item.Enabled)
{
await GenRoutingUserRule(item, singboxConfig.route.rules);
await GenRoutingUserRule(item, singboxConfig);
}
}
}
@ -1206,7 +1206,7 @@ public class CoreConfigSingboxService
lstDirectExe = new List<string>(directExeSet);
}
private async Task<int> GenRoutingUserRule(RulesItem item, List<Rule4Sbox> rules)
private async Task<int> GenRoutingUserRule(RulesItem item, SingboxConfig singboxConfig)
{
try
{
@ -1214,6 +1214,8 @@ public class CoreConfigSingboxService
{
return 0;
}
item.OutboundTag = await GenRoutingUserRuleOutbound(item.OutboundTag, singboxConfig);
var rules = singboxConfig.route.rules;
var rule = new Rule4Sbox()
{
@ -1365,6 +1367,29 @@ public class CoreConfigSingboxService
return true;
}
private async Task<string?> GenRoutingUserRuleOutbound(string outboundTag, SingboxConfig singboxConfig)
{
if (outboundTag is Global.ProxyTag or Global.ProxyTag or Global.BlockTag)
{
return outboundTag;
}
var node = await AppHandler.Instance.GetProfileItemViaRemarks(outboundTag);
if (node == null
|| node.ConfigType == EConfigType.Custom)
{
return Global.ProxyTag;
}
var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
await GenOutbound(node, outbound);
outbound.tag = Global.ProxyTag + node.IndexId.ToString();
singboxConfig.outbounds.Add(outbound);
return outbound.tag;
}
private async Task<int> GenDns(ProfileItem? node, SingboxConfig singboxConfig)
{
try

View File

@ -54,12 +54,12 @@ public class CoreConfigV2rayService
await GenInbounds(v2rayConfig);
await GenRouting(v2rayConfig);
await GenOutbound(node, v2rayConfig.outbounds.First());
await GenMoreOutbounds(node, v2rayConfig);
await GenRouting(v2rayConfig);
await GenDns(node, v2rayConfig);
await GenStatistic(v2rayConfig);
@ -556,6 +556,8 @@ public class CoreConfigV2rayService
{
return 0;
}
rule.outboundTag = await GenRoutingUserRuleOutbound(rule.outboundTag, v2rayConfig);
if (rule.port.IsNullOrEmpty())
{
rule.port = null;
@ -627,6 +629,31 @@ public class CoreConfigV2rayService
return await Task.FromResult(0);
}
private async Task<string?> GenRoutingUserRuleOutbound(string outboundTag, V2rayConfig v2rayConfig)
{
if (outboundTag is Global.ProxyTag or Global.ProxyTag or Global.BlockTag)
{
return outboundTag;
}
var node = await AppHandler.Instance.GetProfileItemViaRemarks(outboundTag);
if (node == null
|| node.ConfigType == EConfigType.Custom
|| node.ConfigType == EConfigType.Hysteria2
|| node.ConfigType == EConfigType.TUIC)
{
return Global.ProxyTag;
}
var txtOutbound = EmbedUtils.GetEmbedText(Global.V2raySampleOutbound);
var outbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
await GenOutbound(node, outbound);
outbound.tag = Global.ProxyTag + node.IndexId.ToString();
v2rayConfig.outbounds.Add(outbound);
return outbound.tag;
}
private async Task<int> GenOutbound(ProfileItem node, Outbounds4Ray outbound)
{
try
@ -659,7 +686,7 @@ public class CoreConfigV2rayService
{
usersItem = vnextItem.users.First();
}
usersItem.id = node.Id;
usersItem.alterId = node.AlterId;
usersItem.email = Global.UserEMail;
@ -1318,7 +1345,7 @@ public class CoreConfigV2rayService
//Previous proxy
var prevNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.PrevProfile);
string? prevOutboundTag = null;
string? prevOutboundTag = null;
if (prevNode is not null
&& prevNode.ConfigType != EConfigType.Custom
&& prevNode.ConfigType != EConfigType.Hysteria2

View File

@ -2,6 +2,7 @@
x:Class="v2rayN.Desktop.Views.RoutingRuleDetailsWindow"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ctrls="clr-namespace:v2rayN.Desktop.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
@ -22,86 +23,95 @@
<TextBlock
Grid.Row="0"
Grid.Column="0"
VerticalAlignment="Center"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.LvRemarks}" />
<TextBox
x:Name="txtRemarks"
Grid.Row="0"
Grid.Column="1"
Width="200"
HorizontalAlignment="Left"
Margin="{StaticResource Margin4}" />
Width="300"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
<ToggleSwitch
x:Name="togEnabled"
Grid.Row="0"
Grid.Column="2"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
Margin="{StaticResource Margin4}" />
VerticalAlignment="Center" />
<TextBlock
Grid.Row="1"
Grid.Column="0"
VerticalAlignment="Center"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="outboundTag" />
<ComboBox
x:Name="cmbOutboundTag"
<ctrls:AutoCompleteBox
Name="cmbOutboundTag"
Grid.Row="1"
Grid.Column="1"
Width="200"
Width="300"
Margin="{StaticResource Margin4}"
MaxDropDownHeight="1000" />
Text="{Binding SelectedSource.OutboundTag, Mode=TwoWay}" />
<TextBlock
Grid.Row="1"
Grid.Column="2"
HorizontalAlignment="Left"
Margin="{StaticResource Margin4}"
Text="{x:Static resx:ResUI.TbRuleMatchingTips}" />
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbRuleOutboundTagTip}" />
<TextBlock
Grid.Row="2"
Grid.Column="0"
VerticalAlignment="Center"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="port" />
<TextBox
x:Name="txtPort"
Grid.Row="2"
Grid.Column="1"
Width="200"
HorizontalAlignment="Left"
Margin="{StaticResource Margin4}" />
Width="300"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="2"
Grid.Column="2"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="{StaticResource Margin4}">
Text="{x:Static resx:ResUI.TbRuleMatchingTips}" />
<TextBlock
Grid.Row="3"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="protocol" />
<ListBox
x:Name="clbProtocol"
Grid.Row="3"
Grid.Column="1"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
SelectionMode="Multiple,Toggle"
Theme="{DynamicResource CardCheckGroupListBox}" />
<TextBlock
Grid.Row="3"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center">
<HyperlinkButton Classes="WithIcon" Click="linkRuleobjectDoc_Click">
<TextBlock Text="{x:Static resx:ResUI.TbRuleobjectDoc}" />
</HyperlinkButton>
</TextBlock>
<TextBlock
Grid.Row="3"
Grid.Column="0"
VerticalAlignment="Center"
Margin="{StaticResource Margin4}"
Text="protocol" />
<ListBox
x:Name="clbProtocol"
Grid.Row="3"
Grid.Column="1"
HorizontalAlignment="Left"
Margin="{StaticResource Margin4}"
SelectionMode="Multiple,Toggle"
Theme="{DynamicResource CardCheckGroupListBox}" />
<TextBlock
Grid.Row="4"
Grid.Column="0"
VerticalAlignment="Center"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="inboundTag" />
<ListBox
x:Name="clbInboundTag"
@ -113,35 +123,36 @@
<TextBlock
Grid.Row="4"
Grid.Column="2"
HorizontalAlignment="Left"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbRoutingInboundTagTips}" />
<TextBlock
Grid.Row="5"
Grid.Column="0"
VerticalAlignment="Center"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="network" />
<ComboBox
x:Name="cmbNetwork"
Grid.Row="5"
Grid.Column="1"
Width="200"
Width="300"
Margin="{StaticResource Margin4}"
MaxDropDownHeight="1000" />
<TextBlock
Grid.Row="5"
Grid.Column="2"
HorizontalAlignment="Left"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbRoutingTips}" />
</Grid>
<StackPanel
HorizontalAlignment="Right"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Right"
DockPanel.Dock="Bottom"
Orientation="Horizontal">
<StackPanel

View File

@ -23,9 +23,7 @@ public partial class RoutingRuleDetailsWindow : WindowBase<RoutingRuleDetailsVie
clbInboundTag.SelectionChanged += ClbInboundTag_SelectionChanged;
ViewModel = new RoutingRuleDetailsViewModel(rulesItem, UpdateViewHandler);
cmbOutboundTag.Items.Add(Global.ProxyTag);
cmbOutboundTag.Items.Add(Global.DirectTag);
cmbOutboundTag.Items.Add(Global.BlockTag);
cmbOutboundTag.ItemsSource = new List<string> { Global.ProxyTag, Global.DirectTag, Global.BlockTag };
Global.RuleProtocols.ForEach(it =>
{
clbProtocol.Items.Add(it);
@ -54,7 +52,7 @@ public partial class RoutingRuleDetailsWindow : WindowBase<RoutingRuleDetailsVie
this.WhenActivated(disposables =>
{
this.Bind(ViewModel, vm => vm.SelectedSource.Remarks, v => v.txtRemarks.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.OutboundTag, v => v.cmbOutboundTag.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.OutboundTag, v => v.cmbOutboundTag.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.Port, v => v.txtPort.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.Enabled, v => v.togEnabled.IsChecked).DisposeWith(disposables);
@ -80,7 +78,7 @@ public partial class RoutingRuleDetailsWindow : WindowBase<RoutingRuleDetailsVie
private void Window_Loaded(object? sender, RoutedEventArgs e)
{
cmbOutboundTag.Focus();
txtRemarks.Focus();
}
private void ClbProtocol_SelectionChanged(object? sender, SelectionChangedEventArgs e)

View File

@ -53,7 +53,8 @@
Grid.Row="0"
Grid.Column="2"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
HorizontalAlignment="Left"
VerticalAlignment="Center" />
<TextBlock
Grid.Row="1"
@ -68,6 +69,7 @@
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin4}"
IsEditable="True"
MaxDropDownHeight="1000"
Style="{StaticResource DefComboBox}" />
<TextBlock
@ -75,8 +77,9 @@
Grid.Column="2"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbRuleMatchingTips}" />
Text="{x:Static resx:ResUI.TbRuleOutboundTagTip}" />
<TextBlock
Grid.Row="2"
@ -97,13 +100,10 @@
Grid.Row="2"
Grid.Column="2"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}">
<Hyperlink Click="linkRuleobjectDoc_Click">
<TextBlock Text="{x:Static resx:ResUI.TbRuleobjectDoc}" />
<materialDesign:PackIcon Kind="Link" />
</Hyperlink>
</TextBlock>
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbRuleMatchingTips}" />
<TextBlock
Grid.Row="3"
@ -120,6 +120,17 @@
HorizontalAlignment="Left"
FontSize="{DynamicResource StdFontSize}"
Style="{StaticResource MaterialDesignFilterChipPrimaryListBox}" />
<TextBlock
Grid.Row="3"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}">
<Hyperlink Click="linkRuleobjectDoc_Click">
<TextBlock Text="{x:Static resx:ResUI.TbRuleobjectDoc}" />
<materialDesign:PackIcon Kind="Link" />
</Hyperlink>
</TextBlock>
<TextBlock
Grid.Row="4"
@ -140,6 +151,7 @@
Grid.Column="2"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbRoutingInboundTagTips}" />
@ -164,6 +176,7 @@
Grid.Column="2"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbRoutingTips}" />
</Grid>

View File

@ -74,7 +74,7 @@ public partial class RoutingRuleDetailsWindow
private void Window_Loaded(object sender, RoutedEventArgs e)
{
cmbOutboundTag.Focus();
txtRemarks.Focus();
}
private void ClbProtocol_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)