v2rayN/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigV2rayService.cs

1260 lines
49 KiB
C#
Raw Normal View History

using System.Net;
2023-04-23 12:21:52 +00:00
using System.Net.NetworkInformation;
2024-06-26 08:00:37 +00:00
using System.Text.Json.Nodes;
2023-04-23 12:21:52 +00:00
2024-10-07 02:39:43 +00:00
namespace ServiceLib.Services.CoreConfig
2023-04-23 12:21:52 +00:00
{
2024-10-07 02:39:43 +00:00
public class CoreConfigV2rayService
2023-04-23 12:21:52 +00:00
{
private Config _config;
2024-10-07 02:39:43 +00:00
public CoreConfigV2rayService(Config config)
2023-04-23 12:21:52 +00:00
{
_config = config;
}
2024-07-14 09:16:07 +00:00
#region public gen function
2024-10-21 01:45:33 +00:00
public async Task<RetResult> GenerateClientConfigContent(ProfileItem node)
2023-04-23 12:21:52 +00:00
{
2024-10-21 10:18:41 +00:00
var ret = new RetResult();
2023-04-23 12:21:52 +00:00
try
{
if (node == null
|| node.Port <= 0)
2023-04-23 12:21:52 +00:00
{
2024-10-21 01:45:33 +00:00
ret.Msg = ResUI.CheckServerSettings;
return ret;
2023-04-23 12:21:52 +00:00
}
if (node.GetNetwork() is nameof(ETransport.quic))
{
ret.Msg = ResUI.Incorrectconfiguration + $" - {node.GetNetwork()}";
return ret;
}
2024-10-21 01:45:33 +00:00
ret.Msg = ResUI.InitialConfiguration;
2023-04-23 12:21:52 +00:00
2024-10-21 01:45:33 +00:00
var result = Utils.GetEmbedText(Global.V2raySampleClient);
2024-03-26 06:26:03 +00:00
if (Utils.IsNullOrEmpty(result))
2023-04-23 12:21:52 +00:00
{
2024-10-21 01:45:33 +00:00
ret.Msg = ResUI.FailedGetDefaultConfiguration;
return ret;
2023-04-23 12:21:52 +00:00
}
2024-10-21 01:45:33 +00:00
var v2rayConfig = JsonUtils.Deserialize<V2rayConfig>(result);
2023-04-23 12:21:52 +00:00
if (v2rayConfig == null)
{
2024-10-21 01:45:33 +00:00
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
2023-04-23 12:21:52 +00:00
}
2024-10-21 01:45:33 +00:00
await GenLog(v2rayConfig);
2023-04-23 12:21:52 +00:00
2024-10-21 01:45:33 +00:00
await GenInbounds(v2rayConfig);
2023-04-23 12:21:52 +00:00
2024-10-21 01:45:33 +00:00
await GenRouting(v2rayConfig);
2023-04-23 12:21:52 +00:00
2024-10-21 01:45:33 +00:00
await GenOutbound(node, v2rayConfig.outbounds[0]);
2023-04-23 12:21:52 +00:00
2024-10-21 01:45:33 +00:00
await GenMoreOutbounds(node, v2rayConfig);
2023-12-23 12:57:31 +00:00
2024-10-21 01:45:33 +00:00
await GenDns(node, v2rayConfig);
2023-04-23 12:21:52 +00:00
2024-10-21 01:45:33 +00:00
await GenStatistic(v2rayConfig);
2023-04-23 12:21:52 +00:00
2024-10-21 01:45:33 +00:00
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
2024-10-21 10:18:41 +00:00
ret.Success = true;
2024-10-21 01:45:33 +00:00
ret.Data = JsonUtils.Serialize(v2rayConfig);
return ret;
2023-04-23 12:21:52 +00:00
}
catch (Exception ex)
{
2024-01-10 02:43:48 +00:00
Logging.SaveLog("GenerateClientConfig4V2ray", ex);
2024-10-21 01:45:33 +00:00
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
2023-04-23 12:21:52 +00:00
}
}
2024-10-21 01:45:33 +00:00
public async Task<RetResult> GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds)
2024-07-21 03:26:10 +00:00
{
2024-10-21 10:18:41 +00:00
var ret = new RetResult();
2024-10-21 01:45:33 +00:00
2024-07-21 03:26:10 +00:00
try
{
if (_config == null)
{
2024-10-21 01:45:33 +00:00
ret.Msg = ResUI.CheckServerSettings;
return ret;
2024-07-21 03:26:10 +00:00
}
2024-10-21 01:45:33 +00:00
ret.Msg = ResUI.InitialConfiguration;
2024-07-21 03:26:10 +00:00
string result = Utils.GetEmbedText(Global.V2raySampleClient);
string txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound);
if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty())
{
2024-10-21 01:45:33 +00:00
ret.Msg = ResUI.FailedGetDefaultConfiguration;
return ret;
2024-07-21 03:26:10 +00:00
}
2024-10-21 01:45:33 +00:00
var v2rayConfig = JsonUtils.Deserialize<V2rayConfig>(result);
2024-07-21 03:26:10 +00:00
if (v2rayConfig == null)
{
2024-10-21 01:45:33 +00:00
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
2024-07-21 03:26:10 +00:00
}
2024-10-21 01:45:33 +00:00
await GenLog(v2rayConfig);
await GenInbounds(v2rayConfig);
await GenRouting(v2rayConfig);
await GenDns(null, v2rayConfig);
await GenStatistic(v2rayConfig);
2024-07-21 03:26:10 +00:00
v2rayConfig.outbounds.RemoveAt(0);
var tagProxy = new List<string>();
foreach (var it in selecteds)
{
if (it.ConfigType == EConfigType.Custom)
2024-07-21 03:26:10 +00:00
{
continue;
}
if (it.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.WireGuard)
2024-07-21 03:26:10 +00:00
{
continue;
}
if (it.Port <= 0)
2024-07-21 03:26:10 +00:00
{
continue;
}
var item = await AppHandler.Instance.GetProfileItem(it.IndexId);
2024-07-21 03:26:10 +00:00
if (item is null)
{
continue;
}
if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS)
2024-07-21 03:26:10 +00:00
{
if (Utils.IsNullOrEmpty(item.Id) || !Utils.IsGuidByParse(item.Id))
2024-07-21 03:26:10 +00:00
{
continue;
}
}
if (item.ConfigType == EConfigType.Shadowsocks
&& !Global.SsSecuritiesInSingbox.Contains(item.Security))
2024-07-21 03:26:10 +00:00
{
continue;
}
if (item.ConfigType == EConfigType.VLESS && !Global.Flows.Contains(item.Flow))
2024-07-21 03:26:10 +00:00
{
continue;
}
//outbound
var outbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
2024-10-21 01:45:33 +00:00
await GenOutbound(item, outbound);
2024-07-21 03:26:10 +00:00
outbound.tag = $"{Global.ProxyTag}-{tagProxy.Count + 1}";
v2rayConfig.outbounds.Add(outbound);
tagProxy.Add(outbound.tag);
}
if (tagProxy.Count <= 0)
{
2024-10-21 01:45:33 +00:00
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
2024-07-21 03:26:10 +00:00
}
//add balancers
var balancer = new BalancersItem4Ray
{
selector = [Global.ProxyTag],
strategy = new() { type = "roundRobin" },
tag = $"{Global.ProxyTag}-round",
};
v2rayConfig.routing.balancers = [balancer];
//add rule
var rules = v2rayConfig.routing.rules.Where(t => t.outboundTag == Global.ProxyTag).ToList();
if (rules?.Count > 0)
{
foreach (var rule in rules)
{
rule.outboundTag = null;
rule.balancerTag = balancer.tag;
}
}
else
{
v2rayConfig.routing.rules.Add(new()
{
network = "tcp,udp",
balancerTag = balancer.tag,
type = "field"
});
}
2024-10-21 10:18:41 +00:00
ret.Success = true;
2024-10-21 01:45:33 +00:00
ret.Data = JsonUtils.Serialize(v2rayConfig);
return ret;
2024-07-21 03:26:10 +00:00
}
catch (Exception ex)
{
Logging.SaveLog(ex.Message, ex);
2024-10-21 01:45:33 +00:00
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
2024-07-21 03:26:10 +00:00
}
}
2024-10-21 01:45:33 +00:00
public async Task<RetResult> GenerateClientSpeedtestConfig(List<ServerTestItem> selecteds)
2024-07-14 09:16:07 +00:00
{
2024-10-21 10:18:41 +00:00
var ret = new RetResult();
2024-07-14 09:16:07 +00:00
try
{
if (_config == null)
{
2024-10-21 01:45:33 +00:00
ret.Msg = ResUI.CheckServerSettings;
return ret;
2024-07-14 09:16:07 +00:00
}
2024-10-21 01:45:33 +00:00
ret.Msg = ResUI.InitialConfiguration;
2024-07-14 09:16:07 +00:00
var result = Utils.GetEmbedText(Global.V2raySampleClient);
var txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound);
2024-07-14 09:16:07 +00:00
if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty())
{
2024-10-21 01:45:33 +00:00
ret.Msg = ResUI.FailedGetDefaultConfiguration;
return ret;
2024-07-14 09:16:07 +00:00
}
2024-10-21 01:45:33 +00:00
var v2rayConfig = JsonUtils.Deserialize<V2rayConfig>(result);
2024-07-14 09:16:07 +00:00
if (v2rayConfig == null)
{
2024-10-21 01:45:33 +00:00
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
2024-07-14 09:16:07 +00:00
}
List<IPEndPoint> lstIpEndPoints = new();
List<TcpConnectionInformation> lstTcpConns = new();
try
{
lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners());
lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners());
lstTcpConns.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections());
}
catch (Exception ex)
{
Logging.SaveLog(ex.Message, ex);
}
2024-10-21 01:45:33 +00:00
await GenLog(v2rayConfig);
2024-11-20 04:01:04 +00:00
v2rayConfig.inbounds.Clear();
v2rayConfig.outbounds.Clear();
v2rayConfig.routing.rules.Clear();
2024-07-14 09:16:07 +00:00
var httpPort = AppHandler.Instance.GetLocalPort(EInboundProtocol.speedtest);
2024-07-14 09:16:07 +00:00
foreach (var it in selecteds)
{
2024-10-08 01:50:03 +00:00
if (it.ConfigType == EConfigType.Custom)
2024-07-14 09:16:07 +00:00
{
continue;
}
2024-10-08 01:50:03 +00:00
if (it.Port <= 0)
2024-07-14 09:16:07 +00:00
{
continue;
}
2024-10-21 01:45:33 +00:00
var item = await AppHandler.Instance.GetProfileItem(it.IndexId);
2024-10-08 01:50:03 +00:00
if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS)
2024-07-14 09:16:07 +00:00
{
if (item is null || Utils.IsNullOrEmpty(item.Id) || !Utils.IsGuidByParse(item.Id))
2024-07-14 09:16:07 +00:00
{
continue;
}
}
//find unused port
var port = httpPort;
for (var k = httpPort; k < Global.MaxPort; k++)
2024-07-14 09:16:07 +00:00
{
if (lstIpEndPoints?.FindIndex(_it => _it.Port == k) >= 0)
{
continue;
}
if (lstTcpConns?.FindIndex(_it => _it.LocalEndPoint.Port == k) >= 0)
{
continue;
}
//found
port = k;
httpPort = port + 1;
break;
}
//Port In Used
if (lstIpEndPoints?.FindIndex(_it => _it.Port == port) >= 0)
{
continue;
}
2024-10-08 01:50:03 +00:00
it.Port = port;
it.AllowTest = true;
2024-07-14 09:16:07 +00:00
//outbound
if (item is null)
{
continue;
}
if (item.ConfigType == EConfigType.Shadowsocks
&& !Global.SsSecuritiesInXray.Contains(item.Security))
2024-07-14 09:16:07 +00:00
{
continue;
}
if (item.ConfigType == EConfigType.VLESS
&& !Global.Flows.Contains(item.Flow))
2024-07-14 09:16:07 +00:00
{
continue;
}
2024-10-08 01:50:03 +00:00
if (it.ConfigType is EConfigType.VLESS or EConfigType.Trojan
&& item.StreamSecurity == Global.StreamSecurityReality
&& item.PublicKey.IsNullOrEmpty())
2024-09-17 10:41:01 +00:00
{
continue;
}
2024-11-20 04:01:04 +00:00
//inbound
Inbounds4Ray inbound = new()
{
listen = Global.Loopback,
port = port,
protocol = EInboundProtocol.http.ToString(),
};
inbound.tag = inbound.protocol + inbound.port.ToString();
v2rayConfig.inbounds.Add(inbound);
2024-07-14 09:16:07 +00:00
var outbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
2024-10-21 01:45:33 +00:00
await GenOutbound(item, outbound);
2024-07-14 09:16:07 +00:00
outbound.tag = Global.ProxyTag + inbound.port.ToString();
v2rayConfig.outbounds.Add(outbound);
//rule
RulesItem4Ray rule = new()
{
inboundTag = new List<string> { inbound.tag },
outboundTag = outbound.tag,
type = "field"
};
v2rayConfig.routing.rules.Add(rule);
}
2024-10-21 01:45:33 +00:00
//ret.Msg =string.Format(ResUI.SuccessfulConfiguration"), node.getSummary());
2024-10-21 10:18:41 +00:00
ret.Success = true;
2024-10-21 01:45:33 +00:00
ret.Data = JsonUtils.Serialize(v2rayConfig);
return ret;
2024-07-14 09:16:07 +00:00
}
catch (Exception ex)
{
Logging.SaveLog(ex.Message, ex);
2024-10-21 01:45:33 +00:00
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
2024-07-14 09:16:07 +00:00
}
}
#endregion public gen function
#region private gen function
2024-10-21 01:45:33 +00:00
public async Task<int> GenLog(V2rayConfig v2rayConfig)
2023-04-23 12:21:52 +00:00
{
try
{
if (_config.CoreBasicItem.LogEnabled)
2023-04-23 12:21:52 +00:00
{
var dtNow = DateTime.Now;
v2rayConfig.log.loglevel = _config.CoreBasicItem.Loglevel;
2024-03-26 06:26:03 +00:00
v2rayConfig.log.access = Utils.GetLogPath($"Vaccess_{dtNow:yyyy-MM-dd}.txt");
v2rayConfig.log.error = Utils.GetLogPath($"Verror_{dtNow:yyyy-MM-dd}.txt");
2023-04-23 12:21:52 +00:00
}
else
{
v2rayConfig.log.loglevel = _config.CoreBasicItem.Loglevel;
v2rayConfig.log.access = null;
v2rayConfig.log.error = null;
2023-04-23 12:21:52 +00:00
}
}
catch (Exception ex)
{
2024-01-10 02:43:48 +00:00
Logging.SaveLog(ex.Message, ex);
2023-04-23 12:21:52 +00:00
}
return 0;
}
2024-10-21 01:45:33 +00:00
public async Task<int> GenInbounds(V2rayConfig v2rayConfig)
2023-04-23 12:21:52 +00:00
{
try
{
2024-05-14 05:42:42 +00:00
var listen = "0.0.0.0";
v2rayConfig.inbounds = [];
2023-04-23 12:21:52 +00:00
Inbounds4Ray? inbound = GetInbound(_config.Inbound[0], EInboundProtocol.socks, true);
2023-04-23 12:21:52 +00:00
v2rayConfig.inbounds.Add(inbound);
//http
Inbounds4Ray? inbound2 = GetInbound(_config.Inbound[0], EInboundProtocol.http, false);
2023-04-23 12:21:52 +00:00
v2rayConfig.inbounds.Add(inbound2);
if (_config.Inbound[0].AllowLANConn)
2023-04-23 12:21:52 +00:00
{
if (_config.Inbound[0].NewPort4LAN)
2023-04-23 12:21:52 +00:00
{
var inbound3 = GetInbound(_config.Inbound[0], EInboundProtocol.socks2, true);
2024-05-14 05:42:42 +00:00
inbound3.listen = listen;
2023-04-23 12:21:52 +00:00
v2rayConfig.inbounds.Add(inbound3);
var inbound4 = GetInbound(_config.Inbound[0], EInboundProtocol.http2, false);
2024-05-14 05:42:42 +00:00
inbound4.listen = listen;
2023-04-23 12:21:52 +00:00
v2rayConfig.inbounds.Add(inbound4);
//auth
if (Utils.IsNotEmpty(_config.Inbound[0].User) && Utils.IsNotEmpty(_config.Inbound[0].Pass))
2023-04-23 12:21:52 +00:00
{
inbound3.settings.auth = "password";
inbound3.settings.accounts = new List<AccountsItem4Ray> { new AccountsItem4Ray() { user = _config.Inbound[0].User, pass = _config.Inbound[0].Pass } };
2023-04-23 12:21:52 +00:00
inbound4.settings.auth = "password";
inbound4.settings.accounts = new List<AccountsItem4Ray> { new AccountsItem4Ray() { user = _config.Inbound[0].User, pass = _config.Inbound[0].Pass } };
2023-04-23 12:21:52 +00:00
}
}
else
{
2024-05-14 05:42:42 +00:00
inbound.listen = listen;
inbound2.listen = listen;
2023-04-23 12:21:52 +00:00
}
}
}
catch (Exception ex)
{
2024-01-10 02:43:48 +00:00
Logging.SaveLog(ex.Message, ex);
2023-04-23 12:21:52 +00:00
}
return 0;
}
2024-05-14 05:42:42 +00:00
private Inbounds4Ray GetInbound(InItem inItem, EInboundProtocol protocol, bool bSocks)
2023-04-23 12:21:52 +00:00
{
2024-03-26 06:26:03 +00:00
string result = Utils.GetEmbedText(Global.V2raySampleInbound);
if (Utils.IsNullOrEmpty(result))
2023-04-23 12:21:52 +00:00
{
2024-05-14 05:42:42 +00:00
return new();
2023-04-23 12:21:52 +00:00
}
2024-03-26 06:26:03 +00:00
var inbound = JsonUtils.Deserialize<Inbounds4Ray>(result);
2023-04-23 12:21:52 +00:00
if (inbound == null)
{
2024-05-14 05:42:42 +00:00
return new();
2023-04-23 12:21:52 +00:00
}
2024-03-09 02:12:45 +00:00
inbound.tag = protocol.ToString();
inbound.port = inItem.LocalPort + (int)protocol;
2024-03-09 02:12:45 +00:00
inbound.protocol = bSocks ? EInboundProtocol.socks.ToString() : EInboundProtocol.http.ToString();
inbound.settings.udp = inItem.UdpEnabled;
inbound.sniffing.enabled = inItem.SniffingEnabled;
inbound.sniffing.destOverride = inItem.DestOverride;
inbound.sniffing.routeOnly = inItem.RouteOnly;
2023-04-23 12:21:52 +00:00
return inbound;
}
2024-10-20 03:51:05 +00:00
private async Task<int> GenRouting(V2rayConfig v2rayConfig)
2023-04-23 12:21:52 +00:00
{
try
{
if (v2rayConfig.routing?.rules != null)
{
v2rayConfig.routing.domainStrategy = _config.RoutingBasicItem.DomainStrategy;
v2rayConfig.routing.domainMatcher = Utils.IsNullOrEmpty(_config.RoutingBasicItem.DomainMatcher) ? null : _config.RoutingBasicItem.DomainMatcher;
2023-04-23 12:21:52 +00:00
2024-11-20 04:01:04 +00:00
var routing = await ConfigHandler.GetDefaultRouting(_config);
if (routing != null)
2023-04-23 12:21:52 +00:00
{
2024-11-20 04:01:04 +00:00
if (Utils.IsNotEmpty(routing.DomainStrategy))
2023-04-23 12:21:52 +00:00
{
2024-11-20 04:01:04 +00:00
v2rayConfig.routing.domainStrategy = routing.DomainStrategy;
2023-04-23 12:21:52 +00:00
}
2024-11-20 04:01:04 +00:00
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
foreach (var item in rules)
2023-04-23 12:21:52 +00:00
{
2024-11-20 04:01:04 +00:00
if (item.Enabled)
2023-04-23 12:21:52 +00:00
{
2024-03-26 06:26:03 +00:00
var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item));
2024-10-21 01:45:33 +00:00
await GenRoutingUserRule(item2, v2rayConfig);
2023-04-23 12:21:52 +00:00
}
}
}
}
}
catch (Exception ex)
{
2024-01-10 02:43:48 +00:00
Logging.SaveLog(ex.Message, ex);
2023-04-23 12:21:52 +00:00
}
return 0;
}
2024-10-21 01:45:33 +00:00
public async Task<int> GenRoutingUserRule(RulesItem4Ray? rule, V2rayConfig v2rayConfig)
2023-04-23 12:21:52 +00:00
{
try
{
if (rule == null)
2023-04-23 12:21:52 +00:00
{
return 0;
}
if (Utils.IsNullOrEmpty(rule.port))
2023-04-23 12:21:52 +00:00
{
rule.port = null;
2023-04-23 12:21:52 +00:00
}
if (Utils.IsNullOrEmpty(rule.network))
2023-04-23 12:21:52 +00:00
{
rule.network = null;
2023-04-23 12:21:52 +00:00
}
if (rule.domain?.Count == 0)
2023-04-23 12:21:52 +00:00
{
rule.domain = null;
2023-04-23 12:21:52 +00:00
}
if (rule.ip?.Count == 0)
2023-04-23 12:21:52 +00:00
{
rule.ip = null;
2023-04-23 12:21:52 +00:00
}
if (rule.protocol?.Count == 0)
2023-04-23 12:21:52 +00:00
{
rule.protocol = null;
}
if (rule.inboundTag?.Count == 0)
{
rule.inboundTag = null;
2023-04-23 12:21:52 +00:00
}
var hasDomainIp = false;
if (rule.domain?.Count > 0)
2023-04-23 12:21:52 +00:00
{
var it = JsonUtils.DeepCopy(rule);
2023-04-23 12:21:52 +00:00
it.ip = null;
it.type = "field";
for (int k = it.domain.Count - 1; k >= 0; k--)
{
if (it.domain[k].StartsWith("#"))
{
it.domain.RemoveAt(k);
}
it.domain[k] = it.domain[k].Replace(Global.RoutingRuleComma, ",");
}
v2rayConfig.routing.rules.Add(it);
hasDomainIp = true;
}
if (rule.ip?.Count > 0)
2023-04-23 12:21:52 +00:00
{
var it = JsonUtils.DeepCopy(rule);
2023-04-23 12:21:52 +00:00
it.domain = null;
it.type = "field";
v2rayConfig.routing.rules.Add(it);
hasDomainIp = true;
}
if (!hasDomainIp)
{
2024-09-17 08:52:41 +00:00
if (Utils.IsNotEmpty(rule.port)
|| rule.protocol?.Count > 0
|| rule.inboundTag?.Count > 0
2023-04-23 12:21:52 +00:00
)
{
var it = JsonUtils.DeepCopy(rule);
2023-04-23 12:21:52 +00:00
it.type = "field";
v2rayConfig.routing.rules.Add(it);
}
}
}
catch (Exception ex)
{
2024-01-10 02:43:48 +00:00
Logging.SaveLog(ex.Message, ex);
2023-04-23 12:21:52 +00:00
}
return 0;
}
2024-10-21 01:45:33 +00:00
public async Task<int> GenOutbound(ProfileItem node, Outbounds4Ray outbound)
2023-04-23 12:21:52 +00:00
{
try
{
switch (node.ConfigType)
2023-04-23 12:21:52 +00:00
{
case EConfigType.VMess:
{
VnextItem4Ray vnextItem;
if (outbound.settings.vnext.Count <= 0)
{
vnextItem = new VnextItem4Ray();
outbound.settings.vnext.Add(vnextItem);
}
else
{
vnextItem = outbound.settings.vnext[0];
}
vnextItem.address = node.Address;
vnextItem.port = node.Port;
2023-04-23 12:21:52 +00:00
UsersItem4Ray usersItem;
if (vnextItem.users.Count <= 0)
{
usersItem = new UsersItem4Ray();
vnextItem.users.Add(usersItem);
}
else
{
usersItem = vnextItem.users[0];
}
//远程服务器用户ID
usersItem.id = node.Id;
usersItem.alterId = node.AlterId;
usersItem.email = Global.UserEMail;
if (Global.VmessSecurities.Contains(node.Security))
{
usersItem.security = node.Security;
}
else
{
usersItem.security = Global.DefaultSecurity;
}
2023-04-23 12:21:52 +00:00
await GenOutboundMux(node, outbound, _config.CoreBasicItem.MuxEnabled);
2023-04-23 12:21:52 +00:00
outbound.settings.servers = null;
break;
}
case EConfigType.Shadowsocks:
{
ServersItem4Ray serversItem;
if (outbound.settings.servers.Count <= 0)
{
serversItem = new ServersItem4Ray();
outbound.settings.servers.Add(serversItem);
}
else
{
serversItem = outbound.settings.servers[0];
}
serversItem.address = node.Address;
serversItem.port = node.Port;
serversItem.password = node.Id;
serversItem.method = AppHandler.Instance.GetShadowsocksSecurities(node).Contains(node.Security) ? node.Security : "none";
2023-04-23 12:21:52 +00:00
serversItem.ota = false;
serversItem.level = 1;
2023-04-23 12:21:52 +00:00
2024-10-21 01:45:33 +00:00
await GenOutboundMux(node, outbound, false);
2023-04-23 12:21:52 +00:00
outbound.settings.vnext = null;
break;
}
2024-09-23 09:17:12 +00:00
case EConfigType.SOCKS:
case EConfigType.HTTP:
2023-04-23 12:21:52 +00:00
{
ServersItem4Ray serversItem;
if (outbound.settings.servers.Count <= 0)
{
serversItem = new ServersItem4Ray();
outbound.settings.servers.Add(serversItem);
}
else
{
serversItem = outbound.settings.servers[0];
}
serversItem.address = node.Address;
serversItem.port = node.Port;
serversItem.method = null;
serversItem.password = null;
2023-04-23 12:21:52 +00:00
if (Utils.IsNotEmpty(node.Security)
&& Utils.IsNotEmpty(node.Id))
{
SocksUsersItem4Ray socksUsersItem = new()
{
user = node.Security,
pass = node.Id,
level = 1
};
2023-04-23 12:21:52 +00:00
serversItem.users = new List<SocksUsersItem4Ray>() { socksUsersItem };
}
2023-04-23 12:21:52 +00:00
2024-10-21 01:45:33 +00:00
await GenOutboundMux(node, outbound, false);
2023-04-23 12:21:52 +00:00
outbound.settings.vnext = null;
break;
}
case EConfigType.VLESS:
{
VnextItem4Ray vnextItem;
if (outbound.settings.vnext?.Count <= 0)
{
vnextItem = new VnextItem4Ray();
outbound.settings.vnext.Add(vnextItem);
}
else
{
vnextItem = outbound.settings.vnext[0];
}
vnextItem.address = node.Address;
vnextItem.port = node.Port;
2023-04-23 12:21:52 +00:00
UsersItem4Ray usersItem;
if (vnextItem.users.Count <= 0)
{
usersItem = new UsersItem4Ray();
vnextItem.users.Add(usersItem);
}
else
{
usersItem = vnextItem.users[0];
}
usersItem.id = node.Id;
usersItem.email = Global.UserEMail;
usersItem.encryption = node.Security;
2023-04-23 12:21:52 +00:00
await GenOutboundMux(node, outbound, _config.CoreBasicItem.MuxEnabled);
2023-04-23 12:21:52 +00:00
if (node.StreamSecurity == Global.StreamSecurityReality
|| node.StreamSecurity == Global.StreamSecurity)
{
if (Utils.IsNotEmpty(node.Flow))
{
usersItem.flow = node.Flow;
2023-04-23 12:21:52 +00:00
2024-10-21 01:45:33 +00:00
await GenOutboundMux(node, outbound, false);
}
}
if (node.StreamSecurity == Global.StreamSecurityReality && Utils.IsNullOrEmpty(node.Flow))
{
await GenOutboundMux(node, outbound, _config.CoreBasicItem.MuxEnabled);
}
outbound.settings.servers = null;
break;
}
case EConfigType.Trojan:
{
ServersItem4Ray serversItem;
if (outbound.settings.servers.Count <= 0)
{
serversItem = new ServersItem4Ray();
outbound.settings.servers.Add(serversItem);
}
else
{
serversItem = outbound.settings.servers[0];
}
serversItem.address = node.Address;
serversItem.port = node.Port;
serversItem.password = node.Id;
2023-04-23 12:21:52 +00:00
serversItem.ota = false;
serversItem.level = 1;
2023-04-23 12:21:52 +00:00
2024-10-21 01:45:33 +00:00
await GenOutboundMux(node, outbound, false);
2023-04-23 12:21:52 +00:00
outbound.settings.vnext = null;
break;
}
2023-04-23 12:21:52 +00:00
}
outbound.protocol = Global.ProtocolTypes[node.ConfigType];
2024-10-21 01:45:33 +00:00
await GenBoundStreamSettings(node, outbound.streamSettings);
2023-04-23 12:21:52 +00:00
}
catch (Exception ex)
{
2024-01-10 02:43:48 +00:00
Logging.SaveLog(ex.Message, ex);
2023-04-23 12:21:52 +00:00
}
return 0;
}
2024-10-21 01:45:33 +00:00
public async Task<int> GenOutboundMux(ProfileItem node, Outbounds4Ray outbound, bool enabled)
{
try
{
2023-05-07 08:35:46 +00:00
if (enabled)
{
outbound.mux.enabled = true;
outbound.mux.concurrency = _config.Mux4RayItem.Concurrency;
outbound.mux.xudpConcurrency = _config.Mux4RayItem.XudpConcurrency;
outbound.mux.xudpProxyUDP443 = _config.Mux4RayItem.XudpProxyUDP443;
}
else
{
outbound.mux.enabled = false;
outbound.mux.concurrency = -1;
}
}
catch (Exception ex)
{
2024-01-10 02:43:48 +00:00
Logging.SaveLog(ex.Message, ex);
}
return 0;
}
2024-10-21 01:45:33 +00:00
public async Task<int> GenBoundStreamSettings(ProfileItem node, StreamSettings4Ray streamSettings)
2023-04-23 12:21:52 +00:00
{
try
{
streamSettings.network = node.GetNetwork();
string host = node.RequestHost.TrimEx();
string sni = node.Sni;
2023-04-23 12:21:52 +00:00
string useragent = "";
if (!_config.CoreBasicItem.DefUserAgent.IsNullOrEmpty())
2023-04-23 12:21:52 +00:00
{
try
{
useragent = Global.UserAgentTexts[_config.CoreBasicItem.DefUserAgent];
2023-04-23 12:21:52 +00:00
}
catch (KeyNotFoundException)
{
useragent = _config.CoreBasicItem.DefUserAgent;
2023-04-23 12:21:52 +00:00
}
}
//if tls
if (node.StreamSecurity == Global.StreamSecurity)
2023-04-23 12:21:52 +00:00
{
streamSettings.security = node.StreamSecurity;
2023-04-23 12:21:52 +00:00
2023-05-07 08:35:46 +00:00
TlsSettings4Ray tlsSettings = new()
2023-04-23 12:21:52 +00:00
{
allowInsecure = Utils.ToBool(node.AllowInsecure.IsNullOrEmpty() ? _config.CoreBasicItem.DefAllowInsecure.ToString().ToLower() : node.AllowInsecure),
2023-04-23 12:21:52 +00:00
alpn = node.GetAlpn(),
fingerprint = node.Fingerprint.IsNullOrEmpty() ? _config.CoreBasicItem.DefFingerprint : node.Fingerprint
2023-04-23 12:21:52 +00:00
};
2024-09-17 08:52:41 +00:00
if (Utils.IsNotEmpty(sni))
2023-04-23 12:21:52 +00:00
{
tlsSettings.serverName = sni;
}
2024-09-17 08:52:41 +00:00
else if (Utils.IsNotEmpty(host))
2023-04-23 12:21:52 +00:00
{
2024-10-14 02:42:05 +00:00
tlsSettings.serverName = Utils.String2List(host)?.First();
2023-04-23 12:21:52 +00:00
}
streamSettings.tlsSettings = tlsSettings;
}
//if Reality
if (node.StreamSecurity == Global.StreamSecurityReality)
2023-04-23 12:21:52 +00:00
{
streamSettings.security = node.StreamSecurity;
2023-04-23 12:21:52 +00:00
2023-05-07 08:35:46 +00:00
TlsSettings4Ray realitySettings = new()
2023-04-23 12:21:52 +00:00
{
fingerprint = node.Fingerprint.IsNullOrEmpty() ? _config.CoreBasicItem.DefFingerprint : node.Fingerprint,
2023-04-23 12:21:52 +00:00
serverName = sni,
publicKey = node.PublicKey,
shortId = node.ShortId,
spiderX = node.SpiderX,
show = false,
2023-04-23 12:21:52 +00:00
};
streamSettings.realitySettings = realitySettings;
}
//streamSettings
switch (node.GetNetwork())
{
2024-03-09 01:27:55 +00:00
case nameof(ETransport.kcp):
2023-05-07 08:35:46 +00:00
KcpSettings4Ray kcpSettings = new()
2023-04-23 12:21:52 +00:00
{
mtu = _config.KcpItem.Mtu,
tti = _config.KcpItem.Tti
2023-04-23 12:21:52 +00:00
};
kcpSettings.uplinkCapacity = _config.KcpItem.UplinkCapacity;
kcpSettings.downlinkCapacity = _config.KcpItem.DownlinkCapacity;
2023-04-23 12:21:52 +00:00
kcpSettings.congestion = _config.KcpItem.Congestion;
kcpSettings.readBufferSize = _config.KcpItem.ReadBufferSize;
kcpSettings.writeBufferSize = _config.KcpItem.WriteBufferSize;
2023-05-07 08:35:46 +00:00
kcpSettings.header = new Header4Ray
2023-04-23 12:21:52 +00:00
{
type = node.HeaderType
2023-04-23 12:21:52 +00:00
};
if (Utils.IsNotEmpty(node.Path))
2023-04-23 12:21:52 +00:00
{
kcpSettings.seed = node.Path;
2023-04-23 12:21:52 +00:00
}
streamSettings.kcpSettings = kcpSettings;
break;
//ws
2024-03-09 01:27:55 +00:00
case nameof(ETransport.ws):
2023-05-07 08:35:46 +00:00
WsSettings4Ray wsSettings = new();
wsSettings.headers = new Headers4Ray();
string path = node.Path;
2024-09-17 08:52:41 +00:00
if (Utils.IsNotEmpty(host))
2023-04-23 12:21:52 +00:00
{
wsSettings.headers.Host = host;
}
2024-09-17 08:52:41 +00:00
if (Utils.IsNotEmpty(path))
2023-04-23 12:21:52 +00:00
{
wsSettings.path = path;
}
2024-09-17 08:52:41 +00:00
if (Utils.IsNotEmpty(useragent))
2023-04-23 12:21:52 +00:00
{
wsSettings.headers.UserAgent = useragent;
}
streamSettings.wsSettings = wsSettings;
2024-03-12 01:05:59 +00:00
break;
//httpupgrade
case nameof(ETransport.httpupgrade):
HttpupgradeSettings4Ray httpupgradeSettings = new();
if (Utils.IsNotEmpty(node.Path))
2024-03-12 01:05:59 +00:00
{
httpupgradeSettings.path = node.Path;
2024-03-12 01:05:59 +00:00
}
2024-09-17 08:52:41 +00:00
if (Utils.IsNotEmpty(host))
2024-03-12 01:05:59 +00:00
{
httpupgradeSettings.host = host;
}
streamSettings.httpupgradeSettings = httpupgradeSettings;
break;
2024-11-22 12:56:34 +00:00
//xhttp
2024-11-13 11:48:44 +00:00
case nameof(ETransport.xhttp):
streamSettings.network = ETransport.xhttp.ToString();
XhttpSettings4Ray xhttpSettings = new()
{
2024-11-13 11:48:44 +00:00
scMaxEachPostBytes = "500000-1000000",
scMaxConcurrentPosts = "50-100",
scMinPostsIntervalMs = "30-50"
};
if (Utils.IsNotEmpty(node.Path))
{
2024-11-13 11:48:44 +00:00
xhttpSettings.path = node.Path;
}
2024-09-17 08:52:41 +00:00
if (Utils.IsNotEmpty(host))
{
2024-11-13 11:48:44 +00:00
xhttpSettings.host = host;
}
if (Utils.IsNotEmpty(node.HeaderType) && Global.XhttpMode.Contains(node.HeaderType))
{
xhttpSettings.mode = node.HeaderType;
}
if (Utils.IsNotEmpty(node.Extra))
{
xhttpSettings.extra = JsonUtils.ParseJson(node.Extra);
}
2024-11-13 11:48:44 +00:00
streamSettings.xhttpSettings = xhttpSettings;
2023-04-23 12:21:52 +00:00
break;
//h2
2024-03-09 01:27:55 +00:00
case nameof(ETransport.h2):
2023-05-07 08:35:46 +00:00
HttpSettings4Ray httpSettings = new();
2023-04-23 12:21:52 +00:00
2024-09-17 08:52:41 +00:00
if (Utils.IsNotEmpty(host))
2023-04-23 12:21:52 +00:00
{
2024-03-26 06:26:03 +00:00
httpSettings.host = Utils.String2List(host);
2023-04-23 12:21:52 +00:00
}
httpSettings.path = node.Path;
2023-04-23 12:21:52 +00:00
streamSettings.httpSettings = httpSettings;
break;
//quic
2024-03-09 01:27:55 +00:00
case nameof(ETransport.quic):
2023-05-07 08:35:46 +00:00
QuicSettings4Ray quicsettings = new()
2023-04-23 12:21:52 +00:00
{
security = host,
key = node.Path,
2023-05-07 08:35:46 +00:00
header = new Header4Ray
2023-04-23 12:21:52 +00:00
{
type = node.HeaderType
2023-04-23 12:21:52 +00:00
}
};
streamSettings.quicSettings = quicsettings;
if (node.StreamSecurity == Global.StreamSecurity)
2023-04-23 12:21:52 +00:00
{
2024-09-17 08:52:41 +00:00
if (Utils.IsNotEmpty(sni))
2023-04-23 12:21:52 +00:00
{
streamSettings.tlsSettings.serverName = sni;
}
else
{
streamSettings.tlsSettings.serverName = node.Address;
2023-04-23 12:21:52 +00:00
}
}
break;
2024-03-09 01:27:55 +00:00
case nameof(ETransport.grpc):
2023-05-07 08:35:46 +00:00
GrpcSettings4Ray grpcSettings = new()
2023-04-23 12:21:52 +00:00
{
2024-03-26 06:26:03 +00:00
authority = Utils.IsNullOrEmpty(host) ? null : host,
serviceName = node.Path,
multiMode = node.HeaderType == Global.GrpcMultiMode,
idle_timeout = _config.GrpcItem.IdleTimeout,
health_check_timeout = _config.GrpcItem.HealthCheckTimeout,
permit_without_stream = _config.GrpcItem.PermitWithoutStream,
initial_windows_size = _config.GrpcItem.InitialWindowsSize,
2023-04-23 12:21:52 +00:00
};
streamSettings.grpcSettings = grpcSettings;
break;
default:
//tcp
if (node.HeaderType == Global.TcpHeaderHttp)
2023-04-23 12:21:52 +00:00
{
2023-05-07 08:35:46 +00:00
TcpSettings4Ray tcpSettings = new()
2023-04-23 12:21:52 +00:00
{
2023-05-07 08:35:46 +00:00
header = new Header4Ray
2023-04-23 12:21:52 +00:00
{
type = node.HeaderType
2023-04-23 12:21:52 +00:00
}
};
//request Host
2024-03-26 06:26:03 +00:00
string request = Utils.GetEmbedText(Global.V2raySampleHttpRequestFileName);
2023-04-23 12:21:52 +00:00
string[] arrHost = host.Split(',');
2024-11-17 06:11:17 +00:00
string host2 = string.Join(",".AppendQuotes(), arrHost);
request = request.Replace("$requestHost$", $"{host2.AppendQuotes()}");
request = request.Replace("$requestUserAgent$", $"{useragent.AppendQuotes()}");
2023-04-23 12:21:52 +00:00
//Path
string pathHttp = @"/";
if (Utils.IsNotEmpty(node.Path))
2023-04-23 12:21:52 +00:00
{
string[] arrPath = node.Path.Split(',');
2024-11-17 06:11:17 +00:00
pathHttp = string.Join(",".AppendQuotes(), arrPath);
2023-04-23 12:21:52 +00:00
}
2024-11-17 06:11:17 +00:00
request = request.Replace("$requestPath$", $"{pathHttp.AppendQuotes()}");
2024-03-26 06:26:03 +00:00
tcpSettings.header.request = JsonUtils.Deserialize<object>(request);
2023-04-23 12:21:52 +00:00
streamSettings.tcpSettings = tcpSettings;
}
break;
}
}
catch (Exception ex)
{
2024-01-10 02:43:48 +00:00
Logging.SaveLog(ex.Message, ex);
2023-04-23 12:21:52 +00:00
}
return 0;
}
2024-10-21 01:45:33 +00:00
public async Task<int> GenDns(ProfileItem? node, V2rayConfig v2rayConfig)
2023-04-23 12:21:52 +00:00
{
try
{
2024-10-21 01:45:33 +00:00
var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
var normalDNS = item?.NormalDNS;
var domainStrategy4Freedom = item?.DomainStrategy4Freedom;
2024-03-26 06:26:03 +00:00
if (Utils.IsNullOrEmpty(normalDNS))
2023-04-23 12:21:52 +00:00
{
normalDNS = Utils.GetEmbedText(Global.DNSV2rayNormalFileName);
2023-04-23 12:21:52 +00:00
}
//Outbound Freedom domainStrategy
2024-09-17 08:52:41 +00:00
if (Utils.IsNotEmpty(domainStrategy4Freedom))
2023-04-23 12:21:52 +00:00
{
var outbound = v2rayConfig.outbounds[1];
outbound.settings.domainStrategy = domainStrategy4Freedom;
2023-04-23 12:21:52 +00:00
outbound.settings.userLevel = 0;
}
2024-03-26 06:26:03 +00:00
var obj = JsonUtils.ParseJson(normalDNS);
if (obj is null)
2023-04-23 12:21:52 +00:00
{
2024-01-13 08:52:42 +00:00
List<string> servers = [];
string[] arrDNS = normalDNS.Split(',');
2023-04-23 12:21:52 +00:00
foreach (string str in arrDNS)
{
servers.Add(str);
}
2024-03-26 06:26:03 +00:00
obj = JsonUtils.ParseJson("{}");
obj["servers"] = JsonUtils.SerializeToNode(servers);
}
2023-12-01 09:03:49 +00:00
// 追加至 dns 设置
if (item.UseSystemHosts)
{
2024-03-26 06:26:03 +00:00
var systemHosts = Utils.GetSystemHosts();
if (systemHosts.Count > 0)
2023-04-23 12:21:52 +00:00
{
var normalHost = obj["hosts"];
if (normalHost != null)
{
foreach (var host in systemHosts)
{
if (normalHost[host.Key] != null)
continue;
normalHost[host.Key] = host.Value;
}
}
}
2023-04-23 12:21:52 +00:00
}
2023-12-01 09:03:49 +00:00
2024-10-21 01:45:33 +00:00
await GenDnsDomains(node, obj, item);
2024-06-26 08:00:37 +00:00
v2rayConfig.dns = obj;
2023-04-23 12:21:52 +00:00
}
catch (Exception ex)
{
2024-01-10 02:43:48 +00:00
Logging.SaveLog(ex.Message, ex);
2023-04-23 12:21:52 +00:00
}
return 0;
}
2024-10-21 01:45:33 +00:00
public async Task<int> GenDnsDomains(ProfileItem? node, JsonNode dns, DNSItem? dNSItem)
2024-06-26 08:00:37 +00:00
{
2024-07-21 03:26:10 +00:00
if (node == null)
{ return 0; }
2024-06-26 08:00:37 +00:00
var servers = dns["servers"];
if (servers != null)
{
if (Utils.IsDomain(node.Address))
2024-06-26 08:00:37 +00:00
{
var dnsServer = new DnsServer4Ray()
{
address = Utils.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.DomainDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress,
domains = [node.Address]
2024-06-26 08:00:37 +00:00
};
servers.AsArray().Add(JsonUtils.SerializeToNode(dnsServer));
2024-06-26 08:00:37 +00:00
}
}
return 0;
}
2024-10-21 01:45:33 +00:00
public async Task<int> GenStatistic(V2rayConfig v2rayConfig)
2023-04-23 12:21:52 +00:00
{
if (_config.GuiItem.EnableStatistics)
2023-04-23 12:21:52 +00:00
{
2024-03-09 06:30:39 +00:00
string tag = EInboundProtocol.api.ToString();
Metrics4Ray apiObj = new();
2023-05-07 08:35:46 +00:00
Policy4Ray policyObj = new();
SystemPolicy4Ray policySystemSetting = new();
2023-04-23 12:21:52 +00:00
2023-05-07 08:35:46 +00:00
v2rayConfig.stats = new Stats4Ray();
2023-04-23 12:21:52 +00:00
apiObj.tag = tag;
v2rayConfig.metrics = apiObj;
2023-04-23 12:21:52 +00:00
policySystemSetting.statsOutboundDownlink = true;
policySystemSetting.statsOutboundUplink = true;
policyObj.system = policySystemSetting;
v2rayConfig.policy = policyObj;
if (!v2rayConfig.inbounds.Exists(item => item.tag == tag))
{
2023-05-07 08:35:46 +00:00
Inbounds4Ray apiInbound = new();
Inboundsettings4Ray apiInboundSettings = new();
2023-04-23 12:21:52 +00:00
apiInbound.tag = tag;
apiInbound.listen = Global.Loopback;
2024-10-07 01:51:41 +00:00
apiInbound.port = AppHandler.Instance.StatePort;
2024-02-19 09:43:36 +00:00
apiInbound.protocol = Global.InboundAPIProtocol;
2023-04-23 12:21:52 +00:00
apiInboundSettings.address = Global.Loopback;
apiInbound.settings = apiInboundSettings;
v2rayConfig.inbounds.Add(apiInbound);
}
if (!v2rayConfig.routing.rules.Exists(item => item.outboundTag == tag))
{
2023-05-07 08:35:46 +00:00
RulesItem4Ray apiRoutingRule = new()
2023-04-23 12:21:52 +00:00
{
inboundTag = new List<string> { tag },
outboundTag = tag,
type = "field"
};
2023-05-07 08:35:46 +00:00
2023-04-23 12:21:52 +00:00
v2rayConfig.routing.rules.Add(apiRoutingRule);
}
}
return 0;
}
2024-10-21 01:45:33 +00:00
private async Task<int> GenMoreOutbounds(ProfileItem node, V2rayConfig v2rayConfig)
2023-12-23 12:57:31 +00:00
{
//fragment proxy
if (_config.CoreBasicItem.EnableFragment
2024-09-17 08:52:41 +00:00
&& Utils.IsNotEmpty(v2rayConfig.outbounds[0].streamSettings?.security))
{
var fragmentOutbound = new Outbounds4Ray
{
protocol = "freedom",
tag = $"{Global.ProxyTag}3",
settings = new()
{
fragment = new()
{
packets = "tlshello",
length = "100-200",
interval = "10-20"
}
}
};
v2rayConfig.outbounds.Add(fragmentOutbound);
v2rayConfig.outbounds[0].streamSettings.sockopt = new()
{
dialerProxy = fragmentOutbound.tag
};
return 0;
}
if (node.Subid.IsNullOrEmpty())
2023-12-23 12:57:31 +00:00
{
return 0;
}
try
{
var subItem = await AppHandler.Instance.GetSubItem(node.Subid);
2023-12-23 12:57:31 +00:00
if (subItem is null)
{
return 0;
}
//current proxy
var outbound = v2rayConfig.outbounds[0];
2024-03-26 06:26:03 +00:00
var txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound);
2023-12-23 12:57:31 +00:00
//Previous proxy
var prevNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.PrevProfile);
2023-12-25 08:42:23 +00:00
if (prevNode is not null
&& prevNode.ConfigType != EConfigType.Custom
&& prevNode.ConfigType != EConfigType.Hysteria2
&& prevNode.ConfigType != EConfigType.TUIC
&& prevNode.ConfigType != EConfigType.WireGuard)
2023-12-23 12:57:31 +00:00
{
2024-03-26 06:26:03 +00:00
var prevOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
2024-10-21 01:45:33 +00:00
await GenOutbound(prevNode, prevOutbound);
2023-12-23 12:57:31 +00:00
prevOutbound.tag = $"{Global.ProxyTag}2";
v2rayConfig.outbounds.Add(prevOutbound);
outbound.streamSettings.sockopt = new()
{
dialerProxy = prevOutbound.tag
};
}
//Next proxy
var nextNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.NextProfile);
2023-12-25 08:42:23 +00:00
if (nextNode is not null
&& nextNode.ConfigType != EConfigType.Custom
&& nextNode.ConfigType != EConfigType.Hysteria2
&& nextNode.ConfigType != EConfigType.TUIC
&& nextNode.ConfigType != EConfigType.WireGuard)
2023-12-23 12:57:31 +00:00
{
2024-03-26 06:26:03 +00:00
var nextOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
2024-10-21 01:45:33 +00:00
await GenOutbound(nextNode, nextOutbound);
2023-12-23 12:57:31 +00:00
nextOutbound.tag = Global.ProxyTag;
v2rayConfig.outbounds.Insert(0, nextOutbound);
outbound.tag = $"{Global.ProxyTag}1";
nextOutbound.streamSettings.sockopt = new()
{
dialerProxy = outbound.tag
};
}
}
catch (Exception ex)
{
2024-01-10 02:43:48 +00:00
Logging.SaveLog(ex.Message, ex);
2023-12-23 12:57:31 +00:00
}
return 0;
}
#endregion private gen function
2023-04-23 12:21:52 +00:00
}
}