mirror of https://github.com/2dust/v2rayN
support Wireguard endpoint
Refactors Singbox config classes for dial fields
parent
1e3705b73f
commit
85b7a728ed
|
@ -8,6 +8,7 @@ public class SingboxConfig
|
||||||
public Dns4Sbox? dns { get; set; }
|
public Dns4Sbox? dns { get; set; }
|
||||||
public List<Inbound4Sbox> inbounds { get; set; }
|
public List<Inbound4Sbox> inbounds { get; set; }
|
||||||
public List<Outbound4Sbox> outbounds { get; set; }
|
public List<Outbound4Sbox> outbounds { get; set; }
|
||||||
|
public List<Endpoints4Sbox>? endpoints { get; set; }
|
||||||
public Route4Sbox route { get; set; }
|
public Route4Sbox route { get; set; }
|
||||||
public Experimental4Sbox? experimental { get; set; }
|
public Experimental4Sbox? experimental { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -96,10 +97,8 @@ public class User4Sbox
|
||||||
public string password { get; set; }
|
public string password { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Outbound4Sbox
|
public class Outbound4Sbox : BaseServer4Sbox
|
||||||
{
|
{
|
||||||
public string type { get; set; }
|
|
||||||
public string tag { get; set; }
|
|
||||||
public string? server { get; set; }
|
public string? server { get; set; }
|
||||||
public int? server_port { get; set; }
|
public int? server_port { get; set; }
|
||||||
public List<string>? server_ports { get; set; }
|
public List<string>? server_ports { get; set; }
|
||||||
|
@ -114,7 +113,6 @@ public class Outbound4Sbox
|
||||||
public int? recv_window_conn { get; set; }
|
public int? recv_window_conn { get; set; }
|
||||||
public int? recv_window { get; set; }
|
public int? recv_window { get; set; }
|
||||||
public bool? disable_mtu_discovery { get; set; }
|
public bool? disable_mtu_discovery { get; set; }
|
||||||
public string? detour { get; set; }
|
|
||||||
public string? method { get; set; }
|
public string? method { get; set; }
|
||||||
public string? username { get; set; }
|
public string? username { get; set; }
|
||||||
public string? password { get; set; }
|
public string? password { get; set; }
|
||||||
|
@ -122,26 +120,14 @@ public class Outbound4Sbox
|
||||||
public string? version { get; set; }
|
public string? version { get; set; }
|
||||||
public string? network { get; set; }
|
public string? network { get; set; }
|
||||||
public string? packet_encoding { get; set; }
|
public string? packet_encoding { get; set; }
|
||||||
public List<string>? local_address { get; set; }
|
|
||||||
public string? private_key { get; set; }
|
|
||||||
public string? peer_public_key { get; set; }
|
|
||||||
public List<int>? reserved { get; set; }
|
|
||||||
public int? mtu { get; set; }
|
|
||||||
public string? plugin { get; set; }
|
public string? plugin { get; set; }
|
||||||
public string? plugin_opts { get; set; }
|
public string? plugin_opts { get; set; }
|
||||||
public Tls4Sbox? tls { get; set; }
|
|
||||||
public Multiplex4Sbox? multiplex { get; set; }
|
|
||||||
public Transport4Sbox? transport { get; set; }
|
|
||||||
public HyObfs4Sbox? obfs { get; set; }
|
|
||||||
public List<string>? outbounds { get; set; }
|
public List<string>? outbounds { get; set; }
|
||||||
public bool? interrupt_exist_connections { get; set; }
|
public bool? interrupt_exist_connections { get; set; }
|
||||||
public Rule4Sbox? domain_resolver { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Endpoints4Sbox
|
public class Endpoints4Sbox : BaseServer4Sbox
|
||||||
{
|
{
|
||||||
public string type { get; set; }
|
|
||||||
public string tag { get; set; }
|
|
||||||
public bool? system { get; set; }
|
public bool? system { get; set; }
|
||||||
public string? name { get; set; }
|
public string? name { get; set; }
|
||||||
public int? mtu { get; set; }
|
public int? mtu { get; set; }
|
||||||
|
@ -219,14 +205,11 @@ public class HyObfs4Sbox
|
||||||
public string? password { get; set; }
|
public string? password { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Server4Sbox
|
public class Server4Sbox : BaseServer4Sbox
|
||||||
{
|
{
|
||||||
public string? tag { get; set; }
|
|
||||||
public string? detour { get; set; }
|
|
||||||
public string? inet4_range { get; set; }
|
public string? inet4_range { get; set; }
|
||||||
public string? inet6_range { get; set; }
|
public string? inet6_range { get; set; }
|
||||||
public string? client_subnet { get; set; }
|
public string? client_subnet { get; set; }
|
||||||
public string? type { get; set; }
|
|
||||||
public string? server { get; set; }
|
public string? server { get; set; }
|
||||||
public string? server_resolver { get; set; }
|
public string? server_resolver { get; set; }
|
||||||
[JsonPropertyName("interface")] public string? Interface { get; set; }
|
[JsonPropertyName("interface")] public string? Interface { get; set; }
|
||||||
|
@ -277,3 +260,33 @@ public class Ruleset4Sbox
|
||||||
public string? download_detour { get; set; }
|
public string? download_detour { get; set; }
|
||||||
public string? update_interval { get; set; }
|
public string? update_interval { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract class DialFields4Sbox
|
||||||
|
{
|
||||||
|
public string? detour { get; set; }
|
||||||
|
public string? bind_interface { get; set; }
|
||||||
|
public string? inet4_bind_address { get; set; }
|
||||||
|
public string? inet6_bind_address { get; set; }
|
||||||
|
public int? routing_mark { get; set; }
|
||||||
|
public bool? reuse_addr { get; set; }
|
||||||
|
public string? netns { get; set; }
|
||||||
|
public string? connect_timeout { get; set; }
|
||||||
|
public bool? tcp_fast_open { get; set; }
|
||||||
|
public bool? tcp_multi_path { get; set; }
|
||||||
|
public bool? udp_fragment { get; set; }
|
||||||
|
public Rule4Sbox? domain_resolver { get; set; } // or string
|
||||||
|
public string? network_strategy { get; set; }
|
||||||
|
public List<string>? network_type { get; set; }
|
||||||
|
public List<string>? fallback_network_type { get; set; }
|
||||||
|
public string? fallback_delay { get; set; }
|
||||||
|
public Tls4Sbox? tls { get; set; }
|
||||||
|
public Multiplex4Sbox? multiplex { get; set; }
|
||||||
|
public Transport4Sbox? transport { get; set; }
|
||||||
|
public HyObfs4Sbox? obfs { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class BaseServer4Sbox : DialFields4Sbox
|
||||||
|
{
|
||||||
|
public string type { get; set; }
|
||||||
|
public string tag { get; set; }
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
|
using System.Reactive;
|
||||||
using DynamicData;
|
using DynamicData;
|
||||||
using ServiceLib.Models;
|
using ServiceLib.Models;
|
||||||
|
|
||||||
|
@ -55,7 +56,18 @@ public class CoreConfigSingboxService
|
||||||
|
|
||||||
await GenInbounds(singboxConfig);
|
await GenInbounds(singboxConfig);
|
||||||
|
|
||||||
|
if (node.ConfigType == EConfigType.WireGuard)
|
||||||
|
{
|
||||||
|
singboxConfig.outbounds.RemoveAt(0);
|
||||||
|
var endpoints = new Endpoints4Sbox();
|
||||||
|
await GenEndpoint(node, endpoints);
|
||||||
|
endpoints.tag = Global.ProxyTag;
|
||||||
|
singboxConfig.endpoints = new() { endpoints };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
await GenOutbound(node, singboxConfig.outbounds.First());
|
await GenOutbound(node, singboxConfig.outbounds.First());
|
||||||
|
}
|
||||||
|
|
||||||
await GenMoreOutbounds(node, singboxConfig);
|
await GenMoreOutbounds(node, singboxConfig);
|
||||||
|
|
||||||
|
@ -204,16 +216,29 @@ public class CoreConfigSingboxService
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
|
var server = await GenServer(item);
|
||||||
await GenOutbound(item, outbound);
|
if (server is null)
|
||||||
outbound.tag = Global.ProxyTag + inbound.listen_port.ToString();
|
{
|
||||||
|
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
var tag = Global.ProxyTag + inbound.listen_port.ToString();
|
||||||
|
server.tag = tag;
|
||||||
|
if (server is Endpoints4Sbox endpoint)
|
||||||
|
{
|
||||||
|
singboxConfig.endpoints ??= new();
|
||||||
|
singboxConfig.endpoints.Add(endpoint);
|
||||||
|
}
|
||||||
|
else if (server is Outbound4Sbox outbound)
|
||||||
|
{
|
||||||
singboxConfig.outbounds.Add(outbound);
|
singboxConfig.outbounds.Add(outbound);
|
||||||
|
}
|
||||||
|
|
||||||
//rule
|
//rule
|
||||||
Rule4Sbox rule = new()
|
Rule4Sbox rule = new()
|
||||||
{
|
{
|
||||||
inbound = new List<string> { inbound.tag },
|
inbound = new List<string> { inbound.tag },
|
||||||
outbound = outbound.tag
|
outbound = tag
|
||||||
};
|
};
|
||||||
singboxConfig.route.rules.Add(rule);
|
singboxConfig.route.rules.Add(rule);
|
||||||
}
|
}
|
||||||
|
@ -277,7 +302,18 @@ public class CoreConfigSingboxService
|
||||||
}
|
}
|
||||||
|
|
||||||
await GenLog(singboxConfig);
|
await GenLog(singboxConfig);
|
||||||
|
if (node.ConfigType == EConfigType.WireGuard)
|
||||||
|
{
|
||||||
|
singboxConfig.outbounds.RemoveAt(0);
|
||||||
|
var endpoints = new Endpoints4Sbox();
|
||||||
|
await GenEndpoint(node, endpoints);
|
||||||
|
endpoints.tag = Global.ProxyTag;
|
||||||
|
singboxConfig.endpoints = new() { endpoints };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
await GenOutbound(node, singboxConfig.outbounds.First());
|
await GenOutbound(node, singboxConfig.outbounds.First());
|
||||||
|
}
|
||||||
await GenMoreOutbounds(node, singboxConfig);
|
await GenMoreOutbounds(node, singboxConfig);
|
||||||
await GenDnsDomains(null, singboxConfig, null);
|
await GenDnsDomains(null, singboxConfig, null);
|
||||||
|
|
||||||
|
@ -731,15 +767,6 @@ public class CoreConfigSingboxService
|
||||||
outbound.congestion_control = node.HeaderType;
|
outbound.congestion_control = node.HeaderType;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EConfigType.WireGuard:
|
|
||||||
{
|
|
||||||
outbound.private_key = node.Id;
|
|
||||||
outbound.peer_public_key = node.PublicKey;
|
|
||||||
outbound.reserved = Utils.String2List(node.Path)?.Select(int.Parse).ToList();
|
|
||||||
outbound.local_address = Utils.String2List(node.RequestHost);
|
|
||||||
outbound.mtu = node.ShortId.IsNullOrEmpty() ? Global.TunMtus.First() : node.ShortId.ToInt();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EConfigType.Anytls:
|
case EConfigType.Anytls:
|
||||||
{
|
{
|
||||||
outbound.password = node.Id;
|
outbound.password = node.Id;
|
||||||
|
@ -758,6 +785,76 @@ public class CoreConfigSingboxService
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<int> GenEndpoint(ProfileItem node, Endpoints4Sbox endpoint)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
endpoint.address = Utils.String2List(node.RequestHost);
|
||||||
|
// Utils.GetFreePort() 9090 ?
|
||||||
|
endpoint.listen_port = Utils.GetFreePort();
|
||||||
|
endpoint.type = Global.ProtocolTypes[node.ConfigType];
|
||||||
|
|
||||||
|
if (Utils.IsDomain(node.Address))
|
||||||
|
{
|
||||||
|
var item = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
|
||||||
|
endpoint.domain_resolver = new()
|
||||||
|
{
|
||||||
|
server = "local_local",
|
||||||
|
strategy = string.IsNullOrEmpty(item?.DomainStrategy4Freedom) ? null : item?.DomainStrategy4Freedom
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (node.ConfigType)
|
||||||
|
{
|
||||||
|
case EConfigType.WireGuard:
|
||||||
|
{
|
||||||
|
var peer = new Peer4Sbox
|
||||||
|
{
|
||||||
|
public_key = node.PublicKey,
|
||||||
|
reserved = Utils.String2List(node.Path)?.Select(int.Parse).ToList(),
|
||||||
|
address = node.Address,
|
||||||
|
port = node.Port,
|
||||||
|
// TODO default ["0.0.0.0/0", "::/0"]
|
||||||
|
allowed_ips = new() { "0.0.0.0/0", "::/0" },
|
||||||
|
};
|
||||||
|
endpoint.private_key = node.Id;
|
||||||
|
endpoint.mtu = node.ShortId.IsNullOrEmpty() ? Global.TunMtus.First() : node.ShortId.ToInt();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(_tag, ex);
|
||||||
|
}
|
||||||
|
return await Task.FromResult(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<BaseServer4Sbox?> GenServer(ProfileItem node)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
|
||||||
|
if (node.ConfigType == EConfigType.WireGuard)
|
||||||
|
{
|
||||||
|
var endpoint = JsonUtils.Deserialize<Endpoints4Sbox>(txtOutbound);
|
||||||
|
await GenEndpoint(node, endpoint);
|
||||||
|
return endpoint;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
|
||||||
|
await GenOutbound(node, outbound);
|
||||||
|
return outbound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(_tag, ex);
|
||||||
|
}
|
||||||
|
return await Task.FromResult<BaseServer4Sbox?>(null);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<int> GenOutboundMux(ProfileItem node, Outbound4Sbox outbound)
|
private async Task<int> GenOutboundMux(ProfileItem node, Outbound4Sbox outbound)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -924,7 +1021,8 @@ public class CoreConfigSingboxService
|
||||||
}
|
}
|
||||||
|
|
||||||
//current proxy
|
//current proxy
|
||||||
var outbound = singboxConfig.outbounds.First();
|
BaseServer4Sbox? outbound = singboxConfig.endpoints?.FirstOrDefault(t => t.tag == Global.ProxyTag) == null ? singboxConfig.outbounds.First() : null;
|
||||||
|
|
||||||
var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
|
var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
|
||||||
|
|
||||||
//Previous proxy
|
//Previous proxy
|
||||||
|
@ -933,17 +1031,32 @@ public class CoreConfigSingboxService
|
||||||
if (prevNode is not null
|
if (prevNode is not null
|
||||||
&& prevNode.ConfigType != EConfigType.Custom)
|
&& prevNode.ConfigType != EConfigType.Custom)
|
||||||
{
|
{
|
||||||
var prevOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
|
|
||||||
await GenOutbound(prevNode, prevOutbound);
|
|
||||||
prevOutboundTag = $"prev-{Global.ProxyTag}";
|
prevOutboundTag = $"prev-{Global.ProxyTag}";
|
||||||
prevOutbound.tag = prevOutboundTag;
|
var prevServer = await GenServer(prevNode);
|
||||||
singboxConfig.outbounds.Add(prevOutbound);
|
prevServer.tag = prevOutboundTag;
|
||||||
}
|
if (prevServer is Endpoints4Sbox endpoint)
|
||||||
var nextOutbound = await GenChainOutbounds(subItem, outbound, prevOutboundTag);
|
|
||||||
|
|
||||||
if (nextOutbound is not null)
|
|
||||||
{
|
{
|
||||||
singboxConfig.outbounds.Insert(0, nextOutbound);
|
singboxConfig.endpoints ??= new();
|
||||||
|
singboxConfig.endpoints.Add(endpoint);
|
||||||
|
}
|
||||||
|
else if (prevServer is Outbound4Sbox outboundPrev)
|
||||||
|
{
|
||||||
|
singboxConfig.outbounds.Add(outboundPrev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var nextServer = await GenChainOutbounds(subItem, outbound, prevOutboundTag);
|
||||||
|
|
||||||
|
if (nextServer is not null)
|
||||||
|
{
|
||||||
|
if (nextServer is Endpoints4Sbox endpoint)
|
||||||
|
{
|
||||||
|
singboxConfig.endpoints ??= new();
|
||||||
|
singboxConfig.endpoints.Insert(0, endpoint);
|
||||||
|
}
|
||||||
|
else if (nextServer is Outbound4Sbox outboundNext)
|
||||||
|
{
|
||||||
|
singboxConfig.outbounds.Insert(0, outboundNext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -966,11 +1079,13 @@ public class CoreConfigSingboxService
|
||||||
}
|
}
|
||||||
|
|
||||||
var resultOutbounds = new List<Outbound4Sbox>();
|
var resultOutbounds = new List<Outbound4Sbox>();
|
||||||
|
var resultEndpoints = new List<Endpoints4Sbox>(); // For endpoints
|
||||||
var prevOutbounds = new List<Outbound4Sbox>(); // Separate list for prev outbounds
|
var prevOutbounds = new List<Outbound4Sbox>(); // Separate list for prev outbounds
|
||||||
|
var prevEndpoints = new List<Endpoints4Sbox>(); // Separate list for prev endpoints
|
||||||
var proxyTags = new List<string>(); // For selector and urltest outbounds
|
var proxyTags = new List<string>(); // For selector and urltest outbounds
|
||||||
|
|
||||||
// Cache for chain proxies to avoid duplicate generation
|
// Cache for chain proxies to avoid duplicate generation
|
||||||
var nextProxyCache = new Dictionary<string, Outbound4Sbox?>();
|
var nextProxyCache = new Dictionary<string, BaseServer4Sbox?>();
|
||||||
var prevProxyTags = new Dictionary<string, string?>(); // Map from profile name to tag
|
var prevProxyTags = new Dictionary<string, string?>(); // Map from profile name to tag
|
||||||
int prevIndex = 0; // Index for prev outbounds
|
int prevIndex = 0; // Index for prev outbounds
|
||||||
|
|
||||||
|
@ -982,19 +1097,18 @@ public class CoreConfigSingboxService
|
||||||
|
|
||||||
// Handle proxy chain
|
// Handle proxy chain
|
||||||
string? prevTag = null;
|
string? prevTag = null;
|
||||||
var currentOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
|
var currentServer = await GenServer(node);
|
||||||
var nextOutbound = nextProxyCache.GetValueOrDefault(node.Subid, null);
|
var nextServer = nextProxyCache.GetValueOrDefault(node.Subid, null);
|
||||||
if (nextOutbound != null)
|
if (nextServer != null)
|
||||||
{
|
{
|
||||||
nextOutbound = JsonUtils.DeepCopy(nextOutbound);
|
nextServer = JsonUtils.DeepCopy(nextServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
var subItem = await AppHandler.Instance.GetSubItem(node.Subid);
|
var subItem = await AppHandler.Instance.GetSubItem(node.Subid);
|
||||||
|
|
||||||
// current proxy
|
// current proxy
|
||||||
await GenOutbound(node, currentOutbound);
|
currentServer.tag = $"{Global.ProxyTag}-{index}";
|
||||||
currentOutbound.tag = $"{Global.ProxyTag}-{index}";
|
proxyTags.Add(currentServer.tag);
|
||||||
proxyTags.Add(currentOutbound.tag);
|
|
||||||
|
|
||||||
if (!node.Subid.IsNullOrEmpty())
|
if (!node.Subid.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
|
@ -1017,19 +1131,33 @@ public class CoreConfigSingboxService
|
||||||
prevProxyTags[node.Subid] = prevTag;
|
prevProxyTags[node.Subid] = prevTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
nextOutbound = await GenChainOutbounds(subItem, currentOutbound, prevTag, nextOutbound);
|
nextServer = await GenChainOutbounds(subItem, currentServer, prevTag, nextServer);
|
||||||
if (!nextProxyCache.ContainsKey(node.Subid))
|
if (!nextProxyCache.ContainsKey(node.Subid))
|
||||||
{
|
{
|
||||||
nextProxyCache[node.Subid] = nextOutbound;
|
nextProxyCache[node.Subid] = nextServer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextOutbound is not null)
|
if (nextServer is not null)
|
||||||
|
{
|
||||||
|
if (nextServer is Endpoints4Sbox nextEndpoint)
|
||||||
|
{
|
||||||
|
resultEndpoints.Add(nextEndpoint);
|
||||||
|
}
|
||||||
|
else if (nextServer is Outbound4Sbox nextOutbound)
|
||||||
{
|
{
|
||||||
resultOutbounds.Add(nextOutbound);
|
resultOutbounds.Add(nextOutbound);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (currentServer is Endpoints4Sbox currentEndpoint)
|
||||||
|
{
|
||||||
|
resultEndpoints.Add(currentEndpoint);
|
||||||
|
}
|
||||||
|
else if (currentServer is Outbound4Sbox currentOutbound)
|
||||||
|
{
|
||||||
resultOutbounds.Add(currentOutbound);
|
resultOutbounds.Add(currentOutbound);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add urltest outbound (auto selection based on latency)
|
// Add urltest outbound (auto selection based on latency)
|
||||||
if (proxyTags.Count > 0)
|
if (proxyTags.Count > 0)
|
||||||
|
@ -1061,6 +1189,9 @@ public class CoreConfigSingboxService
|
||||||
resultOutbounds.AddRange(prevOutbounds);
|
resultOutbounds.AddRange(prevOutbounds);
|
||||||
resultOutbounds.AddRange(singboxConfig.outbounds);
|
resultOutbounds.AddRange(singboxConfig.outbounds);
|
||||||
singboxConfig.outbounds = resultOutbounds;
|
singboxConfig.outbounds = resultOutbounds;
|
||||||
|
singboxConfig.endpoints ??= new List<Endpoints4Sbox>();
|
||||||
|
resultEndpoints.AddRange(singboxConfig.endpoints);
|
||||||
|
singboxConfig.endpoints = resultEndpoints;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -1082,7 +1213,7 @@ public class CoreConfigSingboxService
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// The outbound configuration for the next proxy in the chain, or null if no next proxy exists.
|
/// The outbound configuration for the next proxy in the chain, or null if no next proxy exists.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
private async Task<Outbound4Sbox?> GenChainOutbounds(SubItem subItem, Outbound4Sbox outbound, string? prevOutboundTag, Outbound4Sbox? nextOutbound = null)
|
private async Task<BaseServer4Sbox?> GenChainOutbounds(SubItem subItem, BaseServer4Sbox outbound, string? prevOutboundTag, BaseServer4Sbox? nextOutbound = null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -1098,11 +1229,7 @@ public class CoreConfigSingboxService
|
||||||
if (nextNode is not null
|
if (nextNode is not null
|
||||||
&& nextNode.ConfigType != EConfigType.Custom)
|
&& nextNode.ConfigType != EConfigType.Custom)
|
||||||
{
|
{
|
||||||
if (nextOutbound == null)
|
nextOutbound ??= await GenServer(nextNode);
|
||||||
{
|
|
||||||
nextOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
|
|
||||||
await GenOutbound(nextNode, nextOutbound);
|
|
||||||
}
|
|
||||||
nextOutbound.tag = outbound.tag;
|
nextOutbound.tag = outbound.tag;
|
||||||
|
|
||||||
outbound.tag = $"mid-{outbound.tag}";
|
outbound.tag = $"mid-{outbound.tag}";
|
||||||
|
@ -1426,13 +1553,24 @@ public class CoreConfigSingboxService
|
||||||
return Global.ProxyTag;
|
return Global.ProxyTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
|
var server = await GenServer(node);
|
||||||
var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
|
if (server is null)
|
||||||
await GenOutbound(node, outbound);
|
{
|
||||||
outbound.tag = Global.ProxyTag + node.IndexId.ToString();
|
return Global.ProxyTag;
|
||||||
singboxConfig.outbounds.Add(outbound);
|
}
|
||||||
|
|
||||||
return outbound.tag;
|
server.tag = Global.ProxyTag + node.IndexId.ToString();
|
||||||
|
if (server is Endpoints4Sbox endpoint)
|
||||||
|
{
|
||||||
|
singboxConfig.endpoints ??= new();
|
||||||
|
singboxConfig.endpoints.Add(endpoint);
|
||||||
|
}
|
||||||
|
else if (server is Outbound4Sbox outbound)
|
||||||
|
{
|
||||||
|
singboxConfig.outbounds.Add(outbound);
|
||||||
|
}
|
||||||
|
|
||||||
|
return server.tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<int> GenDns(ProfileItem? node, SingboxConfig singboxConfig)
|
private async Task<int> GenDns(ProfileItem? node, SingboxConfig singboxConfig)
|
||||||
|
|
Loading…
Reference in New Issue