mirror of
https://github.com/2dust/v2rayN.git
synced 2025-10-27 18:42:52 +00:00
add xray core leastPing support
This commit is contained in:
parent
6ad0762731
commit
dc3200f0a6
6 changed files with 146 additions and 18 deletions
10
v2rayN/ServiceLib/Enums/EMultipleLoad.cs
Normal file
10
v2rayN/ServiceLib/Enums/EMultipleLoad.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
namespace ServiceLib.Enums
|
||||||
|
{
|
||||||
|
public enum EMultipleLoad
|
||||||
|
{
|
||||||
|
Random,
|
||||||
|
RoundRobin,
|
||||||
|
LeastPing,
|
||||||
|
LeastLoad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1005,12 +1005,33 @@ namespace ServiceLib.Handler
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<RetResult> AddCustomServer4Multiple(Config config, List<ProfileItem> selecteds, ECoreType coreType)
|
public static async Task<RetResult> AddCustomServer4Multiple(Config config, List<ProfileItem> selecteds, EMultipleLoad multipleLoad)
|
||||||
{
|
{
|
||||||
var indexId = Utils.GetMd5(Global.CoreMultipleLoadConfigFileName);
|
var indexId = Utils.GetMd5(Global.CoreMultipleLoadConfigFileName);
|
||||||
var configPath = Utils.GetConfigPath(Global.CoreMultipleLoadConfigFileName);
|
var configPath = Utils.GetConfigPath(Global.CoreMultipleLoadConfigFileName);
|
||||||
|
|
||||||
var result = await CoreConfigHandler.GenerateClientMultipleLoadConfig(config, configPath, selecteds, coreType);
|
var coreType = AppHandler.Instance.Config.CoreTypeItem?.FirstOrDefault(it => it.ConfigType == EConfigType.Custom)?.CoreType ?? ECoreType.Xray;
|
||||||
|
if (multipleLoad == EMultipleLoad.LeastPing && coreType == ECoreType.Xray)
|
||||||
|
{
|
||||||
|
var support = selecteds.All(it => it.ConfigType is
|
||||||
|
EConfigType.VMess or
|
||||||
|
EConfigType.VLESS or
|
||||||
|
EConfigType.Trojan or
|
||||||
|
EConfigType.Shadowsocks or
|
||||||
|
EConfigType.SOCKS or
|
||||||
|
EConfigType.HTTP or
|
||||||
|
EConfigType.WireGuard);
|
||||||
|
if (!support)
|
||||||
|
{
|
||||||
|
coreType = ECoreType.sing_box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (multipleLoad == EMultipleLoad.RoundRobin)
|
||||||
|
{
|
||||||
|
coreType = ECoreType.Xray;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = await CoreConfigHandler.GenerateClientMultipleLoadConfig(config, configPath, selecteds, coreType, multipleLoad);
|
||||||
if (result.Success != true)
|
if (result.Success != true)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
using DynamicData;
|
||||||
|
using ServiceLib.Enums;
|
||||||
|
using ServiceLib.Models;
|
||||||
|
|
||||||
namespace ServiceLib.Handler
|
namespace ServiceLib.Handler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -133,16 +137,23 @@ namespace ServiceLib.Handler
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<RetResult> GenerateClientMultipleLoadConfig(Config config, string fileName, List<ProfileItem> selecteds, ECoreType coreType)
|
public static async Task<RetResult> GenerateClientMultipleLoadConfig(Config config, string fileName, List<ProfileItem> selecteds, ECoreType coreType, EMultipleLoad multipleLoad)
|
||||||
{
|
{
|
||||||
var result = new RetResult();
|
var result = new RetResult();
|
||||||
if (coreType == ECoreType.sing_box)
|
if (multipleLoad == EMultipleLoad.RoundRobin)
|
||||||
{
|
{
|
||||||
result = await new CoreConfigSingboxService(config).GenerateClientMultipleLoadConfig(selecteds);
|
result = await new CoreConfigV2rayService(config).GenerateClientMultipleRoundRobinConfig(selecteds);
|
||||||
}
|
}
|
||||||
else if (coreType == ECoreType.Xray)
|
else
|
||||||
{
|
{
|
||||||
result = await new CoreConfigV2rayService(config).GenerateClientMultipleLoadConfig(selecteds);
|
if (coreType == ECoreType.sing_box)
|
||||||
|
{
|
||||||
|
result = await new CoreConfigSingboxService(config).GenerateClientMultipleLoadConfig(selecteds);
|
||||||
|
}
|
||||||
|
else if (coreType == ECoreType.Xray)
|
||||||
|
{
|
||||||
|
result = await new CoreConfigV2rayService(config).GenerateClientMultipleLeastPingConfig(selecteds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.Success != true)
|
if (result.Success != true)
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ namespace ServiceLib.Models
|
||||||
public Metrics4Ray? metrics { get; set; }
|
public Metrics4Ray? metrics { get; set; }
|
||||||
public Policy4Ray? policy { get; set; }
|
public Policy4Ray? policy { get; set; }
|
||||||
public Stats4Ray? stats { get; set; }
|
public Stats4Ray? stats { get; set; }
|
||||||
|
public Observatory4Ray? observatory { get; set; }
|
||||||
|
public BurstObservatory4Ray? burstObservatory { get; set; }
|
||||||
public string? remarks { get; set; }
|
public string? remarks { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -232,6 +234,46 @@ namespace ServiceLib.Models
|
||||||
public class BalancersStrategy4Ray
|
public class BalancersStrategy4Ray
|
||||||
{
|
{
|
||||||
public string? type { get; set; }
|
public string? type { get; set; }
|
||||||
|
public BalancersStrategySettings4Ray? settings { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BalancersStrategySettings4Ray
|
||||||
|
{
|
||||||
|
public int? expected { get; set; }
|
||||||
|
public string? maxRTT { get; set; }
|
||||||
|
public float? tolerance { get; set; }
|
||||||
|
public List<string>? baselines { get; set; }
|
||||||
|
public List<BalancersStrategySettingsCosts4Ray>? costs { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BalancersStrategySettingsCosts4Ray
|
||||||
|
{
|
||||||
|
public bool? regexp { get; set; }
|
||||||
|
public string? match { get; set; }
|
||||||
|
public float? value { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Observatory4Ray
|
||||||
|
{
|
||||||
|
public List<string>? subjectSelector { get; set; }
|
||||||
|
public string? probeUrl { get; set; }
|
||||||
|
public string? probeInterval { get; set; }
|
||||||
|
public bool? enableConcurrency { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BurstObservatory4Ray
|
||||||
|
{
|
||||||
|
public List<string>? subjectSelector { get; set; }
|
||||||
|
public BurstObservatoryPingConfig4Ray? pingConfig { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BurstObservatoryPingConfig4Ray
|
||||||
|
{
|
||||||
|
public string? destination { get; set; }
|
||||||
|
public string? connectivity { get; set; }
|
||||||
|
public string? interval { get; set; }
|
||||||
|
public int? sampling { get; set; }
|
||||||
|
public string? timeout { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StreamSettings4Ray
|
public class StreamSettings4Ray
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,17 @@ namespace ServiceLib.Services.CoreConfig
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RetResult> GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds)
|
public async Task<RetResult> GenerateClientMultipleRoundRobinConfig(List<ProfileItem> selecteds)
|
||||||
|
{
|
||||||
|
return await GenerateClientMultipleLoadConfig(selecteds, EMultipleLoad.RoundRobin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RetResult> GenerateClientMultipleLeastPingConfig(List<ProfileItem> selecteds)
|
||||||
|
{
|
||||||
|
return await GenerateClientMultipleLoadConfig(selecteds, EMultipleLoad.LeastPing);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RetResult> GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds, EMultipleLoad multipleLoad)
|
||||||
{
|
{
|
||||||
var ret = new RetResult();
|
var ret = new RetResult();
|
||||||
|
|
||||||
|
|
@ -164,13 +174,16 @@ namespace ServiceLib.Services.CoreConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
//add balancers
|
//add balancers
|
||||||
var balancer = new BalancersItem4Ray
|
if (multipleLoad == EMultipleLoad.RoundRobin)
|
||||||
{
|
{
|
||||||
selector = [Global.ProxyTag],
|
await GenRoundRobinBalancer(v2rayConfig);
|
||||||
strategy = new() { type = "roundRobin" },
|
}
|
||||||
tag = $"{Global.ProxyTag}-round",
|
else
|
||||||
};
|
{
|
||||||
v2rayConfig.routing.balancers = [balancer];
|
await GenLeastPingBalancer(v2rayConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
var balancer = v2rayConfig.routing.balancers.First();
|
||||||
|
|
||||||
//add rule
|
//add rule
|
||||||
var rules = v2rayConfig.routing.rules.Where(t => t.outboundTag == Global.ProxyTag).ToList();
|
var rules = v2rayConfig.routing.rules.Where(t => t.outboundTag == Global.ProxyTag).ToList();
|
||||||
|
|
@ -1316,6 +1329,37 @@ namespace ServiceLib.Services.CoreConfig
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<int> GenRoundRobinBalancer(V2rayConfig v2rayConfig)
|
||||||
|
{
|
||||||
|
var balancer = new BalancersItem4Ray
|
||||||
|
{
|
||||||
|
selector = [Global.ProxyTag],
|
||||||
|
strategy = new() { type = "roundRobin" },
|
||||||
|
tag = $"{Global.ProxyTag}-round",
|
||||||
|
};
|
||||||
|
v2rayConfig.routing.balancers = [balancer];
|
||||||
|
return await Task.FromResult(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<int> GenLeastPingBalancer(V2rayConfig v2rayConfig)
|
||||||
|
{
|
||||||
|
var observatory = new Observatory4Ray
|
||||||
|
{
|
||||||
|
subjectSelector = [Global.ProxyTag],
|
||||||
|
probeUrl = AppHandler.Instance.Config.SpeedTestItem.SpeedPingTestUrl,
|
||||||
|
probeInterval = "3m"
|
||||||
|
};
|
||||||
|
var balancer = new BalancersItem4Ray
|
||||||
|
{
|
||||||
|
selector = [Global.ProxyTag],
|
||||||
|
strategy = new() { type = "leastPing" },
|
||||||
|
tag = $"{Global.ProxyTag}-round",
|
||||||
|
};
|
||||||
|
v2rayConfig.routing.balancers = [balancer];
|
||||||
|
v2rayConfig.observatory = observatory;
|
||||||
|
return await Task.FromResult(0);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion private gen function
|
#endregion private gen function
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -152,11 +152,11 @@ namespace ServiceLib.ViewModels
|
||||||
}, canEditRemove);
|
}, canEditRemove);
|
||||||
SetDefaultMultipleServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
SetDefaultMultipleServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
await SetDefaultMultipleServer(ECoreType.sing_box);
|
await SetDefaultMultipleServer(EMultipleLoad.LeastPing);
|
||||||
}, canEditRemove);
|
}, canEditRemove);
|
||||||
SetDefaultLoadBalanceServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
SetDefaultLoadBalanceServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
await SetDefaultMultipleServer(ECoreType.Xray);
|
await SetDefaultMultipleServer(EMultipleLoad.RoundRobin);
|
||||||
}, canEditRemove);
|
}, canEditRemove);
|
||||||
|
|
||||||
//servers move
|
//servers move
|
||||||
|
|
@ -621,7 +621,7 @@ namespace ServiceLib.ViewModels
|
||||||
await _updateView?.Invoke(EViewAction.ShareServer, url);
|
await _updateView?.Invoke(EViewAction.ShareServer, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SetDefaultMultipleServer(ECoreType coreType)
|
private async Task SetDefaultMultipleServer(EMultipleLoad multipleLoad)
|
||||||
{
|
{
|
||||||
var lstSelected = await GetProfileItems(true);
|
var lstSelected = await GetProfileItems(true);
|
||||||
if (lstSelected == null)
|
if (lstSelected == null)
|
||||||
|
|
@ -629,7 +629,7 @@ namespace ServiceLib.ViewModels
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var ret = await ConfigHandler.AddCustomServer4Multiple(_config, lstSelected, coreType);
|
var ret = await ConfigHandler.AddCustomServer4Multiple(_config, lstSelected, multipleLoad);
|
||||||
if (ret.Success != true)
|
if (ret.Success != true)
|
||||||
{
|
{
|
||||||
NoticeHandler.Instance.Enqueue(ResUI.OperationFailed);
|
NoticeHandler.Instance.Enqueue(ResUI.OperationFailed);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue