Compare commits

..

No commits in common. "d4fdb93b55d1bcb4e9fe283e0157ff000e2e3f0c" and "9c20beb6da8ae57f2c5b2521025e41eaba8ddc72" have entirely different histories.

18 changed files with 405 additions and 261 deletions

View file

@ -15,6 +15,7 @@ public class Global
public const string CoreConfigFileName = "config.json"; public const string CoreConfigFileName = "config.json";
public const string CorePreConfigFileName = "configPre.json"; public const string CorePreConfigFileName = "configPre.json";
public const string CoreSpeedtestConfigFileName = "configTest{0}.json"; public const string CoreSpeedtestConfigFileName = "configTest{0}.json";
public const string CoreMultipleLoadConfigFileName = "configMultipleLoad.json";
public const string ClashMixinConfigFileName = "Mixin.yaml"; public const string ClashMixinConfigFileName = "Mixin.yaml";
public const string NamespaceSample = "ServiceLib.Sample."; public const string NamespaceSample = "ServiceLib.Sample.";

View file

@ -18,6 +18,7 @@ public static class CoreConfigHandler
result = node.CoreType switch result = node.CoreType switch
{ {
ECoreType.mihomo => await new CoreConfigClashService(config).GenerateClientCustomConfig(node, fileName), ECoreType.mihomo => await new CoreConfigClashService(config).GenerateClientCustomConfig(node, fileName),
ECoreType.sing_box => await new CoreConfigSingboxService(context).GenerateClientCustomConfig(fileName),
_ => await GenerateClientCustomConfig(node, fileName) _ => await GenerateClientCustomConfig(node, fileName)
}; };
} }
@ -95,7 +96,8 @@ public static class CoreConfigHandler
var result = new RetResult(); var result = new RetResult();
var context = await BuildCoreConfigContext(config, new()); var context = await BuildCoreConfigContext(config, new());
var ids = selecteds.Where(serverTestItem => !serverTestItem.IndexId.IsNullOrEmpty()) var ids = selecteds.Where(serverTestItem => !serverTestItem.IndexId.IsNullOrEmpty())
.Select(serverTestItem => serverTestItem.IndexId); .Select(serverTestItem => serverTestItem.IndexId!)
.ToList();
var nodes = await AppManager.Instance.GetProfileItemsByIndexIds(ids); var nodes = await AppManager.Instance.GetProfileItemsByIndexIds(ids);
foreach (var node in nodes) foreach (var node in nodes)
{ {
@ -183,21 +185,18 @@ public static class CoreConfigHandler
{ {
return node; return node;
} }
context.AllProxiesMap[node.IndexId] = node;
var newItems = new List<ProfileItem> { node }; var newItems = new List<ProfileItem> { node };
if (node.ConfigType.IsGroupType()) if (node.ConfigType.IsGroupType())
{ {
var groupChildList = await GroupProfileManager.GetAllChildProfileItems(node); var groupChildList = await GroupProfileManager.GetAllChildProfileItems(node);
foreach (var childItem in groupChildList) foreach (var childItem in groupChildList)
{ {
context.AllProxiesMap[childItem.IndexId] = childItem; context.AllProxiesMap[childItem.IndexId] = childItem;
newItems.Add(childItem);
} }
node.SetProtocolExtra(node.GetProtocolExtra() with
{
ChildItems = Utils.List2String(groupChildList.Select(n => n.IndexId).ToList()),
});
newItems.AddRange(groupChildList);
} }
context.AllProxiesMap[node.IndexId] = node;
foreach (var item in newItems) foreach (var item in newItems)
{ {

View file

@ -230,9 +230,9 @@ public sealed class AppManager
return await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync(it => it.IndexId == indexId); return await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync(it => it.IndexId == indexId);
} }
public async Task<List<ProfileItem>> GetProfileItemsByIndexIds(IEnumerable<string> indexIds) public async Task<List<ProfileItem>> GetProfileItemsByIndexIds(List<string> indexIds)
{ {
var ids = indexIds.Where(id => !id.IsNullOrEmpty()).Distinct().ToList(); var ids = indexIds.Where(id => id.IsNotEmpty()).Distinct().ToList();
if (ids.Count == 0) if (ids.Count == 0)
{ {
return []; return [];

View file

@ -79,7 +79,7 @@ public class GroupProfileManager
{ {
if (protocolExtra == null) if (protocolExtra == null)
{ {
return []; return new();
} }
var items = new List<ProfileItem>(); var items = new List<ProfileItem>();
@ -93,19 +93,27 @@ public class GroupProfileManager
{ {
if (extra == null || extra.ChildItems.IsNullOrEmpty()) if (extra == null || extra.ChildItems.IsNullOrEmpty())
{ {
return []; return new();
} }
var childProfileIds = Utils.String2List(extra.ChildItems) var childProfiles = (await Task.WhenAll(
?.Where(p => !string.IsNullOrEmpty(p)) ?? []; (Utils.String2List(extra.ChildItems) ?? new())
var childProfiles = await AppManager.Instance.GetProfileItemsByIndexIds(childProfileIds); .Where(p => !p.IsNullOrEmpty())
return childProfiles ?? []; .Select(AppManager.Instance.GetProfileItem)
))
.Where(p =>
p != null &&
p.IsValid() &&
p.ConfigType != EConfigType.Custom
)
.ToList();
return childProfiles ?? new();
} }
private static async Task<List<ProfileItem>> GetSubChildProfileItems(ProtocolExtraItem? extra) private static async Task<List<ProfileItem>> GetSubChildProfileItems(ProtocolExtraItem? extra)
{ {
if (extra == null || extra.SubChildItems.IsNullOrEmpty()) if (extra == null || extra.SubChildItems.IsNullOrEmpty())
{ {
return []; return new();
} }
var childProfiles = await AppManager.Instance.ProfileItems(extra.SubChildItems ?? string.Empty); var childProfiles = await AppManager.Instance.ProfileItems(extra.SubChildItems ?? string.Empty);
@ -115,7 +123,7 @@ public class GroupProfileManager
!p.ConfigType.IsComplexType() && !p.ConfigType.IsComplexType() &&
(extra.Filter.IsNullOrEmpty() || Regex.IsMatch(p.Remarks, extra.Filter)) (extra.Filter.IsNullOrEmpty() || Regex.IsMatch(p.Remarks, extra.Filter))
) )
.ToList() ?? []; .ToList() ?? new();
} }
public static async Task<List<ProfileItem>> GetAllChildProfileItems(ProfileItem profileItem) public static async Task<List<ProfileItem>> GetAllChildProfileItems(ProfileItem profileItem)
@ -141,4 +149,38 @@ public class GroupProfileManager
} }
} }
} }
public static async Task<HashSet<string>> GetAllChildDomainAddresses(ProfileItem profileItem)
{
var childAddresses = new HashSet<string>();
var childItems = await GetAllChildProfileItems(profileItem);
foreach (var child in childItems.Where(child => !child.Address.IsNullOrEmpty()).Where(child => Utils.IsDomain(child.Address)))
{
childAddresses.Add(child.Address);
}
return childAddresses;
}
public static async Task<HashSet<string>> GetAllChildEchQuerySni(ProfileItem profileItem)
{
var childAddresses = new HashSet<string>();
var childItems = await GetAllChildProfileItems(profileItem);
foreach (var childNode in childItems.Where(childNode => !childNode.EchConfigList.IsNullOrEmpty()))
{
var sni = childNode.Sni;
if (childNode.StreamSecurity == Global.StreamSecurity
&& childNode.EchConfigList?.Contains("://") == true)
{
var idx = childNode.EchConfigList.IndexOf('+');
sni = idx > 0 ? childNode.EchConfigList[..idx] : childNode.Sni;
}
if (!Utils.IsDomain(sni))
{
continue;
}
childAddresses.Add(sni);
}
return childAddresses;
}
} }

View file

@ -3,8 +3,6 @@ namespace ServiceLib.Services.CoreConfig;
public partial class CoreConfigSingboxService(CoreConfigContext context) public partial class CoreConfigSingboxService(CoreConfigContext context)
{ {
private static readonly string _tag = "CoreConfigSingboxService"; private static readonly string _tag = "CoreConfigSingboxService";
private readonly Config _config = context.AppConfig;
private readonly ProfileItem _node = context.Node;
private SingboxConfig _coreConfig = new(); private SingboxConfig _coreConfig = new();
@ -15,15 +13,16 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
var ret = new RetResult(); var ret = new RetResult();
try try
{ {
if (_node == null var node = context.Node;
|| !_node.IsValid()) if (node == null
|| !node.IsValid())
{ {
ret.Msg = ResUI.CheckServerSettings; ret.Msg = ResUI.CheckServerSettings;
return ret; return ret;
} }
if (_node.GetNetwork() is nameof(ETransport.kcp) or nameof(ETransport.xhttp)) if (node.GetNetwork() is nameof(ETransport.kcp) or nameof(ETransport.xhttp))
{ {
ret.Msg = ResUI.Incorrectconfiguration + $" - {_node.GetNetwork()}"; ret.Msg = ResUI.Incorrectconfiguration + $" - {node.GetNetwork()}";
return ret; return ret;
} }
@ -194,15 +193,16 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
var ret = new RetResult(); var ret = new RetResult();
try try
{ {
if (_node == null var node = context.Node;
|| !_node.IsValid()) if (node == null
|| !node.IsValid())
{ {
ret.Msg = ResUI.CheckServerSettings; ret.Msg = ResUI.CheckServerSettings;
return ret; return ret;
} }
if (_node.GetNetwork() is nameof(ETransport.kcp) or nameof(ETransport.xhttp)) if (node.GetNetwork() is nameof(ETransport.kcp) or nameof(ETransport.xhttp))
{ {
ret.Msg = ResUI.Incorrectconfiguration + $" - {_node.GetNetwork()}"; ret.Msg = ResUI.Incorrectconfiguration + $" - {node.GetNetwork()}";
return ret; return ret;
} }
@ -249,5 +249,87 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
} }
} }
public async Task<RetResult> GenerateClientCustomConfig(string? fileName)
{
var ret = new RetResult();
var node = context.Node;
if (node == null || fileName is null)
{
ret.Msg = ResUI.CheckServerSettings;
return ret;
}
ret.Msg = ResUI.InitialConfiguration;
try
{
if (node == null)
{
ret.Msg = ResUI.CheckServerSettings;
return ret;
}
if (File.Exists(fileName))
{
File.Delete(fileName);
}
var addressFileName = node.Address;
if (addressFileName.IsNullOrEmpty())
{
ret.Msg = ResUI.FailedGetDefaultConfiguration;
return ret;
}
if (!File.Exists(addressFileName))
{
addressFileName = Path.Combine(Utils.GetConfigPath(), addressFileName);
}
if (!File.Exists(addressFileName))
{
ret.Msg = ResUI.FailedReadConfiguration + "1";
return ret;
}
if (node.Address == Global.CoreMultipleLoadConfigFileName)
{
var txtFile = File.ReadAllText(addressFileName);
_coreConfig = JsonUtils.Deserialize<SingboxConfig>(txtFile);
if (_coreConfig == null)
{
File.Copy(addressFileName, fileName);
}
else
{
GenInbounds();
GenExperimental();
var content = JsonUtils.Serialize(_coreConfig, true);
await File.WriteAllTextAsync(fileName, content);
}
}
else
{
File.Copy(addressFileName, fileName);
}
//check again
if (!File.Exists(fileName))
{
ret.Msg = ResUI.FailedReadConfiguration + "2";
return ret;
}
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
ret.Success = true;
return ret;
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
}
}
#endregion public gen function #endregion public gen function
} }

