mirror of
https://github.com/2dust/v2rayN.git
synced 2025-04-19 13:42:24 +00:00
up stat
This commit is contained in:
parent
912f682359
commit
3f1688f8b7
13 changed files with 1902 additions and 2149 deletions
|
@ -197,7 +197,7 @@ namespace v2rayN.Forms
|
||||||
ListViewItem lvItem = null;
|
ListViewItem lvItem = null;
|
||||||
if (statistics != null && statistics.Enable)
|
if (statistics != null && statistics.Enable)
|
||||||
{
|
{
|
||||||
var index = statistics.Statistic.FindIndex(item_ => item_.address == item.address);
|
var index = statistics.Statistic.FindIndex(item_ => item_.itemId == item.getItemId());
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
{
|
{
|
||||||
totalUp = Utils.HumanFy(statistics.Statistic[index].totalUp);
|
totalUp = Utils.HumanFy(statistics.Statistic[index].totalUp);
|
||||||
|
@ -350,7 +350,7 @@ namespace v2rayN.Forms
|
||||||
Utils.SetClipboardData(e.ClickedItem.Text);
|
Utils.SetClipboardData(e.ClickedItem.Text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region v2ray 操作
|
#region v2ray 操作
|
||||||
|
@ -367,6 +367,7 @@ namespace v2rayN.Forms
|
||||||
v2rayHandler.LoadV2ray(config);
|
v2rayHandler.LoadV2ray(config);
|
||||||
Global.reloadV2ray = false;
|
Global.reloadV2ray = false;
|
||||||
ConfigHandler.SaveConfig(ref config, false);
|
ConfigHandler.SaveConfig(ref config, false);
|
||||||
|
statistics?.SaveToFile();
|
||||||
|
|
||||||
ChangePACButtonStatus(config.listenerType);
|
ChangePACButtonStatus(config.listenerType);
|
||||||
}
|
}
|
||||||
|
@ -377,6 +378,7 @@ namespace v2rayN.Forms
|
||||||
private void CloseV2ray()
|
private void CloseV2ray()
|
||||||
{
|
{
|
||||||
ConfigHandler.SaveConfig(ref config, false);
|
ConfigHandler.SaveConfig(ref config, false);
|
||||||
|
statistics?.SaveToFile();
|
||||||
|
|
||||||
ChangePACButtonStatus(0);
|
ChangePACButtonStatus(0);
|
||||||
|
|
||||||
|
@ -958,51 +960,34 @@ namespace v2rayN.Forms
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateStatisticsHandler(ulong totalUp, ulong totalDown, ulong up, ulong down, List<Mode.ServerStatistics> statistics)
|
private void UpdateStatisticsHandler(ulong up, ulong down, List<ServerStatItem> statistics)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
up /= (ulong)(config.statisticsFreshRate / 1000f);
|
up /= (ulong)(config.statisticsFreshRate / 1000f);
|
||||||
down /= (ulong)(config.statisticsFreshRate / 1000f);
|
down /= (ulong)(config.statisticsFreshRate / 1000f);
|
||||||
toolSslServerSpeed.Text = string.Format(
|
toolSslServerSpeed.Text = string.Format("{0}/s↑ | {1}/s↓", Utils.HumanFy(up), Utils.HumanFy(down));
|
||||||
"{0}/s↑ | {1}/s↓",
|
|
||||||
Utils.HumanFy(up),
|
|
||||||
Utils.HumanFy(down)
|
|
||||||
);
|
|
||||||
|
|
||||||
List<string[]> datas = new List<string[]>();
|
List<string[]> datas = new List<string[]>();
|
||||||
for (int i = 0; i < config.vmess.Count; i++)
|
for (int i = 0; i < config.vmess.Count; i++)
|
||||||
{
|
{
|
||||||
string totalUp_ = string.Empty,
|
var index = statistics.FindIndex(item_ => item_.itemId == config.vmess[i].getItemId());
|
||||||
totalDown_ = string.Empty,
|
|
||||||
todayUp_ = string.Empty,
|
|
||||||
todayDown_ = string.Empty;
|
|
||||||
var index = statistics.FindIndex(item_ => Utils.IsIdenticalServer(item_, new ServerStatistics(config.vmess[i].remarks, config.vmess[i].address, config.vmess[i].port, config.vmess[i].path, config.vmess[i].requestHost, 0, 0, 0, 0)));
|
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
{
|
{
|
||||||
totalUp_ = Utils.HumanFy(statistics[index].totalUp);
|
lvServers.Invoke((MethodInvoker)delegate
|
||||||
totalDown_ = Utils.HumanFy(statistics[index].totalDown);
|
{
|
||||||
todayUp_ = Utils.HumanFy(statistics[index].todayUp);
|
lvServers.SuspendLayout();
|
||||||
todayDown_ = Utils.HumanFy(statistics[index].todayDown);
|
|
||||||
}
|
|
||||||
|
|
||||||
datas.Add(new string[] { totalUp_, totalDown_, todayUp_, todayDown_ });
|
var indexStart = 9;
|
||||||
|
lvServers.Items[i].SubItems[indexStart++].Text = Utils.HumanFy(statistics[index].totalUp);
|
||||||
|
lvServers.Items[i].SubItems[indexStart++].Text = Utils.HumanFy(statistics[index].totalDown);
|
||||||
|
lvServers.Items[i].SubItems[indexStart++].Text = Utils.HumanFy(statistics[index].todayUp);
|
||||||
|
lvServers.Items[i].SubItems[indexStart++].Text = Utils.HumanFy(statistics[index].todayDown);
|
||||||
|
|
||||||
|
lvServers.ResumeLayout();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lvServers.Invoke((MethodInvoker)delegate
|
|
||||||
{
|
|
||||||
lvServers.SuspendLayout();
|
|
||||||
for (int i = 0; i < datas.Count; i++)
|
|
||||||
{
|
|
||||||
var indexStart = 9;
|
|
||||||
lvServers.Items[i].SubItems[indexStart++].Text = datas[i][0];
|
|
||||||
lvServers.Items[i].SubItems[indexStart++].Text = datas[i][1];
|
|
||||||
lvServers.Items[i].SubItems[indexStart++].Text = datas[i][2];
|
|
||||||
lvServers.Items[i].SubItems[indexStart++].Text = datas[i][3];
|
|
||||||
}
|
|
||||||
lvServers.ResumeLayout();
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -1149,7 +1134,7 @@ namespace v2rayN.Forms
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
downloadHandle.DownloadFileAsync(config, url, null);
|
downloadHandle.DownloadFileAsync(config, url, null, -1);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
62
v2rayN/v2rayN/Forms/OptionSettingForm.Designer.cs
generated
62
v2rayN/v2rayN/Forms/OptionSettingForm.Designer.cs
generated
|
@ -85,9 +85,7 @@
|
||||||
this.label6 = new System.Windows.Forms.Label();
|
this.label6 = new System.Windows.Forms.Label();
|
||||||
this.tabPage7 = new System.Windows.Forms.TabPage();
|
this.tabPage7 = new System.Windows.Forms.TabPage();
|
||||||
this.cbFreshrate = new System.Windows.Forms.ComboBox();
|
this.cbFreshrate = new System.Windows.Forms.ComboBox();
|
||||||
this.tbCacheDays = new System.Windows.Forms.TextBox();
|
|
||||||
this.lbFreshrate = new System.Windows.Forms.Label();
|
this.lbFreshrate = new System.Windows.Forms.Label();
|
||||||
this.lbCacheDays = new System.Windows.Forms.Label();
|
|
||||||
this.chkEnableStatistics = new System.Windows.Forms.CheckBox();
|
this.chkEnableStatistics = new System.Windows.Forms.CheckBox();
|
||||||
this.chkAllowLANConn = new System.Windows.Forms.CheckBox();
|
this.chkAllowLANConn = new System.Windows.Forms.CheckBox();
|
||||||
this.txturlGFWList = new System.Windows.Forms.TextBox();
|
this.txturlGFWList = new System.Windows.Forms.TextBox();
|
||||||
|
@ -114,32 +112,31 @@
|
||||||
//
|
//
|
||||||
// btnClose
|
// btnClose
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.btnClose, "btnClose");
|
|
||||||
this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||||
|
resources.ApplyResources(this.btnClose, "btnClose");
|
||||||
this.btnClose.Name = "btnClose";
|
this.btnClose.Name = "btnClose";
|
||||||
this.btnClose.UseVisualStyleBackColor = true;
|
this.btnClose.UseVisualStyleBackColor = true;
|
||||||
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
|
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
|
||||||
//
|
//
|
||||||
// tabControl1
|
// tabControl1
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.tabControl1, "tabControl1");
|
|
||||||
this.tabControl1.Controls.Add(this.tabPage1);
|
this.tabControl1.Controls.Add(this.tabPage1);
|
||||||
this.tabControl1.Controls.Add(this.tabPage2);
|
this.tabControl1.Controls.Add(this.tabPage2);
|
||||||
this.tabControl1.Controls.Add(this.tabPage6);
|
this.tabControl1.Controls.Add(this.tabPage6);
|
||||||
this.tabControl1.Controls.Add(this.tabPage7);
|
this.tabControl1.Controls.Add(this.tabPage7);
|
||||||
|
resources.ApplyResources(this.tabControl1, "tabControl1");
|
||||||
this.tabControl1.Name = "tabControl1";
|
this.tabControl1.Name = "tabControl1";
|
||||||
this.tabControl1.SelectedIndex = 0;
|
this.tabControl1.SelectedIndex = 0;
|
||||||
//
|
//
|
||||||
// tabPage1
|
// tabPage1
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.tabPage1, "tabPage1");
|
|
||||||
this.tabPage1.Controls.Add(this.groupBox1);
|
this.tabPage1.Controls.Add(this.groupBox1);
|
||||||
|
resources.ApplyResources(this.tabPage1, "tabPage1");
|
||||||
this.tabPage1.Name = "tabPage1";
|
this.tabPage1.Name = "tabPage1";
|
||||||
this.tabPage1.UseVisualStyleBackColor = true;
|
this.tabPage1.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// groupBox1
|
// groupBox1
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.groupBox1, "groupBox1");
|
|
||||||
this.groupBox1.Controls.Add(this.label16);
|
this.groupBox1.Controls.Add(this.label16);
|
||||||
this.groupBox1.Controls.Add(this.cmblistenerType);
|
this.groupBox1.Controls.Add(this.cmblistenerType);
|
||||||
this.groupBox1.Controls.Add(this.chksniffingEnabled2);
|
this.groupBox1.Controls.Add(this.chksniffingEnabled2);
|
||||||
|
@ -160,6 +157,7 @@
|
||||||
this.groupBox1.Controls.Add(this.label5);
|
this.groupBox1.Controls.Add(this.label5);
|
||||||
this.groupBox1.Controls.Add(this.txtlocalPort);
|
this.groupBox1.Controls.Add(this.txtlocalPort);
|
||||||
this.groupBox1.Controls.Add(this.label2);
|
this.groupBox1.Controls.Add(this.label2);
|
||||||
|
resources.ApplyResources(this.groupBox1, "groupBox1");
|
||||||
this.groupBox1.Name = "groupBox1";
|
this.groupBox1.Name = "groupBox1";
|
||||||
this.groupBox1.TabStop = false;
|
this.groupBox1.TabStop = false;
|
||||||
//
|
//
|
||||||
|
@ -170,7 +168,6 @@
|
||||||
//
|
//
|
||||||
// cmblistenerType
|
// cmblistenerType
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.cmblistenerType, "cmblistenerType");
|
|
||||||
this.cmblistenerType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
this.cmblistenerType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
this.cmblistenerType.FormattingEnabled = true;
|
this.cmblistenerType.FormattingEnabled = true;
|
||||||
this.cmblistenerType.Items.AddRange(new object[] {
|
this.cmblistenerType.Items.AddRange(new object[] {
|
||||||
|
@ -179,6 +176,7 @@
|
||||||
resources.GetString("cmblistenerType.Items2"),
|
resources.GetString("cmblistenerType.Items2"),
|
||||||
resources.GetString("cmblistenerType.Items3"),
|
resources.GetString("cmblistenerType.Items3"),
|
||||||
resources.GetString("cmblistenerType.Items4")});
|
resources.GetString("cmblistenerType.Items4")});
|
||||||
|
resources.ApplyResources(this.cmblistenerType, "cmblistenerType");
|
||||||
this.cmblistenerType.Name = "cmblistenerType";
|
this.cmblistenerType.Name = "cmblistenerType";
|
||||||
//
|
//
|
||||||
// chksniffingEnabled2
|
// chksniffingEnabled2
|
||||||
|
@ -224,12 +222,12 @@
|
||||||
//
|
//
|
||||||
// cmbprotocol2
|
// cmbprotocol2
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.cmbprotocol2, "cmbprotocol2");
|
|
||||||
this.cmbprotocol2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
this.cmbprotocol2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
this.cmbprotocol2.FormattingEnabled = true;
|
this.cmbprotocol2.FormattingEnabled = true;
|
||||||
this.cmbprotocol2.Items.AddRange(new object[] {
|
this.cmbprotocol2.Items.AddRange(new object[] {
|
||||||
resources.GetString("cmbprotocol2.Items"),
|
resources.GetString("cmbprotocol2.Items"),
|
||||||
resources.GetString("cmbprotocol2.Items1")});
|
resources.GetString("cmbprotocol2.Items1")});
|
||||||
|
resources.ApplyResources(this.cmbprotocol2, "cmbprotocol2");
|
||||||
this.cmbprotocol2.Name = "cmbprotocol2";
|
this.cmbprotocol2.Name = "cmbprotocol2";
|
||||||
//
|
//
|
||||||
// label3
|
// label3
|
||||||
|
@ -244,8 +242,8 @@
|
||||||
//
|
//
|
||||||
// cmbprotocol
|
// cmbprotocol
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.cmbprotocol, "cmbprotocol");
|
|
||||||
this.cmbprotocol.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
this.cmbprotocol.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
|
resources.ApplyResources(this.cmbprotocol, "cmbprotocol");
|
||||||
this.cmbprotocol.FormattingEnabled = true;
|
this.cmbprotocol.FormattingEnabled = true;
|
||||||
this.cmbprotocol.Items.AddRange(new object[] {
|
this.cmbprotocol.Items.AddRange(new object[] {
|
||||||
resources.GetString("cmbprotocol.Items"),
|
resources.GetString("cmbprotocol.Items"),
|
||||||
|
@ -271,7 +269,6 @@
|
||||||
//
|
//
|
||||||
// cmbloglevel
|
// cmbloglevel
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.cmbloglevel, "cmbloglevel");
|
|
||||||
this.cmbloglevel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
this.cmbloglevel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
this.cmbloglevel.FormattingEnabled = true;
|
this.cmbloglevel.FormattingEnabled = true;
|
||||||
this.cmbloglevel.Items.AddRange(new object[] {
|
this.cmbloglevel.Items.AddRange(new object[] {
|
||||||
|
@ -280,6 +277,7 @@
|
||||||
resources.GetString("cmbloglevel.Items2"),
|
resources.GetString("cmbloglevel.Items2"),
|
||||||
resources.GetString("cmbloglevel.Items3"),
|
resources.GetString("cmbloglevel.Items3"),
|
||||||
resources.GetString("cmbloglevel.Items4")});
|
resources.GetString("cmbloglevel.Items4")});
|
||||||
|
resources.ApplyResources(this.cmbloglevel, "cmbloglevel");
|
||||||
this.cmbloglevel.Name = "cmbloglevel";
|
this.cmbloglevel.Name = "cmbloglevel";
|
||||||
//
|
//
|
||||||
// label5
|
// label5
|
||||||
|
@ -299,33 +297,33 @@
|
||||||
//
|
//
|
||||||
// tabPage2
|
// tabPage2
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.tabPage2, "tabPage2");
|
|
||||||
this.tabPage2.Controls.Add(this.groupBox2);
|
this.tabPage2.Controls.Add(this.groupBox2);
|
||||||
|
resources.ApplyResources(this.tabPage2, "tabPage2");
|
||||||
this.tabPage2.Name = "tabPage2";
|
this.tabPage2.Name = "tabPage2";
|
||||||
this.tabPage2.UseVisualStyleBackColor = true;
|
this.tabPage2.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// groupBox2
|
// groupBox2
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.groupBox2, "groupBox2");
|
|
||||||
this.groupBox2.Controls.Add(this.tabControl2);
|
this.groupBox2.Controls.Add(this.tabControl2);
|
||||||
this.groupBox2.Controls.Add(this.panel3);
|
this.groupBox2.Controls.Add(this.panel3);
|
||||||
|
resources.ApplyResources(this.groupBox2, "groupBox2");
|
||||||
this.groupBox2.Name = "groupBox2";
|
this.groupBox2.Name = "groupBox2";
|
||||||
this.groupBox2.TabStop = false;
|
this.groupBox2.TabStop = false;
|
||||||
//
|
//
|
||||||
// tabControl2
|
// tabControl2
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.tabControl2, "tabControl2");
|
|
||||||
this.tabControl2.Controls.Add(this.tabPage3);
|
this.tabControl2.Controls.Add(this.tabPage3);
|
||||||
this.tabControl2.Controls.Add(this.tabPage4);
|
this.tabControl2.Controls.Add(this.tabPage4);
|
||||||
this.tabControl2.Controls.Add(this.tabPage5);
|
this.tabControl2.Controls.Add(this.tabPage5);
|
||||||
this.tabControl2.Controls.Add(this.tabPage8);
|
this.tabControl2.Controls.Add(this.tabPage8);
|
||||||
|
resources.ApplyResources(this.tabControl2, "tabControl2");
|
||||||
this.tabControl2.Name = "tabControl2";
|
this.tabControl2.Name = "tabControl2";
|
||||||
this.tabControl2.SelectedIndex = 0;
|
this.tabControl2.SelectedIndex = 0;
|
||||||
//
|
//
|
||||||
// tabPage3
|
// tabPage3
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.tabPage3, "tabPage3");
|
|
||||||
this.tabPage3.Controls.Add(this.txtUseragent);
|
this.tabPage3.Controls.Add(this.txtUseragent);
|
||||||
|
resources.ApplyResources(this.tabPage3, "tabPage3");
|
||||||
this.tabPage3.Name = "tabPage3";
|
this.tabPage3.Name = "tabPage3";
|
||||||
this.tabPage3.UseVisualStyleBackColor = true;
|
this.tabPage3.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
|
@ -336,8 +334,8 @@
|
||||||
//
|
//
|
||||||
// tabPage4
|
// tabPage4
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.tabPage4, "tabPage4");
|
|
||||||
this.tabPage4.Controls.Add(this.txtUserdirect);
|
this.tabPage4.Controls.Add(this.txtUserdirect);
|
||||||
|
resources.ApplyResources(this.tabPage4, "tabPage4");
|
||||||
this.tabPage4.Name = "tabPage4";
|
this.tabPage4.Name = "tabPage4";
|
||||||
this.tabPage4.UseVisualStyleBackColor = true;
|
this.tabPage4.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
|
@ -348,8 +346,8 @@
|
||||||
//
|
//
|
||||||
// tabPage5
|
// tabPage5
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.tabPage5, "tabPage5");
|
|
||||||
this.tabPage5.Controls.Add(this.txtUserblock);
|
this.tabPage5.Controls.Add(this.txtUserblock);
|
||||||
|
resources.ApplyResources(this.tabPage5, "tabPage5");
|
||||||
this.tabPage5.Name = "tabPage5";
|
this.tabPage5.Name = "tabPage5";
|
||||||
this.tabPage5.UseVisualStyleBackColor = true;
|
this.tabPage5.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
|
@ -360,14 +358,13 @@
|
||||||
//
|
//
|
||||||
// tabPage8
|
// tabPage8
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.tabPage8, "tabPage8");
|
|
||||||
this.tabPage8.Controls.Add(this.cmbroutingMode);
|
this.tabPage8.Controls.Add(this.cmbroutingMode);
|
||||||
|
resources.ApplyResources(this.tabPage8, "tabPage8");
|
||||||
this.tabPage8.Name = "tabPage8";
|
this.tabPage8.Name = "tabPage8";
|
||||||
this.tabPage8.UseVisualStyleBackColor = true;
|
this.tabPage8.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// cmbroutingMode
|
// cmbroutingMode
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.cmbroutingMode, "cmbroutingMode");
|
|
||||||
this.cmbroutingMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
this.cmbroutingMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
this.cmbroutingMode.FormattingEnabled = true;
|
this.cmbroutingMode.FormattingEnabled = true;
|
||||||
this.cmbroutingMode.Items.AddRange(new object[] {
|
this.cmbroutingMode.Items.AddRange(new object[] {
|
||||||
|
@ -375,15 +372,16 @@
|
||||||
resources.GetString("cmbroutingMode.Items1"),
|
resources.GetString("cmbroutingMode.Items1"),
|
||||||
resources.GetString("cmbroutingMode.Items2"),
|
resources.GetString("cmbroutingMode.Items2"),
|
||||||
resources.GetString("cmbroutingMode.Items3")});
|
resources.GetString("cmbroutingMode.Items3")});
|
||||||
|
resources.ApplyResources(this.cmbroutingMode, "cmbroutingMode");
|
||||||
this.cmbroutingMode.Name = "cmbroutingMode";
|
this.cmbroutingMode.Name = "cmbroutingMode";
|
||||||
//
|
//
|
||||||
// panel3
|
// panel3
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.panel3, "panel3");
|
|
||||||
this.panel3.Controls.Add(this.btnSetDefRountingRule);
|
this.panel3.Controls.Add(this.btnSetDefRountingRule);
|
||||||
this.panel3.Controls.Add(this.labRoutingTips);
|
this.panel3.Controls.Add(this.labRoutingTips);
|
||||||
this.panel3.Controls.Add(this.cmbdomainStrategy);
|
this.panel3.Controls.Add(this.cmbdomainStrategy);
|
||||||
this.panel3.Controls.Add(this.label15);
|
this.panel3.Controls.Add(this.label15);
|
||||||
|
resources.ApplyResources(this.panel3, "panel3");
|
||||||
this.panel3.Name = "panel3";
|
this.panel3.Name = "panel3";
|
||||||
//
|
//
|
||||||
// btnSetDefRountingRule
|
// btnSetDefRountingRule
|
||||||
|
@ -395,19 +393,19 @@
|
||||||
//
|
//
|
||||||
// labRoutingTips
|
// labRoutingTips
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.labRoutingTips, "labRoutingTips");
|
|
||||||
this.labRoutingTips.ForeColor = System.Drawing.Color.Brown;
|
this.labRoutingTips.ForeColor = System.Drawing.Color.Brown;
|
||||||
|
resources.ApplyResources(this.labRoutingTips, "labRoutingTips");
|
||||||
this.labRoutingTips.Name = "labRoutingTips";
|
this.labRoutingTips.Name = "labRoutingTips";
|
||||||
//
|
//
|
||||||
// cmbdomainStrategy
|
// cmbdomainStrategy
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.cmbdomainStrategy, "cmbdomainStrategy");
|
|
||||||
this.cmbdomainStrategy.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
this.cmbdomainStrategy.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
this.cmbdomainStrategy.FormattingEnabled = true;
|
this.cmbdomainStrategy.FormattingEnabled = true;
|
||||||
this.cmbdomainStrategy.Items.AddRange(new object[] {
|
this.cmbdomainStrategy.Items.AddRange(new object[] {
|
||||||
resources.GetString("cmbdomainStrategy.Items"),
|
resources.GetString("cmbdomainStrategy.Items"),
|
||||||
resources.GetString("cmbdomainStrategy.Items1"),
|
resources.GetString("cmbdomainStrategy.Items1"),
|
||||||
resources.GetString("cmbdomainStrategy.Items2")});
|
resources.GetString("cmbdomainStrategy.Items2")});
|
||||||
|
resources.ApplyResources(this.cmbdomainStrategy, "cmbdomainStrategy");
|
||||||
this.cmbdomainStrategy.Name = "cmbdomainStrategy";
|
this.cmbdomainStrategy.Name = "cmbdomainStrategy";
|
||||||
//
|
//
|
||||||
// label15
|
// label15
|
||||||
|
@ -417,7 +415,6 @@
|
||||||
//
|
//
|
||||||
// tabPage6
|
// tabPage6
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.tabPage6, "tabPage6");
|
|
||||||
this.tabPage6.Controls.Add(this.chkKcpcongestion);
|
this.tabPage6.Controls.Add(this.chkKcpcongestion);
|
||||||
this.tabPage6.Controls.Add(this.txtKcpwriteBufferSize);
|
this.tabPage6.Controls.Add(this.txtKcpwriteBufferSize);
|
||||||
this.tabPage6.Controls.Add(this.label10);
|
this.tabPage6.Controls.Add(this.label10);
|
||||||
|
@ -431,6 +428,7 @@
|
||||||
this.tabPage6.Controls.Add(this.label7);
|
this.tabPage6.Controls.Add(this.label7);
|
||||||
this.tabPage6.Controls.Add(this.txtKcpmtu);
|
this.tabPage6.Controls.Add(this.txtKcpmtu);
|
||||||
this.tabPage6.Controls.Add(this.label6);
|
this.tabPage6.Controls.Add(this.label6);
|
||||||
|
resources.ApplyResources(this.tabPage6, "tabPage6");
|
||||||
this.tabPage6.Name = "tabPage6";
|
this.tabPage6.Name = "tabPage6";
|
||||||
this.tabPage6.UseVisualStyleBackColor = true;
|
this.tabPage6.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
|
@ -502,41 +500,29 @@
|
||||||
//
|
//
|
||||||
// tabPage7
|
// tabPage7
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.tabPage7, "tabPage7");
|
|
||||||
this.tabPage7.Controls.Add(this.cbFreshrate);
|
this.tabPage7.Controls.Add(this.cbFreshrate);
|
||||||
this.tabPage7.Controls.Add(this.tbCacheDays);
|
|
||||||
this.tabPage7.Controls.Add(this.lbFreshrate);
|
this.tabPage7.Controls.Add(this.lbFreshrate);
|
||||||
this.tabPage7.Controls.Add(this.lbCacheDays);
|
|
||||||
this.tabPage7.Controls.Add(this.chkEnableStatistics);
|
this.tabPage7.Controls.Add(this.chkEnableStatistics);
|
||||||
this.tabPage7.Controls.Add(this.chkAllowLANConn);
|
this.tabPage7.Controls.Add(this.chkAllowLANConn);
|
||||||
this.tabPage7.Controls.Add(this.txturlGFWList);
|
this.tabPage7.Controls.Add(this.txturlGFWList);
|
||||||
this.tabPage7.Controls.Add(this.label13);
|
this.tabPage7.Controls.Add(this.label13);
|
||||||
this.tabPage7.Controls.Add(this.chkAutoRun);
|
this.tabPage7.Controls.Add(this.chkAutoRun);
|
||||||
|
resources.ApplyResources(this.tabPage7, "tabPage7");
|
||||||
this.tabPage7.Name = "tabPage7";
|
this.tabPage7.Name = "tabPage7";
|
||||||
this.tabPage7.UseVisualStyleBackColor = true;
|
this.tabPage7.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// cbFreshrate
|
// cbFreshrate
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.cbFreshrate, "cbFreshrate");
|
|
||||||
this.cbFreshrate.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
this.cbFreshrate.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
this.cbFreshrate.FormattingEnabled = true;
|
this.cbFreshrate.FormattingEnabled = true;
|
||||||
|
resources.ApplyResources(this.cbFreshrate, "cbFreshrate");
|
||||||
this.cbFreshrate.Name = "cbFreshrate";
|
this.cbFreshrate.Name = "cbFreshrate";
|
||||||
//
|
//
|
||||||
// tbCacheDays
|
|
||||||
//
|
|
||||||
resources.ApplyResources(this.tbCacheDays, "tbCacheDays");
|
|
||||||
this.tbCacheDays.Name = "tbCacheDays";
|
|
||||||
//
|
|
||||||
// lbFreshrate
|
// lbFreshrate
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.lbFreshrate, "lbFreshrate");
|
resources.ApplyResources(this.lbFreshrate, "lbFreshrate");
|
||||||
this.lbFreshrate.Name = "lbFreshrate";
|
this.lbFreshrate.Name = "lbFreshrate";
|
||||||
//
|
//
|
||||||
// lbCacheDays
|
|
||||||
//
|
|
||||||
resources.ApplyResources(this.lbCacheDays, "lbCacheDays");
|
|
||||||
this.lbCacheDays.Name = "lbCacheDays";
|
|
||||||
//
|
|
||||||
// chkEnableStatistics
|
// chkEnableStatistics
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.chkEnableStatistics, "chkEnableStatistics");
|
resources.ApplyResources(this.chkEnableStatistics, "chkEnableStatistics");
|
||||||
|
@ -567,9 +553,9 @@
|
||||||
//
|
//
|
||||||
// panel2
|
// panel2
|
||||||
//
|
//
|
||||||
resources.ApplyResources(this.panel2, "panel2");
|
|
||||||
this.panel2.Controls.Add(this.btnClose);
|
this.panel2.Controls.Add(this.btnClose);
|
||||||
this.panel2.Controls.Add(this.btnOK);
|
this.panel2.Controls.Add(this.btnOK);
|
||||||
|
resources.ApplyResources(this.panel2, "panel2");
|
||||||
this.panel2.Name = "panel2";
|
this.panel2.Name = "panel2";
|
||||||
//
|
//
|
||||||
// btnOK
|
// btnOK
|
||||||
|
@ -682,8 +668,6 @@
|
||||||
private System.Windows.Forms.CheckBox chksniffingEnabled2;
|
private System.Windows.Forms.CheckBox chksniffingEnabled2;
|
||||||
private System.Windows.Forms.Button btnSetDefRountingRule;
|
private System.Windows.Forms.Button btnSetDefRountingRule;
|
||||||
private System.Windows.Forms.CheckBox chkEnableStatistics;
|
private System.Windows.Forms.CheckBox chkEnableStatistics;
|
||||||
private System.Windows.Forms.TextBox tbCacheDays;
|
|
||||||
private System.Windows.Forms.Label lbCacheDays;
|
|
||||||
private System.Windows.Forms.ComboBox cbFreshrate;
|
private System.Windows.Forms.ComboBox cbFreshrate;
|
||||||
private System.Windows.Forms.Label lbFreshrate;
|
private System.Windows.Forms.Label lbFreshrate;
|
||||||
private System.Windows.Forms.Label label16;
|
private System.Windows.Forms.Label label16;
|
||||||
|
|
|
@ -115,8 +115,6 @@ namespace v2rayN.Forms
|
||||||
var enableStatistics = config.enableStatistics;
|
var enableStatistics = config.enableStatistics;
|
||||||
chkEnableStatistics.Checked = enableStatistics;
|
chkEnableStatistics.Checked = enableStatistics;
|
||||||
|
|
||||||
tbCacheDays.Text = config.CacheDays.ToString();
|
|
||||||
|
|
||||||
|
|
||||||
var cbSource = new ComboItem[]
|
var cbSource = new ComboItem[]
|
||||||
{
|
{
|
||||||
|
@ -332,13 +330,6 @@ namespace v2rayN.Forms
|
||||||
|
|
||||||
var lastEnableStatistics = config.enableStatistics;
|
var lastEnableStatistics = config.enableStatistics;
|
||||||
config.enableStatistics = chkEnableStatistics.Checked;
|
config.enableStatistics = chkEnableStatistics.Checked;
|
||||||
|
|
||||||
uint days = 0;
|
|
||||||
var valid = uint.TryParse(tbCacheDays.Text, out days);
|
|
||||||
if (!valid)
|
|
||||||
days = 7;
|
|
||||||
config.CacheDays = days;
|
|
||||||
|
|
||||||
config.statisticsFreshRate = (int)cbFreshrate.SelectedValue;
|
config.statisticsFreshRate = (int)cbFreshrate.SelectedValue;
|
||||||
|
|
||||||
//if(lastEnableStatistics != config.enableStatistics)
|
//if(lastEnableStatistics != config.enableStatistics)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -13,7 +13,7 @@ namespace v2rayN
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SpeedTestUrl
|
/// SpeedTestUrl
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string SpeedTestUrl = @"http://speedtest-sfo2.digitalocean.com/10mb.test";
|
public const string SpeedTestUrl = @"http://speedtest-sgp1.digitalocean.com/10mb.test";
|
||||||
public const string SpeedPingTestUrl = @"https://www.google.com/generate_204";
|
public const string SpeedPingTestUrl = @"https://www.google.com/generate_204";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -160,8 +160,7 @@ namespace v2rayN
|
||||||
medium = 2000,
|
medium = 2000,
|
||||||
slow = 3000
|
slow = 3000
|
||||||
}
|
}
|
||||||
public const string StatisticLogDirectory = "Statistics";
|
public const string StatisticLogOverall = "StatisticLogOverall.json";
|
||||||
public const string StatisticLogOverall = "overall.txt";
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
@ -41,10 +41,7 @@ namespace v2rayN.Handler
|
||||||
|
|
||||||
////默认监听端口
|
////默认监听端口
|
||||||
//config.pacPort = 8888;
|
//config.pacPort = 8888;
|
||||||
|
|
||||||
// 默认缓存七天
|
|
||||||
config.CacheDays = 7;
|
|
||||||
|
|
||||||
// 默认不开启统计
|
// 默认不开启统计
|
||||||
config.enableStatistics = false;
|
config.enableStatistics = false;
|
||||||
|
|
||||||
|
@ -125,6 +122,10 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
config.urlGFWList = Global.GFWLIST_URL;
|
config.urlGFWList = Global.GFWLIST_URL;
|
||||||
}
|
}
|
||||||
|
if (Utils.IsNullOrEmpty(config.remoteDNS))
|
||||||
|
{
|
||||||
|
config.remoteDNS = "1.1.1.1";
|
||||||
|
}
|
||||||
|
|
||||||
if (config.subItem == null)
|
if (config.subItem == null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,15 +40,13 @@ namespace v2rayN.Handler
|
||||||
private string latestUrl = "https://github.com/v2ray/v2ray-core/releases/latest";
|
private string latestUrl = "https://github.com/v2ray/v2ray-core/releases/latest";
|
||||||
private const string coreURL = "https://github.com/v2ray/v2ray-core/releases/download/{0}/v2ray-windows-{1}.zip";
|
private const string coreURL = "https://github.com/v2ray/v2ray-core/releases/download/{0}/v2ray-windows-{1}.zip";
|
||||||
private int progressPercentage = -1;
|
private int progressPercentage = -1;
|
||||||
private bool blFirst = true;
|
|
||||||
private long totalBytesToReceive = 0;
|
private long totalBytesToReceive = 0;
|
||||||
private DateTime totalDatetime = new DateTime();
|
private DateTime totalDatetime = new DateTime();
|
||||||
|
private int DownloadTimeout = -1;
|
||||||
|
|
||||||
public void AbsoluteV2rayCore(Config config)
|
public void AbsoluteV2rayCore(Config config)
|
||||||
{
|
{
|
||||||
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; //TLS 1.2
|
SetSecurityProtocol();
|
||||||
ServicePointManager.DefaultConnectionLimit = 256;
|
|
||||||
WebRequest request = WebRequest.Create(latestUrl);
|
WebRequest request = WebRequest.Create(latestUrl);
|
||||||
request.BeginGetResponse(new AsyncCallback(OnResponseV2rayCore), request);
|
request.BeginGetResponse(new AsyncCallback(OnResponseV2rayCore), request);
|
||||||
}
|
}
|
||||||
|
@ -87,12 +85,11 @@ namespace v2rayN.Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void DownloadFileAsync(Config config, string url, WebProxy webProxy)
|
public void DownloadFileAsync(Config config, string url, WebProxy webProxy, int downloadTimeout)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; //TLS 1.2
|
SetSecurityProtocol();
|
||||||
ServicePointManager.DefaultConnectionLimit = 256;
|
|
||||||
if (UpdateCompleted != null)
|
if (UpdateCompleted != null)
|
||||||
{
|
{
|
||||||
UpdateCompleted(this, new ResultEventArgs(false, "Downloading..."));
|
UpdateCompleted(this, new ResultEventArgs(false, "Downloading..."));
|
||||||
|
@ -101,6 +98,7 @@ namespace v2rayN.Handler
|
||||||
progressPercentage = -1;
|
progressPercentage = -1;
|
||||||
|
|
||||||
WebClientEx ws = new WebClientEx();
|
WebClientEx ws = new WebClientEx();
|
||||||
|
DownloadTimeout = downloadTimeout;
|
||||||
if (webProxy != null)
|
if (webProxy != null)
|
||||||
{
|
{
|
||||||
ws.Proxy = webProxy;// new WebProxy(Global.Loopback, Global.httpPort);
|
ws.Proxy = webProxy;// new WebProxy(Global.Loopback, Global.httpPort);
|
||||||
|
@ -109,7 +107,7 @@ namespace v2rayN.Handler
|
||||||
ws.DownloadFileCompleted += ws_DownloadFileCompleted;
|
ws.DownloadFileCompleted += ws_DownloadFileCompleted;
|
||||||
ws.DownloadProgressChanged += ws_DownloadProgressChanged;
|
ws.DownloadProgressChanged += ws_DownloadProgressChanged;
|
||||||
ws.DownloadFileAsync(new Uri(url), Utils.GetPath(DownloadFileName));
|
ws.DownloadFileAsync(new Uri(url), Utils.GetPath(DownloadFileName));
|
||||||
blFirst = true;
|
totalBytesToReceive = 0;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -122,14 +120,24 @@ namespace v2rayN.Handler
|
||||||
|
|
||||||
void ws_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
|
void ws_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (blFirst)
|
|
||||||
{
|
|
||||||
totalBytesToReceive = e.TotalBytesToReceive - e.BytesReceived;
|
|
||||||
totalDatetime = DateTime.Now;
|
|
||||||
blFirst = false;
|
|
||||||
}
|
|
||||||
if (UpdateCompleted != null)
|
if (UpdateCompleted != null)
|
||||||
{
|
{
|
||||||
|
if (DownloadTimeout != -1)
|
||||||
|
{
|
||||||
|
if ((DateTime.Now - totalDatetime).TotalSeconds > DownloadTimeout)
|
||||||
|
{
|
||||||
|
((WebClientEx)sender).CancelAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (totalBytesToReceive == 0)
|
||||||
|
{
|
||||||
|
totalDatetime = DateTime.Now;
|
||||||
|
totalBytesToReceive = e.BytesReceived;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
totalBytesToReceive = e.BytesReceived;
|
||||||
|
|
||||||
if (progressPercentage != e.ProgressPercentage && e.ProgressPercentage % 10 == 0)
|
if (progressPercentage != e.ProgressPercentage && e.ProgressPercentage % 10 == 0)
|
||||||
{
|
{
|
||||||
progressPercentage = e.ProgressPercentage;
|
progressPercentage = e.ProgressPercentage;
|
||||||
|
@ -143,19 +151,29 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (e.Error == null
|
if (UpdateCompleted != null)
|
||||||
|| Utils.IsNullOrEmpty(e.Error.ToString()))
|
|
||||||
{
|
{
|
||||||
if (UpdateCompleted != null)
|
if (e.Cancelled)
|
||||||
{
|
{
|
||||||
|
((WebClientEx)sender).Dispose();
|
||||||
|
TimeSpan ts = (DateTime.Now - totalDatetime);
|
||||||
|
string speed = string.Format("<{0} M/s", (totalBytesToReceive / ts.TotalMilliseconds / 1000).ToString("#0.##"));
|
||||||
|
UpdateCompleted(this, new ResultEventArgs(true, speed));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Error == null
|
||||||
|
|| Utils.IsNullOrEmpty(e.Error.ToString()))
|
||||||
|
{
|
||||||
|
|
||||||
TimeSpan ts = (DateTime.Now - totalDatetime);
|
TimeSpan ts = (DateTime.Now - totalDatetime);
|
||||||
string speed = string.Format("{0} M/s", (totalBytesToReceive / ts.TotalMilliseconds / 1000).ToString("#0.##"));
|
string speed = string.Format("{0} M/s", (totalBytesToReceive / ts.TotalMilliseconds / 1000).ToString("#0.##"));
|
||||||
UpdateCompleted(this, new ResultEventArgs(true, speed));
|
UpdateCompleted(this, new ResultEventArgs(true, speed));
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
throw e.Error;
|
||||||
throw e.Error;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -176,8 +194,7 @@ namespace v2rayN.Handler
|
||||||
string source = string.Empty;
|
string source = string.Empty;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; //TLS 1.2
|
SetSecurityProtocol();
|
||||||
ServicePointManager.DefaultConnectionLimit = 256;
|
|
||||||
|
|
||||||
WebClientEx ws = new WebClientEx();
|
WebClientEx ws = new WebClientEx();
|
||||||
ws.DownloadStringCompleted += Ws_DownloadStringCompleted;
|
ws.DownloadStringCompleted += Ws_DownloadStringCompleted;
|
||||||
|
@ -216,6 +233,13 @@ namespace v2rayN.Handler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SetSecurityProtocol()
|
||||||
|
{
|
||||||
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
|
||||||
|
| SecurityProtocolType.Tls
|
||||||
|
| SecurityProtocolType.Tls11
|
||||||
|
| SecurityProtocolType.Tls12;
|
||||||
|
ServicePointManager.DefaultConnectionLimit = 256;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,7 +244,7 @@ namespace v2rayN.Handler
|
||||||
|
|
||||||
testCounter++;
|
testCounter++;
|
||||||
var webProxy = new WebProxy(Global.Loopback, httpPort + index);
|
var webProxy = new WebProxy(Global.Loopback, httpPort + index);
|
||||||
downloadHandle2.DownloadFileAsync(_config, url, webProxy);
|
downloadHandle2.DownloadFileAsync(_config, url, webProxy, 30);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,58 +15,33 @@ namespace v2rayN.Handler
|
||||||
class StatisticsHandler
|
class StatisticsHandler
|
||||||
{
|
{
|
||||||
private Mode.Config config_;
|
private Mode.Config config_;
|
||||||
|
private ServerStatistics serverStatistics_;
|
||||||
private Channel channel_;
|
private Channel channel_;
|
||||||
private StatsService.StatsServiceClient client_;
|
private StatsService.StatsServiceClient client_;
|
||||||
private Thread workThread_;
|
private Thread workThread_;
|
||||||
|
private bool exitFlag_;
|
||||||
|
|
||||||
Action<ulong, ulong, ulong, ulong, List<Mode.ServerStatistics>> updateFunc_;
|
Action<ulong, ulong, List<ServerStatItem>> updateFunc_;
|
||||||
|
|
||||||
private bool enabled_;
|
|
||||||
public bool Enable
|
public bool Enable
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return enabled_;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
enabled_ = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool UpdateUI;
|
|
||||||
|
|
||||||
public ulong TotalUp
|
|
||||||
{
|
|
||||||
get; private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ulong TotalDown
|
|
||||||
{
|
|
||||||
get; private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Mode.ServerStatistics> Statistic
|
|
||||||
{
|
{
|
||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ulong Up
|
public bool UpdateUI
|
||||||
{
|
{
|
||||||
get; private set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ulong Down
|
public List<ServerStatItem> Statistic
|
||||||
{
|
{
|
||||||
get; private set;
|
get
|
||||||
|
{
|
||||||
|
return serverStatistics_.server;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string logPath_;
|
public StatisticsHandler(Mode.Config config, Action<ulong, ulong, List<ServerStatItem>> update)
|
||||||
|
|
||||||
private bool exitFlag_; // true to close workThread_
|
|
||||||
|
|
||||||
public StatisticsHandler(Mode.Config config, Action<ulong, ulong, ulong, ulong, List<Mode.ServerStatistics>> update)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -86,20 +61,11 @@ namespace v2rayN.Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
config_ = config;
|
config_ = config;
|
||||||
enabled_ = config.enableStatistics;
|
Enable = config.enableStatistics;
|
||||||
UpdateUI = false;
|
UpdateUI = false;
|
||||||
updateFunc_ = update;
|
updateFunc_ = update;
|
||||||
logPath_ = Utils.GetPath(Global.StatisticLogDirectory);
|
|
||||||
Statistic = new List<Mode.ServerStatistics>();
|
|
||||||
exitFlag_ = false;
|
exitFlag_ = false;
|
||||||
|
|
||||||
DeleteExpiredLog();
|
|
||||||
foreach (var server in config.vmess)
|
|
||||||
{
|
|
||||||
var statistic = new ServerStatistics(server.remarks, server.address, server.port, server.path, server.requestHost, 0, 0, 0, 0);
|
|
||||||
Statistic.Add(statistic);
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadFromFile();
|
LoadFromFile();
|
||||||
|
|
||||||
GrpcInit();
|
GrpcInit();
|
||||||
|
@ -125,7 +91,6 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
exitFlag_ = true;
|
exitFlag_ = true;
|
||||||
channel_.ShutdownAsync();
|
channel_.ShutdownAsync();
|
||||||
}
|
}
|
||||||
|
@ -141,7 +106,7 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (enabled_ && channel_.State == ChannelState.Ready)
|
if (Enable && channel_.State == ChannelState.Ready)
|
||||||
{
|
{
|
||||||
QueryStatsResponse res = null;
|
QueryStatsResponse res = null;
|
||||||
try
|
try
|
||||||
|
@ -155,32 +120,23 @@ namespace v2rayN.Handler
|
||||||
|
|
||||||
if (res != null)
|
if (res != null)
|
||||||
{
|
{
|
||||||
var addr = config_.address();
|
var itemId = config_.getItemId();
|
||||||
var port = config_.port();
|
var serverStatItem = GetServerStatItem(itemId);
|
||||||
var path = config_.path();
|
|
||||||
var cur = Statistic.FindIndex(item => item.address == addr && item.port == port && item.path == path);
|
|
||||||
ulong up = 0,
|
ulong up = 0,
|
||||||
down = 0;
|
down = 0;
|
||||||
|
|
||||||
//TODO: parse output
|
//TODO: parse output
|
||||||
ParseOutput(res.Stat, out up, out down);
|
ParseOutput(res.Stat, out up, out down);
|
||||||
|
|
||||||
Up = up;
|
serverStatItem.todayUp += up;
|
||||||
Down = down;
|
serverStatItem.todayDown += down;
|
||||||
|
serverStatItem.totalUp += up;
|
||||||
TotalUp += up;
|
serverStatItem.totalDown += down;
|
||||||
TotalDown += down;
|
|
||||||
|
|
||||||
if (cur != -1)
|
|
||||||
{
|
|
||||||
Statistic[cur].todayUp += up;
|
|
||||||
Statistic[cur].todayDown += down;
|
|
||||||
Statistic[cur].totalUp += up;
|
|
||||||
Statistic[cur].totalDown += down;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UpdateUI)
|
if (UpdateUI)
|
||||||
updateFunc_(TotalUp, TotalDown, Up, Down, Statistic);
|
{
|
||||||
|
updateFunc_(up, down, new List<ServerStatItem> { serverStatItem });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Thread.Sleep(config_.statisticsFreshRate);
|
Thread.Sleep(config_.statisticsFreshRate);
|
||||||
|
@ -193,7 +149,82 @@ namespace v2rayN.Handler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ParseOutput(Google.Protobuf.Collections.RepeatedField<Stat> source, out ulong up, out ulong down)
|
public void LoadFromFile()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string result = Utils.LoadResource(Utils.GetPath(Global.StatisticLogOverall));
|
||||||
|
if (!Utils.IsNullOrEmpty(result))
|
||||||
|
{
|
||||||
|
//转成Json
|
||||||
|
serverStatistics_ = Utils.FromJson<ServerStatistics>(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serverStatistics_ == null)
|
||||||
|
{
|
||||||
|
serverStatistics_ = new ServerStatistics();
|
||||||
|
}
|
||||||
|
if (serverStatistics_.server == null)
|
||||||
|
{
|
||||||
|
serverStatistics_.server = new List<ServerStatItem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
var ticks = DateTime.Now.Date.Ticks;
|
||||||
|
foreach (var item in serverStatistics_.server)
|
||||||
|
{
|
||||||
|
if (item.dateNow != ticks)
|
||||||
|
{
|
||||||
|
item.todayUp = 0;
|
||||||
|
item.todayDown = 0;
|
||||||
|
item.dateNow = ticks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Utils.SaveLog(ex.Message, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveToFile()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Utils.ToJsonFile(serverStatistics_, Utils.GetPath(Global.StatisticLogOverall));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Utils.SaveLog(ex.Message, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ServerStatItem GetServerStatItem(string itemId)
|
||||||
|
{
|
||||||
|
var ticks = DateTime.Now.Date.Ticks;
|
||||||
|
var cur = Statistic.FindIndex(item => item.itemId == itemId);
|
||||||
|
if (cur < 0)
|
||||||
|
{
|
||||||
|
Statistic.Add(new ServerStatItem
|
||||||
|
{
|
||||||
|
itemId = itemId,
|
||||||
|
totalUp = 0,
|
||||||
|
totalDown = 0,
|
||||||
|
todayUp = 0,
|
||||||
|
todayDown = 0,
|
||||||
|
dateNow = ticks
|
||||||
|
});
|
||||||
|
cur = Statistic.Count - 1;
|
||||||
|
}
|
||||||
|
if (Statistic[cur].dateNow != ticks)
|
||||||
|
{
|
||||||
|
Statistic[cur].todayUp = 0;
|
||||||
|
Statistic[cur].todayDown = 0;
|
||||||
|
Statistic[cur].dateNow = ticks;
|
||||||
|
}
|
||||||
|
return Statistic[cur];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ParseOutput(Google.Protobuf.Collections.RepeatedField<Stat> source, out ulong up, out ulong down)
|
||||||
{
|
{
|
||||||
|
|
||||||
up = 0; down = 0;
|
up = 0; down = 0;
|
||||||
|
@ -231,218 +262,6 @@ namespace v2rayN.Handler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveToFile()
|
|
||||||
{
|
|
||||||
if (!Directory.Exists(logPath_))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(logPath_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 总流量统计文件
|
|
||||||
var overallPath = Path.Combine(logPath_, Global.StatisticLogOverall);
|
|
||||||
if (!File.Exists(overallPath))
|
|
||||||
{
|
|
||||||
File.Create(overallPath);
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (var overallWriter = new StreamWriter(overallPath))
|
|
||||||
{
|
|
||||||
double up_amount, down_amount;
|
|
||||||
string up_unit, down_unit;
|
|
||||||
|
|
||||||
Utils.ToHumanReadable(TotalUp, out up_amount, out up_unit);
|
|
||||||
Utils.ToHumanReadable(TotalDown, out down_amount, out down_unit);
|
|
||||||
|
|
||||||
overallWriter.WriteLine($"LastUpdate {DateTime.Now.ToString("yyyy-MM-dd")} {DateTime.Now.ToLongTimeString()}");
|
|
||||||
overallWriter.WriteLine($"UP {string.Format("{0:f2}", up_amount)}{up_unit} {TotalUp}");
|
|
||||||
overallWriter.WriteLine($"DOWN {string.Format("{0:f2}", down_amount)}{down_unit} {TotalDown}");
|
|
||||||
foreach (var s in Statistic)
|
|
||||||
{
|
|
||||||
overallWriter.WriteLine($"* {s.name} {s.address} {s.port} {s.path} {s.host} {s.totalUp} {s.totalDown}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Utils.SaveLog(ex.Message, ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 当天流量记录文件
|
|
||||||
var dailyPath = Path.Combine(logPath_, $"{DateTime.Now.ToString("yyyy-MM-dd")}.txt");
|
|
||||||
if (!File.Exists(dailyPath))
|
|
||||||
{
|
|
||||||
File.Create(dailyPath);
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (var dailyWriter = new StreamWriter(dailyPath))
|
|
||||||
{
|
|
||||||
dailyWriter.WriteLine($"LastUpdate {DateTime.Now.ToString("yyyy-MM-dd")} {DateTime.Now.ToLongTimeString()}");
|
|
||||||
foreach (var s in Statistic)
|
|
||||||
{
|
|
||||||
dailyWriter.WriteLine($"* {s.name} {s.address} {s.port} {s.path} {s.host} {s.todayUp} {s.todayDown}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Utils.SaveLog(ex.Message, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LoadFromFile()
|
|
||||||
{
|
|
||||||
if (!Directory.Exists(logPath_)) return;
|
|
||||||
|
|
||||||
// 总流量统计文件
|
|
||||||
///
|
|
||||||
/// 文件结构
|
|
||||||
/// LastUpdate [date] [time]
|
|
||||||
/// UP [readable string] [amount]
|
|
||||||
/// DOWN [readable string] [amount]
|
|
||||||
/// 每行每个数据空格分隔
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Utils.SaveLog(logPath_ + Global.StatisticLogOverall);
|
|
||||||
var overallPath = Path.Combine(logPath_, Global.StatisticLogOverall);
|
|
||||||
if (File.Exists(overallPath))
|
|
||||||
{
|
|
||||||
using (var overallReader = new StreamReader(overallPath))
|
|
||||||
{
|
|
||||||
while (!overallReader.EndOfStream)
|
|
||||||
{
|
|
||||||
var line = overallReader.ReadLine();
|
|
||||||
if (line.StartsWith("LastUpdate"))
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (line.StartsWith("UP"))
|
|
||||||
{
|
|
||||||
var datas = line.Split(' ');
|
|
||||||
if (datas.Length < 3) return;
|
|
||||||
TotalUp = ulong.Parse(datas[2]);
|
|
||||||
}
|
|
||||||
else if (line.StartsWith("DOWN"))
|
|
||||||
{
|
|
||||||
var datas = line.Split(' ');
|
|
||||||
if (datas.Length < 3) return;
|
|
||||||
TotalDown = ulong.Parse(datas[2]);
|
|
||||||
}
|
|
||||||
else if (line.StartsWith("*"))
|
|
||||||
{
|
|
||||||
var datas = line.Split(' ');
|
|
||||||
if (datas.Length < 8) return;
|
|
||||||
var name = datas[1];
|
|
||||||
var address = datas[2];
|
|
||||||
var port = int.Parse(datas[3]);
|
|
||||||
var path = datas[4];
|
|
||||||
var host = datas[5];
|
|
||||||
var totalUp = ulong.Parse(datas[6]);
|
|
||||||
var totalDown = ulong.Parse(datas[7]);
|
|
||||||
|
|
||||||
var temp = new ServerStatistics(name, address, port, path, host, 0, 0, 0, 0);
|
|
||||||
var index = Statistic.FindIndex(item => Utils.IsIdenticalServer(item, temp));
|
|
||||||
if (index != -1)
|
|
||||||
{
|
|
||||||
Statistic[index].totalUp = totalUp;
|
|
||||||
Statistic[index].totalDown = totalDown;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var s = new Mode.ServerStatistics(name, address, port, path, host, totalUp, totalDown, 0, 0);
|
|
||||||
Statistic.Add(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Utils.SaveLog(ex.Message, ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Utils.SaveLog(logPath_ + $"{DateTime.Now.ToString("yyyy-MM-dd")}.txt");
|
|
||||||
var dailyPath = Path.Combine(logPath_, $"{DateTime.Now.ToString("yyyy-MM-dd")}.txt");
|
|
||||||
if (File.Exists(dailyPath))
|
|
||||||
{
|
|
||||||
|
|
||||||
using (var dailyReader = new StreamReader(dailyPath))
|
|
||||||
{
|
|
||||||
while (!dailyReader.EndOfStream)
|
|
||||||
{
|
|
||||||
var line = dailyReader.ReadLine();
|
|
||||||
if (line.StartsWith("LastUpdate"))
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (line.StartsWith("*"))
|
|
||||||
{
|
|
||||||
var datas = line.Split(' ');
|
|
||||||
if (datas.Length < 8) return;
|
|
||||||
var name = datas[1];
|
|
||||||
var address = datas[2];
|
|
||||||
var port = int.Parse(datas[3]);
|
|
||||||
var path = datas[4];
|
|
||||||
var host = datas[5];
|
|
||||||
var todayUp = ulong.Parse(datas[6]);
|
|
||||||
var todayDown = ulong.Parse(datas[7]);
|
|
||||||
|
|
||||||
var temp = new ServerStatistics(name, address, port, path, host, 0, 0, 0, 0);
|
|
||||||
var index = Statistic.FindIndex(item => Utils.IsIdenticalServer(item, temp));
|
|
||||||
if (index != -1)
|
|
||||||
{
|
|
||||||
Statistic[index].todayUp = todayUp;
|
|
||||||
Statistic[index].todayDown = todayDown;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var s = new Mode.ServerStatistics(name, address, port, path, host, 0, 0, todayUp, todayDown);
|
|
||||||
Statistic.Add(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Utils.SaveLog(ex.Message, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void DeleteExpiredLog()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!Directory.Exists(logPath_)) return;
|
|
||||||
var dirInfo = new DirectoryInfo(logPath_);
|
|
||||||
var files = dirInfo.GetFiles();
|
|
||||||
foreach (var file in files)
|
|
||||||
{
|
|
||||||
if (file.Name == "overall.txt") continue;
|
|
||||||
var name = file.Name.Split('.')[0];
|
|
||||||
var ft = DateTime.Parse(name);
|
|
||||||
var ct = DateTime.Now;
|
|
||||||
var dur = ct - ft;
|
|
||||||
if (dur.Days > config_.CacheDays)
|
|
||||||
{
|
|
||||||
file.Delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Utils.SaveLog(ex.Message, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int GetFreePort()
|
private int GetFreePort()
|
||||||
{
|
{
|
||||||
int defaultPort = 28123;
|
int defaultPort = 28123;
|
||||||
|
|
|
@ -145,26 +145,7 @@ namespace v2rayN.Mode
|
||||||
{
|
{
|
||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 统计数据缓存天数 [0, 30]
|
|
||||||
/// * 0 关闭单独每天使用流量的缓存
|
|
||||||
/// * 无论如何不会关闭总流量的缓存
|
|
||||||
/// </summary>
|
|
||||||
private uint cacheDays;
|
|
||||||
public uint CacheDays
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return cacheDays;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value < 0) cacheDays = 0;
|
|
||||||
else if (value > 30) cacheDays = 30;
|
|
||||||
else cacheDays = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自定义远程DNS
|
/// 自定义远程DNS
|
||||||
|
@ -337,6 +318,16 @@ namespace v2rayN.Mode
|
||||||
return vmess[index].getSummary();
|
return vmess[index].getSummary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string getItemId()
|
||||||
|
{
|
||||||
|
if (index < 0)
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vmess[index].getItemId();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -420,6 +411,14 @@ namespace v2rayN.Mode
|
||||||
}
|
}
|
||||||
return subid.Substring(0, 4);
|
return subid.Substring(0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string getItemId()
|
||||||
|
{
|
||||||
|
var itemId = $"{address}{port}{requestHost}{path}";
|
||||||
|
itemId = Utils.Base64Encode(itemId);
|
||||||
|
return itemId;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 版本(现在=2)
|
/// 版本(现在=2)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,35 +1,43 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace v2rayN.Mode
|
namespace v2rayN.Mode
|
||||||
{
|
{
|
||||||
class ServerStatistics
|
[Serializable]
|
||||||
|
public class ServerStatistics
|
||||||
{
|
{
|
||||||
public string name;
|
public List<ServerStatItem> server
|
||||||
public string address;
|
|
||||||
public int port;
|
|
||||||
public string path;
|
|
||||||
public string host;
|
|
||||||
public ulong totalUp;
|
|
||||||
public ulong totalDown;
|
|
||||||
public ulong todayUp;
|
|
||||||
public ulong todayDown;
|
|
||||||
|
|
||||||
public ServerStatistics() { }
|
|
||||||
public ServerStatistics(string name, string addr, int port, string path, string host, ulong totalUp, ulong totalDown, ulong todayUp, ulong todayDown)
|
|
||||||
{
|
{
|
||||||
this.name = name;
|
get; set;
|
||||||
this.address = addr;
|
}
|
||||||
this.port = port;
|
}
|
||||||
this.path = path;
|
|
||||||
this.host = host;
|
[Serializable]
|
||||||
this.totalUp = totalUp;
|
public class ServerStatItem
|
||||||
this.totalDown = totalDown;
|
{
|
||||||
this.todayUp = todayUp;
|
public string itemId
|
||||||
this.todayDown = todayDown;
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
public ulong totalUp
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
public ulong totalDown
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
public ulong todayUp
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
public ulong todayDown
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
public long dateNow
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,4 +33,4 @@ using System.Runtime.InteropServices;
|
||||||
// 方法是按如下所示使用“*”:
|
// 方法是按如下所示使用“*”:
|
||||||
//[assembly: AssemblyVersion("1.0.*")]
|
//[assembly: AssemblyVersion("1.0.*")]
|
||||||
//[assembly: AssemblyVersion("1.0.0")]
|
//[assembly: AssemblyVersion("1.0.0")]
|
||||||
[assembly: AssemblyFileVersion("2.50")]
|
[assembly: AssemblyFileVersion("2.51")]
|
||||||
|
|
|
@ -443,15 +443,6 @@ namespace v2rayN
|
||||||
return Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase);
|
return Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsIdenticalServer(Mode.ServerStatistics a, Mode.ServerStatistics b)
|
|
||||||
{
|
|
||||||
return (a.address == b.address
|
|
||||||
&& a.port == b.port
|
|
||||||
&& a.path == b.path
|
|
||||||
&& a.host == b.host
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 开机自动启动
|
#region 开机自动启动
|
||||||
|
|
Loading…
Reference in a new issue