From bec1f808b38ff841379b10e011404bd482249595 Mon Sep 17 00:00:00 2001 From: icylogic Date: Wed, 20 Jan 2016 23:51:51 +0800 Subject: [PATCH] add an option for Ping tests (disabled by default) and improve the readability of the code --- .../Service/AvailabilityStatistics.cs | 181 +++++++----------- .../Controller/Strategy/StatisticsStrategy.cs | 12 +- .../Model/StatisticsStrategyConfiguration.cs | 50 +---- ...sticsStrategyConfigurationForm.Designer.cs | 108 +++++------ .../StatisticsStrategyConfigurationForm.cs | 7 +- 5 files changed, 137 insertions(+), 221 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs b/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs index 0a67962c..8d805786 100644 --- a/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs +++ b/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs @@ -19,84 +19,87 @@ namespace Shadowsocks.Controller public sealed class AvailabilityStatistics : IDisposable { public const string DateTimePattern = "yyyy-MM-dd HH:mm:ss"; + public static readonly DateTime UnknownDateTime; private const string StatisticsFilesName = "shadowsocks.availability.json"; - private const int TimeoutMilliseconds = 500; + public static string AvailabilityStatisticsFile; + //static constructor to initialize every public static fields before refereced + static AvailabilityStatistics() + { + AvailabilityStatisticsFile = Utils.GetTempPath(StatisticsFilesName); + UnknownDateTime = new DateTime(1970, 1, 1); + } - public static readonly DateTime UnknownDateTime = new DateTime(1970, 1, 1); + //arguments for ICMP tests + private int Repeat => Config.RepeatTimesNum; + private const int TimeoutMilliseconds = 500; - public static string AvailabilityStatisticsFile; - private readonly TimeSpan _delayBeforeStart = TimeSpan.FromSeconds(1); - private readonly TimeSpan _monitorInterval = TimeSpan.FromSeconds(1); - private readonly TimeSpan _retryInterval = TimeSpan.FromMinutes(2); //retry 2 minutes after failed - private readonly TimeSpan _writingInterval = TimeSpan.FromMinutes(1); - private StatisticsStrategyConfiguration _config; - private ShadowsocksController _controller; - private Server _currentServer; + //records cache for current server in {_monitorInterval} minutes + private List _latencyRecords; //speed in KiB/s - private List _inboundSpeedRecords; private long _lastInboundCounter; + private List _inboundSpeedRecords; private long _lastOutboundCounter; - private List _latencyRecords; private List _outboundSpeedRecords; - private Timer _recorder; - private List _servers; - private Timer _speedMonior; - private Timer _writer; - //static constructor to initialize every public static fields before refereced - static AvailabilityStatistics() - { - AvailabilityStatisticsFile = Utils.GetTempPath(StatisticsFilesName); - } + //tasks + private readonly TimeSpan _delayBeforeStart = TimeSpan.FromSeconds(1); + private readonly TimeSpan _retryInterval = TimeSpan.FromMinutes(2); + private Timer _recorder; //analyze and save cached records to RawStatistics and filter records + private TimeSpan RecordingInterval => TimeSpan.FromMinutes(Config.DataCollectionMinutes); + private Timer _speedMonior; + private readonly TimeSpan _monitorInterval = TimeSpan.FromSeconds(1); + private Timer _writer; //write RawStatistics to file + private readonly TimeSpan _writingInterval = TimeSpan.FromMinutes(1); - private AvailabilityStatistics() - { - RawStatistics = new Statistics(); - } + private ShadowsocksController _controller; + private StatisticsStrategyConfiguration Config => _controller.StatisticsConfiguration; + private Server CurrentServer => _controller.GetCurrentServer(); // Static Singleton Initialization public static AvailabilityStatistics Instance { get; } = new AvailabilityStatistics(); public Statistics RawStatistics { get; private set; } public Statistics FilteredStatistics { get; private set; } - private int Repeat => _config.RepeatTimesNum; - private TimeSpan RecordingInterval => TimeSpan.FromMinutes(_config.DataCollectionMinutes); - public bool Set(StatisticsStrategyConfiguration config) + private AvailabilityStatistics() + { + RawStatistics = new Statistics(); + } + + internal void UpdateConfiguration(ShadowsocksController controller) { - _config = config; + _controller = controller; + Reset(); try { - if (config.StatisticsEnabled) + if (Config.StatisticsEnabled) { - if (_recorder?.Change(_delayBeforeStart, RecordingInterval) == null) - { - _recorder = new Timer(Run, null, _delayBeforeStart, RecordingInterval); - } + StartTimerWithoutState(ref _recorder, Run, RecordingInterval); LoadRawStatistics(); - if (_speedMonior?.Change(_delayBeforeStart, _monitorInterval) == null) - { - _speedMonior = new Timer(UpdateSpeed, null, _delayBeforeStart, _monitorInterval); - } - if (_writer?.Change(_delayBeforeStart, RecordingInterval) == null) - { - _writer = new Timer(Save, null, _delayBeforeStart, RecordingInterval); - } + StartTimerWithoutState(ref _speedMonior, UpdateSpeed, _monitorInterval); + StartTimerWithoutState(ref _writer, Save, _writingInterval); } else { _recorder?.Dispose(); _speedMonior?.Dispose(); + _writer?.Dispose(); } - return true; } catch (Exception e) { Logging.LogUsefulException(e); - return false; } } - private void UpdateSpeed(object state) + private void StartTimerWithoutState(ref Timer timer, TimerCallback callback, TimeSpan interval) + { + if (timer?.Change(_delayBeforeStart, interval) == null) + { + timer = new Timer(callback, null, _delayBeforeStart, interval); + } + } + + private void UpdateSpeed(object _) { var bytes = _controller.inboundCounter - _lastInboundCounter; _lastInboundCounter = _controller.inboundCounter; @@ -109,7 +112,7 @@ namespace Shadowsocks.Controller _outboundSpeedRecords.Add(outboundSpeed); Logging.Debug( - $"{_currentServer.FriendlyName()}: current/max inbound {inboundSpeed}/{_inboundSpeedRecords.Max()} KiB/s, current/max outbound {outboundSpeed}/{_outboundSpeedRecords.Max()} KiB/s"); + $"{CurrentServer.FriendlyName()}: current/max inbound {inboundSpeed}/{_inboundSpeedRecords.Max()} KiB/s, current/max outbound {outboundSpeed}/{_outboundSpeedRecords.Max()} KiB/s"); } private async Task ICMPTest(Server server) @@ -168,94 +171,66 @@ namespace Shadowsocks.Controller private void Run(object _) { - AppendRecord(); + UpdateRecords(); Reset(); FilterRawStatistics(); } - private async void AppendRecord() + private async void UpdateRecords() { - //todo: option for icmp test - var icmpResults = TaskEx.WhenAll(_servers.Select(ICMPTest)); + var currentServerRecord = new StatisticsRecord(CurrentServer.Identifier(), _inboundSpeedRecords, _outboundSpeedRecords, _latencyRecords); - var currentServerRecord = new StatisticsRecord(_currentServer.Identifier(), - _inboundSpeedRecords, _outboundSpeedRecords, _latencyRecords); + if (!Config.Ping) + { + AppendRecord(CurrentServer, currentServerRecord); + return; + } + + var icmpResults = TaskEx.WhenAll(_controller.GetCurrentConfiguration().configs.Select(ICMPTest)); foreach (var result in (await icmpResults).Where(result => result != null)) { - List records; - if (!RawStatistics.TryGetValue(result.Server.Identifier(), out records)) - { - records = new List(); - } - - if (result.Server.Equals(_currentServer)) + if (result.Server.Equals(CurrentServer)) { currentServerRecord.setResponse(result.RoundtripTime); - records.Add(currentServerRecord); + AppendRecord(CurrentServer, currentServerRecord); } else { - records.Add(new StatisticsRecord(result.Server.Identifier(), result.RoundtripTime)); + AppendRecord(result.Server, new StatisticsRecord(result.Server.Identifier(), result.RoundtripTime)); } - RawStatistics[result.Server.Identifier()] = records; } } - private void Save(object _) + private void AppendRecord(Server server, StatisticsRecord record) { - try + List records; + if (!RawStatistics.TryGetValue(server.Identifier(), out records)) { - File.WriteAllText(AvailabilityStatisticsFile, - JsonConvert.SerializeObject(RawStatistics, Formatting.None)); - } - catch (IOException e) - { - Logging.LogUsefulException(e); - _writer.Change(_retryInterval, _writingInterval); + records = new List(); } + records.Add(record); + RawStatistics[server.Identifier()] = records; } - /* - private static void Append(DataList dataList, IEnumerable extra) + private void Save(object _) { - var data = dataList.Concat(extra); - var dataLine = string.Join(Delimiter, data.Select(kv => kv.Value).ToArray()); - string[] lines; - if (!File.Exists(AvailabilityStatisticsFile)) - { - var headerLine = string.Join(Delimiter, data.Select(kv => kv.Key).ToArray()); - lines = new[] { headerLine, dataLine }; - } - else - { - lines = new[] { dataLine }; - } try { - File.AppendAllLines(AvailabilityStatisticsFile, lines); + File.WriteAllText(AvailabilityStatisticsFile, + JsonConvert.SerializeObject(RawStatistics, Formatting.None)); } catch (IOException e) { Logging.LogUsefulException(e); + _writer.Change(_retryInterval, _writingInterval); } } - */ - - internal void UpdateConfiguration(ShadowsocksController controller) - { - _controller = controller; - _currentServer = _controller.GetCurrentServer(); - Reset(); - Set(controller.StatisticsConfiguration); - _servers = _controller.GetCurrentConfiguration().configs; - } private bool IsValidRecord(StatisticsRecord record) { - if (_config.ByHourOfDay) + if (Config.ByHourOfDay) { - var currentHour = DateTime.Now.Hour; if (record.Timestamp == UnknownDateTime) return false; if (!record.Timestamp.Hour.Equals(DateTime.Now.Hour)) return false; } @@ -288,7 +263,7 @@ namespace Shadowsocks.Controller { try { - using (var fs = File.Create(path)) + using (File.Create(path)) { //do nothing } @@ -313,14 +288,6 @@ namespace Shadowsocks.Controller } } - private DateTime ParseExactOrUnknown(string str) - { - DateTime dateTime; - return !DateTime.TryParseExact(str, DateTimePattern, null, DateTimeStyles.None, out dateTime) - ? UnknownDateTime - : dateTime; - } - public void UpdateLatency(int latency) { _latencyRecords.Add(latency); diff --git a/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs b/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs index d9d786d2..c2c64898 100644 --- a/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs +++ b/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Net; -using System.Net.NetworkInformation; using System.Threading; using Newtonsoft.Json; @@ -27,7 +26,7 @@ namespace Shadowsocks.Controller.Strategy { _controller = controller; var servers = controller.GetCurrentConfiguration().configs; - var randomIndex = new Random().Next() % servers.Count(); + var randomIndex = new Random().Next() % servers.Count; _currentServer = servers[randomIndex]; //choose a server randomly at first _timer = new Timer(ReloadStatisticsAndChooseAServer); } @@ -117,14 +116,10 @@ namespace Shadowsocks.Controller.Strategy public Server GetAServer(IStrategyCallerType type, IPEndPoint localIPEndPoint) { - var oldServer = _currentServer; - if (oldServer == null) + if (_currentServer == null) { ChooseNewServer(_controller.GetCurrentConfiguration().configs); } - if (oldServer != _currentServer) - { - } return _currentServer; //current server cached for CachedInterval } @@ -141,17 +136,14 @@ namespace Shadowsocks.Controller.Strategy public void UpdateLastRead(Server server) { - //TODO: combine this part of data with ICMP statics } public void UpdateLastWrite(Server server) { - //TODO: combine this part of data with ICMP statics } public void UpdateLatency(Server server, TimeSpan latency) { - //TODO: combine this part of data with ICMP statics } public void Dispose() diff --git a/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs b/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs index e59fcde5..895a7f03 100644 --- a/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs +++ b/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs @@ -13,13 +13,13 @@ namespace Shadowsocks.Model [Serializable] public class StatisticsStrategyConfiguration { - public static readonly string ID = "com.shadowsocks.strategy.statistics"; - private bool _statisticsEnabled = true; - private bool _byIsp = false; - private bool _byHourOfDay = false; - private int _choiceKeptMinutes = 10; - private int _dataCollectionMinutes = 10; - private int _repeatTimesNum = 4; + public static readonly string ID = "com.shadowsocks.strategy.statistics"; + public bool StatisticsEnabled { get; } = true; + public bool ByHourOfDay { get; } = true; + public bool Ping { get; set; } + public int ChoiceKeptMinutes { get; } = 10; + public int DataCollectionMinutes { get; } = 10; + public int RepeatTimesNum { get; } = 4; private const string ConfigFile = "statistics-config.json"; @@ -64,41 +64,5 @@ namespace Shadowsocks.Model var properties = typeof(StatisticsRecord).GetFields(BindingFlags.Instance | BindingFlags.Public); Calculations = properties.ToDictionary(p => p.Name, _ => (float)0); } - - public bool StatisticsEnabled - { - get { return _statisticsEnabled; } - set { _statisticsEnabled = value; } - } - - public bool ByIsp - { - get { return _byIsp; } - set { _byIsp = value; } - } - - public bool ByHourOfDay - { - get { return _byHourOfDay; } - set { _byHourOfDay = value; } - } - - public int ChoiceKeptMinutes - { - get { return _choiceKeptMinutes; } - set { _choiceKeptMinutes = value; } - } - - public int DataCollectionMinutes - { - get { return _dataCollectionMinutes; } - set { _dataCollectionMinutes = value; } - } - - public int RepeatTimesNum - { - get { return _repeatTimesNum; } - set { _repeatTimesNum = value; } - } } } diff --git a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs b/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs index a207f309..d3f319a9 100644 --- a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs +++ b/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs @@ -34,10 +34,9 @@ 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(); this.StatisticsChart = new System.Windows.Forms.DataVisualization.Charting.Chart(); - this.byISPCheckBox = new System.Windows.Forms.CheckBox(); + this.PingCheckBox = new System.Windows.Forms.CheckBox(); this.label2 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); - this.label4 = new System.Windows.Forms.Label(); this.chartModeSelector = new System.Windows.Forms.GroupBox(); this.allMode = new System.Windows.Forms.RadioButton(); this.dayMode = new System.Windows.Forms.RadioButton(); @@ -111,57 +110,48 @@ series2.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.DateTime; this.StatisticsChart.Series.Add(series1); this.StatisticsChart.Series.Add(series2); - this.StatisticsChart.Size = new System.Drawing.Size(1077, 303); + this.StatisticsChart.Size = new System.Drawing.Size(1089, 303); this.StatisticsChart.TabIndex = 2; // - // byISPCheckBox + // PingCheckBox // - this.byISPCheckBox.AutoSize = true; - this.byISPCheckBox.DataBindings.Add(new System.Windows.Forms.Binding("Checked", this.bindingConfiguration, "ByIsp", true)); - this.byISPCheckBox.Location = new System.Drawing.Point(13, 54); - this.byISPCheckBox.Margin = new System.Windows.Forms.Padding(5, 10, 5, 10); - this.byISPCheckBox.Name = "byISPCheckBox"; - this.byISPCheckBox.Size = new System.Drawing.Size(220, 31); - this.byISPCheckBox.TabIndex = 5; - this.byISPCheckBox.Text = "By ISP/geolocation"; - this.byISPCheckBox.UseVisualStyleBackColor = true; + this.PingCheckBox.AutoSize = true; + this.PingCheckBox.DataBindings.Add(new System.Windows.Forms.Binding("Checked", this.bindingConfiguration, "Ping", true)); + this.PingCheckBox.Location = new System.Drawing.Point(13, 54); + this.PingCheckBox.Margin = new System.Windows.Forms.Padding(5, 10, 5, 10); + this.PingCheckBox.Name = "PingCheckBox"; + this.PingCheckBox.Size = new System.Drawing.Size(107, 27); + this.PingCheckBox.TabIndex = 5; + this.PingCheckBox.Text = "Ping Test"; + this.PingCheckBox.UseVisualStyleBackColor = true; + this.PingCheckBox.CheckedChanged += new System.EventHandler(this.PingCheckBox_CheckedChanged); // // label2 // this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(8, 136); + this.label2.Location = new System.Drawing.Point(9, 267); this.label2.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(167, 27); + this.label2.Size = new System.Drawing.Size(144, 23); this.label2.TabIndex = 8; this.label2.Text = "Keep choice for "; // // label3 // this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(285, 136); + this.label3.Location = new System.Drawing.Point(286, 267); this.label3.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(87, 27); + this.label3.Size = new System.Drawing.Size(75, 23); this.label3.TabIndex = 9; this.label3.Text = "minutes"; // - // label4 - // - this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(8, 218); - this.label4.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); - this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(54, 27); - this.label4.TabIndex = 10; - this.label4.Text = "Ping"; - // // chartModeSelector // this.chartModeSelector.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.chartModeSelector.Controls.Add(this.allMode); this.chartModeSelector.Controls.Add(this.dayMode); - this.chartModeSelector.Location = new System.Drawing.Point(801, 104); + this.chartModeSelector.Location = new System.Drawing.Point(813, 98); this.chartModeSelector.Margin = new System.Windows.Forms.Padding(5, 10, 5, 10); this.chartModeSelector.Name = "chartModeSelector"; this.chartModeSelector.Padding = new System.Windows.Forms.Padding(5, 10, 5, 10); @@ -178,7 +168,7 @@ this.allMode.Location = new System.Drawing.Point(11, 61); this.allMode.Margin = new System.Windows.Forms.Padding(5, 10, 5, 10); this.allMode.Name = "allMode"; - this.allMode.Size = new System.Drawing.Size(58, 31); + this.allMode.Size = new System.Drawing.Size(50, 27); this.allMode.TabIndex = 1; this.allMode.TabStop = true; this.allMode.Text = "all"; @@ -191,7 +181,7 @@ this.dayMode.Location = new System.Drawing.Point(11, 29); this.dayMode.Margin = new System.Windows.Forms.Padding(5, 10, 5, 10); this.dayMode.Name = "dayMode"; - this.dayMode.Size = new System.Drawing.Size(73, 31); + this.dayMode.Size = new System.Drawing.Size(61, 27); this.dayMode.TabIndex = 0; this.dayMode.Text = "24h"; this.dayMode.UseVisualStyleBackColor = true; @@ -217,7 +207,7 @@ this.splitContainer1.Panel2.Controls.Add(this.OKButton); this.splitContainer1.Panel2.Controls.Add(this.chartModeSelector); this.splitContainer1.Panel2.Controls.Add(this.StatisticsChart); - this.splitContainer1.Size = new System.Drawing.Size(1077, 614); + this.splitContainer1.Size = new System.Drawing.Size(1089, 614); this.splitContainer1.SplitterDistance = 301; this.splitContainer1.SplitterWidth = 10; this.splitContainer1.TabIndex = 12; @@ -242,14 +232,13 @@ this.splitContainer2.Panel1.Controls.Add(this.repeatTimesNum); this.splitContainer2.Panel1.Controls.Add(this.label6); this.splitContainer2.Panel1.Controls.Add(this.label2); - this.splitContainer2.Panel1.Controls.Add(this.label4); - this.splitContainer2.Panel1.Controls.Add(this.byISPCheckBox); + this.splitContainer2.Panel1.Controls.Add(this.PingCheckBox); this.splitContainer2.Panel1.Controls.Add(this.label3); // // splitContainer2.Panel2 // this.splitContainer2.Panel2.Controls.Add(this.splitContainer3); - this.splitContainer2.Size = new System.Drawing.Size(1077, 301); + this.splitContainer2.Size = new System.Drawing.Size(1089, 301); this.splitContainer2.SplitterDistance = 384; this.splitContainer2.SplitterWidth = 5; this.splitContainer2.TabIndex = 7; @@ -257,10 +246,10 @@ // label9 // this.label9.AutoSize = true; - this.label9.Location = new System.Drawing.Point(8, 175); + this.label9.Location = new System.Drawing.Point(9, 164); this.label9.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); this.label9.Name = "label9"; - this.label9.Size = new System.Drawing.Size(162, 27); + this.label9.Size = new System.Drawing.Size(139, 23); this.label9.TabIndex = 20; this.label9.Text = "Collect data per"; // @@ -268,10 +257,10 @@ // this.label8.AutoSize = true; this.label8.Font = new System.Drawing.Font("Microsoft YaHei", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label8.Location = new System.Drawing.Point(285, 176); + this.label8.Location = new System.Drawing.Point(286, 165); this.label8.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); this.label8.Name = "label8"; - this.label8.Size = new System.Drawing.Size(87, 27); + this.label8.Size = new System.Drawing.Size(75, 23); this.label8.TabIndex = 19; this.label8.Text = "minutes"; // @@ -283,7 +272,7 @@ 0, 0, 0}); - this.dataCollectionMinutesNum.Location = new System.Drawing.Point(176, 173); + this.dataCollectionMinutesNum.Location = new System.Drawing.Point(177, 162); this.dataCollectionMinutesNum.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); this.dataCollectionMinutesNum.Maximum = new decimal(new int[] { 120, @@ -296,7 +285,7 @@ 0, 0}); this.dataCollectionMinutesNum.Name = "dataCollectionMinutesNum"; - this.dataCollectionMinutesNum.Size = new System.Drawing.Size(100, 34); + this.dataCollectionMinutesNum.Size = new System.Drawing.Size(100, 29); this.dataCollectionMinutesNum.TabIndex = 18; this.dataCollectionMinutesNum.Value = new decimal(new int[] { 10, @@ -311,7 +300,7 @@ this.StatisticsEnabledCheckBox.Location = new System.Drawing.Point(13, 12); this.StatisticsEnabledCheckBox.Margin = new System.Windows.Forms.Padding(5, 10, 5, 10); this.StatisticsEnabledCheckBox.Name = "StatisticsEnabledCheckBox"; - this.StatisticsEnabledCheckBox.Size = new System.Drawing.Size(189, 31); + this.StatisticsEnabledCheckBox.Size = new System.Drawing.Size(163, 27); this.StatisticsEnabledCheckBox.TabIndex = 17; this.StatisticsEnabledCheckBox.Text = "Enable Statistics"; this.StatisticsEnabledCheckBox.UseVisualStyleBackColor = true; @@ -324,7 +313,7 @@ 0, 0, 0}); - this.choiceKeptMinutesNum.Location = new System.Drawing.Point(176, 134); + this.choiceKeptMinutesNum.Location = new System.Drawing.Point(177, 265); this.choiceKeptMinutesNum.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); this.choiceKeptMinutesNum.Maximum = new decimal(new int[] { 120, @@ -337,7 +326,7 @@ 0, 0}); this.choiceKeptMinutesNum.Name = "choiceKeptMinutesNum"; - this.choiceKeptMinutesNum.Size = new System.Drawing.Size(100, 34); + this.choiceKeptMinutesNum.Size = new System.Drawing.Size(100, 29); this.choiceKeptMinutesNum.TabIndex = 16; this.choiceKeptMinutesNum.Value = new decimal(new int[] { 10, @@ -349,10 +338,10 @@ // this.byHourOfDayCheckBox.AutoSize = true; this.byHourOfDayCheckBox.DataBindings.Add(new System.Windows.Forms.Binding("Checked", this.bindingConfiguration, "ByHourOfDay", true)); - this.byHourOfDayCheckBox.Location = new System.Drawing.Point(13, 95); + this.byHourOfDayCheckBox.Location = new System.Drawing.Point(13, 127); this.byHourOfDayCheckBox.Margin = new System.Windows.Forms.Padding(5, 10, 5, 10); this.byHourOfDayCheckBox.Name = "byHourOfDayCheckBox"; - this.byHourOfDayCheckBox.Size = new System.Drawing.Size(180, 31); + this.byHourOfDayCheckBox.Size = new System.Drawing.Size(150, 27); this.byHourOfDayCheckBox.TabIndex = 15; this.byHourOfDayCheckBox.Text = "By hour of day"; this.byHourOfDayCheckBox.UseVisualStyleBackColor = true; @@ -360,7 +349,7 @@ // repeatTimesNum // this.repeatTimesNum.DataBindings.Add(new System.Windows.Forms.Binding("Value", this.bindingConfiguration, "RepeatTimesNum", true)); - this.repeatTimesNum.Location = new System.Drawing.Point(72, 216); + this.repeatTimesNum.Location = new System.Drawing.Point(34, 84); this.repeatTimesNum.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); this.repeatTimesNum.Maximum = new decimal(new int[] { 10, @@ -368,7 +357,7 @@ 0, 0}); this.repeatTimesNum.Name = "repeatTimesNum"; - this.repeatTimesNum.Size = new System.Drawing.Size(99, 34); + this.repeatTimesNum.Size = new System.Drawing.Size(99, 29); this.repeatTimesNum.TabIndex = 14; this.repeatTimesNum.Value = new decimal(new int[] { 4, @@ -380,9 +369,9 @@ // this.label6.AutoSize = true; this.label6.Font = new System.Drawing.Font("Microsoft YaHei", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label6.Location = new System.Drawing.Point(178, 218); + this.label6.Location = new System.Drawing.Point(139, 86); this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(201, 27); + this.label6.Size = new System.Drawing.Size(172, 23); this.label6.TabIndex = 13; this.label6.Text = "packages everytime"; // @@ -403,7 +392,7 @@ // splitContainer3.Panel2 // this.splitContainer3.Panel2.Controls.Add(this.calculationContainer); - this.splitContainer3.Size = new System.Drawing.Size(688, 301); + this.splitContainer3.Size = new System.Drawing.Size(700, 301); this.splitContainer3.SplitterDistance = 46; this.splitContainer3.SplitterWidth = 10; this.splitContainer3.TabIndex = 6; @@ -414,7 +403,7 @@ this.label1.Location = new System.Drawing.Point(5, 12); this.label1.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(262, 27); + this.label1.Size = new System.Drawing.Size(225, 23); this.label1.TabIndex = 0; this.label1.Text = "Design evaluation method"; // @@ -425,23 +414,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(688, 245); + this.calculationContainer.Size = new System.Drawing.Size(700, 245); this.calculationContainer.TabIndex = 1; // // serverSelector // this.serverSelector.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.serverSelector.FormattingEnabled = true; - this.serverSelector.Location = new System.Drawing.Point(801, 67); + this.serverSelector.Location = new System.Drawing.Point(813, 61); this.serverSelector.Name = "serverSelector"; - this.serverSelector.Size = new System.Drawing.Size(260, 35); + this.serverSelector.Size = new System.Drawing.Size(260, 31); this.serverSelector.TabIndex = 6; this.serverSelector.SelectedIndexChanged += new System.EventHandler(this.serverSelector_SelectedIndexChanged); // // 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(960, 220); + this.CancelButton.Location = new System.Drawing.Point(972, 214); this.CancelButton.Name = "CancelButton"; this.CancelButton.Size = new System.Drawing.Size(101, 41); this.CancelButton.TabIndex = 5; @@ -452,7 +441,7 @@ // 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(852, 220); + this.OKButton.Location = new System.Drawing.Point(864, 214); this.OKButton.Name = "OKButton"; this.OKButton.Size = new System.Drawing.Size(101, 41); this.OKButton.TabIndex = 4; @@ -466,10 +455,10 @@ // // StatisticsStrategyConfigurationForm // - this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 27F); + this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 23F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoSize = true; - this.ClientSize = new System.Drawing.Size(1077, 614); + this.ClientSize = new System.Drawing.Size(1089, 614); this.Controls.Add(this.splitContainer1); this.Font = new System.Drawing.Font("Microsoft YaHei", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.Margin = new System.Windows.Forms.Padding(5, 10, 5, 10); @@ -503,10 +492,9 @@ #endregion private System.Windows.Forms.DataVisualization.Charting.Chart StatisticsChart; - private System.Windows.Forms.CheckBox byISPCheckBox; + private System.Windows.Forms.CheckBox PingCheckBox; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label3; - private System.Windows.Forms.Label label4; private System.Windows.Forms.GroupBox chartModeSelector; private System.Windows.Forms.RadioButton allMode; private System.Windows.Forms.RadioButton dayMode; diff --git a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.cs b/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.cs index 9db17302..cda9448c 100644 --- a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.cs +++ b/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.cs @@ -15,7 +15,7 @@ namespace Shadowsocks.View { private readonly ShadowsocksController _controller; private StatisticsStrategyConfiguration _configuration; - private DataTable _dataTable = new DataTable(); + private readonly DataTable _dataTable = new DataTable(); private List _servers; public StatisticsStrategyConfigurationForm(ShadowsocksController controller) @@ -135,5 +135,10 @@ namespace Shadowsocks.View { loadChartData(); } + + private void PingCheckBox_CheckedChanged(object sender, EventArgs e) + { + repeatTimesNum.ReadOnly = !PingCheckBox.Checked; + } } }