From 5c6e5b927c4688e28a9f52a13d272728c96c0923 Mon Sep 17 00:00:00 2001 From: database64128 Date: Mon, 19 Oct 2020 19:44:08 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=B9=20Remove=20statistics=20strategy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/AvailabilityStatistics.cs | 534 ----------------- .../Controller/ShadowsocksController.cs | 43 +- .../Controller/Strategy/StatisticsStrategy.cs | 170 ------ .../Controller/Strategy/StrategyManager.cs | 1 - shadowsocks-csharp/Data/i18n.csv | 32 -- shadowsocks-csharp/Model/Configuration.cs | 2 - shadowsocks-csharp/Model/StatisticsRecord.cs | 95 ---- .../Model/StatisticsStrategyConfiguration.cs | 69 --- ...StatisticsStrategyConfiguration.datasource | 10 - .../View/CalculationControl.Designer.cs | 113 ---- shadowsocks-csharp/View/CalculationControl.cs | 25 - .../View/CalculationControl.resx | 120 ---- shadowsocks-csharp/View/MenuViewController.cs | 7 - ...sticsStrategyConfigurationForm.Designer.cs | 537 ------------------ .../StatisticsStrategyConfigurationForm.cs | 170 ------ .../StatisticsStrategyConfigurationForm.resx | 129 ----- shadowsocks-csharp/shadowsocks-csharp.csproj | 23 - 17 files changed, 1 insertion(+), 2079 deletions(-) delete mode 100644 shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs delete mode 100644 shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs delete mode 100644 shadowsocks-csharp/Model/StatisticsRecord.cs delete mode 100644 shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs delete mode 100644 shadowsocks-csharp/Properties/DataSources/Shadowsocks.Model.StatisticsStrategyConfiguration.datasource delete mode 100644 shadowsocks-csharp/View/CalculationControl.Designer.cs delete mode 100644 shadowsocks-csharp/View/CalculationControl.cs delete mode 100644 shadowsocks-csharp/View/CalculationControl.resx delete mode 100644 shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs delete mode 100644 shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.cs delete mode 100644 shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.resx diff --git a/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs b/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs deleted file mode 100644 index 112c5493..00000000 --- a/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs +++ /dev/null @@ -1,534 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.NetworkInformation; -using System.Net.Sockets; -using System.Threading; -using System.Threading.Tasks; -using Newtonsoft.Json; -using NLog; -using Shadowsocks.Model; -using Shadowsocks.Util; - -namespace Shadowsocks.Controller -{ - using Statistics = Dictionary>; - - public sealed class AvailabilityStatistics : IDisposable - { - private static Logger logger = LogManager.GetCurrentClassLogger(); - - public const string DateTimePattern = "yyyy-MM-dd HH:mm:ss"; - private const string StatisticsFilesName = "shadowsocks.availability.json"; - public static string AvailabilityStatisticsFile; - //static constructor to initialize every public static fields before refereced - static AvailabilityStatistics() - { - AvailabilityStatisticsFile = Utils.GetTempPath(StatisticsFilesName); - } - - //arguments for ICMP tests - private int Repeat => Config.RepeatTimesNum; - public const int TimeoutMilliseconds = 500; - - //records cache for current server in {_monitorInterval} minutes - private readonly ConcurrentDictionary> _latencyRecords = new ConcurrentDictionary>(); - //speed in KiB/s - private readonly ConcurrentDictionary> _inboundSpeedRecords = new ConcurrentDictionary>(); - private readonly ConcurrentDictionary> _outboundSpeedRecords = new ConcurrentDictionary>(); - private readonly ConcurrentDictionary _inOutBoundRecords = new ConcurrentDictionary(); - - private class InOutBoundRecord - { - private long _inbound; - private long _lastInbound; - private long _outbound; - private long _lastOutbound; - - public void UpdateInbound(long delta) - { - Interlocked.Add(ref _inbound, delta); - } - - public void UpdateOutbound(long delta) - { - Interlocked.Add(ref _outbound, delta); - } - - public void GetDelta(out long inboundDelta, out long outboundDelta) - { - var i = Interlocked.Read(ref _inbound); - var il = Interlocked.Exchange(ref _lastInbound, i); - inboundDelta = i - il; - - - var o = Interlocked.Read(ref _outbound); - var ol = Interlocked.Exchange(ref _lastOutbound, o); - outboundDelta = o - ol; - } - } - - //tasks - private readonly TimeSpan _delayBeforeStart = TimeSpan.FromSeconds(1); - private readonly TimeSpan _retryInterval = TimeSpan.FromMinutes(2); - private TimeSpan RecordingInterval => TimeSpan.FromMinutes(Config.DataCollectionMinutes); - private Timer _perSecondTimer; //analyze and save cached records to RawStatistics and filter records - private readonly TimeSpan _monitorInterval = TimeSpan.FromSeconds(1); - //private Timer _writer; //write RawStatistics to file - //private readonly TimeSpan _writingInterval = TimeSpan.FromMinutes(1); - - private ShadowsocksController _controller; - private StatisticsStrategyConfiguration Config => _controller.StatisticsConfiguration; - - // Static Singleton Initialization - public static AvailabilityStatistics Instance { get; } = new AvailabilityStatistics(); - public Statistics RawStatistics { get; private set; } - public Statistics FilteredStatistics { get; private set; } - - private AvailabilityStatistics() - { - RawStatistics = new Statistics(); - } - - internal void UpdateConfiguration(ShadowsocksController controller) - { - _controller = controller; - Reset(); - try - { - if (Config.StatisticsEnabled) - { - LoadRawStatistics(); - if (_perSecondTimer == null) - { - _perSecondTimer = new Timer(OperationsPerSecond, new Counter(), _delayBeforeStart, TimeSpan.FromSeconds(1)); - } - } - else - { - _perSecondTimer?.Dispose(); - } - } - catch (Exception e) - { - logger.LogUsefulException(e); - } - } - - private void OperationsPerSecond(object state) - { - lock(state) - { - var counter = state as Counter; - if (counter.count % _monitorInterval.TotalSeconds == 0) - { - UpdateSpeed(); - } - - if (counter.count % RecordingInterval.TotalSeconds == 0) - { - Run(); - } - - counter.count++; - } - } - - private void UpdateSpeed() - { - foreach (var kv in _inOutBoundRecords) - { - var id = kv.Key; - var record = kv.Value; - - long inboundDelta, outboundDelta; - - record.GetDelta(out inboundDelta, out outboundDelta); - - var inboundSpeed = GetSpeedInKiBPerSecond(inboundDelta, _monitorInterval.TotalSeconds); - var outboundSpeed = GetSpeedInKiBPerSecond(outboundDelta, _monitorInterval.TotalSeconds); - - // not thread safe - var inR = _inboundSpeedRecords.GetOrAdd(id, (k) => new List()); - var outR = _outboundSpeedRecords.GetOrAdd(id, (k) => new List()); - - inR.Add(inboundSpeed); - outR.Add(outboundSpeed); - - logger.Debug( - $"{id}: current/max inbound {inboundSpeed}/{inR.Max()} KiB/s, current/max outbound {outboundSpeed}/{outR.Max()} KiB/s"); - } - } - - private void Reset() - { - _inboundSpeedRecords.Clear(); - _outboundSpeedRecords.Clear(); - _latencyRecords.Clear(); - } - - private void Run() - { - UpdateRecords(); - Reset(); - } - - private void UpdateRecords() - { - var records = new Dictionary(); - UpdateRecordsState state = new UpdateRecordsState(); - int serverCount = _controller.GetCurrentConfiguration().configs.Count; - state.counter = serverCount; - bool isPing = Config.Ping; - for (int i = 0; i < serverCount; i++) - { - try - { - var server = _controller.GetCurrentConfiguration().configs[i]; - var id = server.Identifier(); - List inboundSpeedRecords = null; - List outboundSpeedRecords = null; - List latencyRecords = null; - _inboundSpeedRecords.TryGetValue(id, out inboundSpeedRecords); - _outboundSpeedRecords.TryGetValue(id, out outboundSpeedRecords); - _latencyRecords.TryGetValue(id, out latencyRecords); - StatisticsRecord record = new StatisticsRecord(id, inboundSpeedRecords, outboundSpeedRecords, latencyRecords); - /* duplicate server identifier */ - if (records.ContainsKey(id)) - records[id] = record; - else - records.Add(id, record); - if (isPing) - { - // FIXME: on ping completed, every thing could be asynchrously changed. - // focus on: Config/ RawStatistics - MyPing ping = new MyPing(server, Repeat); - ping.Completed += ping_Completed; - ping.Start(new PingState { state = state, record = record }); - } - else if (!record.IsEmptyData()) - { - AppendRecord(id, record); - } - } - catch - { - logger.Debug("config changed asynchrously, just ignore this server"); - } - } - - if (!isPing) - { - Save(); - FilterRawStatistics(); - } - } - - private void ping_Completed(object sender, MyPing.CompletedEventArgs e) - { - PingState pingState = (PingState)e.UserState; - UpdateRecordsState state = pingState.state; - Server server = e.Server; - StatisticsRecord record = pingState.record; - record.SetResponse(e.RoundtripTime); - if (!record.IsEmptyData()) - { - AppendRecord(server.Identifier(), record); - } - logger.Debug($"Ping {server} {e.RoundtripTime.Count} times, {(100 - record.PackageLoss * 100)}% packages loss, min {record.MinResponse} ms, max {record.MaxResponse} ms, avg {record.AverageResponse} ms"); - if (Interlocked.Decrement(ref state.counter) == 0) - { - Save(); - FilterRawStatistics(); - } - } - - private void AppendRecord(string serverIdentifier, StatisticsRecord record) - { - try - { - List records; - lock (RawStatistics) - { - if (!RawStatistics.TryGetValue(serverIdentifier, out records)) - { - records = new List(); - RawStatistics[serverIdentifier] = records; - } - } - records.Add(record); - } - catch (Exception e) - { - logger.LogUsefulException(e); - } - } - - private void Save() - { - logger.Debug($"save statistics to {AvailabilityStatisticsFile}"); - if (RawStatistics.Count == 0) - { - return; - } - try - { - string content; -#if DEBUG - content = JsonConvert.SerializeObject(RawStatistics, Formatting.Indented); -#else - content = JsonConvert.SerializeObject(RawStatistics, Formatting.None); -#endif - File.WriteAllText(AvailabilityStatisticsFile, content); - } - catch (IOException e) - { - logger.LogUsefulException(e); - } - } - - private bool IsValidRecord(StatisticsRecord record) - { - if (Config.ByHourOfDay) - { - if (!record.Timestamp.Hour.Equals(DateTime.Now.Hour)) return false; - } - return true; - } - - private void FilterRawStatistics() - { - try - { - logger.Debug("filter raw statistics"); - if (RawStatistics == null) return; - var filteredStatistics = new Statistics(); - - foreach (var serverAndRecords in RawStatistics) - { - var server = serverAndRecords.Key; - var filteredRecords = serverAndRecords.Value.FindAll(IsValidRecord); - filteredStatistics[server] = filteredRecords; - } - - FilteredStatistics = filteredStatistics; - } - catch (Exception e) - { - logger.LogUsefulException(e); - } - } - - private void LoadRawStatistics() - { - try - { - var path = AvailabilityStatisticsFile; - logger.Debug($"loading statistics from {path}"); - if (!File.Exists(path)) - { - using (File.Create(path)) - { - //do nothing - } - } - var content = File.ReadAllText(path); - RawStatistics = JsonConvert.DeserializeObject(content) ?? RawStatistics; - } - catch (Exception e) - { - logger.LogUsefulException(e); - Console.WriteLine($"failed to load statistics; use runtime statistics, some data may be lost"); - } - } - - private static int GetSpeedInKiBPerSecond(long bytes, double seconds) - { - var result = (int)(bytes / seconds) / 1024; - return result; - } - - public void Dispose() - { - _perSecondTimer.Dispose(); - } - - public void UpdateLatency(Server server, int latency) - { - _latencyRecords.GetOrAdd(server.Identifier(), (k) => - { - List records = new List(); - records.Add(latency); - return records; - }); - } - - public void UpdateInboundCounter(Server server, long n) - { - _inOutBoundRecords.AddOrUpdate(server.Identifier(), (k) => - { - var r = new InOutBoundRecord(); - r.UpdateInbound(n); - - return r; - }, (k, v) => - { - v.UpdateInbound(n); - return v; - }); - } - - public void UpdateOutboundCounter(Server server, long n) - { - _inOutBoundRecords.AddOrUpdate(server.Identifier(), (k) => - { - var r = new InOutBoundRecord(); - r.UpdateOutbound(n); - - return r; - }, (k, v) => - { - v.UpdateOutbound(n); - return v; - }); - } - - private class Counter - { - public int count = 0; - } - - class UpdateRecordsState - { - public int counter; - } - - class PingState - { - public UpdateRecordsState state; - public StatisticsRecord record; - } - - class MyPing - { - private static Logger logger = LogManager.GetCurrentClassLogger(); - - //arguments for ICMP tests - public const int TimeoutMilliseconds = 500; - - public EventHandler Completed; - private Server server; - - private int repeat; - private IPAddress ip; - private Ping ping; - private List RoundtripTime; - - public MyPing(Server server, int repeat) - { - this.server = server; - this.repeat = repeat; - RoundtripTime = new List(repeat); - ping = new Ping(); - ping.PingCompleted += Ping_PingCompleted; - } - - public void Start(object userstate) - { - if (server.server == "") - { - FireCompleted(new Exception("Invalid Server"), userstate); - return; - } - new Task(() => ICMPTest(0, userstate)).Start(); - } - - private void ICMPTest(int delay, object userstate) - { - try - { - logger.Debug($"Ping {server}"); - if (ip == null) - { - ip = Dns.GetHostAddresses(server.server) - .First( - ip => - ip.AddressFamily == AddressFamily.InterNetwork || - ip.AddressFamily == AddressFamily.InterNetworkV6); - } - repeat--; - if (delay > 0) - Thread.Sleep(delay); - ping.SendAsync(ip, TimeoutMilliseconds, userstate); - } - catch (Exception e) - { - logger.Error($"An exception occured while eveluating {server}"); - logger.LogUsefulException(e); - FireCompleted(e, userstate); - } - } - - private void Ping_PingCompleted(object sender, PingCompletedEventArgs e) - { - try - { - if (e.Reply.Status == IPStatus.Success) - { - logger.Debug($"Ping {server} {e.Reply.RoundtripTime} ms"); - RoundtripTime.Add((int?)e.Reply.RoundtripTime); - } - else - { - logger.Debug($"Ping {server} timeout"); - RoundtripTime.Add(null); - } - TestNext(e.UserState); - } - catch (Exception ex) - { - logger.Error($"An exception occured while eveluating {server}"); - logger.LogUsefulException(ex); - FireCompleted(ex, e.UserState); - } - } - - private void TestNext(object userstate) - { - if (repeat > 0) - { - //Do ICMPTest in a random frequency - int delay = TimeoutMilliseconds + new Random().Next() % TimeoutMilliseconds; - new Task(() => ICMPTest(delay, userstate)).Start(); - } - else - { - FireCompleted(null, userstate); - } - } - - private void FireCompleted(Exception error, object userstate) - { - Completed?.Invoke(this, new CompletedEventArgs - { - Error = error, - Server = server, - RoundtripTime = RoundtripTime, - UserState = userstate - }); - } - - public class CompletedEventArgs : EventArgs - { - public Exception Error; - public Server Server; - public List RoundtripTime; - public object UserState; - } - } - - } -} diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 06238c04..372b923b 100644 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -40,9 +40,6 @@ namespace Shadowsocks.Controller private PrivoxyRunner privoxyRunner; private readonly ConcurrentDictionary _pluginsByServer; - public AvailabilityStatistics availabilityStatistics = AvailabilityStatistics.Instance; - public StatisticsStrategyConfiguration StatisticsConfiguration { get; private set; } - private long _inboundCounter = 0; private long _outboundCounter = 0; public long InboundCounter => Interlocked.Read(ref _inboundCounter); @@ -98,7 +95,6 @@ namespace Shadowsocks.Controller httpClient = new HttpClient(); _config = Configuration.Load(); Configuration.Process(ref _config); - StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); _strategyManager = new StrategyManager(this); _pluginsByServer = new ConcurrentDictionary(); StartTrafficStatistics(61); @@ -188,8 +184,6 @@ namespace Shadowsocks.Controller httpClient.DefaultRequestHeaders.Add("User-Agent", _config.userAgentString); } - StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); - privoxyRunner = privoxyRunner ?? new PrivoxyRunner(); _pacDaemon = _pacDaemon ?? new PACDaemon(_config); @@ -202,7 +196,6 @@ namespace Shadowsocks.Controller GeositeUpdater.UpdateCompleted += PacServer_PACUpdateCompleted; GeositeUpdater.Error += PacServer_PACUpdateError; - availabilityStatistics.UpdateConfiguration(this); _listener?.Stop(); StopPlugins(); @@ -220,7 +213,6 @@ namespace Shadowsocks.Controller privoxyRunner.Start(_config); TCPRelay tcpRelay = new TCPRelay(this, _config); - tcpRelay.OnConnected += UpdateLatency; tcpRelay.OnInbound += UpdateInboundCounter; tcpRelay.OnOutbound += UpdateOutboundCounter; tcpRelay.OnFailed += (o, e) => GetCurrentStrategy()?.SetFailure(e.server); @@ -524,7 +516,7 @@ namespace Shadowsocks.Controller #endregion - #region Statistics + #region Strategy public void SelectStrategy(string strategyID) { @@ -533,12 +525,6 @@ namespace Shadowsocks.Controller SaveConfig(_config); } - public void SaveStrategyConfigurations(StatisticsStrategyConfiguration configuration) - { - StatisticsConfiguration = configuration; - StatisticsStrategyConfiguration.Save(configuration); - } - public IList GetStrategies() { return _strategyManager.GetStrategies(); @@ -556,43 +542,16 @@ namespace Shadowsocks.Controller return null; } - public void UpdateStatisticsConfiguration(bool enabled) - { - if (availabilityStatistics != null) - { - availabilityStatistics.UpdateConfiguration(this); - _config.availabilityStatistics = enabled; - SaveConfig(_config); - } - } - - public void UpdateLatency(object sender, SSTCPConnectedEventArgs args) - { - GetCurrentStrategy()?.UpdateLatency(args.server, args.latency); - if (_config.availabilityStatistics) - { - availabilityStatistics.UpdateLatency(args.server, (int)args.latency.TotalMilliseconds); - } - } - public void UpdateInboundCounter(object sender, SSTransmitEventArgs args) { GetCurrentStrategy()?.UpdateLastRead(args.server); Interlocked.Add(ref _inboundCounter, args.length); - if (_config.availabilityStatistics) - { - availabilityStatistics.UpdateInboundCounter(args.server, args.length); - } } public void UpdateOutboundCounter(object sender, SSTransmitEventArgs args) { GetCurrentStrategy()?.UpdateLastWrite(args.server); Interlocked.Add(ref _outboundCounter, args.length); - if (_config.availabilityStatistics) - { - availabilityStatistics.UpdateOutboundCounter(args.server, args.length); - } } #endregion diff --git a/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs b/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs deleted file mode 100644 index a2d9bfc7..00000000 --- a/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs +++ /dev/null @@ -1,170 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading; - -using Newtonsoft.Json; -using NLog; -using Shadowsocks.Model; - -namespace Shadowsocks.Controller.Strategy -{ - using Statistics = Dictionary>; - - internal class StatisticsStrategy : IStrategy, IDisposable - { - private static Logger logger = LogManager.GetCurrentClassLogger(); - - private readonly ShadowsocksController _controller; - private Server _currentServer; - private readonly Timer _timer; - private Statistics _filteredStatistics; - private AvailabilityStatistics Service => _controller.availabilityStatistics; - private int ChoiceKeptMilliseconds - => (int)TimeSpan.FromMinutes(_controller.StatisticsConfiguration.ChoiceKeptMinutes).TotalMilliseconds; - - public StatisticsStrategy(ShadowsocksController controller) - { - _controller = controller; - var servers = controller.GetCurrentConfiguration().configs; - var randomIndex = new Random().Next() % servers.Count; - _currentServer = servers[randomIndex]; //choose a server randomly at first - // FIXME: consider Statistics and Config changing asynchrously. - _timer = new Timer(ReloadStatisticsAndChooseAServer); - } - - private void ReloadStatisticsAndChooseAServer(object obj) - { - logger.Debug("Reloading statistics and choose a new server...."); - var servers = _controller.GetCurrentConfiguration().configs; - LoadStatistics(); - ChooseNewServer(servers); - } - - private void LoadStatistics() - { - _filteredStatistics = - Service.FilteredStatistics ?? - Service.RawStatistics ?? - _filteredStatistics; - } - - //return the score by data - //server with highest score will be choosen - private float? GetScore(string identifier, List records) - { - var config = _controller.StatisticsConfiguration; - float? score = null; - - var averageRecord = new StatisticsRecord(identifier, - records.Where(record => record.MaxInboundSpeed != null).Select(record => record.MaxInboundSpeed.Value).ToList(), - records.Where(record => record.MaxOutboundSpeed != null).Select(record => record.MaxOutboundSpeed.Value).ToList(), - records.Where(record => record.AverageLatency != null).Select(record => record.AverageLatency.Value).ToList()); - averageRecord.SetResponse(records.Select(record => record.AverageResponse).ToList()); - - foreach (var calculation in config.Calculations) - { - var name = calculation.Key; - var field = typeof (StatisticsRecord).GetField(name); - dynamic value = field?.GetValue(averageRecord); - var factor = calculation.Value; - if (value == null || factor.Equals(0)) continue; - score = score ?? 0; - score += value * factor; - } - - if (score != null) - { - logger.Debug($"Highest score: {score} {JsonConvert.SerializeObject(averageRecord, Formatting.Indented)}"); - } - return score; - } - - private void ChooseNewServer(List servers) - { - if (_filteredStatistics == null || servers.Count == 0) - { - return; - } - try - { - var serversWithStatistics = (from server in servers - let id = server.Identifier() - where _filteredStatistics.ContainsKey(id) - let score = GetScore(id, _filteredStatistics[id]) - where score != null - select new - { - server, - score - }).ToArray(); - - if (serversWithStatistics.Length < 2) - { - LogWhenEnabled("no enough statistics data or all factors in calculations are 0"); - return; - } - - var bestResult = serversWithStatistics - .Aggregate((server1, server2) => server1.score > server2.score ? server1 : server2); - - LogWhenEnabled($"Switch to server: {bestResult.server.ToString()} by statistics: score {bestResult.score}"); - _currentServer = bestResult.server; - } - catch (Exception e) - { - logger.LogUsefulException(e); - } - } - - private void LogWhenEnabled(string log) - { - if (_controller.GetCurrentStrategy()?.ID == ID) //output when enabled - { - Console.WriteLine(log); - } - } - - public string ID => "com.shadowsocks.strategy.scbs"; - - public string Name => I18N.GetString("Choose by statistics"); - - public Server GetAServer(IStrategyCallerType type, IPEndPoint localIPEndPoint, EndPoint destEndPoint) - { - if (_currentServer == null) - { - ChooseNewServer(_controller.GetCurrentConfiguration().configs); - } - return _currentServer; //current server cached for CachedInterval - } - - public void ReloadServers() - { - ChooseNewServer(_controller.GetCurrentConfiguration().configs); - _timer?.Change(0, ChoiceKeptMilliseconds); - } - - public void SetFailure(Server server) - { - logger.Debug($"failure: {server.ToString()}"); - } - - public void UpdateLastRead(Server server) - { - } - - public void UpdateLastWrite(Server server) - { - } - - public void UpdateLatency(Server server, TimeSpan latency) - { - } - - public void Dispose() - { - _timer.Dispose(); - } - } -} diff --git a/shadowsocks-csharp/Controller/Strategy/StrategyManager.cs b/shadowsocks-csharp/Controller/Strategy/StrategyManager.cs index 81a00e4d..be8869da 100644 --- a/shadowsocks-csharp/Controller/Strategy/StrategyManager.cs +++ b/shadowsocks-csharp/Controller/Strategy/StrategyManager.cs @@ -13,7 +13,6 @@ namespace Shadowsocks.Controller.Strategy _strategies = new List(); _strategies.Add(new BalancingStrategy(controller)); _strategies.Add(new HighAvailabilityStrategy(controller)); - _strategies.Add(new StatisticsStrategy(controller)); // TODO: load DLL plugins } public IList GetStrategies() diff --git a/shadowsocks-csharp/Data/i18n.csv b/shadowsocks-csharp/Data/i18n.csv index 61664367..4a373e0d 100644 --- a/shadowsocks-csharp/Data/i18n.csv +++ b/shadowsocks-csharp/Data/i18n.csv @@ -16,7 +16,6 @@ PAC,Сценарий настройки (PAC),PAC 模式,PAC 模式,PACモード Global,Для всей системы,全局模式,全局模式,グローバルプロキシ,전역,Global Servers,Серверы,服务器,伺服器,サーバー,서버,Serveurs Edit Servers...,Редактировать серверы…,编辑服务器...,編輯伺服器...,サーバーの編集...,서버 수정…,Éditer serveurs… -Statistics Config...,Настройки статистики…,统计配置...,統計設定檔...,統計情報の設定...,통계 설정,Configuration des statistiques… Online Config...,,在线配置...,線上配置...,,, Start on Boot,Автозагрузка,开机启动,開機啟動,システム起動時に実行,시스템 시작 시에 시작하기,Démarrage automatique Associate ss:// Links,Ассоциированный ss:// Ссылки,关联 ss:// 链接,關聯 ss:// 鏈接,ss:// リンクの関連付け,ss:// 링크 연결, @@ -47,7 +46,6 @@ Quit,Выход,退出,結束,終了,종료,Quitter Edit Servers,Редактирование серверов,编辑服务器,編輯伺服器,サーバーの編集,서버 수정,Éditer serveurs Load Balance,Балансировка нагрузки,负载均衡,負載平衡,サーバーロードバランス,로드밸런싱,Répartition de charge High Availability,Высокая доступность,高可用,高可用性,高可用性,고가용성,Haute disponibilité -Choose by statistics,На основе статистики,根据统计,根據統計,統計で選ぶ,통계 기반,Choisissez par statistiques Show Plugin Output,События плагинов в журнале,显示插件输出,,プラグインの出力情報を表示,플러그인 출력 보이기,Afficher la sortie du plugin Write translation template,Создать шаблон для перевода,写入翻译模板,,翻訳テンプレートファイルを書き込む,번역 템플릿 쓰기,Écrire un modèle de traduction ,,,,,, @@ -81,36 +79,6 @@ Move D&own,Ниже,下移(&O),下移 (&O),下に移動 (&O),아래로 (&O),Desc deprecated,Устаревшее,不推荐,不推薦,非推奨,더 이상 사용되지 않음,Obsolète "Encryption method {0} not exist, will replace with {1}",,加密方法{0}不存在,将使用{1}代替,,暗号化方式{0}が存在しません,{1}に置換します,{0} 암호화 방식이 존재하지 않으므로 {1}로 대체될 것입니다.,"Méthode de chiffrement {0} n'existe pas, sera remplacée par {1}" ,,,,,, -#Statistics Config,,,,,, -,,,,,, -Enable Statistics,Включить сбор статистики,启用统计,,統計を有効にする,통계 활성화,Activer statistiques -Ping Test,Проверка связи (Ping),Ping测试,,Ping測定,Ping 테스트,Test ping -packages everytime,пакета на проверку,个包/次,,パケット/回,시간 당 패킷,Packages à chaque fois -By hour of day,Ежечасно,按照每天的小时数统计,,毎日の時間数で統計,매 시간,Par heure du jour -Collect data per,Собирать данные за,收集数据每,,ごとにデータを収集,데이터 수집 기간,Recueillir des données par -Keep choice for,Хранить отбор данных за,保持选择每,,,설정 유지하기,Gardez le choix pour -minutes,мин.,分钟,,分,분,Minutes -Final Score:,Финальная оценка:,总分:,,,최종 점수:,Score final: -AverageLatency,СредЗадержка,平均延迟,,平均遅延時間,평균 지연시간,LatenceMoyenne -MinLatency,МинЗадержка,最小延迟,,最小遅延時間,최소 지연시간,MinLatence -MaxLatency,МаксЗадержка,最大延迟,,最大遅延時間,최대 지연시간,MaxLatence -AverageInboundSpeed,СредВходСкорость,平均入站速度,,平均インバウンド速度,평균 인바운드 속도,VitesseEntranteMoyenne -MinInboundSpeed,МинВходСкорость,最小入站速度,,最小インバウンド速度,최소 인바운드 속도,MinVitesseEntrante -MaxInboundSpeed,СредВходСкорость,最大入站速度,,最大インバウンド速度,최대 인바운드 속도,MaxVitesseEntrante -AverageOutboundSpeed,СредИсхСкорость,平均出站速度,,平均アウトバウンド速度,평균 아웃바운드 속도,VitesseSortanteMoyenne -MinOutboundSpeed,МинИсхСкорость,最小出站速度,,最小アウトバウンド速度,최소 아웃바운드 속도,MinVitesseSortante -MaxOutboundSpeed,МаксИсхСкорость,最大出站速度,,最大アウトバウンド速度,최대 아웃바운드 속도,MaxVitesseSortante -AverageResponse,СредВремяОтвета,平均响应速度,,平均レスポンス速度,평균 응답,RéponseMoyenne -MinResponse,МинВремяОтвета,最小响应速度,,最小レスポンス速度,최소 응답,MinRéponse -MaxResponse,МаксВремяОтвета,最大响应速度,,最大レスポンス速度,최대 응답,MaxRéponse -PackageLoss,ПотериПакетов,丢包率,,パケットロス率,패킷 손실,Perte de paquets -Speed,Скорость,速度,,速度,속도,Vitesse -Package Loss,Потери пакетов,丢包率,,パケットロス率,패킷 손실,Perte de paquets -Ping,Ping,网络延迟,,Ping,Ping,Ping -Chart Mode,График,图表模式,,図表モード,차트 모드,Mode graphique -24h,24ч,24小时,,24時間,24시간,24h -all,За все время,全部,,すべて,전체,tout -,,,,,, # Log Form,,,,,, ,,,,,, &File,Файл,文件(&F),檔案 (&F),ファイル (&F),파일 (&F),Fichier diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index 322dca5e..b955e0f7 100644 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -37,7 +37,6 @@ namespace Shadowsocks.Model public bool useOnlinePac; public bool secureLocalPac; // enable secret for PAC server public bool regeneratePacOnUpdate; // regenerate pac.txt on version update - public bool availabilityStatistics; public bool autoCheckUpdate; public bool checkPreRelease; public string skippedUpdateVersion; // skip the update with this version number @@ -76,7 +75,6 @@ namespace Shadowsocks.Model useOnlinePac = false; secureLocalPac = true; regeneratePacOnUpdate = true; - availabilityStatistics = false; autoCheckUpdate = false; checkPreRelease = false; skippedUpdateVersion = ""; diff --git a/shadowsocks-csharp/Model/StatisticsRecord.cs b/shadowsocks-csharp/Model/StatisticsRecord.cs deleted file mode 100644 index 5c1051a4..00000000 --- a/shadowsocks-csharp/Model/StatisticsRecord.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Shadowsocks.Model -{ - // Simple processed records for a short period of time - public class StatisticsRecord - { - public DateTime Timestamp { get; set; } = DateTime.Now; - public string ServerIdentifier { get; set; } - - // in ping-only records, these fields would be null - public int? AverageLatency; - public int? MinLatency; - public int? MaxLatency; - - private bool EmptyLatencyData => (AverageLatency == null) && (MinLatency == null) && (MaxLatency == null); - - public int? AverageInboundSpeed; - public int? MinInboundSpeed; - public int? MaxInboundSpeed; - - private bool EmptyInboundSpeedData - => (AverageInboundSpeed == null) && (MinInboundSpeed == null) && (MaxInboundSpeed == null); - - public int? AverageOutboundSpeed; - public int? MinOutboundSpeed; - public int? MaxOutboundSpeed; - - private bool EmptyOutboundSpeedData - => (AverageOutboundSpeed == null) && (MinOutboundSpeed == null) && (MaxOutboundSpeed == null); - - // if user disabled ping test, response would be null - public int? AverageResponse; - public int? MinResponse; - public int? MaxResponse; - public float? PackageLoss; - - private bool EmptyResponseData - => (AverageResponse == null) && (MinResponse == null) && (MaxResponse == null) && (PackageLoss == null); - - public bool IsEmptyData() { - return EmptyInboundSpeedData && EmptyOutboundSpeedData && EmptyResponseData && EmptyLatencyData; - } - - public StatisticsRecord() - { - } - - public StatisticsRecord(string identifier, ICollection inboundSpeedRecords, ICollection outboundSpeedRecords, ICollection latencyRecords) - { - ServerIdentifier = identifier; - var inbound = inboundSpeedRecords?.Where(s => s > 0).ToList(); - if (inbound != null && inbound.Any()) - { - AverageInboundSpeed = (int) inbound.Average(); - MinInboundSpeed = inbound.Min(); - MaxInboundSpeed = inbound.Max(); - } - var outbound = outboundSpeedRecords?.Where(s => s > 0).ToList(); - if (outbound!= null && outbound.Any()) - { - AverageOutboundSpeed = (int) outbound.Average(); - MinOutboundSpeed = outbound.Min(); - MaxOutboundSpeed = outbound.Max(); - } - var latency = latencyRecords?.Where(s => s > 0).ToList(); - if (latency!= null && latency.Any()) - { - AverageLatency = (int) latency.Average(); - MinLatency = latency.Min(); - MaxLatency = latency.Max(); - } - } - - public StatisticsRecord(string identifier, ICollection responseRecords) - { - ServerIdentifier = identifier; - SetResponse(responseRecords); - } - - public void SetResponse(ICollection responseRecords) - { - if (responseRecords == null) return; - var records = responseRecords.Where(response => response != null).Select(response => response.Value).ToList(); - if (!records.Any()) return; - AverageResponse = (int?) records.Average(); - MinResponse = records.Min(); - MaxResponse = records.Max(); - PackageLoss = responseRecords.Count(response => response != null)/(float) responseRecords.Count; - } - } -} diff --git a/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs b/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs deleted file mode 100644 index 18028856..00000000 --- a/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; - -using Newtonsoft.Json; -using NLog; - -namespace Shadowsocks.Model -{ - [Serializable] - public class StatisticsStrategyConfiguration - { - private static Logger logger = LogManager.GetCurrentClassLogger(); - - public static readonly string ID = "com.shadowsocks.strategy.statistics"; - public bool StatisticsEnabled { get; set; } = false; - public bool ByHourOfDay { get; set; } = true; - public bool Ping { get; set; } - public int ChoiceKeptMinutes { get; set; } = 10; - public int DataCollectionMinutes { get; set; } = 10; - public int RepeatTimesNum { get; set; } = 4; - - 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) - { - var configuration = new StatisticsStrategyConfiguration(); - Save(configuration); - return configuration; - } - catch (Exception e) - { - logger.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) - { - logger.LogUsefulException(e); - } - } - - public Dictionary Calculations; - - public StatisticsStrategyConfiguration() - { - var properties = typeof(StatisticsRecord).GetFields(BindingFlags.Instance | BindingFlags.Public); - Calculations = properties.ToDictionary(p => p.Name, _ => (float)0); - } - } -} diff --git a/shadowsocks-csharp/Properties/DataSources/Shadowsocks.Model.StatisticsStrategyConfiguration.datasource b/shadowsocks-csharp/Properties/DataSources/Shadowsocks.Model.StatisticsStrategyConfiguration.datasource deleted file mode 100644 index a1a52e80..00000000 --- a/shadowsocks-csharp/Properties/DataSources/Shadowsocks.Model.StatisticsStrategyConfiguration.datasource +++ /dev/null @@ -1,10 +0,0 @@ - - - - Shadowsocks.Model.StatisticsStrategyConfiguration, Shadowsocks, Version=2.5.2.0, Culture=neutral, PublicKeyToken=null - \ No newline at end of file diff --git a/shadowsocks-csharp/View/CalculationControl.Designer.cs b/shadowsocks-csharp/View/CalculationControl.Designer.cs deleted file mode 100644 index 9995bb05..00000000 --- a/shadowsocks-csharp/View/CalculationControl.Designer.cs +++ /dev/null @@ -1,113 +0,0 @@ -namespace Shadowsocks.View -{ - partial class CalculationControl - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Component Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.factorNum = new System.Windows.Forms.NumericUpDown(); - this.multiply = new System.Windows.Forms.Label(); - this.plus = new System.Windows.Forms.Label(); - this.valueLabel = new System.Windows.Forms.Label(); - ((System.ComponentModel.ISupportInitialize)(this.factorNum)).BeginInit(); - this.SuspendLayout(); - // - // factorNum - // - this.factorNum.DecimalPlaces = 2; - this.factorNum.Dock = System.Windows.Forms.DockStyle.Right; - this.factorNum.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.factorNum.Increment = new decimal(new int[] { - 1, - 0, - 0, - 131072}); - this.factorNum.Location = new System.Drawing.Point(236, 0); - this.factorNum.Minimum = new decimal(new int[] { - 1000, - 0, - 0, - -2147418112}); - this.factorNum.Name = "factorNum"; - this.factorNum.Size = new System.Drawing.Size(86, 34); - this.factorNum.TabIndex = 6; - // - // multiply - // - this.multiply.AutoSize = true; - this.multiply.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.multiply.Location = new System.Drawing.Point(202, 2); - this.multiply.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); - this.multiply.Name = "multiply"; - this.multiply.Size = new System.Drawing.Size(26, 28); - this.multiply.TabIndex = 2; - this.multiply.Text = "×"; - // - // plus - // - this.plus.AutoSize = true; - this.plus.Font = new System.Drawing.Font("Segoe UI", 10F); - this.plus.Location = new System.Drawing.Point(5, 2); - this.plus.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); - this.plus.Name = "plus"; - this.plus.Size = new System.Drawing.Size(26, 28); - this.plus.TabIndex = 3; - this.plus.Text = "+"; - // - // valueLabel - // - this.valueLabel.AutoSize = true; - this.valueLabel.Font = new System.Drawing.Font("Microsoft YaHei", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.valueLabel.Location = new System.Drawing.Point(39, 6); - this.valueLabel.Name = "valueLabel"; - this.valueLabel.Size = new System.Drawing.Size(118, 24); - this.valueLabel.TabIndex = 7; - this.valueLabel.Text = "PackageLoss"; - // - // CalculationControl - // - this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.valueLabel); - this.Controls.Add(this.factorNum); - this.Controls.Add(this.multiply); - this.Controls.Add(this.plus); - this.Margin = new System.Windows.Forms.Padding(0); - this.Name = "CalculationControl"; - this.Size = new System.Drawing.Size(322, 34); - ((System.ComponentModel.ISupportInitialize)(this.factorNum)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - private System.Windows.Forms.NumericUpDown factorNum; - private System.Windows.Forms.Label multiply; - private System.Windows.Forms.Label plus; - private System.Windows.Forms.Label valueLabel; - } -} diff --git a/shadowsocks-csharp/View/CalculationControl.cs b/shadowsocks-csharp/View/CalculationControl.cs deleted file mode 100644 index c7f8fdf2..00000000 --- a/shadowsocks-csharp/View/CalculationControl.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; -using System.Data; -using System.Globalization; -using System.Linq; -using System.Text; -using System.Windows.Forms; - -namespace Shadowsocks.View -{ - public partial class CalculationControl : UserControl - { - public CalculationControl(string text, float value) - { - InitializeComponent(); - valueLabel.Text = text; - factorNum.Value = (decimal) value; - } - - public string Value => valueLabel.Text; - public float Factor => (float) factorNum.Value; - } -} diff --git a/shadowsocks-csharp/View/CalculationControl.resx b/shadowsocks-csharp/View/CalculationControl.resx deleted file mode 100644 index 1af7de15..00000000 --- a/shadowsocks-csharp/View/CalculationControl.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index ddbf9c48..2891dad1 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -265,7 +265,6 @@ 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), new MenuItem("-"), CreateMenuItem("Share Server Config...", new EventHandler(this.QRCodeItem_Click)), CreateMenuItem("Scan QRCode from Screen...", new EventHandler(this.ScanQRCodeItem_Click)), @@ -725,12 +724,6 @@ namespace Shadowsocks.View Process.Start(_urlToOpen); } - private void StatisticsConfigItem_Click(object sender, EventArgs e) - { - StatisticsStrategyConfigurationForm form = new StatisticsStrategyConfigurationForm(controller); - form.Show(); - } - private void QRCodeItem_Click(object sender, EventArgs e) { if (serverSharingWindow == null) diff --git a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs b/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs deleted file mode 100644 index 0e80c12e..00000000 --- a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs +++ /dev/null @@ -1,537 +0,0 @@ -namespace Shadowsocks.View -{ - partial class StatisticsStrategyConfigurationForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - 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.PingCheckBox = new System.Windows.Forms.CheckBox(); - this.KeepChoiceForLabel = new System.Windows.Forms.Label(); - this.MinutesLabel2 = 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(); - this.splitContainer1 = new System.Windows.Forms.SplitContainer(); - this.splitContainer2 = new System.Windows.Forms.SplitContainer(); - this.CollectDataPerLabel = new System.Windows.Forms.Label(); - this.MinutesLabel1 = new System.Windows.Forms.Label(); - this.dataCollectionMinutesNum = new System.Windows.Forms.NumericUpDown(); - this.StatisticsEnabledCheckBox = new System.Windows.Forms.CheckBox(); - this.choiceKeptMinutesNum = new System.Windows.Forms.NumericUpDown(); - this.byHourOfDayCheckBox = new System.Windows.Forms.CheckBox(); - this.repeatTimesNum = new System.Windows.Forms.NumericUpDown(); - this.PackagePerPingLabel = new System.Windows.Forms.Label(); - this.splitContainer3 = new System.Windows.Forms.SplitContainer(); - this.FinalScoreLabel = new System.Windows.Forms.Label(); - this.calculationContainer = new System.Windows.Forms.FlowLayoutPanel(); - this.serverSelector = new System.Windows.Forms.ComboBox(); - this.CancelButton = new System.Windows.Forms.Button(); - this.OKButton = new System.Windows.Forms.Button(); - this.CalculatinTip = new System.Windows.Forms.ToolTip(this.components); - this.bindingConfiguration = new System.Windows.Forms.BindingSource(this.components); - ((System.ComponentModel.ISupportInitialize)(this.StatisticsChart)).BeginInit(); - this.chartModeSelector.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); - this.splitContainer1.Panel1.SuspendLayout(); - this.splitContainer1.Panel2.SuspendLayout(); - this.splitContainer1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit(); - this.splitContainer2.Panel1.SuspendLayout(); - this.splitContainer2.Panel2.SuspendLayout(); - this.splitContainer2.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.dataCollectionMinutesNum)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.choiceKeptMinutesNum)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.repeatTimesNum)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer3)).BeginInit(); - 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; - chartArea1.AxisX.MajorGrid.Enabled = false; - chartArea1.AxisY.MajorGrid.Enabled = false; - chartArea1.AxisY2.Enabled = System.Windows.Forms.DataVisualization.Charting.AxisEnabled.False; - chartArea1.AxisY2.MajorGrid.Enabled = false; - chartArea1.BackColor = System.Drawing.Color.Transparent; - chartArea1.Name = "DataArea"; - this.StatisticsChart.ChartAreas.Add(chartArea1); - this.StatisticsChart.Dock = System.Windows.Forms.DockStyle.Fill; - 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; - series1.ChartArea = "DataArea"; - series1.Color = System.Drawing.Color.DarkGray; - series1.Legend = "ChartLegend"; - series1.Name = "Speed"; - series1.ToolTip = "#VALX\\nMax inbound speed\\n#VAL KiB/s"; - series1.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Time; - series2.ChartArea = "DataArea"; - series2.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Bubble; - series2.Color = System.Drawing.Color.Crimson; - series2.CustomProperties = "EmptyPointValue=Zero"; - series2.Legend = "ChartLegend"; - series2.Name = "Package Loss"; - series2.ToolTip = "#VALX\\n#VAL%"; - series2.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Time; - series2.YAxisType = System.Windows.Forms.DataVisualization.Charting.AxisType.Secondary; - series2.YValuesPerPoint = 2; - series3.BorderWidth = 5; - series3.ChartArea = "DataArea"; - series3.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; - series3.Color = System.Drawing.Color.DodgerBlue; - series3.Legend = "ChartLegend"; - series3.MarkerSize = 10; - series3.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Circle; - series3.Name = "Ping"; - series3.ToolTip = "#VALX\\n#VAL ms"; - series3.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Time; - this.StatisticsChart.Series.Add(series1); - this.StatisticsChart.Series.Add(series2); - this.StatisticsChart.Series.Add(series3); - this.StatisticsChart.Size = new System.Drawing.Size(982, 435); - this.StatisticsChart.TabIndex = 2; - // - // PingCheckBox - // - 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); - // - // KeepChoiceForLabel - // - this.KeepChoiceForLabel.AutoSize = true; - this.KeepChoiceForLabel.Location = new System.Drawing.Point(9, 206); - this.KeepChoiceForLabel.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); - this.KeepChoiceForLabel.Name = "KeepChoiceForLabel"; - this.KeepChoiceForLabel.Size = new System.Drawing.Size(139, 23); - this.KeepChoiceForLabel.TabIndex = 8; - this.KeepChoiceForLabel.Text = "Keep choice for"; - // - // MinutesLabel2 - // - this.MinutesLabel2.AutoSize = true; - this.MinutesLabel2.Location = new System.Drawing.Point(286, 206); - this.MinutesLabel2.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); - this.MinutesLabel2.Name = "MinutesLabel2"; - this.MinutesLabel2.Size = new System.Drawing.Size(75, 23); - this.MinutesLabel2.TabIndex = 9; - this.MinutesLabel2.Text = "minutes"; - // - // 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(733, 182); - 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); - this.chartModeSelector.Size = new System.Drawing.Size(234, 103); - this.chartModeSelector.TabIndex = 3; - this.chartModeSelector.TabStop = false; - this.chartModeSelector.Text = "Chart Mode"; - // - // allMode - // - this.allMode.AutoSize = true; - 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(50, 27); - this.allMode.TabIndex = 1; - this.allMode.Text = "all"; - this.allMode.UseVisualStyleBackColor = true; - this.allMode.CheckedChanged += new System.EventHandler(this.allMode_CheckedChanged); - // - // dayMode - // - this.dayMode.AutoSize = true; - this.dayMode.Checked = true; - 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(61, 27); - this.dayMode.TabIndex = 0; - this.dayMode.TabStop = true; - this.dayMode.Text = "24h"; - this.dayMode.UseVisualStyleBackColor = true; - this.dayMode.CheckedChanged += new System.EventHandler(this.dayMode_CheckedChanged); - // - // 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"; - this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; - // - // splitContainer1.Panel1 - // - this.splitContainer1.Panel1.Controls.Add(this.splitContainer2); - // - // splitContainer1.Panel2 - // - this.splitContainer1.Panel2.Controls.Add(this.serverSelector); - this.splitContainer1.Panel2.Controls.Add(this.CancelButton); - 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(982, 753); - this.splitContainer1.SplitterDistance = 308; - this.splitContainer1.SplitterWidth = 10; - this.splitContainer1.TabIndex = 12; - // - // splitContainer2 - // - this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill; - this.splitContainer2.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; - this.splitContainer2.IsSplitterFixed = true; - this.splitContainer2.Location = new System.Drawing.Point(0, 0); - this.splitContainer2.Margin = new System.Windows.Forms.Padding(5, 10, 5, 10); - this.splitContainer2.Name = "splitContainer2"; - // - // splitContainer2.Panel1 - // - this.splitContainer2.Panel1.Controls.Add(this.CollectDataPerLabel); - this.splitContainer2.Panel1.Controls.Add(this.MinutesLabel1); - this.splitContainer2.Panel1.Controls.Add(this.dataCollectionMinutesNum); - this.splitContainer2.Panel1.Controls.Add(this.StatisticsEnabledCheckBox); - this.splitContainer2.Panel1.Controls.Add(this.choiceKeptMinutesNum); - this.splitContainer2.Panel1.Controls.Add(this.byHourOfDayCheckBox); - this.splitContainer2.Panel1.Controls.Add(this.repeatTimesNum); - this.splitContainer2.Panel1.Controls.Add(this.PackagePerPingLabel); - this.splitContainer2.Panel1.Controls.Add(this.KeepChoiceForLabel); - this.splitContainer2.Panel1.Controls.Add(this.PingCheckBox); - this.splitContainer2.Panel1.Controls.Add(this.MinutesLabel2); - // - // splitContainer2.Panel2 - // - this.splitContainer2.Panel2.Controls.Add(this.splitContainer3); - this.splitContainer2.Size = new System.Drawing.Size(982, 308); - this.splitContainer2.SplitterDistance = 384; - this.splitContainer2.SplitterWidth = 5; - this.splitContainer2.TabIndex = 7; - // - // CollectDataPerLabel - // - this.CollectDataPerLabel.AutoSize = true; - this.CollectDataPerLabel.Location = new System.Drawing.Point(9, 164); - this.CollectDataPerLabel.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); - this.CollectDataPerLabel.Name = "CollectDataPerLabel"; - this.CollectDataPerLabel.Size = new System.Drawing.Size(139, 23); - this.CollectDataPerLabel.TabIndex = 20; - this.CollectDataPerLabel.Text = "Collect data per"; - // - // MinutesLabel1 - // - this.MinutesLabel1.AutoSize = true; - this.MinutesLabel1.Font = new System.Drawing.Font("微软雅黑", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.MinutesLabel1.Location = new System.Drawing.Point(286, 165); - this.MinutesLabel1.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); - this.MinutesLabel1.Name = "MinutesLabel1"; - this.MinutesLabel1.Size = new System.Drawing.Size(75, 23); - this.MinutesLabel1.TabIndex = 19; - this.MinutesLabel1.Text = "minutes"; - // - // dataCollectionMinutesNum - // - this.dataCollectionMinutesNum.DataBindings.Add(new System.Windows.Forms.Binding("Value", this.bindingConfiguration, "DataCollectionMinutes", true)); - this.dataCollectionMinutesNum.Increment = new decimal(new int[] { - 10, - 0, - 0, - 0}); - 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, - 0, - 0, - 0}); - this.dataCollectionMinutesNum.Minimum = new decimal(new int[] { - 1, - 0, - 0, - 0}); - this.dataCollectionMinutesNum.Name = "dataCollectionMinutesNum"; - this.dataCollectionMinutesNum.Size = new System.Drawing.Size(100, 29); - this.dataCollectionMinutesNum.TabIndex = 18; - this.dataCollectionMinutesNum.Value = new decimal(new int[] { - 10, - 0, - 0, - 0}); - // - // StatisticsEnabledCheckBox - // - this.StatisticsEnabledCheckBox.AutoSize = true; - this.StatisticsEnabledCheckBox.DataBindings.Add(new System.Windows.Forms.Binding("Checked", this.bindingConfiguration, "StatisticsEnabled", true)); - 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(163, 27); - this.StatisticsEnabledCheckBox.TabIndex = 17; - this.StatisticsEnabledCheckBox.Text = "Enable Statistics"; - this.StatisticsEnabledCheckBox.UseVisualStyleBackColor = true; - // - // choiceKeptMinutesNum - // - this.choiceKeptMinutesNum.DataBindings.Add(new System.Windows.Forms.Binding("Value", this.bindingConfiguration, "ChoiceKeptMinutes", true)); - this.choiceKeptMinutesNum.Increment = new decimal(new int[] { - 10, - 0, - 0, - 0}); - this.choiceKeptMinutesNum.Location = new System.Drawing.Point(177, 204); - this.choiceKeptMinutesNum.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); - this.choiceKeptMinutesNum.Maximum = new decimal(new int[] { - 120, - 0, - 0, - 0}); - this.choiceKeptMinutesNum.Minimum = new decimal(new int[] { - 1, - 0, - 0, - 0}); - this.choiceKeptMinutesNum.Name = "choiceKeptMinutesNum"; - this.choiceKeptMinutesNum.Size = new System.Drawing.Size(100, 29); - this.choiceKeptMinutesNum.TabIndex = 16; - this.choiceKeptMinutesNum.Value = new decimal(new int[] { - 10, - 0, - 0, - 0}); - // - // byHourOfDayCheckBox - // - 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, 127); - this.byHourOfDayCheckBox.Margin = new System.Windows.Forms.Padding(5, 10, 5, 10); - this.byHourOfDayCheckBox.Name = "byHourOfDayCheckBox"; - this.byHourOfDayCheckBox.Size = new System.Drawing.Size(150, 27); - this.byHourOfDayCheckBox.TabIndex = 15; - this.byHourOfDayCheckBox.Text = "By hour of day"; - this.byHourOfDayCheckBox.UseVisualStyleBackColor = true; - // - // repeatTimesNum - // - this.repeatTimesNum.DataBindings.Add(new System.Windows.Forms.Binding("Value", this.bindingConfiguration, "RepeatTimesNum", true)); - 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, - 0, - 0, - 0}); - this.repeatTimesNum.Name = "repeatTimesNum"; - this.repeatTimesNum.Size = new System.Drawing.Size(99, 29); - this.repeatTimesNum.TabIndex = 14; - this.repeatTimesNum.Value = new decimal(new int[] { - 4, - 0, - 0, - 0}); - // - // PackagePerPingLabel - // - this.PackagePerPingLabel.AutoSize = true; - this.PackagePerPingLabel.Font = new System.Drawing.Font("微软雅黑", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.PackagePerPingLabel.Location = new System.Drawing.Point(139, 86); - this.PackagePerPingLabel.Name = "PackagePerPingLabel"; - this.PackagePerPingLabel.Size = new System.Drawing.Size(172, 23); - this.PackagePerPingLabel.TabIndex = 13; - this.PackagePerPingLabel.Text = "packages everytime"; - // - // splitContainer3 - // - this.splitContainer3.Dock = System.Windows.Forms.DockStyle.Fill; - this.splitContainer3.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; - this.splitContainer3.IsSplitterFixed = true; - this.splitContainer3.Location = new System.Drawing.Point(0, 0); - this.splitContainer3.Margin = new System.Windows.Forms.Padding(5, 10, 5, 10); - this.splitContainer3.Name = "splitContainer3"; - this.splitContainer3.Orientation = System.Windows.Forms.Orientation.Horizontal; - // - // splitContainer3.Panel1 - // - this.splitContainer3.Panel1.Controls.Add(this.FinalScoreLabel); - // - // splitContainer3.Panel2 - // - this.splitContainer3.Panel2.Controls.Add(this.calculationContainer); - this.splitContainer3.Size = new System.Drawing.Size(593, 308); - this.splitContainer3.SplitterDistance = 42; - this.splitContainer3.SplitterWidth = 1; - this.splitContainer3.TabIndex = 6; - // - // FinalScoreLabel - // - this.FinalScoreLabel.AutoSize = true; - this.FinalScoreLabel.Location = new System.Drawing.Point(5, 9); - this.FinalScoreLabel.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); - this.FinalScoreLabel.Name = "FinalScoreLabel"; - this.FinalScoreLabel.Size = new System.Drawing.Size(103, 23); - this.FinalScoreLabel.TabIndex = 0; - this.FinalScoreLabel.Text = "Final Score:"; - this.CalculatinTip.SetToolTip(this.FinalScoreLabel, "(The server with the highest score would be choosen)"); - // - // calculationContainer - // - this.calculationContainer.AutoScroll = true; - this.calculationContainer.Dock = System.Windows.Forms.DockStyle.Fill; - 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(593, 265); - 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(733, 145); - this.serverSelector.Name = "serverSelector"; - this.serverSelector.Size = new System.Drawing.Size(233, 31); - this.serverSelector.TabIndex = 6; - this.serverSelector.SelectionChangeCommitted += new System.EventHandler(this.serverSelector_SelectionChangeCommitted); - // - // 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(865, 364); - this.CancelButton.Name = "CancelButton"; - this.CancelButton.Size = new System.Drawing.Size(101, 41); - 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(758, 364); - this.OKButton.Name = "OKButton"; - this.OKButton.Size = new System.Drawing.Size(101, 41); - this.OKButton.TabIndex = 4; - this.OKButton.Text = "OK"; - this.OKButton.UseVisualStyleBackColor = true; - this.OKButton.Click += new System.EventHandler(this.OKButton_Click); - // - // bindingConfiguration - // - this.bindingConfiguration.DataSource = typeof(Shadowsocks.Model.StatisticsStrategyConfiguration); - // - // StatisticsStrategyConfigurationForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 23F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.AutoSize = true; - this.ClientSize = new System.Drawing.Size(982, 753); - this.Controls.Add(this.splitContainer1); - this.Font = new System.Drawing.Font("微软雅黑", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.Margin = new System.Windows.Forms.Padding(5, 10, 5, 10); - this.MinimumSize = new System.Drawing.Size(1000, 800); - this.Name = "StatisticsStrategyConfigurationForm"; - this.Text = "StatisticsStrategyConfigurationForm"; - this.Text = "Statistics configuration"; - ((System.ComponentModel.ISupportInitialize)(this.StatisticsChart)).EndInit(); - this.chartModeSelector.ResumeLayout(false); - this.chartModeSelector.PerformLayout(); - this.splitContainer1.Panel1.ResumeLayout(false); - this.splitContainer1.Panel2.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); - this.splitContainer1.ResumeLayout(false); - this.splitContainer2.Panel1.ResumeLayout(false); - this.splitContainer2.Panel1.PerformLayout(); - this.splitContainer2.Panel2.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit(); - this.splitContainer2.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.dataCollectionMinutesNum)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.choiceKeptMinutesNum)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.repeatTimesNum)).EndInit(); - this.splitContainer3.Panel1.ResumeLayout(false); - this.splitContainer3.Panel1.PerformLayout(); - this.splitContainer3.Panel2.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer3)).EndInit(); - this.splitContainer3.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.bindingConfiguration)).EndInit(); - this.ResumeLayout(false); - - } - - #endregion - private System.Windows.Forms.DataVisualization.Charting.Chart StatisticsChart; - private System.Windows.Forms.CheckBox PingCheckBox; - private System.Windows.Forms.Label KeepChoiceForLabel; - private System.Windows.Forms.Label MinutesLabel2; - private System.Windows.Forms.GroupBox chartModeSelector; - private System.Windows.Forms.RadioButton allMode; - private System.Windows.Forms.RadioButton dayMode; - private System.Windows.Forms.SplitContainer splitContainer1; - private System.Windows.Forms.Label FinalScoreLabel; - private System.Windows.Forms.SplitContainer splitContainer2; - private System.Windows.Forms.FlowLayoutPanel calculationContainer; - private System.Windows.Forms.SplitContainer splitContainer3; - private System.Windows.Forms.NumericUpDown repeatTimesNum; - private System.Windows.Forms.Label PackagePerPingLabel; - private System.Windows.Forms.CheckBox byHourOfDayCheckBox; - private System.Windows.Forms.NumericUpDown choiceKeptMinutesNum; - private System.Windows.Forms.CheckBox StatisticsEnabledCheckBox; - private System.Windows.Forms.Label CollectDataPerLabel; - private System.Windows.Forms.Label MinutesLabel1; - private System.Windows.Forms.NumericUpDown dataCollectionMinutesNum; - private System.Windows.Forms.BindingSource bindingConfiguration; - private new System.Windows.Forms.Button CancelButton; - private System.Windows.Forms.Button OKButton; - private System.Windows.Forms.ComboBox serverSelector; - private System.Windows.Forms.ToolTip CalculatinTip; - } -} \ No newline at end of file diff --git a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.cs b/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.cs deleted file mode 100644 index dac87c3b..00000000 --- a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.cs +++ /dev/null @@ -1,170 +0,0 @@ -using System; -using System.Drawing; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Windows.Forms; -using System.Windows.Forms.DataVisualization.Charting; -using Shadowsocks.Controller; -using Shadowsocks.Model; -using Shadowsocks.Properties; - -namespace Shadowsocks.View -{ - public partial class StatisticsStrategyConfigurationForm : Form - { - private readonly ShadowsocksController _controller; - private StatisticsStrategyConfiguration _configuration; - private readonly DataTable _dataTable = new DataTable(); - private List _servers; - private readonly Series _speedSeries; - private readonly Series _packageLossSeries; - private readonly Series _pingSeries; - - public StatisticsStrategyConfigurationForm(ShadowsocksController controller) - { - if (controller == null) return; - InitializeComponent(); - Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); - _speedSeries = StatisticsChart.Series["Speed"]; - _packageLossSeries = StatisticsChart.Series["Package Loss"]; - _pingSeries = StatisticsChart.Series["Ping"]; - _controller = controller; - _controller.ConfigChanged += (sender, args) => LoadConfiguration(); - UpdateTexts(); - LoadConfiguration(); - Load += (sender, args) => InitData(); - } - - private void UpdateTexts() - { - I18N.TranslateForm(this); - - foreach (var item in StatisticsChart.Series) - { - item.Name = I18N.GetString(item.Name); - } - - } - private void LoadConfiguration() - { - var configs = _controller.GetCurrentConfiguration().configs; - _servers = configs.Select(server => server.Identifier()).ToList(); - _configuration = _controller.StatisticsConfiguration - ?? new StatisticsStrategyConfiguration(); - if (_configuration.Calculations == null) - { - _configuration = new StatisticsStrategyConfiguration(); - } - } - - private void InitData() - { - bindingConfiguration.Add(_configuration); - foreach (var kv in _configuration.Calculations) - { - var calculation = new CalculationControl(I18N.GetString(kv.Key), kv.Value); - calculationContainer.Controls.Add(calculation); - } - - serverSelector.DataSource = _servers; - - _dataTable.Columns.Add("Timestamp", typeof(DateTime)); - _dataTable.Columns.Add("Speed", typeof(int)); - _speedSeries.XValueMember = "Timestamp"; - _speedSeries.YValueMembers = "Speed"; - - // might be empty - _dataTable.Columns.Add("Package Loss", typeof(int)); - _dataTable.Columns.Add("Ping", typeof(int)); - _packageLossSeries.XValueMember = "Timestamp"; - _packageLossSeries.YValueMembers = "Package Loss"; - _pingSeries.XValueMember = "Timestamp"; - _pingSeries.YValueMembers = "Ping"; - - StatisticsChart.DataSource = _dataTable; - LoadChartData(); - StatisticsChart.DataBind(); - } - - private void CancelButton_Click(object sender, EventArgs e) - { - Close(); - } - - private void OKButton_Click(object sender, EventArgs e) - { - foreach (CalculationControl calculation in calculationContainer.Controls) - { - _configuration.Calculations[calculation.Value] = calculation.Factor; - } - _controller?.SaveStrategyConfigurations(_configuration); - _controller?.UpdateStatisticsConfiguration(StatisticsEnabledCheckBox.Checked); - Close(); - } - - private void LoadChartData() - { - var serverName = _servers[serverSelector.SelectedIndex]; - _dataTable.Rows.Clear(); - - //return directly when no data is usable - if (_controller.availabilityStatistics?.FilteredStatistics == null) return; - List statistics; - if (!_controller.availabilityStatistics.FilteredStatistics.TryGetValue(serverName, out statistics)) return; - IEnumerable> dataGroups; - if (allMode.Checked) - { - _pingSeries.XValueType = ChartValueType.DateTime; - _packageLossSeries.XValueType = ChartValueType.DateTime; - _speedSeries.XValueType = ChartValueType.DateTime; - dataGroups = statistics.GroupBy(data => data.Timestamp.DayOfYear); - StatisticsChart.ChartAreas["DataArea"].AxisX.LabelStyle.Format = "g"; - StatisticsChart.ChartAreas["DataArea"].AxisX2.LabelStyle.Format = "g"; - } - else - { - _pingSeries.XValueType = ChartValueType.Time; - _packageLossSeries.XValueType = ChartValueType.Time; - _speedSeries.XValueType = ChartValueType.Time; - dataGroups = statistics.GroupBy(data => data.Timestamp.Hour); - StatisticsChart.ChartAreas["DataArea"].AxisX.LabelStyle.Format = "HH:00"; - StatisticsChart.ChartAreas["DataArea"].AxisX2.LabelStyle.Format = "HH:00"; - } - var finalData = from dataGroup in dataGroups - orderby dataGroup.Key - select new - { - dataGroup.First().Timestamp, - Speed = dataGroup.Max(data => data.MaxInboundSpeed) ?? 0, - Ping = (int)(dataGroup.Average(data => data.AverageResponse) ?? 0), - PackageLossPercentage = (int)(dataGroup.Average(data => data.PackageLoss) ?? 0) * 100 - }; - foreach (var data in finalData.Where(data => data.Speed != 0 || data.PackageLossPercentage != 0 || data.Ping != 0)) - { - _dataTable.Rows.Add(data.Timestamp, data.Speed, data.PackageLossPercentage, data.Ping); - } - StatisticsChart.DataBind(); - } - - private void serverSelector_SelectionChangeCommitted(object sender, EventArgs e) - { - LoadChartData(); - } - - private void dayMode_CheckedChanged(object sender, EventArgs e) - { - LoadChartData(); - } - - private void allMode_CheckedChanged(object sender, EventArgs e) - { - LoadChartData(); - } - - private void PingCheckBox_CheckedChanged(object sender, EventArgs e) - { - repeatTimesNum.ReadOnly = !PingCheckBox.Checked; - } - } -} diff --git a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.resx b/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.resx deleted file mode 100644 index 8360b4c2..00000000 --- a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.resx +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 4, 5 - - - 238, 6 - - - 191 - - \ No newline at end of file diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 72db2dd0..d3790903 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -268,9 +268,7 @@ - - @@ -282,8 +280,6 @@ - - @@ -329,12 +325,6 @@ - - UserControl - - - CalculationControl.cs - Form @@ -348,12 +338,6 @@ ServerSharingView.xaml - - Form - - - StatisticsStrategyConfigurationForm.cs - @@ -373,15 +357,9 @@ Designer Resources.Designer.cs - - CalculationControl.cs - LogForm.cs - - StatisticsStrategyConfigurationForm.cs - Designer @@ -397,7 +375,6 @@ - SettingsSingleFileGenerator Settings.Designer.cs