Improve profile matching for Subscription, remove old option

This commit is contained in:
2dust
2026-03-12 14:56:01 +08:00
parent 5e18567ce6
commit 17ed26cd06
15 changed files with 82 additions and 70 deletions
+81 -6
View File
@@ -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
}
}
/// <summary>
/// Searches the specified collection for a profile item that matches the target profile item based on a series of
/// criteria.
/// </summary>
/// <remarks>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.</remarks>
/// <param name="source">An enumerable collection of profile items to search. This parameter can be null.</param>
/// <param name="target">The profile item to match against items in the source collection. This parameter can be null.</param>
/// <returns>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.</returns>
private static ProfileItem? FindMatchedProfileItem(IEnumerable<ProfileItem>? 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);
}
}
/// <summary>
/// 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);