This commit is contained in:
DHR60 2025-07-31 10:46:01 +08:00
parent c820b58067
commit 271fdbc2a8
14 changed files with 337 additions and 269 deletions

View file

@ -9,33 +9,26 @@ public class CoreConfigHandler
{
private static readonly string _tag = "CoreConfigHandler";
public static async Task<RetResult> GenerateClientConfig(ProfileItem node, string? fileName)
public static async Task<RetResult> GenerateClientConfig(CoreLaunchContext context, string? fileName)
{
var config = AppHandler.Instance.Config;
var result = new RetResult();
if (node.ConfigType == EConfigType.Custom)
if (context.ConfigType == EConfigType.Custom)
{
result = node.CoreType switch
{
ECoreType.mihomo => await new CoreConfigClashService(config).GenerateClientCustomConfig(node, fileName),
ECoreType.sing_box => await new CoreConfigSingboxService(config).GenerateClientCustomConfig(node, fileName),
_ => await GenerateClientCustomConfig(node, fileName)
};
}
else if (AppHandler.Instance.GetCoreType(node, node.ConfigType) == ECoreType.sing_box || (Global.SingboxSupportConfigType.Contains(node.ConfigType) && !Global.XraySupportConfigType.Contains(node.ConfigType)))
{
result = await new CoreConfigSingboxService(config).GenerateClientConfigContent(node);
}
else if (Global.XraySupportConfigType.Contains(node.ConfigType))
{
result = await new CoreConfigV2rayService(config).GenerateClientConfigContent(node);
result = await GetCoreConfigServiceForCustom(context.CoreType).GenerateClientCustomConfig(context.Node, fileName);
}
else
{
result.Msg = ResUI.OperationFailed;
result.Success = false;
return result;
try
{
result = await GetCoreConfigServiceForClientConfig(context.CoreType).GenerateClientConfigContent(context.Node);
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
result.Msg = ResUI.FailedGenDefaultConfiguration;
return result;
}
}
if (result.Success != true)
{
@ -49,96 +42,44 @@ public class CoreConfigHandler
return result;
}
public static async Task<RetResult> GeneratePureEndpointConfig(ProfileItem node, string? fileName)
public static async Task<RetResult> GeneratePassthroughConfig(CoreLaunchContext context, string? fileName)
{
var config = AppHandler.Instance.Config;
var result = new RetResult();
var coreType = AppHandler.Instance.GetSplitCoreType(node, node.ConfigType);
result = coreType switch
{
ECoreType.sing_box => await new CoreConfigSingboxService(config).GeneratePureEndpointConfig(node),
ECoreType.Xray => await new CoreConfigV2rayService(config).GeneratePureEndpointConfig(node),
ECoreType.hysteria2 => await new CoreConfigHy2Service(config).GeneratePureEndpointConfig(node),
ECoreType.naiveproxy => await new CoreConfigNaiveService(config).GeneratePureEndpointConfig(node),
ECoreType.tuic => await new CoreConfigTuicService(config).GeneratePureEndpointConfig(node),
ECoreType.juicity => await new CoreConfigJuicityService(config).GeneratePureEndpointConfig(node),
ECoreType.brook => await new CoreConfigBrookService(config).GeneratePureEndpointConfig(node),
ECoreType.shadowquic => await new CoreConfigShadowquicService(config).GeneratePureEndpointConfig(node),
_ => throw new NotImplementedException(),
};
if (result.Success != true)
{
return result;
}
if (fileName.IsNotEmpty() && result.Data != null)
{
await File.WriteAllTextAsync(fileName, result.Data.ToString());
}
return result;
}
private static async Task<RetResult> GenerateClientCustomConfig(ProfileItem node, string? fileName)
{
var ret = new RetResult();
try
{
if (node == null || fileName is null)
{
ret.Msg = ResUI.CheckServerSettings;
return ret;
}
if (File.Exists(fileName))
{
File.SetAttributes(fileName, FileAttributes.Normal); //If the file has a read-only attribute, direct deletion will fail
File.Delete(fileName);
}
string addressFileName = node.Address;
if (!File.Exists(addressFileName))
{
addressFileName = Utils.GetConfigPath(addressFileName);
}
if (!File.Exists(addressFileName))
{
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
}
File.Copy(addressFileName, fileName);
File.SetAttributes(fileName, FileAttributes.Normal); //Copy will keep the attributes of addressFileName, so we need to add write permissions to fileName just in case of addressFileName is a read-only file.
//check again
if (!File.Exists(fileName))
{
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
}
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
ret.Success = true;
return await Task.FromResult(ret);
result = await GetCoreConfigServiceForPassthrough(context.CoreType).GeneratePassthroughConfig(context.Node);
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
result.Msg = ResUI.FailedGenDefaultConfiguration;
return result;
}
if (result.Success != true)
{
return result;
}
if (fileName.IsNotEmpty() && result.Data != null)
{
await File.WriteAllTextAsync(fileName, result.Data.ToString());
}
return result;
}
public static async Task<RetResult> GenerateClientSpeedtestConfig(Config config, string fileName, List<ServerTestItem> selecteds, ECoreType coreType)
{
var result = new RetResult();
if (coreType == ECoreType.sing_box)
try
{
result = await new CoreConfigSingboxService(config).GenerateClientSpeedtestConfig(selecteds);
result = await GetCoreConfigServiceForMultipleSpeedtest(coreType).GenerateClientSpeedtestConfig(selecteds);
}
else if (coreType == ECoreType.Xray)
catch (Exception ex)
{
result = await new CoreConfigV2rayService(config).GenerateClientSpeedtestConfig(selecteds);
Logging.SaveLog(_tag, ex);
result.Msg = ResUI.FailedGenDefaultConfiguration;
return result;
}
if (result.Success != true)
{
@ -148,21 +89,24 @@ public class CoreConfigHandler
return result;
}
public static async Task<RetResult> GenerateClientSpeedtestConfig(Config config, ProfileItem node, ServerTestItem testItem, string fileName)
public static async Task<RetResult> GenerateClientSpeedtestConfig(Config config, CoreLaunchContext context, ServerTestItem testItem, string fileName)
{
var result = new RetResult();
var initPort = AppHandler.Instance.GetLocalPort(EInboundProtocol.speedtest);
var port = Utils.GetFreePort(initPort + testItem.QueueNum);
testItem.Port = port;
if (AppHandler.Instance.GetCoreType(node, node.ConfigType) == ECoreType.sing_box)
try
{
result = await new CoreConfigSingboxService(config).GenerateClientSpeedtestConfig(node, port);
result = await GetCoreConfigServiceForSpeedtest(context.CoreType).GenerateClientSpeedtestConfig(context.Node, port);
}
else if (Global.XraySupportConfigType.Contains(node.ConfigType))
catch (Exception ex)
{
result = await new CoreConfigV2rayService(config).GenerateClientSpeedtestConfig(node, port);
Logging.SaveLog(_tag, ex);
result.Msg = ResUI.FailedGenDefaultConfiguration;
return result;
}
if (result.Success != true)
{
return result;
@ -191,4 +135,94 @@ public class CoreConfigHandler
await File.WriteAllTextAsync(fileName, result.Data.ToString());
return result;
}
private static CoreConfigServiceMinimalBase GetCoreConfigServiceForPassthrough(ECoreType coreType)
{
switch (coreType)
{
case ECoreType.sing_box:
return new CoreConfigSingboxService(AppHandler.Instance.Config);
case ECoreType.Xray:
return new CoreConfigV2rayService(AppHandler.Instance.Config);
case ECoreType.hysteria2:
return new CoreConfigHy2Service(AppHandler.Instance.Config);
case ECoreType.naiveproxy:
return new CoreConfigNaiveService(AppHandler.Instance.Config);
case ECoreType.tuic:
return new CoreConfigTuicService(AppHandler.Instance.Config);
case ECoreType.juicity:
return new CoreConfigJuicityService(AppHandler.Instance.Config);
case ECoreType.brook:
return new CoreConfigBrookService(AppHandler.Instance.Config);
case ECoreType.shadowquic:
return new CoreConfigShadowquicService(AppHandler.Instance.Config);
default:
throw new NotImplementedException($"Core type {coreType} is not implemented for passthrough configuration.");
}
}
private static CoreConfigServiceMinimalBase GetCoreConfigServiceForSpeedtest(ECoreType coreType)
{
switch (coreType)
{
case ECoreType.sing_box:
return new CoreConfigSingboxService(AppHandler.Instance.Config);
case ECoreType.Xray:
return new CoreConfigV2rayService(AppHandler.Instance.Config);
case ECoreType.hysteria2:
return new CoreConfigHy2Service(AppHandler.Instance.Config);
case ECoreType.naiveproxy:
return new CoreConfigNaiveService(AppHandler.Instance.Config);
case ECoreType.tuic:
return new CoreConfigTuicService(AppHandler.Instance.Config);
case ECoreType.juicity:
return new CoreConfigJuicityService(AppHandler.Instance.Config);
case ECoreType.brook:
return new CoreConfigBrookService(AppHandler.Instance.Config);
case ECoreType.shadowquic:
return new CoreConfigShadowquicService(AppHandler.Instance.Config);
default:
throw new NotImplementedException($"Core type {coreType} is not implemented for passthrough configuration.");
}
}
private static CoreConfigServiceBase GetCoreConfigServiceForMultipleSpeedtest(ECoreType coreType)
{
switch (coreType)
{
case ECoreType.sing_box:
return new CoreConfigSingboxService(AppHandler.Instance.Config);
case ECoreType.Xray:
return new CoreConfigV2rayService(AppHandler.Instance.Config);
default:
throw new NotImplementedException($"Core type {coreType} is not implemented for passthrough configuration.");
}
}
private static CoreConfigServiceMinimalBase GetCoreConfigServiceForCustom(ECoreType coreType)
{
switch (coreType)
{
case ECoreType.mihomo:
return new CoreConfigClashService(AppHandler.Instance.Config);
case ECoreType.sing_box:
return new CoreConfigSingboxService(AppHandler.Instance.Config);
default:
// CoreConfigServiceMinimalBase
return new CoreConfigV2rayService(AppHandler.Instance.Config);
}
}
private static CoreConfigServiceBase GetCoreConfigServiceForClientConfig(ECoreType coreType)
{
switch (coreType)
{
case ECoreType.sing_box:
return new CoreConfigSingboxService(AppHandler.Instance.Config);
case ECoreType.Xray:
return new CoreConfigV2rayService(AppHandler.Instance.Config);
default:
throw new NotImplementedException($"Core type {coreType} is not implemented for client configuration.");
}
}
}

View file

@ -130,10 +130,12 @@ public class CoreHandler
return -1;
}
var coreType = AppHandler.Instance.GetCoreType(node, node.ConfigType);
var context = new CoreLaunchContext(node, _config);
context.AdjustForConfigType();
var coreType = context.CoreType;
var fileName = string.Format(Global.CoreSpeedtestConfigFileName, Utils.GetGuid(false));
var configPath = Utils.GetBinConfigPath(fileName, coreType);
var result = await CoreConfigHandler.GenerateClientSpeedtestConfig(_config, node, testItem, configPath);
var result = await CoreConfigHandler.GenerateClientSpeedtestConfig(_config, context, testItem, configPath);
if (result.Success != true)
{
return -1;
@ -179,63 +181,13 @@ public class CoreHandler
#region Private
/// <summary>
/// Core launch context that encapsulates all parameters required for launching
/// </summary>
private class CoreLaunchContext
{
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; }
public CoreLaunchContext(ProfileItem node, Config config)
{
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;
}
/// <summary>
/// Adjust context parameters based on configuration type
/// </summary>
public void AdjustForConfigType()
{
(SplitCore, CoreType, PreCoreType) = AppHandler.Instance.GetCoreAndPreType(Node);
if (Node.ConfigType == EConfigType.Custom)
{
if (Node.PreSocksPort > 0)
{
PreSocksPort = Node.PreSocksPort.Value;
}
else
{
EnableTun = false;
}
}
else if (PreCoreType != null)
{
PreSocksPort = AppHandler.Instance.GetLocalPort(EInboundProtocol.split);
}
}
}
private async Task<bool> CoreStart(CoreLaunchContext context)
{
var coreType = context.SplitCore ? context.PureEndpointCore : context.CoreType;
var fileName = Utils.GetBinConfigPath(Global.CoreConfigFileName, coreType);
var result = context.SplitCore
? await CoreConfigHandler.GeneratePureEndpointConfig(context.Node, fileName)
: await CoreConfigHandler.GenerateClientConfig(context.Node, fileName);
? await CoreConfigHandler.GeneratePassthroughConfig(context, fileName)
: await CoreConfigHandler.GenerateClientConfig(context, fileName);
if (result.Success != true)
{
@ -287,8 +239,9 @@ public class CoreHandler
Sni = context.EnableTun && Utils.IsDomain(context.Node.Address) ? context.Node.Address : string.Empty, //Tun2SocksAddress
Port = context.PreSocksPort
};
var result = await CoreConfigHandler.GenerateClientConfig(itemSocks, fileName);
var itemSocksLaunch = new CoreLaunchContext(itemSocks, _config);
var result = await CoreConfigHandler.GenerateClientConfig(itemSocksLaunch, fileName);
if (!result.Success)
{
UpdateFunc(true, result.Msg);

View file

@ -0,0 +1,53 @@
namespace ServiceLib.Models;
/// <summary>
/// Core launch context that encapsulates all parameters required for launching
/// </summary>
public class CoreLaunchContext
{
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; }
public EConfigType ConfigType { get; set; }
public CoreLaunchContext(ProfileItem node, Config config)
{
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;
ConfigType = node.ConfigType;
}
/// <summary>
/// Adjust context parameters based on configuration type
/// </summary>
public void AdjustForConfigType()
{
(SplitCore, CoreType, PreCoreType) = AppHandler.Instance.GetCoreAndPreType(Node);
if (Node.ConfigType == EConfigType.Custom)
{
if (Node.PreSocksPort > 0)
{
PreSocksPort = Node.PreSocksPort.Value;
}
else
{
EnableTun = false;
}
}
else if (PreCoreType != null)
{
PreSocksPort = AppHandler.Instance.GetLocalPort(EInboundProtocol.split);
}
}
}

View file

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YamlDotNet.Core.Tokens;
namespace ServiceLib.Services.CoreConfig;
public abstract class CoreConfigServiceMinimalBase(Config config)
{
public virtual string _tag => GetType().Name;
protected Config _config = config;
public virtual Task<RetResult> GeneratePassthroughConfig(ProfileItem node)
{
return GeneratePassthroughConfig(node, AppHandler.Instance.GetLocalPort(EInboundProtocol.split));
}
public virtual Task<RetResult> GenerateClientSpeedtestConfig(ProfileItem node, int port)
{
return GeneratePassthroughConfig(node, port);
}
protected abstract Task<RetResult> GeneratePassthroughConfig(ProfileItem node, int port);
public virtual async Task<RetResult> GenerateClientCustomConfig(ProfileItem node, string? fileName)
{
var ret = new RetResult();
try
{
if (node == null || fileName is null)
{
ret.Msg = ResUI.CheckServerSettings;
return ret;
}
if (File.Exists(fileName))
{
File.SetAttributes(fileName, FileAttributes.Normal); //If the file has a read-only attribute, direct deletion will fail
File.Delete(fileName);
}
string addressFileName = node.Address;
if (!File.Exists(addressFileName))
{
addressFileName = Utils.GetConfigPath(addressFileName);
}
if (!File.Exists(addressFileName))
{
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
}
File.Copy(addressFileName, fileName);
File.SetAttributes(fileName, FileAttributes.Normal); //Copy will keep the attributes of addressFileName, so we need to add write permissions to fileName just in case of addressFileName is a read-only file.
//check again
if (!File.Exists(fileName))
{
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
}
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
ret.Success = true;
return await Task.FromResult(ret);
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
}
}
}
public abstract class CoreConfigServiceBase(Config config) : CoreConfigServiceMinimalBase(config)
{
public abstract Task<RetResult> GenerateClientConfigContent(ProfileItem node);
public abstract Task<RetResult> GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds, EMultipleLoad multipleLoad);
public virtual Task<RetResult> GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds)
{
return GenerateClientMultipleLoadConfig(selecteds, EMultipleLoad.LeastPing);
}
public abstract Task<RetResult> GenerateClientSpeedtestConfig(List<ServerTestItem> selecteds);
}

View file

@ -9,19 +9,11 @@ using ServiceLib.Models;
namespace ServiceLib.Services.CoreConfig;
public class CoreConfigSingboxService
public class CoreConfigSingboxService(Config config) : CoreConfigServiceBase(config)
{
private Config _config;
private static readonly string _tag = "CoreConfigSingboxService";
public CoreConfigSingboxService(Config config)
{
_config = config;
}
#region public gen function
public async Task<RetResult> GenerateClientConfigContent(ProfileItem node)
public override async Task<RetResult> GenerateClientConfigContent(ProfileItem node)
{
var ret = new RetResult();
try
@ -94,7 +86,7 @@ public class CoreConfigSingboxService
}
}
public async Task<RetResult> GenerateClientSpeedtestConfig(List<ServerTestItem> selecteds)
public override async Task<RetResult> GenerateClientSpeedtestConfig(List<ServerTestItem> selecteds)
{
var ret = new RetResult();
try
@ -271,7 +263,7 @@ public class CoreConfigSingboxService
}
}
public async Task<RetResult> GenerateClientSpeedtestConfig(ProfileItem node, int port)
public override async Task<RetResult> GenerateClientSpeedtestConfig(ProfileItem node, int port)
{
var ret = new RetResult();
try
@ -342,7 +334,7 @@ public class CoreConfigSingboxService
}
}
public async Task<RetResult> GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds)
public override async Task<RetResult> GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds, EMultipleLoad multipleLoad)
{
var ret = new RetResult();
try
@ -434,7 +426,7 @@ public class CoreConfigSingboxService
}
}
public async Task<RetResult> GenerateClientCustomConfig(ProfileItem node, string? fileName)
public override async Task<RetResult> GenerateClientCustomConfig(ProfileItem node, string? fileName)
{
var ret = new RetResult();
if (node == null || fileName is null)
@ -515,7 +507,7 @@ public class CoreConfigSingboxService
}
}
public async Task<RetResult> GeneratePureEndpointConfig(ProfileItem node)
protected override async Task<RetResult> GeneratePassthroughConfig(ProfileItem node, int port)
{
var ret = new RetResult();
try
@ -555,7 +547,7 @@ public class CoreConfigSingboxService
type = EInboundProtocol.mixed.ToString(),
tag = EInboundProtocol.socks.ToString(),
listen = Global.Loopback,
listen_port = AppHandler.Instance.GetLocalPort(EInboundProtocol.split)
listen_port = port
};
singboxConfig.inbounds = new() { inbound };

View file

@ -5,19 +5,11 @@ using System.Text.Json.Nodes;
namespace ServiceLib.Services.CoreConfig;
public class CoreConfigV2rayService
public class CoreConfigV2rayService(Config config) : CoreConfigServiceBase(config)
{
private Config _config;
private static readonly string _tag = "CoreConfigV2rayService";
public CoreConfigV2rayService(Config config)
{
_config = config;
}
#region public gen function
public async Task<RetResult> GenerateClientConfigContent(ProfileItem node)
public override async Task<RetResult> GenerateClientConfigContent(ProfileItem node)
{
var ret = new RetResult();
try
@ -78,7 +70,7 @@ public class CoreConfigV2rayService
}
}
public async Task<RetResult> GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds, EMultipleLoad multipleLoad)
public override async Task<RetResult> GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds, EMultipleLoad multipleLoad)
{
var ret = new RetResult();
@ -203,7 +195,7 @@ public class CoreConfigV2rayService
}
}
public async Task<RetResult> GenerateClientSpeedtestConfig(List<ServerTestItem> selecteds)
public override async Task<RetResult> GenerateClientSpeedtestConfig(List<ServerTestItem> selecteds)
{
var ret = new RetResult();
try
@ -355,7 +347,7 @@ public class CoreConfigV2rayService
}
}
public async Task<RetResult> GenerateClientSpeedtestConfig(ProfileItem node, int port)
public override async Task<RetResult> GenerateClientSpeedtestConfig(ProfileItem node, int port)
{
var ret = new RetResult();
try
@ -413,7 +405,7 @@ public class CoreConfigV2rayService
}
}
public async Task<RetResult> GeneratePureEndpointConfig(ProfileItem node)
protected override async Task<RetResult> GeneratePassthroughConfig(ProfileItem node, int port)
{
var ret = new RetResult();
try
@ -449,13 +441,18 @@ public class CoreConfigV2rayService
await GenLog(v2rayConfig);
var inbound = GetInbound(_config.Inbound.First(), EInboundProtocol.split, true);
inbound.sniffing = new Sniffing4Ray
v2rayConfig.inbounds = new() { new()
{
enabled = false
};
v2rayConfig.inbounds = new() { inbound };
tag = EInboundProtocol.socks.ToString(),
listen = Global.Loopback,
port = port,
protocol = EInboundProtocol.mixed.ToString(),
settings = new Inboundsettings4Ray()
{
udp = true,
auth = "noauth"
},
} };
await GenOutbound(node, v2rayConfig.outbounds.First());

