Update On Sun Mar 1 19:45:37 CET 2026

This commit is contained in:
github-action[bot]
2026-03-01 19:45:38 +01:00
parent b5662fef38
commit af8c3ce29e
290 changed files with 5564 additions and 2007 deletions
@@ -5,6 +5,39 @@ public record CoreConfigContextBuilderResult(CoreConfigContext Context, NodeVali
public bool Success => ValidatorResult.Success;
}
/// <summary>
/// Holds the results of a full context build, including the main context and an optional
/// pre-socks context (e.g. for TUN protection or pre-socks chaining).
/// </summary>
public record CoreConfigContextBuilderAllResult(
CoreConfigContextBuilderResult MainResult,
CoreConfigContextBuilderResult? PreSocksResult)
{
/// <summary>True only when both the main result and (if present) the pre-socks result succeeded.</summary>
public bool Success => MainResult.Success && (PreSocksResult?.Success ?? true);
/// <summary>
/// Merges all errors and warnings from the main result and the optional pre-socks result
/// into a single <see cref="NodeValidatorResult"/> for unified notification.
/// </summary>
public NodeValidatorResult CombinedValidatorResult => new(
[.. MainResult.ValidatorResult.Errors, .. PreSocksResult?.ValidatorResult.Errors ?? []],
[.. MainResult.ValidatorResult.Warnings, .. PreSocksResult?.ValidatorResult.Warnings ?? []]);
/// <summary>
/// The main context with TunProtectSsPort/ProxyRelaySsPort and ProtectDomainList merged in
/// from the pre-socks result (if any). Pass this to the core runner.
/// </summary>
public CoreConfigContext ResolvedMainContext => PreSocksResult is not null
? MainResult.Context with
{
TunProtectSsPort = PreSocksResult.Context.TunProtectSsPort,
ProxyRelaySsPort = PreSocksResult.Context.ProxyRelaySsPort,
ProtectDomainList = [.. MainResult.Context.ProtectDomainList ?? [], .. PreSocksResult.Context.ProtectDomainList ?? []],
}
: MainResult.Context;
}
public class CoreConfigContextBuilder
{
/// <summary>
@@ -75,6 +108,79 @@ public class CoreConfigContextBuilder
return new CoreConfigContextBuilderResult(context, validatorResult);
}
/// <summary>
/// Builds the main <see cref="CoreConfigContext"/> for <paramref name="node"/> and, when
/// the main build succeeds, also builds the optional pre-socks context required for TUN
/// protection or pre-socks proxy chaining.
/// </summary>
public static async Task<CoreConfigContextBuilderAllResult> BuildAll(Config config, ProfileItem node)
{
var mainResult = await Build(config, node);
if (!mainResult.Success)
{
return new CoreConfigContextBuilderAllResult(mainResult, null);
}
var preResult = await BuildPreSocksIfNeeded(mainResult.Context);
return new CoreConfigContextBuilderAllResult(mainResult, preResult);
}
/// <summary>
/// Determines whether a pre-socks context is required for <paramref name="nodeContext"/>
/// and, if so, builds and returns it. Returns <c>null</c> when no pre-socks core is needed.
/// </summary>
private static async Task<CoreConfigContextBuilderResult?> BuildPreSocksIfNeeded(CoreConfigContext nodeContext)
{
var config = nodeContext.AppConfig;
var node = nodeContext.Node;
var coreType = AppManager.Instance.GetCoreType(node, node.ConfigType);
var preSocksItem = ConfigHandler.GetPreSocksItem(config, node, coreType);
if (preSocksItem != null)
{
var preSocksResult = await Build(nodeContext.AppConfig, preSocksItem);
return preSocksResult with
{
Context = preSocksResult.Context with
{
ProtectDomainList = [.. nodeContext.ProtectDomainList ?? [], .. preSocksResult.Context.ProtectDomainList ?? []],
}
};
}
if (!nodeContext.IsTunEnabled
|| coreType != ECoreType.Xray
|| node.ConfigType == EConfigType.Custom)
{
return null;
}
var tunProtectSsPort = Utils.GetFreePort();
var proxyRelaySsPort = Utils.GetFreePort();
var preItem = new ProfileItem()
{
CoreType = ECoreType.sing_box,
ConfigType = EConfigType.Shadowsocks,
Address = Global.Loopback,
Port = proxyRelaySsPort,
Password = Global.None,
};
preItem.SetProtocolExtra(preItem.GetProtocolExtra() with
{
SsMethod = Global.None,
});
var preResult2 = await Build(nodeContext.AppConfig, preItem);
return preResult2 with
{
Context = preResult2.Context with
{
ProtectDomainList = [.. nodeContext.ProtectDomainList ?? [], .. preResult2.Context.ProtectDomainList ?? []],
TunProtectSsPort = tunProtectSsPort,
ProxyRelaySsPort = proxyRelaySsPort,
}
};
}
/// <summary>
/// Resolves a node into the context, optionally wrapping it in a subscription-level proxy chain.
/// Returns the effective (possibly replaced) node and the validation result.