View file

@ -9,8 +9,8 @@ public partial class CoreConfigSingboxService
var listen = "0.0.0.0"; var listen = "0.0.0.0";
_coreConfig.inbounds = []; _coreConfig.inbounds = [];
if (!_config.TunModeItem.EnableTun if (!context.AppConfig.TunModeItem.EnableTun
|| (_config.TunModeItem.EnableTun && _config.TunModeItem.EnableExInbound && AppManager.Instance.RunningCoreType == ECoreType.sing_box)) || (context.AppConfig.TunModeItem.EnableTun && context.AppConfig.TunModeItem.EnableExInbound && AppManager.Instance.RunningCoreType == ECoreType.sing_box))
{ {
var inbound = new Inbound4Sbox() var inbound = new Inbound4Sbox()
{ {
@ -22,24 +22,24 @@ public partial class CoreConfigSingboxService
inbound.listen_port = AppManager.Instance.GetLocalPort(EInboundProtocol.socks); inbound.listen_port = AppManager.Instance.GetLocalPort(EInboundProtocol.socks);
if (_config.Inbound.First().SecondLocalPortEnabled) if (context.AppConfig.Inbound.First().SecondLocalPortEnabled)
{ {
var inbound2 = BuildInbound(inbound, EInboundProtocol.socks2, true); var inbound2 = BuildInbound(inbound, EInboundProtocol.socks2, true);
_coreConfig.inbounds.Add(inbound2); _coreConfig.inbounds.Add(inbound2);
} }
if (_config.Inbound.First().AllowLANConn) if (context.AppConfig.Inbound.First().AllowLANConn)
{ {
if (_config.Inbound.First().NewPort4LAN) if (context.AppConfig.Inbound.First().NewPort4LAN)
{ {
var inbound3 = BuildInbound(inbound, EInboundProtocol.socks3, true); var inbound3 = BuildInbound(inbound, EInboundProtocol.socks3, true);
inbound3.listen = listen; inbound3.listen = listen;
_coreConfig.inbounds.Add(inbound3); _coreConfig.inbounds.Add(inbound3);
//auth //auth
if (_config.Inbound.First().User.IsNotEmpty() && _config.Inbound.First().Pass.IsNotEmpty()) if (context.AppConfig.Inbound.First().User.IsNotEmpty() && context.AppConfig.Inbound.First().Pass.IsNotEmpty())
{ {
inbound3.users = new() { new() { username = _config.Inbound.First().User, password = _config.Inbound.First().Pass } }; inbound3.users = new() { new() { username = context.AppConfig.Inbound.First().User, password = context.AppConfig.Inbound.First().Pass } };
} }
} }
else else
@ -49,24 +49,24 @@ public partial class CoreConfigSingboxService
} }
} }
if (_config.TunModeItem.EnableTun) if (context.AppConfig.TunModeItem.EnableTun)
{ {
if (_config.TunModeItem.Mtu <= 0) if (context.AppConfig.TunModeItem.Mtu <= 0)
{ {
_config.TunModeItem.Mtu = Global.TunMtus.First(); context.AppConfig.TunModeItem.Mtu = Global.TunMtus.First();
} }
if (_config.TunModeItem.Stack.IsNullOrEmpty()) if (context.AppConfig.TunModeItem.Stack.IsNullOrEmpty())
{ {
_config.TunModeItem.Stack = Global.TunStacks.First(); context.AppConfig.TunModeItem.Stack = Global.TunStacks.First();
} }
var tunInbound = JsonUtils.Deserialize<Inbound4Sbox>(EmbedUtils.GetEmbedText(Global.TunSingboxInboundFileName)) ?? new Inbound4Sbox { }; var tunInbound = JsonUtils.Deserialize<Inbound4Sbox>(EmbedUtils.GetEmbedText(Global.TunSingboxInboundFileName)) ?? new Inbound4Sbox { };
tunInbound.interface_name = Utils.IsMacOS() ? $"utun{new Random().Next(99)}" : "singbox_tun"; tunInbound.interface_name = Utils.IsMacOS() ? $"utun{new Random().Next(99)}" : "singbox_tun";
tunInbound.mtu = _config.TunModeItem.Mtu; tunInbound.mtu = context.AppConfig.TunModeItem.Mtu;
tunInbound.auto_route = _config.TunModeItem.AutoRoute; tunInbound.auto_route = context.AppConfig.TunModeItem.AutoRoute;
tunInbound.strict_route = _config.TunModeItem.StrictRoute; tunInbound.strict_route = context.AppConfig.TunModeItem.StrictRoute;
tunInbound.stack = _config.TunModeItem.Stack; tunInbound.stack = context.AppConfig.TunModeItem.Stack;
if (_config.TunModeItem.EnableIPv6Address == false) if (context.AppConfig.TunModeItem.EnableIPv6Address == false)
{ {
tunInbound.address = ["172.18.0.1/30"]; tunInbound.address = ["172.18.0.1/30"];
} }

View file

@ -6,12 +6,12 @@ public partial class CoreConfigSingboxService
{ {
try try
{ {
switch (_config.CoreBasicItem.Loglevel) switch (context.AppConfig.CoreBasicItem.Loglevel)
{ {
case "debug": case "debug":
case "info": case "info":
case "error": case "error":
_coreConfig.log.level = _config.CoreBasicItem.Loglevel; _coreConfig.log.level = context.AppConfig.CoreBasicItem.Loglevel;
break; break;
case "warning": case "warning":
@ -21,11 +21,11 @@ public partial class CoreConfigSingboxService
default: default:
break; break;
} }
if (_config.CoreBasicItem.Loglevel == Global.None) if (context.AppConfig.CoreBasicItem.Loglevel == Global.None)
{ {
_coreConfig.log.disabled = true; _coreConfig.log.disabled = true;
} }
if (_config.CoreBasicItem.LogEnabled) if (context.AppConfig.CoreBasicItem.LogEnabled)
{ {
var dtNow = DateTime.Now; var dtNow = DateTime.Now;
_coreConfig.log.output = Utils.GetLogPath($"sbox_{dtNow:yyyy-MM-dd}.txt"); _coreConfig.log.output = Utils.GetLogPath($"sbox_{dtNow:yyyy-MM-dd}.txt");

View file

@ -11,7 +11,7 @@ public partial class CoreConfigSingboxService
private List<BaseServer4Sbox> BuildAllProxyOutbounds(string baseTagName = Global.ProxyTag, bool withSelector = true) private List<BaseServer4Sbox> BuildAllProxyOutbounds(string baseTagName = Global.ProxyTag, bool withSelector = true)
{ {
var proxyOutboundList = new List<BaseServer4Sbox>(); var proxyOutboundList = new List<BaseServer4Sbox>();
if (!_node.ConfigType.IsComplexType()) if (!context.Node.ConfigType.IsComplexType())
{ {
var outbound = BuildProxyOutbound(baseTagName); var outbound = BuildProxyOutbound(baseTagName);
proxyOutboundList.Add(outbound); proxyOutboundList.Add(outbound);
@ -38,7 +38,7 @@ public partial class CoreConfigSingboxService
private List<BaseServer4Sbox> BuildGroupProxyOutbounds(string baseTagName = Global.ProxyTag) private List<BaseServer4Sbox> BuildGroupProxyOutbounds(string baseTagName = Global.ProxyTag)
{ {
var proxyOutboundList = new List<BaseServer4Sbox>(); var proxyOutboundList = new List<BaseServer4Sbox>();
switch (_node.ConfigType) switch (context.Node.ConfigType)
{ {
case EConfigType.PolicyGroup: case EConfigType.PolicyGroup:
proxyOutboundList = BuildOutboundsList(baseTagName); proxyOutboundList = BuildOutboundsList(baseTagName);
@ -54,8 +54,9 @@ public partial class CoreConfigSingboxService
{ {
try try
{ {
var node = context.Node;
var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound); var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
if (_node.ConfigType == EConfigType.WireGuard) if (node.ConfigType == EConfigType.WireGuard)
{ {
var endpoint = JsonUtils.Deserialize<Endpoints4Sbox>(txtOutbound); var endpoint = JsonUtils.Deserialize<Endpoints4Sbox>(txtOutbound);
FillEndpoint(endpoint); FillEndpoint(endpoint);
@ -79,16 +80,17 @@ public partial class CoreConfigSingboxService
{ {
try try
{ {
var protocolExtra = _node.GetProtocolExtra(); var node = context.Node;
outbound.server = _node.Address; var protocolExtra = node.GetProtocolExtra();
outbound.server_port = _node.Port; outbound.server = node.Address;
outbound.type = Global.ProtocolTypes[_node.ConfigType]; outbound.server_port = node.Port;
outbound.type = Global.ProtocolTypes[node.ConfigType];
switch (_node.ConfigType) switch (node.ConfigType)
{ {
case EConfigType.VMess: case EConfigType.VMess:
{ {
outbound.uuid = _node.Password; outbound.uuid = node.Password;
outbound.alter_id = int.TryParse(protocolExtra.AlterId, out var result) ? result : 0; outbound.alter_id = int.TryParse(protocolExtra.AlterId, out var result) ? result : 0;
if (Global.VmessSecurities.Contains(protocolExtra.VmessSecurity)) if (Global.VmessSecurities.Contains(protocolExtra.VmessSecurity))
{ {
@ -105,35 +107,35 @@ public partial class CoreConfigSingboxService
} }
case EConfigType.Shadowsocks: case EConfigType.Shadowsocks:
{ {
outbound.method = AppManager.Instance.GetShadowsocksSecurities(_node).Contains(protocolExtra.SsMethod) outbound.method = AppManager.Instance.GetShadowsocksSecurities(node).Contains(protocolExtra.SsMethod)
? protocolExtra.SsMethod : Global.None; ? protocolExtra.SsMethod : Global.None;
outbound.password = _node.Password; outbound.password = node.Password;
if (_node.Network == nameof(ETransport.tcp) && _node.HeaderType == Global.TcpHeaderHttp) if (node.Network == nameof(ETransport.tcp) && node.HeaderType == Global.TcpHeaderHttp)
{ {
outbound.plugin = "obfs-local"; outbound.plugin = "obfs-local";
outbound.plugin_opts = $"obfs=http;obfs-host={_node.RequestHost};"; outbound.plugin_opts = $"obfs=http;obfs-host={node.RequestHost};";
} }
else else
{ {
var pluginArgs = string.Empty; var pluginArgs = string.Empty;
if (_node.Network == nameof(ETransport.ws)) if (node.Network == nameof(ETransport.ws))
{ {
pluginArgs += "mode=websocket;"; pluginArgs += "mode=websocket;";
pluginArgs += $"host={_node.RequestHost};"; pluginArgs += $"host={node.RequestHost};";
// https://github.com/shadowsocks/v2ray-plugin/blob/e9af1cdd2549d528deb20a4ab8d61c5fbe51f306/args.go#L172 // https://github.com/shadowsocks/v2ray-plugin/blob/e9af1cdd2549d528deb20a4ab8d61c5fbe51f306/args.go#L172
// Equal signs and commas [and backslashes] must be escaped with a backslash. // Equal signs and commas [and backslashes] must be escaped with a backslash.
var path = _node.Path.Replace("\\", "\\\\").Replace("=", "\\=").Replace(",", "\\,"); var path = node.Path.Replace("\\", "\\\\").Replace("=", "\\=").Replace(",", "\\,");
pluginArgs += $"path={path};"; pluginArgs += $"path={path};";
} }
else if (_node.Network == nameof(ETransport.quic)) else if (node.Network == nameof(ETransport.quic))
{ {
pluginArgs += "mode=quic;"; pluginArgs += "mode=quic;";
} }
if (_node.StreamSecurity == Global.StreamSecurity) if (node.StreamSecurity == Global.StreamSecurity)
{ {
pluginArgs += "tls;"; pluginArgs += "tls;";
var certs = CertPemManager.ParsePemChain(_node.Cert); var certs = CertPemManager.ParsePemChain(node.Cert);
if (certs.Count > 0) if (certs.Count > 0)
{ {
var cert = certs.First(); var cert = certs.First();
@ -163,27 +165,27 @@ public partial class CoreConfigSingboxService
case EConfigType.SOCKS: case EConfigType.SOCKS:
{ {
outbound.version = "5"; outbound.version = "5";
if (_node.Username.IsNotEmpty() if (node.Username.IsNotEmpty()
&& _node.Password.IsNotEmpty()) && node.Password.IsNotEmpty())
{ {
outbound.username = _node.Username; outbound.username = node.Username;
outbound.password = _node.Password; outbound.password = node.Password;
} }
break; break;
} }
case EConfigType.HTTP: case EConfigType.HTTP:
{ {
if (_node.Username.IsNotEmpty() if (node.Username.IsNotEmpty()
&& _node.Password.IsNotEmpty()) && node.Password.IsNotEmpty())
{ {
outbound.username = _node.Username; outbound.username = node.Username;
outbound.password = _node.Password; outbound.password = node.Password;
} }
break; break;
} }
case EConfigType.VLESS: case EConfigType.VLESS:
{ {
outbound.uuid = _node.Password; outbound.uuid = node.Password;
outbound.packet_encoding = "xudp"; outbound.packet_encoding = "xudp";
@ -201,7 +203,7 @@ public partial class CoreConfigSingboxService
} }
case EConfigType.Trojan: case EConfigType.Trojan:
{ {
outbound.password = _node.Password; outbound.password = node.Password;
FillOutboundMux(outbound); FillOutboundMux(outbound);
FillOutboundTransport(outbound); FillOutboundTransport(outbound);
@ -209,7 +211,7 @@ public partial class CoreConfigSingboxService
} }
case EConfigType.Hysteria2: case EConfigType.Hysteria2:
{ {
outbound.password = _node.Password; outbound.password = node.Password;
if (!protocolExtra.SalamanderPass.IsNullOrEmpty()) if (!protocolExtra.SalamanderPass.IsNullOrEmpty())
{ {
@ -222,10 +224,10 @@ public partial class CoreConfigSingboxService
outbound.up_mbps = protocolExtra?.UpMbps is { } su and >= 0 outbound.up_mbps = protocolExtra?.UpMbps is { } su and >= 0
? su ? su
: _config.HysteriaItem.UpMbps; : context.AppConfig.HysteriaItem.UpMbps;
outbound.down_mbps = protocolExtra?.DownMbps is { } sd and >= 0 outbound.down_mbps = protocolExtra?.DownMbps is { } sd and >= 0
? sd ? sd
: _config.HysteriaItem.DownMbps; : context.AppConfig.HysteriaItem.DownMbps;
var ports = protocolExtra?.Ports?.IsNullOrEmpty() == false ? protocolExtra.Ports : null; var ports = protocolExtra?.Ports?.IsNullOrEmpty() == false ? protocolExtra.Ports : null;
if ((!ports.IsNullOrEmpty()) && (ports.Contains(':') || ports.Contains('-') || ports.Contains(','))) if ((!ports.IsNullOrEmpty()) && (ports.Contains(':') || ports.Contains('-') || ports.Contains(',')))
{ {
@ -239,8 +241,8 @@ public partial class CoreConfigSingboxService
return port.Contains(':') ? port : $"{port}:{port}"; return port.Contains(':') ? port : $"{port}:{port}";
}) })
.ToList(); .ToList();
outbound.hop_interval = _config.HysteriaItem.HopInterval >= 5 outbound.hop_interval = context.AppConfig.HysteriaItem.HopInterval >= 5
? $"{_config.HysteriaItem.HopInterval}s" ? $"{context.AppConfig.HysteriaItem.HopInterval}s"
: $"{Global.Hysteria2DefaultHopInt}s"; : $"{Global.Hysteria2DefaultHopInt}s";
if (int.TryParse(protocolExtra.HopInterval, out var hiResult)) if (int.TryParse(protocolExtra.HopInterval, out var hiResult))
{ {
@ -263,14 +265,14 @@ public partial class CoreConfigSingboxService
} }
case EConfigType.TUIC: case EConfigType.TUIC:
{ {
outbound.uuid = _node.Username; outbound.uuid = node.Username;
outbound.password = _node.Password; outbound.password = node.Password;
outbound.congestion_control = _node.HeaderType; outbound.congestion_control = node.HeaderType;
break; break;
} }
case EConfigType.Anytls: case EConfigType.Anytls:
{ {
outbound.password = _node.Password; outbound.password = node.Password;
break; break;
} }
} }
@ -287,12 +289,13 @@ public partial class CoreConfigSingboxService
{ {
try try
{ {
var protocolExtra = _node.GetProtocolExtra(); var node = context.Node;
var protocolExtra = node.GetProtocolExtra();
endpoint.address = Utils.String2List(protocolExtra.WgInterfaceAddress); endpoint.address = Utils.String2List(protocolExtra.WgInterfaceAddress);
endpoint.type = Global.ProtocolTypes[_node.ConfigType]; endpoint.type = Global.ProtocolTypes[node.ConfigType];
switch (_node.ConfigType) switch (node.ConfigType)
{ {
case EConfigType.WireGuard: case EConfigType.WireGuard:
{ {
@ -301,12 +304,12 @@ public partial class CoreConfigSingboxService
public_key = protocolExtra.WgPublicKey, public_key = protocolExtra.WgPublicKey,
pre_shared_key = protocolExtra.WgPresharedKey, pre_shared_key = protocolExtra.WgPresharedKey,
reserved = Utils.String2List(protocolExtra.WgReserved)?.Select(int.Parse).ToList(), reserved = Utils.String2List(protocolExtra.WgReserved)?.Select(int.Parse).ToList(),
address = _node.Address, address = node.Address,
port = _node.Port, port = node.Port,
// TODO default ["0.0.0.0/0", "::/0"] // TODO default ["0.0.0.0/0", "::/0"]
allowed_ips = new() { "0.0.0.0/0", "::/0" }, allowed_ips = new() { "0.0.0.0/0", "::/0" },
}; };
endpoint.private_key = _node.Password; endpoint.private_key = node.Password;
endpoint.mtu = protocolExtra.WgMtu > 0 ? protocolExtra.WgMtu : Global.TunMtus.First(); endpoint.mtu = protocolExtra.WgMtu > 0 ? protocolExtra.WgMtu : Global.TunMtus.First();
endpoint.peers = [peer]; endpoint.peers = [peer];
break; break;
@ -323,15 +326,16 @@ public partial class CoreConfigSingboxService
{ {
try try
{ {
var muxEnabled = _node.MuxEnabled ?? _config.CoreBasicItem.MuxEnabled; var config = context.AppConfig;
if (muxEnabled && _config.Mux4SboxItem.Protocol.IsNotEmpty()) var muxEnabled = context.Node.MuxEnabled ?? config.CoreBasicItem.MuxEnabled;
if (muxEnabled && config.Mux4SboxItem.Protocol.IsNotEmpty())
{ {
var mux = new Multiplex4Sbox() var mux = new Multiplex4Sbox()
{ {
enabled = true, enabled = true,
protocol = _config.Mux4SboxItem.Protocol, protocol = config.Mux4SboxItem.Protocol,
max_connections = _config.Mux4SboxItem.MaxConnections, max_connections = config.Mux4SboxItem.MaxConnections,
padding = _config.Mux4SboxItem.Padding, padding = config.Mux4SboxItem.Padding,
}; };
outbound.multiplex = mux; outbound.multiplex = mux;
} }
@ -346,59 +350,60 @@ public partial class CoreConfigSingboxService
{ {
try try
{ {
if (_node.StreamSecurity is not (Global.StreamSecurityReality or Global.StreamSecurity)) var node = context.Node;
if (node.StreamSecurity is not (Global.StreamSecurityReality or Global.StreamSecurity))
{ {
return; return;
} }
if (_node.ConfigType is EConfigType.Shadowsocks or EConfigType.SOCKS or EConfigType.WireGuard) if (node.ConfigType is EConfigType.Shadowsocks or EConfigType.SOCKS or EConfigType.WireGuard)
{ {
return; return;
} }
var serverName = string.Empty; var serverName = string.Empty;
if (_node.Sni.IsNotEmpty()) if (node.Sni.IsNotEmpty())
{ {
serverName = _node.Sni; serverName = node.Sni;
} }
else if (_node.RequestHost.IsNotEmpty()) else if (node.RequestHost.IsNotEmpty())
{ {
serverName = Utils.String2List(_node.RequestHost)?.First(); serverName = Utils.String2List(node.RequestHost)?.First();
} }
var tls = new Tls4Sbox() var tls = new Tls4Sbox()
{ {
enabled = true, enabled = true,
record_fragment = _config.CoreBasicItem.EnableFragment ? true : null, record_fragment = context.AppConfig.CoreBasicItem.EnableFragment ? true : null,
server_name = serverName, server_name = serverName,
insecure = Utils.ToBool(_node.AllowInsecure.IsNullOrEmpty() ? _config.CoreBasicItem.DefAllowInsecure.ToString().ToLower() : _node.AllowInsecure), insecure = Utils.ToBool(node.AllowInsecure.IsNullOrEmpty() ? context.AppConfig.CoreBasicItem.DefAllowInsecure.ToString().ToLower() : node.AllowInsecure),
alpn = _node.GetAlpn(), alpn = node.GetAlpn(),
}; };
if (_node.Fingerprint.IsNotEmpty()) if (node.Fingerprint.IsNotEmpty())
{ {
tls.utls = new Utls4Sbox() tls.utls = new Utls4Sbox()
{ {
enabled = true, enabled = true,
fingerprint = _node.Fingerprint.IsNullOrEmpty() ? _config.CoreBasicItem.DefFingerprint : _node.Fingerprint fingerprint = node.Fingerprint.IsNullOrEmpty() ? context.AppConfig.CoreBasicItem.DefFingerprint : node.Fingerprint
}; };
} }
if (_node.StreamSecurity == Global.StreamSecurity) if (node.StreamSecurity == Global.StreamSecurity)
{ {
var certs = CertPemManager.ParsePemChain(_node.Cert); var certs = CertPemManager.ParsePemChain(node.Cert);
if (certs.Count > 0) if (certs.Count > 0)
{ {
tls.certificate = certs; tls.certificate = certs;
tls.insecure = false; tls.insecure = false;
} }
} }
else if (_node.StreamSecurity == Global.StreamSecurityReality) else if (node.StreamSecurity == Global.StreamSecurityReality)
{ {
tls.reality = new Reality4Sbox() tls.reality = new Reality4Sbox()
{ {
enabled = true, enabled = true,
public_key = _node.PublicKey, public_key = node.PublicKey,
short_id = _node.ShortId short_id = node.ShortId
}; };
tls.insecure = false; tls.insecure = false;
} }
var (ech, _) = ParseEchParam(_node.EchConfigList); var (ech, _) = ParseEchParam(node.EchConfigList);
if (ech is not null) if (ech is not null)
{ {
tls.ech = ech; tls.ech = ech;
@ -415,28 +420,29 @@ public partial class CoreConfigSingboxService
{ {
try try
{ {
var node = context.Node;
var transport = new Transport4Sbox(); var transport = new Transport4Sbox();
switch (_node.GetNetwork()) switch (node.GetNetwork())
{ {
case nameof(ETransport.h2): case nameof(ETransport.h2):
transport.type = nameof(ETransport.http); transport.type = nameof(ETransport.http);
transport.host = _node.RequestHost.IsNullOrEmpty() ? null : Utils.String2List(_node.RequestHost); transport.host = node.RequestHost.IsNullOrEmpty() ? null : Utils.String2List(node.RequestHost);
transport.path = _node.Path.NullIfEmpty(); transport.path = node.Path.NullIfEmpty();
break; break;
case nameof(ETransport.tcp): //http case nameof(ETransport.tcp): //http
if (_node.HeaderType == Global.TcpHeaderHttp) if (node.HeaderType == Global.TcpHeaderHttp)
{ {
transport.type = nameof(ETransport.http); transport.type = nameof(ETransport.http);
transport.host = _node.RequestHost.IsNullOrEmpty() ? null : Utils.String2List(_node.RequestHost); transport.host = node.RequestHost.IsNullOrEmpty() ? null : Utils.String2List(node.RequestHost);
transport.path = _node.Path.NullIfEmpty(); transport.path = node.Path.NullIfEmpty();
} }
break; break;
case nameof(ETransport.ws): case nameof(ETransport.ws):
transport.type = nameof(ETransport.ws); transport.type = nameof(ETransport.ws);
var wsPath = _node.Path; var wsPath = node.Path;
// Parse eh and ed parameters from path using regex // Parse eh and ed parameters from path using regex
if (!wsPath.IsNullOrEmpty()) if (!wsPath.IsNullOrEmpty())
@ -465,19 +471,19 @@ public partial class CoreConfigSingboxService
} }
transport.path = wsPath.NullIfEmpty(); transport.path = wsPath.NullIfEmpty();
if (_node.RequestHost.IsNotEmpty()) if (node.RequestHost.IsNotEmpty())
{ {
transport.headers = new() transport.headers = new()
{ {
Host = _node.RequestHost Host = node.RequestHost
}; };
} }
break; break;
case nameof(ETransport.httpupgrade): case nameof(ETransport.httpupgrade):
transport.type = nameof(ETransport.httpupgrade); transport.type = nameof(ETransport.httpupgrade);
transport.path = _node.Path.NullIfEmpty(); transport.path = node.Path.NullIfEmpty();
transport.host = _node.RequestHost.NullIfEmpty(); transport.host = node.RequestHost.NullIfEmpty();
break; break;
@ -487,10 +493,10 @@ public partial class CoreConfigSingboxService
case nameof(ETransport.grpc): case nameof(ETransport.grpc):
transport.type = nameof(ETransport.grpc); transport.type = nameof(ETransport.grpc);
transport.service_name = _node.Path; transport.service_name = node.Path;
transport.idle_timeout = _config.GrpcItem.IdleTimeout?.ToString("##s"); transport.idle_timeout = context.AppConfig.GrpcItem.IdleTimeout?.ToString("##s");
transport.ping_timeout = _config.GrpcItem.HealthCheckTimeout?.ToString("##s"); transport.ping_timeout = context.AppConfig.GrpcItem.HealthCheckTimeout?.ToString("##s");
transport.permit_without_stream = _config.GrpcItem.PermitWithoutStream; transport.permit_without_stream = context.AppConfig.GrpcItem.PermitWithoutStream;
break; break;
default: default:
@ -509,7 +515,7 @@ public partial class CoreConfigSingboxService
private List<Outbound4Sbox> BuildSelectorOutbounds(List<string> proxyTags, string baseTagName = Global.ProxyTag) private List<Outbound4Sbox> BuildSelectorOutbounds(List<string> proxyTags, string baseTagName = Global.ProxyTag)
{ {
var multipleLoad = _node.GetProtocolExtra().MultipleLoad ?? EMultipleLoad.LeastPing; var multipleLoad = context.Node.GetProtocolExtra().MultipleLoad ?? EMultipleLoad.LeastPing;
var outUrltest = new Outbound4Sbox var outUrltest = new Outbound4Sbox
{ {
type = "urltest", type = "urltest",
@ -539,7 +545,7 @@ public partial class CoreConfigSingboxService
private List<BaseServer4Sbox> BuildOutboundsList(string baseTagName = Global.ProxyTag) private List<BaseServer4Sbox> BuildOutboundsList(string baseTagName = Global.ProxyTag)
{ {
var nodes = new List<ProfileItem>(); var nodes = new List<ProfileItem>();
foreach (var nodeId in Utils.String2List(_node.GetProtocolExtra().ChildItems) ?? []) foreach (var nodeId in Utils.String2List(context.Node.GetProtocolExtra().ChildItems) ?? [])
{ {
if (context.AllProxiesMap.TryGetValue(nodeId, out var node)) if (context.AllProxiesMap.TryGetValue(nodeId, out var node))
{ {
@ -568,7 +574,7 @@ public partial class CoreConfigSingboxService
private List<BaseServer4Sbox> BuildChainOutboundsList(string baseTagName = Global.ProxyTag) private List<BaseServer4Sbox> BuildChainOutboundsList(string baseTagName = Global.ProxyTag)
{ {
var nodes = new List<ProfileItem>(); var nodes = new List<ProfileItem>();
foreach (var nodeId in Utils.String2List(_node.GetProtocolExtra().ChildItems) ?? []) foreach (var nodeId in Utils.String2List(context.Node.GetProtocolExtra().ChildItems) ?? [])
{ {
if (context.AllProxiesMap.TryGetValue(nodeId, out var node)) if (context.AllProxiesMap.TryGetValue(nodeId, out var node))
{ {

View file

@ -7,7 +7,7 @@ public partial class CoreConfigSingboxService
try try
{ {
_coreConfig.route.final = Global.ProxyTag; _coreConfig.route.final = Global.ProxyTag;
var simpleDnsItem = context.SimpleDnsItem; var simpleDnsItem = context.AppConfig.SimpleDNSItem;
var defaultDomainResolverTag = Global.SingboxDirectDNSTag; var defaultDomainResolverTag = Global.SingboxDirectDNSTag;
var directDnsStrategy = Utils.DomainStrategy4Sbox(simpleDnsItem.Strategy4Freedom); var directDnsStrategy = Utils.DomainStrategy4Sbox(simpleDnsItem.Strategy4Freedom);
@ -24,7 +24,7 @@ public partial class CoreConfigSingboxService
strategy = directDnsStrategy strategy = directDnsStrategy
}; };
if (_config.TunModeItem.EnableTun) if (context.AppConfig.TunModeItem.EnableTun)
{ {
_coreConfig.route.auto_detect_interface = true; _coreConfig.route.auto_detect_interface = true;
@ -49,7 +49,7 @@ public partial class CoreConfigSingboxService
}); });
} }
if (_config.Inbound.First().SniffingEnabled) if (context.AppConfig.Inbound.First().SniffingEnabled)
{ {
_coreConfig.route.rules.Add(new() _coreConfig.route.rules.Add(new()
{ {
@ -102,7 +102,7 @@ public partial class CoreConfigSingboxService
clash_mode = ERuleMode.Global.ToString() clash_mode = ERuleMode.Global.ToString()
}); });
var domainStrategy = _config.RoutingBasicItem.DomainStrategy4Singbox.NullIfEmpty(); var domainStrategy = context.AppConfig.RoutingBasicItem.DomainStrategy4Singbox.NullIfEmpty();
var routing = context.RoutingItem; var routing = context.RoutingItem;
if (routing.DomainStrategy4Singbox.IsNotEmpty()) if (routing.DomainStrategy4Singbox.IsNotEmpty())
{ {
@ -113,7 +113,7 @@ public partial class CoreConfigSingboxService
action = "resolve", action = "resolve",
strategy = domainStrategy strategy = domainStrategy
}; };
if (_config.RoutingBasicItem.DomainStrategy == Global.IPOnDemand) if (context.AppConfig.RoutingBasicItem.DomainStrategy == Global.IPOnDemand)
{ {
_coreConfig.route.rules.Add(resolveRule); _coreConfig.route.rules.Add(resolveRule);
} }
@ -142,7 +142,7 @@ public partial class CoreConfigSingboxService
} }
} }
} }
if (_config.RoutingBasicItem.DomainStrategy == Global.IPIfNonMatch) if (context.AppConfig.RoutingBasicItem.DomainStrategy == Global.IPIfNonMatch)
{ {
_coreConfig.route.rules.Add(resolveRule); _coreConfig.route.rules.Add(resolveRule);
foreach (var item2 in ipRules) foreach (var item2 in ipRules)

View file

@ -99,9 +99,9 @@ public partial class CoreConfigSingboxService
} }
else else
{ {
var srsUrl = string.IsNullOrEmpty(_config.ConstItem.SrsSourceUrl) var srsUrl = string.IsNullOrEmpty(context.AppConfig.ConstItem.SrsSourceUrl)
? Global.SingboxRulesetUrl ? Global.SingboxRulesetUrl
: _config.ConstItem.SrsSourceUrl; : context.AppConfig.ConstItem.SrsSourceUrl;
customRuleset = new() customRuleset = new()
{ {

View file

@ -13,14 +13,14 @@ public partial class CoreConfigSingboxService
}; };
} }
if (_config.CoreBasicItem.EnableCacheFile4Sbox) if (context.AppConfig.CoreBasicItem.EnableCacheFile4Sbox)
{ {
_coreConfig.experimental ??= new Experimental4Sbox(); _coreConfig.experimental ??= new Experimental4Sbox();
_coreConfig.experimental.cache_file = new CacheFile4Sbox() _coreConfig.experimental.cache_file = new CacheFile4Sbox()
{ {
enabled = true, enabled = true,
path = Utils.GetBinPath("cache.db"), path = Utils.GetBinPath("cache.db"),
store_fakeip = context.SimpleDnsItem.FakeIP == true store_fakeip = context.AppConfig.SimpleDNSItem.FakeIP == true
}; };
} }
} }

View file

@ -3,8 +3,6 @@ namespace ServiceLib.Services.CoreConfig;
public partial class CoreConfigV2rayService(CoreConfigContext context) public partial class CoreConfigV2rayService(CoreConfigContext context)
{ {
private static readonly string _tag = "CoreConfigV2rayService"; private static readonly string _tag = "CoreConfigV2rayService";
private readonly Config _config = context.AppConfig;
private readonly ProfileItem _node = context.Node;
private V2rayConfig _coreConfig = new(); private V2rayConfig _coreConfig = new();
@ -15,16 +13,17 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
var ret = new RetResult(); var ret = new RetResult();
try try
{ {
if (_node == null var node = context?.Node;
|| !_node.IsValid()) if (node == null
|| !node.IsValid())
{ {
ret.Msg = ResUI.CheckServerSettings; ret.Msg = ResUI.CheckServerSettings;
return ret; return ret;
} }
if (_node.GetNetwork() is nameof(ETransport.quic)) if (node.GetNetwork() is nameof(ETransport.quic))
{ {
ret.Msg = ResUI.Incorrectconfiguration + $" - {_node.GetNetwork()}"; ret.Msg = ResUI.Incorrectconfiguration + $" - {node.GetNetwork()}";
return ret; return ret;
} }
@ -171,7 +170,7 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
if (proxyOutbounds.Count(n => n.tag.StartsWith(tag)) > 1) if (proxyOutbounds.Count(n => n.tag.StartsWith(tag)) > 1)
{ {
isBalancer = true; isBalancer = true;
var multipleLoad = _node.GetProtocolExtra().MultipleLoad ?? EMultipleLoad.LeastPing; var multipleLoad = context.Node.GetProtocolExtra().MultipleLoad ?? EMultipleLoad.LeastPing;
GenObservatory(multipleLoad, tag); GenObservatory(multipleLoad, tag);
GenBalancer(multipleLoad, tag); GenBalancer(multipleLoad, tag);
} }
@ -209,16 +208,17 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
var ret = new RetResult(); var ret = new RetResult();
try try
{ {
if (_node == null var node = context.Node;
|| !_node.IsValid()) if (node == null
|| !node.IsValid())
{ {
ret.Msg = ResUI.CheckServerSettings; ret.Msg = ResUI.CheckServerSettings;
return ret; return ret;
} }
if (_node.GetNetwork() is nameof(ETransport.quic)) if (node.GetNetwork() is nameof(ETransport.quic))
{ {
ret.Msg = ResUI.Incorrectconfiguration + $" - {_node.GetNetwork()}"; ret.Msg = ResUI.Incorrectconfiguration + $" - {node.GetNetwork()}";
return ret; return ret;
} }

View file

@ -92,6 +92,7 @@ public partial class CoreConfigV2rayService
private void FillDnsServers(Dns4Ray dnsItem) private void FillDnsServers(Dns4Ray dnsItem)
{ {
var node = context.Node;
var simpleDNSItem = context.SimpleDnsItem; var simpleDNSItem = context.SimpleDnsItem;
static List<string> ParseDnsAddresses(string? dnsInput, string defaultAddress) static List<string> ParseDnsAddresses(string? dnsInput, string defaultAddress)
{ {
@ -245,6 +246,11 @@ public partial class CoreConfigV2rayService
} }
} }
if (Utils.IsDomain(node?.Address))
{
directDomainList.Add(node.Address);
}
if (context.ProtectDomainList.Count > 0) if (context.ProtectDomainList.Count > 0)
{ {
directDomainList.AddRange(context.ProtectDomainList); directDomainList.AddRange(context.ProtectDomainList);
@ -401,6 +407,7 @@ public partial class CoreConfigV2rayService
private void FillDnsDomainsCustom(JsonNode dns) private void FillDnsDomainsCustom(JsonNode dns)
{ {
var node = context.Node;
var servers = dns["servers"]; var servers = dns["servers"];
if (servers == null) if (servers == null)
{ {

View file

@ -6,31 +6,32 @@ public partial class CoreConfigV2rayService
{ {
try try
{ {
var config = context.AppConfig;
var listen = "0.0.0.0"; var listen = "0.0.0.0";
_coreConfig.inbounds = []; _coreConfig.inbounds = [];
var inbound = BuildInbound(_config.Inbound.First(), EInboundProtocol.socks, true); var inbound = BuildInbound(config.Inbound.First(), EInboundProtocol.socks, true);
_coreConfig.inbounds.Add(inbound); _coreConfig.inbounds.Add(inbound);
if (_config.Inbound.First().SecondLocalPortEnabled) if (config.Inbound.First().SecondLocalPortEnabled)
{ {
var inbound2 = BuildInbound(_config.Inbound.First(), EInboundProtocol.socks2, true); var inbound2 = BuildInbound(config.Inbound.First(), EInboundProtocol.socks2, true);
_coreConfig.inbounds.Add(inbound2); _coreConfig.inbounds.Add(inbound2);
} }
if (_config.Inbound.First().AllowLANConn) if (config.Inbound.First().AllowLANConn)
{ {
if (_config.Inbound.First().NewPort4LAN) if (config.Inbound.First().NewPort4LAN)
{ {
var inbound3 = BuildInbound(_config.Inbound.First(), EInboundProtocol.socks3, true); var inbound3 = BuildInbound(config.Inbound.First(), EInboundProtocol.socks3, true);
inbound3.listen = listen; inbound3.listen = listen;
_coreConfig.inbounds.Add(inbound3); _coreConfig.inbounds.Add(inbound3);
//auth //auth
if (_config.Inbound.First().User.IsNotEmpty() && _config.Inbound.First().Pass.IsNotEmpty()) if (config.Inbound.First().User.IsNotEmpty() && config.Inbound.First().Pass.IsNotEmpty())
{ {
inbound3.settings.auth = "password"; inbound3.settings.auth = "password";
inbound3.settings.accounts = new List<AccountsItem4Ray> { new() { user = _config.Inbound.First().User, pass = _config.Inbound.First().Pass } }; inbound3.settings.accounts = new List<AccountsItem4Ray> { new() { user = config.Inbound.First().User, pass = config.Inbound.First().Pass } };
} }
} }
else else

View file

@ -6,16 +6,17 @@ public partial class CoreConfigV2rayService
{ {
try try
{ {
if (_config.CoreBasicItem.LogEnabled) var config = context.AppConfig;
if (config.CoreBasicItem.LogEnabled)
{ {
var dtNow = DateTime.Now; var dtNow = DateTime.Now;
_coreConfig.log.loglevel = _config.CoreBasicItem.Loglevel; _coreConfig.log.loglevel = config.CoreBasicItem.Loglevel;
_coreConfig.log.access = Utils.GetLogPath($"Vaccess_{dtNow:yyyy-MM-dd}.txt"); _coreConfig.log.access = Utils.GetLogPath($"Vaccess_{dtNow:yyyy-MM-dd}.txt");
_coreConfig.log.error = Utils.GetLogPath($"Verror_{dtNow:yyyy-MM-dd}.txt"); _coreConfig.log.error = Utils.GetLogPath($"Verror_{dtNow:yyyy-MM-dd}.txt");
} }
else else
{ {
_coreConfig.log.loglevel = _config.CoreBasicItem.Loglevel; _coreConfig.log.loglevel = config.CoreBasicItem.Loglevel;
_coreConfig.log.access = null; _coreConfig.log.access = null;
_coreConfig.log.error = null; _coreConfig.log.error = null;
} }

View file

@ -8,7 +8,7 @@ public partial class CoreConfigV2rayService
_coreConfig.outbounds.InsertRange(0, proxyOutboundList); _coreConfig.outbounds.InsertRange(0, proxyOutboundList);
if (proxyOutboundList.Count(n => n.tag.StartsWith(Global.ProxyTag)) > 1) if (proxyOutboundList.Count(n => n.tag.StartsWith(Global.ProxyTag)) > 1)
{ {
var multipleLoad = _node.GetProtocolExtra().MultipleLoad ?? EMultipleLoad.LeastPing; var multipleLoad = context.Node.GetProtocolExtra().MultipleLoad ?? EMultipleLoad.LeastPing;
GenObservatory(multipleLoad); GenObservatory(multipleLoad);
GenBalancer(multipleLoad); GenBalancer(multipleLoad);
} }
@ -17,7 +17,8 @@ public partial class CoreConfigV2rayService
private List<Outbounds4Ray> BuildAllProxyOutbounds(string baseTagName = Global.ProxyTag) private List<Outbounds4Ray> BuildAllProxyOutbounds(string baseTagName = Global.ProxyTag)
{ {
var proxyOutboundList = new List<Outbounds4Ray>(); var proxyOutboundList = new List<Outbounds4Ray>();
if (_node.ConfigType.IsGroupType()) var node = context.Node;
if (node.ConfigType.IsGroupType())
{ {
proxyOutboundList.AddRange(BuildGroupProxyOutbounds(baseTagName)); proxyOutboundList.AddRange(BuildGroupProxyOutbounds(baseTagName));
} }
@ -26,7 +27,7 @@ public partial class CoreConfigV2rayService
proxyOutboundList.Add(BuildProxyOutbound(baseTagName)); proxyOutboundList.Add(BuildProxyOutbound(baseTagName));
} }
if (_config.CoreBasicItem.EnableFragment) if (context.AppConfig.CoreBasicItem.EnableFragment)
{ {
var fragmentOutbound = new Outbounds4Ray var fragmentOutbound = new Outbounds4Ray
{ {
@ -36,9 +37,9 @@ public partial class CoreConfigV2rayService
{ {
fragment = new() fragment = new()
{ {
packets = _config.Fragment4RayItem?.Packets, packets = context.AppConfig.Fragment4RayItem?.Packets,
length = _config.Fragment4RayItem?.Length, length = context.AppConfig.Fragment4RayItem?.Length,
interval = _config.Fragment4RayItem?.Interval interval = context.AppConfig.Fragment4RayItem?.Interval
} }
} }
}; };
@ -62,7 +63,8 @@ public partial class CoreConfigV2rayService
private List<Outbounds4Ray> BuildGroupProxyOutbounds(string baseTagName = Global.ProxyTag) private List<Outbounds4Ray> BuildGroupProxyOutbounds(string baseTagName = Global.ProxyTag)
{ {
var proxyOutboundList = new List<Outbounds4Ray>(); var proxyOutboundList = new List<Outbounds4Ray>();
switch (_node.ConfigType) var node = context.Node;
switch (node.ConfigType)
{ {
case EConfigType.PolicyGroup: case EConfigType.PolicyGroup:
proxyOutboundList.AddRange(BuildOutboundsList(baseTagName)); proxyOutboundList.AddRange(BuildOutboundsList(baseTagName));
@ -87,9 +89,10 @@ public partial class CoreConfigV2rayService
{ {
try try
{ {
var protocolExtra = _node.GetProtocolExtra(); var node = context.Node;
var muxEnabled = _node.MuxEnabled ?? _config.CoreBasicItem.MuxEnabled; var protocolExtra = node.GetProtocolExtra();
switch (_node.ConfigType) var muxEnabled = node.MuxEnabled ?? context.AppConfig.CoreBasicItem.MuxEnabled;
switch (node.ConfigType)
{ {
case EConfigType.VMess: case EConfigType.VMess:
{ {
@ -103,8 +106,8 @@ public partial class CoreConfigV2rayService
{ {
vnextItem = outbound.settings.vnext.First(); vnextItem = outbound.settings.vnext.First();
} }
vnextItem.address = _node.Address; vnextItem.address = node.Address;
vnextItem.port = _node.Port; vnextItem.port = node.Port;
UsersItem4Ray usersItem; UsersItem4Ray usersItem;
if (vnextItem.users.Count <= 0) if (vnextItem.users.Count <= 0)
@ -117,7 +120,7 @@ public partial class CoreConfigV2rayService
usersItem = vnextItem.users.First(); usersItem = vnextItem.users.First();
} }
usersItem.id = _node.Password; usersItem.id = node.Password;
usersItem.alterId = int.TryParse(protocolExtra?.AlterId, out var result) ? result : 0; usersItem.alterId = int.TryParse(protocolExtra?.AlterId, out var result) ? result : 0;
usersItem.email = Global.UserEMail; usersItem.email = Global.UserEMail;
if (Global.VmessSecurities.Contains(protocolExtra.VmessSecurity)) if (Global.VmessSecurities.Contains(protocolExtra.VmessSecurity))
@ -146,10 +149,10 @@ public partial class CoreConfigV2rayService
{ {
serversItem = outbound.settings.servers.First(); serversItem = outbound.settings.servers.First();
} }
serversItem.address = _node.Address; serversItem.address = node.Address;
serversItem.port = _node.Port; serversItem.port = node.Port;
serversItem.password = _node.Password; serversItem.password = node.Password;
serversItem.method = AppManager.Instance.GetShadowsocksSecurities(_node).Contains(protocolExtra.SsMethod) serversItem.method = AppManager.Instance.GetShadowsocksSecurities(node).Contains(protocolExtra.SsMethod)
? protocolExtra.SsMethod : "none"; ? protocolExtra.SsMethod : "none";
serversItem.ota = false; serversItem.ota = false;
@ -173,18 +176,18 @@ public partial class CoreConfigV2rayService
{ {
serversItem = outbound.settings.servers.First(); serversItem = outbound.settings.servers.First();
} }
serversItem.address = _node.Address; serversItem.address = node.Address;
serversItem.port = _node.Port; serversItem.port = node.Port;
serversItem.method = null; serversItem.method = null;
serversItem.password = null; serversItem.password = null;
if (_node.Username.IsNotEmpty() if (node.Username.IsNotEmpty()
&& _node.Password.IsNotEmpty()) && node.Password.IsNotEmpty())
{ {
SocksUsersItem4Ray socksUsersItem = new() SocksUsersItem4Ray socksUsersItem = new()
{ {
user = _node.Username ?? "", user = node.Username ?? "",
pass = _node.Password, pass = node.Password,
level = 1 level = 1
}; };
@ -208,8 +211,8 @@ public partial class CoreConfigV2rayService
{ {
vnextItem = outbound.settings.vnext.First(); vnextItem = outbound.settings.vnext.First();
} }
vnextItem.address = _node.Address; vnextItem.address = node.Address;
vnextItem.port = _node.Port; vnextItem.port = node.Port;
UsersItem4Ray usersItem; UsersItem4Ray usersItem;
if (vnextItem.users.Count <= 0) if (vnextItem.users.Count <= 0)
@ -221,7 +224,7 @@ public partial class CoreConfigV2rayService
{ {
usersItem = vnextItem.users.First(); usersItem = vnextItem.users.First();
} }
usersItem.id = _node.Password; usersItem.id = node.Password;
usersItem.email = Global.UserEMail; usersItem.email = Global.UserEMail;
usersItem.encryption = protocolExtra.VlessEncryption; usersItem.encryption = protocolExtra.VlessEncryption;
@ -248,9 +251,9 @@ public partial class CoreConfigV2rayService
{ {
serversItem = outbound.settings.servers.First(); serversItem = outbound.settings.servers.First();
} }
serversItem.address = _node.Address; serversItem.address = node.Address;
serversItem.port = _node.Port; serversItem.port = node.Port;
serversItem.password = _node.Password; serversItem.password = node.Password;
serversItem.ota = false; serversItem.ota = false;
serversItem.level = 1; serversItem.level = 1;
@ -265,8 +268,8 @@ public partial class CoreConfigV2rayService
outbound.settings = new() outbound.settings = new()
{ {
version = 2, version = 2,
address = _node.Address, address = node.Address,
port = _node.Port, port = node.Port,
}; };
outbound.settings.vnext = null; outbound.settings.vnext = null;
outbound.settings.servers = null; outbound.settings.servers = null;
@ -274,7 +277,7 @@ public partial class CoreConfigV2rayService
} }
case EConfigType.WireGuard: case EConfigType.WireGuard:
{ {
var address = _node.Address; var address = node.Address;
if (Utils.IsIpv6(address)) if (Utils.IsIpv6(address))
{ {
address = $"[{address}]"; address = $"[{address}]";
@ -282,12 +285,12 @@ public partial class CoreConfigV2rayService
var peer = new WireguardPeer4Ray var peer = new WireguardPeer4Ray
{ {
publicKey = protocolExtra.WgPublicKey ?? "", publicKey = protocolExtra.WgPublicKey ?? "",
endpoint = address + ":" + _node.Port.ToString() endpoint = address + ":" + node.Port.ToString()
}; };
var setting = new Outboundsettings4Ray var setting = new Outboundsettings4Ray
{ {
address = Utils.String2List(protocolExtra.WgInterfaceAddress), address = Utils.String2List(protocolExtra.WgInterfaceAddress),
secretKey = _node.Password, secretKey = node.Password,
reserved = Utils.String2List(protocolExtra.WgReserved)?.Select(int.Parse).ToList(), reserved = Utils.String2List(protocolExtra.WgReserved)?.Select(int.Parse).ToList(),
mtu = protocolExtra.WgMtu > 0 ? protocolExtra.WgMtu : Global.TunMtus.First(), mtu = protocolExtra.WgMtu > 0 ? protocolExtra.WgMtu : Global.TunMtus.First(),
peers = [peer] peers = [peer]
@ -299,8 +302,8 @@ public partial class CoreConfigV2rayService
} }
} }
outbound.protocol = Global.ProtocolTypes[_node.ConfigType]; outbound.protocol = Global.ProtocolTypes[node.ConfigType];
if (_node.ConfigType == EConfigType.Hysteria2) if (node.ConfigType == EConfigType.Hysteria2)
{ {
outbound.protocol = "hysteria"; outbound.protocol = "hysteria";
} }
@ -322,13 +325,13 @@ public partial class CoreConfigV2rayService
if (enabledTCP) if (enabledTCP)
{ {
outbound.mux.enabled = true; outbound.mux.enabled = true;
outbound.mux.concurrency = _config.Mux4RayItem.Concurrency; outbound.mux.concurrency = context.AppConfig.Mux4RayItem.Concurrency;
} }
else if (enabledUDP) else if (enabledUDP)
{ {
outbound.mux.enabled = true; outbound.mux.enabled = true;
outbound.mux.xudpConcurrency = _config.Mux4RayItem.XudpConcurrency; outbound.mux.xudpConcurrency = context.AppConfig.Mux4RayItem.XudpConcurrency;
outbound.mux.xudpProxyUDP443 = _config.Mux4RayItem.XudpProxyUDP443; outbound.mux.xudpProxyUDP443 = context.AppConfig.Mux4RayItem.XudpProxyUDP443;
} }
} }
catch (Exception ex) catch (Exception ex)
@ -341,41 +344,43 @@ public partial class CoreConfigV2rayService
{ {
try try
{ {
var node = context.Node;
var config = context.AppConfig;
var streamSettings = outbound.streamSettings; var streamSettings = outbound.streamSettings;
var network = _node.GetNetwork(); var network = node.GetNetwork();
if (_node.ConfigType == EConfigType.Hysteria2) if (node.ConfigType == EConfigType.Hysteria2)
{ {
network = "hysteria"; network = "hysteria";
} }
streamSettings.network = network; streamSettings.network = network;
var host = _node.RequestHost.TrimEx(); var host = node.RequestHost.TrimEx();
var path = _node.Path.TrimEx(); var path = node.Path.TrimEx();
var sni = _node.Sni.TrimEx(); var sni = node.Sni.TrimEx();
var useragent = ""; var useragent = "";
if (!_config.CoreBasicItem.DefUserAgent.IsNullOrEmpty()) if (!config.CoreBasicItem.DefUserAgent.IsNullOrEmpty())
{ {
try try
{ {
useragent = Global.UserAgentTexts[_config.CoreBasicItem.DefUserAgent]; useragent = Global.UserAgentTexts[config.CoreBasicItem.DefUserAgent];
} }
catch (KeyNotFoundException) catch (KeyNotFoundException)
{ {
useragent = _config.CoreBasicItem.DefUserAgent; useragent = config.CoreBasicItem.DefUserAgent;
} }
} }
//if tls //if tls
if (_node.StreamSecurity == Global.StreamSecurity) if (node.StreamSecurity == Global.StreamSecurity)
{ {
streamSettings.security = _node.StreamSecurity; streamSettings.security = node.StreamSecurity;
TlsSettings4Ray tlsSettings = new() TlsSettings4Ray tlsSettings = new()
{ {
allowInsecure = Utils.ToBool(_node.AllowInsecure.IsNullOrEmpty() ? _config.CoreBasicItem.DefAllowInsecure.ToString().ToLower() : _node.AllowInsecure), allowInsecure = Utils.ToBool(node.AllowInsecure.IsNullOrEmpty() ? config.CoreBasicItem.DefAllowInsecure.ToString().ToLower() : node.AllowInsecure),
alpn = _node.GetAlpn(), alpn = node.GetAlpn(),
fingerprint = _node.Fingerprint.IsNullOrEmpty() ? _config.CoreBasicItem.DefFingerprint : _node.Fingerprint, fingerprint = node.Fingerprint.IsNullOrEmpty() ? config.CoreBasicItem.DefFingerprint : node.Fingerprint,
echConfigList = _node.EchConfigList.NullIfEmpty(), echConfigList = node.EchConfigList.NullIfEmpty(),
echForceQuery = _node.EchForceQuery.NullIfEmpty() echForceQuery = node.EchForceQuery.NullIfEmpty()
}; };
if (sni.IsNotEmpty()) if (sni.IsNotEmpty())
{ {
@ -385,7 +390,7 @@ public partial class CoreConfigV2rayService
{ {
tlsSettings.serverName = Utils.String2List(host)?.First(); tlsSettings.serverName = Utils.String2List(host)?.First();
} }
var certs = CertPemManager.ParsePemChain(_node.Cert); var certs = CertPemManager.ParsePemChain(node.Cert);
if (certs.Count > 0) if (certs.Count > 0)
{ {
var certsettings = new List<CertificateSettings4Ray>(); var certsettings = new List<CertificateSettings4Ray>();
@ -402,27 +407,27 @@ public partial class CoreConfigV2rayService
tlsSettings.disableSystemRoot = true; tlsSettings.disableSystemRoot = true;
tlsSettings.allowInsecure = false; tlsSettings.allowInsecure = false;
} }
else if (!_node.CertSha.IsNullOrEmpty()) else if (!node.CertSha.IsNullOrEmpty())
{ {
tlsSettings.pinnedPeerCertSha256 = _node.CertSha; tlsSettings.pinnedPeerCertSha256 = node.CertSha;
tlsSettings.allowInsecure = false; tlsSettings.allowInsecure = false;
} }
streamSettings.tlsSettings = tlsSettings; streamSettings.tlsSettings = tlsSettings;
} }
//if Reality //if Reality
if (_node.StreamSecurity == Global.StreamSecurityReality) if (node.StreamSecurity == Global.StreamSecurityReality)
{ {
streamSettings.security = _node.StreamSecurity; streamSettings.security = node.StreamSecurity;
TlsSettings4Ray realitySettings = new() TlsSettings4Ray realitySettings = new()
{ {
fingerprint = _node.Fingerprint.IsNullOrEmpty() ? _config.CoreBasicItem.DefFingerprint : _node.Fingerprint, fingerprint = node.Fingerprint.IsNullOrEmpty() ? config.CoreBasicItem.DefFingerprint : node.Fingerprint,
serverName = sni, serverName = sni,
publicKey = _node.PublicKey, publicKey = node.PublicKey,
shortId = _node.ShortId, shortId = node.ShortId,
spiderX = _node.SpiderX, spiderX = node.SpiderX,
mldsa65Verify = _node.Mldsa65Verify, mldsa65Verify = node.Mldsa65Verify,
show = false, show = false,
}; };
@ -435,25 +440,25 @@ public partial class CoreConfigV2rayService
case nameof(ETransport.kcp): case nameof(ETransport.kcp):
KcpSettings4Ray kcpSettings = new() KcpSettings4Ray kcpSettings = new()
{ {
mtu = _config.KcpItem.Mtu, mtu = config.KcpItem.Mtu,
tti = _config.KcpItem.Tti tti = config.KcpItem.Tti
}; };
kcpSettings.uplinkCapacity = _config.KcpItem.UplinkCapacity; kcpSettings.uplinkCapacity = config.KcpItem.UplinkCapacity;
kcpSettings.downlinkCapacity = _config.KcpItem.DownlinkCapacity; kcpSettings.downlinkCapacity = config.KcpItem.DownlinkCapacity;
kcpSettings.congestion = _config.KcpItem.Congestion; kcpSettings.congestion = config.KcpItem.Congestion;
kcpSettings.readBufferSize = _config.KcpItem.ReadBufferSize; kcpSettings.readBufferSize = config.KcpItem.ReadBufferSize;
kcpSettings.writeBufferSize = _config.KcpItem.WriteBufferSize; kcpSettings.writeBufferSize = config.KcpItem.WriteBufferSize;
streamSettings.finalmask ??= new(); streamSettings.finalmask ??= new();
if (Global.KcpHeaderMaskMap.TryGetValue(_node.HeaderType, out var header)) if (Global.KcpHeaderMaskMap.TryGetValue(node.HeaderType, out var header))
{ {
streamSettings.finalmask.udp = streamSettings.finalmask.udp =
[ [
new Mask4Ray new Mask4Ray
{ {
type = header, type = header,
settings = _node.HeaderType == "dns" && !host.IsNullOrEmpty() ? new MaskSettings4Ray { domain = host } : null settings = node.HeaderType == "dns" && !host.IsNullOrEmpty() ? new MaskSettings4Ray { domain = host } : null
} }
]; ];
} }
@ -523,13 +528,13 @@ public partial class CoreConfigV2rayService
{ {
xhttpSettings.host = host; xhttpSettings.host = host;
} }
if (_node.HeaderType.IsNotEmpty() && Global.XhttpMode.Contains(_node.HeaderType)) if (node.HeaderType.IsNotEmpty() && Global.XhttpMode.Contains(node.HeaderType))
{ {
xhttpSettings.mode = _node.HeaderType; xhttpSettings.mode = node.HeaderType;
} }
if (_node.Extra.IsNotEmpty()) if (node.Extra.IsNotEmpty())
{ {
xhttpSettings.extra = JsonUtils.ParseJson(_node.Extra); xhttpSettings.extra = JsonUtils.ParseJson(node.Extra);
} }
streamSettings.xhttpSettings = xhttpSettings; streamSettings.xhttpSettings = xhttpSettings;
@ -557,11 +562,11 @@ public partial class CoreConfigV2rayService
key = path, key = path,
header = new Header4Ray header = new Header4Ray
{ {
type = _node.HeaderType type = node.HeaderType
} }
}; };
streamSettings.quicSettings = quicsettings; streamSettings.quicSettings = quicsettings;
if (_node.StreamSecurity == Global.StreamSecurity) if (node.StreamSecurity == Global.StreamSecurity)
{ {
if (sni.IsNotEmpty()) if (sni.IsNotEmpty())
{ {
@ -569,7 +574,7 @@ public partial class CoreConfigV2rayService
} }
else else
{ {
streamSettings.tlsSettings.serverName = _node.Address; streamSettings.tlsSettings.serverName = node.Address;
} }
} }
break; break;
@ -579,28 +584,28 @@ public partial class CoreConfigV2rayService
{ {
authority = host.NullIfEmpty(), authority = host.NullIfEmpty(),
serviceName = path, serviceName = path,
multiMode = _node.HeaderType == Global.GrpcMultiMode, multiMode = node.HeaderType == Global.GrpcMultiMode,
idle_timeout = _config.GrpcItem.IdleTimeout, idle_timeout = config.GrpcItem.IdleTimeout,
health_check_timeout = _config.GrpcItem.HealthCheckTimeout, health_check_timeout = config.GrpcItem.HealthCheckTimeout,
permit_without_stream = _config.GrpcItem.PermitWithoutStream, permit_without_stream = config.GrpcItem.PermitWithoutStream,
initial_windows_size = _config.GrpcItem.InitialWindowsSize, initial_windows_size = config.GrpcItem.InitialWindowsSize,
}; };
streamSettings.grpcSettings = grpcSettings; streamSettings.grpcSettings = grpcSettings;
break; break;
case "hysteria": case "hysteria":
var protocolExtra = _node.GetProtocolExtra(); var protocolExtra = node.GetProtocolExtra();
var ports = protocolExtra?.Ports; var ports = protocolExtra?.Ports;
int? upMbps = protocolExtra?.UpMbps is { } su and >= 0 int? upMbps = protocolExtra?.UpMbps is { } su and >= 0
? su ? su
: _config.HysteriaItem.UpMbps; : config.HysteriaItem.UpMbps;
int? downMbps = protocolExtra?.DownMbps is { } sd and >= 0 int? downMbps = protocolExtra?.DownMbps is { } sd and >= 0
? sd ? sd
: _config.HysteriaItem.UpMbps; : config.HysteriaItem.UpMbps;
var hopInterval = !protocolExtra.HopInterval.IsNullOrEmpty() var hopInterval = !protocolExtra.HopInterval.IsNullOrEmpty()
? protocolExtra.HopInterval ? protocolExtra.HopInterval
: (_config.HysteriaItem.HopInterval >= 5 : (config.HysteriaItem.HopInterval >= 5
? _config.HysteriaItem.HopInterval ? config.HysteriaItem.HopInterval
: Global.Hysteria2DefaultHopInt).ToString(); : Global.Hysteria2DefaultHopInt).ToString();
HysteriaUdpHop4Ray? udpHop = null; HysteriaUdpHop4Ray? udpHop = null;
if (!ports.IsNullOrEmpty() && if (!ports.IsNullOrEmpty() &&
@ -615,7 +620,7 @@ public partial class CoreConfigV2rayService
streamSettings.hysteriaSettings = new() streamSettings.hysteriaSettings = new()
{ {
version = 2, version = 2,
auth = _node.Password, auth = node.Password,
up = upMbps > 0 ? $"{upMbps}mbps" : null, up = upMbps > 0 ? $"{upMbps}mbps" : null,
down = downMbps > 0 ? $"{downMbps}mbps" : null, down = downMbps > 0 ? $"{downMbps}mbps" : null,
udphop = udpHop, udphop = udpHop,
@ -636,13 +641,13 @@ public partial class CoreConfigV2rayService
default: default:
//tcp //tcp
if (_node.HeaderType == Global.TcpHeaderHttp) if (node.HeaderType == Global.TcpHeaderHttp)
{ {
TcpSettings4Ray tcpSettings = new() TcpSettings4Ray tcpSettings = new()
{ {
header = new Header4Ray header = new Header4Ray
{ {
type = _node.HeaderType type = node.HeaderType
} }
}; };
@ -676,7 +681,7 @@ public partial class CoreConfigV2rayService
private List<Outbounds4Ray> BuildOutboundsList(string baseTagName = Global.ProxyTag) private List<Outbounds4Ray> BuildOutboundsList(string baseTagName = Global.ProxyTag)
{ {
var nodes = new List<ProfileItem>(); var nodes = new List<ProfileItem>();
foreach (var nodeId in Utils.String2List(_node.GetProtocolExtra().ChildItems) ?? []) foreach (var nodeId in Utils.String2List(context.Node.GetProtocolExtra().ChildItems) ?? [])
{ {
if (context.AllProxiesMap.TryGetValue(nodeId, out var node)) if (context.AllProxiesMap.TryGetValue(nodeId, out var node))
{ {
@ -705,7 +710,7 @@ public partial class CoreConfigV2rayService
private List<Outbounds4Ray> BuildChainOutboundsList(string baseTagName = Global.ProxyTag) private List<Outbounds4Ray> BuildChainOutboundsList(string baseTagName = Global.ProxyTag)
{ {
var nodes = new List<ProfileItem>(); var nodes = new List<ProfileItem>();
foreach (var nodeId in Utils.String2List(_node.GetProtocolExtra().ChildItems) ?? []) foreach (var nodeId in Utils.String2List(context.Node.GetProtocolExtra().ChildItems) ?? [])
{ {
if (context.AllProxiesMap.TryGetValue(nodeId, out var node)) if (context.AllProxiesMap.TryGetValue(nodeId, out var node))
{ {

View file

@ -8,7 +8,7 @@ public partial class CoreConfigV2rayService
{ {
if (_coreConfig.routing?.rules != null) if (_coreConfig.routing?.rules != null)
{ {
_coreConfig.routing.domainStrategy = _config.RoutingBasicItem.DomainStrategy; _coreConfig.routing.domainStrategy = context.AppConfig.RoutingBasicItem.DomainStrategy;
var routing = context.RoutingItem; var routing = context.RoutingItem;
if (routing != null) if (routing != null)

View file

@ -4,7 +4,7 @@ public partial class CoreConfigV2rayService
{ {
private void GenStatistic() private void GenStatistic()
{ {
if (_config.GuiItem.EnableStatistics || _config.GuiItem.DisplayRealTimeSpeed) if (context.AppConfig.GuiItem.EnableStatistics || context.AppConfig.GuiItem.DisplayRealTimeSpeed)
{ {
var tag = EInboundProtocol.api.ToString(); var tag = EInboundProtocol.api.ToString();
Metrics4Ray apiObj = new(); Metrics4Ray apiObj = new();