mirror of
https://github.com/2dust/v2rayN.git
synced 2026-04-16 12:35:46 +00:00
151 lines
4.5 KiB
C#
151 lines
4.5 KiB
C#
namespace ServiceLib.Manager;
|
|
|
|
public class GroupProfileManager
|
|
{
|
|
public static async Task<bool> HasCycle(ProfileItem item)
|
|
{
|
|
return await HasCycle(item.IndexId, item.GetProtocolExtra());
|
|
}
|
|
|
|
public static async Task<bool> HasCycle(string? indexId, ProtocolExtraItem? extraInfo)
|
|
{
|
|
return await HasCycle(indexId, extraInfo, new HashSet<string>(), new HashSet<string>());
|
|
}
|
|
|
|
private static async Task<bool> HasCycle(string? indexId, ProtocolExtraItem? extraInfo, HashSet<string> visited, HashSet<string> stack)
|
|
{
|
|
if (indexId.IsNullOrEmpty() || extraInfo == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (stack.Contains(indexId))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (visited.Contains(indexId))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
visited.Add(indexId);
|
|
stack.Add(indexId);
|
|
|
|
try
|
|
{
|
|
if (extraInfo.GroupType.IsNullOrEmpty())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (extraInfo.ChildItems.IsNullOrEmpty())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var childIds = Utils.String2List(extraInfo.ChildItems)
|
|
?.Where(p => !string.IsNullOrEmpty(p))
|
|
.ToList();
|
|
if (childIds == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var childItems = await AppManager.Instance.GetProfileItemsByIndexIds(childIds);
|
|
foreach (var childItem in childItems)
|
|
{
|
|
if (await HasCycle(childItem.IndexId, childItem?.GetProtocolExtra(), visited, stack))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
finally
|
|
{
|
|
stack.Remove(indexId);
|
|
}
|
|
}
|
|
|
|
public static async Task<(List<ProfileItem> Items, ProtocolExtraItem? Extra)> GetChildProfileItems(ProfileItem profileItem)
|
|
{
|
|
var protocolExtra = profileItem?.GetProtocolExtra();
|
|
return (await GetChildProfileItemsByProtocolExtra(protocolExtra), protocolExtra);
|
|
}
|
|
|
|
public static async Task<List<ProfileItem>> GetChildProfileItemsByProtocolExtra(ProtocolExtraItem? protocolExtra)
|
|
{
|
|
if (protocolExtra == null)
|
|
{
|
|
return [];
|
|
}
|
|
|
|
var items = new List<ProfileItem>();
|
|
items.AddRange(await GetSubChildProfileItems(protocolExtra));
|
|
items.AddRange(await GetSelectedChildProfileItems(protocolExtra));
|
|
|
|
return items;
|
|
}
|
|
|
|
private static async Task<List<ProfileItem>> GetSelectedChildProfileItems(ProtocolExtraItem? extra)
|
|
{
|
|
if (extra == null || extra.ChildItems.IsNullOrEmpty())
|
|
{
|
|
return [];
|
|
}
|
|
var childProfileIds = Utils.String2List(extra.ChildItems)
|
|
?.Where(p => !string.IsNullOrEmpty(p))
|
|
.ToList() ?? [];
|
|
if (childProfileIds.Count == 0)
|
|
{
|
|
return [];
|
|
}
|
|
|
|
var ordered = await AppManager.Instance.GetProfileItemsOrderedByIndexIds(childProfileIds);
|
|
return ordered;
|
|
}
|
|
|
|
private static async Task<List<ProfileItem>> GetSubChildProfileItems(ProtocolExtraItem? extra)
|
|
{
|
|
if (extra == null || extra.SubChildItems.IsNullOrEmpty())
|
|
{
|
|
return [];
|
|
}
|
|
var childProfiles = await AppManager.Instance.ProfileItems(extra.SubChildItems ?? string.Empty);
|
|
|
|
return childProfiles?.Where(p =>
|
|
p != null &&
|
|
p.IsValid() &&
|
|
!p.ConfigType.IsComplexType() &&
|
|
(extra.Filter.IsNullOrEmpty() || Regex.IsMatch(p.Remarks, extra.Filter))
|
|
)
|
|
.ToList() ?? [];
|
|
}
|
|
|
|
public static async Task<Dictionary<string, ProfileItem>> GetAllChildProfileItems(ProfileItem profileItem)
|
|
{
|
|
var itemMap = new Dictionary<string, ProfileItem>();
|
|
var visited = new HashSet<string>();
|
|
|
|
await CollectChildItems(profileItem, itemMap, visited);
|
|
|
|
return itemMap;
|
|
}
|
|
|
|
private static async Task CollectChildItems(ProfileItem profileItem, Dictionary<string, ProfileItem> itemMap,
|
|
HashSet<string> visited)
|
|
{
|
|
var (childItems, _) = await GetChildProfileItems(profileItem);
|
|
foreach (var child in childItems.Where(child => visited.Add(child.IndexId)))
|
|
{
|
|
itemMap[child.IndexId] = child;
|
|
|
|
if (child.ConfigType.IsGroupType())
|
|
{
|
|
await CollectChildItems(child, itemMap, visited);
|
|
}
|
|
}
|
|
}
|
|
}
|