Files
v2rayN/v2rayN/ServiceLib/Handler/CoreConfigHandler.cs
T
2dust 2c90ed1a94 Move configuration data classes to handlers
Rename the database and text configuration managers as handlers, move configuration data classes into Handler.Data, and relocate ProfileExManager. Update references across applications and tests.
2026-11-14 20:35:50 +08:00

156 lines
5.3 KiB
C#

namespace ServiceLib.Handler;
/// <summary>
/// Core configuration file processing class
/// </summary>
public static class CoreConfigHandler
{
private static readonly string _tag = "CoreConfigHandler";
public static async Task<RetResult> GenerateClientConfig(CoreConfigContext context, string? fileName)
{
var config = ConfigTextHandler.Config;
var result = new RetResult();
var node = context.Node;
if (node.ConfigType == EConfigType.Custom)
{
result = node.CoreType switch
{
ECoreType.mihomo => await new CoreConfigClashService(config, context.IsTunEnabled).GenerateClientCustomConfig(node, fileName),
_ => await GenerateClientCustomConfig(node, fileName)
};
}
else if (context.RunCoreType == ECoreType.sing_box)
{
result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
}
else
{
result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
}
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);
}
var addressFileName = node.Address;
if (!File.Exists(addressFileName))
{
addressFileName = Utils.GetConfigPath(addressFileName);
}
if (!File.Exists(addressFileName))
{
var message = $"{ResUI.FailedReadConfiguration}: {addressFileName}";
Logging.SaveLog($"{_tag}: {message}");
ret.Msg = message;
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))
{
var message = $"{ResUI.FailedReadConfiguration}: {fileName}";
Logging.SaveLog($"{_tag}: {message}");
ret.Msg = message;
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 static async Task<RetResult> GenerateClientSpeedtestConfig(Config config, string fileName, List<ServerTestItem> selecteds, ECoreType coreType)
{
var result = new RetResult();
var dummyNode = new ProfileItem
{
CoreType = coreType
};
var builderResult = await CoreConfigContextBuilder.Build(config, dummyNode);
var context = builderResult.Context;
foreach (var testItem in selecteds)
{
var node = testItem.Profile;
var (actNode, _) = await CoreConfigContextBuilder.ResolveNodeAsync(context, node, true);
if (node.IndexId == actNode.IndexId)
{
continue;
}
context.ServerTestItemMap[node.IndexId] = actNode.IndexId;
}
if (coreType == ECoreType.sing_box)
{
result = new CoreConfigSingboxService(context).GenerateClientSpeedtestConfig(selecteds);
}
else if (coreType == ECoreType.Xray)
{
result = new CoreConfigV2rayService(context).GenerateClientSpeedtestConfig(selecteds);
}
if (result.Success != true)
{
return result;
}
await File.WriteAllTextAsync(fileName, result.Data.ToString());
return result;
}
public static async Task<RetResult> GenerateClientSpeedtestConfig(Config config, CoreConfigContext context, ServerTestItem testItem, string fileName)
{
var result = new RetResult();
var initPort = AppManager.Instance.GetLocalPort(EInboundProtocol.speedtest);
var port = Utils.GetFreePort(initPort + testItem.QueueNum);
testItem.Port = port;
if (context.RunCoreType == ECoreType.sing_box)
{
result = new CoreConfigSingboxService(context).GenerateClientSpeedtestConfig(port);
}
else
{
result = new CoreConfigV2rayService(context).GenerateClientSpeedtestConfig(port);
}
if (result.Success != true)
{
return result;
}
await File.WriteAllTextAsync(fileName, result.Data.ToString());
return result;
}
}