mirror of
https://github.com/2dust/v2rayN.git
synced 2025-08-25 20:36:55 +00:00
Merge branch '2dust:master' into master
This commit is contained in:
commit
bb88f2f76b
21 changed files with 397 additions and 408 deletions
|
@ -1,5 +1,5 @@
|
|||
# v2rayN
|
||||
A GUI client for Windows, support [Xray core](https://github.com/XTLS/Xray-core) and [v2fly core](https://github.com/v2fly/v2ray-core) and [others](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores)
|
||||
A GUI client for Windows and Linux, support [Xray core](https://github.com/XTLS/Xray-core) and [v2fly core](https://github.com/v2fly/v2ray-core) and [others](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores)
|
||||
|
||||
|
||||
[](https://github.com/2dust/v2rayN/commits/master)
|
||||
|
|
|
@ -68,6 +68,7 @@ namespace ServiceLib.Handler
|
|||
{
|
||||
ShowMsg(true, $"{node.GetSummary()}");
|
||||
await CoreStop();
|
||||
await Task.Delay(100);
|
||||
await CoreStart(node);
|
||||
|
||||
//In tun mode, do a delay check and restart the core
|
||||
|
@ -169,21 +170,12 @@ namespace ServiceLib.Handler
|
|||
ShowMsg(false, $"{Environment.OSVersion} - {(Environment.Is64BitOperatingSystem ? 64 : 32)}");
|
||||
ShowMsg(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
|
||||
|
||||
//ECoreType coreType;
|
||||
//if (node.configType != EConfigType.Custom && _config.tunModeItem.enableTun)
|
||||
//{
|
||||
// coreType = ECoreType.sing_box;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// coreType = LazyConfig.Instance.GetCoreType(node, node.configType);
|
||||
//}
|
||||
var coreType = AppHandler.Instance.GetCoreType(node, node.ConfigType);
|
||||
_config.RunningCoreType = coreType;
|
||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
|
||||
|
||||
var displayLog = node.ConfigType != EConfigType.Custom || node.DisplayLog;
|
||||
var proc = await RunProcess(coreInfo, Global.CoreConfigFileName, displayLog);
|
||||
var proc = await RunProcess(coreInfo, Global.CoreConfigFileName, displayLog, true);
|
||||
if (proc is null)
|
||||
{
|
||||
return;
|
||||
|
@ -225,7 +217,7 @@ namespace ServiceLib.Handler
|
|||
if (result.Success)
|
||||
{
|
||||
var coreInfo2 = CoreInfoHandler.Instance.GetCoreInfo(preCoreType);
|
||||
var proc2 = await RunProcess(coreInfo2, Global.CorePreConfigFileName, true);
|
||||
var proc2 = await RunProcess(coreInfo2, Global.CorePreConfigFileName, true, true);
|
||||
if (proc2 is not null)
|
||||
{
|
||||
_processPre = proc2;
|
||||
|
@ -243,7 +235,7 @@ namespace ServiceLib.Handler
|
|||
try
|
||||
{
|
||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
|
||||
var proc = await RunProcess(coreInfo, Global.CoreSpeedtestConfigFileName, true);
|
||||
var proc = await RunProcess(coreInfo, Global.CoreSpeedtestConfigFileName, true, false);
|
||||
if (proc is null)
|
||||
{
|
||||
return -1;
|
||||
|
@ -264,17 +256,28 @@ namespace ServiceLib.Handler
|
|||
_updateFunc?.Invoke(notify, msg);
|
||||
}
|
||||
|
||||
private bool IsNeedSudo(ECoreType eCoreType)
|
||||
{
|
||||
return _config.TunModeItem.EnableTun
|
||||
&& eCoreType == ECoreType.sing_box
|
||||
&& Utils.IsLinux()
|
||||
&& _config.TunModeItem.LinuxSudoPassword.IsNotEmpty()
|
||||
;
|
||||
}
|
||||
|
||||
#endregion Private
|
||||
|
||||
#region Process
|
||||
|
||||
private async Task<Process?> RunProcess(CoreInfo coreInfo, string configPath, bool displayLog)
|
||||
private async Task<Process?> RunProcess(CoreInfo coreInfo, string configPath, bool displayLog, bool mayNeedSudo)
|
||||
{
|
||||
var fileName = CoreFindExe(coreInfo);
|
||||
if (Utils.IsNullOrEmpty(fileName))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var isNeedSudo = mayNeedSudo && IsNeedSudo(coreInfo.CoreType);
|
||||
try
|
||||
{
|
||||
Process proc = new()
|
||||
|
@ -292,6 +295,15 @@ namespace ServiceLib.Handler
|
|||
StandardErrorEncoding = displayLog ? Encoding.UTF8 : null,
|
||||
}
|
||||
};
|
||||
|
||||
if (isNeedSudo)
|
||||
{
|
||||
proc.StartInfo.FileName = $"/bin/sudo";
|
||||
proc.StartInfo.Arguments = $"-S {fileName} {string.Format(coreInfo.Arguments, configPath)}";
|
||||
proc.StartInfo.StandardInputEncoding = Encoding.UTF8;
|
||||
proc.StartInfo.RedirectStandardInput = true;
|
||||
}
|
||||
|
||||
var startUpErrorMessage = new StringBuilder();
|
||||
var startUpSuccessful = false;
|
||||
if (displayLog)
|
||||
|
@ -313,6 +325,15 @@ namespace ServiceLib.Handler
|
|||
};
|
||||
}
|
||||
proc.Start();
|
||||
|
||||
if (isNeedSudo)
|
||||
{
|
||||
await Task.Delay(10);
|
||||
await proc.StandardInput.WriteLineAsync(_config.TunModeItem.LinuxSudoPassword);
|
||||
await Task.Delay(10);
|
||||
await proc.StandardInput.WriteLineAsync(_config.TunModeItem.LinuxSudoPassword);
|
||||
}
|
||||
|
||||
if (displayLog)
|
||||
{
|
||||
proc.BeginOutputReadLine();
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
private ServerStatItem? _serverStatItem;
|
||||
private List<ServerStatItem> _lstServerStat;
|
||||
private Action<ServerSpeedItem>? _updateFunc;
|
||||
private StatisticsV2rayService? _statisticsV2Ray;
|
||||
//private StatisticsV2rayService? _statisticsV2Ray;
|
||||
private StatisticsXrayService? _statisticsXray;
|
||||
private StatisticsSingboxService? _statisticsSingbox;
|
||||
|
||||
public List<ServerStatItem> ServerStat => _lstServerStat;
|
||||
|
@ -25,7 +26,8 @@
|
|||
|
||||
await InitData();
|
||||
|
||||
_statisticsV2Ray = new StatisticsV2rayService(config, UpdateServerStatHandler);
|
||||
//_statisticsV2Ray = new StatisticsV2rayService(config, UpdateServerStatHandler);
|
||||
_statisticsXray = new StatisticsXrayService(config, UpdateServerStatHandler);
|
||||
_statisticsSingbox = new StatisticsSingboxService(config, UpdateServerStatHandler);
|
||||
}
|
||||
|
||||
|
@ -33,7 +35,8 @@
|
|||
{
|
||||
try
|
||||
{
|
||||
_statisticsV2Ray?.Close();
|
||||
//_statisticsV2Ray?.Close();
|
||||
_statisticsXray?.Close();
|
||||
_statisticsSingbox?.Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
@ -161,6 +161,7 @@
|
|||
public int Mtu { get; set; }
|
||||
public bool EnableExInbound { get; set; }
|
||||
public bool EnableIPv6Address { get; set; }
|
||||
public string? LinuxSudoPassword { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
|
|
|
@ -2,60 +2,33 @@ using System.Text.Json.Serialization;
|
|||
|
||||
namespace ServiceLib.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// v2ray配置文件实体类 例子SampleConfig.txt
|
||||
/// </summary>
|
||||
public class V2rayConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Properties that do not belong to Ray
|
||||
/// </summary>
|
||||
public string? remarks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 日志配置
|
||||
/// </summary>
|
||||
public Log4Ray log { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 传入连接配置
|
||||
/// </summary>
|
||||
public List<Inbounds4Ray> inbounds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 传出连接配置
|
||||
/// </summary>
|
||||
public List<Outbounds4Ray> outbounds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 统计需要, 空对象
|
||||
/// </summary>
|
||||
public Stats4Ray stats { get; set; }
|
||||
public Stats4Ray? stats { get; set; }
|
||||
|
||||
/// </summary>
|
||||
public API4Ray api { get; set; }
|
||||
public Metrics4Ray? metrics { get; set; }
|
||||
|
||||
/// </summary>
|
||||
public Policy4Ray policy { get; set; }
|
||||
public Policy4Ray? policy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// DNS 配置
|
||||
/// </summary>
|
||||
public object dns { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 路由配置
|
||||
/// </summary>
|
||||
public Routing4Ray routing { get; set; }
|
||||
}
|
||||
|
||||
public class Stats4Ray
|
||||
{ }
|
||||
|
||||
public class API4Ray
|
||||
public class Metrics4Ray
|
||||
{
|
||||
public string tag { get; set; }
|
||||
public List<string> services { get; set; }
|
||||
}
|
||||
|
||||
public class Policy4Ray
|
||||
|
@ -71,124 +44,59 @@ namespace ServiceLib.Models
|
|||
|
||||
public class Log4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string access { get; set; }
|
||||
public string? access { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string error { get; set; }
|
||||
public string? error { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string loglevel { get; set; }
|
||||
public string? loglevel { get; set; }
|
||||
}
|
||||
|
||||
public class Inbounds4Ray
|
||||
{
|
||||
public string tag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string listen { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string protocol { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Sniffing4Ray sniffing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Inboundsettings4Ray settings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public StreamSettings4Ray streamSettings { get; set; }
|
||||
}
|
||||
|
||||
public class Inboundsettings4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string auth { get; set; }
|
||||
public string? auth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool udp { get; set; }
|
||||
public bool? udp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string ip { get; set; }
|
||||
public string? ip { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// api 使用
|
||||
/// </summary>
|
||||
public string address { get; set; }
|
||||
public string? address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public List<UsersItem4Ray> clients { get; set; }
|
||||
public List<UsersItem4Ray>? clients { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// VLESS
|
||||
/// </summary>
|
||||
public string decryption { get; set; }
|
||||
public string? decryption { get; set; }
|
||||
|
||||
public bool allowTransparent { get; set; }
|
||||
public bool? allowTransparent { get; set; }
|
||||
|
||||
public List<AccountsItem4Ray> accounts { get; set; }
|
||||
public List<AccountsItem4Ray>? accounts { get; set; }
|
||||
}
|
||||
|
||||
public class UsersItem4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string id { get; set; }
|
||||
public string? id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int alterId { get; set; }
|
||||
public int? alterId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string email { get; set; }
|
||||
public string? email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string security { get; set; }
|
||||
public string? security { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// VLESS
|
||||
/// </summary>
|
||||
public string encryption { get; set; }
|
||||
public string? encryption { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// VLESS
|
||||
/// </summary>
|
||||
public string? flow { get; set; }
|
||||
}
|
||||
|
||||
|
@ -201,57 +109,27 @@ namespace ServiceLib.Models
|
|||
|
||||
public class Outbounds4Ray
|
||||
{
|
||||
/// <summary>
|
||||
/// 默认值agentout
|
||||
/// </summary>
|
||||
public string tag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string protocol { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Outboundsettings4Ray settings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public StreamSettings4Ray streamSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Mux4Ray mux { get; set; }
|
||||
}
|
||||
|
||||
public class Outboundsettings4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public List<VnextItem4Ray>? vnext { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public List<ServersItem4Ray> servers { get; set; }
|
||||
public List<ServersItem4Ray>? servers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Response4Ray response { get; set; }
|
||||
public Response4Ray? response { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string domainStrategy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int? userLevel { get; set; }
|
||||
|
||||
public FragmentItem4Ray? fragment { get; set; }
|
||||
|
@ -259,85 +137,40 @@ namespace ServiceLib.Models
|
|||
|
||||
public class VnextItem4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public List<UsersItem4Ray> users { get; set; }
|
||||
}
|
||||
|
||||
public class ServersItem4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string? method { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool? ota { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string? password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int? level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// trojan
|
||||
/// </summary>
|
||||
public string flow { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public List<SocksUsersItem4Ray> users { get; set; }
|
||||
}
|
||||
|
||||
public class SocksUsersItem4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string user { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string pass { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int? level { get; set; }
|
||||
}
|
||||
|
||||
|
@ -351,17 +184,11 @@ namespace ServiceLib.Models
|
|||
|
||||
public class Response4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string type { get; set; }
|
||||
}
|
||||
|
||||
public class Dns4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public List<string> servers { get; set; }
|
||||
}
|
||||
|
||||
|
@ -373,19 +200,10 @@ namespace ServiceLib.Models
|
|||
|
||||
public class Routing4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string domainStrategy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string? domainMatcher { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public List<RulesItem4Ray> rules { get; set; }
|
||||
|
||||
public List<BalancersItem4Ray>? balancers { get; set; }
|
||||
|
@ -426,87 +244,39 @@ namespace ServiceLib.Models
|
|||
|
||||
public class StreamSettings4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string network { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string security { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public TlsSettings4Ray? tlsSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tcp传输额外设置
|
||||
/// </summary>
|
||||
public TcpSettings4Ray? tcpSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Kcp传输额外设置
|
||||
/// </summary>
|
||||
public KcpSettings4Ray? kcpSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ws传输额外设置
|
||||
/// </summary>
|
||||
public WsSettings4Ray? wsSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public HttpupgradeSettings4Ray? httpupgradeSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SplithttpSettings4Ray? splithttpSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// h2传输额外设置
|
||||
/// </summary>
|
||||
public HttpSettings4Ray? httpSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// QUIC
|
||||
/// </summary>
|
||||
public QuicSettings4Ray? quicSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// VLESS only
|
||||
/// </summary>
|
||||
public TlsSettings4Ray? realitySettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// grpc
|
||||
/// </summary>
|
||||
public GrpcSettings4Ray? grpcSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// sockopt
|
||||
/// </summary>
|
||||
public Sockopt4Ray? sockopt { get; set; }
|
||||
}
|
||||
|
||||
public class TlsSettings4Ray
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否允许不安全连接(用于客户端)
|
||||
/// </summary>
|
||||
public bool? allowInsecure { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string? serverName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public List<string>? alpn { get; set; }
|
||||
|
||||
public string? fingerprint { get; set; }
|
||||
|
@ -519,115 +289,58 @@ namespace ServiceLib.Models
|
|||
|
||||
public class TcpSettings4Ray
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据包头部伪装设置
|
||||
/// </summary>
|
||||
public Header4Ray header { get; set; }
|
||||
}
|
||||
|
||||
public class Header4Ray
|
||||
{
|
||||
/// <summary>
|
||||
/// 伪装
|
||||
/// </summary>
|
||||
public string type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结构复杂,直接存起来
|
||||
/// </summary>
|
||||
public object request { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结构复杂,直接存起来
|
||||
/// </summary>
|
||||
public object response { get; set; }
|
||||
}
|
||||
|
||||
public class KcpSettings4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int mtu { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int tti { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int uplinkCapacity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int downlinkCapacity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool congestion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int readBufferSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int writeBufferSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Header4Ray header { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string seed { get; set; }
|
||||
}
|
||||
|
||||
public class WsSettings4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Headers4Ray headers { get; set; }
|
||||
}
|
||||
|
||||
public class Headers4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Host { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户代理
|
||||
/// </summary>
|
||||
[JsonPropertyName("User-Agent")]
|
||||
public string UserAgent { get; set; }
|
||||
}
|
||||
|
||||
public class HttpupgradeSettings4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string? path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string? host { get; set; }
|
||||
}
|
||||
|
||||
|
@ -644,32 +357,17 @@ namespace ServiceLib.Models
|
|||
|
||||
public class HttpSettings4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string? path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public List<string>? host { get; set; }
|
||||
}
|
||||
|
||||
public class QuicSettings4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string security { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string key { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Header4Ray header { get; set; }
|
||||
}
|
||||
|
||||
|
@ -686,14 +384,8 @@ namespace ServiceLib.Models
|
|||
|
||||
public class AccountsItem4Ray
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string user { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string pass { get; set; }
|
||||
}
|
||||
|
||||
|
|
20
v2rayN/ServiceLib/Models/V2rayMetricsVars.cs
Normal file
20
v2rayN/ServiceLib/Models/V2rayMetricsVars.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using System.Collections;
|
||||
|
||||
namespace ServiceLib.Models
|
||||
{
|
||||
internal class V2rayMetricsVars
|
||||
{
|
||||
public V2rayMetricsVarsStats? stats { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
public class V2rayMetricsVarsStats
|
||||
{
|
||||
public Hashtable? outbound { get; set; }
|
||||
}
|
||||
|
||||
public class V2rayMetricsVarsLink
|
||||
{
|
||||
public long downlink { get; set; }
|
||||
public long uplink { get; set; }
|
||||
}
|
36
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
36
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
|
@ -3148,6 +3148,42 @@ namespace ServiceLib.Resx {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Linux system sudo password 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSettingsLinuxSudoPassword {
|
||||
get {
|
||||
return ResourceManager.GetString("TbSettingsLinuxSudoPassword", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Please set the sudo password in Tun mode settings first 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSettingsLinuxSudoPasswordIsEmpty {
|
||||
get {
|
||||
return ResourceManager.GetString("TbSettingsLinuxSudoPasswordIsEmpty", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Please do not run this app with sudo 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSettingsLinuxSudoPasswordNotSudoRunApp {
|
||||
get {
|
||||
return ResourceManager.GetString("TbSettingsLinuxSudoPasswordNotSudoRunApp", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 The password will only be stored in the local file. 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSettingsLinuxSudoPasswordTip {
|
||||
get {
|
||||
return ResourceManager.GetString("TbSettingsLinuxSudoPasswordTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Enable Log 的本地化字符串。
|
||||
/// </summary>
|
||||
|
|
|
@ -1369,4 +1369,16 @@
|
|||
<data name="TbRuleMatchingTips" xml:space="preserve">
|
||||
<value>(Domain or IP or ProcName) and Port and Protocol and InboundTag => OutboundTag</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPassword" xml:space="preserve">
|
||||
<value>Linux system sudo password</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
|
||||
<value>The password will only be stored in the local file.</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordIsEmpty" xml:space="preserve">
|
||||
<value>Please set the sudo password in Tun mode settings first</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordNotSudoRunApp" xml:space="preserve">
|
||||
<value>Please do not run this app with sudo</value>
|
||||
</data>
|
||||
</root>
|
|
@ -1369,4 +1369,16 @@
|
|||
<data name="LvMemo" xml:space="preserve">
|
||||
<value>Remarks Memo</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPassword" xml:space="preserve">
|
||||
<value>Linux system sudo password</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
|
||||
<value>The password will only be stored in the local file.</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordIsEmpty" xml:space="preserve">
|
||||
<value>Please set the sudo password in Tun mode settings first</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordNotSudoRunApp" xml:space="preserve">
|
||||
<value>Please do not run this app with sudo</value>
|
||||
</data>
|
||||
</root>
|
|
@ -1369,4 +1369,16 @@
|
|||
<data name="menuRemoteBackupAndRestore" xml:space="preserve">
|
||||
<value>Remote (WebDAV)</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPassword" xml:space="preserve">
|
||||
<value>Linux system sudo password</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
|
||||
<value>The password will only be stored in the local file.</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordIsEmpty" xml:space="preserve">
|
||||
<value>Please set the sudo password in Tun mode settings first</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordNotSudoRunApp" xml:space="preserve">
|
||||
<value>Please do not run this app with sudo</value>
|
||||
</data>
|
||||
</root>
|
|
@ -1366,4 +1366,16 @@
|
|||
<data name="LvMemo" xml:space="preserve">
|
||||
<value>备注备忘</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPassword" xml:space="preserve">
|
||||
<value>Linux系统的sudo密码</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
|
||||
<value>密码只会存储在本地文件中,没有密码无法开启Tun</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordIsEmpty" xml:space="preserve">
|
||||
<value>请先在Tun模式设置中设置sudo密码</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordNotSudoRunApp" xml:space="preserve">
|
||||
<value>请不要用sudo运行本app</value>
|
||||
</data>
|
||||
</root>
|
|
@ -301,7 +301,7 @@
|
|||
<value>掃描匯入分享链接成功</value>
|
||||
</data>
|
||||
<data name="TestMeOutput" xml:space="preserve">
|
||||
<value>目前服務的真連接延遲: {0} ms</value>
|
||||
<value>目前服務的真連線延遲: {0} ms</value>
|
||||
</data>
|
||||
<data name="OperationSuccess" xml:space="preserve">
|
||||
<value>操作成功</value>
|
||||
|
@ -511,7 +511,7 @@
|
|||
<value>清除所有服務統計資料</value>
|
||||
</data>
|
||||
<data name="menuRealPingServer" xml:space="preserve">
|
||||
<value>測試伺服器真連接延遲(多選) (Ctrl+R)</value>
|
||||
<value>測試伺服器真連線延遲(多選) (Ctrl+R)</value>
|
||||
</data>
|
||||
<data name="menuSortServerResult" xml:space="preserve">
|
||||
<value>按測試結果排序</value>
|
||||
|
@ -683,7 +683,7 @@
|
|||
<value>進階代理設定, 協定選擇(可選)</value>
|
||||
</data>
|
||||
<data name="TbSettingsAllowLAN" xml:space="preserve">
|
||||
<value>允許來自區域網路的連接</value>
|
||||
<value>允許來自區域網路的連線</value>
|
||||
</data>
|
||||
<data name="TbSettingsAutoHideStartup" xml:space="preserve">
|
||||
<value>啟動後隱藏視窗</value>
|
||||
|
@ -1106,7 +1106,7 @@
|
|||
<value>自动滚动到末尾</value>
|
||||
</data>
|
||||
<data name="TbSettingsSpeedPingTestUrl" xml:space="preserve">
|
||||
<value>真連接測試地址</value>
|
||||
<value>真連線測試位址</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableUpdateSubOnlyRemarksExist" xml:space="preserve">
|
||||
<value>更新訂閱時只判斷別名是否存在</value>
|
||||
|
@ -1187,7 +1187,7 @@
|
|||
<value>WebDav 密碼</value>
|
||||
</data>
|
||||
<data name="LvWebDavUrl" xml:space="preserve">
|
||||
<value>WebDav 伺服器地址</value>
|
||||
<value>WebDav 伺服器位址</value>
|
||||
</data>
|
||||
<data name="LvWebDavDirName" xml:space="preserve">
|
||||
<value>遠端資料夾名稱(可選)</value>
|
||||
|
@ -1205,25 +1205,25 @@
|
|||
<value>儲存介面佈局</value>
|
||||
</data>
|
||||
<data name="TbSettingsGeoFilesSource" xml:space="preserve">
|
||||
<value>Geo文件來源(可選)</value>
|
||||
<value>Geo檔案來源(可選)</value>
|
||||
</data>
|
||||
<data name="UpgradeAppNotExistTip" xml:space="preserve">
|
||||
<value>升级工具App不存在</value>
|
||||
<value>升級工具App不存在</value>
|
||||
</data>
|
||||
<data name="TbSettingsSrsFilesSource" xml:space="preserve">
|
||||
<value>sing-box ruleset文件來源(可選)</value>
|
||||
<value>sing-box ruleset檔案來源(可選)</value>
|
||||
</data>
|
||||
<data name="TbSettingsRoutingRulesSource" xml:space="preserve">
|
||||
<value>路由规则集来源(可选)</value>
|
||||
<value>路由規則集來源(可選)</value>
|
||||
</data>
|
||||
<data name="TbSettingsChinaUserTip" xml:space="preserve">
|
||||
<value>中国区域用户可忽略此项</value>
|
||||
<value>中國區域用戶可忽略此項</value>
|
||||
</data>
|
||||
<data name="menuRegionalPresets" xml:space="preserve">
|
||||
<value>区域预置设置</value>
|
||||
<value>區域預置設定</value>
|
||||
</data>
|
||||
<data name="menuRegionalPresetsDefault" xml:space="preserve">
|
||||
<value>默认区域</value>
|
||||
<value>預設區域</value>
|
||||
</data>
|
||||
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
||||
<value>俄羅斯</value>
|
||||
|
@ -1232,13 +1232,13 @@
|
|||
<value>掃描圖片中的二維碼</value>
|
||||
</data>
|
||||
<data name="InvalidUrlTip" xml:space="preserve">
|
||||
<value>地址(Url)無效</value>
|
||||
<value>位址(Url)無效</value>
|
||||
</data>
|
||||
<data name="InsecureUrlProtocol" xml:space="preserve">
|
||||
<value>請不要使用不安全的HTTP協定訂閱位址</value>
|
||||
</data>
|
||||
<data name="TbSettingsCurrentFontFamilyLinuxTip" xml:space="preserve">
|
||||
<value>安裝字體到系統中,重新啟動設定</value>
|
||||
<value>安裝字型到系統中,重新啟動設定</value>
|
||||
</data>
|
||||
<data name="menuExitTips" xml:space="preserve">
|
||||
<value>是否確定退出?</value>
|
||||
|
@ -1247,22 +1247,22 @@
|
|||
<value>備註備忘</value>
|
||||
</data>
|
||||
<data name="TbHeaderType8" xml:space="preserve">
|
||||
<value>拥塞控制算法</value>
|
||||
<value>擁塞控制算法</value>
|
||||
</data>
|
||||
<data name="menuProxiesSelectActivity" xml:space="preserve">
|
||||
<value>设为活动节点 (Enter)</value>
|
||||
<value>設為活動節點 (Enter)</value>
|
||||
</data>
|
||||
<data name="menuProxiesReload" xml:space="preserve">
|
||||
<value>刷新</value>
|
||||
<value>重新整理</value>
|
||||
</data>
|
||||
<data name="TbSorting" xml:space="preserve">
|
||||
<value>排序</value>
|
||||
</data>
|
||||
<data name="menuProxiesDelaytest" xml:space="preserve">
|
||||
<value>延迟测试</value>
|
||||
<value>延遲測試</value>
|
||||
</data>
|
||||
<data name="menuModeRule" xml:space="preserve">
|
||||
<value>规则</value>
|
||||
<value>規則</value>
|
||||
</data>
|
||||
<data name="menuModeNothing" xml:space="preserve">
|
||||
<value>随原配置</value>
|
||||
|
@ -1271,79 +1271,79 @@
|
|||
<value>全局</value>
|
||||
</data>
|
||||
<data name="menuModeDirect" xml:space="preserve">
|
||||
<value>直连</value>
|
||||
<value>直連</value>
|
||||
</data>
|
||||
<data name="menuRulemode" xml:space="preserve">
|
||||
<value>规则模式</value>
|
||||
<value>規則模式</value>
|
||||
</data>
|
||||
<data name="TbProxies" xml:space="preserve">
|
||||
<value>当前代理</value>
|
||||
<value>目前代理</value>
|
||||
</data>
|
||||
<data name="menuConnectionCloseAll" xml:space="preserve">
|
||||
<value>关闭所有连接</value>
|
||||
<value>關閉所有連線</value>
|
||||
</data>
|
||||
<data name="TbSettingsDomainStrategy4Out" xml:space="preserve">
|
||||
<value>Outbound默认解析策略</value>
|
||||
<value>Outbound預設解析策略</value>
|
||||
</data>
|
||||
<data name="menuConnectionClose" xml:space="preserve">
|
||||
<value>关闭连接</value>
|
||||
<value>關閉連線</value>
|
||||
</data>
|
||||
<data name="TbSortingUpTraffic" xml:space="preserve">
|
||||
<value>上传流量</value>
|
||||
<value>上傳流量</value>
|
||||
</data>
|
||||
<data name="TbSortingUpSpeed" xml:space="preserve">
|
||||
<value>上传速度</value>
|
||||
<value>上傳速度</value>
|
||||
</data>
|
||||
<data name="TbSortingType" xml:space="preserve">
|
||||
<value>类型</value>
|
||||
<value>類型</value>
|
||||
</data>
|
||||
<data name="TbSortingTime" xml:space="preserve">
|
||||
<value>时间</value>
|
||||
<value>時間</value>
|
||||
</data>
|
||||
<data name="TbSortingNetwork" xml:space="preserve">
|
||||
<value>网络</value>
|
||||
<value>網路</value>
|
||||
</data>
|
||||
<data name="TbSortingName" xml:space="preserve">
|
||||
<value>名称</value>
|
||||
<value>名稱</value>
|
||||
</data>
|
||||
<data name="TbSortingHost" xml:space="preserve">
|
||||
<value>主机</value>
|
||||
<value>主機</value>
|
||||
</data>
|
||||
<data name="TbSortingDownTraffic" xml:space="preserve">
|
||||
<value>下载流量</value>
|
||||
<value>下載流量</value>
|
||||
</data>
|
||||
<data name="TbSortingDownSpeed" xml:space="preserve">
|
||||
<value>下载速度</value>
|
||||
<value>下載速度</value>
|
||||
</data>
|
||||
<data name="TbSortingDelay" xml:space="preserve">
|
||||
<value>延迟</value>
|
||||
<value>延遲</value>
|
||||
</data>
|
||||
<data name="TbSortingDefault" xml:space="preserve">
|
||||
<value>默认</value>
|
||||
<value>預設</value>
|
||||
</data>
|
||||
<data name="TbConnections" xml:space="preserve">
|
||||
<value>当前连接</value>
|
||||
<value>目前連線</value>
|
||||
</data>
|
||||
<data name="menuSetDefaultMultipleServer" xml:space="preserve">
|
||||
<value>多服务器最低延迟 (多选)</value>
|
||||
<value>多伺服器最低延遲 (多選)</value>
|
||||
</data>
|
||||
<data name="menuProxiesDelaytestPart" xml:space="preserve">
|
||||
<value>当前部分节点延迟测试</value>
|
||||
<value>目前部分節點延遲測試</value>
|
||||
</data>
|
||||
<data name="menuSetDefaultLoadBalanceServer" xml:space="preserve">
|
||||
<value>多服务器负载均衡 (多选)</value>
|
||||
<value>多伺服器負載平衡 (多選)</value>
|
||||
</data>
|
||||
<data name="menuAddHysteria2Server" xml:space="preserve">
|
||||
<value>添加[Hysteria2]服务器</value>
|
||||
<value>添加[Hysteria2]伺服器</value>
|
||||
</data>
|
||||
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
|
||||
<value>Hysteria 最大带宽(Up/Dw)</value>
|
||||
<value>Hysteria 最大頻寬(Up/Dw)</value>
|
||||
</data>
|
||||
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
|
||||
<value>主界面布局方向(需重启)</value>
|
||||
<value>主界面佈局方向(需重啟)</value>
|
||||
</data>
|
||||
<data name="menuAddWireguardServer" xml:space="preserve">
|
||||
<value>添加[WireGuard]服务器</value>
|
||||
<value>添加[WireGuard]伺服器</value>
|
||||
</data>
|
||||
<data name="TbPrivateKey" xml:space="preserve">
|
||||
<value>PrivateKey</value>
|
||||
|
@ -1355,15 +1355,27 @@
|
|||
<value>Address(Ip,Ipv6)</value>
|
||||
</data>
|
||||
<data name="TbSettingsUseSystemHosts" xml:space="preserve">
|
||||
<value>使用系统hosts</value>
|
||||
<value>使用系統hosts</value>
|
||||
</data>
|
||||
<data name="TbSortingChain" xml:space="preserve">
|
||||
<value>路由链</value>
|
||||
<value>路由鏈</value>
|
||||
</data>
|
||||
<data name="TbSettingsDomainDNSAddress" xml:space="preserve">
|
||||
<value>Outbound域名解析地址</value>
|
||||
<value>Outbound域名解析位址</value>
|
||||
</data>
|
||||
<data name="TbPath7" xml:space="preserve">
|
||||
<value>混淆密码(obfs password)</value>
|
||||
<value>混淆密碼(obfs password)</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPassword" xml:space="preserve">
|
||||
<value>Linux系統的sudo密碼</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
|
||||
<value>密碼只會儲存在本機檔案中,沒有密碼無法開啟Tun</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordIsEmpty" xml:space="preserve">
|
||||
<value>請先在Tun模式設定中設定sudo密碼</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordNotSudoRunApp" xml:space="preserve">
|
||||
<value>請不要用sudo來運行本app</value>
|
||||
</data>
|
||||
</root>
|
|
@ -14,7 +14,7 @@
|
|||
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
|
||||
<PackageReference Include="Splat.NLog" Version="15.2.22" />
|
||||
<PackageReference Include="WebDav.Client" Version="2.8.0" />
|
||||
<PackageReference Include="YamlDotNet" Version="16.1.3" />
|
||||
<PackageReference Include="YamlDotNet" Version="16.2.0" />
|
||||
<PackageReference Include="QRCoder" Version="1.6.0" />
|
||||
<PackageReference Include="CliWrap" Version="3.6.7" />
|
||||
<PackageReference Include="SkiaSharp.QrCode" Version="0.7.0" />
|
||||
|
|
|
@ -366,8 +366,8 @@ namespace ServiceLib.Services.CoreConfig
|
|||
else
|
||||
{
|
||||
v2rayConfig.log.loglevel = _config.CoreBasicItem.Loglevel;
|
||||
v2rayConfig.log.access = "";
|
||||
v2rayConfig.log.error = "";
|
||||
v2rayConfig.log.access = null;
|
||||
v2rayConfig.log.error = null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -1120,17 +1120,14 @@ namespace ServiceLib.Services.CoreConfig
|
|||
if (_config.GuiItem.EnableStatistics)
|
||||
{
|
||||
string tag = EInboundProtocol.api.ToString();
|
||||
API4Ray apiObj = new();
|
||||
Metrics4Ray apiObj = new();
|
||||
Policy4Ray policyObj = new();
|
||||
SystemPolicy4Ray policySystemSetting = new();
|
||||
|
||||
string[] services = { "StatsService" };
|
||||
|
||||
v2rayConfig.stats = new Stats4Ray();
|
||||
|
||||
apiObj.tag = tag;
|
||||
apiObj.services = services.ToList();
|
||||
v2rayConfig.api = apiObj;
|
||||
v2rayConfig.metrics = apiObj;
|
||||
|
||||
policySystemSetting.statsOutboundDownlink = true;
|
||||
policySystemSetting.statsOutboundUplink = true;
|
||||
|
|
106
v2rayN/ServiceLib/Services/Statistics/StatisticsXrayService.cs
Normal file
106
v2rayN/ServiceLib/Services/Statistics/StatisticsXrayService.cs
Normal file
|
@ -0,0 +1,106 @@
|
|||
namespace ServiceLib.Services.Statistics
|
||||
{
|
||||
public class StatisticsXrayService
|
||||
{
|
||||
private const long linkBase = 1024;
|
||||
private string _url;
|
||||
private ServerSpeedItem _serverSpeedItem = new();
|
||||
private Config _config;
|
||||
private bool _exitFlag;
|
||||
private Action<ServerSpeedItem>? _updateFunc;
|
||||
|
||||
public StatisticsXrayService(Config config, Action<ServerSpeedItem> updateFunc)
|
||||
{
|
||||
_config = config;
|
||||
_updateFunc = updateFunc;
|
||||
_exitFlag = false;
|
||||
_url = $"{Global.HttpProtocol}{Global.Loopback}:{AppHandler.Instance.StatePort}/debug/vars";
|
||||
|
||||
Task.Run(Run);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
_exitFlag = true;
|
||||
}
|
||||
|
||||
private async void Run()
|
||||
{
|
||||
while (!_exitFlag)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
try
|
||||
{
|
||||
if (!_config.IsRunningCore(ECoreType.Xray))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var result = await HttpClientHelper.Instance.TryGetAsync(_url);
|
||||
if (result != null)
|
||||
{
|
||||
var server = ParseOutput(result) ?? new ServerSpeedItem();
|
||||
_updateFunc?.Invoke(server);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ServerSpeedItem? ParseOutput(string result)
|
||||
{
|
||||
try
|
||||
{
|
||||
var source = JsonUtils.Deserialize<V2rayMetricsVars>(result);
|
||||
if (source?.stats?.outbound == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ServerSpeedItem server = new();
|
||||
foreach (string key in source.stats.outbound.Keys)
|
||||
{
|
||||
var value = source.stats.outbound[key];
|
||||
if (value == null) continue;
|
||||
var state = JsonUtils.Deserialize<V2rayMetricsVarsLink>(value.ToString());
|
||||
|
||||
if (key.StartsWith(Global.ProxyTag))
|
||||
{
|
||||
server.ProxyUp += state.uplink / linkBase;
|
||||
server.ProxyDown += state.downlink / linkBase;
|
||||
}
|
||||
else if (key == Global.DirectTag)
|
||||
{
|
||||
server.DirectUp = state.uplink / linkBase;
|
||||
server.DirectDown = state.downlink / linkBase;
|
||||
}
|
||||
}
|
||||
|
||||
if (server.DirectDown < _serverSpeedItem.DirectDown || server.ProxyDown < _serverSpeedItem.ProxyDown)
|
||||
{
|
||||
_serverSpeedItem = new();
|
||||
return null;
|
||||
}
|
||||
|
||||
ServerSpeedItem curItem = new()
|
||||
{
|
||||
ProxyUp = server.ProxyUp - _serverSpeedItem.ProxyUp,
|
||||
ProxyDown = server.ProxyDown - _serverSpeedItem.ProxyDown,
|
||||
DirectUp = server.DirectUp - _serverSpeedItem.DirectUp,
|
||||
DirectDown = server.DirectDown - _serverSpeedItem.DirectDown,
|
||||
};
|
||||
_serverSpeedItem = server;
|
||||
return curItem;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -85,6 +85,7 @@ namespace ServiceLib.ViewModels
|
|||
[Reactive] public int TunMtu { get; set; }
|
||||
[Reactive] public bool TunEnableExInbound { get; set; }
|
||||
[Reactive] public bool TunEnableIPv6Address { get; set; }
|
||||
[Reactive] public string TunLinuxSudoPassword { get; set; }
|
||||
|
||||
#endregion Tun mode
|
||||
|
||||
|
@ -197,6 +198,7 @@ namespace ServiceLib.ViewModels
|
|||
TunMtu = _config.TunModeItem.Mtu;
|
||||
TunEnableExInbound = _config.TunModeItem.EnableExInbound;
|
||||
TunEnableIPv6Address = _config.TunModeItem.EnableIPv6Address;
|
||||
TunLinuxSudoPassword = _config.TunModeItem.LinuxSudoPassword;
|
||||
|
||||
#endregion Tun mode
|
||||
|
||||
|
@ -340,6 +342,7 @@ namespace ServiceLib.ViewModels
|
|||
_config.TunModeItem.Mtu = TunMtu;
|
||||
_config.TunModeItem.EnableExInbound = TunEnableExInbound;
|
||||
_config.TunModeItem.EnableIPv6Address = TunEnableIPv6Address;
|
||||
_config.TunModeItem.LinuxSudoPassword = TunLinuxSudoPassword;
|
||||
|
||||
//coreType
|
||||
await SaveCoreType();
|
||||
|
|
|
@ -108,7 +108,7 @@ namespace ServiceLib.ViewModels
|
|||
SelectedServer = new();
|
||||
RunningServerToolTipText = "-";
|
||||
|
||||
if (_config.TunModeItem.EnableTun && AppHandler.Instance.IsAdministrator)
|
||||
if (_config.TunModeItem.EnableTun && AllowEnableTun())
|
||||
{
|
||||
EnableTun = true;
|
||||
}
|
||||
|
@ -414,10 +414,17 @@ namespace ServiceLib.ViewModels
|
|||
{
|
||||
_config.TunModeItem.EnableTun = EnableTun;
|
||||
// When running as a non-administrator, reboot to administrator mode
|
||||
if (EnableTun && !AppHandler.Instance.IsAdministrator)
|
||||
if (EnableTun && AllowEnableTun() == false)
|
||||
{
|
||||
_config.TunModeItem.EnableTun = false;
|
||||
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
|
||||
if (Utils.IsWindows())
|
||||
{
|
||||
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
|
||||
}
|
||||
else if (Utils.IsLinux())
|
||||
{
|
||||
NoticeHandler.Instance.SendMessageAndEnqueue(ResUI.TbSettingsLinuxSudoPasswordIsEmpty);
|
||||
}
|
||||
return;
|
||||
}
|
||||
await ConfigHandler.SaveConfig(_config);
|
||||
|
@ -425,6 +432,19 @@ namespace ServiceLib.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
private bool AllowEnableTun()
|
||||
{
|
||||
if (Utils.IsWindows())
|
||||
{
|
||||
return AppHandler.Instance.IsAdministrator;
|
||||
}
|
||||
else if (Utils.IsLinux())
|
||||
{
|
||||
return _config.TunModeItem.LinuxSudoPassword.IsNotEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion System proxy and Routings
|
||||
|
||||
#region UI
|
||||
|
|
|
@ -117,6 +117,11 @@ namespace v2rayN.Desktop.Views
|
|||
}
|
||||
else
|
||||
{
|
||||
if (AppHandler.Instance.IsAdministrator)
|
||||
{
|
||||
this.Title = $"{Utils.GetVersion()} - {ResUI.TbSettingsLinuxSudoPasswordNotSudoRunApp}";
|
||||
NoticeHandler.Instance.SendMessageAndEnqueue(ResUI.TbSettingsLinuxSudoPasswordNotSudoRunApp);
|
||||
}
|
||||
menuRebootAsAdmin.IsVisible = false;
|
||||
menuSettingsSetUWP.IsVisible = false;
|
||||
menuGlobalHotkeySetting.IsVisible = false;
|
||||
|
@ -282,6 +287,7 @@ namespace v2rayN.Desktop.Views
|
|||
e.Cancel = true;
|
||||
ShowHideWindow(false);
|
||||
break;
|
||||
|
||||
case WindowCloseReason.ApplicationShutdown or WindowCloseReason.OSShutdown:
|
||||
await ViewModel?.MyAppExitAsync(true);
|
||||
break;
|
||||
|
|
|
@ -489,7 +489,7 @@
|
|||
HorizontalAlignment="Left"
|
||||
Classes="Margin8" />
|
||||
|
||||
|
||||
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="11"
|
||||
|
@ -721,6 +721,7 @@
|
|||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
|
@ -794,6 +795,28 @@
|
|||
Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
Classes="Margin8" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="7"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Classes="Margin8"
|
||||
Text="{x:Static resx:ResUI.TbSettingsLinuxSudoPassword}" />
|
||||
<TextBox
|
||||
x:Name="txtLinuxSudoPassword"
|
||||
Grid.Row="7"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
HorizontalAlignment="Left"
|
||||
Classes="Margin8"
|
||||
PasswordChar="*" />
|
||||
<TextBlock
|
||||
Grid.Row="7"
|
||||
Grid.Column="2"
|
||||
VerticalAlignment="Center"
|
||||
Classes="Margin8"
|
||||
Text="{x:Static resx:ResUI.TbSettingsLinuxSudoPasswordTip}"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
</DockPanel>
|
||||
</TabItem>
|
||||
|
|
|
@ -152,6 +152,7 @@ namespace v2rayN.Desktop.Views
|
|||
this.Bind(ViewModel, vm => vm.TunMtu, v => v.cmbMtu.SelectedValue).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunEnableExInbound, v => v.togEnableExInbound.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunEnableIPv6Address, v => v.togEnableIPv6Address.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunLinuxSudoPassword, v => v.txtLinuxSudoPassword.Text).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.SelectedValue).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.CoreType2, v => v.cmbCoreType2.SelectedValue).DisposeWith(disposables);
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace v2rayN.Desktop.Views
|
|||
this.Bind(ViewModel, vm => vm.SelectedRouting, v => v.cmbRoutings2.SelectedItem).DisposeWith(disposables);
|
||||
});
|
||||
|
||||
spEnableTun.IsVisible = (Utils.IsWindows() || AppHandler.Instance.IsAdministrator);
|
||||
//spEnableTun.IsVisible = (Utils.IsWindows() || AppHandler.Instance.IsAdministrator);
|
||||
}
|
||||
|
||||
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
||||
|
|
Loading…
Reference in a new issue