diff --git a/v2rayN/ServiceLib/Handler/ConfigHandler.cs b/v2rayN/ServiceLib/Handler/ConfigHandler.cs
index b0bde1df..f984b99c 100644
--- a/v2rayN/ServiceLib/Handler/ConfigHandler.cs
+++ b/v2rayN/ServiceLib/Handler/ConfigHandler.cs
@@ -1163,48 +1163,42 @@ public static class ConfigHandler
return 0;
}
+ // Matches subscription-info noise words in both Chinese and English.
+ // Chinese: 剩余(remaining), 过期/到期(expired/expiry), 重置(reset)
+ // English: remaining, expir(e/ed/y), reset
+ private const string PolicyGroupExcludeKeywords = @"剩余|过期|到期|重置|[Rr]emaining|[Ee]xpir|[Rr]eset";
+
+ private const string PolicyGroupDefaultAllFilter = $"^(?!.*(?:{PolicyGroupExcludeKeywords})).*$";
+
+ ///
+ /// Combines a region pattern with PolicyGroupDefaultAllFilter so results must
+ /// match the region keyword AND not contain expiry/traffic noise words (CN + EN).
+ /// Result pattern: ^(?!.*(?:...excludeKeywords...)).*(?:regionPattern).*$
+ ///
+ private static string CombineWithDefaultAllFilter(string regionPattern)
+ {
+ return $"^(?!.*(?:{PolicyGroupExcludeKeywords})).*(?:{regionPattern}).*$";
+ }
+
///
/// Create a group server that combines multiple servers for load balancing
- /// Generates a configuration file that references multiple servers
+ /// Generates a PolicyGroup profile with references to the sub-items
///
/// Current configuration
- /// Selected servers to combine
- /// Core type to use (Xray or sing_box)
- /// Load balancing algorithm
+ /// Sub-item for grouping
/// Result object with success state and data
- public static async Task AddGroupServer4Multiple(Config config, List selecteds, ECoreType coreType, EMultipleLoad multipleLoad, string? subId)
+ public static async Task AddGroupAllServer(Config config, SubItem? subItem)
{
var result = new RetResult();
var indexId = Utils.GetGuid(false);
- var childProfileIndexId = Utils.List2String(selecteds.Select(p => p.IndexId).ToList());
+ var subId = subItem?.Id;
- var remark = subId.IsNullOrEmpty() ? string.Empty : $"{(await AppManager.Instance.GetSubItem(subId))?.Remarks} ";
- if (coreType == ECoreType.Xray)
- {
- remark += multipleLoad switch
- {
- EMultipleLoad.LeastPing => ResUI.menuGenGroupMultipleServerXrayLeastPing,
- EMultipleLoad.Fallback => ResUI.menuGenGroupMultipleServerXrayFallback,
- EMultipleLoad.Random => ResUI.menuGenGroupMultipleServerXrayRandom,
- EMultipleLoad.RoundRobin => ResUI.menuGenGroupMultipleServerXrayRoundRobin,
- EMultipleLoad.LeastLoad => ResUI.menuGenGroupMultipleServerXrayLeastLoad,
- _ => ResUI.menuGenGroupMultipleServerXrayRoundRobin,
- };
- }
- else if (coreType == ECoreType.sing_box)
- {
- remark += multipleLoad switch
- {
- EMultipleLoad.LeastPing => ResUI.menuGenGroupMultipleServerSingBoxLeastPing,
- EMultipleLoad.Fallback => ResUI.menuGenGroupMultipleServerSingBoxFallback,
- _ => ResUI.menuGenGroupMultipleServerSingBoxLeastPing,
- };
- }
+ var remark = subItem is null ? ResUI.TbConfigTypePolicyGroup : $"{subItem.Remarks} - {ResUI.TbConfigTypePolicyGroup}";
var profile = new ProfileItem
{
IndexId = indexId,
- CoreType = coreType,
+ CoreType = ECoreType.Xray,
ConfigType = EConfigType.PolicyGroup,
Remarks = remark,
IsSub = false
@@ -1215,8 +1209,10 @@ public static class ConfigHandler
}
var extraItem = new ProtocolExtraItem
{
- ChildItems = childProfileIndexId,
- MultipleLoad = multipleLoad,
+ MultipleLoad = EMultipleLoad.LeastPing,
+ GroupType = profile.ConfigType.ToString(),
+ SubChildItems = subId,
+ Filter = PolicyGroupDefaultAllFilter,
};
profile.SetProtocolExtra(extraItem);
var ret = await AddServerCommon(config, profile, true);
@@ -1225,6 +1221,76 @@ public static class ConfigHandler
return result;
}
+ private static readonly Dictionary PolicyGroupRegionFilters = new()
+ {
+ { "JP", "日本|[Jj][Pp]|🇯🇵" },
+ { "US", "美国|[Uu][Ss]|🇺🇸" },
+ { "HK", "香港|[Hh][Kk]|🇭🇰" },
+ { "TW", "台湾|[Tt][Ww]|🇹🇼" },
+ { "KR", "韩国|[Kk][Rr]|🇰🇷" },
+ { "SG", "新加坡|[Ss][Gg]|🇸🇬" },
+ { "DE", "德国|[Dd][Ee]|🇩🇪" },
+ { "FR", "法国|[Ff][Rr]|🇫🇷" },
+ { "GB", "英国|[Gg][Bb]|🇬🇧" },
+ { "CA", "加拿大|[Cc][Aa]|🇨🇦" },
+ { "AU", "澳大利亚|[Aa][Uu]|🇦🇺" },
+ { "RU", "俄罗斯|[Rr][Uu]|🇷🇺" },
+ { "BR", "巴西|[Bb][Rr]|🇧🇷" },
+ { "IN", "印度|[Ii][Nn]|🇮🇳" },
+ { "VN", "越南|[Vv][Nn]|🇻🇳" },
+ { "ID", "印度尼西亚|[Ii][Dd]|🇮🇩" },
+ { "MX", "墨西哥|[Mm][Xx]|🇲🇽" }
+ };
+
+ public static async Task AddGroupRegionServer(Config config, SubItem? subItem)
+ {
+ var result = new RetResult();
+ List indexIdList = [];
+
+ foreach (var regionFilter in PolicyGroupRegionFilters)
+ {
+ var indexId = Utils.GetGuid(false);
+ var subId = subItem?.Id;
+
+ var remark = subItem is null ? ResUI.TbConfigTypePolicyGroup : $"{subItem.Remarks} - {ResUI.TbConfigTypePolicyGroup} - {regionFilter.Key}";
+ var profile = new ProfileItem
+ {
+ IndexId = indexId,
+ CoreType = ECoreType.Xray,
+ ConfigType = EConfigType.PolicyGroup,
+ Remarks = remark,
+ IsSub = false
+ };
+ if (!subId.IsNullOrEmpty())
+ {
+ profile.Subid = subId;
+ }
+ var extraItem = new ProtocolExtraItem
+ {
+ MultipleLoad = EMultipleLoad.LeastPing,
+ GroupType = profile.ConfigType.ToString(),
+ SubChildItems = subId,
+ Filter = CombineWithDefaultAllFilter(regionFilter.Value),
+ };
+ profile.SetProtocolExtra(extraItem);
+
+ var childProfile = await GroupProfileManager.GetChildProfileItemsByProtocolExtra(extraItem);
+ if (childProfile.Count == 0)
+ {
+ continue;
+ }
+
+ var ret = await AddServerCommon(config, profile, true);
+ if (ret == 0)
+ {
+ indexIdList.Add(indexId);
+ }
+ }
+ result.Success = indexIdList.Count > 0;
+ result.Data = indexIdList;
+ return result;
+ }
+
///
/// Get a SOCKS server profile for pre-SOCKS functionality
/// Used when TUN mode is enabled or when a custom config has a pre-SOCKS port
diff --git a/v2rayN/ServiceLib/Manager/GroupProfileManager.cs b/v2rayN/ServiceLib/Manager/GroupProfileManager.cs
index 5e87f0e6..7d2fdbff 100644
--- a/v2rayN/ServiceLib/Manager/GroupProfileManager.cs
+++ b/v2rayN/ServiceLib/Manager/GroupProfileManager.cs
@@ -128,7 +128,7 @@ public class GroupProfileManager
private static async Task> GetSubChildProfileItems(ProtocolExtraItem? extra)
{
- if (extra == null || extra.SubChildItems.IsNullOrEmpty())
+ if (extra == null || extra.Filter.IsNullOrEmpty())
{
return [];
}
diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
index 8f798007..d1dd3b75 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
+++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
@@ -888,6 +888,15 @@ namespace ServiceLib.Resx {
}
}
+ ///
+ /// 查找类似 All configurations 的本地化字符串。
+ ///
+ public static string menuAllServers {
+ get {
+ return ResourceManager.GetString("menuAllServers", resourceCulture);
+ }
+ }
+
///
/// 查找类似 Backup and Restore 的本地化字符串。
///
@@ -1060,74 +1069,20 @@ namespace ServiceLib.Resx {
}
///
- /// 查找类似 Generate Policy Group from Multiple Profiles 的本地化字符串。
+ /// 查找类似 Generate Policy Group 的本地化字符串。
///
- public static string menuGenGroupMultipleServer {
+ public static string menuGenGroupServer {
get {
- return ResourceManager.GetString("menuGenGroupMultipleServer", resourceCulture);
+ return ResourceManager.GetString("menuGenGroupServer", resourceCulture);
}
}
///
- /// 查找类似 Fallback by sing-box 的本地化字符串。
+ /// 查找类似 Group by Region 的本地化字符串。
///
- public static string menuGenGroupMultipleServerSingBoxFallback {
+ public static string menuGenRegionGroup {
get {
- return ResourceManager.GetString("menuGenGroupMultipleServerSingBoxFallback", resourceCulture);
- }
- }
-
- ///
- /// 查找类似 LeastPing by sing-box 的本地化字符串。
- ///
- public static string menuGenGroupMultipleServerSingBoxLeastPing {
- get {
- return ResourceManager.GetString("menuGenGroupMultipleServerSingBoxLeastPing", resourceCulture);
- }
- }
-
- ///
- /// 查找类似 Fallback by Xray 的本地化字符串。
- ///
- public static string menuGenGroupMultipleServerXrayFallback {
- get {
- return ResourceManager.GetString("menuGenGroupMultipleServerXrayFallback", resourceCulture);
- }
- }
-
- ///
- /// 查找类似 LeastLoad by Xray 的本地化字符串。
- ///
- public static string menuGenGroupMultipleServerXrayLeastLoad {
- get {
- return ResourceManager.GetString("menuGenGroupMultipleServerXrayLeastLoad", resourceCulture);
- }
- }
-
- ///
- /// 查找类似 LeastPing by Xray 的本地化字符串。
- ///
- public static string menuGenGroupMultipleServerXrayLeastPing {
- get {
- return ResourceManager.GetString("menuGenGroupMultipleServerXrayLeastPing", resourceCulture);
- }
- }
-
- ///
- /// 查找类似 Random by Xray 的本地化字符串。
- ///
- public static string menuGenGroupMultipleServerXrayRandom {
- get {
- return ResourceManager.GetString("menuGenGroupMultipleServerXrayRandom", resourceCulture);
- }
- }
-
- ///
- /// 查找类似 RoundRobin by Xray 的本地化字符串。
- ///
- public static string menuGenGroupMultipleServerXrayRoundRobin {
- get {
- return ResourceManager.GetString("menuGenGroupMultipleServerXrayRoundRobin", resourceCulture);
+ return ResourceManager.GetString("menuGenRegionGroup", resourceCulture);
}
}
diff --git a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
index 9aba2fed..31d8d7f7 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
@@ -1371,24 +1371,6 @@
مخفی و پورت می شود، با کاما (،) جدا می شود
-
- Generate Policy Group from Multiple Profiles
-
-
- چند سرور تصادفی توسط Xray
-
-
- چند سرور RoundRobin توسط Xray
-
-
- چند سرور LeastPing توسط Xray
-
-
- چند سرور LeastLoad توسط Xray
-
-
- LeastPing چند سرور توسط sing-box
-
صادر کردن سرور
@@ -1533,12 +1515,6 @@
Fallback
-
- Multi-Configuration Fallback by sing-box
-
-
- Multi-Configuration Fallback by Xray
-
Core '{0}' does not support network type '{1}'.
@@ -1668,4 +1644,13 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
Finalmask
+
+ Generate Policy Group
+
+
+ All configurations
+
+
+ Group by Region
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Resx/ResUI.fr.resx b/v2rayN/ServiceLib/Resx/ResUI.fr.resx
index 3dfbcc09..87fbb37c 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.fr.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.fr.resx
@@ -1368,24 +1368,6 @@
Écrase le port ; pour plusieurs groupes, séparer par virgules (,)
-
- Générer un groupe de stratégie depuis plusieurs profils
-
-
- Xray aléatoire (multi-sélection)
-
-
- Xray équilibrage (tourniquet) multi-sélection
-
-
- Xray latence minimale (multi-sélection)
-
-
- Xray le plus stable (multi-sélection)
-
-
- sing-box latence minimale (multi-sélection)
-
Exporter
@@ -1530,12 +1512,6 @@
Basculement (failover)
-
- sing-box basculement (multi-sélection)
-
-
- Xray basculement (multi-sélection)
-
Le cœur « {0} » ne prend pas en charge le type de réseau « {1} ».
@@ -1665,4 +1641,13 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
Finalmask
+
+ Generate Policy Group
+
+
+ All configurations
+
+
+ Group by Region
+
diff --git a/v2rayN/ServiceLib/Resx/ResUI.hu.resx b/v2rayN/ServiceLib/Resx/ResUI.hu.resx
index e69a0a54..2c5c44f7 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.hu.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.hu.resx
@@ -1371,24 +1371,6 @@
A portot lefedi, vesszővel (,) elválasztva
-
- Generate Policy Group from Multiple Profiles
-
-
- Több konfiguráció véletlenszerűen Xray szerint
-
-
- Több konfiguráció RoundRobin Xray szerint
-
-
- Több konfiguráció legkisebb pinggel Xray szerint
-
-
- Több konfiguráció legkisebb terheléssel Xray szerint
-
-
- Több konfiguráció legkisebb pinggel sing-box szerint
-
Konfiguráció exportálása
@@ -1533,12 +1515,6 @@
Fallback
-
- Multi-Configuration Fallback by sing-box
-
-
- Multi-Configuration Fallback by Xray
-
Core '{0}' does not support network type '{1}'.
@@ -1668,4 +1644,13 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
Finalmask
+
+ Generate Policy Group
+
+
+ All configurations
+
+
+ Group by Region
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx
index cc304154..16cef1b7 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.resx
@@ -1371,24 +1371,6 @@
Will cover the port, separate with commas (,)
-
- Generate Policy Group from Multiple Profiles
-
-
- Random by Xray
-
-
- RoundRobin by Xray
-
-
- LeastPing by Xray
-
-
- LeastLoad by Xray
-
-
- LeastPing by sing-box
-
Export
@@ -1533,12 +1515,6 @@
Fallback
-
- Fallback by sing-box
-
-
- Fallback by Xray
-
Core '{0}' does not support network type '{1}'.
@@ -1668,4 +1644,13 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
Finalmask
+
+ Generate Policy Group
+
+
+ All configurations
+
+
+ Group by Region
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayN/ServiceLib/Resx/ResUI.ru.resx
index 6f093f72..4a29c8c9 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.ru.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.ru.resx
@@ -1371,24 +1371,6 @@
Заменит указанный порт, перечисляйте через запятую (,)
-
- Generate Policy Group from Multiple Profiles
-
-
- Случайный (Xray)
-
-
- Круговой (Xray)
-
-
- Минимальное RTT (минимальное время туда-обратно) (Xray)
-
-
- Минимальная нагрузка (Xray)
-
-
- Минимальное RTT (минимальное время туда-обратно) (sing-box)
-
Экспортировать конфигурацию
@@ -1533,12 +1515,6 @@
Fallback
-
- Multi-Configuration Fallback by sing-box
-
-
- Multi-Configuration Fallback by Xray
-
Core '{0}' does not support network type '{1}'.
@@ -1668,4 +1644,13 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
Finalmask
+
+ Generate Policy Group
+
+
+ All configurations
+
+
+ Group by Region
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
index c0f8665d..f74d83ef 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
@@ -1368,24 +1368,6 @@
会覆盖端口,多组时用逗号 (,) 隔开
-
- 多选生成策略组
-
-
- 多选随机 Xray
-
-
- 多选负载均衡 Xray
-
-
- 多选最低延迟 Xray
-
-
- 多选最稳定 Xray
-
-
- 多选最低延迟 sing-box
-
导出
@@ -1530,12 +1512,6 @@
故障转移
-
- 多选故障转移 sing-box
-
-
- 多选故障转移 Xray
-
核心 '{0}' 不支持网络类型 '{1}'。
@@ -1665,4 +1641,13 @@
Finalmask
+
+ 一键生成策略组
+
+
+ 全部配置项
+
+
+ 按地区分组
+
\ 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 9002c3af..ddb087f0 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
@@ -1368,24 +1368,6 @@
會覆蓋埠,多組時用逗號 (,) 隔開
-
- 多選生成策略組
-
-
- 多選隨機 Xray
-
-
- 多選負載平衡 Xray
-
-
- 多選最低延遲 Xray
-
-
- 多選最穩定 Xray
-
-
- 多選最低延遲 sing-box
-
匯出
@@ -1530,12 +1512,6 @@
容錯移轉
-
- 多選容錯移轉 sing-box
-
-
- 多選容錯移轉 Xray
-
核心 '{0}' 不支援網路類型 '{1}'.
@@ -1665,4 +1641,13 @@
Finalmask
+
+ Generate Policy Group
+
+
+ All configurations
+
+
+ Group by Region
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs
index 8b4e7eb0..ad21883e 100644
--- a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs
+++ b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs
@@ -8,6 +8,7 @@ public class ProfilesViewModel : MyReactiveObject
private string _serverFilter = string.Empty;
private Dictionary _dicHeaderSort = new();
private SpeedtestService? _speedtestService;
+ private string? _pendingSelectIndexId;
#endregion private prop
@@ -43,13 +44,8 @@ public class ProfilesViewModel : MyReactiveObject
public ReactiveCommand CopyServerCmd { get; }
public ReactiveCommand SetDefaultServerCmd { get; }
public ReactiveCommand ShareServerCmd { get; }
- public ReactiveCommand GenGroupMultipleServerXrayRandomCmd { get; }
- public ReactiveCommand GenGroupMultipleServerXrayRoundRobinCmd { get; }
- public ReactiveCommand GenGroupMultipleServerXrayLeastPingCmd { get; }
- public ReactiveCommand GenGroupMultipleServerXrayLeastLoadCmd { get; }
- public ReactiveCommand GenGroupMultipleServerXrayFallbackCmd { get; }
- public ReactiveCommand GenGroupMultipleServerSingBoxLeastPingCmd { get; }
- public ReactiveCommand GenGroupMultipleServerSingBoxFallbackCmd { get; }
+ public ReactiveCommand GenGroupAllServerCmd { get; }
+ public ReactiveCommand GenGroupRegionServerCmd { get; }
//servers move
public ReactiveCommand MoveTopCmd { get; }
@@ -134,33 +130,13 @@ public class ProfilesViewModel : MyReactiveObject
{
await ShareServerAsync();
}, canEditRemove);
- GenGroupMultipleServerXrayRandomCmd = ReactiveCommand.CreateFromTask(async () =>
+ GenGroupAllServerCmd = ReactiveCommand.CreateFromTask(async () =>
{
- await GenGroupMultipleServer(ECoreType.Xray, EMultipleLoad.Random);
+ await GenGroupAllServer();
}, canEditRemove);
- GenGroupMultipleServerXrayRoundRobinCmd = ReactiveCommand.CreateFromTask(async () =>
+ GenGroupRegionServerCmd = ReactiveCommand.CreateFromTask(async () =>
{
- await GenGroupMultipleServer(ECoreType.Xray, EMultipleLoad.RoundRobin);
- }, canEditRemove);
- GenGroupMultipleServerXrayLeastPingCmd = ReactiveCommand.CreateFromTask(async () =>
- {
- await GenGroupMultipleServer(ECoreType.Xray, EMultipleLoad.LeastPing);
- }, canEditRemove);
- GenGroupMultipleServerXrayLeastLoadCmd = ReactiveCommand.CreateFromTask(async () =>
- {
- await GenGroupMultipleServer(ECoreType.Xray, EMultipleLoad.LeastLoad);
- }, canEditRemove);
- GenGroupMultipleServerXrayFallbackCmd = ReactiveCommand.CreateFromTask(async () =>
- {
- await GenGroupMultipleServer(ECoreType.Xray, EMultipleLoad.Fallback);
- }, canEditRemove);
- GenGroupMultipleServerSingBoxLeastPingCmd = ReactiveCommand.CreateFromTask(async () =>
- {
- await GenGroupMultipleServer(ECoreType.sing_box, EMultipleLoad.LeastPing);
- }, canEditRemove);
- GenGroupMultipleServerSingBoxFallbackCmd = ReactiveCommand.CreateFromTask(async () =>
- {
- await GenGroupMultipleServer(ECoreType.sing_box, EMultipleLoad.Fallback);
+ await GenGroupRegionServer();
}, canEditRemove);
//servers move
@@ -392,15 +368,14 @@ public class ProfilesViewModel : MyReactiveObject
ProfileItems.AddRange(lstModel);
if (lstModel.Count > 0)
{
- var selected = lstModel.FirstOrDefault(t => t.IndexId == _config.IndexId);
- if (selected != null)
+ ProfileItemModel? selected = null;
+ if (!_pendingSelectIndexId.IsNullOrEmpty())
{
- SelectedProfile = selected;
- }
- else
- {
- SelectedProfile = lstModel.First();
+ selected = lstModel.FirstOrDefault(t => t.IndexId == _pendingSelectIndexId);
+ _pendingSelectIndexId = null;
}
+ selected ??= lstModel.FirstOrDefault(t => t.IndexId == _config.IndexId);
+ SelectedProfile = selected ?? lstModel.First();
}
await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null);
@@ -641,29 +616,29 @@ public class ProfilesViewModel : MyReactiveObject
await _updateView?.Invoke(EViewAction.ShareServer, url);
}
- private async Task GenGroupMultipleServer(ECoreType coreType, EMultipleLoad multipleLoad)
+ private async Task GenGroupAllServer()
{
- var lstSelected = await GetProfileItems(true);
- if (lstSelected == null)
- {
- return;
- }
-
- var ret = await ConfigHandler.AddGroupServer4Multiple(_config, lstSelected, coreType, multipleLoad, SelectedSub?.Id);
+ var ret = await ConfigHandler.AddGroupAllServer(_config, SelectedSub);
if (ret.Success != true)
{
NoticeManager.Instance.Enqueue(ResUI.OperationFailed);
return;
}
- if (ret?.Data?.ToString() == _config.IndexId)
+ _pendingSelectIndexId = ret.Data?.ToString();
+ await RefreshServers();
+ }
+
+ private async Task GenGroupRegionServer()
+ {
+ var ret = await ConfigHandler.AddGroupRegionServer(_config, SelectedSub);
+ if (ret.Success != true)
{
- await RefreshServers();
- Reload();
- }
- else
- {
- await SetDefaultServer(ret?.Data?.ToString());
+ NoticeManager.Instance.Enqueue(ResUI.OperationFailed);
+ return;
}
+ var indexIdList = ret.Data as List;
+ _pendingSelectIndexId = indexIdList?.FirstOrDefault();
+ await RefreshServers();
}
public async Task SortServer(string colName)
diff --git a/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml b/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml
index 116f35fa..e0751ca1 100644
--- a/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml
+++ b/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml
@@ -193,14 +193,9 @@
-
-
+
+ Header="{x:Static resx:ResUI.menuAllServers}" />
-
-
-
-
-
+ Header="{x:Static resx:ResUI.menuGenRegionGroup}" />
diff --git a/v2rayN/v2rayN/Views/ProfilesView.xaml.cs b/v2rayN/v2rayN/Views/ProfilesView.xaml.cs
index 58b468a4..46def3e2 100644
--- a/v2rayN/v2rayN/Views/ProfilesView.xaml.cs
+++ b/v2rayN/v2rayN/Views/ProfilesView.xaml.cs
@@ -54,12 +54,8 @@ public partial class ProfilesView
this.BindCommand(ViewModel, vm => vm.CopyServerCmd, v => v.menuCopyServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SetDefaultServerCmd, v => v.menuSetDefaultServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ShareServerCmd, v => v.menuShareServer).DisposeWith(disposables);
- this.BindCommand(ViewModel, vm => vm.GenGroupMultipleServerXrayRandomCmd, v => v.menuGenGroupMultipleServerXrayRandom).DisposeWith(disposables);
- this.BindCommand(ViewModel, vm => vm.GenGroupMultipleServerXrayRoundRobinCmd, v => v.menuGenGroupMultipleServerXrayRoundRobin).DisposeWith(disposables);
- this.BindCommand(ViewModel, vm => vm.GenGroupMultipleServerXrayLeastPingCmd, v => v.menuGenGroupMultipleServerXrayLeastPing).DisposeWith(disposables);
- this.BindCommand(ViewModel, vm => vm.GenGroupMultipleServerXrayLeastLoadCmd, v => v.menuGenGroupMultipleServerXrayLeastLoad).DisposeWith(disposables);
- this.BindCommand(ViewModel, vm => vm.GenGroupMultipleServerSingBoxLeastPingCmd, v => v.menuGenGroupMultipleServerSingBoxLeastPing).DisposeWith(disposables);
- this.BindCommand(ViewModel, vm => vm.GenGroupMultipleServerSingBoxFallbackCmd, v => v.menuGenGroupMultipleServerSingBoxFallback).DisposeWith(disposables);
+ this.BindCommand(ViewModel, vm => vm.GenGroupAllServerCmd, v => v.menuGenGroupAllServer).DisposeWith(disposables);
+ this.BindCommand(ViewModel, vm => vm.GenGroupRegionServerCmd, v => v.menuGenGroupRegionServer).DisposeWith(disposables);
//servers move
this.OneWayBind(ViewModel, vm => vm.SubItems, v => v.cmbMoveToGroup.ItemsSource).DisposeWith(disposables);