diff --git a/v2rayN/ServiceLib/Handler/ConfigHandler.cs b/v2rayN/ServiceLib/Handler/ConfigHandler.cs index eff345f3..f3596c9f 100644 --- a/v2rayN/ServiceLib/Handler/ConfigHandler.cs +++ b/v2rayN/ServiceLib/Handler/ConfigHandler.cs @@ -871,13 +871,19 @@ namespace ServiceLib.Handler public static async Task> DedupServerList(Config config, string subId) { var lstProfile = await AppHandler.Instance.ProfileItems(subId); + if (lstProfile == null) + { + return new Tuple(0, 0); + } List lstKeep = new(); List lstRemove = new(); if (!config.GuiItem.KeepOlderDedupl) + { lstProfile.Reverse(); + } - foreach (ProfileItem item in lstProfile) + foreach (var item in lstProfile) { if (!lstKeep.Exists(i => CompareProfileItem(i, item, false))) { @@ -944,35 +950,35 @@ namespace ServiceLib.Handler return 0; } - private static bool CompareProfileItem(ProfileItem o, ProfileItem n, bool remarks) + private static bool CompareProfileItem(ProfileItem? o, ProfileItem? n, bool remarks) { if (o == null || n == null) { return false; } + return o.ConfigType == n.ConfigType + && AreEqual(o.Address, n.Address) + && o.Port == n.Port + && AreEqual(o.Id, n.Id) + && AreEqual(o.Security, n.Security) + && AreEqual(o.Network, n.Network) + && AreEqual(o.HeaderType, n.HeaderType) + && AreEqual(o.RequestHost, n.RequestHost) + && AreEqual(o.Path, n.Path) + && (o.ConfigType == EConfigType.Trojan || o.StreamSecurity == n.StreamSecurity) + && AreEqual(o.Flow, n.Flow) + && AreEqual(o.Sni, n.Sni) + && AreEqual(o.Alpn, n.Alpn) + && AreEqual(o.Fingerprint, n.Fingerprint) + && AreEqual(o.PublicKey, n.PublicKey) + && AreEqual(o.ShortId, n.ShortId) + && (!remarks || o.Remarks == n.Remarks); + static bool AreEqual(string? a, string? b) { return string.Equals(a, b) || (string.IsNullOrEmpty(a) && string.IsNullOrEmpty(b)); } - - return o.ConfigType == n.ConfigType - && AreEqual(o.Address, n.Address) - && o.Port == n.Port - && AreEqual(o.Id, n.Id) - && AreEqual(o.Security, n.Security) - && AreEqual(o.Network, n.Network) - && AreEqual(o.HeaderType, n.HeaderType) - && AreEqual(o.RequestHost, n.RequestHost) - && AreEqual(o.Path, n.Path) - && (o.ConfigType == EConfigType.Trojan || o.StreamSecurity == n.StreamSecurity) - && AreEqual(o.Flow, n.Flow) - && AreEqual(o.Sni, n.Sni) - && AreEqual(o.Alpn, n.Alpn) - && AreEqual(o.Fingerprint, n.Fingerprint) - && AreEqual(o.PublicKey, n.PublicKey) - && AreEqual(o.ShortId, n.ShortId) - && (!remarks || o.Remarks == n.Remarks); } private static async Task RemoveProfileItem(Config config, string indexId) @@ -1010,8 +1016,7 @@ namespace ServiceLib.Handler return result; } - var fileName = configPath; - if (!File.Exists(fileName)) + if (!File.Exists(configPath)) { return result; } diff --git a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs index 3f9e9cf2..d4032e98 100644 --- a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs @@ -448,7 +448,7 @@ namespace ServiceLib.ViewModels private async Task?> GetProfileItems(bool latest) { - var lstSelecteds = new List(); + var lstSelected = new List(); if (SelectedProfiles == null || SelectedProfiles.Count <= 0) { return null; @@ -462,16 +462,16 @@ namespace ServiceLib.ViewModels var item = await AppHandler.Instance.GetProfileItem(profile.IndexId); if (item is not null) { - lstSelecteds.Add(item); + lstSelected.Add(item); } } } else { - lstSelecteds = JsonUtils.Deserialize>(JsonUtils.Serialize(orderProfiles)); + lstSelected = JsonUtils.Deserialize>(JsonUtils.Serialize(orderProfiles)); } - return lstSelecteds; + return lstSelected; } public async Task EditServerAsync(EConfigType eConfigType) @@ -509,8 +509,8 @@ namespace ServiceLib.ViewModels public async Task RemoveServerAsync() { - var lstSelecteds = await GetProfileItems(true); - if (lstSelecteds == null) + var lstSelected = await GetProfileItems(true); + if (lstSelected == null) { return; } @@ -518,11 +518,11 @@ namespace ServiceLib.ViewModels { return; } - var exists = lstSelecteds.Exists(t => t.IndexId == _config.IndexId); + var exists = lstSelected.Exists(t => t.IndexId == _config.IndexId); - await ConfigHandler.RemoveServers(_config, lstSelecteds); + await ConfigHandler.RemoveServers(_config, lstSelected); NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess); - if (lstSelecteds.Count == _profileItems.Count) + if (lstSelected.Count == _profileItems.Count) { _profileItems.Clear(); } @@ -536,19 +536,22 @@ namespace ServiceLib.ViewModels private async Task RemoveDuplicateServer() { var tuple = await ConfigHandler.DedupServerList(_config, _config.SubIndexId); - RefreshServers(); - Reload(); + if (tuple.Item1 > 0 || tuple.Item2 > 0) + { + RefreshServers(); + Reload(); + } NoticeHandler.Instance.Enqueue(string.Format(ResUI.RemoveDuplicateServerResult, tuple.Item1, tuple.Item2)); } private async Task CopyServer() { - var lstSelecteds = await GetProfileItems(false); - if (lstSelecteds == null) + var lstSelected = await GetProfileItems(false); + if (lstSelected == null) { return; } - if (await ConfigHandler.CopyServer(_config, lstSelecteds) == 0) + if (await ConfigHandler.CopyServer(_config, lstSelected) == 0) { RefreshServers(); NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess); @@ -564,7 +567,7 @@ namespace ServiceLib.ViewModels await SetDefaultServer(SelectedProfile.IndexId); } - public async Task SetDefaultServer(string indexId) + public async Task SetDefaultServer(string? indexId) { if (indexId.IsNullOrEmpty()) { @@ -594,11 +597,7 @@ namespace ServiceLib.ViewModels { return; } - if (SelectedServer == null) - { - return; - } - if (SelectedServer.ID.IsNullOrEmpty()) + if (SelectedServer == null || SelectedServer.ID.IsNullOrEmpty()) { return; } @@ -624,13 +623,13 @@ namespace ServiceLib.ViewModels private async Task SetDefaultMultipleServer(ECoreType coreType) { - var lstSelecteds = await GetProfileItems(true); - if (lstSelecteds == null) + var lstSelected = await GetProfileItems(true); + if (lstSelected == null) { return; } - var ret = await ConfigHandler.AddCustomServer4Multiple(_config, lstSelecteds, coreType); + var ret = await ConfigHandler.AddCustomServer4Multiple(_config, lstSelected, coreType); if (ret.Success != true) { NoticeHandler.Instance.Enqueue(ResUI.OperationFailed); @@ -679,19 +678,18 @@ namespace ServiceLib.ViewModels return; } - var lstSelecteds = await GetProfileItems(true); - if (lstSelecteds == null) + var lstSelected = await GetProfileItems(true); + if (lstSelected == null) { return; } - await ConfigHandler.MoveToGroup(_config, lstSelecteds, SelectedMoveToGroup.Id); + await ConfigHandler.MoveToGroup(_config, lstSelected, SelectedMoveToGroup.Id); NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess); RefreshServers(); SelectedMoveToGroup = null; SelectedMoveToGroup = new(); - //Reload(); } public async Task MoveServer(EMove eMove) @@ -703,7 +701,7 @@ namespace ServiceLib.ViewModels return; } - int index = _lstProfile.IndexOf(item); + var index = _lstProfile.IndexOf(item); if (index < 0) { return; @@ -732,14 +730,14 @@ namespace ServiceLib.ViewModels { SelectedProfiles = _profileItems; } - var lstSelecteds = await GetProfileItems(false); - if (lstSelecteds == null) + var lstSelected = await GetProfileItems(false); + if (lstSelected == null) { return; } _speedtestService ??= new SpeedtestService(_config, (SpeedTestResult result) => _updateView?.Invoke(EViewAction.DispatcherSpeedTest, result)); - _speedtestService?.RunLoop(actionType, lstSelecteds); + _speedtestService?.RunLoop(actionType, lstSelected); } public void ServerSpeedtestStop() @@ -793,14 +791,14 @@ namespace ServiceLib.ViewModels public async Task Export2ShareUrlAsync(bool blEncode) { - var lstSelecteds = await GetProfileItems(true); - if (lstSelecteds == null) + var lstSelected = await GetProfileItems(true); + if (lstSelected == null) { return; } StringBuilder sb = new(); - foreach (var it in lstSelecteds) + foreach (var it in lstSelected) { var url = FmtHandler.GetShareUri(it); if (url.IsNullOrEmpty())