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;
|
var tun2SocksAddress = node.Address;
|
||||||
if (node.ConfigType > EConfigType.Group)
|
if (node.ConfigType > EConfigType.Group)
|
||||||
{
|
{
|
||||||
static async Task<List<string>> GetChildNodeAddressesAsync(string parentIndexId)
|
var lstAddresses = (await ProfileGroupItemManager.GetAllChildDomainAddresses(node.IndexId)).ToList();
|
||||||
{
|
|
||||||
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);
|
|
||||||
if (lstAddresses.Count > 0)
|
if (lstAddresses.Count > 0)
|
||||||
{
|
{
|
||||||
tun2SocksAddress = Utils.List2String(lstAddresses);
|
tun2SocksAddress = Utils.List2String(lstAddresses);
|
||||||
|
|
|
@ -100,7 +100,6 @@ public sealed class AppManager
|
||||||
|
|
||||||
await ConfigHandler.SaveConfig(_config);
|
await ConfigHandler.SaveConfig(_config);
|
||||||
await ProfileExManager.Instance.SaveTo();
|
await ProfileExManager.Instance.SaveTo();
|
||||||
await ProfileGroupItemManager.Instance.SaveTo();
|
|
||||||
await StatisticsManager.Instance.SaveTo();
|
await StatisticsManager.Instance.SaveTo();
|
||||||
await CoreManager.Instance.CoreStop();
|
await CoreManager.Instance.CoreStop();
|
||||||
StatisticsManager.Instance.Close();
|
StatisticsManager.Instance.Close();
|
||||||
|
|
|
@ -164,4 +164,113 @@ public class ProfileGroupItemManager
|
||||||
Logging.SaveLog(_tag, ex);
|
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 ConfigHandler.SaveConfig(_config);
|
||||||
await ProfileExManager.Instance.SaveTo();
|
await ProfileExManager.Instance.SaveTo();
|
||||||
await ProfileGroupItemManager.Instance.SaveTo();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Execute once 1 hour
|
//Execute once 1 hour
|
||||||
|
|
|
@ -11,48 +11,4 @@ public class ProfileGroupItem
|
||||||
public string ChildItems { get; set; }
|
public string ChildItems { get; set; }
|
||||||
|
|
||||||
public EMultipleLoad MultipleLoad { get; set; } = EMultipleLoad.LeastPing;
|
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;
|
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
|
#endregion function
|
||||||
|
|
||||||
[PrimaryKey]
|
[PrimaryKey]
|
||||||
|
|
|
@ -212,33 +212,13 @@ public partial class CoreConfigSingboxService
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ProfileGroupItemManager.Instance.TryGet(node.IndexId, out var profileGroupItem);
|
var hasCycle = ProfileGroupItemManager.HasCycle(node.IndexId);
|
||||||
if (profileGroupItem is null || profileGroupItem.ChildItems.IsNullOrEmpty())
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
var hasCycle = await node.HasCycle(new HashSet<string>(), new HashSet<string>());
|
|
||||||
if (hasCycle)
|
if (hasCycle)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove custom nodes
|
var (childProfiles, profileGroupItem) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId);
|
||||||
// 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();
|
|
||||||
|
|
||||||
if (childProfiles.Count <= 0)
|
if (childProfiles.Count <= 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -514,16 +494,7 @@ public partial class CoreConfigSingboxService
|
||||||
|
|
||||||
if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
|
if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
|
||||||
{
|
{
|
||||||
ProfileGroupItemManager.Instance.TryGet(node.IndexId, out var profileGroupItem);
|
var (childProfiles, profileGroupItem) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId);
|
||||||
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();
|
|
||||||
if (childProfiles.Count <= 0)
|
if (childProfiles.Count <= 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -698,16 +669,7 @@ public partial class CoreConfigSingboxService
|
||||||
continue;
|
continue;
|
||||||
if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
|
if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
|
||||||
{
|
{
|
||||||
ProfileGroupItemManager.Instance.TryGet(node.IndexId, out var profileGroupItem);
|
var (childProfiles, profileGroupItem) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId);
|
||||||
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();
|
|
||||||
if (childProfiles.Count <= 0)
|
if (childProfiles.Count <= 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
using ServiceLib.Models;
|
|
||||||
|
|
||||||
namespace ServiceLib.Services.CoreConfig;
|
namespace ServiceLib.Services.CoreConfig;
|
||||||
|
|
||||||
public partial class CoreConfigV2rayService
|
public partial class CoreConfigV2rayService
|
||||||
|
@ -490,34 +488,13 @@ public partial class CoreConfigV2rayService
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ProfileGroupItemManager.Instance.TryGet(node.IndexId, out var profileGroupItem);
|
var hasCycle = ProfileGroupItemManager.HasCycle(node.IndexId);
|
||||||
if (profileGroupItem is null || profileGroupItem.ChildItems.IsNullOrEmpty())
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
var hasCycle = profileGroupItem.HasCycle();
|
|
||||||
//var hasCycle = await node.HasCycle(new HashSet<string>(), new HashSet<string>());
|
|
||||||
if (hasCycle)
|
if (hasCycle)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove custom nodes
|
var (childProfiles, profileGroupItem) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId);
|
||||||
// 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();
|
|
||||||
|
|
||||||
if (childProfiles.Count <= 0)
|
if (childProfiles.Count <= 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -654,16 +631,7 @@ public partial class CoreConfigV2rayService
|
||||||
|
|
||||||
if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
|
if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
|
||||||
{
|
{
|
||||||
ProfileGroupItemManager.Instance.TryGet(node.IndexId, out var profileGroupItem);
|
var (childProfiles, _) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId);
|
||||||
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();
|
|
||||||
if (childProfiles.Count <= 0)
|
if (childProfiles.Count <= 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -814,16 +782,7 @@ public partial class CoreConfigV2rayService
|
||||||
continue;
|
continue;
|
||||||
if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
|
if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
|
||||||
{
|
{
|
||||||
ProfileGroupItemManager.Instance.TryGet(node.IndexId, out var profileGroupItem);
|
var (childProfiles, _) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId);
|
||||||
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();
|
|
||||||
if (childProfiles.Count <= 0)
|
if (childProfiles.Count <= 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in a new issue