mirror of
https://github.com/2dust/v2rayN.git
synced 2025-10-13 20:09:12 +00:00
Config Handler
This commit is contained in:
parent
c899d534af
commit
b8dbe61db3
2 changed files with 149 additions and 78 deletions
|
@ -1197,43 +1197,6 @@ public class ConfigHandler
|
|||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a SOCKS server profile for pre-SOCKS functionality
|
||||
/// Used when TUN mode is enabled or when a custom config has a pre-SOCKS port
|
||||
/// </summary>
|
||||
/// <param name="config">Current configuration</param>
|
||||
/// <param name="node">Server node that might need pre-SOCKS</param>
|
||||
/// <param name="coreType">Core type being used</param>
|
||||
/// <returns>A SOCKS profile item or null if not needed</returns>
|
||||
public static async Task<ProfileItem?> GetPreSocksItem(Config config, ProfileItem node, ECoreType coreType)
|
||||
{
|
||||
ProfileItem? itemSocks = null;
|
||||
if (node.ConfigType != EConfigType.Custom && coreType != ECoreType.sing_box && config.TunModeItem.EnableTun)
|
||||
{
|
||||
itemSocks = new ProfileItem()
|
||||
{
|
||||
CoreType = ECoreType.sing_box,
|
||||
ConfigType = EConfigType.SOCKS,
|
||||
Address = Global.Loopback,
|
||||
Sni = node.Address, //Tun2SocksAddress
|
||||
Port = AppHandler.Instance.GetLocalPort(EInboundProtocol.socks)
|
||||
};
|
||||
}
|
||||
else if ((node.ConfigType == EConfigType.Custom && node.PreSocksPort > 0))
|
||||
{
|
||||
var preCoreType = config.RunningCoreType = config.TunModeItem.EnableTun ? ECoreType.sing_box : ECoreType.Xray;
|
||||
itemSocks = new ProfileItem()
|
||||
{
|
||||
CoreType = preCoreType,
|
||||
ConfigType = EConfigType.SOCKS,
|
||||
Address = Global.Loopback,
|
||||
Port = node.PreSocksPort.Value,
|
||||
};
|
||||
}
|
||||
await Task.CompletedTask;
|
||||
return itemSocks;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove servers with invalid test results (timeout)
|
||||
/// Useful for cleaning up subscription lists
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using ServiceLib.Enums;
|
||||
using ServiceLib.Models;
|
||||
|
||||
namespace ServiceLib.Handler;
|
||||
|
||||
|
@ -71,28 +73,24 @@ public class CoreHandler
|
|||
return;
|
||||
}
|
||||
|
||||
var fileName = Utils.GetBinConfigPath(Global.CoreConfigFileName);
|
||||
var result = await CoreConfigHandler.GenerateClientConfig(node, fileName);
|
||||
if (result.Success != true)
|
||||
// Create launch context and configure parameters
|
||||
var context = new CoreLaunchContext(node, _config);
|
||||
context.AdjustForConfigType();
|
||||
context.AdjustForSplitCore();
|
||||
|
||||
// Start main core
|
||||
if (!await CoreStart(context))
|
||||
{
|
||||
UpdateFunc(true, result.Msg);
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateFunc(false, $"{node.GetSummary()}");
|
||||
UpdateFunc(false, $"{Utils.GetRuntimeInfo()}");
|
||||
UpdateFunc(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
|
||||
await CoreStop();
|
||||
await Task.Delay(100);
|
||||
|
||||
if (Utils.IsWindows() && _config.TunModeItem.EnableTun)
|
||||
// Start pre-core if needed
|
||||
if (!await CoreStartPreService(context))
|
||||
{
|
||||
await Task.Delay(100);
|
||||
await WindowsUtils.RemoveTunDevice();
|
||||
await CoreStop(); // Clean up main core if pre-core fails
|
||||
return;
|
||||
}
|
||||
|
||||
await CoreStart(node);
|
||||
await CoreStartPreService(node);
|
||||
if (_process != null)
|
||||
{
|
||||
UpdateFunc(true, $"{node.GetSummary()}");
|
||||
|
@ -181,43 +179,153 @@ public class CoreHandler
|
|||
|
||||
#region Private
|
||||
|
||||
private async Task CoreStart(ProfileItem node)
|
||||
/// <summary>
|
||||
/// Core launch context that encapsulates all parameters required for launching
|
||||
/// </summary>
|
||||
private class CoreLaunchContext
|
||||
{
|
||||
var coreType = _config.RunningCoreType = AppHandler.Instance.GetCoreType(node, node.ConfigType);
|
||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
|
||||
public ProfileItem Node { get; set; }
|
||||
public bool SplitCore { get; set; }
|
||||
public ECoreType CoreType { get; set; }
|
||||
public ECoreType? PreCoreType { get; set; }
|
||||
public ECoreType PureEndpointCore { get; set; }
|
||||
public ECoreType SplitRouteCore { get; set; }
|
||||
public bool EnableTun { get; set; }
|
||||
public int PreSocksPort { get; set; }
|
||||
|
||||
var displayLog = node.ConfigType != EConfigType.Custom || node.DisplayLog;
|
||||
var proc = await RunProcess(coreInfo, Global.CoreConfigFileName, displayLog, true);
|
||||
if (proc is null)
|
||||
public CoreLaunchContext(ProfileItem node, Config config)
|
||||
{
|
||||
return;
|
||||
Node = node;
|
||||
SplitCore = config.SplitCoreItem.EnableSplitCore;
|
||||
CoreType = AppHandler.Instance.GetCoreType(node, node.ConfigType);
|
||||
PureEndpointCore = AppHandler.Instance.GetSplitCoreType(node, node.ConfigType);
|
||||
SplitRouteCore = config.SplitCoreItem.RouteCoreType;
|
||||
EnableTun = config.TunModeItem.EnableTun;
|
||||
PreSocksPort = 0;
|
||||
PreCoreType = null;
|
||||
}
|
||||
_process = proc;
|
||||
}
|
||||
|
||||
private async Task CoreStartPreService(ProfileItem node)
|
||||
{
|
||||
if (_process != null && !_process.HasExited)
|
||||
/// <summary>
|
||||
/// Adjust context parameters based on configuration type
|
||||
/// </summary>
|
||||
public void AdjustForConfigType()
|
||||
{
|
||||
var coreType = AppHandler.Instance.GetCoreType(node, node.ConfigType);
|
||||
var itemSocks = await ConfigHandler.GetPreSocksItem(_config, node, coreType);
|
||||
if (itemSocks != null)
|
||||
if (Node.ConfigType == EConfigType.Custom)
|
||||
{
|
||||
var preCoreType = itemSocks.CoreType ?? ECoreType.sing_box;
|
||||
var fileName = Utils.GetBinConfigPath(Global.CorePreConfigFileName);
|
||||
var result = await CoreConfigHandler.GenerateClientConfig(itemSocks, fileName);
|
||||
if (result.Success)
|
||||
SplitCore = false;
|
||||
CoreType = Node.CoreType ?? ECoreType.Xray;
|
||||
if (Node.PreSocksPort > 0)
|
||||
{
|
||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(preCoreType);
|
||||
var proc = await RunProcess(coreInfo, Global.CorePreConfigFileName, true, true);
|
||||
if (proc is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_processPre = proc;
|
||||
PreCoreType = EnableTun ? ECoreType.sing_box : AppHandler.Instance.GetCoreType(Node, Node.ConfigType);
|
||||
PreSocksPort = Node.PreSocksPort.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
EnableTun = false;
|
||||
PreCoreType = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjust split core configuration
|
||||
/// </summary>
|
||||
public void AdjustForSplitCore()
|
||||
{
|
||||
if (SplitCore)
|
||||
{
|
||||
PreCoreType = EnableTun ? ECoreType.sing_box : SplitRouteCore;
|
||||
CoreType = PureEndpointCore;
|
||||
|
||||
if (PreCoreType == CoreType)
|
||||
{
|
||||
PreCoreType = null;
|
||||
SplitCore = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
PreSocksPort = AppHandler.Instance.GetLocalPort(EInboundProtocol.split);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> CoreStart(CoreLaunchContext context)
|
||||
{
|
||||
var fileName = Utils.GetBinConfigPath(Global.CoreConfigFileName);
|
||||
var result = context.SplitCore
|
||||
? await CoreConfigHandler.GeneratePureEndpointConfig(context.Node, fileName)
|
||||
: await CoreConfigHandler.GenerateClientConfig(context.Node, fileName);
|
||||
|
||||
if (result.Success != true)
|
||||
{
|
||||
UpdateFunc(true, result.Msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
UpdateFunc(false, $"{context.Node.GetSummary()}");
|
||||
UpdateFunc(false, $"{Utils.GetRuntimeInfo()}");
|
||||
UpdateFunc(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
|
||||
|
||||
await CoreStop();
|
||||
await Task.Delay(100);
|
||||
|
||||
if (Utils.IsWindows() && _config.TunModeItem.EnableTun)
|
||||
{
|
||||
await Task.Delay(100);
|
||||
await WindowsUtils.RemoveTunDevice();
|
||||
}
|
||||
|
||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(context.CoreType);
|
||||
var displayLog = context.Node.ConfigType != EConfigType.Custom || context.Node.DisplayLog;
|
||||
var proc = await RunProcess(coreInfo, Global.CoreConfigFileName, displayLog, true);
|
||||
|
||||
if (proc is null)
|
||||
{
|
||||
UpdateFunc(true, ResUI.FailedToRunCore);
|
||||
return false;
|
||||
}
|
||||
|
||||
_process = proc;
|
||||
_config.RunningCoreType = AppHandler.Instance.GetCoreType(context.Node, context.Node.ConfigType);
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<bool> CoreStartPreService(CoreLaunchContext context)
|
||||
{
|
||||
if (context.PreCoreType == null)
|
||||
{
|
||||
return true; // No pre-core needed, consider successful
|
||||
}
|
||||
|
||||
var fileName = Utils.GetBinConfigPath(Global.CorePreConfigFileName);
|
||||
var itemSocks = new ProfileItem()
|
||||
{
|
||||
CoreType = context.PreCoreType,
|
||||
ConfigType = EConfigType.SOCKS,
|
||||
Address = Global.Loopback,
|
||||
Sni = context.EnableTun && Utils.IsDomain(context.Node.Address) ? context.Node.Address : string.Empty, //Tun2SocksAddress
|
||||
Port = context.PreSocksPort
|
||||
};
|
||||
|
||||
var result = await CoreConfigHandler.GenerateClientConfig(itemSocks, fileName);
|
||||
if (!result.Success)
|
||||
{
|
||||
UpdateFunc(true, result.Msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo((ECoreType)context.PreCoreType);
|
||||
var proc = await RunProcess(coreInfo, Global.CorePreConfigFileName, true, true);
|
||||
|
||||
if (proc is null || (_process?.HasExited == true))
|
||||
{
|
||||
UpdateFunc(true, ResUI.FailedToRunCore);
|
||||
return false;
|
||||
}
|
||||
|
||||
_processPre = proc;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void UpdateFunc(bool notify, string msg)
|
||||
|
|
Loading…
Reference in a new issue