mirror of
https://github.com/2dust/v2rayN.git
synced 2025-10-13 20:09:12 +00:00
Compare commits
2 commits
6808595fa1
...
224f9b1c95
Author | SHA1 | Date | |
---|---|---|---|
![]() |
224f9b1c95 | ||
![]() |
25f8730021 |
8 changed files with 118 additions and 198 deletions
|
@ -1257,35 +1257,7 @@ public static class ConfigHandler
|
|||
var tun2SocksAddress = node.Address;
|
||||
if (node.ConfigType > EConfigType.Group)
|
||||
{
|
||||
static async Task<List<string>> GetChildNodeAddressesAsync(string parentIndexId)
|
||||
{
|
||||
var childAddresses = new List<string>();
|
||||
if (!ProfileGroupItemManager.Instance.TryGet(parentIndexId, out var groupItem) || groupItem.ChildItems.IsNullOrEmpty())
|
||||
return childAddresses;
|
||||
|
||||
var childIds = Utils.String2List(groupItem.ChildItems);
|
||||
|
||||
foreach (var childId in childIds)
|
||||
{
|
||||
var childNode = await AppManager.Instance.GetProfileItem(childId);
|
||||
if (childNode == null)
|
||||
continue;
|
||||
|
||||
if (!childNode.IsComplex())
|
||||
{
|
||||
childAddresses.Add(childNode.Address);
|
||||
}
|
||||
else if (childNode.ConfigType > EConfigType.Group)
|
||||
{
|
||||
var subAddresses = await GetChildNodeAddressesAsync(childNode.IndexId);
|
||||
childAddresses.AddRange(subAddresses);
|
||||
}
|
||||
}
|
||||
|
||||
return childAddresses;
|
||||
}
|
||||
|
||||
var lstAddresses = await GetChildNodeAddressesAsync(node.IndexId);
|
||||
var lstAddresses = (await ProfileGroupItemManager.GetAllChildDomainAddresses(node.IndexId)).ToList();
|
||||
if (lstAddresses.Count > 0)
|
||||
{
|
||||
tun2SocksAddress = Utils.List2String(lstAddresses);
|
||||
|
|
|
@ -100,7 +100,6 @@ public sealed class AppManager
|
|||
|
||||
await ConfigHandler.SaveConfig(_config);
|
||||
await ProfileExManager.Instance.SaveTo();
|
||||
await ProfileGroupItemManager.Instance.SaveTo();
|
||||
await StatisticsManager.Instance.SaveTo();
|
||||
await CoreManager.Instance.CoreStop();
|
||||
StatisticsManager.Instance.Close();
|
||||
|
|
|
@ -164,4 +164,113 @@ public class ProfileGroupItemManager
|
|||
Logging.SaveLog(_tag, ex);
|
||||
}
|
||||
}
|
||||
|
||||
#region Helper
|
||||
|
||||
public static bool HasCycle(string? indexId)
|
||||
{
|
||||
return HasCycle(indexId, new HashSet<string>(), new HashSet<string>());
|
||||
}
|
||||
|
||||
public static bool HasCycle(string? indexId, HashSet<string> visited, HashSet<string> stack)
|
||||
{
|
||||
if (indexId.IsNullOrEmpty())
|
||||
return false;
|
||||
|
||||
if (stack.Contains(indexId))
|
||||
return true;
|
||||
|
||||
if (visited.Contains(indexId))
|
||||
return false;
|
||||
|
||||
visited.Add(indexId);
|
||||
stack.Add(indexId);
|
||||
|
||||
Instance.TryGet(indexId, out var groupItem);
|
||||
|
||||
if (groupItem == null || groupItem.ChildItems.IsNullOrEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var childIds = Utils.String2List(groupItem.ChildItems)
|
||||
.Where(p => !string.IsNullOrEmpty(p))
|
||||
.ToList();
|
||||
|
||||
foreach (var child in childIds)
|
||||
{
|
||||
if (HasCycle(child, visited, stack))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
stack.Remove(indexId);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static async Task<(List<ProfileItem> Items, ProfileGroupItem? Group)> GetChildProfileItems(string? indexId)
|
||||
{
|
||||
Instance.TryGet(indexId, out var profileGroupItem);
|
||||
if (profileGroupItem == null || profileGroupItem.ChildItems.IsNullOrEmpty())
|
||||
{
|
||||
return (new List<ProfileItem>(), profileGroupItem);
|
||||
}
|
||||
var items = await GetChildProfileItems(profileGroupItem);
|
||||
return (items, profileGroupItem);
|
||||
}
|
||||
|
||||
public static async Task<List<ProfileItem>> GetChildProfileItems(ProfileGroupItem? group)
|
||||
{
|
||||
if (group == null || group.ChildItems.IsNullOrEmpty())
|
||||
{
|
||||
return new();
|
||||
}
|
||||
var childProfiles = (await Task.WhenAll(
|
||||
Utils.String2List(group.ChildItems)
|
||||
.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<HashSet<string>> GetAllChildDomainAddresses(string parentIndexId)
|
||||
{
|
||||
// include grand children
|
||||
var childAddresses = new HashSet<string>();
|
||||
if (!Instance.TryGet(parentIndexId, out var groupItem) || groupItem.ChildItems.IsNullOrEmpty())
|
||||
return childAddresses;
|
||||
|
||||
var childIds = Utils.String2List(groupItem.ChildItems);
|
||||
|
||||
foreach (var childId in childIds)
|
||||
{
|
||||
var childNode = await AppManager.Instance.GetProfileItem(childId);
|
||||
if (childNode == null)
|
||||
continue;
|
||||
|
||||
if (!childNode.IsComplex())
|
||||
{
|
||||
childAddresses.Add(childNode.Address);
|
||||
}
|
||||
else if (childNode.ConfigType > EConfigType.Group)
|
||||
{
|
||||
var subAddresses = await GetAllChildDomainAddresses(childNode.IndexId);
|
||||
foreach (var addr in subAddresses)
|
||||
{
|
||||
childAddresses.Add(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return childAddresses;
|
||||
}
|
||||
|
||||
#endregion Helper
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ public class TaskManager
|
|||
|
||||
await ConfigHandler.SaveConfig(_config);
|
||||
await ProfileExManager.Instance.SaveTo();
|
||||
await ProfileGroupItemManager.Instance.SaveTo();
|
||||
}
|
||||
|
||||
//Execute once 1 hour
|
||||
|
|
|
@ -11,48 +11,4 @@ public class ProfileGroupItem
|
|||
public string ChildItems { get; set; }
|
||||
|
||||
public EMultipleLoad MultipleLoad { get; set; } = EMultipleLoad.LeastPing;
|
||||
|
||||
public bool HasCycle()
|
||||
{
|
||||
return HasCycle(new HashSet<string>(), new HashSet<string>());
|
||||
}
|
||||
|
||||
public bool HasCycle(HashSet<string> visited, HashSet<string> stack)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ParentIndexId))
|
||||
return false;
|
||||
|
||||
if (stack.Contains(ParentIndexId))
|
||||
return true;
|
||||
|
||||
if (visited.Contains(ParentIndexId))
|
||||
return false;
|
||||
|
||||
visited.Add(ParentIndexId);
|
||||
stack.Add(ParentIndexId);
|
||||
|
||||
if (string.IsNullOrEmpty(ChildItems))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var childIds = Utils.String2List(ChildItems)
|
||||
.Where(p => !string.IsNullOrEmpty(p))
|
||||
.ToList();
|
||||
|
||||
var childProfiles = childIds.Select(ProfileGroupItemManager.Instance.GetOrDefault)//这里是内存访问
|
||||
.Where(p => p != null)
|
||||
.ToList();
|
||||
|
||||
foreach (var child in childProfiles)
|
||||
{
|
||||
if (child.HasCycle(visited, stack))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
stack.Remove(ParentIndexId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,42 +109,6 @@ public class ProfileItem : ReactiveObject
|
|||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> HasCycle(HashSet<string> visited, HashSet<string> stack)
|
||||
{
|
||||
if (ConfigType < EConfigType.Group)
|
||||
return false;
|
||||
|
||||
if (stack.Contains(IndexId))
|
||||
return true;
|
||||
|
||||
if (visited.Contains(IndexId))
|
||||
return false;
|
||||
|
||||
visited.Add(IndexId);
|
||||
stack.Add(IndexId);
|
||||
|
||||
if (ProfileGroupItemManager.Instance.TryGet(IndexId, out var group)
|
||||
&& !group.ChildItems.IsNullOrEmpty())
|
||||
{
|
||||
var childProfiles = (await Task.WhenAll(
|
||||
Utils.String2List(group.ChildItems)
|
||||
.Where(p => !p.IsNullOrEmpty())
|
||||
.Select(AppManager.Instance.GetProfileItem)
|
||||
))
|
||||
.Where(p => p != null)
|
||||
.ToList();
|
||||
|
||||
foreach (var child in childProfiles)
|
||||
{
|
||||
if (await child.HasCycle(visited, stack))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
stack.Remove(IndexId);
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion function
|
||||
|
||||
[PrimaryKey]
|
||||
|
|
|
@ -212,33 +212,13 @@ public partial class CoreConfigSingboxService
|
|||
{
|
||||
return -1;
|
||||
}
|
||||
ProfileGroupItemManager.Instance.TryGet(node.IndexId, out var profileGroupItem);
|
||||
if (profileGroupItem is null || profileGroupItem.ChildItems.IsNullOrEmpty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
var hasCycle = await node.HasCycle(new HashSet<string>(), new HashSet<string>());
|
||||
var hasCycle = ProfileGroupItemManager.HasCycle(node.IndexId);
|
||||
if (hasCycle)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// remove custom nodes
|
||||
// remove group nodes for proxy chain
|
||||
var childProfiles = (await Task.WhenAll(
|
||||
Utils.String2List(profileGroupItem.ChildItems)
|
||||
.Where(p => !p.IsNullOrEmpty())
|
||||
.Select(AppManager.Instance.GetProfileItem)
|
||||
))
|
||||
.Where(p =>
|
||||
p != null
|
||||
&& p.IsValid()
|
||||
&& p.ConfigType != EConfigType.Custom
|
||||
&& (node.ConfigType == EConfigType.PolicyGroup || p.ConfigType < EConfigType.Group)
|
||||
)
|
||||
.ToList();
|
||||
|
||||
var (childProfiles, profileGroupItem) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId);
|
||||
if (childProfiles.Count <= 0)
|
||||
{
|
||||
return -1;
|
||||
|
@ -514,16 +494,7 @@ public partial class CoreConfigSingboxService
|
|||
|
||||
if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
|
||||
{
|
||||
ProfileGroupItemManager.Instance.TryGet(node.IndexId, out var profileGroupItem);
|
||||
if (profileGroupItem == null || profileGroupItem.ChildItems.IsNullOrEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var childProfiles = (await Task.WhenAll(
|
||||
Utils.String2List(profileGroupItem.ChildItems)
|
||||
.Where(p => !p.IsNullOrEmpty())
|
||||
.Select(AppManager.Instance.GetProfileItem)
|
||||
)).Where(p => p != null).ToList();
|
||||
var (childProfiles, profileGroupItem) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId);
|
||||
if (childProfiles.Count <= 0)
|
||||
{
|
||||
continue;
|
||||
|
@ -698,16 +669,7 @@ public partial class CoreConfigSingboxService
|
|||
continue;
|
||||
if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
|
||||
{
|
||||
ProfileGroupItemManager.Instance.TryGet(node.IndexId, out var profileGroupItem);
|
||||
if (profileGroupItem == null || profileGroupItem.ChildItems.IsNullOrEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var childProfiles = (await Task.WhenAll(
|
||||
Utils.String2List(profileGroupItem.ChildItems)
|
||||
.Where(p => !p.IsNullOrEmpty())
|
||||
.Select(AppManager.Instance.GetProfileItem)
|
||||
)).Where(p => p != null).ToList();
|
||||
var (childProfiles, profileGroupItem) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId);
|
||||
if (childProfiles.Count <= 0)
|
||||
{
|
||||
continue;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
using ServiceLib.Models;
|
||||
|
||||
namespace ServiceLib.Services.CoreConfig;
|
||||
|
||||
public partial class CoreConfigV2rayService
|
||||
|
@ -490,34 +488,13 @@ public partial class CoreConfigV2rayService
|
|||
{
|
||||
return -1;
|
||||
}
|
||||
ProfileGroupItemManager.Instance.TryGet(node.IndexId, out var profileGroupItem);
|
||||
if (profileGroupItem is null || profileGroupItem.ChildItems.IsNullOrEmpty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
var hasCycle = profileGroupItem.HasCycle();
|
||||
//var hasCycle = await node.HasCycle(new HashSet<string>(), new HashSet<string>());
|
||||
var hasCycle = ProfileGroupItemManager.HasCycle(node.IndexId);
|
||||
if (hasCycle)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// remove custom nodes
|
||||
// remove group nodes for proxy chain
|
||||
var childProfiles = (await Task.WhenAll(
|
||||
Utils.String2List(profileGroupItem.ChildItems)
|
||||
.Where(p => !p.IsNullOrEmpty())
|
||||
.Select(AppManager.Instance.GetProfileItem)
|
||||
))
|
||||
.Where(p =>
|
||||
p != null &&
|
||||
p.IsValid() &&
|
||||
p.ConfigType != EConfigType.Custom &&
|
||||
(node.ConfigType == EConfigType.PolicyGroup || p.ConfigType < EConfigType.Group)
|
||||
)
|
||||
.ToList();
|
||||
|
||||
var (childProfiles, profileGroupItem) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId);
|
||||
if (childProfiles.Count <= 0)
|
||||
{
|
||||
return -1;
|
||||
|
@ -654,16 +631,7 @@ public partial class CoreConfigV2rayService
|
|||
|
||||
if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
|
||||
{
|
||||
ProfileGroupItemManager.Instance.TryGet(node.IndexId, out var profileGroupItem);
|
||||
if (profileGroupItem == null || profileGroupItem.ChildItems.IsNullOrEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var childProfiles = (await Task.WhenAll(
|
||||
Utils.String2List(profileGroupItem.ChildItems)
|
||||
.Where(p => !p.IsNullOrEmpty())
|
||||
.Select(AppManager.Instance.GetProfileItem)
|
||||
)).Where(p => p != null).ToList();
|
||||
var (childProfiles, _) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId);
|
||||
if (childProfiles.Count <= 0)
|
||||
{
|
||||
continue;
|
||||
|
@ -814,16 +782,7 @@ public partial class CoreConfigV2rayService
|
|||
continue;
|
||||
if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
|
||||
{
|
||||
ProfileGroupItemManager.Instance.TryGet(node.IndexId, out var profileGroupItem);
|
||||
if (profileGroupItem == null || profileGroupItem.ChildItems.IsNullOrEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var childProfiles = (await Task.WhenAll(
|
||||
Utils.String2List(profileGroupItem.ChildItems)
|
||||
.Where(p => !p.IsNullOrEmpty())
|
||||
.Select(AppManager.Instance.GetProfileItem)
|
||||
)).Where(p => p != null).ToList();
|
||||
var (childProfiles, _) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId);
|
||||
if (childProfiles.Count <= 0)
|
||||
{
|
||||
continue;
|
||||
|
|
Loading…
Reference in a new issue