2025-04-02 03:44:23 +00:00
namespace ServiceLib.Handler ;
2025-03-29 08:44:42 +00:00
2025-04-02 03:44:23 +00:00
/// <summary>
/// Core configuration file processing class
/// </summary>
2025-08-17 08:52:51 +00:00
public static class CoreConfigHandler
2019-10-11 06:15:20 +00:00
{
2025-04-02 03:44:23 +00:00
private static readonly string _tag = "CoreConfigHandler" ;
public static async Task < RetResult > GenerateClientConfig ( ProfileItem node , string? fileName )
2019-10-11 06:15:20 +00:00
{
2025-08-17 09:31:55 +00:00
var config = AppManager . Instance . Config ;
2025-04-02 03:44:23 +00:00
var result = new RetResult ( ) ;
2025-01-03 07:02:31 +00:00
2025-04-02 03:44:23 +00:00
if ( node . ConfigType = = EConfigType . Custom )
2019-10-11 06:15:20 +00:00
{
2025-04-02 03:44:23 +00:00
result = node . CoreType switch
2024-10-21 01:45:33 +00:00
{
2025-04-02 03:44:23 +00:00
ECoreType . mihomo = > await new CoreConfigClashService ( config ) . GenerateClientCustomConfig ( node , fileName ) ,
ECoreType . sing_box = > await new CoreConfigSingboxService ( config ) . GenerateClientCustomConfig ( node , fileName ) ,
_ = > await GenerateClientCustomConfig ( node , fileName )
} ;
}
2025-08-17 09:31:55 +00:00
else if ( AppManager . Instance . GetCoreType ( node , node . ConfigType ) = = ECoreType . sing_box )
2025-04-02 03:44:23 +00:00
{
result = await new CoreConfigSingboxService ( config ) . GenerateClientConfigContent ( node ) ;
}
else
{
result = await new CoreConfigV2rayService ( config ) . GenerateClientConfigContent ( node ) ;
}
if ( result . Success ! = true )
{
2024-10-21 01:45:33 +00:00
return result ;
2019-10-11 06:15:20 +00:00
}
2025-04-02 03:44:23 +00:00
if ( fileName . IsNotEmpty ( ) & & result . Data ! = null )
2019-10-11 06:15:20 +00:00
{
2025-04-02 03:44:23 +00:00
await File . WriteAllTextAsync ( fileName , result . Data . ToString ( ) ) ;
}
2019-10-11 06:15:20 +00:00
2025-04-02 03:44:23 +00:00
return result ;
}
2019-10-11 06:15:20 +00:00
2025-04-02 03:44:23 +00:00
private static async Task < RetResult > GenerateClientCustomConfig ( ProfileItem node , string? fileName )
{
var ret = new RetResult ( ) ;
try
{
if ( node = = null | | fileName is null )
2019-10-11 06:15:20 +00:00
{
2025-04-02 03:44:23 +00:00
ret . Msg = ResUI . CheckServerSettings ;
2024-10-21 01:45:33 +00:00
return ret ;
2019-10-11 06:15:20 +00:00
}
2025-04-02 03:44:23 +00:00
if ( File . Exists ( fileName ) )
2023-12-29 01:39:55 +00:00
{
2025-04-02 03:44:23 +00:00
File . SetAttributes ( fileName , FileAttributes . Normal ) ; //If the file has a read-only attribute, direct deletion will fail
File . Delete ( fileName ) ;
2023-12-29 01:39:55 +00:00
}
2025-04-02 03:44:23 +00:00
string addressFileName = node . Address ;
if ( ! File . Exists ( addressFileName ) )
2023-12-29 01:39:55 +00:00
{
2025-04-02 03:44:23 +00:00
addressFileName = Utils . GetConfigPath ( addressFileName ) ;
2024-10-21 01:45:33 +00:00
}
2025-04-02 03:44:23 +00:00
if ( ! File . Exists ( addressFileName ) )
2024-10-21 01:45:33 +00:00
{
2025-04-02 03:44:23 +00:00
ret . Msg = ResUI . FailedGenDefaultConfiguration ;
return ret ;
2023-12-29 01:39:55 +00:00
}
2025-04-02 03:44:23 +00:00
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 ) ;
2019-10-11 06:15:20 +00:00
}
2025-04-02 03:44:23 +00:00
catch ( Exception ex )
{
Logging . SaveLog ( _tag , ex ) ;
ret . Msg = ResUI . FailedGenDefaultConfiguration ;
return ret ;
}
}
2024-07-14 08:13:28 +00:00
2025-04-02 03:44:23 +00:00
public static async Task < RetResult > GenerateClientSpeedtestConfig ( Config config , string fileName , List < ServerTestItem > selecteds , ECoreType coreType )
{
var result = new RetResult ( ) ;
if ( coreType = = ECoreType . sing_box )
{
result = await new CoreConfigSingboxService ( config ) . GenerateClientSpeedtestConfig ( selecteds ) ;
}
else if ( coreType = = ECoreType . Xray )
{
result = await new CoreConfigV2rayService ( config ) . GenerateClientSpeedtestConfig ( selecteds ) ;
}
if ( result . Success ! = true )
2025-02-13 11:46:51 +00:00
{
2025-04-02 03:44:23 +00:00
return result ;
}
await File . WriteAllTextAsync ( fileName , result . Data . ToString ( ) ) ;
return result ;
}
2025-02-13 11:46:51 +00:00
2025-04-02 03:44:23 +00:00
public static async Task < RetResult > GenerateClientSpeedtestConfig ( Config config , ProfileItem node , ServerTestItem testItem , string fileName )
{
var result = new RetResult ( ) ;
2025-08-17 09:31:55 +00:00
var initPort = AppManager . Instance . GetLocalPort ( EInboundProtocol . speedtest ) ;
2025-04-02 03:44:23 +00:00
var port = Utils . GetFreePort ( initPort + testItem . QueueNum ) ;
testItem . Port = port ;
2025-02-13 11:46:51 +00:00
2025-08-17 09:31:55 +00:00
if ( AppManager . Instance . GetCoreType ( node , node . ConfigType ) = = ECoreType . sing_box )
2025-04-02 03:44:23 +00:00
{
result = await new CoreConfigSingboxService ( config ) . GenerateClientSpeedtestConfig ( node , port ) ;
}
else
{
result = await new CoreConfigV2rayService ( config ) . GenerateClientSpeedtestConfig ( node , port ) ;
}
if ( result . Success ! = true )
{
2025-02-13 11:46:51 +00:00
return result ;
}
2025-04-02 03:44:23 +00:00
await File . WriteAllTextAsync ( fileName , result . Data . ToString ( ) ) ;
return result ;
}
2025-02-13 11:46:51 +00:00
}