diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 50c56b7e..15a5d76a 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -26,6 +26,8 @@ namespace Shadowsocks.Controller private PolipoRunner polipoRunner; private GFWListUpdater gfwListUpdater; private AvailabilityStatistics _availabilityStatics; + public StatisticsStrategyConfiguration StatisticsConfiguration { get; private set; } + private bool stopped = false; private bool _systemProxyIsDirty = false; @@ -53,10 +55,12 @@ namespace Shadowsocks.Controller public ShadowsocksController() { _config = Configuration.Load(); + StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); _strategyManager = new StrategyManager(this); StartReleasingMemory(); } + public void Start() { Reload(); @@ -127,8 +131,8 @@ namespace Shadowsocks.Controller public void SaveStrategyConfigurations(StatisticsStrategyConfiguration configuration) { - _config.statisticsStrategyConfiguration = configuration; - SaveConfig(_config); + StatisticsConfiguration = configuration; + StatisticsStrategyConfiguration.Save(configuration); } public bool AddServerBySSURL(string ssURL) @@ -290,6 +294,7 @@ namespace Shadowsocks.Controller { // some logic in configuration updated the config when saving, we need to read it again _config = Configuration.Load(); + StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); if (polipoRunner == null) { diff --git a/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs b/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs index 17bda19c..8bbe13e4 100644 --- a/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs +++ b/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs @@ -93,7 +93,7 @@ namespace Shadowsocks.Controller.Strategy return (double)data.SuccessTimes / (data.SuccessTimes + data.TimedOutTimes); //simply choose min package loss } - private class StatisticsData + public class StatisticsData { public int SuccessTimes; public int TimedOutTimes; diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index 06e0d690..ea8ff27f 100755 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -25,8 +25,6 @@ namespace Shadowsocks.Model public bool useOnlinePac; public bool availabilityStatistics; - public StatisticsStrategyConfiguration statisticsStrategyConfiguration; - private static string CONFIG_FILE = "gui-config.json"; public Server GetCurrentServer() diff --git a/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs b/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs index 452ecc1d..b427355b 100644 --- a/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs +++ b/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs @@ -1,8 +1,12 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Reflection; +using Shadowsocks.Controller; using Shadowsocks.Controller.Strategy; +using SimpleJson; +using Newtonsoft.Json; namespace Shadowsocks.Model { @@ -17,6 +21,41 @@ namespace Shadowsocks.Model private int _dataCollectionMinutes; private int _repeatTimesNum; + + private const string ConfigFile = "statistics-config.json"; + + public static StatisticsStrategyConfiguration Load() + { + try + { + var content = File.ReadAllText(ConfigFile); + var configuration = JsonConvert.DeserializeObject(content); + return configuration; + } + catch (FileNotFoundException e) + { + return new StatisticsStrategyConfiguration(); + } + catch (Exception e) + { + Logging.LogUsefulException(e); + return new StatisticsStrategyConfiguration(); + } + } + + public static void Save(StatisticsStrategyConfiguration configuration) + { + try + { + var content = JsonConvert.SerializeObject(configuration, Formatting.Indented); + File.WriteAllText(ConfigFile, content); + } + catch (Exception e) + { + Logging.LogUsefulException(e); + } + } + public Dictionary Calculations; public StatisticsStrategyConfiguration() diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index c8a4c0eb..9c73f320 100755 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -164,6 +164,7 @@ namespace Shadowsocks.View this.ServersItem = CreateMenuGroup("Servers", new MenuItem[] { this.SeperatorItem = new MenuItem("-"), this.ConfigItem = CreateMenuItem("Edit Servers...", new EventHandler(this.Config_Click)), + CreateMenuItem("Statistics Config...", StatisticsConfigItem_Click), CreateMenuItem("Show QRCode...", new EventHandler(this.QRCodeItem_Click)), CreateMenuItem("Scan QRCode from Screen...", new EventHandler(this.ScanQRCodeItem_Click)) }), @@ -188,6 +189,7 @@ namespace Shadowsocks.View }); } + private void controller_ConfigChanged(object sender, EventArgs e) { LoadCurrentConfiguration(); @@ -417,6 +419,12 @@ namespace Shadowsocks.View new LogForm(argument).Show(); } + + private void StatisticsConfigItem_Click(object sender, EventArgs e) + { + StatisticsStrategyConfigurationForm form = new StatisticsStrategyConfigurationForm(controller); + form.Show(); + } private void QRCodeItem_Click(object sender, EventArgs e) { diff --git a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs b/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs index 8563fcc5..801d9821 100644 --- a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs +++ b/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs @@ -29,14 +29,13 @@ private void InitializeComponent() { this.components = new System.ComponentModel.Container(); - System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea2 = new System.Windows.Forms.DataVisualization.Charting.ChartArea(); - System.Windows.Forms.DataVisualization.Charting.Legend legend2 = new System.Windows.Forms.DataVisualization.Charting.Legend(); - System.Windows.Forms.DataVisualization.Charting.Series series4 = new System.Windows.Forms.DataVisualization.Charting.Series(); - System.Windows.Forms.DataVisualization.Charting.Series series5 = new System.Windows.Forms.DataVisualization.Charting.Series(); - System.Windows.Forms.DataVisualization.Charting.Series series6 = new System.Windows.Forms.DataVisualization.Charting.Series(); + System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea(); + System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend(); + System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series(); + System.Windows.Forms.DataVisualization.Charting.Series series2 = new System.Windows.Forms.DataVisualization.Charting.Series(); + System.Windows.Forms.DataVisualization.Charting.Series series3 = new System.Windows.Forms.DataVisualization.Charting.Series(); this.StatisticsChart = new System.Windows.Forms.DataVisualization.Charting.Chart(); this.byISPCheckBox = new System.Windows.Forms.CheckBox(); - this.bindingConfiguration = new System.Windows.Forms.BindingSource(this.components); this.label2 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.label4 = new System.Windows.Forms.Label(); @@ -56,10 +55,10 @@ this.splitContainer3 = new System.Windows.Forms.SplitContainer(); this.label1 = new System.Windows.Forms.Label(); this.calculationContainer = new System.Windows.Forms.FlowLayoutPanel(); - this.OKButton = new System.Windows.Forms.Button(); this.CancelButton = new System.Windows.Forms.Button(); + this.OKButton = new System.Windows.Forms.Button(); + this.bindingConfiguration = new System.Windows.Forms.BindingSource(this.components); ((System.ComponentModel.ISupportInitialize)(this.StatisticsChart)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.bindingConfiguration)).BeginInit(); this.groupBox1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); this.splitContainer1.Panel1.SuspendLayout(); @@ -76,46 +75,47 @@ this.splitContainer3.Panel1.SuspendLayout(); this.splitContainer3.Panel2.SuspendLayout(); this.splitContainer3.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.bindingConfiguration)).BeginInit(); this.SuspendLayout(); // // StatisticsChart // this.StatisticsChart.BackColor = System.Drawing.Color.Transparent; - chartArea2.AxisX.MajorGrid.Enabled = false; - chartArea2.AxisY.MajorGrid.Enabled = false; - chartArea2.AxisY2.MajorGrid.Enabled = false; - chartArea2.BackColor = System.Drawing.Color.Transparent; - chartArea2.Name = "ChartArea"; - this.StatisticsChart.ChartAreas.Add(chartArea2); + chartArea1.AxisX.MajorGrid.Enabled = false; + chartArea1.AxisY.MajorGrid.Enabled = false; + chartArea1.AxisY2.MajorGrid.Enabled = false; + chartArea1.BackColor = System.Drawing.Color.Transparent; + chartArea1.Name = "ChartArea"; + this.StatisticsChart.ChartAreas.Add(chartArea1); this.StatisticsChart.Dock = System.Windows.Forms.DockStyle.Fill; - legend2.BackColor = System.Drawing.Color.Transparent; - legend2.Name = "ChartLegend"; - this.StatisticsChart.Legends.Add(legend2); + legend1.BackColor = System.Drawing.Color.Transparent; + legend1.Name = "ChartLegend"; + this.StatisticsChart.Legends.Add(legend1); this.StatisticsChart.Location = new System.Drawing.Point(0, 0); this.StatisticsChart.Margin = new System.Windows.Forms.Padding(5, 10, 5, 10); this.StatisticsChart.Name = "StatisticsChart"; this.StatisticsChart.Palette = System.Windows.Forms.DataVisualization.Charting.ChartColorPalette.Pastel; - series4.ChartArea = "ChartArea"; - series4.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Area; - series4.Color = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204))))); - series4.Legend = "ChartLegend"; - series4.Name = "Data Transferred"; - series5.ChartArea = "ChartArea"; - series5.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Bubble; - series5.Color = System.Drawing.Color.FromArgb(((int)(((byte)(221)))), ((int)(((byte)(88)))), ((int)(((byte)(0))))); - series5.Legend = "ChartLegend"; - series5.Name = "Package Loss"; - series5.YValuesPerPoint = 4; - series6.BorderWidth = 4; - series6.ChartArea = "ChartArea"; - series6.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; - series6.Color = System.Drawing.Color.FromArgb(((int)(((byte)(155)))), ((int)(((byte)(77)))), ((int)(((byte)(150))))); - series6.Legend = "ChartLegend"; - series6.Name = "Ping"; - this.StatisticsChart.Series.Add(series4); - this.StatisticsChart.Series.Add(series5); - this.StatisticsChart.Series.Add(series6); - this.StatisticsChart.Size = new System.Drawing.Size(951, 221); + series1.ChartArea = "ChartArea"; + series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Area; + series1.Color = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204))))); + series1.Legend = "ChartLegend"; + series1.Name = "Data Transferred"; + series2.ChartArea = "ChartArea"; + series2.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Bubble; + series2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(221)))), ((int)(((byte)(88)))), ((int)(((byte)(0))))); + series2.Legend = "ChartLegend"; + series2.Name = "Package Loss"; + series2.YValuesPerPoint = 4; + series3.BorderWidth = 4; + series3.ChartArea = "ChartArea"; + series3.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; + series3.Color = System.Drawing.Color.FromArgb(((int)(((byte)(155)))), ((int)(((byte)(77)))), ((int)(((byte)(150))))); + series3.Legend = "ChartLegend"; + series3.Name = "Ping"; + this.StatisticsChart.Series.Add(series1); + this.StatisticsChart.Series.Add(series2); + this.StatisticsChart.Series.Add(series3); + this.StatisticsChart.Size = new System.Drawing.Size(951, 222); this.StatisticsChart.TabIndex = 2; // // byISPCheckBox @@ -130,10 +130,6 @@ this.byISPCheckBox.Text = "By ISP/geolocation"; this.byISPCheckBox.UseVisualStyleBackColor = true; // - // bindingConfiguration - // - this.bindingConfiguration.DataSource = typeof(Shadowsocks.Model.StatisticsStrategyConfiguration); - // // label2 // this.label2.AutoSize = true; @@ -169,7 +165,7 @@ this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.groupBox1.Controls.Add(this.radioButton2); this.groupBox1.Controls.Add(this.radioButton1); - this.groupBox1.Location = new System.Drawing.Point(698, 12); + this.groupBox1.Location = new System.Drawing.Point(698, 7); this.groupBox1.Margin = new System.Windows.Forms.Padding(5, 10, 5, 10); this.groupBox1.Name = "groupBox1"; this.groupBox1.Padding = new System.Windows.Forms.Padding(5, 10, 5, 10); @@ -205,6 +201,7 @@ // splitContainer1 // this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.IsSplitterFixed = true; this.splitContainer1.Location = new System.Drawing.Point(0, 0); this.splitContainer1.Margin = new System.Windows.Forms.Padding(5, 10, 5, 10); this.splitContainer1.Name = "splitContainer1"; @@ -221,7 +218,7 @@ this.splitContainer1.Panel2.Controls.Add(this.groupBox1); this.splitContainer1.Panel2.Controls.Add(this.StatisticsChart); this.splitContainer1.Size = new System.Drawing.Size(951, 458); - this.splitContainer1.SplitterDistance = 227; + this.splitContainer1.SplitterDistance = 226; this.splitContainer1.SplitterWidth = 10; this.splitContainer1.TabIndex = 12; // @@ -252,7 +249,7 @@ // splitContainer2.Panel2 // this.splitContainer2.Panel2.Controls.Add(this.splitContainer3); - this.splitContainer2.Size = new System.Drawing.Size(951, 227); + this.splitContainer2.Size = new System.Drawing.Size(951, 226); this.splitContainer2.SplitterDistance = 365; this.splitContainer2.SplitterWidth = 5; this.splitContainer2.TabIndex = 7; @@ -404,7 +401,7 @@ // splitContainer3.Panel2 // this.splitContainer3.Panel2.Controls.Add(this.calculationContainer); - this.splitContainer3.Size = new System.Drawing.Size(581, 227); + this.splitContainer3.Size = new System.Drawing.Size(581, 226); this.splitContainer3.SplitterDistance = 46; this.splitContainer3.SplitterWidth = 10; this.splitContainer3.TabIndex = 6; @@ -426,11 +423,23 @@ this.calculationContainer.Location = new System.Drawing.Point(0, 0); this.calculationContainer.Margin = new System.Windows.Forms.Padding(5, 10, 5, 10); this.calculationContainer.Name = "calculationContainer"; - this.calculationContainer.Size = new System.Drawing.Size(581, 171); + this.calculationContainer.Size = new System.Drawing.Size(581, 170); this.calculationContainer.TabIndex = 1; // + // CancelButton + // + this.CancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.CancelButton.Location = new System.Drawing.Point(844, 166); + this.CancelButton.Name = "CancelButton"; + this.CancelButton.Size = new System.Drawing.Size(93, 43); + this.CancelButton.TabIndex = 5; + this.CancelButton.Text = "Cancel"; + this.CancelButton.UseVisualStyleBackColor = true; + this.CancelButton.Click += new System.EventHandler(this.CancelButton_Click); + // // OKButton // + this.OKButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.OKButton.Location = new System.Drawing.Point(745, 166); this.OKButton.Name = "OKButton"; this.OKButton.Size = new System.Drawing.Size(93, 43); @@ -439,15 +448,9 @@ this.OKButton.UseVisualStyleBackColor = true; this.OKButton.Click += new System.EventHandler(this.OKButton_Click); // - // CancelButton + // bindingConfiguration // - this.CancelButton.Location = new System.Drawing.Point(844, 166); - this.CancelButton.Name = "CancelButton"; - this.CancelButton.Size = new System.Drawing.Size(93, 43); - this.CancelButton.TabIndex = 5; - this.CancelButton.Text = "Cancel"; - this.CancelButton.UseVisualStyleBackColor = true; - this.CancelButton.Click += new System.EventHandler(this.CancelButton_Click); + this.bindingConfiguration.DataSource = typeof(Shadowsocks.Model.StatisticsStrategyConfiguration); // // StatisticsStrategyConfigurationForm // @@ -462,7 +465,6 @@ this.Name = "StatisticsStrategyConfigurationForm"; this.Text = "StatisticsStrategyConfigurationForm"; ((System.ComponentModel.ISupportInitialize)(this.StatisticsChart)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.bindingConfiguration)).EndInit(); this.groupBox1.ResumeLayout(false); this.groupBox1.PerformLayout(); this.splitContainer1.Panel1.ResumeLayout(false); @@ -482,6 +484,7 @@ this.splitContainer3.Panel2.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.splitContainer3)).EndInit(); this.splitContainer3.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.bindingConfiguration)).EndInit(); this.ResumeLayout(false); } @@ -509,7 +512,7 @@ private System.Windows.Forms.Label label8; private System.Windows.Forms.NumericUpDown dataCollectionMinutesNum; private System.Windows.Forms.BindingSource bindingConfiguration; - private System.Windows.Forms.Button CancelButton; + private new System.Windows.Forms.Button CancelButton; private System.Windows.Forms.Button OKButton; } } \ No newline at end of file diff --git a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.cs b/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.cs index 970b5761..587153c7 100644 --- a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.cs +++ b/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.cs @@ -9,7 +9,7 @@ namespace Shadowsocks.View { public partial class StatisticsStrategyConfigurationForm: Form { - private ShadowsocksController _controller; + private readonly ShadowsocksController _controller; private StatisticsStrategyConfiguration _configuration; public StatisticsStrategyConfigurationForm(ShadowsocksController controller) @@ -24,8 +24,12 @@ namespace Shadowsocks.View private void LoadConfiguration() { - _configuration = _controller.GetConfigurationCopy()?.statisticsStrategyConfiguration + _configuration = _controller.StatisticsConfiguration ?? new StatisticsStrategyConfiguration(); + if (_configuration.Calculations == null) + { + _configuration = new StatisticsStrategyConfiguration(); + } } private void InitData() diff --git a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.resx b/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.resx index 55c9d750..fa7d769a 100644 --- a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.resx +++ b/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.resx @@ -120,7 +120,4 @@ 1, 30 - - 1, 30 - \ No newline at end of file diff --git a/shadowsocks-csharp/packages.config b/shadowsocks-csharp/packages.config index b9a6cbf2..b309fb97 100644 --- a/shadowsocks-csharp/packages.config +++ b/shadowsocks-csharp/packages.config @@ -1,8 +1,9 @@  - + + \ No newline at end of file diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 19e91b95..61660623 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -81,6 +81,10 @@ False + + 3rd\Newtonsoft.Json.7.0.1\lib\net40\Newtonsoft.Json.dll + True + @@ -280,7 +284,9 @@ - + + Designer + @@ -321,12 +327,12 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - +