mirror of
https://github.com/2dust/v2rayN.git
synced 2025-10-13 20:09:12 +00:00
Add Proxy Chain support
This commit is contained in:
parent
c98566f270
commit
3d8559d06d
4 changed files with 308 additions and 16 deletions
|
@ -23,16 +23,23 @@ public partial class CoreConfigSingboxService(Config config)
|
|||
ret.Msg = ResUI.CheckServerSettings;
|
||||
return ret;
|
||||
}
|
||||
if (node.ConfigType is EConfigType.PolicyGroup)
|
||||
var childProfiles = (await Task.WhenAll(
|
||||
Utils.String2List(profileGroupItem.ChildItems)
|
||||
.Where(p => !p.IsNullOrEmpty())
|
||||
.Select(AppManager.Instance.GetProfileItem)
|
||||
)).Where(p => p != null).ToList();
|
||||
if (childProfiles.Count <= 0)
|
||||
{
|
||||
var childProfiles = (await Task.WhenAll(
|
||||
Utils.String2List(profileGroupItem.ChildItems)
|
||||
.Where(p => !p.IsNullOrEmpty())
|
||||
.Select(AppManager.Instance.GetProfileItem)
|
||||
)).Where(p => p != null).ToList();
|
||||
return await GenerateClientMultipleLoadConfig(childProfiles);
|
||||
ret.Msg = ResUI.CheckServerSettings;
|
||||
return ret;
|
||||
}
|
||||
switch (node.ConfigType)
|
||||
{
|
||||
case EConfigType.PolicyGroup:
|
||||
return await GenerateClientMultipleLoadConfig(childProfiles);
|
||||
case EConfigType.ProxyChain:
|
||||
return await GenerateClientChainConfig(childProfiles);
|
||||
}
|
||||
// TODO proxy chain
|
||||
}
|
||||
|
||||
if (node == null
|
||||
|
@ -457,6 +464,99 @@ public partial class CoreConfigSingboxService(Config config)
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<RetResult> GenerateClientChainConfig(List<ProfileItem> selecteds)
|
||||
{
|
||||
var ret = new RetResult();
|
||||
try
|
||||
{
|
||||
if (_config == null)
|
||||
{
|
||||
ret.Msg = ResUI.CheckServerSettings;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret.Msg = ResUI.InitialConfiguration;
|
||||
|
||||
var result = EmbedUtils.GetEmbedText(Global.SingboxSampleClient);
|
||||
var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
|
||||
if (result.IsNullOrEmpty() || txtOutbound.IsNullOrEmpty())
|
||||
{
|
||||
ret.Msg = ResUI.FailedGetDefaultConfiguration;
|
||||
return ret;
|
||||
}
|
||||
|
||||
var singboxConfig = JsonUtils.Deserialize<SingboxConfig>(result);
|
||||
if (singboxConfig == null)
|
||||
{
|
||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||
return ret;
|
||||
}
|
||||
|
||||
await GenLog(singboxConfig);
|
||||
await GenInbounds(singboxConfig);
|
||||
await GenRouting(singboxConfig);
|
||||
await GenExperimental(singboxConfig);
|
||||
singboxConfig.outbounds.RemoveAt(0);
|
||||
|
||||
var proxyProfiles = new List<ProfileItem>();
|
||||
foreach (var it in selecteds)
|
||||
{
|
||||
if (!Global.SingboxSupportConfigType.Contains(it.ConfigType))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (it.Port <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var item = await AppManager.Instance.GetProfileItem(it.IndexId);
|
||||
if (item is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS)
|
||||
{
|
||||
if (item.Id.IsNullOrEmpty() || !Utils.IsGuidByParse(item.Id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (item.ConfigType == EConfigType.Shadowsocks
|
||||
&& !Global.SsSecuritiesInSingbox.Contains(item.Security))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (item.ConfigType == EConfigType.VLESS && !Global.Flows.Contains(item.Flow))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//outbound
|
||||
proxyProfiles.Add(item);
|
||||
}
|
||||
if (proxyProfiles.Count <= 0)
|
||||
{
|
||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||
return ret;
|
||||
}
|
||||
await GenChainOutboundsList(proxyProfiles, singboxConfig);
|
||||
|
||||
await GenDns(null, singboxConfig);
|
||||
await ConvertGeo2Ruleset(singboxConfig);
|
||||
|
||||
ret.Success = true;
|
||||
|
||||
ret.Data = await ApplyFullConfigTemplate(singboxConfig);
|
||||
return ret;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(_tag, ex);
|
||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RetResult> GenerateClientCustomConfig(ProfileItem node, string? fileName)
|
||||
{
|
||||
var ret = new RetResult();
|
||||
|
|
|
@ -574,4 +574,52 @@ public partial class CoreConfigSingboxService
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private async Task<int> GenChainOutboundsList(List<ProfileItem> nodes, SingboxConfig singboxConfig)
|
||||
{
|
||||
var resultOutbounds = new List<Outbound4Sbox>();
|
||||
var resultEndpoints = new List<Endpoints4Sbox>(); // For endpoints
|
||||
for (var i = 0; i < nodes.Count; i++)
|
||||
{
|
||||
var node = nodes[i];
|
||||
var server = await GenServer(node);
|
||||
|
||||
if (server is null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
server.tag = Global.ProxyTag;
|
||||
}
|
||||
else
|
||||
{
|
||||
server.tag = Global.ProxyTag + i.ToString();
|
||||
}
|
||||
|
||||
if (i != nodes.Count - 1)
|
||||
{
|
||||
server.detour = Global.ProxyTag + (i + 1).ToString();
|
||||
}
|
||||
|
||||
if (server is Endpoints4Sbox endpoint)
|
||||
{
|
||||
resultEndpoints.Add(endpoint);
|
||||
}
|
||||
else if (server is Outbound4Sbox outbound)
|
||||
{
|
||||
resultOutbounds.Add(outbound);
|
||||
}
|
||||
}
|
||||
singboxConfig.outbounds ??= new();
|
||||
resultOutbounds.AddRange(singboxConfig.outbounds);
|
||||
singboxConfig.outbounds = resultOutbounds;
|
||||
|
||||
singboxConfig.endpoints ??= new();
|
||||
resultEndpoints.AddRange(singboxConfig.endpoints);
|
||||
singboxConfig.endpoints = resultEndpoints;
|
||||
|
||||
return await Task.FromResult(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,16 +23,23 @@ public partial class CoreConfigV2rayService(Config config)
|
|||
ret.Msg = ResUI.CheckServerSettings;
|
||||
return ret;
|
||||
}
|
||||
if (node.ConfigType is EConfigType.PolicyGroup)
|
||||
var childProfiles = (await Task.WhenAll(
|
||||
Utils.String2List(profileGroupItem.ChildItems)
|
||||
.Where(p => !p.IsNullOrEmpty())
|
||||
.Select(AppManager.Instance.GetProfileItem)
|
||||
)).Where(p => p != null).ToList();
|
||||
if (childProfiles.Count <= 0)
|
||||
{
|
||||
var childProfiles = (await Task.WhenAll(
|
||||
Utils.String2List(profileGroupItem.ChildItems)
|
||||
.Where(p => !p.IsNullOrEmpty())
|
||||
.Select(AppManager.Instance.GetProfileItem)
|
||||
)).Where(p => p != null).ToList();
|
||||
return await GenerateClientMultipleLoadConfig(childProfiles, profileGroupItem.MultipleLoad);
|
||||
ret.Msg = ResUI.CheckServerSettings;
|
||||
return ret;
|
||||
}
|
||||
switch (node.ConfigType)
|
||||
{
|
||||
case EConfigType.PolicyGroup:
|
||||
return await GenerateClientMultipleLoadConfig(childProfiles, profileGroupItem.MultipleLoad);
|
||||
case EConfigType.ProxyChain:
|
||||
return await GenerateClientChainConfig(childProfiles);
|
||||
}
|
||||
// TODO proxy chain
|
||||
}
|
||||
|
||||
if (node == null
|
||||
|
@ -217,6 +224,98 @@ public partial class CoreConfigV2rayService(Config config)
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<RetResult> GenerateClientChainConfig(List<ProfileItem> selecteds)
|
||||
{
|
||||
var ret = new RetResult();
|
||||
|
||||
try
|
||||
{
|
||||
if (_config == null)
|
||||
{
|
||||
ret.Msg = ResUI.CheckServerSettings;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret.Msg = ResUI.InitialConfiguration;
|
||||
|
||||
string result = EmbedUtils.GetEmbedText(Global.V2raySampleClient);
|
||||
string txtOutbound = EmbedUtils.GetEmbedText(Global.V2raySampleOutbound);
|
||||
if (result.IsNullOrEmpty() || txtOutbound.IsNullOrEmpty())
|
||||
{
|
||||
ret.Msg = ResUI.FailedGetDefaultConfiguration;
|
||||
return ret;
|
||||
}
|
||||
|
||||
var v2rayConfig = JsonUtils.Deserialize<V2rayConfig>(result);
|
||||
if (v2rayConfig == null)
|
||||
{
|
||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||
return ret;
|
||||
}
|
||||
|
||||
await GenLog(v2rayConfig);
|
||||
await GenInbounds(v2rayConfig);
|
||||
await GenRouting(v2rayConfig);
|
||||
await GenDns(null, v2rayConfig);
|
||||
await GenStatistic(v2rayConfig);
|
||||
v2rayConfig.outbounds.RemoveAt(0);
|
||||
|
||||
var proxyProfiles = new List<ProfileItem>();
|
||||
foreach (var it in selecteds)
|
||||
{
|
||||
if (!Global.XraySupportConfigType.Contains(it.ConfigType))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (it.Port <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var item = await AppManager.Instance.GetProfileItem(it.IndexId);
|
||||
if (item is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS)
|
||||
{
|
||||
if (item.Id.IsNullOrEmpty() || !Utils.IsGuidByParse(item.Id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (item.ConfigType == EConfigType.Shadowsocks
|
||||
&& !Global.SsSecuritiesInSingbox.Contains(item.Security))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (item.ConfigType == EConfigType.VLESS && !Global.Flows.Contains(item.Flow))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//outbound
|
||||
proxyProfiles.Add(item);
|
||||
}
|
||||
if (proxyProfiles.Count <= 0)
|
||||
{
|
||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||
return ret;
|
||||
}
|
||||
await GenChainOutboundsList(proxyProfiles, v2rayConfig);
|
||||
|
||||
ret.Success = true;
|
||||
|
||||
ret.Data = await ApplyFullConfigTemplate(v2rayConfig);
|
||||
return ret;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(_tag, ex);
|
||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RetResult> GenerateClientSpeedtestConfig(List<ServerTestItem> selecteds)
|
||||
{
|
||||
var ret = new RetResult();
|
||||
|
|
|
@ -692,4 +692,49 @@ public partial class CoreConfigV2rayService
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private async Task<int> GenChainOutboundsList(List<ProfileItem> nodes, V2rayConfig v2RayConfig)
|
||||
{
|
||||
var resultOutbounds = new List<Outbounds4Ray>();
|
||||
for (var i = 0; i < nodes.Count; i++)
|
||||
{
|
||||
var node = nodes[i];
|
||||
var txtOutbound = EmbedUtils.GetEmbedText(Global.V2raySampleOutbound);
|
||||
if (txtOutbound.IsNullOrEmpty())
|
||||
{
|
||||
break;
|
||||
}
|
||||
var outbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
|
||||
var result = await GenOutbound(node, outbound);
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
outbound.tag = Global.ProxyTag;
|
||||
}
|
||||
else
|
||||
{
|
||||
outbound.tag = Global.ProxyTag + i.ToString();
|
||||
}
|
||||
|
||||
if (i != nodes.Count - 1)
|
||||
{
|
||||
outbound.streamSettings.sockopt = new()
|
||||
{
|
||||
dialerProxy = Global.ProxyTag + (i + 1).ToString()
|
||||
};
|
||||
}
|
||||
|
||||
resultOutbounds.Add(outbound);
|
||||
}
|
||||
v2RayConfig.outbounds ??= new();
|
||||
resultOutbounds.AddRange(v2RayConfig.outbounds);
|
||||
v2RayConfig.outbounds = resultOutbounds;
|
||||
|
||||
return await Task.FromResult(0);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue