mirror of
https://github.com/2dust/v2rayN.git
synced 2026-11-05 03:55:00 +03:00
Refactor profile item config (#8659)
* Refactor * Add hysteria2 bandwidth and hop interval support * Upgrade config version and rename * Refactor id and security * Refactor flow * Fix hy2 bbr * Fix warning CS0618 * Remove unused code * Fix hy2 migrate * Fix * Refactor * Refactor ProfileItem protocol extra handling * Refactor, use record instead of class * Hy2 SalamanderPass * Fix Tuic * Fix group * Fix Tuic * Fix hy2 Brutal Bandwidth * Clean Code * Fix * Support interval range * Add Username --------- Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
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>());
|
||||
}
|
||||
|
||||
public 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;
|
||||
}
|
||||
|
||||
foreach (var child in childIds)
|
||||
{
|
||||
var childItem = await AppManager.Instance.GetProfileItem(child);
|
||||
if (await HasCycle(child, 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 new();
|
||||
}
|
||||
var items = await GetSelectedChildProfileItems(protocolExtra);
|
||||
var subItems = await GetSubChildProfileItems(protocolExtra);
|
||||
items.AddRange(subItems);
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public static async Task<List<ProfileItem>> GetSelectedChildProfileItems(ProtocolExtraItem? extra)
|
||||
{
|
||||
if (extra == null || extra.ChildItems.IsNullOrEmpty())
|
||||
{
|
||||
return new();
|
||||
}
|
||||
var childProfiles = (await Task.WhenAll(
|
||||
(Utils.String2List(extra.ChildItems) ?? new())
|
||||
.Where(p => !p.IsNullOrEmpty())
|
||||
.Select(AppManager.Instance.GetProfileItem)
|
||||
))
|
||||
.Where(p =>
|
||||
p != null &&
|
||||
p.IsValid() &&
|
||||
p.ConfigType != EConfigType.Custom
|
||||
)
|
||||
.ToList();
|
||||
return childProfiles;
|
||||
}
|
||||
|
||||
public static async Task<List<ProfileItem>> GetSubChildProfileItems(ProtocolExtraItem? extra)
|
||||
{
|
||||
if (extra == null || extra.SubChildItems.IsNullOrEmpty())
|
||||
{
|
||||
return new();
|
||||
}
|
||||
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() ?? new();
|
||||
}
|
||||
|
||||
public static async Task<HashSet<string>> GetAllChildDomainAddresses(ProfileItem profileItem)
|
||||
{
|
||||
var childAddresses = new HashSet<string>();
|
||||
var (childItems, _) = await GetChildProfileItems(profileItem);
|
||||
foreach (var child in childItems)
|
||||
{
|
||||
if (!child.IsComplex())
|
||||
{
|
||||
childAddresses.Add(child.Address);
|
||||
}
|
||||
else if (child.ConfigType.IsGroupType())
|
||||
{
|
||||
var subAddresses = await GetAllChildDomainAddresses(child);
|
||||
foreach (var addr in subAddresses)
|
||||
{
|
||||
childAddresses.Add(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return childAddresses;
|
||||
}
|
||||
|
||||
public static async Task<HashSet<string>> GetAllChildEchQuerySni(ProfileItem profileItem)
|
||||
{
|
||||
var childAddresses = new HashSet<string>();
|
||||
var (childItems, _) = await GetChildProfileItems(profileItem);
|
||||
foreach (var childNode in childItems)
|
||||
{
|
||||
if (!childNode.IsComplex() && !childNode.EchConfigList.IsNullOrEmpty())
|
||||
{
|
||||
if (childNode.StreamSecurity == Global.StreamSecurity
|
||||
&& childNode.EchConfigList?.Contains("://") == true)
|
||||
{
|
||||
var idx = childNode.EchConfigList.IndexOf('+');
|
||||
childAddresses.Add(idx > 0 ? childNode.EchConfigList[..idx] : childNode.Sni);
|
||||
}
|
||||
else
|
||||
{
|
||||
childAddresses.Add(childNode.Sni);
|
||||
}
|
||||
}
|
||||
else if (childNode.ConfigType.IsGroupType())
|
||||
{
|
||||
var subAddresses = await GetAllChildDomainAddresses(childNode);
|
||||
foreach (var addr in subAddresses)
|
||||
{
|
||||
childAddresses.Add(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return childAddresses;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user