From 5e18567ce6d240420554ddb246752d6651068588 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Thu, 12 Mar 2026 14:21:21 +0800 Subject: [PATCH 1/6] Modify routing rule process name description --- v2rayN/ServiceLib/Resx/ResUI.Designer.cs | 2 +- v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx | 2 +- v2rayN/ServiceLib/Resx/ResUI.fr.resx | 4 ++-- v2rayN/ServiceLib/Resx/ResUI.hu.resx | 2 +- v2rayN/ServiceLib/Resx/ResUI.resx | 2 +- v2rayN/ServiceLib/Resx/ResUI.ru.resx | 2 +- v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx | 4 ++-- v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs index b00bec2d..5edca7bf 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs +++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs @@ -3376,7 +3376,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Process (Tun mode) 的本地化字符串。 + /// 查找类似 Process name: Linux/Windows/macOS (sing-box) 的本地化字符串。 /// public static string TbRoutingRuleProcess { get { diff --git a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx index 16836861..b3ffa77e 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx @@ -1027,7 +1027,7 @@ پروتکل sing-box Mux - Process (Tun mode) + Process name: Linux/Windows/macOS (sing-box) IP or IP CIDR diff --git a/v2rayN/ServiceLib/Resx/ResUI.fr.resx b/v2rayN/ServiceLib/Resx/ResUI.fr.resx index 253831ef..ad88aca5 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.fr.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.fr.resx @@ -1024,7 +1024,7 @@ Protocole de multiplexage Mux (sing-box) - Process (Tun mode) + Process name: Linux/Windows/macOS (sing-box) IP ou IP CIDR @@ -1668,4 +1668,4 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Group by Region - + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.hu.resx b/v2rayN/ServiceLib/Resx/ResUI.hu.resx index a29d8987..8c734066 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.hu.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.hu.resx @@ -1027,7 +1027,7 @@ sing-box Mux protokoll - Process (Tun mode) + Process name: Linux/Windows/macOS (sing-box) IP vagy IP CIDR diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx index 17416125..3fdd653a 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.resx @@ -1027,7 +1027,7 @@ sing-box Mux Protocol - Process (Tun mode) + Process name: Linux/Windows/macOS (sing-box) IP or IP CIDR diff --git a/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayN/ServiceLib/Resx/ResUI.ru.resx index d8a174d5..4aa03795 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.ru.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.ru.resx @@ -1027,7 +1027,7 @@ Протокол Mux для sing-box - Process (Tun mode) + Process name: Linux/Windows/macOS (sing-box) IP-адрес или сеть CIDR diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx index 3a4e4924..6aef06ec 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx @@ -1024,7 +1024,7 @@ sing-box Mux 多路复用协议 - 进程 (Tun 模式) + 进程名 Linux/Windows/macOS(sing-box) IP 或 IP CIDR @@ -1668,4 +1668,4 @@ 按地区分组 - \ No newline at end of file + diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx index c4125679..3ecedfb4 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx @@ -1024,7 +1024,7 @@ sing-box Mux 多路復用協定 - 行程 (Tun 模式) + 行程名 Linux/Windows/macOS(sing-box) IP 或 IP CIDR From 17ed26cd0626f2aab92342e118a73d73d86f5329 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Thu, 12 Mar 2026 14:56:01 +0800 Subject: [PATCH 2/6] Improve profile matching for Subscription, remove old option --- v2rayN/ServiceLib/Handler/ConfigHandler.cs | 87 +++++++++++++++++-- v2rayN/ServiceLib/Models/ConfigItems.cs | 1 - v2rayN/ServiceLib/Resx/ResUI.Designer.cs | 9 -- v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx | 3 - v2rayN/ServiceLib/Resx/ResUI.fr.resx | 3 - v2rayN/ServiceLib/Resx/ResUI.hu.resx | 3 - v2rayN/ServiceLib/Resx/ResUI.resx | 3 - v2rayN/ServiceLib/Resx/ResUI.ru.resx | 3 - v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx | 5 +- v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx | 3 - .../ViewModels/OptionSettingViewModel.cs | 3 - .../Views/OptionSettingWindow.axaml | 13 --- .../Views/OptionSettingWindow.axaml.cs | 1 - v2rayN/v2rayN/Views/OptionSettingWindow.xaml | 14 --- .../v2rayN/Views/OptionSettingWindow.xaml.cs | 1 - 15 files changed, 82 insertions(+), 70 deletions(-) diff --git a/v2rayN/ServiceLib/Handler/ConfigHandler.cs b/v2rayN/ServiceLib/Handler/ConfigHandler.cs index 3c587676..34758618 100644 --- a/v2rayN/ServiceLib/Handler/ConfigHandler.cs +++ b/v2rayN/ServiceLib/Handler/ConfigHandler.cs @@ -95,10 +95,7 @@ public static class ConfigHandler config.GuiItem ??= new(); config.MsgUIItem ??= new(); - config.UiItem ??= new UIItem() - { - EnableUpdateSubOnlyRemarksExist = true - }; + config.UiItem ??= new(); config.UiItem.MainColumnItem ??= new(); config.UiItem.WindowSizeItem ??= new(); @@ -1132,6 +1129,84 @@ public static class ConfigHandler } } + /// + /// Searches the specified collection for a profile item that matches the target profile item based on a series of + /// criteria. + /// + /// The method attempts to find a match by comparing the target's remarks, address, port, and + /// password in various combinations. The search is performed in order of specificity, starting with the most + /// detailed comparison. If no match is found at any stage, the method returns null. + /// An enumerable collection of profile items to search. This parameter can be null. + /// The profile item to match against items in the source collection. This parameter can be null. + /// A profile item from the source collection that matches the target item according to defined criteria; otherwise, + /// null if no match is found or if either parameter is null. + private static ProfileItem? FindMatchedProfileItem(IEnumerable? source, ProfileItem? target) + { + if (source == null || target == null) + { + return null; + } + + var matchedItem = source.FirstOrDefault(t => CompareProfileItem(t, target, true)); + if (matchedItem != null) + { + return matchedItem; + } + + if (target.Remarks.IsNotEmpty()) + { + matchedItem = source.FirstOrDefault(t => t.Remarks == target.Remarks); + if (matchedItem != null) + { + return matchedItem; + } + } + + if (target.Address.IsNotEmpty() && target.Port > 0 && target.Password.IsNotEmpty()) + { + matchedItem = source.FirstOrDefault(t => + IsSameText(t.Address, target.Address) && + t.Port == target.Port && + IsSameText(t.Password, target.Password)); + if (matchedItem != null) + { + return matchedItem; + } + } + + if (target.Address.IsNotEmpty() && target.Port > 0) + { + matchedItem = source.FirstOrDefault(t => + IsSameText(t.Address, target.Address) && + t.Port == target.Port); + if (matchedItem != null) + { + return matchedItem; + } + } + + if (target.Address.IsNotEmpty()) + { + matchedItem = source.FirstOrDefault(t => IsSameText(t.Address, target.Address)); + if (matchedItem != null) + { + return matchedItem; + } + } + + return null; + + static bool IsSameText(string? left, string? right) + { + if (left.IsNullOrEmpty() || right.IsNullOrEmpty()) + { + return false; + } + + return string.Equals(left.TrimEx(), right.TrimEx(), StringComparison.OrdinalIgnoreCase); + } + } + /// /// Remove a single server profile by its index ID /// Deletes the configuration file if it's a custom config @@ -1636,7 +1711,7 @@ public static class ConfigHandler if (activeProfile != null) { var lstSub = await AppManager.Instance.ProfileItems(subid); - var existItem = lstSub?.FirstOrDefault(t => config.UiItem.EnableUpdateSubOnlyRemarksExist ? t.Remarks == activeProfile.Remarks : CompareProfileItem(t, activeProfile, true)); + var existItem = FindMatchedProfileItem(lstSub, activeProfile); if (existItem != null) { await ConfigHandler.SetDefaultServerIndex(config, existItem.IndexId); @@ -1649,7 +1724,7 @@ public static class ConfigHandler var lstSub = await AppManager.Instance.ProfileItems(subid); foreach (var item in lstSub) { - var existItem = lstOriSub?.FirstOrDefault(t => config.UiItem.EnableUpdateSubOnlyRemarksExist ? t.Remarks == item.Remarks : CompareProfileItem(t, item, true)); + var existItem = FindMatchedProfileItem(lstOriSub, item); if (existItem != null) { await StatisticsManager.Instance.CloneServerStatItem(existItem.IndexId, item.IndexId); diff --git a/v2rayN/ServiceLib/Models/ConfigItems.cs b/v2rayN/ServiceLib/Models/ConfigItems.cs index 56e5fe47..741c21e5 100644 --- a/v2rayN/ServiceLib/Models/ConfigItems.cs +++ b/v2rayN/ServiceLib/Models/ConfigItems.cs @@ -87,7 +87,6 @@ public class MsgUIItem public class UIItem { public bool EnableAutoAdjustMainLvColWidth { get; set; } - public bool EnableUpdateSubOnlyRemarksExist { get; set; } public int MainGirdHeight1 { get; set; } public int MainGirdHeight2 { get; set; } public EGirdOrientation MainGirdOrientation { get; set; } = EGirdOrientation.Vertical; diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs index 5edca7bf..2111ba0e 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs +++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs @@ -3816,15 +3816,6 @@ namespace ServiceLib.Resx { } } - /// - /// 查找类似 Updating subscription, only determining if remarks exist 的本地化字符串。 - /// - public static string TbSettingsEnableUpdateSubOnlyRemarksExist { - get { - return ResourceManager.GetString("TbSettingsEnableUpdateSubOnlyRemarksExist", resourceCulture); - } - } - /// /// 查找类似 Exception 的本地化字符串。 /// diff --git a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx index b3ffa77e..b6ad108e 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx @@ -1098,9 +1098,6 @@ آدرس اینترنتی تست پینگ سرعت - - اشتراک در حال به‌روزرسانی، فقط مشخص کنید که ملاحظاتی آیا وجود دارد! - پایان تست... diff --git a/v2rayN/ServiceLib/Resx/ResUI.fr.resx b/v2rayN/ServiceLib/Resx/ResUI.fr.resx index ad88aca5..0dfe120f 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.fr.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.fr.resx @@ -1095,9 +1095,6 @@ Adresse de test de connexion réelle - - Ne vérifier l’existence de l’alias qu’à la maj. des abonnements - Arrêt du test en cours... diff --git a/v2rayN/ServiceLib/Resx/ResUI.hu.resx b/v2rayN/ServiceLib/Resx/ResUI.hu.resx index 8c734066..94d7e48f 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.hu.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.hu.resx @@ -1098,9 +1098,6 @@ Sebesség Ping Teszt URL - - Előfizetés frissítése, csak a megjegyzések létezésének ellenőrzése - Teszt megszakítása... diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx index 3fdd653a..dc24c384 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.resx @@ -1098,9 +1098,6 @@ Speed Ping Test URL - - Updating subscription, only determining if remarks exist - Test terminating... diff --git a/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayN/ServiceLib/Resx/ResUI.ru.resx index 4aa03795..28dc34d0 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.ru.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.ru.resx @@ -1098,9 +1098,6 @@ URL для быстрой проверки реальной задержки - - Обновляя подписку, проверять лишь наличие примечаний - Отмена тестирования... diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx index 6aef06ec..9f400c17 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx @@ -1095,9 +1095,6 @@ 真连接测试地址 - - 更新订阅时只判断别名已存在否 - 测试终止中... @@ -1668,4 +1665,4 @@ 按地区分组 - + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx index 3ecedfb4..b35b603f 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx @@ -1095,9 +1095,6 @@ 真連線測試位址 - - 更新訂閱時只判斷別名是否存在 - 測試終止中... diff --git a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs index b5bfe71f..d936c5df 100644 --- a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs @@ -47,7 +47,6 @@ public class OptionSettingViewModel : MyReactiveObject [Reactive] public bool KeepOlderDedupl { get; set; } [Reactive] public bool DisplayRealTimeSpeed { get; set; } [Reactive] public bool EnableAutoAdjustMainLvColWidth { get; set; } - [Reactive] public bool EnableUpdateSubOnlyRemarksExist { get; set; } [Reactive] public bool AutoHideStartup { get; set; } [Reactive] public bool Hide2TrayWhenClose { get; set; } [Reactive] public bool MacOSShowInDock { get; set; } @@ -180,7 +179,6 @@ public class OptionSettingViewModel : MyReactiveObject DisplayRealTimeSpeed = _config.GuiItem.DisplayRealTimeSpeed; KeepOlderDedupl = _config.GuiItem.KeepOlderDedupl; EnableAutoAdjustMainLvColWidth = _config.UiItem.EnableAutoAdjustMainLvColWidth; - EnableUpdateSubOnlyRemarksExist = _config.UiItem.EnableUpdateSubOnlyRemarksExist; AutoHideStartup = _config.UiItem.AutoHideStartup; Hide2TrayWhenClose = _config.UiItem.Hide2TrayWhenClose; MacOSShowInDock = _config.UiItem.MacOSShowInDock; @@ -345,7 +343,6 @@ public class OptionSettingViewModel : MyReactiveObject _config.GuiItem.DisplayRealTimeSpeed = DisplayRealTimeSpeed; _config.GuiItem.KeepOlderDedupl = KeepOlderDedupl; _config.UiItem.EnableAutoAdjustMainLvColWidth = EnableAutoAdjustMainLvColWidth; - _config.UiItem.EnableUpdateSubOnlyRemarksExist = EnableUpdateSubOnlyRemarksExist; _config.UiItem.AutoHideStartup = AutoHideStartup; _config.UiItem.Hide2TrayWhenClose = Hide2TrayWhenClose; _config.UiItem.MacOSShowInDock = MacOSShowInDock; diff --git a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml index cfcb48f0..8c4f1fcc 100644 --- a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml @@ -410,19 +410,6 @@ Margin="{StaticResource Margin4}" HorizontalAlignment="Left" /> - - - this.Bind(ViewModel, vm => vm.DisplayRealTimeSpeed, v => v.togDisplayRealTimeSpeed.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.KeepOlderDedupl, v => v.togKeepOlderDedupl.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableAutoAdjustMainLvColWidth, v => v.togEnableAutoAdjustMainLvColWidth.IsChecked).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.EnableUpdateSubOnlyRemarksExist, v => v.togEnableUpdateSubOnlyRemarksExist.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.AutoHideStartup, v => v.togAutoHideStartup.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Hide2TrayWhenClose, v => v.togHide2TrayWhenClose.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.MacOSShowInDock, v => v.togMacOSShowInDock.IsChecked).DisposeWith(disposables); diff --git a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml index 8f0d24d4..133b4134 100644 --- a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml +++ b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml @@ -630,20 +630,6 @@ Margin="{StaticResource Margin8}" HorizontalAlignment="Left" /> - - - vm.DisplayRealTimeSpeed, v => v.togDisplayRealTimeSpeed.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.KeepOlderDedupl, v => v.togKeepOlderDedupl.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableAutoAdjustMainLvColWidth, v => v.togEnableAutoAdjustMainLvColWidth.IsChecked).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.EnableUpdateSubOnlyRemarksExist, v => v.togEnableUpdateSubOnlyRemarksExist.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.AutoHideStartup, v => v.togAutoHideStartup.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableDragDropSort, v => v.togEnableDragDropSort.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.DoubleClick2Activate, v => v.togDoubleClick2Activate.IsChecked).DisposeWith(disposables); From 5cf3d6eff6c9385f60ecbb6a6b4ed14bf5386d7c Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Thu, 12 Mar 2026 17:19:30 +0800 Subject: [PATCH 3/6] Modify routing rule process name description --- v2rayN/ServiceLib/Resx/ResUI.Designer.cs | 2 +- v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx | 2 +- v2rayN/ServiceLib/Resx/ResUI.fr.resx | 2 +- v2rayN/ServiceLib/Resx/ResUI.hu.resx | 2 +- v2rayN/ServiceLib/Resx/ResUI.resx | 2 +- v2rayN/ServiceLib/Resx/ResUI.ru.resx | 2 +- v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx | 2 +- v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs index 2111ba0e..5a1ea759 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs +++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs @@ -3376,7 +3376,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Process name: Linux/Windows/macOS (sing-box) 的本地化字符串。 + /// 查找类似 Process (Linux/Windows) 的本地化字符串。 /// public static string TbRoutingRuleProcess { get { diff --git a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx index b6ad108e..1dd09e85 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx @@ -1027,7 +1027,7 @@ پروتکل sing-box Mux - Process name: Linux/Windows/macOS (sing-box) + Process (Linux/Windows) IP or IP CIDR diff --git a/v2rayN/ServiceLib/Resx/ResUI.fr.resx b/v2rayN/ServiceLib/Resx/ResUI.fr.resx index 0dfe120f..c873db43 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.fr.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.fr.resx @@ -1024,7 +1024,7 @@ Protocole de multiplexage Mux (sing-box) - Process name: Linux/Windows/macOS (sing-box) + Process (Linux/Windows) IP ou IP CIDR diff --git a/v2rayN/ServiceLib/Resx/ResUI.hu.resx b/v2rayN/ServiceLib/Resx/ResUI.hu.resx index 94d7e48f..f59a652b 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.hu.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.hu.resx @@ -1027,7 +1027,7 @@ sing-box Mux protokoll - Process name: Linux/Windows/macOS (sing-box) + Process (Linux/Windows) IP vagy IP CIDR diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx index dc24c384..f299a877 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.resx @@ -1027,7 +1027,7 @@ sing-box Mux Protocol - Process name: Linux/Windows/macOS (sing-box) + Process (Linux/Windows) IP or IP CIDR diff --git a/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayN/ServiceLib/Resx/ResUI.ru.resx index 28dc34d0..957e6052 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.ru.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.ru.resx @@ -1027,7 +1027,7 @@ Протокол Mux для sing-box - Process name: Linux/Windows/macOS (sing-box) + Process (Linux/Windows) IP-адрес или сеть CIDR diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx index 9f400c17..d655c30d 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx @@ -1024,7 +1024,7 @@ sing-box Mux 多路复用协议 - 进程名 Linux/Windows/macOS(sing-box) + 进程 (Linux/Windows) IP 或 IP CIDR diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx index b35b603f..65b1dbfb 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx @@ -1024,7 +1024,7 @@ sing-box Mux 多路復用協定 - 行程名 Linux/Windows/macOS(sing-box) + 行程 (Linux/Windows) IP 或 IP CIDR From 0f4031f4451df388634ac9d856acae37cc500f2f Mon Sep 17 00:00:00 2001 From: DHR60 Date: Thu, 12 Mar 2026 12:45:28 +0000 Subject: [PATCH 4/6] Update dep (#8926) --- v2rayN/Directory.Packages.props | 10 +++++----- .../ServiceLib/ViewModels/CheckUpdateViewModel.cs | 4 ++-- .../ViewModels/ClashConnectionsViewModel.cs | 2 +- .../ServiceLib/ViewModels/ClashProxiesViewModel.cs | 6 +++--- .../ServiceLib/ViewModels/MainWindowViewModel.cs | 12 ++++++------ v2rayN/ServiceLib/ViewModels/MsgViewModel.cs | 2 +- v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs | 10 +++++----- v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs | 14 +++++++------- v2rayN/v2rayN.Desktop/Program.cs | 2 +- .../Views/ClashConnectionsView.axaml.cs | 2 +- v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs | 8 ++++---- v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs | 4 ++-- v2rayN/v2rayN/App.xaml.cs | 5 +++++ v2rayN/v2rayN/GlobalUsings.cs | 1 + v2rayN/v2rayN/Views/ClashConnectionsView.xaml.cs | 2 +- v2rayN/v2rayN/Views/MainWindow.xaml.cs | 8 ++++---- v2rayN/v2rayN/Views/ProfilesView.xaml.cs | 4 ++-- v2rayN/v2rayN/v2rayN.csproj | 2 +- 18 files changed, 52 insertions(+), 46 deletions(-) diff --git a/v2rayN/Directory.Packages.props b/v2rayN/Directory.Packages.props index 0921f480..839b3384 100644 --- a/v2rayN/Directory.Packages.props +++ b/v2rayN/Directory.Packages.props @@ -9,18 +9,18 @@ - + - + - + - + - + diff --git a/v2rayN/ServiceLib/ViewModels/CheckUpdateViewModel.cs b/v2rayN/ServiceLib/ViewModels/CheckUpdateViewModel.cs index 7bcb36ea..dc31b41b 100644 --- a/v2rayN/ServiceLib/ViewModels/CheckUpdateViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/CheckUpdateViewModel.cs @@ -204,7 +204,7 @@ public class CheckUpdateViewModel : MyReactiveObject private async Task UpdateFinishedSub(bool blReload) { - RxApp.MainThreadScheduler.Schedule(blReload, (scheduler, blReload) => + RxSchedulers.MainThreadScheduler.Schedule(blReload, (scheduler, blReload) => { _ = UpdateFinishedResult(blReload); return Disposable.Empty; @@ -317,7 +317,7 @@ public class CheckUpdateViewModel : MyReactiveObject Remarks = msg, }; - RxApp.MainThreadScheduler.Schedule(item, (scheduler, model) => + RxSchedulers.MainThreadScheduler.Schedule(item, (scheduler, model) => { _ = UpdateViewResult(model); return Disposable.Empty; diff --git a/v2rayN/ServiceLib/ViewModels/ClashConnectionsViewModel.cs b/v2rayN/ServiceLib/ViewModels/ClashConnectionsViewModel.cs index 48500f3e..07de23f2 100644 --- a/v2rayN/ServiceLib/ViewModels/ClashConnectionsViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/ClashConnectionsViewModel.cs @@ -56,7 +56,7 @@ public class ClashConnectionsViewModel : MyReactiveObject return; } - RxApp.MainThreadScheduler.Schedule(ret?.connections, (scheduler, model) => + RxSchedulers.MainThreadScheduler.Schedule(ret?.connections, (scheduler, model) => { _ = RefreshConnections(model); return Disposable.Empty; diff --git a/v2rayN/ServiceLib/ViewModels/ClashProxiesViewModel.cs b/v2rayN/ServiceLib/ViewModels/ClashProxiesViewModel.cs index 6628e11d..6220719b 100644 --- a/v2rayN/ServiceLib/ViewModels/ClashProxiesViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/ClashProxiesViewModel.cs @@ -90,7 +90,7 @@ public class ClashProxiesViewModel : MyReactiveObject AppEvents.ProxiesReloadRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(async _ => await ProxiesReload()); #endregion AppEvents @@ -173,7 +173,7 @@ public class ClashProxiesViewModel : MyReactiveObject if (refreshUI) { - RxApp.MainThreadScheduler.Schedule(() => _ = RefreshProxyGroups()); + RxSchedulers.MainThreadScheduler.Schedule(() => _ = RefreshProxyGroups()); } } @@ -387,7 +387,7 @@ public class ClashProxiesViewModel : MyReactiveObject } var model = new SpeedTestResult() { IndexId = item.Name, Delay = result }; - RxApp.MainThreadScheduler.Schedule(model, (scheduler, model) => + RxSchedulers.MainThreadScheduler.Schedule(model, (scheduler, model) => { _ = ProxiesDelayTestResult(model); return Disposable.Empty; diff --git a/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs b/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs index 0bd0c588..ee92a0cd 100644 --- a/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs @@ -228,22 +228,22 @@ public class MainWindowViewModel : MyReactiveObject AppEvents.ReloadRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(async _ => await Reload()); AppEvents.AddServerViaScanRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(async _ => await AddServerViaScanAsync()); AppEvents.AddServerViaClipboardRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(async _ => await AddServerViaClipboardAsync(null)); AppEvents.SubscriptionsUpdateRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(async blProxy => await UpdateSubscriptionProcess("", blProxy)); #endregion AppEvents @@ -583,7 +583,7 @@ public class MainWindowViewModel : MyReactiveObject private void ReloadResult(bool showClashUI) { - RxApp.MainThreadScheduler.Schedule(() => + RxSchedulers.MainThreadScheduler.Schedule(() => { ShowClashUI = showClashUI; TabMainSelectedIndex = showClashUI ? TabMainSelectedIndex : 0; @@ -592,7 +592,7 @@ public class MainWindowViewModel : MyReactiveObject private void SetReloadEnabled(bool enabled) { - RxApp.MainThreadScheduler.Schedule(() => BlReloadEnabled = enabled); + RxSchedulers.MainThreadScheduler.Schedule(() => BlReloadEnabled = enabled); } private async Task LoadCore(CoreConfigContext? mainContext, CoreConfigContext? preContext) diff --git a/v2rayN/ServiceLib/ViewModels/MsgViewModel.cs b/v2rayN/ServiceLib/ViewModels/MsgViewModel.cs index 68bf71b5..06657a93 100644 --- a/v2rayN/ServiceLib/ViewModels/MsgViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/MsgViewModel.cs @@ -31,7 +31,7 @@ public class MsgViewModel : MyReactiveObject AppEvents.SendMsgViewRequested .AsObservable() - //.ObserveOn(RxApp.MainThreadScheduler) + //.ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(content => _ = AppendQueueMsg(content)); } diff --git a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs index edeec49e..7700d416 100644 --- a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs @@ -228,22 +228,22 @@ public class ProfilesViewModel : MyReactiveObject AppEvents.ProfilesRefreshRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(async _ => await RefreshServersBiz()); AppEvents.SubscriptionsRefreshRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(async _ => await RefreshSubscriptions()); AppEvents.DispatcherStatisticsRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(async result => await UpdateStatistics(result)); AppEvents.SetDefaultServerRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(async indexId => await SetDefaultServer(indexId)); #endregion AppEvents @@ -732,7 +732,7 @@ public class ProfilesViewModel : MyReactiveObject _speedtestService ??= new SpeedtestService(_config, async (SpeedTestResult result) => { - RxApp.MainThreadScheduler.Schedule(result, (scheduler, result) => + RxSchedulers.MainThreadScheduler.Schedule(result, (scheduler, result) => { _ = SetSpeedTestResult(result); return Disposable.Empty; diff --git a/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs b/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs index 9269851d..b8154c16 100644 --- a/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs @@ -200,27 +200,27 @@ public class StatusBarViewModel : MyReactiveObject AppEvents.DispatcherStatisticsRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(async result => await UpdateStatistics(result)); AppEvents.RoutingsMenuRefreshRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(async _ => await RefreshRoutingsMenu()); AppEvents.TestServerRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(async _ => await TestServerAvailability()); AppEvents.InboundDisplayRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(async _ => await InboundDisplayStatus()); AppEvents.SysProxyChangeRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(async result => await SetListenerType(result)); #endregion AppEvents @@ -243,7 +243,7 @@ public class StatusBarViewModel : MyReactiveObject { AppEvents.ProfilesRefreshRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(async _ => await RefreshServersBiz()); //.DisposeWith(_disposables); } } @@ -362,7 +362,7 @@ public class StatusBarViewModel : MyReactiveObject private async Task TestServerAvailabilitySub(string msg) { - RxApp.MainThreadScheduler.Schedule(msg, (scheduler, msg) => + RxSchedulers.MainThreadScheduler.Schedule(msg, (scheduler, msg) => { _ = TestServerAvailabilityResult(msg); return Disposable.Empty; diff --git a/v2rayN/v2rayN.Desktop/Program.cs b/v2rayN/v2rayN.Desktop/Program.cs index 70c43130..0ad036ec 100644 --- a/v2rayN/v2rayN.Desktop/Program.cs +++ b/v2rayN/v2rayN.Desktop/Program.cs @@ -59,7 +59,7 @@ internal class Program //.WithInterFont() .WithFontByDefault() .LogToTrace() - .UseReactiveUI(); + .UseReactiveUI(_ => { }); if (OperatingSystem.IsMacOS()) { diff --git a/v2rayN/v2rayN.Desktop/Views/ClashConnectionsView.axaml.cs b/v2rayN/v2rayN.Desktop/Views/ClashConnectionsView.axaml.cs index 4bf5237b..90690c1e 100644 --- a/v2rayN/v2rayN.Desktop/Views/ClashConnectionsView.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/ClashConnectionsView.axaml.cs @@ -28,7 +28,7 @@ public partial class ClashConnectionsView : ReactiveUserControl StorageUI()) .DisposeWith(disposables); }); diff --git a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs index 5c5ba9cb..7e96fad2 100644 --- a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs @@ -128,25 +128,25 @@ public partial class MainWindow : WindowBase AppEvents.SendSnackMsgRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(async content => await DelegateSnackMsg(content)) .DisposeWith(disposables); AppEvents.AppExitRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(_ => StorageUI()) .DisposeWith(disposables); AppEvents.ShutdownRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(content => Shutdown(content)) .DisposeWith(disposables); AppEvents.ShowHideWindowRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(blShow => ShowHideWindow(blShow)) .DisposeWith(disposables); }); diff --git a/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs b/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs index 40336be5..7d803f10 100644 --- a/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs @@ -90,13 +90,13 @@ public partial class ProfilesView : ReactiveUserControl AppEvents.AppExitRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(_ => StorageUI()) .DisposeWith(disposables); AppEvents.AdjustMainLvColWidthRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(_ => AutofitColumnWidth()) .DisposeWith(disposables); }); diff --git a/v2rayN/v2rayN/App.xaml.cs b/v2rayN/v2rayN/App.xaml.cs index ca56311b..3c5f1989 100644 --- a/v2rayN/v2rayN/App.xaml.cs +++ b/v2rayN/v2rayN/App.xaml.cs @@ -39,6 +39,11 @@ public partial class App : Application } AppManager.Instance.InitComponents(); + + RxAppBuilder.CreateReactiveUIBuilder() + .WithWpf() + .BuildApp(); + base.OnStartup(e); } diff --git a/v2rayN/v2rayN/GlobalUsings.cs b/v2rayN/v2rayN/GlobalUsings.cs index 1f2d1936..fb63f7eb 100644 --- a/v2rayN/v2rayN/GlobalUsings.cs +++ b/v2rayN/v2rayN/GlobalUsings.cs @@ -20,6 +20,7 @@ global using System.Windows.Threading; global using DynamicData; global using DynamicData.Binding; global using ReactiveUI; +global using ReactiveUI.Builder; global using ReactiveUI.Fody.Helpers; global using ServiceLib; global using ServiceLib.Base; diff --git a/v2rayN/v2rayN/Views/ClashConnectionsView.xaml.cs b/v2rayN/v2rayN/Views/ClashConnectionsView.xaml.cs index 47482b8e..337b38e4 100644 --- a/v2rayN/v2rayN/Views/ClashConnectionsView.xaml.cs +++ b/v2rayN/v2rayN/Views/ClashConnectionsView.xaml.cs @@ -33,7 +33,7 @@ public partial class ClashConnectionsView AppEvents.AppExitRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(_ => StorageUI()) .DisposeWith(disposables); }); diff --git a/v2rayN/v2rayN/Views/MainWindow.xaml.cs b/v2rayN/v2rayN/Views/MainWindow.xaml.cs index 93e62aad..42d8aabc 100644 --- a/v2rayN/v2rayN/Views/MainWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/MainWindow.xaml.cs @@ -127,25 +127,25 @@ public partial class MainWindow AppEvents.SendSnackMsgRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(async content => await DelegateSnackMsg(content)) .DisposeWith(disposables); AppEvents.AppExitRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(_ => StorageUI()) .DisposeWith(disposables); AppEvents.ShutdownRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(content => Shutdown(content)) .DisposeWith(disposables); AppEvents.ShowHideWindowRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(blShow => ShowHideWindow(blShow)) .DisposeWith(disposables); }); diff --git a/v2rayN/v2rayN/Views/ProfilesView.xaml.cs b/v2rayN/v2rayN/Views/ProfilesView.xaml.cs index b088fe7b..7075d358 100644 --- a/v2rayN/v2rayN/Views/ProfilesView.xaml.cs +++ b/v2rayN/v2rayN/Views/ProfilesView.xaml.cs @@ -84,13 +84,13 @@ public partial class ProfilesView AppEvents.AppExitRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(_ => StorageUI()) .DisposeWith(disposables); AppEvents.AdjustMainLvColWidthRequested .AsObservable() - .ObserveOn(RxApp.MainThreadScheduler) + .ObserveOn(RxSchedulers.MainThreadScheduler) .Subscribe(_ => AutofitColumnWidth()) .DisposeWith(disposables); }); diff --git a/v2rayN/v2rayN/v2rayN.csproj b/v2rayN/v2rayN/v2rayN.csproj index 9654625d..45cbc376 100644 --- a/v2rayN/v2rayN/v2rayN.csproj +++ b/v2rayN/v2rayN/v2rayN.csproj @@ -2,7 +2,7 @@ WinExe - net8.0-windows10.0.17763 + net8.0-windows10.0.19041.0 true true Resources\v2rayN.ico From e6af9ab34236bd5f59c2419392341138e10e33b3 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Fri, 13 Mar 2026 10:36:58 +0800 Subject: [PATCH 5/6] Fix https://github.com/2dust/v2rayN/issues/8916 --- .../ServiceLib/ViewModels/ProfilesSelectViewModel.cs | 11 +++-------- v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs | 11 +++-------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/v2rayN/ServiceLib/ViewModels/ProfilesSelectViewModel.cs b/v2rayN/ServiceLib/ViewModels/ProfilesSelectViewModel.cs index eb010c58..b3810b52 100644 --- a/v2rayN/ServiceLib/ViewModels/ProfilesSelectViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/ProfilesSelectViewModel.cs @@ -188,14 +188,9 @@ public class ProfilesSelectViewModel : MyReactiveObject { SubItems.Add(item); } - if (_subIndexId != null && SubItems.FirstOrDefault(t => t.Id == _subIndexId) != null) - { - SelectedSub = SubItems.FirstOrDefault(t => t.Id == _subIndexId); - } - else - { - SelectedSub = SubItems.First(); - } + SelectedSub = (_config.SubIndexId.IsNotEmpty() + ? SubItems.FirstOrDefault(t => t.Id == _config.SubIndexId) + : null) ?? SubItems.LastOrDefault(); } private async Task?> GetProfileItemsEx(string subid, string filter) diff --git a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs index 7700d416..6e7e183c 100644 --- a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs @@ -391,14 +391,9 @@ public class ProfilesViewModel : MyReactiveObject { SubItems.Add(item); } - if (_config.SubIndexId != null && SubItems.FirstOrDefault(t => t.Id == _config.SubIndexId) != null) - { - SelectedSub = SubItems.FirstOrDefault(t => t.Id == _config.SubIndexId); - } - else - { - SelectedSub = SubItems.First(); - } + SelectedSub = (_config.SubIndexId.IsNotEmpty() + ? SubItems.FirstOrDefault(t => t.Id == _config.SubIndexId) + : null) ?? SubItems.LastOrDefault(); } private async Task?> GetProfileItemsEx(string subid, string filter) From 214a09bc48537c62d971d97c785de326abc1b5f1 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Fri, 13 Mar 2026 10:44:20 +0800 Subject: [PATCH 6/6] up 7.19.4 --- v2rayN/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v2rayN/Directory.Build.props b/v2rayN/Directory.Build.props index 12693e1c..37a05fdc 100644 --- a/v2rayN/Directory.Build.props +++ b/v2rayN/Directory.Build.props @@ -1,7 +1,7 @@ - 7.19.3 + 7.19.4