mirror of https://github.com/2dust/v2rayN
Migrate xray traffic statistics to Metrics
https://xtls.github.io/config/metrics.htmlpull/6079/head
parent
9d638968a9
commit
28019dc511
|
@ -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)
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue