mirror of
https://github.com/2dust/v2rayN.git
synced 2025-10-13 20:09:12 +00:00
Add group in traffic splitting support
This commit is contained in:
parent
af62d9e0f4
commit
2d5a5465df
9 changed files with 115 additions and 17 deletions
|
@ -50,6 +50,7 @@ public class Global
|
|||
public const string DirectTag = "direct";
|
||||
public const string BlockTag = "block";
|
||||
public const string DnsTag = "dns-module";
|
||||
public const string BalancerTagSuffix = "-round";
|
||||
public const string StreamSecurity = "tls";
|
||||
public const string StreamSecurityReality = "reality";
|
||||
public const string Loopback = "127.0.0.1";
|
||||
|
|
|
@ -398,12 +398,12 @@ public partial class CoreConfigSingboxService(Config config)
|
|||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||
return ret;
|
||||
}
|
||||
singboxConfig.outbounds.RemoveAt(0);
|
||||
|
||||
await GenLog(singboxConfig);
|
||||
await GenInbounds(singboxConfig);
|
||||
await GenRouting(singboxConfig);
|
||||
await GenExperimental(singboxConfig);
|
||||
singboxConfig.outbounds.RemoveAt(0);
|
||||
|
||||
var proxyProfiles = new List<ProfileItem>();
|
||||
foreach (var it in selecteds)
|
||||
|
|
|
@ -368,6 +368,39 @@ public partial class CoreConfigSingboxService
|
|||
}
|
||||
|
||||
var node = await AppManager.Instance.GetProfileItemViaRemarks(outboundTag);
|
||||
|
||||
if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
|
||||
{
|
||||
ProfileGroupItemManager.Instance.TryGet(node.IndexId, out var profileGroupItem);
|
||||
if (profileGroupItem == null || profileGroupItem.ChildItems.IsNullOrEmpty())
|
||||
{
|
||||
return Global.ProxyTag;
|
||||
}
|
||||
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)
|
||||
{
|
||||
return Global.ProxyTag;
|
||||
}
|
||||
var childBaseTagName = $"{Global.ProxyTag}-{node.IndexId}";
|
||||
var ret = node.ConfigType switch
|
||||
{
|
||||
EConfigType.PolicyGroup =>
|
||||
await GenOutboundsList(childProfiles, singboxConfig, profileGroupItem.MultipleLoad, childBaseTagName),
|
||||
EConfigType.ProxyChain =>
|
||||
await GenChainOutboundsList(childProfiles, singboxConfig, childBaseTagName),
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
if (ret == 0)
|
||||
{
|
||||
return childBaseTagName;
|
||||
}
|
||||
return Global.ProxyTag;
|
||||
}
|
||||
|
||||
if (node == null
|
||||
|| !Global.SingboxSupportConfigType.Contains(node.ConfigType))
|
||||
{
|
||||
|
|
|
@ -126,13 +126,13 @@ public partial class CoreConfigV2rayService(Config config)
|
|||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||
return ret;
|
||||
}
|
||||
v2rayConfig.outbounds.RemoveAt(0);
|
||||
|
||||
await GenLog(v2rayConfig);
|
||||
await GenInbounds(v2rayConfig);
|
||||
await GenRouting(v2rayConfig);
|
||||
await GenDns(null, v2rayConfig);
|
||||
await GenStatistic(v2rayConfig);
|
||||
v2rayConfig.outbounds.RemoveAt(0);
|
||||
|
||||
var proxyProfiles = new List<ProfileItem>();
|
||||
foreach (var it in selecteds)
|
||||
|
@ -183,18 +183,37 @@ public partial class CoreConfigV2rayService(Config config)
|
|||
await GenOutboundsList(proxyProfiles, v2rayConfig);
|
||||
|
||||
//add balancers
|
||||
await GenObservatory(v2rayConfig, multipleLoad);
|
||||
await GenBalancer(v2rayConfig, multipleLoad);
|
||||
|
||||
var balancer = v2rayConfig.routing.balancers.First();
|
||||
var defaultBalancerTag = $"{Global.ProxyTag}{Global.BalancerTagSuffix}";
|
||||
|
||||
//add rule
|
||||
var rules = v2rayConfig.routing.rules.Where(t => t.outboundTag == Global.ProxyTag).ToList();
|
||||
var rules = v2rayConfig.routing.rules;
|
||||
if (rules?.Count > 0)
|
||||
{
|
||||
var balancerTagSet = v2rayConfig.routing.balancers
|
||||
.Select(b => b.tag)
|
||||
.ToHashSet();
|
||||
|
||||
foreach (var rule in rules)
|
||||
{
|
||||
if (rule.outboundTag == null)
|
||||
continue;
|
||||
|
||||
if (balancerTagSet.Contains(rule.outboundTag))
|
||||
{
|
||||
rule.balancerTag = rule.outboundTag;
|
||||
rule.outboundTag = null;
|
||||
rule.balancerTag = balancer.tag;
|
||||
continue;
|
||||
}
|
||||
|
||||
var outboundWithSuffix = rule.outboundTag + Global.BalancerTagSuffix;
|
||||
if (balancerTagSet.Contains(outboundWithSuffix))
|
||||
{
|
||||
rule.balancerTag = outboundWithSuffix;
|
||||
rule.outboundTag = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (v2rayConfig.routing.domainStrategy == Global.IPIfNonMatch)
|
||||
|
@ -202,7 +221,7 @@ public partial class CoreConfigV2rayService(Config config)
|
|||
v2rayConfig.routing.rules.Add(new()
|
||||
{
|
||||
ip = ["0.0.0.0/0", "::/0"],
|
||||
balancerTag = balancer.tag,
|
||||
balancerTag = defaultBalancerTag,
|
||||
type = "field"
|
||||
});
|
||||
}
|
||||
|
@ -211,7 +230,7 @@ public partial class CoreConfigV2rayService(Config config)
|
|||
v2rayConfig.routing.rules.Add(new()
|
||||
{
|
||||
network = "tcp,udp",
|
||||
balancerTag = balancer.tag,
|
||||
balancerTag = defaultBalancerTag,
|
||||
type = "field"
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ namespace ServiceLib.Services.CoreConfig;
|
|||
|
||||
public partial class CoreConfigV2rayService
|
||||
{
|
||||
private async Task<int> GenBalancer(V2rayConfig v2rayConfig, EMultipleLoad multipleLoad)
|
||||
private async Task<int> GenObservatory(V2rayConfig v2rayConfig, EMultipleLoad multipleLoad)
|
||||
{
|
||||
if (multipleLoad == EMultipleLoad.LeastPing)
|
||||
{
|
||||
|
@ -30,6 +30,11 @@ public partial class CoreConfigV2rayService
|
|||
};
|
||||
v2rayConfig.burstObservatory = burstObservatory;
|
||||
}
|
||||
return await Task.FromResult(0);
|
||||
}
|
||||
|
||||
private async Task<string> GenBalancer(V2rayConfig v2rayConfig, EMultipleLoad multipleLoad, string selector = Global.ProxyTag)
|
||||
{
|
||||
var strategyType = multipleLoad switch
|
||||
{
|
||||
EMultipleLoad.Random => "random",
|
||||
|
@ -38,9 +43,10 @@ public partial class CoreConfigV2rayService
|
|||
EMultipleLoad.LeastLoad => "leastLoad",
|
||||
_ => "roundRobin",
|
||||
};
|
||||
var balancerTag = $"{selector}{Global.BalancerTagSuffix}";
|
||||
var balancer = new BalancersItem4Ray
|
||||
{
|
||||
selector = [Global.ProxyTag],
|
||||
selector = [selector],
|
||||
strategy = new()
|
||||
{
|
||||
type = strategyType,
|
||||
|
@ -49,9 +55,10 @@ public partial class CoreConfigV2rayService
|
|||
expected = 1,
|
||||
},
|
||||
},
|
||||
tag = $"{Global.ProxyTag}-round",
|
||||
tag = balancerTag,
|
||||
};
|
||||
v2rayConfig.routing.balancers = [balancer];
|
||||
return await Task.FromResult(0);
|
||||
v2rayConfig.routing.balancers ??= new();
|
||||
v2rayConfig.routing.balancers.Add(balancer);
|
||||
return await Task.FromResult(balancerTag);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -746,14 +746,15 @@ public partial class CoreConfigV2rayService
|
|||
}
|
||||
else
|
||||
{
|
||||
outbound.tag = baseTagName + i.ToString();
|
||||
// avoid v2ray observe
|
||||
outbound.tag = "chain-" + baseTagName + i.ToString();
|
||||
}
|
||||
|
||||
if (i != nodes.Count - 1)
|
||||
{
|
||||
outbound.streamSettings.sockopt = new()
|
||||
{
|
||||
dialerProxy = baseTagName + (i + 1).ToString()
|
||||
dialerProxy = "chain-" + baseTagName + (i + 1).ToString()
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -125,6 +125,43 @@ public partial class CoreConfigV2rayService
|
|||
}
|
||||
|
||||
var node = await AppManager.Instance.GetProfileItemViaRemarks(outboundTag);
|
||||
|
||||
if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
|
||||
{
|
||||
ProfileGroupItemManager.Instance.TryGet(node.IndexId, out var profileGroupItem);
|
||||
if (profileGroupItem == null || profileGroupItem.ChildItems.IsNullOrEmpty())
|
||||
{
|
||||
return Global.ProxyTag;
|
||||
}
|
||||
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)
|
||||
{
|
||||
return Global.ProxyTag;
|
||||
}
|
||||
var childBaseTagName = $"{Global.ProxyTag}-{node.IndexId}";
|
||||
var ret = node.ConfigType switch
|
||||
{
|
||||
EConfigType.PolicyGroup =>
|
||||
await GenOutboundsList(childProfiles, v2rayConfig, childBaseTagName),
|
||||
EConfigType.ProxyChain =>
|
||||
await GenChainOutboundsList(childProfiles, v2rayConfig, childBaseTagName),
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
if (node.ConfigType == EConfigType.PolicyGroup)
|
||||
{
|
||||
await GenBalancer(v2rayConfig, profileGroupItem.MultipleLoad, childBaseTagName);
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
return childBaseTagName;
|
||||
}
|
||||
return Global.ProxyTag;
|
||||
}
|
||||
|
||||
if (node == null
|
||||
|| !Global.XraySupportConfigType.Contains(node.ConfigType))
|
||||
{
|
||||
|
|
|
@ -97,7 +97,7 @@ public partial class RoutingRuleDetailsWindow : WindowBase<RoutingRuleDetailsVie
|
|||
private async void BtnSelectProfile_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
var selectWindow = new ProfilesSelectWindow();
|
||||
selectWindow.SetConfigTypeFilter(new[] { EConfigType.Custom, EConfigType.PolicyGroup, EConfigType.ProxyChain }, exclude: true);
|
||||
selectWindow.SetConfigTypeFilter(new[] { EConfigType.Custom }, exclude: true);
|
||||
var result = await selectWindow.ShowDialog<bool?>(this);
|
||||
if (result == true)
|
||||
{
|
||||
|
|
|
@ -91,7 +91,7 @@ public partial class RoutingRuleDetailsWindow
|
|||
private async void BtnSelectProfile_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var selectWindow = new ProfilesSelectWindow();
|
||||
selectWindow.SetConfigTypeFilter(new[] { EConfigType.Custom, EConfigType.PolicyGroup, EConfigType.ProxyChain }, exclude: true);
|
||||
selectWindow.SetConfigTypeFilter(new[] { EConfigType.Custom }, exclude: true);
|
||||
if (selectWindow.ShowDialog() == true)
|
||||
{
|
||||
var profile = await selectWindow.ProfileItem;
|
||||
|
|
Loading…
Reference in a new issue