View file

@ -1,15 +1,7 @@
namespace ServiceLib.Services.CoreConfig.Minimal;
public class CoreConfigBrookService
public class CoreConfigBrookService(Config config) : CoreConfigServiceMinimalBase(config)
{
private Config _config;
private static readonly string _tag = "CoreConfigBrookService";
public CoreConfigBrookService(Config config)
{
_config = config;
}
public async Task<RetResult> GeneratePureEndpointConfig(ProfileItem node)
protected override async Task<RetResult> GeneratePassthroughConfig(ProfileItem node, int port)
{
var ret = new RetResult();
try
@ -30,7 +22,7 @@ public class CoreConfigBrookService
var processArgs = "client";
// inbound
processArgs += " --socks5 " + Global.Loopback + ":" + AppHandler.Instance.GetLocalPort(EInboundProtocol.split).ToString();
processArgs += " --socks5 " + Global.Loopback + ":" + port.ToString();
// outbound
processArgs += " --server " + node.Address + ":" + node.Port;

View file

@ -1,19 +1,21 @@
namespace ServiceLib.Services.CoreConfig;
namespace ServiceLib.Services.CoreConfig.Minimal;
/// <summary>
/// Core configuration file processing class
/// </summary>
public class CoreConfigClashService
public class CoreConfigClashService(Config config) : CoreConfigServiceMinimalBase(config)
{
private Config _config;
private static readonly string _tag = "CoreConfigClashService";
public CoreConfigClashService(Config config)
protected override async Task<RetResult> GeneratePassthroughConfig(ProfileItem node, int port)
{
_config = config;
var ret = new RetResult
{
Success = false,
Msg = ResUI.OperationFailed
};
return await Task.FromResult(ret);
}
public async Task<RetResult> GenerateClientCustomConfig(ProfileItem node, string? fileName)
public override async Task<RetResult> GenerateClientCustomConfig(ProfileItem node, string? fileName)
{
var ret = new RetResult();
if (node == null || fileName is null)

View file

@ -1,17 +1,9 @@
using System.Text.Json.Nodes;
namespace ServiceLib.Services.CoreConfig.Minimal;
public class CoreConfigHy2Service
public class CoreConfigHy2Service(Config config) : CoreConfigServiceMinimalBase(config)
{
private Config _config;
private static readonly string _tag = "CoreConfigHy2Service";
public CoreConfigHy2Service(Config config)
{
_config = config;
}
public async Task<RetResult> GeneratePureEndpointConfig(ProfileItem node)
protected override async Task<RetResult> GeneratePassthroughConfig(ProfileItem node, int port)
{
var ret = new RetResult();
try
@ -34,14 +26,14 @@ public class CoreConfigHy2Service
// inbound
configJsonNode["socks5"] = new JsonObject
{
["listen"] = Global.Loopback + ":" + AppHandler.Instance.GetLocalPort(EInboundProtocol.split).ToString()
["listen"] = Global.Loopback + ":" + port.ToString()
};
// outbound
var port = string.Empty;
var outboundPort = string.Empty;
if (node.Ports.IsNotEmpty())
{
port = node.Ports.Replace(':', '-');
outboundPort = node.Ports.Replace(':', '-');
if (_config.HysteriaItem.HopInterval > 0)
{
configJsonNode["transport"] = new JsonObject
@ -55,9 +47,9 @@ public class CoreConfigHy2Service
}
else
{
port = node.Port.ToString();
outboundPort = node.Port.ToString();
}
configJsonNode["server"] = node.Address + ":" + port;
configJsonNode["server"] = node.Address + ":" + outboundPort;
configJsonNode["auth"] = node.Id;
if (node.Sni.IsNotEmpty())

View file

@ -1,17 +1,9 @@
using System.Text.Json.Nodes;
namespace ServiceLib.Services.CoreConfig.Minimal;
public class CoreConfigJuicityService
public class CoreConfigJuicityService(Config config) : CoreConfigServiceMinimalBase(config)
{
private Config _config;
private static readonly string _tag = "CoreConfigJuicityService";
public CoreConfigJuicityService(Config config)
{
_config = config;
}
public async Task<RetResult> GeneratePureEndpointConfig(ProfileItem node)
protected override async Task<RetResult> GeneratePassthroughConfig(ProfileItem node, int port)
{
var ret = new RetResult();
try
@ -45,7 +37,7 @@ public class CoreConfigJuicityService
configJsonNode["log_level"] = logLevel;
// inbound
configJsonNode["listen"] = ":" + AppHandler.Instance.GetLocalPort(EInboundProtocol.split).ToString();
configJsonNode["listen"] = ":" + port.ToString();
// outbound
configJsonNode["server"] = node.Address + ":" + node.Port;

View file

@ -1,17 +1,9 @@
using System.Text.Json.Nodes;
namespace ServiceLib.Services.CoreConfig.Minimal;
public class CoreConfigNaiveService
public class CoreConfigNaiveService(Config config) : CoreConfigServiceMinimalBase(config)
{
private Config _config;
private static readonly string _tag = "CoreConfigNaiveService";
public CoreConfigNaiveService(Config config)
{
_config = config;
}
public async Task<RetResult> GeneratePureEndpointConfig(ProfileItem node)
protected override async Task<RetResult> GeneratePassthroughConfig(ProfileItem node, int port)
{
var ret = new RetResult();
try
@ -32,7 +24,7 @@ public class CoreConfigNaiveService
var configJsonNode = new JsonObject();
// inbound
configJsonNode["listen"] = Global.SocksProtocol + Global.Loopback + ":" + AppHandler.Instance.GetLocalPort(EInboundProtocol.split).ToString();
configJsonNode["listen"] = Global.SocksProtocol + Global.Loopback + ":" + port.ToString();
// outbound
configJsonNode["proxy"] = (node.HeaderType == "quic" ? "quic://" : Global.HttpsProtocol) + node.Id + "@" + node.Address + ":" + node.Port;

View file

@ -1,17 +1,9 @@
using System.Text.Json.Nodes;
namespace ServiceLib.Services.CoreConfig.Minimal;
public class CoreConfigShadowquicService
public class CoreConfigShadowquicService(Config config) : CoreConfigServiceMinimalBase(config)
{
private Config _config;
private static readonly string _tag = "CoreConfigShadowquicService";
public CoreConfigShadowquicService(Config config)
{
_config = config;
}
public async Task<RetResult> GeneratePureEndpointConfig(ProfileItem node)
protected override async Task<RetResult> GeneratePassthroughConfig(ProfileItem node, int port)
{
var ret = new RetResult();
try
@ -48,7 +40,7 @@ public class CoreConfigShadowquicService
var inboundNode = new Dictionary<string, object>
{
["type"] = "socks5",
["listen"] = Global.Loopback + ":" + AppHandler.Instance.GetLocalPort(EInboundProtocol.split).ToString()
["listen"] = Global.Loopback + ":" + port.ToString()
};
configYamlNode["inbound"] = inboundNode;

View file

@ -1,17 +1,9 @@
using System.Text.Json.Nodes;
namespace ServiceLib.Services.CoreConfig.Minimal;
public class CoreConfigTuicService
public class CoreConfigTuicService(Config config) : CoreConfigServiceMinimalBase(config)
{
private Config _config;
private static readonly string _tag = "CoreConfigTuicService";
public CoreConfigTuicService(Config config)
{
_config = config;
}
public async Task<RetResult> GeneratePureEndpointConfig(ProfileItem node)
protected override async Task<RetResult> GeneratePassthroughConfig(ProfileItem node, int port)
{
var ret = new RetResult();
try
@ -47,7 +39,7 @@ public class CoreConfigTuicService
// inbound
configJsonNode["local"] = new JsonObject
{
["server"] = Global.Loopback + ":" + AppHandler.Instance.GetLocalPort(EInboundProtocol.split).ToString()
["server"] = Global.Loopback + ":" + port.ToString()
};
// outbound

View file

@ -770,7 +770,8 @@ public class ProfilesViewModel : MyReactiveObject
}
if (blClipboard)
{
var result = await CoreConfigHandler.GenerateClientConfig(item, null);
var coreLaunchContext = new CoreLaunchContext(item, _config);
var result = await CoreConfigHandler.GenerateClientConfig(coreLaunchContext, null);
if (result.Success != true)
{
NoticeHandler.Instance.Enqueue(result.Msg);
@ -793,7 +794,8 @@ public class ProfilesViewModel : MyReactiveObject
{
return;
}
var result = await CoreConfigHandler.GenerateClientConfig(item, fileName);
var coreLaunchContext = new CoreLaunchContext(item, _config);
var result = await CoreConfigHandler.GenerateClientConfig(coreLaunchContext, fileName);
if (result.Success != true)
{
NoticeHandler.Instance.Enqueue(result.Msg);