This commit is contained in:
DHR60 2026-02-06 15:24:14 +08:00
parent a89471da92
commit f900ce7f3f
5 changed files with 130 additions and 57 deletions

View file

@ -95,13 +95,13 @@ public static class CoreConfigHandler
{ {
var result = new RetResult(); var result = new RetResult();
var context = await BuildCoreConfigContext(config, new()); var context = await BuildCoreConfigContext(config, new());
foreach (var serverTestItem in selecteds.Where(serverTestItem => !serverTestItem.IndexId.IsNullOrEmpty())) var ids = selecteds.Where(serverTestItem => !serverTestItem.IndexId.IsNullOrEmpty())
.Select(serverTestItem => serverTestItem.IndexId!)
.ToList();
foreach (var id in ids)
{ {
var node = await AppManager.Instance.GetProfileItem(serverTestItem.IndexId!); var node = await AppManager.Instance.GetProfileItem(id) ?? new();
if (node != null) await FillNodeContext(context, node, false);
{
await FillNodeContext(context, node, false);
}
} }
if (coreType == ECoreType.sing_box) if (coreType == ECoreType.sing_box)
{ {
@ -186,34 +186,37 @@ public static class CoreConfigHandler
return node; return node;
} }
context.AllProxiesMap[node.IndexId] = node; context.AllProxiesMap[node.IndexId] = node;
var newItems = new List<ProfileItem> { node };
if (node.ConfigType.IsGroupType()) if (node.ConfigType.IsGroupType())
{ {
var groupChildList = await GroupProfileManager.GetAllChildProfileItems(node); var groupChildList = await GroupProfileManager.GetAllChildProfileItems(node);
foreach (var childItem in groupChildList) foreach (var childItem in groupChildList)
{ {
context.AllProxiesMap[childItem.IndexId] = childItem; context.AllProxiesMap[childItem.IndexId] = childItem;
newItems.Add(childItem);
} }
} }
foreach (var profileItemPair in context.AllProxiesMap) foreach (var item in newItems)
{ {
var address = profileItemPair.Value.Address; var address = item.Address;
if (Utils.IsDomain(address)) if (Utils.IsDomain(address))
{ {
context.ProtectDomainList.Add(address); context.ProtectDomainList.Add(address);
} }
if (profileItemPair.Value.EchConfigList.IsNullOrEmpty()) if (item.EchConfigList.IsNullOrEmpty())
{ {
continue; continue;
} }
var echQuerySni = profileItemPair.Value.Sni; var echQuerySni = item.Sni;
if (profileItemPair.Value.StreamSecurity == Global.StreamSecurity if (item.StreamSecurity == Global.StreamSecurity
&& profileItemPair.Value.EchConfigList?.Contains("://") == true) && item.EchConfigList?.Contains("://") == true)
{ {
var idx = profileItemPair.Value.EchConfigList.IndexOf('+'); var idx = item.EchConfigList.IndexOf('+');
echQuerySni = idx > 0 ? profileItemPair.Value.EchConfigList[..idx] : profileItemPair.Value.Sni; echQuerySni = idx > 0 ? item.EchConfigList[..idx] : item.Sni;
} }
if (!Utils.IsDomain(echQuerySni)) if (!Utils.IsDomain(echQuerySni))
{ {

View file

@ -349,6 +349,7 @@ public partial class CoreConfigSingboxService
{ {
GenDnsServers(); GenDnsServers();
_coreConfig.dns ??= new(); _coreConfig.dns ??= new();
_coreConfig.dns.rules ??= [];
_coreConfig.dns.rules.Clear(); _coreConfig.dns.rules.Clear();
_coreConfig.dns.final = Global.SingboxDirectDNSTag; _coreConfig.dns.final = Global.SingboxDirectDNSTag;
_coreConfig.route.default_domain_resolver = new() _coreConfig.route.default_domain_resolver = new()

View file

@ -519,7 +519,7 @@ public partial class CoreConfigSingboxService
var outUrltest = new Outbound4Sbox var outUrltest = new Outbound4Sbox
{ {
type = "urltest", type = "urltest",
tag = $"{Global.ProxyTag}-auto", tag = $"{baseTagName}-auto",
outbounds = proxyTags, outbounds = proxyTags,
interrupt_exist_connections = false, interrupt_exist_connections = false,
}; };
@ -533,7 +533,7 @@ public partial class CoreConfigSingboxService
var outSelector = new Outbound4Sbox var outSelector = new Outbound4Sbox
{ {
type = "selector", type = "selector",
tag = Global.ProxyTag, tag = baseTagName,
outbounds = JsonUtils.DeepCopy(proxyTags), outbounds = JsonUtils.DeepCopy(proxyTags),
interrupt_exist_connections = false, interrupt_exist_connections = false,
}; };
@ -604,21 +604,39 @@ public partial class CoreConfigSingboxService
if (i != 0) if (i != 0)
{ {
var chainStartNodes = childProfiles.Where(n => n.tag.StartsWith(currentTag)).ToList(); var chainStartNodes = childProfiles.Where(n => n.tag.StartsWith(currentTag)).ToList();
var existedChainNodes = JsonUtils.DeepCopy(resultOutbounds); if (chainStartNodes.Count == 1)
resultOutbounds.Clear();
foreach (var chainStartNode in chainStartNodes)
{ {
var existedChainNodesClone = JsonUtils.DeepCopy(existedChainNodes); foreach (var existedChainEndNode in resultOutbounds.Where(n => n.detour == currentTag))
for (var j = 0; j < existedChainNodesClone.Count; j++)
{ {
var existedChainNode = existedChainNodesClone[j]; existedChainEndNode.detour = chainStartNodes.First().tag;
var cloneTag = $"{existedChainNode.tag}-clone-{j + 1}"; }
existedChainNode.tag = cloneTag; }
var previousDialerProxyTag = existedChainNode.detour; else if (chainStartNodes.Count > 1)
existedChainNode.detour = (previousDialerProxyTag == currentTag) {
? chainStartNode.tag var existedChainNodes = CloneOutbounds(resultOutbounds);
: existedChainNodesClone[j + 1].tag; resultOutbounds.Clear();
resultOutbounds.Add(existedChainNode); var j = 0;
foreach (var chainStartNode in chainStartNodes)
{
var existedChainNodesClone = CloneOutbounds(existedChainNodes);
foreach (var existedChainNode in existedChainNodesClone)
{
var cloneTag = $"{existedChainNode.tag}-clone-{j + 1}";
existedChainNode.tag = cloneTag;
}
for (var k = 0; k < existedChainNodesClone.Count; k++)
{
var existedChainNode = existedChainNodesClone[k];
var previousDialerProxyTag = existedChainNode.detour;
var nextTag = k + 1 < existedChainNodesClone.Count
? existedChainNodesClone[k + 1].tag
: chainStartNode.tag;
existedChainNode.detour = (previousDialerProxyTag == currentTag)
? chainStartNode.tag
: nextTag;
resultOutbounds.Add(existedChainNode);
}
j++;
} }
} }
} }
@ -639,6 +657,33 @@ public partial class CoreConfigSingboxService
return resultOutbounds; return resultOutbounds;
} }
private static List<BaseServer4Sbox> CloneOutbounds(List<BaseServer4Sbox> source)
{
if (source is null || source.Count == 0)
{
return [];
}
var result = new List<BaseServer4Sbox>(source.Count);
foreach (var item in source)
{
BaseServer4Sbox? clone = null;
if (item is Outbound4Sbox outbound)
{
clone = JsonUtils.DeepCopy(outbound);
}
else if (item is Endpoints4Sbox endpoint)
{
clone = JsonUtils.DeepCopy(endpoint);
}
if (clone is not null)
{
result.Add(clone);
}
}
return result;
}
private static void FillRangeProxy(List<BaseServer4Sbox> servers, SingboxConfig singboxConfig, bool prepend = true) private static void FillRangeProxy(List<BaseServer4Sbox> servers, SingboxConfig singboxConfig, bool prepend = true)
{ {
try try

View file

@ -83,8 +83,8 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
return ret; return ret;
} }
var v2rayConfig = JsonUtils.Deserialize<V2rayConfig>(result); _coreConfig = JsonUtils.Deserialize<V2rayConfig>(result);
if (v2rayConfig == null) if (_coreConfig == null)
{ {
ret.Msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret; return ret;
@ -103,9 +103,9 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
} }
GenLog(); GenLog();
v2rayConfig.inbounds.Clear(); _coreConfig.inbounds.Clear();
v2rayConfig.outbounds.Clear(); _coreConfig.outbounds.Clear();
v2rayConfig.routing.rules.Clear(); _coreConfig.routing.rules.Clear();
var initPort = AppManager.Instance.GetLocalPort(EInboundProtocol.speedtest); var initPort = AppManager.Instance.GetLocalPort(EInboundProtocol.speedtest);
@ -159,13 +159,14 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
protocol = EInboundProtocol.mixed.ToString(), protocol = EInboundProtocol.mixed.ToString(),
}; };
inbound.tag = inbound.protocol + inbound.port.ToString(); inbound.tag = inbound.protocol + inbound.port.ToString();
v2rayConfig.inbounds.Add(inbound); _coreConfig.inbounds.Add(inbound);
var tag = Global.ProxyTag + inbound.port.ToString(); var tag = Global.ProxyTag + inbound.port.ToString();
var isBalancer = false; var isBalancer = false;
//outbound //outbound
var proxyOutbounds = BuildAllProxyOutbounds(tag); var proxyOutbounds =
v2rayConfig.outbounds.AddRange(proxyOutbounds); new CoreConfigV2rayService(context with { Node = item }).BuildAllProxyOutbounds(tag);
_coreConfig.outbounds.AddRange(proxyOutbounds);
if (proxyOutbounds.Count(n => n.tag.StartsWith(tag)) > 1) if (proxyOutbounds.Count(n => n.tag.StartsWith(tag)) > 1)
{ {
isBalancer = true; isBalancer = true;
@ -186,12 +187,12 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
rule.balancerTag = tag; rule.balancerTag = tag;
rule.outboundTag = null; rule.outboundTag = null;
} }
v2rayConfig.routing.rules.Add(rule); _coreConfig.routing.rules.Add(rule);
} }
//ret.Msg =string.Format(ResUI.SuccessfulConfiguration"), node.getSummary()); //ret.Msg =string.Format(ResUI.SuccessfulConfiguration"), node.getSummary());
ret.Success = true; ret.Success = true;
ret.Data = JsonUtils.Serialize(v2rayConfig); ret.Data = JsonUtils.Serialize(_coreConfig);
return ret; return ret;
} }
catch (Exception ex) catch (Exception ex)
@ -228,8 +229,8 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
return ret; return ret;
} }
var v2rayConfig = JsonUtils.Deserialize<V2rayConfig>(result); _coreConfig = JsonUtils.Deserialize<V2rayConfig>(result);
if (v2rayConfig == null) if (_coreConfig == null)
{ {
ret.Msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret; return ret;
@ -238,9 +239,9 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
GenLog(); GenLog();
GenOutbounds(); GenOutbounds();
v2rayConfig.routing.rules.Clear(); _coreConfig.routing.rules.Clear();
v2rayConfig.inbounds.Clear(); _coreConfig.inbounds.Clear();
v2rayConfig.inbounds.Add(new() _coreConfig.inbounds.Add(new()
{ {
tag = $"{EInboundProtocol.socks}{port}", tag = $"{EInboundProtocol.socks}{port}",
listen = Global.Loopback, listen = Global.Loopback,
@ -250,7 +251,7 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, ""); ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
ret.Success = true; ret.Success = true;
ret.Data = JsonUtils.Serialize(v2rayConfig); ret.Data = JsonUtils.Serialize(_coreConfig);
return ret; return ret;
} }
catch (Exception ex) catch (Exception ex)

View file

@ -743,22 +743,45 @@ public partial class CoreConfigV2rayService
if (i != 0) if (i != 0)
{ {
var chainStartNodes = childProfiles.Where(n => n.tag.StartsWith(currentTag)).ToList(); var chainStartNodes = childProfiles.Where(n => n.tag.StartsWith(currentTag)).ToList();
var existedChainNodes = JsonUtils.DeepCopy(resultOutbounds); if (chainStartNodes.Count == 1)
resultOutbounds.Clear();
foreach (var chainStartNode in chainStartNodes)
{ {
var existedChainNodesClone = JsonUtils.DeepCopy(existedChainNodes); foreach (var existedChainEndNode in resultOutbounds.Where(n => n.streamSettings?.sockopt?.dialerProxy == currentTag))
for (var j = 0; j < existedChainNodesClone.Count; j++)
{ {
var existedChainNode = existedChainNodesClone[j]; existedChainEndNode.streamSettings.sockopt = new()
var cloneTag = $"{existedChainNode.tag}-clone-{j + 1}";
existedChainNode.tag = cloneTag;
var previousDialerProxyTag = existedChainNode.streamSettings?.sockopt?.dialerProxy;
existedChainNode.streamSettings.sockopt = new()
{ {
dialerProxy = (previousDialerProxyTag == currentTag) ? chainStartNode.tag : existedChainNodesClone[j + 1].tag dialerProxy = chainStartNodes.First().tag
}; };
resultOutbounds.Add(existedChainNode); }
}
else if (chainStartNodes.Count > 1)
{
var existedChainNodes = JsonUtils.DeepCopy(resultOutbounds);
resultOutbounds.Clear();
var j = 0;
foreach (var chainStartNode in chainStartNodes)
{
var existedChainNodesClone = JsonUtils.DeepCopy(existedChainNodes);
foreach (var existedChainNode in existedChainNodesClone)
{
var cloneTag = $"{existedChainNode.tag}-clone-{j + 1}";
existedChainNode.tag = cloneTag;
}
for (var k = 0; k < existedChainNodesClone.Count; k++)
{
var existedChainNode = existedChainNodesClone[k];
var previousDialerProxyTag = existedChainNode.streamSettings?.sockopt?.dialerProxy;
var nextTag = k + 1 < existedChainNodesClone.Count
? existedChainNodesClone[k + 1].tag
: chainStartNode.tag;
existedChainNode.streamSettings.sockopt = new()
{
dialerProxy = (previousDialerProxyTag == currentTag)
? chainStartNode.tag
: nextTag
};
resultOutbounds.Add(existedChainNode);
}
j++;
} }
} }
} }