mirror of
https://github.com/2dust/v2rayN.git
synced 2026-02-28 21:23:04 +00:00
Fix
This commit is contained in:
parent
84a1eb8445
commit
a03e38fb16
19 changed files with 298 additions and 412 deletions
|
|
@ -15,7 +15,6 @@ 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.";
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ 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)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -96,8 +95,7 @@ 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)
|
||||||
{
|
{
|
||||||
|
|
@ -172,7 +170,8 @@ public static class CoreConfigHandler
|
||||||
var ruleOutboundNode = await AppManager.Instance.GetProfileItemViaRemarks(ruleItem.OutboundTag);
|
var ruleOutboundNode = await AppManager.Instance.GetProfileItemViaRemarks(ruleItem.OutboundTag);
|
||||||
if (ruleOutboundNode != null)
|
if (ruleOutboundNode != null)
|
||||||
{
|
{
|
||||||
await FillNodeContext(context, ruleOutboundNode);
|
var ruleOutboundNodeAct = await FillNodeContext(context, ruleOutboundNode, false);
|
||||||
|
context.AllProxiesMap[$"remark:{ruleItem.OutboundTag}"] = ruleOutboundNodeAct;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -185,18 +184,21 @@ 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.GetChildProfileItems(node);
|
||||||
foreach (var childItem in groupChildList)
|
foreach (var childItem in groupChildList.Where(childItem => !context.AllProxiesMap.ContainsKey(childItem.IndexId)))
|
||||||
{
|
{
|
||||||
context.AllProxiesMap[childItem.IndexId] = childItem;
|
await FillNodeContext(context, childItem, false);
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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(List<string> indexIds)
|
public async Task<List<ProfileItem>> GetProfileItemsByIndexIds(IEnumerable<string> indexIds)
|
||||||
{
|
{
|
||||||
var ids = indexIds.Where(id => id.IsNotEmpty()).Distinct().ToList();
|
var ids = indexIds.Where(id => !id.IsNullOrEmpty()).Distinct().ToList();
|
||||||
if (ids.Count == 0)
|
if (ids.Count == 0)
|
||||||
{
|
{
|
||||||
return [];
|
return [];
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ public class GroupProfileManager
|
||||||
{
|
{
|
||||||
if (protocolExtra == null)
|
if (protocolExtra == null)
|
||||||
{
|
{
|
||||||
return new();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
var items = new List<ProfileItem>();
|
var items = new List<ProfileItem>();
|
||||||
|
|
@ -93,27 +93,44 @@ public class GroupProfileManager
|
||||||
{
|
{
|
||||||
if (extra == null || extra.ChildItems.IsNullOrEmpty())
|
if (extra == null || extra.ChildItems.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
return new();
|
return [];
|
||||||
}
|
}
|
||||||
var childProfiles = (await Task.WhenAll(
|
var childProfileIds = Utils.String2List(extra.ChildItems)
|
||||||
(Utils.String2List(extra.ChildItems) ?? new())
|
?.Where(p => !string.IsNullOrEmpty(p))
|
||||||
.Where(p => !p.IsNullOrEmpty())
|
.ToList() ?? [];
|
||||||
.Select(AppManager.Instance.GetProfileItem)
|
if (childProfileIds.Count == 0)
|
||||||
))
|
{
|
||||||
.Where(p =>
|
return [];
|
||||||
p != null &&
|
}
|
||||||
p.IsValid() &&
|
|
||||||
p.ConfigType != EConfigType.Custom
|
var childProfiles = await AppManager.Instance.GetProfileItemsByIndexIds(childProfileIds);
|
||||||
)
|
if (childProfiles == null || childProfiles.Count == 0)
|
||||||
.ToList();
|
{
|
||||||
return childProfiles ?? new();
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
var profileMap = childProfiles
|
||||||
|
.Where(p => p != null && !p.IndexId.IsNullOrEmpty())
|
||||||
|
.GroupBy(p => p!.IndexId!)
|
||||||
|
.ToDictionary(g => g.Key, g => g.First());
|
||||||
|
|
||||||
|
var ordered = new List<ProfileItem>(childProfileIds.Count);
|
||||||
|
foreach (var id in childProfileIds)
|
||||||
|
{
|
||||||
|
if (id != null && profileMap.TryGetValue(id, out var item) && item != null)
|
||||||
|
{
|
||||||
|
ordered.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ordered;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 new();
|
return [];
|
||||||
}
|
}
|
||||||
var childProfiles = await AppManager.Instance.ProfileItems(extra.SubChildItems ?? string.Empty);
|
var childProfiles = await AppManager.Instance.ProfileItems(extra.SubChildItems ?? string.Empty);
|
||||||
|
|
||||||
|
|
@ -123,7 +140,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() ?? new();
|
.ToList() ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<List<ProfileItem>> GetAllChildProfileItems(ProfileItem profileItem)
|
public static async Task<List<ProfileItem>> GetAllChildProfileItems(ProfileItem profileItem)
|
||||||
|
|
@ -149,38 +166,4 @@ 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ 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();
|
||||||
|
|
||||||
|
|
@ -13,16 +15,15 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
|
||||||
var ret = new RetResult();
|
var ret = new RetResult();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var node = context.Node;
|
if (_node == null
|
||||||
if (node == null
|
|| !_node.IsValid())
|
||||||
|| !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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -193,16 +194,15 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
|
||||||
var ret = new RetResult();
|
var ret = new RetResult();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var node = context.Node;
|
if (_node == null
|
||||||
if (node == null
|
|| !_node.IsValid())
|
||||||
|| !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,87 +249,5 @@ 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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -348,6 +348,10 @@ public partial class CoreConfigSingboxService
|
||||||
private void GenMinimizedDns()
|
private void GenMinimizedDns()
|
||||||
{
|
{
|
||||||
GenDnsServers();
|
GenDnsServers();
|
||||||
|
foreach (var server in _coreConfig.dns!.servers.Where(s => !string.IsNullOrEmpty(s.detour)).ToList())
|
||||||
|
{
|
||||||
|
_coreConfig.dns.servers.Remove(server);
|
||||||
|
}
|
||||||
_coreConfig.dns ??= new();
|
_coreConfig.dns ??= new();
|
||||||
_coreConfig.dns.rules ??= [];
|
_coreConfig.dns.rules ??= [];
|
||||||
_coreConfig.dns.rules.Clear();
|
_coreConfig.dns.rules.Clear();
|
||||||
|
|
|
||||||
|
|
@ -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 (!context.AppConfig.TunModeItem.EnableTun
|
if (!_config.TunModeItem.EnableTun
|
||||||
|| (context.AppConfig.TunModeItem.EnableTun && context.AppConfig.TunModeItem.EnableExInbound && AppManager.Instance.RunningCoreType == ECoreType.sing_box))
|
|| (_config.TunModeItem.EnableTun && _config.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 (context.AppConfig.Inbound.First().SecondLocalPortEnabled)
|
if (_config.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 (context.AppConfig.Inbound.First().AllowLANConn)
|
if (_config.Inbound.First().AllowLANConn)
|
||||||
{
|
{
|
||||||
if (context.AppConfig.Inbound.First().NewPort4LAN)
|
if (_config.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 (context.AppConfig.Inbound.First().User.IsNotEmpty() && context.AppConfig.Inbound.First().Pass.IsNotEmpty())
|
if (_config.Inbound.First().User.IsNotEmpty() && _config.Inbound.First().Pass.IsNotEmpty())
|
||||||
{
|
{
|
||||||
inbound3.users = new() { new() { username = context.AppConfig.Inbound.First().User, password = context.AppConfig.Inbound.First().Pass } };
|
inbound3.users = new() { new() { username = _config.Inbound.First().User, password = _config.Inbound.First().Pass } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -49,24 +49,24 @@ public partial class CoreConfigSingboxService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.AppConfig.TunModeItem.EnableTun)
|
if (_config.TunModeItem.EnableTun)
|
||||||
{
|
{
|
||||||
if (context.AppConfig.TunModeItem.Mtu <= 0)
|
if (_config.TunModeItem.Mtu <= 0)
|
||||||
{
|
{
|
||||||
context.AppConfig.TunModeItem.Mtu = Global.TunMtus.First();
|
_config.TunModeItem.Mtu = Global.TunMtus.First();
|
||||||
}
|
}
|
||||||
if (context.AppConfig.TunModeItem.Stack.IsNullOrEmpty())
|
if (_config.TunModeItem.Stack.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
context.AppConfig.TunModeItem.Stack = Global.TunStacks.First();
|
_config.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 = context.AppConfig.TunModeItem.Mtu;
|
tunInbound.mtu = _config.TunModeItem.Mtu;
|
||||||
tunInbound.auto_route = context.AppConfig.TunModeItem.AutoRoute;
|
tunInbound.auto_route = _config.TunModeItem.AutoRoute;
|
||||||
tunInbound.strict_route = context.AppConfig.TunModeItem.StrictRoute;
|
tunInbound.strict_route = _config.TunModeItem.StrictRoute;
|
||||||
tunInbound.stack = context.AppConfig.TunModeItem.Stack;
|
tunInbound.stack = _config.TunModeItem.Stack;
|
||||||
if (context.AppConfig.TunModeItem.EnableIPv6Address == false)
|
if (_config.TunModeItem.EnableIPv6Address == false)
|
||||||
{
|
{
|
||||||
tunInbound.address = ["172.18.0.1/30"];
|
tunInbound.address = ["172.18.0.1/30"];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,12 @@ public partial class CoreConfigSingboxService
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
switch (context.AppConfig.CoreBasicItem.Loglevel)
|
switch (_config.CoreBasicItem.Loglevel)
|
||||||
{
|
{
|
||||||
case "debug":
|
case "debug":
|
||||||
case "info":
|
case "info":
|
||||||
case "error":
|
case "error":
|
||||||
_coreConfig.log.level = context.AppConfig.CoreBasicItem.Loglevel;
|
_coreConfig.log.level = _config.CoreBasicItem.Loglevel;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "warning":
|
case "warning":
|
||||||
|
|
@ -21,11 +21,11 @@ public partial class CoreConfigSingboxService
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (context.AppConfig.CoreBasicItem.Loglevel == Global.None)
|
if (_config.CoreBasicItem.Loglevel == Global.None)
|
||||||
{
|
{
|
||||||
_coreConfig.log.disabled = true;
|
_coreConfig.log.disabled = true;
|
||||||
}
|
}
|
||||||
if (context.AppConfig.CoreBasicItem.LogEnabled)
|
if (_config.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");
|
||||||
|
|
|
||||||
|
|
@ -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 (!context.Node.ConfigType.IsComplexType())
|
if (!_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 (context.Node.ConfigType)
|
switch (_node.ConfigType)
|
||||||
{
|
{
|
||||||
case EConfigType.PolicyGroup:
|
case EConfigType.PolicyGroup:
|
||||||
proxyOutboundList = BuildOutboundsList(baseTagName);
|
proxyOutboundList = BuildOutboundsList(baseTagName);
|
||||||
|
|
@ -54,9 +54,8 @@ 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);
|
||||||
|
|
@ -80,17 +79,16 @@ public partial class CoreConfigSingboxService
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var node = context.Node;
|
var protocolExtra = _node.GetProtocolExtra();
|
||||||
var protocolExtra = node.GetProtocolExtra();
|
outbound.server = _node.Address;
|
||||||
outbound.server = node.Address;
|
outbound.server_port = _node.Port;
|
||||||
outbound.server_port = node.Port;
|
outbound.type = Global.ProtocolTypes[_node.ConfigType];
|
||||||
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))
|
||||||
{
|
{
|
||||||
|
|
@ -107,35 +105,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();
|
||||||
|
|
@ -165,27 +163,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";
|
||||||
|
|
||||||
|
|
@ -203,7 +201,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);
|
||||||
|
|
@ -211,7 +209,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())
|
||||||
{
|
{
|
||||||
|
|
@ -224,10 +222,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
|
||||||
: context.AppConfig.HysteriaItem.UpMbps;
|
: _config.HysteriaItem.UpMbps;
|
||||||
outbound.down_mbps = protocolExtra?.DownMbps is { } sd and >= 0
|
outbound.down_mbps = protocolExtra?.DownMbps is { } sd and >= 0
|
||||||
? sd
|
? sd
|
||||||
: context.AppConfig.HysteriaItem.DownMbps;
|
: _config.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(',')))
|
||||||
{
|
{
|
||||||
|
|
@ -241,8 +239,8 @@ public partial class CoreConfigSingboxService
|
||||||
return port.Contains(':') ? port : $"{port}:{port}";
|
return port.Contains(':') ? port : $"{port}:{port}";
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
outbound.hop_interval = context.AppConfig.HysteriaItem.HopInterval >= 5
|
outbound.hop_interval = _config.HysteriaItem.HopInterval >= 5
|
||||||
? $"{context.AppConfig.HysteriaItem.HopInterval}s"
|
? $"{_config.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))
|
||||||
{
|
{
|
||||||
|
|
@ -265,14 +263,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -289,13 +287,12 @@ public partial class CoreConfigSingboxService
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var node = context.Node;
|
var protocolExtra = _node.GetProtocolExtra();
|
||||||
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:
|
||||||
{
|
{
|
||||||
|
|
@ -304,12 +301,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;
|
||||||
|
|
@ -326,16 +323,15 @@ public partial class CoreConfigSingboxService
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var config = context.AppConfig;
|
var muxEnabled = _node.MuxEnabled ?? _config.CoreBasicItem.MuxEnabled;
|
||||||
var muxEnabled = context.Node.MuxEnabled ?? config.CoreBasicItem.MuxEnabled;
|
if (muxEnabled && _config.Mux4SboxItem.Protocol.IsNotEmpty())
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
@ -350,60 +346,59 @@ public partial class CoreConfigSingboxService
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var node = context.Node;
|
if (_node.StreamSecurity is not (Global.StreamSecurityReality or Global.StreamSecurity))
|
||||||
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 = context.AppConfig.CoreBasicItem.EnableFragment ? true : null,
|
record_fragment = _config.CoreBasicItem.EnableFragment ? true : null,
|
||||||
server_name = serverName,
|
server_name = serverName,
|
||||||
insecure = Utils.ToBool(node.AllowInsecure.IsNullOrEmpty() ? context.AppConfig.CoreBasicItem.DefAllowInsecure.ToString().ToLower() : node.AllowInsecure),
|
insecure = Utils.ToBool(_node.AllowInsecure.IsNullOrEmpty() ? _config.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() ? context.AppConfig.CoreBasicItem.DefFingerprint : node.Fingerprint
|
fingerprint = _node.Fingerprint.IsNullOrEmpty() ? _config.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;
|
||||||
|
|
@ -420,29 +415,28 @@ 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())
|
||||||
|
|
@ -471,19 +465,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;
|
||||||
|
|
||||||
|
|
@ -493,10 +487,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 = context.AppConfig.GrpcItem.IdleTimeout?.ToString("##s");
|
transport.idle_timeout = _config.GrpcItem.IdleTimeout?.ToString("##s");
|
||||||
transport.ping_timeout = context.AppConfig.GrpcItem.HealthCheckTimeout?.ToString("##s");
|
transport.ping_timeout = _config.GrpcItem.HealthCheckTimeout?.ToString("##s");
|
||||||
transport.permit_without_stream = context.AppConfig.GrpcItem.PermitWithoutStream;
|
transport.permit_without_stream = _config.GrpcItem.PermitWithoutStream;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -515,7 +509,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 = context.Node.GetProtocolExtra().MultipleLoad ?? EMultipleLoad.LeastPing;
|
var multipleLoad = _node.GetProtocolExtra().MultipleLoad ?? EMultipleLoad.LeastPing;
|
||||||
var outUrltest = new Outbound4Sbox
|
var outUrltest = new Outbound4Sbox
|
||||||
{
|
{
|
||||||
type = "urltest",
|
type = "urltest",
|
||||||
|
|
@ -545,7 +539,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(context.Node.GetProtocolExtra().ChildItems) ?? [])
|
foreach (var nodeId in Utils.String2List(_node.GetProtocolExtra().ChildItems) ?? [])
|
||||||
{
|
{
|
||||||
if (context.AllProxiesMap.TryGetValue(nodeId, out var node))
|
if (context.AllProxiesMap.TryGetValue(nodeId, out var node))
|
||||||
{
|
{
|
||||||
|
|
@ -574,7 +568,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(context.Node.GetProtocolExtra().ChildItems) ?? [])
|
foreach (var nodeId in Utils.String2List(_node.GetProtocolExtra().ChildItems) ?? [])
|
||||||
{
|
{
|
||||||
if (context.AllProxiesMap.TryGetValue(nodeId, out var node))
|
if (context.AllProxiesMap.TryGetValue(nodeId, out var node))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ public partial class CoreConfigSingboxService
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_coreConfig.route.final = Global.ProxyTag;
|
_coreConfig.route.final = Global.ProxyTag;
|
||||||
var simpleDnsItem = context.AppConfig.SimpleDNSItem;
|
var simpleDnsItem = context.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 (context.AppConfig.TunModeItem.EnableTun)
|
if (_config.TunModeItem.EnableTun)
|
||||||
{
|
{
|
||||||
_coreConfig.route.auto_detect_interface = true;
|
_coreConfig.route.auto_detect_interface = true;
|
||||||
|
|
||||||
|
|
@ -49,7 +49,7 @@ public partial class CoreConfigSingboxService
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.AppConfig.Inbound.First().SniffingEnabled)
|
if (_config.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 = context.AppConfig.RoutingBasicItem.DomainStrategy4Singbox.NullIfEmpty();
|
var domainStrategy = _config.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 (context.AppConfig.RoutingBasicItem.DomainStrategy == Global.IPOnDemand)
|
if (_config.RoutingBasicItem.DomainStrategy == Global.IPOnDemand)
|
||||||
{
|
{
|
||||||
_coreConfig.route.rules.Add(resolveRule);
|
_coreConfig.route.rules.Add(resolveRule);
|
||||||
}
|
}
|
||||||
|
|
@ -142,7 +142,7 @@ public partial class CoreConfigSingboxService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (context.AppConfig.RoutingBasicItem.DomainStrategy == Global.IPIfNonMatch)
|
if (_config.RoutingBasicItem.DomainStrategy == Global.IPIfNonMatch)
|
||||||
{
|
{
|
||||||
_coreConfig.route.rules.Add(resolveRule);
|
_coreConfig.route.rules.Add(resolveRule);
|
||||||
foreach (var item2 in ipRules)
|
foreach (var item2 in ipRules)
|
||||||
|
|
@ -413,8 +413,8 @@ public partial class CoreConfigSingboxService
|
||||||
}
|
}
|
||||||
|
|
||||||
var tag = $"{node.IndexId}-{Global.ProxyTag}";
|
var tag = $"{node.IndexId}-{Global.ProxyTag}";
|
||||||
if (_coreConfig.outbounds.Any(o => o.tag == tag)
|
if (_coreConfig.outbounds.Any(o => o.tag.StartsWith(tag))
|
||||||
|| (_coreConfig.endpoints != null && _coreConfig.endpoints.Any(e => e.tag == tag)))
|
|| (_coreConfig.endpoints != null && _coreConfig.endpoints.Any(e => e.tag.StartsWith(tag))))
|
||||||
{
|
{
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,9 +99,9 @@ public partial class CoreConfigSingboxService
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var srsUrl = string.IsNullOrEmpty(context.AppConfig.ConstItem.SrsSourceUrl)
|
var srsUrl = string.IsNullOrEmpty(_config.ConstItem.SrsSourceUrl)
|
||||||
? Global.SingboxRulesetUrl
|
? Global.SingboxRulesetUrl
|
||||||
: context.AppConfig.ConstItem.SrsSourceUrl;
|
: _config.ConstItem.SrsSourceUrl;
|
||||||
|
|
||||||
customRuleset = new()
|
customRuleset = new()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,14 @@ public partial class CoreConfigSingboxService
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.AppConfig.CoreBasicItem.EnableCacheFile4Sbox)
|
if (_config.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.AppConfig.SimpleDNSItem.FakeIP == true
|
store_fakeip = context.SimpleDnsItem.FakeIP == true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ 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();
|
||||||
|
|
||||||
|
|
@ -13,17 +15,16 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
|
||||||
var ret = new RetResult();
|
var ret = new RetResult();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var node = context?.Node;
|
if (_node == null
|
||||||
if (node == null
|
|| !_node.IsValid())
|
||||||
|| !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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,7 +171,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 = context.Node.GetProtocolExtra().MultipleLoad ?? EMultipleLoad.LeastPing;
|
var multipleLoad = _node.GetProtocolExtra().MultipleLoad ?? EMultipleLoad.LeastPing;
|
||||||
GenObservatory(multipleLoad, tag);
|
GenObservatory(multipleLoad, tag);
|
||||||
GenBalancer(multipleLoad, tag);
|
GenBalancer(multipleLoad, tag);
|
||||||
}
|
}
|
||||||
|
|
@ -208,17 +209,16 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
|
||||||
var ret = new RetResult();
|
var ret = new RetResult();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var node = context.Node;
|
if (_node == null
|
||||||
if (node == null
|
|| !_node.IsValid())
|
||||||
|| !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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,6 @@ 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)
|
||||||
{
|
{
|
||||||
|
|
@ -246,11 +245,6 @@ 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);
|
||||||
|
|
@ -407,7 +401,6 @@ 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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,32 +6,31 @@ 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
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,16 @@ public partial class CoreConfigV2rayService
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var config = context.AppConfig;
|
if (_config.CoreBasicItem.LogEnabled)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 = context.Node.GetProtocolExtra().MultipleLoad ?? EMultipleLoad.LeastPing;
|
var multipleLoad = _node.GetProtocolExtra().MultipleLoad ?? EMultipleLoad.LeastPing;
|
||||||
GenObservatory(multipleLoad);
|
GenObservatory(multipleLoad);
|
||||||
GenBalancer(multipleLoad);
|
GenBalancer(multipleLoad);
|
||||||
}
|
}
|
||||||
|
|
@ -17,8 +17,7 @@ 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>();
|
||||||
var node = context.Node;
|
if (_node.ConfigType.IsGroupType())
|
||||||
if (node.ConfigType.IsGroupType())
|
|
||||||
{
|
{
|
||||||
proxyOutboundList.AddRange(BuildGroupProxyOutbounds(baseTagName));
|
proxyOutboundList.AddRange(BuildGroupProxyOutbounds(baseTagName));
|
||||||
}
|
}
|
||||||
|
|
@ -27,7 +26,7 @@ public partial class CoreConfigV2rayService
|
||||||
proxyOutboundList.Add(BuildProxyOutbound(baseTagName));
|
proxyOutboundList.Add(BuildProxyOutbound(baseTagName));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.AppConfig.CoreBasicItem.EnableFragment)
|
if (_config.CoreBasicItem.EnableFragment)
|
||||||
{
|
{
|
||||||
var fragmentOutbound = new Outbounds4Ray
|
var fragmentOutbound = new Outbounds4Ray
|
||||||
{
|
{
|
||||||
|
|
@ -37,9 +36,9 @@ public partial class CoreConfigV2rayService
|
||||||
{
|
{
|
||||||
fragment = new()
|
fragment = new()
|
||||||
{
|
{
|
||||||
packets = context.AppConfig.Fragment4RayItem?.Packets,
|
packets = _config.Fragment4RayItem?.Packets,
|
||||||
length = context.AppConfig.Fragment4RayItem?.Length,
|
length = _config.Fragment4RayItem?.Length,
|
||||||
interval = context.AppConfig.Fragment4RayItem?.Interval
|
interval = _config.Fragment4RayItem?.Interval
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -63,8 +62,7 @@ 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>();
|
||||||
var node = context.Node;
|
switch (_node.ConfigType)
|
||||||
switch (node.ConfigType)
|
|
||||||
{
|
{
|
||||||
case EConfigType.PolicyGroup:
|
case EConfigType.PolicyGroup:
|
||||||
proxyOutboundList.AddRange(BuildOutboundsList(baseTagName));
|
proxyOutboundList.AddRange(BuildOutboundsList(baseTagName));
|
||||||
|
|
@ -89,10 +87,9 @@ public partial class CoreConfigV2rayService
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var node = context.Node;
|
var protocolExtra = _node.GetProtocolExtra();
|
||||||
var protocolExtra = node.GetProtocolExtra();
|
var muxEnabled = _node.MuxEnabled ?? _config.CoreBasicItem.MuxEnabled;
|
||||||
var muxEnabled = node.MuxEnabled ?? context.AppConfig.CoreBasicItem.MuxEnabled;
|
switch (_node.ConfigType)
|
||||||
switch (node.ConfigType)
|
|
||||||
{
|
{
|
||||||
case EConfigType.VMess:
|
case EConfigType.VMess:
|
||||||
{
|
{
|
||||||
|
|
@ -106,8 +103,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)
|
||||||
|
|
@ -120,7 +117,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))
|
||||||
|
|
@ -149,10 +146,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;
|
||||||
|
|
@ -176,18 +173,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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -211,8 +208,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)
|
||||||
|
|
@ -224,7 +221,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;
|
||||||
|
|
||||||
|
|
@ -251,9 +248,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;
|
||||||
|
|
@ -268,8 +265,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;
|
||||||
|
|
@ -277,7 +274,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}]";
|
||||||
|
|
@ -285,12 +282,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]
|
||||||
|
|
@ -302,8 +299,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";
|
||||||
}
|
}
|
||||||
|
|
@ -325,13 +322,13 @@ public partial class CoreConfigV2rayService
|
||||||
if (enabledTCP)
|
if (enabledTCP)
|
||||||
{
|
{
|
||||||
outbound.mux.enabled = true;
|
outbound.mux.enabled = true;
|
||||||
outbound.mux.concurrency = context.AppConfig.Mux4RayItem.Concurrency;
|
outbound.mux.concurrency = _config.Mux4RayItem.Concurrency;
|
||||||
}
|
}
|
||||||
else if (enabledUDP)
|
else if (enabledUDP)
|
||||||
{
|
{
|
||||||
outbound.mux.enabled = true;
|
outbound.mux.enabled = true;
|
||||||
outbound.mux.xudpConcurrency = context.AppConfig.Mux4RayItem.XudpConcurrency;
|
outbound.mux.xudpConcurrency = _config.Mux4RayItem.XudpConcurrency;
|
||||||
outbound.mux.xudpProxyUDP443 = context.AppConfig.Mux4RayItem.XudpProxyUDP443;
|
outbound.mux.xudpProxyUDP443 = _config.Mux4RayItem.XudpProxyUDP443;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -344,43 +341,41 @@ 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())
|
||||||
{
|
{
|
||||||
|
|
@ -390,7 +385,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>();
|
||||||
|
|
@ -407,27 +402,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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -440,25 +435,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
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
@ -528,13 +523,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;
|
||||||
|
|
@ -562,11 +557,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())
|
||||||
{
|
{
|
||||||
|
|
@ -574,7 +569,7 @@ public partial class CoreConfigV2rayService
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
streamSettings.tlsSettings.serverName = node.Address;
|
streamSettings.tlsSettings.serverName = _node.Address;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -584,28 +579,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() &&
|
||||||
|
|
@ -620,7 +615,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,
|
||||||
|
|
@ -641,13 +636,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
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -681,7 +676,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(context.Node.GetProtocolExtra().ChildItems) ?? [])
|
foreach (var nodeId in Utils.String2List(_node.GetProtocolExtra().ChildItems) ?? [])
|
||||||
{
|
{
|
||||||
if (context.AllProxiesMap.TryGetValue(nodeId, out var node))
|
if (context.AllProxiesMap.TryGetValue(nodeId, out var node))
|
||||||
{
|
{
|
||||||
|
|
@ -710,7 +705,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(context.Node.GetProtocolExtra().ChildItems) ?? [])
|
foreach (var nodeId in Utils.String2List(_node.GetProtocolExtra().ChildItems) ?? [])
|
||||||
{
|
{
|
||||||
if (context.AllProxiesMap.TryGetValue(nodeId, out var node))
|
if (context.AllProxiesMap.TryGetValue(nodeId, out var node))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ public partial class CoreConfigV2rayService
|
||||||
{
|
{
|
||||||
if (_coreConfig.routing?.rules != null)
|
if (_coreConfig.routing?.rules != null)
|
||||||
{
|
{
|
||||||
_coreConfig.routing.domainStrategy = context.AppConfig.RoutingBasicItem.DomainStrategy;
|
_coreConfig.routing.domainStrategy = _config.RoutingBasicItem.DomainStrategy;
|
||||||
|
|
||||||
var routing = context.RoutingItem;
|
var routing = context.RoutingItem;
|
||||||
if (routing != null)
|
if (routing != null)
|
||||||
|
|
@ -165,7 +165,7 @@ public partial class CoreConfigV2rayService
|
||||||
}
|
}
|
||||||
|
|
||||||
var tag = $"{node.IndexId}-{Global.ProxyTag}";
|
var tag = $"{node.IndexId}-{Global.ProxyTag}";
|
||||||
if (_coreConfig.outbounds.Any(p => p.tag == tag))
|
if (_coreConfig.outbounds.Any(p => p.tag.StartsWith(tag)))
|
||||||
{
|
{
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ public partial class CoreConfigV2rayService
|
||||||
{
|
{
|
||||||
private void GenStatistic()
|
private void GenStatistic()
|
||||||
{
|
{
|
||||||
if (context.AppConfig.GuiItem.EnableStatistics || context.AppConfig.GuiItem.DisplayRealTimeSpeed)
|
if (_config.GuiItem.EnableStatistics || _config.GuiItem.DisplayRealTimeSpeed)
|
||||||
{
|
{
|
||||||
var tag = EInboundProtocol.api.ToString();
|
var tag = EInboundProtocol.api.ToString();
|
||||||
Metrics4Ray apiObj = new();
|
Metrics4Ray apiObj = new();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue