This commit is contained in:
2dust 2019-11-25 13:22:35 +08:00
parent 912f682359
commit 3f1688f8b7
13 changed files with 1902 additions and 2149 deletions

View file

@ -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);
} }
})); }));
} }

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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)
{ {

View file

@ -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;
}
} }
} }

View file

@ -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;
} }

View file

@ -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;

View file

@ -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>

View file

@ -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;
} }
} }
} }

View file

@ -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")]

View file

@ -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