From 50f93d62c1864528ff35579685f66ea95a4266c4 Mon Sep 17 00:00:00 2001 From: Student Main Date: Thu, 3 Sep 2020 13:39:29 +0800 Subject: [PATCH 01/35] sip008 resolver, preparation for sip008 support --- .../Service/OnlineConfigResolver.cs | 91 +++ .../Controller/ShadowsocksController.cs | 556 +++++++++--------- shadowsocks-csharp/Model/Configuration.cs | 16 + shadowsocks-csharp/Model/Server.cs | 9 +- shadowsocks-csharp/shadowsocks-csharp.csproj | 1 + 5 files changed, 408 insertions(+), 265 deletions(-) create mode 100644 shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs diff --git a/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs b/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs new file mode 100644 index 00000000..480dc366 --- /dev/null +++ b/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using NLog; +using Shadowsocks.Model; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Shadowsocks.Controller.Service +{ + public class OnlineConfigResolver + { + private static Logger logger = LogManager.GetCurrentClassLogger(); + + public static async Task> GetOnline(string url, IWebProxy proxy = null) + { + var httpClientHandler = new HttpClientHandler(); + var httpClient = new HttpClient(httpClientHandler); + + if (proxy != null) + { + httpClientHandler.Proxy = proxy; + } + + try + { + string str = await httpClient.GetStringAsync(url); + return Get(str); + } + catch (Exception e) + { + logger.LogUsefulException(e); + return new List(); + } + } + + public static List Get(string json) + { + try + { + var t = JToken.Parse(json); + return SearchJToken(t).ToList(); + } + catch (Exception e) + { + logger.LogUsefulException(e); + return new List(); + } + } + + private static IEnumerable SearchJArray(JArray a) + { + if (a == null) return Array.Empty(); + return a.SelectMany(SearchJToken).ToList(); + } + + private static IEnumerable SearchJObject(JObject o) + { + var l = new List(); + if (o == null) return l; + try + { + return new List { o.ToObject() }; + } + catch { }; + foreach (var kv in o) + { + JToken v = kv.Value; + l.AddRange(SearchJToken(v)); + } + return l; + } + + private static IEnumerable SearchJToken(JToken t) + { + switch (t.Type) + { + default: + return Array.Empty(); + case JTokenType.Object: + return SearchJObject(t as JObject); + case JTokenType.Array: + return SearchJArray(t as JArray); + } + } + } +} diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index ffa78246..ba7230d3 100644 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -25,7 +25,7 @@ namespace Shadowsocks.Controller // handle user actions // manipulates UI // interacts with low level logic - + #region Members definition private Thread _ramThread; private Thread _trafficThread; @@ -87,6 +87,7 @@ namespace Shadowsocks.Controller // Invoked when controller.Start(); public event EventHandler ProgramUpdated; + #endregion public ShadowsocksController() { @@ -103,6 +104,8 @@ namespace Shadowsocks.Controller }; } + #region Basic + public void Start(bool regHotkeys = true) { if (_config.updated && regHotkeys) @@ -122,6 +125,115 @@ namespace Shadowsocks.Controller } } + public void Stop() + { + if (stopped) + { + return; + } + stopped = true; + if (_listener != null) + { + _listener.Stop(); + } + StopPlugins(); + if (privoxyRunner != null) + { + privoxyRunner.Stop(); + } + if (_config.enabled) + { + SystemProxy.Update(_config, true, null); + } + Encryption.RNG.Close(); + } + + protected void Reload() + { + Encryption.RNG.Reload(); + // some logic in configuration updated the config when saving, we need to read it again + _config = Configuration.Load(); + + NLogConfig.LoadConfiguration(); + + StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); + + privoxyRunner = privoxyRunner ?? new PrivoxyRunner(); + + _pacDaemon = _pacDaemon ?? new PACDaemon(_config); + _pacDaemon.PACFileChanged += PacDaemon_PACFileChanged; + _pacDaemon.UserRuleFileChanged += PacDaemon_UserRuleFileChanged; + _pacServer = _pacServer ?? new PACServer(_pacDaemon); + _pacServer.UpdatePACURL(_config); // So PACServer works when system proxy disabled. + + GeositeUpdater.ResetEvent(); + GeositeUpdater.UpdateCompleted += PacServer_PACUpdateCompleted; + GeositeUpdater.Error += PacServer_PACUpdateError; + + availabilityStatistics.UpdateConfiguration(this); + _listener?.Stop(); + StopPlugins(); + + // don't put PrivoxyRunner.Start() before pacServer.Stop() + // or bind will fail when switching bind address from 0.0.0.0 to 127.0.0.1 + // though UseShellExecute is set to true now + // http://stackoverflow.com/questions/10235093/socket-doesnt-close-after-application-exits-if-a-launched-process-is-open + privoxyRunner.Stop(); + try + { + var strategy = GetCurrentStrategy(); + strategy?.ReloadServers(); + + StartPlugin(); + 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); + + UDPRelay udpRelay = new UDPRelay(this); + List services = new List + { + tcpRelay, + udpRelay, + _pacServer, + new PortForwarder(privoxyRunner.RunningPort) + }; + _listener = new Listener(services); + _listener.Start(_config); + } + catch (Exception e) + { + // translate Microsoft language into human language + // i.e. An attempt was made to access a socket in a way forbidden by its access permissions => Port already in use + if (e is SocketException se) + { + if (se.SocketErrorCode == SocketError.AddressAlreadyInUse) + { + e = new Exception(I18N.GetString("Port {0} already in use", _config.localPort), e); + } + else if (se.SocketErrorCode == SocketError.AccessDenied) + { + e = new Exception(I18N.GetString("Port {0} is reserved by system", _config.localPort), e); + } + } + logger.LogUsefulException(e); + ReportError(e); + } + + ConfigChanged?.Invoke(this, new EventArgs()); + UpdateSystemProxy(); + Utils.ReleaseMemory(true); + } + + protected void SaveConfig(Configuration newConfig) + { + Configuration.Save(newConfig); + Reload(); + } + protected void ReportError(Exception e) { Errored?.Invoke(this, new ErrorEventArgs(e)); @@ -144,23 +256,6 @@ namespace Shadowsocks.Controller return _config; } - public IList GetStrategies() - { - return _strategyManager.GetStrategies(); - } - - public IStrategy GetCurrentStrategy() - { - foreach (var strategy in _strategyManager.GetStrategies()) - { - if (strategy.ID == _config.strategy) - { - return strategy; - } - } - return null; - } - public Server GetAServer(IStrategyCallerType type, IPEndPoint localIPEndPoint, EndPoint destEndPoint) { IStrategy strategy = GetCurrentStrategy(); @@ -175,34 +270,6 @@ namespace Shadowsocks.Controller return GetCurrentServer(); } - public EndPoint GetPluginLocalEndPointIfConfigured(Server server) - { - var plugin = _pluginsByServer.GetOrAdd( - server, - x => Sip003Plugin.CreateIfConfigured(x, _config.showPluginOutput)); - - if (plugin == null) - { - return null; - } - - try - { - if (plugin.StartIfNeeded()) - { - logger.Info( - $"Started SIP003 plugin for {server.Identifier()} on {plugin.LocalEndPoint} - PID: {plugin.ProcessId}"); - } - } - catch (Exception ex) - { - logger.Error("Failed to start SIP003 plugin: " + ex.Message); - throw; - } - - return plugin.LocalEndPoint; - } - public void SaveServers(List servers, int localPort, bool portableMode) { _config.configs = servers; @@ -211,56 +278,24 @@ namespace Shadowsocks.Controller Configuration.Save(_config); } - public void SaveStrategyConfigurations(StatisticsStrategyConfiguration configuration) + public void SelectServerIndex(int index) { - StatisticsConfiguration = configuration; - StatisticsStrategyConfiguration.Save(configuration); + _config.index = index; + _config.strategy = null; + SaveConfig(_config); } - public bool AskAddServerBySSURL(string ssURL) + public void ToggleShareOverLAN(bool enabled) { - var dr = MessageBox.Show(I18N.GetString("Import from URL: {0} ?", ssURL), I18N.GetString("Shadowsocks"), MessageBoxButtons.YesNo); - if (dr == DialogResult.Yes) - { - if (AddServerBySSURL(ssURL)) - { - MessageBox.Show(I18N.GetString("Successfully imported from {0}", ssURL)); - return true; - } - else - { - MessageBox.Show(I18N.GetString("Failed to import. Please check if the link is valid.")); - } - } - return false; - } - + _config.shareOverLan = enabled; + SaveConfig(_config); - public bool AddServerBySSURL(string ssURL) - { - try - { - if (ssURL.IsNullOrEmpty() || ssURL.IsWhiteSpace()) - return false; + ShareOverLANStatusChanged?.Invoke(this, new EventArgs()); + } - var servers = Server.GetServers(ssURL); - if (servers == null || servers.Count == 0) - return false; + #endregion - foreach (var server in servers) - { - _config.configs.Add(server); - } - _config.index = _config.configs.Count - 1; - SaveConfig(_config); - return true; - } - catch (Exception e) - { - logger.LogUsefulException(e); - return false; - } - } + #region OS Proxy public void ToggleEnable(bool enabled) { @@ -278,81 +313,62 @@ namespace Shadowsocks.Controller EnableGlobalChanged?.Invoke(this, new EventArgs()); } - public void ToggleShareOverLAN(bool enabled) - { - _config.shareOverLan = enabled; - SaveConfig(_config); - - ShareOverLANStatusChanged?.Invoke(this, new EventArgs()); - } - public void SaveProxy(ProxyConfig proxyConfig) { _config.proxy = proxyConfig; SaveConfig(_config); } - public void ToggleVerboseLogging(bool enabled) + private void UpdateSystemProxy() { - _config.isVerboseLogging = enabled; - SaveConfig(_config); - NLogConfig.LoadConfiguration(); // reload nlog - - VerboseLoggingStatusChanged?.Invoke(this, new EventArgs()); + SystemProxy.Update(_config, false, _pacServer); } - public void ToggleShowPluginOutput(bool enabled) + #endregion + + #region PAC + + private void PacDaemon_PACFileChanged(object sender, EventArgs e) { - _config.showPluginOutput = enabled; - SaveConfig(_config); + UpdateSystemProxy(); + } - ShowPluginOutputChanged?.Invoke(this, new EventArgs()); + private void PacServer_PACUpdateCompleted(object sender, GeositeResultEventArgs e) + { + UpdatePACFromGeositeCompleted?.Invoke(this, e); } - public void SelectServerIndex(int index) + private void PacServer_PACUpdateError(object sender, ErrorEventArgs e) { - _config.index = index; - _config.strategy = null; - SaveConfig(_config); + UpdatePACFromGeositeError?.Invoke(this, e); } - public void SelectStrategy(string strategyID) + private static readonly IEnumerable IgnoredLineBegins = new[] { '!', '[' }; + private void PacDaemon_UserRuleFileChanged(object sender, EventArgs e) { - _config.index = -1; - _config.strategy = strategyID; - SaveConfig(_config); + GeositeUpdater.MergeAndWritePACFile(_config.geositeGroup, _config.geositeBlacklistMode); + UpdateSystemProxy(); } - public void Stop() + public void CopyPacUrl() { - if (stopped) - { - return; - } - stopped = true; - if (_listener != null) - { - _listener.Stop(); - } - StopPlugins(); - if (privoxyRunner != null) - { - privoxyRunner.Stop(); - } - if (_config.enabled) - { - SystemProxy.Update(_config, true, null); - } - Encryption.RNG.Close(); + Clipboard.SetDataObject(_pacServer.PacUrl); } - private void StopPlugins() + public void SavePACUrl(string pacUrl) { - foreach (var serverAndPlugin in _pluginsByServer) - { - serverAndPlugin.Value?.Dispose(); - } - _pluginsByServer.Clear(); + _config.pacUrl = pacUrl; + SaveConfig(_config); + + ConfigChanged?.Invoke(this, new EventArgs()); + } + + public void UseOnlinePAC(bool useOnlinePac) + { + _config.useOnlinePac = useOnlinePac; + SaveConfig(_config); + + ConfigChanged?.Invoke(this, new EventArgs()); } public void TouchPACFile() @@ -369,43 +385,78 @@ namespace Shadowsocks.Controller UserRuleFileReadyToOpen?.Invoke(this, new PathEventArgs() { Path = userRuleFilename }); } - public string GetServerURLForCurrentServer() + public void ToggleSecureLocalPac(bool enabled) { - return GetCurrentServer().GetURL(_config.generateLegacyUrl); + _config.secureLocalPac = enabled; + SaveConfig(_config); + + ConfigChanged?.Invoke(this, new EventArgs()); } - public void UpdateStatisticsConfiguration(bool enabled) + #endregion + + #region SIP002 + + public bool AskAddServerBySSURL(string ssURL) { - if (availabilityStatistics != null) + var dr = MessageBox.Show(I18N.GetString("Import from URL: {0} ?", ssURL), I18N.GetString("Shadowsocks"), MessageBoxButtons.YesNo); + if (dr == DialogResult.Yes) { - availabilityStatistics.UpdateConfiguration(this); - _config.availabilityStatistics = enabled; - SaveConfig(_config); + if (AddServerBySSURL(ssURL)) + { + MessageBox.Show(I18N.GetString("Successfully imported from {0}", ssURL)); + return true; + } + else + { + MessageBox.Show(I18N.GetString("Failed to import. Please check if the link is valid.")); + } } + return false; } - public void SavePACUrl(string pacUrl) + public bool AddServerBySSURL(string ssURL) { - _config.pacUrl = pacUrl; - SaveConfig(_config); + try + { + if (ssURL.IsNullOrEmpty() || ssURL.IsWhiteSpace()) + return false; - ConfigChanged?.Invoke(this, new EventArgs()); + var servers = Server.GetServers(ssURL); + if (servers == null || servers.Count == 0) + return false; + + foreach (var server in servers) + { + _config.configs.Add(server); + } + _config.index = _config.configs.Count - 1; + SaveConfig(_config); + return true; + } + catch (Exception e) + { + logger.LogUsefulException(e); + return false; + } } - public void UseOnlinePAC(bool useOnlinePac) + public string GetServerURLForCurrentServer() { - _config.useOnlinePac = useOnlinePac; - SaveConfig(_config); - - ConfigChanged?.Invoke(this, new EventArgs()); + return GetCurrentServer().GetURL(_config.generateLegacyUrl); } - public void ToggleSecureLocalPac(bool enabled) + #endregion + + #region Misc + + public void ToggleVerboseLogging(bool enabled) { - _config.secureLocalPac = enabled; + _config.isVerboseLogging = enabled; SaveConfig(_config); + NLogConfig.LoadConfiguration(); // reload nlog - ConfigChanged?.Invoke(this, new EventArgs()); + VerboseLoggingStatusChanged?.Invoke(this, new EventArgs()); } public void ToggleCheckingUpdate(bool enabled) @@ -439,6 +490,50 @@ namespace Shadowsocks.Controller ConfigChanged?.Invoke(this, new EventArgs()); } + + #endregion + + #region Statistic + + public void SelectStrategy(string strategyID) + { + _config.index = -1; + _config.strategy = strategyID; + SaveConfig(_config); + } + + public void SaveStrategyConfigurations(StatisticsStrategyConfiguration configuration) + { + StatisticsConfiguration = configuration; + StatisticsStrategyConfiguration.Save(configuration); + } + + public IList GetStrategies() + { + return _strategyManager.GetStrategies(); + } + + public IStrategy GetCurrentStrategy() + { + foreach (var strategy in _strategyManager.GetStrategies()) + { + if (strategy.ID == _config.strategy) + { + return strategy; + } + } + 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) { @@ -469,130 +564,63 @@ namespace Shadowsocks.Controller } } - protected void Reload() - { - Encryption.RNG.Reload(); - // some logic in configuration updated the config when saving, we need to read it again - _config = Configuration.Load(); - - NLogConfig.LoadConfiguration(); - - StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); - - privoxyRunner = privoxyRunner ?? new PrivoxyRunner(); - - _pacDaemon = _pacDaemon ?? new PACDaemon(_config); - _pacDaemon.PACFileChanged += PacDaemon_PACFileChanged; - _pacDaemon.UserRuleFileChanged += PacDaemon_UserRuleFileChanged; - _pacServer = _pacServer ?? new PACServer(_pacDaemon); - _pacServer.UpdatePACURL(_config); // So PACServer works when system proxy disabled. - - GeositeUpdater.ResetEvent(); - GeositeUpdater.UpdateCompleted += PacServer_PACUpdateCompleted; - GeositeUpdater.Error += PacServer_PACUpdateError; - - availabilityStatistics.UpdateConfiguration(this); - _listener?.Stop(); - StopPlugins(); - - // don't put PrivoxyRunner.Start() before pacServer.Stop() - // or bind will fail when switching bind address from 0.0.0.0 to 127.0.0.1 - // though UseShellExecute is set to true now - // http://stackoverflow.com/questions/10235093/socket-doesnt-close-after-application-exits-if-a-launched-process-is-open - privoxyRunner.Stop(); - try - { - var strategy = GetCurrentStrategy(); - strategy?.ReloadServers(); - - StartPlugin(); - 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); - - UDPRelay udpRelay = new UDPRelay(this); - List services = new List - { - tcpRelay, - udpRelay, - _pacServer, - new PortForwarder(privoxyRunner.RunningPort) - }; - _listener = new Listener(services); - _listener.Start(_config); - } - catch (Exception e) - { - // translate Microsoft language into human language - // i.e. An attempt was made to access a socket in a way forbidden by its access permissions => Port already in use - if (e is SocketException se) - { - if (se.SocketErrorCode == SocketError.AddressAlreadyInUse) - { - e = new Exception(I18N.GetString("Port {0} already in use", _config.localPort), e); - } - else if (se.SocketErrorCode == SocketError.AccessDenied) - { - e = new Exception(I18N.GetString("Port {0} is reserved by system", _config.localPort), e); - } - } - logger.LogUsefulException(e); - ReportError(e); - } - - ConfigChanged?.Invoke(this, new EventArgs()); - UpdateSystemProxy(); - Utils.ReleaseMemory(true); - } + #endregion + #region SIP003 + private void StartPlugin() { var server = _config.GetCurrentServer(); GetPluginLocalEndPointIfConfigured(server); } - protected void SaveConfig(Configuration newConfig) + private void StopPlugins() { - Configuration.Save(newConfig); - Reload(); + foreach (var serverAndPlugin in _pluginsByServer) + { + serverAndPlugin.Value?.Dispose(); + } + _pluginsByServer.Clear(); } - private void UpdateSystemProxy() + public EndPoint GetPluginLocalEndPointIfConfigured(Server server) { - SystemProxy.Update(_config, false, _pacServer); - } + var plugin = _pluginsByServer.GetOrAdd( + server, + x => Sip003Plugin.CreateIfConfigured(x, _config.showPluginOutput)); - private void PacDaemon_PACFileChanged(object sender, EventArgs e) - { - UpdateSystemProxy(); - } + if (plugin == null) + { + return null; + } - private void PacServer_PACUpdateCompleted(object sender, GeositeResultEventArgs e) - { - UpdatePACFromGeositeCompleted?.Invoke(this, e); - } + try + { + if (plugin.StartIfNeeded()) + { + logger.Info( + $"Started SIP003 plugin for {server.Identifier()} on {plugin.LocalEndPoint} - PID: {plugin.ProcessId}"); + } + } + catch (Exception ex) + { + logger.Error("Failed to start SIP003 plugin: " + ex.Message); + throw; + } - private void PacServer_PACUpdateError(object sender, ErrorEventArgs e) - { - UpdatePACFromGeositeError?.Invoke(this, e); + return plugin.LocalEndPoint; } - private static readonly IEnumerable IgnoredLineBegins = new[] { '!', '[' }; - private void PacDaemon_UserRuleFileChanged(object sender, EventArgs e) + public void ToggleShowPluginOutput(bool enabled) { - GeositeUpdater.MergeAndWritePACFile(_config.geositeGroup, _config.geositeBlacklistMode); - UpdateSystemProxy(); - } + _config.showPluginOutput = enabled; + SaveConfig(_config); - public void CopyPacUrl() - { - Clipboard.SetDataObject(_pacServer.PacUrl); + ShowPluginOutputChanged?.Invoke(this, new EventArgs()); } + #endregion + #region Memory Management private void StartReleasingMemory() diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index f712653e..93c33365 100644 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Net; using Newtonsoft.Json; using NLog; using Shadowsocks.Controller; @@ -17,6 +18,9 @@ namespace Shadowsocks.Model public List configs; + public List onlineConfigSource; + + // when strategy is set, index is ignored public string strategy; public int index; @@ -77,6 +81,15 @@ namespace Shadowsocks.Model return GetDefaultServer(); } + public WebProxy WebProxy => enabled + ? new WebProxy( + isIPv6Enabled + ? $"[{IPAddress.IPv6Loopback}]" + : IPAddress.Loopback.ToString(), + localPort) + : null; + + public static void CheckServer(Server server) { CheckServer(server.server); @@ -113,6 +126,9 @@ namespace Shadowsocks.Model if (config.configs == null) config.configs = new List(); + if (config.onlineConfigSource == null) + config.onlineConfigSource = new List(); + if (config.configs.Count == 0) config.configs.Add(GetDefaultServer()); if (config.localPort == 0) diff --git a/shadowsocks-csharp/Model/Server.cs b/shadowsocks-csharp/Model/Server.cs index e84f27b3..daa26395 100755 --- a/shadowsocks-csharp/Model/Server.cs +++ b/shadowsocks-csharp/Model/Server.cs @@ -29,6 +29,9 @@ namespace Shadowsocks.Model public int server_port; public string password; public string method; + + + // optional fields [DefaultValue("")] @@ -43,7 +46,11 @@ namespace Shadowsocks.Model [DefaultValue("")] [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] public string remarks; - + + [DefaultValue("")] + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] + public string group; + public int timeout; public override int GetHashCode() diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index a5229a78..c71ab472 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -169,6 +169,7 @@ + From ca963c638d6343b11bd6020d48fe1f4a8d7bc96b Mon Sep 17 00:00:00 2001 From: Student Main Date: Thu, 3 Sep 2020 16:18:37 +0800 Subject: [PATCH 02/35] sip008 controller support --- .../Controller/ShadowsocksController.cs | 39 +++++++++++++++++-- shadowsocks-csharp/Model/Configuration.cs | 11 ++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index ba7230d3..d407957c 100644 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -7,6 +7,7 @@ using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; +using System.Threading.Tasks; using System.Web; using System.Windows.Forms; using NLog; @@ -449,7 +450,7 @@ namespace Shadowsocks.Controller #endregion #region Misc - + public void ToggleVerboseLogging(bool enabled) { _config.isVerboseLogging = enabled; @@ -490,7 +491,7 @@ namespace Shadowsocks.Controller ConfigChanged?.Invoke(this, new EventArgs()); } - + #endregion #region Statistic @@ -567,7 +568,7 @@ namespace Shadowsocks.Controller #endregion #region SIP003 - + private void StartPlugin() { var server = _config.GetCurrentServer(); @@ -685,5 +686,37 @@ namespace Shadowsocks.Controller #endregion + #region SIP008 + + public async Task UpdateOnlineConfig(string url) + { + var selected = GetCurrentServer(); + var onlineServer = await OnlineConfigResolver.GetOnline(url, _config.WebProxy); + _config.configs = Configuration.SortByOnlineConfig( + _config.configs + .Where(c => c.group != url) + .Concat(onlineServer) + ); + _config.index = _config.configs.IndexOf(selected); + Configuration.Save(_config); + } + + public async Task UpdateAllOnlineConfig() + { + var selected = GetCurrentServer(); + var r = await Task.WhenAll( + _config.onlineConfigSource.Select(url => OnlineConfigResolver.GetOnline(url, _config.WebProxy)) + ); + var results = r.SelectMany(s => s); + _config.configs = Configuration.SortByOnlineConfig( + _config.configs + .Where(c => string.IsNullOrEmpty(c.group)) + .Concat(r.SelectMany(s => s)) + ); + _config.index = _config.configs.IndexOf(selected); + Configuration.Save(_config); + } + + #endregion } } diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index 93c33365..f4d9e35c 100644 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Net; using Newtonsoft.Json; using NLog; @@ -197,6 +198,7 @@ namespace Shadowsocks.Model public static void Save(Configuration config) { + config.configs = SortByOnlineConfig(config.configs); config.version = UpdateChecker.Version; if (config.index >= config.configs.Count) config.index = config.configs.Count - 1; @@ -230,6 +232,15 @@ namespace Shadowsocks.Model } } + public static List SortByOnlineConfig(IEnumerable servers) + { + var groups = servers.GroupBy(s => s.group); + List ret = new List(); + ret.AddRange(groups.Where(g => string.IsNullOrEmpty(g.Key)).SelectMany(g => g)); + ret.AddRange(groups.Where(g => !string.IsNullOrEmpty(g.Key)).SelectMany(g => g)); + return ret; + } + public static Server AddDefaultServerOrServer(Configuration config, Server server = null, int? index = null) { if (config?.configs != null) From 1287b574103df8267014c43f63e80feb4dedcab3 Mon Sep 17 00:00:00 2001 From: Student Main Date: Thu, 3 Sep 2020 17:52:28 +0800 Subject: [PATCH 03/35] add onlineConfigForm --- .../Controller/ShadowsocksController.cs | 6 + shadowsocks-csharp/View/MenuViewController.cs | 531 ++++++++++-------- .../View/OnlineConfigForm.Designer.cs | 207 +++++++ shadowsocks-csharp/View/OnlineConfigForm.cs | 76 +++ shadowsocks-csharp/View/OnlineConfigForm.resx | 120 ++++ shadowsocks-csharp/shadowsocks-csharp.csproj | 9 + 6 files changed, 713 insertions(+), 236 deletions(-) create mode 100644 shadowsocks-csharp/View/OnlineConfigForm.Designer.cs create mode 100644 shadowsocks-csharp/View/OnlineConfigForm.cs create mode 100644 shadowsocks-csharp/View/OnlineConfigForm.resx diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index d407957c..2728b3d0 100644 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -717,6 +717,12 @@ namespace Shadowsocks.Controller Configuration.Save(_config); } + public void SaveOnlineConfigSource(IEnumerable vs) + { + _config.onlineConfigSource = vs.ToList(); + SaveConfig(_config); + } + #endregion } } diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 3ac1748f..f73e2102 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -57,13 +57,13 @@ namespace Shadowsocks.View private MenuItem VerboseLoggingToggleItem; private MenuItem ShowPluginOutputToggleItem; private MenuItem WriteI18NFileItem; + private MenuItem onlineConfigItem; private ConfigForm configForm; private ProxyForm proxyForm; private LogForm logForm; private HotkeySettingsForm hotkeySettingsForm; - - + private OnlineConfigForm onlineConfigForm; // color definition for icon color transformation private readonly Color colorMaskBlue = Color.FromArgb(255, 25, 125, 191); @@ -118,37 +118,6 @@ namespace Shadowsocks.View } } - private void controller_TrafficChanged(object sender, EventArgs e) - { - if (icon == null) - return; - - Icon newIcon; - - bool hasInbound = controller.trafficPerSecondQueue.Last().inboundIncreasement > 0; - bool hasOutbound = controller.trafficPerSecondQueue.Last().outboundIncreasement > 0; - - if (hasInbound && hasOutbound) - newIcon = icon_both; - else if (hasInbound) - newIcon = icon_in; - else if (hasOutbound) - newIcon = icon_out; - else - newIcon = icon; - - if (newIcon != this.previousIcon) - { - this.previousIcon = newIcon; - _notifyIcon.Icon = newIcon; - } - } - - void controller_Errored(object sender, System.IO.ErrorEventArgs e) - { - MessageBox.Show(e.GetException().ToString(), I18N.GetString("Shadowsocks Error: {0}", e.GetException().Message)); - } - #region Tray Icon private void UpdateTrayIconAndNotifyText() @@ -269,8 +238,6 @@ namespace Shadowsocks.View icon_both = Icon.FromHandle(ViewUtils.ResizeBitmap(ViewUtils.AddBitmapOverlay(iconBitmap, Resources.ss32In, Resources.ss32Out), size.Width, size.Height).GetHicon()); } - - #endregion #region MenuItems and MenuGroups @@ -314,6 +281,7 @@ namespace Shadowsocks.View this.editOnlinePACItem = CreateMenuItem("Edit Online PAC URL...", new EventHandler(this.UpdateOnlinePACURLItem_Click)), }), this.proxyItem = CreateMenuItem("Forward Proxy...", new EventHandler(this.proxyItem_Click)), + this.onlineConfigItem = CreateMenuItem("Online Config...", new EventHandler(this.OnlineConfig_Click)), new MenuItem("-"), this.AutoStartupItem = CreateMenuItem("Start on Boot", new EventHandler(this.AutoStartupItem_Click)), this.ProtocolHandlerItem = CreateMenuItem("Associate ss:// Links", new EventHandler(this.ProtocolHandlerItem_Click)), @@ -340,99 +308,41 @@ namespace Shadowsocks.View #endregion - private void controller_ConfigChanged(object sender, EventArgs e) - { - LoadCurrentConfiguration(); - UpdateTrayIconAndNotifyText(); - } - - private void controller_EnableStatusChanged(object sender, EventArgs e) - { - disableItem.Checked = !controller.GetConfigurationCopy().enabled; - } - - void controller_ShareOverLANStatusChanged(object sender, EventArgs e) - { - ShareOverLANItem.Checked = controller.GetConfigurationCopy().shareOverLan; - } - - void controller_VerboseLoggingStatusChanged(object sender, EventArgs e) - { - VerboseLoggingToggleItem.Checked = controller.GetConfigurationCopy().isVerboseLogging; - } - - void controller_ShowPluginOutputChanged(object sender, EventArgs e) - { - ShowPluginOutputToggleItem.Checked = controller.GetConfigurationCopy().showPluginOutput; - } - - void controller_EnableGlobalChanged(object sender, EventArgs e) - { - globalModeItem.Checked = controller.GetConfigurationCopy().global; - PACModeItem.Checked = !globalModeItem.Checked; - } - - void controller_FileReadyToOpen(object sender, ShadowsocksController.PathEventArgs e) + private void controller_TrafficChanged(object sender, EventArgs e) { - string argument = @"/select, " + e.Path; - - Process.Start("explorer.exe", argument); - } + if (icon == null) + return; - void ShowBalloonTip(string title, string content, ToolTipIcon icon, int timeout) - { - _notifyIcon.BalloonTipTitle = title; - _notifyIcon.BalloonTipText = content; - _notifyIcon.BalloonTipIcon = icon; - _notifyIcon.ShowBalloonTip(timeout); - } + Icon newIcon; - void controller_UpdatePACFromGeositeError(object sender, System.IO.ErrorEventArgs e) - { - ShowBalloonTip(I18N.GetString("Failed to update PAC file"), e.GetException().Message, ToolTipIcon.Error, 5000); - logger.LogUsefulException(e.GetException()); - } + bool hasInbound = controller.trafficPerSecondQueue.Last().inboundIncreasement > 0; + bool hasOutbound = controller.trafficPerSecondQueue.Last().outboundIncreasement > 0; - void controller_UpdatePACFromGeositeCompleted(object sender, GeositeResultEventArgs e) - { - string result = e.Success - ? I18N.GetString("PAC updated") - : I18N.GetString("No updates found. Please report to Geosite if you have problems with it."); - ShowBalloonTip(I18N.GetString("Shadowsocks"), result, ToolTipIcon.Info, 1000); - } + if (hasInbound && hasOutbound) + newIcon = icon_both; + else if (hasInbound) + newIcon = icon_in; + else if (hasOutbound) + newIcon = icon_out; + else + newIcon = icon; - void updateChecker_CheckUpdateCompleted(object sender, EventArgs e) - { - if (updateChecker.NewVersionFound) - { - ShowBalloonTip(I18N.GetString("Shadowsocks {0} Update Found", updateChecker.LatestVersionNumber + updateChecker.LatestVersionSuffix), I18N.GetString("Click here to update"), ToolTipIcon.Info, 5000); - } - else if (!_isStartupChecking) + if (newIcon != this.previousIcon) { - ShowBalloonTip(I18N.GetString("Shadowsocks"), I18N.GetString("No update is available"), ToolTipIcon.Info, 5000); + this.previousIcon = newIcon; + _notifyIcon.Icon = newIcon; } - _isStartupChecking = false; } - void notifyIcon1_BalloonTipClicked(object sender, EventArgs e) + void controller_Errored(object sender, System.IO.ErrorEventArgs e) { - if (updateChecker.NewVersionFound) - { - updateChecker.NewVersionFound = false; /* Reset the flag */ - if (File.Exists(updateChecker.LatestVersionLocalName)) - { - string argument = "/select, \"" + updateChecker.LatestVersionLocalName + "\""; - Process.Start("explorer.exe", argument); - } - } + MessageBox.Show(e.GetException().ToString(), I18N.GetString("Shadowsocks Error: {0}", e.GetException().Message)); } - private void _notifyIcon_BalloonTipClosed(object sender, EventArgs e) + private void controller_ConfigChanged(object sender, EventArgs e) { - if (updateChecker.NewVersionFound) - { - updateChecker.NewVersionFound = false; /* Reset the flag */ - } + LoadCurrentConfiguration(); + UpdateTrayIconAndNotifyText(); } private void LoadCurrentConfiguration() @@ -452,48 +362,7 @@ namespace Shadowsocks.View UpdateUpdateMenu(); } - private void UpdateServersMenu() - { - var items = ServersItem.MenuItems; - while (items[0] != SeperatorItem) - { - items.RemoveAt(0); - } - int strategyCount = 0; - foreach (var strategy in controller.GetStrategies()) - { - MenuItem item = new MenuItem(strategy.Name); - item.Tag = strategy.ID; - item.Click += AStrategyItem_Click; - items.Add(strategyCount, item); - strategyCount++; - } - - // user wants a seperator item between strategy and servers menugroup - items.Add(strategyCount++, new MenuItem("-")); - - int serverCount = 0; - Configuration configuration = controller.GetConfigurationCopy(); - foreach (var server in configuration.configs) - { - if (Configuration.ChecksServer(server)) - { - MenuItem item = new MenuItem(server.ToString()); - item.Tag = configuration.configs.FindIndex(s => s == server); - item.Click += AServerItem_Click; - items.Add(strategyCount + serverCount, item); - serverCount++; - } - } - - foreach (MenuItem item in items) - { - if (item.Tag != null && (item.Tag.ToString() == configuration.index.ToString() || item.Tag.ToString() == configuration.strategy)) - { - item.Checked = true; - } - } - } + #region Forms private void ShowConfigForm() { @@ -555,6 +424,22 @@ namespace Shadowsocks.View } } + private void ShowOnlineConfigForm() + { + + if (onlineConfigForm != null) + { + onlineConfigForm.Activate(); + } + else + { + onlineConfigForm = new OnlineConfigForm(controller); + onlineConfigForm.Show(); + onlineConfigForm.Activate(); + onlineConfigForm.FormClosed += onlineConfigForm_FormClosed; + } + } + void logForm_FormClosed(object sender, FormClosedEventArgs e) { logForm.Dispose(); @@ -594,29 +479,44 @@ namespace Shadowsocks.View Utils.ReleaseMemory(true); } - private void Config_Click(object sender, EventArgs e) + void onlineConfigForm_FormClosed(object sender, FormClosedEventArgs e) { - ShowConfigForm(); + onlineConfigForm.Dispose(); + onlineConfigForm = null; + Utils.ReleaseMemory(true); } - private void Quit_Click(object sender, EventArgs e) + #endregion + + #region Misc + + void ShowBalloonTip(string title, string content, ToolTipIcon icon, int timeout) { - controller.Stop(); - _notifyIcon.Visible = false; - Application.Exit(); + _notifyIcon.BalloonTipTitle = title; + _notifyIcon.BalloonTipText = content; + _notifyIcon.BalloonTipIcon = icon; + _notifyIcon.ShowBalloonTip(timeout); } - private void CheckUpdateForFirstRun() + void notifyIcon1_BalloonTipClicked(object sender, EventArgs e) { - Configuration config = controller.GetConfigurationCopy(); - if (config.isDefault) return; - _isStartupChecking = true; - updateChecker.CheckUpdate(config, 3000); + if (updateChecker.NewVersionFound) + { + updateChecker.NewVersionFound = false; /* Reset the flag */ + if (File.Exists(updateChecker.LatestVersionLocalName)) + { + string argument = "/select, \"" + updateChecker.LatestVersionLocalName + "\""; + Process.Start("explorer.exe", argument); + } + } } - private void AboutItem_Click(object sender, EventArgs e) + private void _notifyIcon_BalloonTipClosed(object sender, EventArgs e) { - Process.Start("https://github.com/shadowsocks/shadowsocks-windows"); + if (updateChecker.NewVersionFound) + { + updateChecker.NewVersionFound = false; /* Reset the flag */ + } } private void notifyIcon1_Click(object sender, MouseEventArgs e) @@ -636,6 +536,85 @@ namespace Shadowsocks.View } } + private void CheckUpdateForFirstRun() + { + Configuration config = controller.GetConfigurationCopy(); + if (config.isDefault) return; + _isStartupChecking = true; + updateChecker.CheckUpdate(config, 3000); + } + + public void ShowLogForm_HotKey() + { + ShowLogForm(); + } + + #endregion + + #region Main menu + + void controller_ShareOverLANStatusChanged(object sender, EventArgs e) + { + ShareOverLANItem.Checked = controller.GetConfigurationCopy().shareOverLan; + } + + private void proxyItem_Click(object sender, EventArgs e) + { + ShowProxyForm(); + } + + private void OnlineConfig_Click(object sender, EventArgs e) + { + ShowOnlineConfigForm(); + } + + private void hotKeyItem_Click(object sender, EventArgs e) + { + ShowHotKeySettingsForm(); + } + + private void ShareOverLANItem_Click(object sender, EventArgs e) + { + ShareOverLANItem.Checked = !ShareOverLANItem.Checked; + controller.ToggleShareOverLAN(ShareOverLANItem.Checked); + } + + private void AutoStartupItem_Click(object sender, EventArgs e) + { + AutoStartupItem.Checked = !AutoStartupItem.Checked; + if (!AutoStartup.Set(AutoStartupItem.Checked)) + { + MessageBox.Show(I18N.GetString("Failed to update registry")); + } + LoadCurrentConfiguration(); + } + + private void ProtocolHandlerItem_Click(object sender, EventArgs e) + { + ProtocolHandlerItem.Checked = !ProtocolHandlerItem.Checked; + if (!ProtocolHandler.Set(ProtocolHandlerItem.Checked)) + { + MessageBox.Show(I18N.GetString("Failed to update registry")); + } + LoadCurrentConfiguration(); + } + + private void Quit_Click(object sender, EventArgs e) + { + controller.Stop(); + _notifyIcon.Visible = false; + Application.Exit(); + } + + #endregion + + #region System proxy + + private void controller_EnableStatusChanged(object sender, EventArgs e) + { + disableItem.Checked = !controller.GetConfigurationCopy().enabled; + } + private void EnableItem_Click(object sender, EventArgs e) { controller.ToggleEnable(false); @@ -643,6 +622,12 @@ namespace Shadowsocks.View UpdateSystemProxyItemsEnabledStatus(config); } + void controller_EnableGlobalChanged(object sender, EventArgs e) + { + globalModeItem.Checked = controller.GetConfigurationCopy().global; + PACModeItem.Checked = !globalModeItem.Checked; + } + private void UpdateSystemProxyItemsEnabledStatus(Configuration config) { disableItem.Checked = !config.enabled; @@ -674,25 +659,51 @@ namespace Shadowsocks.View UpdateSystemProxyItemsEnabledStatus(config); } - private void ShareOverLANItem_Click(object sender, EventArgs e) - { - ShareOverLANItem.Checked = !ShareOverLANItem.Checked; - controller.ToggleShareOverLAN(ShareOverLANItem.Checked); - } + #endregion - private void EditPACFileItem_Click(object sender, EventArgs e) - { - controller.TouchPACFile(); - } + #region Server - private async void UpdatePACFromGeositeItem_Click(object sender, EventArgs e) + private void UpdateServersMenu() { - await GeositeUpdater.UpdatePACFromGeosite(); - } + var items = ServersItem.MenuItems; + while (items[0] != SeperatorItem) + { + items.RemoveAt(0); + } + int strategyCount = 0; + foreach (var strategy in controller.GetStrategies()) + { + MenuItem item = new MenuItem(strategy.Name); + item.Tag = strategy.ID; + item.Click += AStrategyItem_Click; + items.Add(strategyCount, item); + strategyCount++; + } - private void EditUserRuleFileForGeositeItem_Click(object sender, EventArgs e) - { - controller.TouchUserRuleFile(); + // user wants a seperator item between strategy and servers menugroup + items.Add(strategyCount++, new MenuItem("-")); + + int serverCount = 0; + Configuration configuration = controller.GetConfigurationCopy(); + foreach (var server in configuration.configs) + { + if (Configuration.ChecksServer(server)) + { + MenuItem item = new MenuItem(server.ToString()); + item.Tag = configuration.configs.FindIndex(s => s == server); + item.Click += AServerItem_Click; + items.Add(strategyCount + serverCount, item); + serverCount++; + } + } + + foreach (MenuItem item in items) + { + if (item.Tag != null && (item.Tag.ToString() == configuration.index.ToString() || item.Tag.ToString() == configuration.strategy)) + { + item.Checked = true; + } + } } private void AServerItem_Click(object sender, EventArgs e) @@ -707,21 +718,19 @@ namespace Shadowsocks.View controller.SelectStrategy((string)item.Tag); } - private void VerboseLoggingToggleItem_Click(object sender, EventArgs e) + private void Config_Click(object sender, EventArgs e) { - VerboseLoggingToggleItem.Checked = !VerboseLoggingToggleItem.Checked; - controller.ToggleVerboseLogging(VerboseLoggingToggleItem.Checked); + ShowConfigForm(); } - private void ShowPluginOutputToggleItem_Click(object sender, EventArgs e) + void splash_FormClosed(object sender, FormClosedEventArgs e) { - ShowPluginOutputToggleItem.Checked = !ShowPluginOutputToggleItem.Checked; - controller.ToggleShowPluginOutput(ShowPluginOutputToggleItem.Checked); + ShowConfigForm(); } - private void WriteI18NFileItem_Click(object sender, EventArgs e) + void openURLFromQRCode(object sender, FormClosedEventArgs e) { - File.WriteAllText(I18N.I18N_FILE, Resources.i18n_csv, Encoding.UTF8); + Process.Start(_urlToOpen); } private void StatisticsConfigItem_Click(object sender, EventArgs e) @@ -830,34 +839,9 @@ namespace Shadowsocks.View } } - void splash_FormClosed(object sender, FormClosedEventArgs e) - { - ShowConfigForm(); - } - - void openURLFromQRCode(object sender, FormClosedEventArgs e) - { - Process.Start(_urlToOpen); - } + #endregion - private void AutoStartupItem_Click(object sender, EventArgs e) - { - AutoStartupItem.Checked = !AutoStartupItem.Checked; - if (!AutoStartup.Set(AutoStartupItem.Checked)) - { - MessageBox.Show(I18N.GetString("Failed to update registry")); - } - LoadCurrentConfiguration(); - } - private void ProtocolHandlerItem_Click(object sender, EventArgs e) - { - ProtocolHandlerItem.Checked = !ProtocolHandlerItem.Checked; - if (!ProtocolHandler.Set(ProtocolHandlerItem.Checked)) - { - MessageBox.Show(I18N.GetString("Failed to update registry")); - } - LoadCurrentConfiguration(); - } + #region PAC private void LocalPACItem_Click(object sender, EventArgs e) { @@ -930,6 +914,94 @@ namespace Shadowsocks.View } } + private void EditPACFileItem_Click(object sender, EventArgs e) + { + controller.TouchPACFile(); + } + + private async void UpdatePACFromGeositeItem_Click(object sender, EventArgs e) + { + await GeositeUpdater.UpdatePACFromGeosite(); + } + + private void EditUserRuleFileForGeositeItem_Click(object sender, EventArgs e) + { + controller.TouchUserRuleFile(); + } + + void controller_FileReadyToOpen(object sender, ShadowsocksController.PathEventArgs e) + { + string argument = @"/select, " + e.Path; + + Process.Start("explorer.exe", argument); + } + + void controller_UpdatePACFromGeositeError(object sender, System.IO.ErrorEventArgs e) + { + ShowBalloonTip(I18N.GetString("Failed to update PAC file"), e.GetException().Message, ToolTipIcon.Error, 5000); + logger.LogUsefulException(e.GetException()); + } + + void controller_UpdatePACFromGeositeCompleted(object sender, GeositeResultEventArgs e) + { + string result = e.Success + ? I18N.GetString("PAC updated") + : I18N.GetString("No updates found. Please report to Geosite if you have problems with it."); + ShowBalloonTip(I18N.GetString("Shadowsocks"), result, ToolTipIcon.Info, 1000); + } + + #endregion + + #region Help + + void controller_VerboseLoggingStatusChanged(object sender, EventArgs e) + { + VerboseLoggingToggleItem.Checked = controller.GetConfigurationCopy().isVerboseLogging; + } + + void controller_ShowPluginOutputChanged(object sender, EventArgs e) + { + ShowPluginOutputToggleItem.Checked = controller.GetConfigurationCopy().showPluginOutput; + } + + private void VerboseLoggingToggleItem_Click(object sender, EventArgs e) + { + VerboseLoggingToggleItem.Checked = !VerboseLoggingToggleItem.Checked; + controller.ToggleVerboseLogging(VerboseLoggingToggleItem.Checked); + } + + private void ShowLogItem_Click(object sender, EventArgs e) + { + ShowLogForm(); + } + + private void ShowPluginOutputToggleItem_Click(object sender, EventArgs e) + { + ShowPluginOutputToggleItem.Checked = !ShowPluginOutputToggleItem.Checked; + controller.ToggleShowPluginOutput(ShowPluginOutputToggleItem.Checked); + } + + private void WriteI18NFileItem_Click(object sender, EventArgs e) + { + File.WriteAllText(I18N.I18N_FILE, Resources.i18n_csv, Encoding.UTF8); + } + + #endregion + + #region Update + + void updateChecker_CheckUpdateCompleted(object sender, EventArgs e) + { + if (updateChecker.NewVersionFound) + { + ShowBalloonTip(I18N.GetString("Shadowsocks {0} Update Found", updateChecker.LatestVersionNumber + updateChecker.LatestVersionSuffix), I18N.GetString("Click here to update"), ToolTipIcon.Info, 5000); + } + else if (!_isStartupChecking) + { + ShowBalloonTip(I18N.GetString("Shadowsocks"), I18N.GetString("No update is available"), ToolTipIcon.Info, 5000); + } + _isStartupChecking = false; + } private void UpdateUpdateMenu() { @@ -957,24 +1029,11 @@ namespace Shadowsocks.View updateChecker.CheckUpdate(controller.GetConfigurationCopy()); } - private void proxyItem_Click(object sender, EventArgs e) - { - ShowProxyForm(); - } - - private void hotKeyItem_Click(object sender, EventArgs e) - { - ShowHotKeySettingsForm(); - } - - private void ShowLogItem_Click(object sender, EventArgs e) + private void AboutItem_Click(object sender, EventArgs e) { - ShowLogForm(); + Process.Start("https://github.com/shadowsocks/shadowsocks-windows"); } - public void ShowLogForm_HotKey() - { - ShowLogForm(); - } + #endregion } } diff --git a/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs b/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs new file mode 100644 index 00000000..f80e5ba6 --- /dev/null +++ b/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs @@ -0,0 +1,207 @@ +namespace Shadowsocks.View +{ + partial class OnlineConfigForm + { + /// + /// 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.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.UrlListBox = new System.Windows.Forms.ListBox(); + this.label1 = new System.Windows.Forms.Label(); + this.UrlTextBox = new System.Windows.Forms.TextBox(); + this.UpdateButton = new System.Windows.Forms.Button(); + this.AddButton = new System.Windows.Forms.Button(); + this.DeleteButton = new System.Windows.Forms.Button(); + this.UpdateAllButton = new System.Windows.Forms.Button(); + this.OkButton = new System.Windows.Forms.Button(); + this.CancelButton = new System.Windows.Forms.Button(); + this.tableLayoutPanel1.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 3; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); + this.tableLayoutPanel1.Controls.Add(this.UrlListBox, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.label1, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.UrlTextBox, 1, 1); + this.tableLayoutPanel1.Controls.Add(this.UpdateButton, 0, 2); + this.tableLayoutPanel1.Controls.Add(this.AddButton, 1, 2); + this.tableLayoutPanel1.Controls.Add(this.DeleteButton, 2, 2); + this.tableLayoutPanel1.Controls.Add(this.OkButton, 1, 3); + this.tableLayoutPanel1.Controls.Add(this.UpdateAllButton, 0, 3); + this.tableLayoutPanel1.Controls.Add(this.CancelButton, 2, 3); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 4; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.Size = new System.Drawing.Size(488, 465); + this.tableLayoutPanel1.TabIndex = 0; + // + // UrlListBox + // + this.tableLayoutPanel1.SetColumnSpan(this.UrlListBox, 3); + this.UrlListBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.UrlListBox.FormattingEnabled = true; + this.UrlListBox.ItemHeight = 15; + this.UrlListBox.Location = new System.Drawing.Point(3, 3); + this.UrlListBox.Name = "UrlListBox"; + this.UrlListBox.Size = new System.Drawing.Size(482, 344); + this.UrlListBox.TabIndex = 0; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Dock = System.Windows.Forms.DockStyle.Fill; + this.label1.Location = new System.Drawing.Point(3, 350); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(156, 31); + this.label1.TabIndex = 1; + this.label1.Text = "Online config URL"; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // UrlTextBox + // + this.tableLayoutPanel1.SetColumnSpan(this.UrlTextBox, 2); + this.UrlTextBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.UrlTextBox.Location = new System.Drawing.Point(165, 353); + this.UrlTextBox.Name = "UrlTextBox"; + this.UrlTextBox.Size = new System.Drawing.Size(320, 25); + this.UrlTextBox.TabIndex = 2; + // + // UpdateButton + // + this.UpdateButton.Dock = System.Windows.Forms.DockStyle.Fill; + this.UpdateButton.Location = new System.Drawing.Point(20, 386); + this.UpdateButton.Margin = new System.Windows.Forms.Padding(20, 5, 20, 5); + this.UpdateButton.MaximumSize = new System.Drawing.Size(0, 32); + this.UpdateButton.MinimumSize = new System.Drawing.Size(0, 32); + this.UpdateButton.Name = "UpdateButton"; + this.UpdateButton.Size = new System.Drawing.Size(122, 32); + this.UpdateButton.TabIndex = 3; + this.UpdateButton.Text = "Update"; + this.UpdateButton.UseVisualStyleBackColor = true; + // + // AddButton + // + this.AddButton.Dock = System.Windows.Forms.DockStyle.Fill; + this.AddButton.Location = new System.Drawing.Point(182, 386); + this.AddButton.Margin = new System.Windows.Forms.Padding(20, 5, 20, 5); + this.AddButton.MaximumSize = new System.Drawing.Size(0, 32); + this.AddButton.MinimumSize = new System.Drawing.Size(0, 32); + this.AddButton.Name = "AddButton"; + this.AddButton.Size = new System.Drawing.Size(122, 32); + this.AddButton.TabIndex = 4; + this.AddButton.Text = "Add"; + this.AddButton.UseVisualStyleBackColor = true; + this.AddButton.Click += new System.EventHandler(this.AddButton_Click); + // + // DeleteButton + // + this.DeleteButton.Dock = System.Windows.Forms.DockStyle.Fill; + this.DeleteButton.Location = new System.Drawing.Point(344, 386); + this.DeleteButton.Margin = new System.Windows.Forms.Padding(20, 5, 20, 5); + this.DeleteButton.MaximumSize = new System.Drawing.Size(0, 32); + this.DeleteButton.MinimumSize = new System.Drawing.Size(0, 32); + this.DeleteButton.Name = "DeleteButton"; + this.DeleteButton.Size = new System.Drawing.Size(124, 32); + this.DeleteButton.TabIndex = 5; + this.DeleteButton.Text = "Delete"; + this.DeleteButton.UseVisualStyleBackColor = true; + // + // UpdateAllButton + // + this.UpdateAllButton.Dock = System.Windows.Forms.DockStyle.Fill; + this.UpdateAllButton.Location = new System.Drawing.Point(20, 428); + this.UpdateAllButton.Margin = new System.Windows.Forms.Padding(20, 5, 20, 5); + this.UpdateAllButton.MaximumSize = new System.Drawing.Size(0, 32); + this.UpdateAllButton.MinimumSize = new System.Drawing.Size(0, 32); + this.UpdateAllButton.Name = "UpdateAllButton"; + this.UpdateAllButton.Size = new System.Drawing.Size(122, 32); + this.UpdateAllButton.TabIndex = 6; + this.UpdateAllButton.Text = "Update all"; + this.UpdateAllButton.UseVisualStyleBackColor = true; + // + // OkButton + // + this.OkButton.Dock = System.Windows.Forms.DockStyle.Fill; + this.OkButton.Location = new System.Drawing.Point(182, 428); + this.OkButton.Margin = new System.Windows.Forms.Padding(20, 5, 20, 5); + this.OkButton.MaximumSize = new System.Drawing.Size(0, 32); + this.OkButton.MinimumSize = new System.Drawing.Size(0, 32); + this.OkButton.Name = "OkButton"; + this.OkButton.Size = new System.Drawing.Size(122, 32); + this.OkButton.TabIndex = 7; + this.OkButton.Text = "OK"; + this.OkButton.UseVisualStyleBackColor = true; + // + // CancelButton + // + this.CancelButton.Dock = System.Windows.Forms.DockStyle.Fill; + this.CancelButton.Location = new System.Drawing.Point(344, 428); + this.CancelButton.Margin = new System.Windows.Forms.Padding(20, 5, 20, 5); + this.CancelButton.MaximumSize = new System.Drawing.Size(0, 32); + this.CancelButton.MinimumSize = new System.Drawing.Size(0, 32); + this.CancelButton.Name = "CancelButton"; + this.CancelButton.Size = new System.Drawing.Size(124, 32); + this.CancelButton.TabIndex = 8; + this.CancelButton.Text = "Cancel"; + this.CancelButton.UseVisualStyleBackColor = true; + // + // OnlineConfigForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(488, 465); + this.Controls.Add(this.tableLayoutPanel1); + this.Name = "OnlineConfigForm"; + this.Text = "OnlineConfigForm"; + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.ListBox UrlListBox; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox UrlTextBox; + private System.Windows.Forms.Button UpdateButton; + private System.Windows.Forms.Button AddButton; + private System.Windows.Forms.Button DeleteButton; + private System.Windows.Forms.Button OkButton; + private System.Windows.Forms.Button UpdateAllButton; + private System.Windows.Forms.Button CancelButton; + } +} \ No newline at end of file diff --git a/shadowsocks-csharp/View/OnlineConfigForm.cs b/shadowsocks-csharp/View/OnlineConfigForm.cs new file mode 100644 index 00000000..782ef65e --- /dev/null +++ b/shadowsocks-csharp/View/OnlineConfigForm.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using Shadowsocks.Controller; +using Shadowsocks.Model; + +namespace Shadowsocks.View +{ + public partial class OnlineConfigForm : Form + { + private ShadowsocksController controller; + private Configuration config; + + private const string DefaultPrefix = "http://www.baidu.com/"; + + public OnlineConfigForm(ShadowsocksController controller) + { + this.controller = controller; + InitializeComponent(); + LoadConfig(); + } + + private void LoadConfig() + { + config = controller.GetConfigurationCopy(); + var idx = UrlListBox.SelectedIndex; + UrlListBox.Items.Clear(); + + foreach (var item in config.onlineConfigSource) + { + UrlListBox.Items.Add(item); + } + + if (idx >= UrlListBox.Items.Count) idx = 0; + UrlListBox.SelectedIndex = idx; + } + + private bool ValidateUrl() + { + try + { + var scheme = new Uri(UrlTextBox.Text).Scheme; + if (scheme != "http" && scheme != "https") return false; + } + catch + { + return false; + } + return true; + } + + private bool Commit() + { + if (!ValidateUrl()) return false; + + UrlListBox.Items[UrlListBox.SelectedIndex] = UrlTextBox.Text; + controller.SaveOnlineConfigSource(UrlListBox.Items.OfType().Where(s=>!string.IsNullOrWhiteSpace(s))); + LoadConfig(); + return true; + } + + private void AddButton_Click(object sender, EventArgs e) + { + Commit(); + UrlListBox.Items.Add(""); + UrlTextBox.Text = DefaultPrefix; + UrlListBox.SelectedIndex = UrlListBox.Items.Count - 1; + } + } +} diff --git a/shadowsocks-csharp/View/OnlineConfigForm.resx b/shadowsocks-csharp/View/OnlineConfigForm.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/shadowsocks-csharp/View/OnlineConfigForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index c71ab472..a8d99a26 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -273,6 +273,12 @@ LogForm.cs + + Form + + + OnlineConfigForm.cs + Form @@ -312,6 +318,9 @@ LogForm.cs + + OnlineConfigForm.cs + ProxyForm.cs From 787f33acae13dd867037c0d87f0cc04e19e1667f Mon Sep 17 00:00:00 2001 From: Student Main Date: Thu, 3 Sep 2020 18:36:56 +0800 Subject: [PATCH 04/35] connect view and controller --- .../Service/OnlineConfigResolver.cs | 18 +++++--- .../Controller/ShadowsocksController.cs | 4 +- .../View/OnlineConfigForm.Designer.cs | 32 ++++++++------ shadowsocks-csharp/View/OnlineConfigForm.cs | 44 +++++++++++++++++-- 4 files changed, 73 insertions(+), 25 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs b/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs index 480dc366..fe3e16c1 100644 --- a/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs +++ b/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs @@ -29,7 +29,12 @@ namespace Shadowsocks.Controller.Service try { string str = await httpClient.GetStringAsync(url); - return Get(str); + var ret = Get(str); + foreach (var item in ret) + { + item.group = url; + } + return ret; } catch (Exception e) { @@ -62,11 +67,9 @@ namespace Shadowsocks.Controller.Service { var l = new List(); if (o == null) return l; - try - { + if (IsServerObject(o)) return new List { o.ToObject() }; - } - catch { }; + foreach (var kv in o) { JToken v = kv.Value; @@ -87,5 +90,10 @@ namespace Shadowsocks.Controller.Service return SearchJArray(t as JArray); } } + + private static bool IsServerObject(JObject o) + { + return new[] { "server", "server_port", "password", "method" }.All(i => o.ContainsKey(i)); + } } } diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 2728b3d0..c2f8e0d4 100644 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -698,7 +698,7 @@ namespace Shadowsocks.Controller .Concat(onlineServer) ); _config.index = _config.configs.IndexOf(selected); - Configuration.Save(_config); + SaveConfig(_config); } public async Task UpdateAllOnlineConfig() @@ -714,7 +714,7 @@ namespace Shadowsocks.Controller .Concat(r.SelectMany(s => s)) ); _config.index = _config.configs.IndexOf(selected); - Configuration.Save(_config); + SaveConfig(_config); } public void SaveOnlineConfigSource(IEnumerable vs) diff --git a/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs b/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs index f80e5ba6..f15503ce 100644 --- a/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs @@ -35,8 +35,8 @@ this.UpdateButton = new System.Windows.Forms.Button(); this.AddButton = new System.Windows.Forms.Button(); this.DeleteButton = new System.Windows.Forms.Button(); - this.UpdateAllButton = new System.Windows.Forms.Button(); this.OkButton = new System.Windows.Forms.Button(); + this.UpdateAllButton = new System.Windows.Forms.Button(); this.CancelButton = new System.Windows.Forms.Button(); this.tableLayoutPanel1.SuspendLayout(); this.SuspendLayout(); @@ -77,6 +77,7 @@ this.UrlListBox.Name = "UrlListBox"; this.UrlListBox.Size = new System.Drawing.Size(482, 344); this.UrlListBox.TabIndex = 0; + this.UrlListBox.SelectedIndexChanged += new System.EventHandler(this.UrlListBox_SelectedIndexChanged); // // label1 // @@ -110,6 +111,7 @@ this.UpdateButton.TabIndex = 3; this.UpdateButton.Text = "Update"; this.UpdateButton.UseVisualStyleBackColor = true; + this.UpdateButton.Click += new System.EventHandler(this.UpdateButton_Click); // // AddButton // @@ -137,19 +139,7 @@ this.DeleteButton.TabIndex = 5; this.DeleteButton.Text = "Delete"; this.DeleteButton.UseVisualStyleBackColor = true; - // - // UpdateAllButton - // - this.UpdateAllButton.Dock = System.Windows.Forms.DockStyle.Fill; - this.UpdateAllButton.Location = new System.Drawing.Point(20, 428); - this.UpdateAllButton.Margin = new System.Windows.Forms.Padding(20, 5, 20, 5); - this.UpdateAllButton.MaximumSize = new System.Drawing.Size(0, 32); - this.UpdateAllButton.MinimumSize = new System.Drawing.Size(0, 32); - this.UpdateAllButton.Name = "UpdateAllButton"; - this.UpdateAllButton.Size = new System.Drawing.Size(122, 32); - this.UpdateAllButton.TabIndex = 6; - this.UpdateAllButton.Text = "Update all"; - this.UpdateAllButton.UseVisualStyleBackColor = true; + this.DeleteButton.Click += new System.EventHandler(this.DeleteButton_Click); // // OkButton // @@ -164,6 +154,20 @@ this.OkButton.Text = "OK"; this.OkButton.UseVisualStyleBackColor = true; // + // UpdateAllButton + // + this.UpdateAllButton.Dock = System.Windows.Forms.DockStyle.Fill; + this.UpdateAllButton.Location = new System.Drawing.Point(20, 428); + this.UpdateAllButton.Margin = new System.Windows.Forms.Padding(20, 5, 20, 5); + this.UpdateAllButton.MaximumSize = new System.Drawing.Size(0, 32); + this.UpdateAllButton.MinimumSize = new System.Drawing.Size(0, 32); + this.UpdateAllButton.Name = "UpdateAllButton"; + this.UpdateAllButton.Size = new System.Drawing.Size(122, 32); + this.UpdateAllButton.TabIndex = 6; + this.UpdateAllButton.Text = "Update all"; + this.UpdateAllButton.UseVisualStyleBackColor = true; + this.UpdateAllButton.Click += new System.EventHandler(this.UpdateAllButton_Click); + // // CancelButton // this.CancelButton.Dock = System.Windows.Forms.DockStyle.Fill; diff --git a/shadowsocks-csharp/View/OnlineConfigForm.cs b/shadowsocks-csharp/View/OnlineConfigForm.cs index 782ef65e..0c23be10 100644 --- a/shadowsocks-csharp/View/OnlineConfigForm.cs +++ b/shadowsocks-csharp/View/OnlineConfigForm.cs @@ -39,6 +39,12 @@ namespace Shadowsocks.View if (idx >= UrlListBox.Items.Count) idx = 0; UrlListBox.SelectedIndex = idx; + SelectItem(); + } + + private void SelectItem() + { + UrlTextBox.Text = (string)UrlListBox.SelectedItem; } private bool ValidateUrl() @@ -57,10 +63,11 @@ namespace Shadowsocks.View private bool Commit() { - if (!ValidateUrl()) return false; - - UrlListBox.Items[UrlListBox.SelectedIndex] = UrlTextBox.Text; - controller.SaveOnlineConfigSource(UrlListBox.Items.OfType().Where(s=>!string.IsNullOrWhiteSpace(s))); + if (ValidateUrl()) + { + UrlListBox.Items[UrlListBox.SelectedIndex] = UrlTextBox.Text; + } + controller.SaveOnlineConfigSource(UrlListBox.Items.OfType().Where(s => !string.IsNullOrWhiteSpace(s))); LoadConfig(); return true; } @@ -72,5 +79,34 @@ namespace Shadowsocks.View UrlTextBox.Text = DefaultPrefix; UrlListBox.SelectedIndex = UrlListBox.Items.Count - 1; } + + private void UpdateButton_Click(object sender, EventArgs e) + { + // update content, also update online config + Commit(); + + _ = controller.UpdateOnlineConfig(UrlTextBox.Text); + } + + private void UrlListBox_SelectedIndexChanged(object sender, EventArgs e) + { + if (!UrlListBox.CanSelect) + { + return; + } + SelectItem(); + } + + private void DeleteButton_Click(object sender, EventArgs e) + { + int idx = UrlListBox.SelectedIndex; + UrlListBox.Items.RemoveAt(idx); + Commit(); + } + + private void UpdateAllButton_Click(object sender, EventArgs e) + { + _ = controller.UpdateAllOnlineConfig(); + } } } From f46b1fb8b0ca112b95f951d00ed2a136de10c224 Mon Sep 17 00:00:00 2001 From: Student Main Date: Fri, 4 Sep 2020 17:29:18 +0800 Subject: [PATCH 05/35] online config deletion, and update when startup --- .../Service/OnlineConfigResolver.cs | 32 +++----- .../Controller/ShadowsocksController.cs | 56 +++++++++++--- shadowsocks-csharp/Program.cs | 11 ++- .../View/OnlineConfigForm.Designer.cs | 4 +- shadowsocks-csharp/View/OnlineConfigForm.cs | 73 ++++++++++++++----- 5 files changed, 120 insertions(+), 56 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs b/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs index fe3e16c1..89ff2565 100644 --- a/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs +++ b/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs @@ -26,35 +26,21 @@ namespace Shadowsocks.Controller.Service httpClientHandler.Proxy = proxy; } - try - { - string str = await httpClient.GetStringAsync(url); - var ret = Get(str); - foreach (var item in ret) - { - item.group = url; - } - return ret; - } - catch (Exception e) + _ = Task.Delay(2000).ContinueWith(_ => httpClient.CancelPendingRequests()); + string str = await httpClient.GetStringAsync(url); + + var ret = Get(str); + foreach (var item in ret) { - logger.LogUsefulException(e); - return new List(); + item.group = url; } + return ret; } public static List Get(string json) { - try - { - var t = JToken.Parse(json); - return SearchJToken(t).ToList(); - } - catch (Exception e) - { - logger.LogUsefulException(e); - return new List(); - } + var t = JToken.Parse(json); + return SearchJToken(t).ToList(); } private static IEnumerable SearchJArray(JArray a) diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index c2f8e0d4..935bf8ea 100644 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -688,33 +688,56 @@ namespace Shadowsocks.Controller #region SIP008 - public async Task UpdateOnlineConfig(string url) + + public async Task UpdateOnlineConfigInternal(string url) { - var selected = GetCurrentServer(); var onlineServer = await OnlineConfigResolver.GetOnline(url, _config.WebProxy); _config.configs = Configuration.SortByOnlineConfig( _config.configs .Where(c => c.group != url) .Concat(onlineServer) ); + logger.Info($"updated {onlineServer.Count} server from {url}"); + return onlineServer.Count; + } + + public async Task UpdateOnlineConfig(string url) + { + var selected = GetCurrentServer(); + try + { + int count = await UpdateOnlineConfigInternal(url); + } + catch (Exception e) + { + logger.LogUsefulException(e); + return false; + } _config.index = _config.configs.IndexOf(selected); SaveConfig(_config); + return true; } - public async Task UpdateAllOnlineConfig() + public async Task UpdateAllOnlineConfig() { var selected = GetCurrentServer(); - var r = await Task.WhenAll( - _config.onlineConfigSource.Select(url => OnlineConfigResolver.GetOnline(url, _config.WebProxy)) - ); - var results = r.SelectMany(s => s); - _config.configs = Configuration.SortByOnlineConfig( - _config.configs - .Where(c => string.IsNullOrEmpty(c.group)) - .Concat(r.SelectMany(s => s)) - ); + int failCount = 0; + foreach (var url in _config.onlineConfigSource) + { + try + { + await UpdateOnlineConfigInternal(url); + } + catch (Exception e) + { + logger.LogUsefulException(e); + failCount++; + } + } + _config.index = _config.configs.IndexOf(selected); SaveConfig(_config); + return failCount; } public void SaveOnlineConfigSource(IEnumerable vs) @@ -723,6 +746,15 @@ namespace Shadowsocks.Controller SaveConfig(_config); } + public void RemoveOnlineConfig(string url) + { + _config.onlineConfigSource.RemoveAll(v => v == url); + _config.configs = Configuration.SortByOnlineConfig( + _config.configs.Where(c => c.group != url) + ); + SaveConfig(_config); + } + #endregion } } diff --git a/shadowsocks-csharp/Program.cs b/shadowsocks-csharp/Program.cs index 4fb8fbbf..6da06f0f 100755 --- a/shadowsocks-csharp/Program.cs +++ b/shadowsocks-csharp/Program.cs @@ -123,7 +123,14 @@ namespace Shadowsocks HotKeys.Init(MainController); MainController.Start(); - #region IPC Handler and Arguement Process + // Update online config + Task.Run(async () => + { + await Task.Delay(10 * 1000); + await MainController.UpdateAllOnlineConfig(); + }); + +#region IPC Handler and Arguement Process IPCService ipcService = new IPCService(); Task.Run(() => ipcService.RunServer()); ipcService.OpenUrlRequested += (_1, e) => MainController.AskAddServerBySSURL(e.Url); @@ -132,7 +139,7 @@ namespace Shadowsocks { MainController.AskAddServerBySSURL(Options.OpenUrl); } - #endregion +#endregion Application.Run(); diff --git a/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs b/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs index f15503ce..d535b523 100644 --- a/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs @@ -153,6 +153,7 @@ this.OkButton.TabIndex = 7; this.OkButton.Text = "OK"; this.OkButton.UseVisualStyleBackColor = true; + this.OkButton.Click += new System.EventHandler(this.OkButton_Click); // // UpdateAllButton // @@ -180,6 +181,7 @@ this.CancelButton.TabIndex = 8; this.CancelButton.Text = "Cancel"; this.CancelButton.UseVisualStyleBackColor = true; + this.CancelButton.Click += new System.EventHandler(this.CancelButton_Click); // // OnlineConfigForm // @@ -188,7 +190,7 @@ this.ClientSize = new System.Drawing.Size(488, 465); this.Controls.Add(this.tableLayoutPanel1); this.Name = "OnlineConfigForm"; - this.Text = "OnlineConfigForm"; + this.Text = "Online config"; this.tableLayoutPanel1.ResumeLayout(false); this.tableLayoutPanel1.PerformLayout(); this.ResumeLayout(false); diff --git a/shadowsocks-csharp/View/OnlineConfigForm.cs b/shadowsocks-csharp/View/OnlineConfigForm.cs index 0c23be10..4cbcf43e 100644 --- a/shadowsocks-csharp/View/OnlineConfigForm.cs +++ b/shadowsocks-csharp/View/OnlineConfigForm.cs @@ -1,14 +1,10 @@ using System; -using System.Collections.Generic; -using System.ComponentModel; using System.Data; -using System.Drawing; using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; using Shadowsocks.Controller; using Shadowsocks.Model; +using Shadowsocks.Properties; namespace Shadowsocks.View { @@ -17,13 +13,13 @@ namespace Shadowsocks.View private ShadowsocksController controller; private Configuration config; - private const string DefaultPrefix = "http://www.baidu.com/"; - public OnlineConfigForm(ShadowsocksController controller) { this.controller = controller; InitializeComponent(); LoadConfig(); + Icon = System.Drawing.Icon.FromHandle(Resources.ssw128.GetHicon()); + I18N.TranslateForm(this); } private void LoadConfig() @@ -38,6 +34,8 @@ namespace Shadowsocks.View } if (idx >= UrlListBox.Items.Count) idx = 0; + if (idx < 0 && UrlListBox.Items.Count > 0) idx = 0; + if (UrlListBox.Items.Count == 0) return; UrlListBox.SelectedIndex = idx; SelectItem(); } @@ -53,6 +51,7 @@ namespace Shadowsocks.View { var scheme = new Uri(UrlTextBox.Text).Scheme; if (scheme != "http" && scheme != "https") return false; + if (UrlListBox.Items.OfType().Contains(UrlTextBox.Text)) return false; } catch { @@ -61,31 +60,47 @@ namespace Shadowsocks.View return true; } - private bool Commit() + private void Commit() { + if (UrlListBox.SelectedIndex < 0) return; + if ((string)UrlListBox.SelectedItem == UrlTextBox.Text) + { + LoadConfig(); + return; + } + if (ValidateUrl()) { + UrlListBox.Items[UrlListBox.SelectedIndex] = UrlTextBox.Text; } - controller.SaveOnlineConfigSource(UrlListBox.Items.OfType().Where(s => !string.IsNullOrWhiteSpace(s))); + controller.SaveOnlineConfigSource(UrlListBox.Items.OfType().Where(s => !string.IsNullOrWhiteSpace(s)).Distinct()); LoadConfig(); - return true; + return; } private void AddButton_Click(object sender, EventArgs e) { + if (string.IsNullOrWhiteSpace(UrlTextBox.Text)) return; Commit(); + // string txt = UrlTextBox.Text; UrlListBox.Items.Add(""); - UrlTextBox.Text = DefaultPrefix; UrlListBox.SelectedIndex = UrlListBox.Items.Count - 1; + UrlTextBox.Text = ""; } - private void UpdateButton_Click(object sender, EventArgs e) + private async void UpdateButton_Click(object sender, EventArgs e) { // update content, also update online config Commit(); - - _ = controller.UpdateOnlineConfig(UrlTextBox.Text); + if (UrlListBox.Items.Count == 0) return; + tableLayoutPanel1.Enabled = false; + bool ok = await controller.UpdateOnlineConfig((string)UrlListBox.SelectedItem); + if (!ok) + { + MessageBox.Show(I18N.GetString("online config failed to update")); + } + tableLayoutPanel1.Enabled = true; } private void UrlListBox_SelectedIndexChanged(object sender, EventArgs e) @@ -99,14 +114,36 @@ namespace Shadowsocks.View private void DeleteButton_Click(object sender, EventArgs e) { - int idx = UrlListBox.SelectedIndex; - UrlListBox.Items.RemoveAt(idx); + if (UrlListBox.Items.Count == 0) return; + string url = (string)UrlListBox.SelectedItem; + if (!string.IsNullOrWhiteSpace(url)) + { + controller.RemoveOnlineConfig(url); + } + LoadConfig(); + } + + private async void UpdateAllButton_Click(object sender, EventArgs e) + { + if (UrlListBox.Items.Count == 0) return; + tableLayoutPanel1.Enabled = false; + int fail = await controller.UpdateAllOnlineConfig(); + if (fail > 0) + { + MessageBox.Show(I18N.GetString("{0} online config failed to update", fail)); + } + tableLayoutPanel1.Enabled = true; + } + + private void OkButton_Click(object sender, EventArgs e) + { Commit(); + Close(); } - private void UpdateAllButton_Click(object sender, EventArgs e) + private void CancelButton_Click(object sender, EventArgs e) { - _ = controller.UpdateAllOnlineConfig(); + Close(); } } } From 4f05e7c98580c2239c414fe3547987adc7f789a0 Mon Sep 17 00:00:00 2001 From: Student Main Date: Fri, 4 Sep 2020 18:01:19 +0800 Subject: [PATCH 06/35] put online config group info into ui --- .../View/ConfigForm.Designer.cs | 286 +++++++----------- shadowsocks-csharp/View/ConfigForm.cs | 5 +- shadowsocks-csharp/View/ConfigForm.resx | 3 + 3 files changed, 115 insertions(+), 179 deletions(-) diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index 3651a33c..5e5a836e 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -58,25 +58,19 @@ this.AddButton = new System.Windows.Forms.Button(); this.ServerGroupBox = new System.Windows.Forms.GroupBox(); this.ServersListBox = new System.Windows.Forms.ListBox(); - this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); - this.tableLayoutPanel6 = new System.Windows.Forms.TableLayoutPanel(); this.MoveDownButton = new System.Windows.Forms.Button(); this.MoveUpButton = new System.Windows.Forms.Button(); - this.tableLayoutPanel5 = new System.Windows.Forms.TableLayoutPanel(); this.ProxyPortTextBox = new System.Windows.Forms.TextBox(); this.ProxyPortLabel = new System.Windows.Forms.Label(); this.PortableModeCheckBox = new System.Windows.Forms.CheckBox(); - this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); - this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel(); this.DuplicateButton = new System.Windows.Forms.Button(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.tableLayoutPanel7 = new System.Windows.Forms.TableLayoutPanel(); + this.GroupLabel = new System.Windows.Forms.Label(); + this.GroupTextBox = new System.Windows.Forms.TextBox(); this.tableLayoutPanel1.SuspendLayout(); this.ServerGroupBox.SuspendLayout(); - this.tableLayoutPanel2.SuspendLayout(); - this.tableLayoutPanel6.SuspendLayout(); - this.tableLayoutPanel5.SuspendLayout(); - this.tableLayoutPanel3.SuspendLayout(); - this.tableLayoutPanel4.SuspendLayout(); + this.tableLayoutPanel7.SuspendLayout(); this.SuspendLayout(); // // tableLayoutPanel1 @@ -104,13 +98,17 @@ this.tableLayoutPanel1.Controls.Add(this.ShowPasswdCheckBox, 1, 3); this.tableLayoutPanel1.Controls.Add(this.PluginArgumentsTextBox, 1, 8); this.tableLayoutPanel1.Controls.Add(this.PluginArgumentsLabel, 0, 8); - this.tableLayoutPanel1.Controls.Add(this.RemarksLabel, 0, 10); this.tableLayoutPanel1.Controls.Add(this.NeedPluginArgCheckBox, 1, 7); - this.tableLayoutPanel1.Location = new System.Drawing.Point(10, 26); + this.tableLayoutPanel1.Controls.Add(this.GroupTextBox, 1, 12); + this.tableLayoutPanel1.Controls.Add(this.GroupLabel, 0, 12); + this.tableLayoutPanel1.Controls.Add(this.RemarksLabel, 0, 10); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(4, 22); this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(4); - this.tableLayoutPanel1.RowCount = 12; + this.tableLayoutPanel1.RowCount = 13; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); @@ -123,7 +121,7 @@ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.Size = new System.Drawing.Size(394, 357); + this.tableLayoutPanel1.Size = new System.Drawing.Size(411, 390); this.tableLayoutPanel1.TabIndex = 0; // // PluginOptionsLabel @@ -145,7 +143,7 @@ this.PluginTextBox.Margin = new System.Windows.Forms.Padding(4); this.PluginTextBox.MaxLength = 256; this.PluginTextBox.Name = "PluginTextBox"; - this.PluginTextBox.Size = new System.Drawing.Size(235, 25); + this.PluginTextBox.Size = new System.Drawing.Size(252, 25); this.PluginTextBox.TabIndex = 5; this.PluginTextBox.WordWrap = false; // @@ -156,7 +154,7 @@ this.RemarksTextBox.Margin = new System.Windows.Forms.Padding(4); this.RemarksTextBox.MaxLength = 32; this.RemarksTextBox.Name = "RemarksTextBox"; - this.RemarksTextBox.Size = new System.Drawing.Size(235, 25); + this.RemarksTextBox.Size = new System.Drawing.Size(252, 25); this.RemarksTextBox.TabIndex = 8; this.RemarksTextBox.WordWrap = false; // @@ -201,7 +199,7 @@ this.IPTextBox.Margin = new System.Windows.Forms.Padding(4); this.IPTextBox.MaxLength = 512; this.IPTextBox.Name = "IPTextBox"; - this.IPTextBox.Size = new System.Drawing.Size(235, 25); + this.IPTextBox.Size = new System.Drawing.Size(252, 25); this.IPTextBox.TabIndex = 0; this.IPTextBox.WordWrap = false; // @@ -212,7 +210,7 @@ this.ServerPortTextBox.Margin = new System.Windows.Forms.Padding(4); this.ServerPortTextBox.MaxLength = 10; this.ServerPortTextBox.Name = "ServerPortTextBox"; - this.ServerPortTextBox.Size = new System.Drawing.Size(235, 25); + this.ServerPortTextBox.Size = new System.Drawing.Size(252, 25); this.ServerPortTextBox.TabIndex = 1; this.ServerPortTextBox.WordWrap = false; // @@ -224,7 +222,7 @@ this.PasswordTextBox.Margin = new System.Windows.Forms.Padding(4); this.PasswordTextBox.MaxLength = 256; this.PasswordTextBox.Name = "PasswordTextBox"; - this.PasswordTextBox.Size = new System.Drawing.Size(235, 25); + this.PasswordTextBox.Size = new System.Drawing.Size(252, 25); this.PasswordTextBox.TabIndex = 2; this.PasswordTextBox.UseSystemPasswordChar = true; this.PasswordTextBox.WordWrap = false; @@ -251,7 +249,7 @@ this.EncryptionSelect.Location = new System.Drawing.Point(151, 134); this.EncryptionSelect.Margin = new System.Windows.Forms.Padding(4); this.EncryptionSelect.Name = "EncryptionSelect"; - this.EncryptionSelect.Size = new System.Drawing.Size(235, 23); + this.EncryptionSelect.Size = new System.Drawing.Size(252, 23); this.EncryptionSelect.TabIndex = 4; // // TimeoutLabel @@ -273,7 +271,7 @@ this.TimeoutTextBox.Margin = new System.Windows.Forms.Padding(4); this.TimeoutTextBox.MaxLength = 5; this.TimeoutTextBox.Name = "TimeoutTextBox"; - this.TimeoutTextBox.Size = new System.Drawing.Size(235, 25); + this.TimeoutTextBox.Size = new System.Drawing.Size(252, 25); this.TimeoutTextBox.TabIndex = 9; // // PluginLabel @@ -294,7 +292,7 @@ this.PluginOptionsTextBox.Margin = new System.Windows.Forms.Padding(4); this.PluginOptionsTextBox.MaxLength = 256; this.PluginOptionsTextBox.Name = "PluginOptionsTextBox"; - this.PluginOptionsTextBox.Size = new System.Drawing.Size(235, 25); + this.PluginOptionsTextBox.Size = new System.Drawing.Size(252, 25); this.PluginOptionsTextBox.TabIndex = 6; this.PluginOptionsTextBox.WordWrap = false; // @@ -320,7 +318,7 @@ this.PluginArgumentsTextBox.Margin = new System.Windows.Forms.Padding(4); this.PluginArgumentsTextBox.MaxLength = 512; this.PluginArgumentsTextBox.Name = "PluginArgumentsTextBox"; - this.PluginArgumentsTextBox.Size = new System.Drawing.Size(235, 25); + this.PluginArgumentsTextBox.Size = new System.Drawing.Size(252, 25); this.PluginArgumentsTextBox.TabIndex = 7; this.PluginArgumentsTextBox.WordWrap = false; // @@ -365,7 +363,7 @@ this.panel2.Anchor = System.Windows.Forms.AnchorStyles.Top; this.panel2.AutoSize = true; this.panel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.panel2.Location = new System.Drawing.Point(206, 234); + this.panel2.Location = new System.Drawing.Point(239, 234); this.panel2.Margin = new System.Windows.Forms.Padding(4); this.panel2.Name = "panel2"; this.panel2.Size = new System.Drawing.Size(0, 0); @@ -374,11 +372,9 @@ // OKButton // this.OKButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.OKButton.Dock = System.Windows.Forms.DockStyle.Right; - this.OKButton.Location = new System.Drawing.Point(4, 4); - this.OKButton.Margin = new System.Windows.Forms.Padding(4, 4, 4, 0); + this.OKButton.Location = new System.Drawing.Point(327, 517); this.OKButton.Name = "OKButton"; - this.OKButton.Size = new System.Drawing.Size(94, 29); + this.OKButton.Size = new System.Drawing.Size(100, 29); this.OKButton.TabIndex = 17; this.OKButton.Text = "OK"; this.OKButton.UseVisualStyleBackColor = true; @@ -387,11 +383,9 @@ // MyCancelButton // this.MyCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.MyCancelButton.Dock = System.Windows.Forms.DockStyle.Right; - this.MyCancelButton.Location = new System.Drawing.Point(106, 4); - this.MyCancelButton.Margin = new System.Windows.Forms.Padding(4, 4, 4, 0); + this.MyCancelButton.Location = new System.Drawing.Point(435, 517); this.MyCancelButton.Name = "MyCancelButton"; - this.MyCancelButton.Size = new System.Drawing.Size(94, 29); + this.MyCancelButton.Size = new System.Drawing.Size(100, 29); this.MyCancelButton.TabIndex = 18; this.MyCancelButton.Text = "Cancel"; this.MyCancelButton.UseVisualStyleBackColor = true; @@ -399,12 +393,10 @@ // // ApplyButton // - this.ApplyButton.Dock = System.Windows.Forms.DockStyle.Right; this.ApplyButton.Enabled = false; - this.ApplyButton.Location = new System.Drawing.Point(208, 4); - this.ApplyButton.Margin = new System.Windows.Forms.Padding(4, 4, 0, 0); + this.ApplyButton.Location = new System.Drawing.Point(543, 517); this.ApplyButton.Name = "ApplyButton"; - this.ApplyButton.Size = new System.Drawing.Size(94, 29); + this.ApplyButton.Size = new System.Drawing.Size(100, 29); this.ApplyButton.TabIndex = 19; this.ApplyButton.Text = "Apply"; this.ApplyButton.UseVisualStyleBackColor = true; @@ -412,9 +404,7 @@ // // DeleteButton // - this.DeleteButton.Dock = System.Windows.Forms.DockStyle.Right; - this.DeleteButton.Location = new System.Drawing.Point(108, 8); - this.DeleteButton.Margin = new System.Windows.Forms.Padding(4, 8, 0, 4); + this.DeleteButton.Location = new System.Drawing.Point(111, 419); this.DeleteButton.Name = "DeleteButton"; this.DeleteButton.Size = new System.Drawing.Size(100, 29); this.DeleteButton.TabIndex = 13; @@ -424,9 +414,7 @@ // // AddButton // - this.AddButton.Dock = System.Windows.Forms.DockStyle.Left; - this.AddButton.Location = new System.Drawing.Point(0, 8); - this.AddButton.Margin = new System.Windows.Forms.Padding(0, 8, 4, 4); + this.AddButton.Location = new System.Drawing.Point(3, 419); this.AddButton.Name = "AddButton"; this.AddButton.Size = new System.Drawing.Size(100, 29); this.AddButton.TabIndex = 12; @@ -438,74 +426,35 @@ // this.ServerGroupBox.AutoSize = true; this.ServerGroupBox.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.tableLayoutPanel7.SetColumnSpan(this.ServerGroupBox, 4); this.ServerGroupBox.Controls.Add(this.tableLayoutPanel1); - this.ServerGroupBox.Location = new System.Drawing.Point(223, 0); + this.ServerGroupBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.ServerGroupBox.Location = new System.Drawing.Point(231, 0); this.ServerGroupBox.Margin = new System.Windows.Forms.Padding(15, 0, 0, 0); this.ServerGroupBox.Name = "ServerGroupBox"; this.ServerGroupBox.Padding = new System.Windows.Forms.Padding(4); - this.ServerGroupBox.Size = new System.Drawing.Size(408, 405); + this.ServerGroupBox.Size = new System.Drawing.Size(419, 416); this.ServerGroupBox.TabIndex = 0; this.ServerGroupBox.TabStop = false; this.ServerGroupBox.Text = "Server"; // // ServersListBox // + this.tableLayoutPanel7.SetColumnSpan(this.ServersListBox, 2); + this.ServersListBox.Dock = System.Windows.Forms.DockStyle.Fill; this.ServersListBox.FormattingEnabled = true; this.ServersListBox.IntegralHeight = false; this.ServersListBox.ItemHeight = 15; this.ServersListBox.Location = new System.Drawing.Point(0, 0); this.ServersListBox.Margin = new System.Windows.Forms.Padding(0); this.ServersListBox.Name = "ServersListBox"; - this.ServersListBox.Size = new System.Drawing.Size(206, 184); + this.ServersListBox.Size = new System.Drawing.Size(216, 416); this.ServersListBox.TabIndex = 11; this.ServersListBox.SelectedIndexChanged += new System.EventHandler(this.ServersListBox_SelectedIndexChanged); // - // tableLayoutPanel2 - // - this.tableLayoutPanel2.AutoSize = true; - this.tableLayoutPanel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.tableLayoutPanel2.ColumnCount = 2; - this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel6, 0, 2); - this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel5, 1, 1); - this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel3, 1, 2); - this.tableLayoutPanel2.Controls.Add(this.ServersListBox, 0, 0); - this.tableLayoutPanel2.Controls.Add(this.ServerGroupBox, 1, 0); - this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel4, 0, 1); - this.tableLayoutPanel2.Location = new System.Drawing.Point(15, 15); - this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0); - this.tableLayoutPanel2.Name = "tableLayoutPanel2"; - this.tableLayoutPanel2.RowCount = 3; - this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel2.Size = new System.Drawing.Size(631, 528); - this.tableLayoutPanel2.TabIndex = 7; - // - // tableLayoutPanel6 - // - this.tableLayoutPanel6.AutoSize = true; - this.tableLayoutPanel6.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.tableLayoutPanel6.ColumnCount = 2; - this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel6.Controls.Add(this.MoveDownButton, 1, 0); - this.tableLayoutPanel6.Controls.Add(this.MoveUpButton, 0, 0); - this.tableLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Top; - this.tableLayoutPanel6.Location = new System.Drawing.Point(0, 487); - this.tableLayoutPanel6.Margin = new System.Windows.Forms.Padding(0); - this.tableLayoutPanel6.Name = "tableLayoutPanel6"; - this.tableLayoutPanel6.RowCount = 1; - this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel6.Size = new System.Drawing.Size(208, 41); - this.tableLayoutPanel6.TabIndex = 10; - // // MoveDownButton // - this.MoveDownButton.Dock = System.Windows.Forms.DockStyle.Right; - this.MoveDownButton.Location = new System.Drawing.Point(108, 8); - this.MoveDownButton.Margin = new System.Windows.Forms.Padding(4, 8, 0, 4); + this.MoveDownButton.Location = new System.Drawing.Point(111, 517); this.MoveDownButton.Name = "MoveDownButton"; this.MoveDownButton.Size = new System.Drawing.Size(100, 29); this.MoveDownButton.TabIndex = 16; @@ -515,9 +464,7 @@ // // MoveUpButton // - this.MoveUpButton.Dock = System.Windows.Forms.DockStyle.Left; - this.MoveUpButton.Location = new System.Drawing.Point(0, 8); - this.MoveUpButton.Margin = new System.Windows.Forms.Padding(0, 8, 4, 4); + this.MoveUpButton.Location = new System.Drawing.Point(3, 517); this.MoveUpButton.Name = "MoveUpButton"; this.MoveUpButton.Size = new System.Drawing.Size(100, 29); this.MoveUpButton.TabIndex = 15; @@ -525,32 +472,11 @@ this.MoveUpButton.UseVisualStyleBackColor = true; this.MoveUpButton.Click += new System.EventHandler(this.MoveUpButton_Click); // - // tableLayoutPanel5 - // - this.tableLayoutPanel5.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left))); - this.tableLayoutPanel5.AutoSize = true; - this.tableLayoutPanel5.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.tableLayoutPanel5.ColumnCount = 2; - this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel5.Controls.Add(this.ProxyPortTextBox, 1, 0); - this.tableLayoutPanel5.Controls.Add(this.ProxyPortLabel, 0, 0); - this.tableLayoutPanel5.Controls.Add(this.PortableModeCheckBox, 0, 1); - this.tableLayoutPanel5.Location = new System.Drawing.Point(208, 405); - this.tableLayoutPanel5.Margin = new System.Windows.Forms.Padding(0); - this.tableLayoutPanel5.Name = "tableLayoutPanel5"; - this.tableLayoutPanel5.Padding = new System.Windows.Forms.Padding(4); - this.tableLayoutPanel5.RowCount = 2; - this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel5.Size = new System.Drawing.Size(251, 82); - this.tableLayoutPanel5.TabIndex = 9; - // // ProxyPortTextBox // this.ProxyPortTextBox.Anchor = System.Windows.Forms.AnchorStyles.Left; - this.ProxyPortTextBox.Location = new System.Drawing.Point(103, 8); + this.tableLayoutPanel7.SetColumnSpan(this.ProxyPortTextBox, 2); + this.ProxyPortTextBox.Location = new System.Drawing.Point(328, 428); this.ProxyPortTextBox.Margin = new System.Windows.Forms.Padding(4); this.ProxyPortTextBox.MaxLength = 10; this.ProxyPortTextBox.Name = "ProxyPortTextBox"; @@ -562,7 +488,7 @@ // this.ProxyPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.ProxyPortLabel.AutoSize = true; - this.ProxyPortLabel.Location = new System.Drawing.Point(8, 13); + this.ProxyPortLabel.Location = new System.Drawing.Point(233, 433); this.ProxyPortLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.ProxyPortLabel.Name = "ProxyPortLabel"; this.ProxyPortLabel.Size = new System.Drawing.Size(87, 15); @@ -573,8 +499,8 @@ // this.PortableModeCheckBox.Anchor = System.Windows.Forms.AnchorStyles.Left; this.PortableModeCheckBox.AutoSize = true; - this.tableLayoutPanel5.SetColumnSpan(this.PortableModeCheckBox, 2); - this.PortableModeCheckBox.Location = new System.Drawing.Point(8, 48); + this.tableLayoutPanel7.SetColumnSpan(this.PortableModeCheckBox, 2); + this.PortableModeCheckBox.Location = new System.Drawing.Point(220, 480); this.PortableModeCheckBox.Margin = new System.Windows.Forms.Padding(4); this.PortableModeCheckBox.Name = "PortableModeCheckBox"; this.PortableModeCheckBox.Size = new System.Drawing.Size(133, 19); @@ -583,52 +509,9 @@ this.toolTip1.SetToolTip(this.PortableModeCheckBox, "restart required"); this.PortableModeCheckBox.UseVisualStyleBackColor = true; // - // tableLayoutPanel3 - // - this.tableLayoutPanel3.AutoSize = true; - this.tableLayoutPanel3.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.tableLayoutPanel3.ColumnCount = 3; - this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 25F)); - this.tableLayoutPanel3.Controls.Add(this.MyCancelButton, 1, 0); - this.tableLayoutPanel3.Controls.Add(this.OKButton, 0, 0); - this.tableLayoutPanel3.Controls.Add(this.ApplyButton, 2, 0); - this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Right; - this.tableLayoutPanel3.Location = new System.Drawing.Point(329, 491); - this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(4, 4, 0, 4); - this.tableLayoutPanel3.Name = "tableLayoutPanel3"; - this.tableLayoutPanel3.RowCount = 1; - this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel3.Size = new System.Drawing.Size(302, 33); - this.tableLayoutPanel3.TabIndex = 8; - // - // tableLayoutPanel4 - // - this.tableLayoutPanel4.AutoSize = true; - this.tableLayoutPanel4.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.tableLayoutPanel4.ColumnCount = 2; - this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel4.Controls.Add(this.DuplicateButton, 0, 1); - this.tableLayoutPanel4.Controls.Add(this.DeleteButton, 1, 0); - this.tableLayoutPanel4.Controls.Add(this.AddButton, 0, 0); - this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Top; - this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 405); - this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0); - this.tableLayoutPanel4.Name = "tableLayoutPanel4"; - this.tableLayoutPanel4.RowCount = 2; - this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel4.Size = new System.Drawing.Size(208, 82); - this.tableLayoutPanel4.TabIndex = 8; - // // DuplicateButton // - this.DuplicateButton.Dock = System.Windows.Forms.DockStyle.Left; - this.DuplicateButton.Location = new System.Drawing.Point(0, 49); - this.DuplicateButton.Margin = new System.Windows.Forms.Padding(0, 8, 4, 4); + this.DuplicateButton.Location = new System.Drawing.Point(3, 468); this.DuplicateButton.Name = "DuplicateButton"; this.DuplicateButton.Size = new System.Drawing.Size(100, 29); this.DuplicateButton.TabIndex = 14; @@ -636,6 +519,64 @@ this.DuplicateButton.UseVisualStyleBackColor = true; this.DuplicateButton.Click += new System.EventHandler(this.DuplicateButton_Click); // + // tableLayoutPanel7 + // + this.tableLayoutPanel7.AutoSize = true; + this.tableLayoutPanel7.ColumnCount = 6; + this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 16.66667F)); + this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 16.66667F)); + this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 16.66667F)); + this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 16.66667F)); + this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 16.66667F)); + this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 16.66667F)); + this.tableLayoutPanel7.Controls.Add(this.ApplyButton, 5, 3); + this.tableLayoutPanel7.Controls.Add(this.MyCancelButton, 4, 3); + this.tableLayoutPanel7.Controls.Add(this.PortableModeCheckBox, 2, 2); + this.tableLayoutPanel7.Controls.Add(this.OKButton, 3, 3); + this.tableLayoutPanel7.Controls.Add(this.ProxyPortTextBox, 3, 1); + this.tableLayoutPanel7.Controls.Add(this.MoveDownButton, 1, 3); + this.tableLayoutPanel7.Controls.Add(this.ProxyPortLabel, 2, 1); + this.tableLayoutPanel7.Controls.Add(this.MoveUpButton, 0, 3); + this.tableLayoutPanel7.Controls.Add(this.AddButton, 0, 1); + this.tableLayoutPanel7.Controls.Add(this.DeleteButton, 1, 1); + this.tableLayoutPanel7.Controls.Add(this.DuplicateButton, 0, 2); + this.tableLayoutPanel7.Controls.Add(this.ServersListBox, 0, 0); + this.tableLayoutPanel7.Controls.Add(this.ServerGroupBox, 2, 0); + this.tableLayoutPanel7.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel7.GrowStyle = System.Windows.Forms.TableLayoutPanelGrowStyle.FixedSize; + this.tableLayoutPanel7.Location = new System.Drawing.Point(15, 15); + this.tableLayoutPanel7.Name = "tableLayoutPanel7"; + this.tableLayoutPanel7.RowCount = 4; + this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); + this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); + this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); + this.tableLayoutPanel7.Size = new System.Drawing.Size(650, 565); + this.tableLayoutPanel7.TabIndex = 8; + // + // GroupLabel + // + this.GroupLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; + this.GroupLabel.AutoSize = true; + this.GroupLabel.Location = new System.Drawing.Point(96, 362); + this.GroupLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.GroupLabel.Name = "GroupLabel"; + this.GroupLabel.RightToLeft = System.Windows.Forms.RightToLeft.No; + this.GroupLabel.Size = new System.Drawing.Size(47, 15); + this.GroupLabel.TabIndex = 11; + this.GroupLabel.Text = "Group"; + // + // GroupTextBox + // + this.GroupTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.GroupTextBox.Location = new System.Drawing.Point(151, 357); + this.GroupTextBox.Margin = new System.Windows.Forms.Padding(4); + this.GroupTextBox.MaxLength = 5; + this.GroupTextBox.Name = "GroupTextBox"; + this.GroupTextBox.ReadOnly = true; + this.GroupTextBox.Size = new System.Drawing.Size(252, 25); + this.GroupTextBox.TabIndex = 12; + // // ConfigForm // this.AcceptButton = this.OKButton; @@ -644,8 +585,8 @@ this.AutoSize = true; this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.CancelButton = this.MyCancelButton; - this.ClientSize = new System.Drawing.Size(614, 548); - this.Controls.Add(this.tableLayoutPanel2); + this.ClientSize = new System.Drawing.Size(680, 591); + this.Controls.Add(this.tableLayoutPanel7); this.Controls.Add(this.panel2); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.Margin = new System.Windows.Forms.Padding(4); @@ -662,13 +603,8 @@ this.tableLayoutPanel1.PerformLayout(); this.ServerGroupBox.ResumeLayout(false); this.ServerGroupBox.PerformLayout(); - this.tableLayoutPanel2.ResumeLayout(false); - this.tableLayoutPanel2.PerformLayout(); - this.tableLayoutPanel6.ResumeLayout(false); - this.tableLayoutPanel5.ResumeLayout(false); - this.tableLayoutPanel5.PerformLayout(); - this.tableLayoutPanel3.ResumeLayout(false); - this.tableLayoutPanel4.ResumeLayout(false); + this.tableLayoutPanel7.ResumeLayout(false); + this.tableLayoutPanel7.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -694,13 +630,8 @@ private System.Windows.Forms.ListBox ServersListBox; private System.Windows.Forms.TextBox RemarksTextBox; private System.Windows.Forms.Label RemarksLabel; - private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; - private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3; - private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4; - private System.Windows.Forms.TableLayoutPanel tableLayoutPanel5; private System.Windows.Forms.TextBox ProxyPortTextBox; private System.Windows.Forms.Label ProxyPortLabel; - private System.Windows.Forms.TableLayoutPanel tableLayoutPanel6; private System.Windows.Forms.Button MoveDownButton; private System.Windows.Forms.Button MoveUpButton; private System.Windows.Forms.Button DuplicateButton; @@ -717,6 +648,9 @@ private System.Windows.Forms.ToolTip toolTip1; private System.Windows.Forms.CheckBox PortableModeCheckBox; private System.Windows.Forms.CheckBox NeedPluginArgCheckBox; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel7; + private System.Windows.Forms.Label GroupLabel; + private System.Windows.Forms.TextBox GroupTextBox; } } diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index 47335b05..846a89a9 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -107,9 +107,6 @@ namespace Shadowsocks.View InitializeComponent(); EncryptionSelect.Items.AddRange(EncryptionMethod.AllMethods); - // a dirty hack - ServersListBox.Dock = DockStyle.Fill; - tableLayoutPanel5.Dock = DockStyle.Fill; PerformLayout(); UpdateTexts(); @@ -413,6 +410,8 @@ namespace Shadowsocks.View RemarksTextBox.Text = server.remarks; TimeoutTextBox.Text = server.timeout.ToString(); + GroupTextBox.Text = server.group; + isChange = false; } diff --git a/shadowsocks-csharp/View/ConfigForm.resx b/shadowsocks-csharp/View/ConfigForm.resx index 80d77309..6dfd76d8 100755 --- a/shadowsocks-csharp/View/ConfigForm.resx +++ b/shadowsocks-csharp/View/ConfigForm.resx @@ -120,4 +120,7 @@ 17, 17 + + 17, 17 + \ No newline at end of file From 0cbb581b41c41bb51d54fbeb5547c5e53bcb01af Mon Sep 17 00:00:00 2001 From: Student Main Date: Fri, 4 Sep 2020 18:27:11 +0800 Subject: [PATCH 07/35] delete old server when update online config url --- shadowsocks-csharp/View/OnlineConfigForm.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shadowsocks-csharp/View/OnlineConfigForm.cs b/shadowsocks-csharp/View/OnlineConfigForm.cs index 4cbcf43e..ab69546d 100644 --- a/shadowsocks-csharp/View/OnlineConfigForm.cs +++ b/shadowsocks-csharp/View/OnlineConfigForm.cs @@ -91,15 +91,19 @@ namespace Shadowsocks.View private async void UpdateButton_Click(object sender, EventArgs e) { + string old = (string)UrlListBox.SelectedItem; // update content, also update online config Commit(); + string current = (string)UrlListBox.SelectedItem; if (UrlListBox.Items.Count == 0) return; tableLayoutPanel1.Enabled = false; - bool ok = await controller.UpdateOnlineConfig((string)UrlListBox.SelectedItem); + bool ok = await controller.UpdateOnlineConfig(current); if (!ok) { MessageBox.Show(I18N.GetString("online config failed to update")); + return; } + if (old != current) controller.RemoveOnlineConfig(old); tableLayoutPanel1.Enabled = true; } From 18486788997bd4c7acc5db6b7823f75a9e5b78a5 Mon Sep 17 00:00:00 2001 From: Student Main Date: Sat, 5 Sep 2020 17:45:05 +0800 Subject: [PATCH 08/35] tweak ui --- .../View/ConfigForm.Designer.cs | 196 +++++++++--------- .../View/HotkeySettingsForm.designer.cs | 77 ++++--- .../View/OnlineConfigForm.Designer.cs | 83 ++++---- 3 files changed, 176 insertions(+), 180 deletions(-) diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index 5e5a836e..3d5794a7 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -79,7 +79,7 @@ this.tableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.tableLayoutPanel1.ColumnCount = 2; this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel1.Controls.Add(this.PluginOptionsLabel, 0, 6); this.tableLayoutPanel1.Controls.Add(this.PluginTextBox, 1, 5); this.tableLayoutPanel1.Controls.Add(this.RemarksTextBox, 1, 10); @@ -107,7 +107,7 @@ this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(4); - this.tableLayoutPanel1.RowCount = 13; + this.tableLayoutPanel1.RowCount = 14; this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); @@ -121,14 +121,15 @@ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.Size = new System.Drawing.Size(411, 390); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(362, 399); this.tableLayoutPanel1.TabIndex = 0; // // PluginOptionsLabel // this.PluginOptionsLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.PluginOptionsLabel.AutoSize = true; - this.PluginOptionsLabel.Location = new System.Drawing.Point(24, 203); + this.PluginOptionsLabel.Location = new System.Drawing.Point(24, 199); this.PluginOptionsLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.PluginOptionsLabel.Name = "PluginOptionsLabel"; this.PluginOptionsLabel.Size = new System.Drawing.Size(119, 15); @@ -138,23 +139,21 @@ // // PluginTextBox // - this.PluginTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.PluginTextBox.Location = new System.Drawing.Point(151, 165); - this.PluginTextBox.Margin = new System.Windows.Forms.Padding(4); + this.PluginTextBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.PluginTextBox.Location = new System.Drawing.Point(150, 163); this.PluginTextBox.MaxLength = 256; this.PluginTextBox.Name = "PluginTextBox"; - this.PluginTextBox.Size = new System.Drawing.Size(252, 25); + this.PluginTextBox.Size = new System.Drawing.Size(205, 25); this.PluginTextBox.TabIndex = 5; this.PluginTextBox.WordWrap = false; // // RemarksTextBox // - this.RemarksTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.RemarksTextBox.Location = new System.Drawing.Point(151, 291); - this.RemarksTextBox.Margin = new System.Windows.Forms.Padding(4); + this.RemarksTextBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.RemarksTextBox.Location = new System.Drawing.Point(150, 283); this.RemarksTextBox.MaxLength = 32; this.RemarksTextBox.Name = "RemarksTextBox"; - this.RemarksTextBox.Size = new System.Drawing.Size(252, 25); + this.RemarksTextBox.Size = new System.Drawing.Size(205, 25); this.RemarksTextBox.TabIndex = 8; this.RemarksTextBox.WordWrap = false; // @@ -162,7 +161,7 @@ // this.IPLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.IPLabel.AutoSize = true; - this.IPLabel.Location = new System.Drawing.Point(64, 13); + this.IPLabel.Location = new System.Drawing.Point(64, 12); this.IPLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.IPLabel.Name = "IPLabel"; this.IPLabel.Size = new System.Drawing.Size(79, 15); @@ -173,7 +172,7 @@ // this.ServerPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.ServerPortLabel.AutoSize = true; - this.ServerPortLabel.Location = new System.Drawing.Point(48, 46); + this.ServerPortLabel.Location = new System.Drawing.Point(48, 43); this.ServerPortLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.ServerPortLabel.Name = "ServerPortLabel"; this.ServerPortLabel.Size = new System.Drawing.Size(95, 15); @@ -184,7 +183,7 @@ // this.PasswordLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.PasswordLabel.AutoSize = true; - this.PasswordLabel.Location = new System.Drawing.Point(72, 79); + this.PasswordLabel.Location = new System.Drawing.Point(72, 74); this.PasswordLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.PasswordLabel.Name = "PasswordLabel"; this.PasswordLabel.Size = new System.Drawing.Size(71, 15); @@ -194,35 +193,32 @@ // // IPTextBox // - this.IPTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.IPTextBox.Location = new System.Drawing.Point(151, 8); - this.IPTextBox.Margin = new System.Windows.Forms.Padding(4); + this.IPTextBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.IPTextBox.Location = new System.Drawing.Point(150, 7); this.IPTextBox.MaxLength = 512; this.IPTextBox.Name = "IPTextBox"; - this.IPTextBox.Size = new System.Drawing.Size(252, 25); + this.IPTextBox.Size = new System.Drawing.Size(205, 25); this.IPTextBox.TabIndex = 0; this.IPTextBox.WordWrap = false; // // ServerPortTextBox // - this.ServerPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ServerPortTextBox.Location = new System.Drawing.Point(151, 41); - this.ServerPortTextBox.Margin = new System.Windows.Forms.Padding(4); + this.ServerPortTextBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.ServerPortTextBox.Location = new System.Drawing.Point(150, 38); this.ServerPortTextBox.MaxLength = 10; this.ServerPortTextBox.Name = "ServerPortTextBox"; - this.ServerPortTextBox.Size = new System.Drawing.Size(252, 25); + this.ServerPortTextBox.Size = new System.Drawing.Size(205, 25); this.ServerPortTextBox.TabIndex = 1; this.ServerPortTextBox.WordWrap = false; // // PasswordTextBox // - this.PasswordTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.PasswordTextBox.Dock = System.Windows.Forms.DockStyle.Fill; this.PasswordTextBox.Font = new System.Drawing.Font("Consolas", 9F); - this.PasswordTextBox.Location = new System.Drawing.Point(151, 74); - this.PasswordTextBox.Margin = new System.Windows.Forms.Padding(4); + this.PasswordTextBox.Location = new System.Drawing.Point(150, 69); this.PasswordTextBox.MaxLength = 256; this.PasswordTextBox.Name = "PasswordTextBox"; - this.PasswordTextBox.Size = new System.Drawing.Size(252, 25); + this.PasswordTextBox.Size = new System.Drawing.Size(205, 25); this.PasswordTextBox.TabIndex = 2; this.PasswordTextBox.UseSystemPasswordChar = true; this.PasswordTextBox.WordWrap = false; @@ -231,7 +227,7 @@ // this.EncryptionLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.EncryptionLabel.AutoSize = true; - this.EncryptionLabel.Location = new System.Drawing.Point(56, 138); + this.EncryptionLabel.Location = new System.Drawing.Point(56, 134); this.EncryptionLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.EncryptionLabel.Name = "EncryptionLabel"; this.EncryptionLabel.Size = new System.Drawing.Size(87, 15); @@ -240,23 +236,22 @@ // // EncryptionSelect // - this.EncryptionSelect.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.EncryptionSelect.Dock = System.Windows.Forms.DockStyle.Fill; this.EncryptionSelect.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.EncryptionSelect.FormattingEnabled = true; this.EncryptionSelect.ImeMode = System.Windows.Forms.ImeMode.NoControl; this.EncryptionSelect.ItemHeight = 15; - this.EncryptionSelect.Location = new System.Drawing.Point(151, 134); - this.EncryptionSelect.Margin = new System.Windows.Forms.Padding(4); + this.EncryptionSelect.Location = new System.Drawing.Point(150, 129); + this.EncryptionSelect.Margin = new System.Windows.Forms.Padding(3, 5, 3, 8); this.EncryptionSelect.Name = "EncryptionSelect"; - this.EncryptionSelect.Size = new System.Drawing.Size(252, 23); + this.EncryptionSelect.Size = new System.Drawing.Size(205, 23); this.EncryptionSelect.TabIndex = 4; // // TimeoutLabel // this.TimeoutLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.TimeoutLabel.AutoSize = true; - this.TimeoutLabel.Location = new System.Drawing.Point(40, 329); + this.TimeoutLabel.Location = new System.Drawing.Point(40, 319); this.TimeoutLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.TimeoutLabel.Name = "TimeoutLabel"; this.TimeoutLabel.RightToLeft = System.Windows.Forms.RightToLeft.No; @@ -266,19 +261,18 @@ // // TimeoutTextBox // - this.TimeoutTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.TimeoutTextBox.Location = new System.Drawing.Point(151, 324); - this.TimeoutTextBox.Margin = new System.Windows.Forms.Padding(4); + this.TimeoutTextBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.TimeoutTextBox.Location = new System.Drawing.Point(150, 314); this.TimeoutTextBox.MaxLength = 5; this.TimeoutTextBox.Name = "TimeoutTextBox"; - this.TimeoutTextBox.Size = new System.Drawing.Size(252, 25); + this.TimeoutTextBox.Size = new System.Drawing.Size(205, 25); this.TimeoutTextBox.TabIndex = 9; // // PluginLabel // this.PluginLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.PluginLabel.AutoSize = true; - this.PluginLabel.Location = new System.Drawing.Point(24, 170); + this.PluginLabel.Location = new System.Drawing.Point(24, 168); this.PluginLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.PluginLabel.Name = "PluginLabel"; this.PluginLabel.Size = new System.Drawing.Size(119, 15); @@ -287,12 +281,11 @@ // // PluginOptionsTextBox // - this.PluginOptionsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.PluginOptionsTextBox.Location = new System.Drawing.Point(151, 198); - this.PluginOptionsTextBox.Margin = new System.Windows.Forms.Padding(4); + this.PluginOptionsTextBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.PluginOptionsTextBox.Location = new System.Drawing.Point(150, 194); this.PluginOptionsTextBox.MaxLength = 256; this.PluginOptionsTextBox.Name = "PluginOptionsTextBox"; - this.PluginOptionsTextBox.Size = new System.Drawing.Size(252, 25); + this.PluginOptionsTextBox.Size = new System.Drawing.Size(205, 25); this.PluginOptionsTextBox.TabIndex = 6; this.PluginOptionsTextBox.WordWrap = false; // @@ -301,7 +294,7 @@ this.ShowPasswdCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left))); this.ShowPasswdCheckBox.AutoSize = true; - this.ShowPasswdCheckBox.Location = new System.Drawing.Point(151, 107); + this.ShowPasswdCheckBox.Location = new System.Drawing.Point(151, 101); this.ShowPasswdCheckBox.Margin = new System.Windows.Forms.Padding(4); this.ShowPasswdCheckBox.Name = "ShowPasswdCheckBox"; this.ShowPasswdCheckBox.Size = new System.Drawing.Size(133, 19); @@ -313,12 +306,11 @@ // // PluginArgumentsTextBox // - this.PluginArgumentsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.PluginArgumentsTextBox.Location = new System.Drawing.Point(151, 258); - this.PluginArgumentsTextBox.Margin = new System.Windows.Forms.Padding(4); + this.PluginArgumentsTextBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.PluginArgumentsTextBox.Location = new System.Drawing.Point(150, 252); this.PluginArgumentsTextBox.MaxLength = 512; this.PluginArgumentsTextBox.Name = "PluginArgumentsTextBox"; - this.PluginArgumentsTextBox.Size = new System.Drawing.Size(252, 25); + this.PluginArgumentsTextBox.Size = new System.Drawing.Size(205, 25); this.PluginArgumentsTextBox.TabIndex = 7; this.PluginArgumentsTextBox.WordWrap = false; // @@ -326,7 +318,7 @@ // this.PluginArgumentsLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.PluginArgumentsLabel.AutoSize = true; - this.PluginArgumentsLabel.Location = new System.Drawing.Point(8, 263); + this.PluginArgumentsLabel.Location = new System.Drawing.Point(8, 257); this.PluginArgumentsLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.PluginArgumentsLabel.Name = "PluginArgumentsLabel"; this.PluginArgumentsLabel.Size = new System.Drawing.Size(135, 15); @@ -339,7 +331,7 @@ // this.RemarksLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.RemarksLabel.AutoSize = true; - this.RemarksLabel.Location = new System.Drawing.Point(80, 296); + this.RemarksLabel.Location = new System.Drawing.Point(80, 288); this.RemarksLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.RemarksLabel.Name = "RemarksLabel"; this.RemarksLabel.Size = new System.Drawing.Size(63, 15); @@ -349,7 +341,7 @@ // NeedPluginArgCheckBox // this.NeedPluginArgCheckBox.AutoSize = true; - this.NeedPluginArgCheckBox.Location = new System.Drawing.Point(151, 231); + this.NeedPluginArgCheckBox.Location = new System.Drawing.Point(151, 226); this.NeedPluginArgCheckBox.Margin = new System.Windows.Forms.Padding(4); this.NeedPluginArgCheckBox.Name = "NeedPluginArgCheckBox"; this.NeedPluginArgCheckBox.Size = new System.Drawing.Size(189, 19); @@ -363,7 +355,7 @@ this.panel2.Anchor = System.Windows.Forms.AnchorStyles.Top; this.panel2.AutoSize = true; this.panel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.panel2.Location = new System.Drawing.Point(239, 234); + this.panel2.Location = new System.Drawing.Point(190, 229); this.panel2.Margin = new System.Windows.Forms.Padding(4); this.panel2.Name = "panel2"; this.panel2.Size = new System.Drawing.Size(0, 0); @@ -372,9 +364,10 @@ // OKButton // this.OKButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.OKButton.Location = new System.Drawing.Point(327, 517); + this.OKButton.Dock = System.Windows.Forms.DockStyle.Fill; + this.OKButton.Location = new System.Drawing.Point(282, 501); this.OKButton.Name = "OKButton"; - this.OKButton.Size = new System.Drawing.Size(100, 29); + this.OKButton.Size = new System.Drawing.Size(87, 29); this.OKButton.TabIndex = 17; this.OKButton.Text = "OK"; this.OKButton.UseVisualStyleBackColor = true; @@ -383,9 +376,10 @@ // MyCancelButton // this.MyCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.MyCancelButton.Location = new System.Drawing.Point(435, 517); + this.MyCancelButton.Dock = System.Windows.Forms.DockStyle.Fill; + this.MyCancelButton.Location = new System.Drawing.Point(375, 501); this.MyCancelButton.Name = "MyCancelButton"; - this.MyCancelButton.Size = new System.Drawing.Size(100, 29); + this.MyCancelButton.Size = new System.Drawing.Size(87, 29); this.MyCancelButton.TabIndex = 18; this.MyCancelButton.Text = "Cancel"; this.MyCancelButton.UseVisualStyleBackColor = true; @@ -393,10 +387,11 @@ // // ApplyButton // + this.ApplyButton.Dock = System.Windows.Forms.DockStyle.Fill; this.ApplyButton.Enabled = false; - this.ApplyButton.Location = new System.Drawing.Point(543, 517); + this.ApplyButton.Location = new System.Drawing.Point(468, 501); this.ApplyButton.Name = "ApplyButton"; - this.ApplyButton.Size = new System.Drawing.Size(100, 29); + this.ApplyButton.Size = new System.Drawing.Size(91, 29); this.ApplyButton.TabIndex = 19; this.ApplyButton.Text = "Apply"; this.ApplyButton.UseVisualStyleBackColor = true; @@ -404,9 +399,10 @@ // // DeleteButton // - this.DeleteButton.Location = new System.Drawing.Point(111, 419); + this.DeleteButton.Dock = System.Windows.Forms.DockStyle.Fill; + this.DeleteButton.Location = new System.Drawing.Point(96, 431); this.DeleteButton.Name = "DeleteButton"; - this.DeleteButton.Size = new System.Drawing.Size(100, 29); + this.DeleteButton.Size = new System.Drawing.Size(87, 29); this.DeleteButton.TabIndex = 13; this.DeleteButton.Text = "&Delete"; this.DeleteButton.UseVisualStyleBackColor = true; @@ -414,9 +410,10 @@ // // AddButton // - this.AddButton.Location = new System.Drawing.Point(3, 419); + this.AddButton.Dock = System.Windows.Forms.DockStyle.Fill; + this.AddButton.Location = new System.Drawing.Point(3, 431); this.AddButton.Name = "AddButton"; - this.AddButton.Size = new System.Drawing.Size(100, 29); + this.AddButton.Size = new System.Drawing.Size(87, 29); this.AddButton.TabIndex = 12; this.AddButton.Text = "&Add"; this.AddButton.UseVisualStyleBackColor = true; @@ -429,11 +426,11 @@ this.tableLayoutPanel7.SetColumnSpan(this.ServerGroupBox, 4); this.ServerGroupBox.Controls.Add(this.tableLayoutPanel1); this.ServerGroupBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.ServerGroupBox.Location = new System.Drawing.Point(231, 0); - this.ServerGroupBox.Margin = new System.Windows.Forms.Padding(15, 0, 0, 0); + this.ServerGroupBox.Location = new System.Drawing.Point(189, 0); + this.ServerGroupBox.Margin = new System.Windows.Forms.Padding(3, 0, 3, 3); this.ServerGroupBox.Name = "ServerGroupBox"; this.ServerGroupBox.Padding = new System.Windows.Forms.Padding(4); - this.ServerGroupBox.Size = new System.Drawing.Size(419, 416); + this.ServerGroupBox.Size = new System.Drawing.Size(370, 425); this.ServerGroupBox.TabIndex = 0; this.ServerGroupBox.TabStop = false; this.ServerGroupBox.Text = "Server"; @@ -445,18 +442,18 @@ this.ServersListBox.FormattingEnabled = true; this.ServersListBox.IntegralHeight = false; this.ServersListBox.ItemHeight = 15; - this.ServersListBox.Location = new System.Drawing.Point(0, 0); - this.ServersListBox.Margin = new System.Windows.Forms.Padding(0); + this.ServersListBox.Location = new System.Drawing.Point(3, 3); this.ServersListBox.Name = "ServersListBox"; - this.ServersListBox.Size = new System.Drawing.Size(216, 416); + this.ServersListBox.Size = new System.Drawing.Size(180, 422); this.ServersListBox.TabIndex = 11; this.ServersListBox.SelectedIndexChanged += new System.EventHandler(this.ServersListBox_SelectedIndexChanged); // // MoveDownButton // - this.MoveDownButton.Location = new System.Drawing.Point(111, 517); + this.MoveDownButton.Dock = System.Windows.Forms.DockStyle.Fill; + this.MoveDownButton.Location = new System.Drawing.Point(96, 501); this.MoveDownButton.Name = "MoveDownButton"; - this.MoveDownButton.Size = new System.Drawing.Size(100, 29); + this.MoveDownButton.Size = new System.Drawing.Size(87, 29); this.MoveDownButton.TabIndex = 16; this.MoveDownButton.Text = "Move D&own"; this.MoveDownButton.UseVisualStyleBackColor = true; @@ -464,9 +461,10 @@ // // MoveUpButton // - this.MoveUpButton.Location = new System.Drawing.Point(3, 517); + this.MoveUpButton.Dock = System.Windows.Forms.DockStyle.Fill; + this.MoveUpButton.Location = new System.Drawing.Point(3, 501); this.MoveUpButton.Name = "MoveUpButton"; - this.MoveUpButton.Size = new System.Drawing.Size(100, 29); + this.MoveUpButton.Size = new System.Drawing.Size(87, 29); this.MoveUpButton.TabIndex = 15; this.MoveUpButton.Text = "Move &Up"; this.MoveUpButton.UseVisualStyleBackColor = true; @@ -474,36 +472,37 @@ // // ProxyPortTextBox // - this.ProxyPortTextBox.Anchor = System.Windows.Forms.AnchorStyles.Left; this.tableLayoutPanel7.SetColumnSpan(this.ProxyPortTextBox, 2); - this.ProxyPortTextBox.Location = new System.Drawing.Point(328, 428); + this.ProxyPortTextBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.ProxyPortTextBox.Location = new System.Drawing.Point(283, 432); this.ProxyPortTextBox.Margin = new System.Windows.Forms.Padding(4); this.ProxyPortTextBox.MaxLength = 10; this.ProxyPortTextBox.Name = "ProxyPortTextBox"; - this.ProxyPortTextBox.Size = new System.Drawing.Size(140, 25); + this.ProxyPortTextBox.Size = new System.Drawing.Size(178, 25); this.ProxyPortTextBox.TabIndex = 10; this.ProxyPortTextBox.WordWrap = false; // // ProxyPortLabel // - this.ProxyPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.ProxyPortLabel.AutoSize = true; - this.ProxyPortLabel.Location = new System.Drawing.Point(233, 433); + this.ProxyPortLabel.Dock = System.Windows.Forms.DockStyle.Fill; + this.ProxyPortLabel.Location = new System.Drawing.Point(190, 428); this.ProxyPortLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.ProxyPortLabel.Name = "ProxyPortLabel"; - this.ProxyPortLabel.Size = new System.Drawing.Size(87, 15); + this.ProxyPortLabel.Size = new System.Drawing.Size(85, 35); this.ProxyPortLabel.TabIndex = 10; this.ProxyPortLabel.Text = "Proxy Port"; + this.ProxyPortLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight; // // PortableModeCheckBox // - this.PortableModeCheckBox.Anchor = System.Windows.Forms.AnchorStyles.Left; this.PortableModeCheckBox.AutoSize = true; this.tableLayoutPanel7.SetColumnSpan(this.PortableModeCheckBox, 2); - this.PortableModeCheckBox.Location = new System.Drawing.Point(220, 480); + this.PortableModeCheckBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.PortableModeCheckBox.Location = new System.Drawing.Point(283, 467); this.PortableModeCheckBox.Margin = new System.Windows.Forms.Padding(4); this.PortableModeCheckBox.Name = "PortableModeCheckBox"; - this.PortableModeCheckBox.Size = new System.Drawing.Size(133, 19); + this.PortableModeCheckBox.Size = new System.Drawing.Size(178, 27); this.PortableModeCheckBox.TabIndex = 11; this.PortableModeCheckBox.Text = "Portable Mode"; this.toolTip1.SetToolTip(this.PortableModeCheckBox, "restart required"); @@ -511,9 +510,10 @@ // // DuplicateButton // - this.DuplicateButton.Location = new System.Drawing.Point(3, 468); + this.DuplicateButton.Dock = System.Windows.Forms.DockStyle.Fill; + this.DuplicateButton.Location = new System.Drawing.Point(3, 466); this.DuplicateButton.Name = "DuplicateButton"; - this.DuplicateButton.Size = new System.Drawing.Size(100, 29); + this.DuplicateButton.Size = new System.Drawing.Size(87, 29); this.DuplicateButton.TabIndex = 14; this.DuplicateButton.Text = "Dupli&cate"; this.DuplicateButton.UseVisualStyleBackColor = true; @@ -531,7 +531,6 @@ this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 16.66667F)); this.tableLayoutPanel7.Controls.Add(this.ApplyButton, 5, 3); this.tableLayoutPanel7.Controls.Add(this.MyCancelButton, 4, 3); - this.tableLayoutPanel7.Controls.Add(this.PortableModeCheckBox, 2, 2); this.tableLayoutPanel7.Controls.Add(this.OKButton, 3, 3); this.tableLayoutPanel7.Controls.Add(this.ProxyPortTextBox, 3, 1); this.tableLayoutPanel7.Controls.Add(this.MoveDownButton, 1, 3); @@ -542,23 +541,24 @@ this.tableLayoutPanel7.Controls.Add(this.DuplicateButton, 0, 2); this.tableLayoutPanel7.Controls.Add(this.ServersListBox, 0, 0); this.tableLayoutPanel7.Controls.Add(this.ServerGroupBox, 2, 0); + this.tableLayoutPanel7.Controls.Add(this.PortableModeCheckBox, 3, 2); this.tableLayoutPanel7.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel7.GrowStyle = System.Windows.Forms.TableLayoutPanelGrowStyle.FixedSize; - this.tableLayoutPanel7.Location = new System.Drawing.Point(15, 15); + this.tableLayoutPanel7.Location = new System.Drawing.Point(10, 10); this.tableLayoutPanel7.Name = "tableLayoutPanel7"; this.tableLayoutPanel7.RowCount = 4; + this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); - this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); - this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); - this.tableLayoutPanel7.Size = new System.Drawing.Size(650, 565); + this.tableLayoutPanel7.Size = new System.Drawing.Size(562, 533); this.tableLayoutPanel7.TabIndex = 8; // // GroupLabel // this.GroupLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.GroupLabel.AutoSize = true; - this.GroupLabel.Location = new System.Drawing.Point(96, 362); + this.GroupLabel.Location = new System.Drawing.Point(96, 350); this.GroupLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.GroupLabel.Name = "GroupLabel"; this.GroupLabel.RightToLeft = System.Windows.Forms.RightToLeft.No; @@ -568,13 +568,12 @@ // // GroupTextBox // - this.GroupTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.GroupTextBox.Location = new System.Drawing.Point(151, 357); - this.GroupTextBox.Margin = new System.Windows.Forms.Padding(4); + this.GroupTextBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.GroupTextBox.Location = new System.Drawing.Point(150, 345); this.GroupTextBox.MaxLength = 5; this.GroupTextBox.Name = "GroupTextBox"; this.GroupTextBox.ReadOnly = true; - this.GroupTextBox.Size = new System.Drawing.Size(252, 25); + this.GroupTextBox.Size = new System.Drawing.Size(205, 25); this.GroupTextBox.TabIndex = 12; // // ConfigForm @@ -582,18 +581,15 @@ this.AcceptButton = this.OKButton; this.AutoScaleDimensions = new System.Drawing.SizeF(120F, 120F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.AutoSize = true; - this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.CancelButton = this.MyCancelButton; - this.ClientSize = new System.Drawing.Size(680, 591); + this.ClientSize = new System.Drawing.Size(582, 553); this.Controls.Add(this.tableLayoutPanel7); this.Controls.Add(this.panel2); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.Margin = new System.Windows.Forms.Padding(4); - this.MaximizeBox = false; this.MinimizeBox = false; + this.MinimumSize = new System.Drawing.Size(400, 575); this.Name = "ConfigForm"; - this.Padding = new System.Windows.Forms.Padding(15, 15, 15, 11); + this.Padding = new System.Windows.Forms.Padding(10); this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "Edit Servers"; this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ConfigForm_FormClosed); diff --git a/shadowsocks-csharp/View/HotkeySettingsForm.designer.cs b/shadowsocks-csharp/View/HotkeySettingsForm.designer.cs index 3d9428ec..47f89946 100644 --- a/shadowsocks-csharp/View/HotkeySettingsForm.designer.cs +++ b/shadowsocks-csharp/View/HotkeySettingsForm.designer.cs @@ -59,7 +59,7 @@ flowLayoutPanel1.Controls.Add(this.btnCancel); flowLayoutPanel1.Controls.Add(this.btnRegisterAll); flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.BottomUp; - flowLayoutPanel1.Location = new System.Drawing.Point(0, 274); + flowLayoutPanel1.Location = new System.Drawing.Point(0, 248); flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); flowLayoutPanel1.Name = "flowLayoutPanel1"; flowLayoutPanel1.Padding = new System.Windows.Forms.Padding(0, 0, 20, 0); @@ -71,7 +71,7 @@ // this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; this.btnOK.Location = new System.Drawing.Point(416, 9); - this.btnOK.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.btnOK.Margin = new System.Windows.Forms.Padding(4); this.btnOK.Name = "btnOK"; this.btnOK.Size = new System.Drawing.Size(154, 39); this.btnOK.TabIndex = 0; @@ -83,7 +83,7 @@ // this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.btnCancel.Location = new System.Drawing.Point(254, 9); - this.btnCancel.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.btnCancel.Margin = new System.Windows.Forms.Padding(4); this.btnCancel.Name = "btnCancel"; this.btnCancel.Size = new System.Drawing.Size(154, 39); this.btnCancel.TabIndex = 1; @@ -95,7 +95,7 @@ // this.btnRegisterAll.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.btnRegisterAll.Location = new System.Drawing.Point(92, 9); - this.btnRegisterAll.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.btnRegisterAll.Margin = new System.Windows.Forms.Padding(4); this.btnRegisterAll.Name = "btnRegisterAll"; this.btnRegisterAll.Size = new System.Drawing.Size(154, 39); this.btnRegisterAll.TabIndex = 2; @@ -125,7 +125,7 @@ this.tableLayoutPanel1.Controls.Add(this.RegHotkeysAtStartupCheckBox, 1, 6); this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); - this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(4); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; this.tableLayoutPanel1.RowCount = 8; this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.16726F)); @@ -138,17 +138,17 @@ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F)); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25F)); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25F)); - this.tableLayoutPanel1.Size = new System.Drawing.Size(614, 326); + this.tableLayoutPanel1.Size = new System.Drawing.Size(582, 303); this.tableLayoutPanel1.TabIndex = 0; // // RegHotkeysAtStartupLabel // this.RegHotkeysAtStartupLabel.AutoSize = true; this.RegHotkeysAtStartupLabel.Dock = System.Windows.Forms.DockStyle.Right; - this.RegHotkeysAtStartupLabel.Location = new System.Drawing.Point(40, 235); + this.RegHotkeysAtStartupLabel.Location = new System.Drawing.Point(40, 213); this.RegHotkeysAtStartupLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); this.RegHotkeysAtStartupLabel.Name = "RegHotkeysAtStartupLabel"; - this.RegHotkeysAtStartupLabel.Size = new System.Drawing.Size(199, 39); + this.RegHotkeysAtStartupLabel.Size = new System.Drawing.Size(199, 35); this.RegHotkeysAtStartupLabel.TabIndex = 16; this.RegHotkeysAtStartupLabel.Text = "Reg Hotkeys At Startup"; this.RegHotkeysAtStartupLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; @@ -160,7 +160,7 @@ this.SwitchSystemProxyLabel.Location = new System.Drawing.Point(63, 0); this.SwitchSystemProxyLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); this.SwitchSystemProxyLabel.Name = "SwitchSystemProxyLabel"; - this.SwitchSystemProxyLabel.Size = new System.Drawing.Size(176, 39); + this.SwitchSystemProxyLabel.Size = new System.Drawing.Size(176, 35); this.SwitchSystemProxyLabel.TabIndex = 0; this.SwitchSystemProxyLabel.Text = "Switch system proxy"; this.SwitchSystemProxyLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; @@ -169,10 +169,10 @@ // this.SwitchProxyModeLabel.AutoSize = true; this.SwitchProxyModeLabel.Dock = System.Windows.Forms.DockStyle.Right; - this.SwitchProxyModeLabel.Location = new System.Drawing.Point(10, 39); + this.SwitchProxyModeLabel.Location = new System.Drawing.Point(10, 35); this.SwitchProxyModeLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); this.SwitchProxyModeLabel.Name = "SwitchProxyModeLabel"; - this.SwitchProxyModeLabel.Size = new System.Drawing.Size(229, 39); + this.SwitchProxyModeLabel.Size = new System.Drawing.Size(229, 35); this.SwitchProxyModeLabel.TabIndex = 1; this.SwitchProxyModeLabel.Text = "Switch system proxy mode"; this.SwitchProxyModeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; @@ -181,10 +181,10 @@ // this.SwitchAllowLanLabel.AutoSize = true; this.SwitchAllowLanLabel.Dock = System.Windows.Forms.DockStyle.Right; - this.SwitchAllowLanLabel.Location = new System.Drawing.Point(39, 78); + this.SwitchAllowLanLabel.Location = new System.Drawing.Point(39, 70); this.SwitchAllowLanLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); this.SwitchAllowLanLabel.Name = "SwitchAllowLanLabel"; - this.SwitchAllowLanLabel.Size = new System.Drawing.Size(200, 39); + this.SwitchAllowLanLabel.Size = new System.Drawing.Size(200, 35); this.SwitchAllowLanLabel.TabIndex = 3; this.SwitchAllowLanLabel.Text = "Allow Clients from LAN"; this.SwitchAllowLanLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; @@ -193,10 +193,10 @@ // this.ShowLogsLabel.AutoSize = true; this.ShowLogsLabel.Dock = System.Windows.Forms.DockStyle.Right; - this.ShowLogsLabel.Location = new System.Drawing.Point(129, 117); + this.ShowLogsLabel.Location = new System.Drawing.Point(129, 105); this.ShowLogsLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); this.ShowLogsLabel.Name = "ShowLogsLabel"; - this.ShowLogsLabel.Size = new System.Drawing.Size(110, 39); + this.ShowLogsLabel.Size = new System.Drawing.Size(110, 35); this.ShowLogsLabel.TabIndex = 4; this.ShowLogsLabel.Text = "Show Logs..."; this.ShowLogsLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; @@ -205,10 +205,10 @@ // this.ServerMoveUpLabel.AutoSize = true; this.ServerMoveUpLabel.Dock = System.Windows.Forms.DockStyle.Right; - this.ServerMoveUpLabel.Location = new System.Drawing.Point(25, 156); + this.ServerMoveUpLabel.Location = new System.Drawing.Point(25, 140); this.ServerMoveUpLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); this.ServerMoveUpLabel.Name = "ServerMoveUpLabel"; - this.ServerMoveUpLabel.Size = new System.Drawing.Size(214, 40); + this.ServerMoveUpLabel.Size = new System.Drawing.Size(214, 37); this.ServerMoveUpLabel.TabIndex = 4; this.ServerMoveUpLabel.Text = "Switch to previous server"; this.ServerMoveUpLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; @@ -217,10 +217,10 @@ // this.ServerMoveDownLabel.AutoSize = true; this.ServerMoveDownLabel.Dock = System.Windows.Forms.DockStyle.Right; - this.ServerMoveDownLabel.Location = new System.Drawing.Point(60, 196); + this.ServerMoveDownLabel.Location = new System.Drawing.Point(60, 177); this.ServerMoveDownLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); this.ServerMoveDownLabel.Name = "ServerMoveDownLabel"; - this.ServerMoveDownLabel.Size = new System.Drawing.Size(179, 39); + this.ServerMoveDownLabel.Size = new System.Drawing.Size(179, 36); this.ServerMoveDownLabel.TabIndex = 4; this.ServerMoveDownLabel.Text = "Switch to next server"; this.ServerMoveDownLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; @@ -228,11 +228,10 @@ // SwitchSystemProxyTextBox // this.SwitchSystemProxyTextBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.SwitchSystemProxyTextBox.Location = new System.Drawing.Point(253, 4); - this.SwitchSystemProxyTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 20, 4); + this.SwitchSystemProxyTextBox.Location = new System.Drawing.Point(252, 3); this.SwitchSystemProxyTextBox.Name = "SwitchSystemProxyTextBox"; this.SwitchSystemProxyTextBox.ReadOnly = true; - this.SwitchSystemProxyTextBox.Size = new System.Drawing.Size(344, 29); + this.SwitchSystemProxyTextBox.Size = new System.Drawing.Size(339, 29); this.SwitchSystemProxyTextBox.TabIndex = 7; this.SwitchSystemProxyTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); this.SwitchSystemProxyTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); @@ -240,11 +239,10 @@ // SwitchProxyModeTextBox // this.SwitchProxyModeTextBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.SwitchProxyModeTextBox.Location = new System.Drawing.Point(253, 43); - this.SwitchProxyModeTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 20, 4); + this.SwitchProxyModeTextBox.Location = new System.Drawing.Point(252, 38); this.SwitchProxyModeTextBox.Name = "SwitchProxyModeTextBox"; this.SwitchProxyModeTextBox.ReadOnly = true; - this.SwitchProxyModeTextBox.Size = new System.Drawing.Size(344, 29); + this.SwitchProxyModeTextBox.Size = new System.Drawing.Size(339, 29); this.SwitchProxyModeTextBox.TabIndex = 8; this.SwitchProxyModeTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); this.SwitchProxyModeTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); @@ -252,11 +250,10 @@ // SwitchAllowLanTextBox // this.SwitchAllowLanTextBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.SwitchAllowLanTextBox.Location = new System.Drawing.Point(253, 82); - this.SwitchAllowLanTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 20, 4); + this.SwitchAllowLanTextBox.Location = new System.Drawing.Point(252, 73); this.SwitchAllowLanTextBox.Name = "SwitchAllowLanTextBox"; this.SwitchAllowLanTextBox.ReadOnly = true; - this.SwitchAllowLanTextBox.Size = new System.Drawing.Size(344, 29); + this.SwitchAllowLanTextBox.Size = new System.Drawing.Size(339, 29); this.SwitchAllowLanTextBox.TabIndex = 10; this.SwitchAllowLanTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); this.SwitchAllowLanTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); @@ -264,11 +261,10 @@ // ShowLogsTextBox // this.ShowLogsTextBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.ShowLogsTextBox.Location = new System.Drawing.Point(253, 121); - this.ShowLogsTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 20, 4); + this.ShowLogsTextBox.Location = new System.Drawing.Point(252, 108); this.ShowLogsTextBox.Name = "ShowLogsTextBox"; this.ShowLogsTextBox.ReadOnly = true; - this.ShowLogsTextBox.Size = new System.Drawing.Size(344, 29); + this.ShowLogsTextBox.Size = new System.Drawing.Size(339, 29); this.ShowLogsTextBox.TabIndex = 11; this.ShowLogsTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); this.ShowLogsTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); @@ -276,11 +272,10 @@ // ServerMoveUpTextBox // this.ServerMoveUpTextBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.ServerMoveUpTextBox.Location = new System.Drawing.Point(253, 160); - this.ServerMoveUpTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 20, 4); + this.ServerMoveUpTextBox.Location = new System.Drawing.Point(252, 143); this.ServerMoveUpTextBox.Name = "ServerMoveUpTextBox"; this.ServerMoveUpTextBox.ReadOnly = true; - this.ServerMoveUpTextBox.Size = new System.Drawing.Size(344, 29); + this.ServerMoveUpTextBox.Size = new System.Drawing.Size(339, 29); this.ServerMoveUpTextBox.TabIndex = 12; this.ServerMoveUpTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); this.ServerMoveUpTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); @@ -288,11 +283,10 @@ // ServerMoveDownTextBox // this.ServerMoveDownTextBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.ServerMoveDownTextBox.Location = new System.Drawing.Point(253, 200); - this.ServerMoveDownTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 20, 4); + this.ServerMoveDownTextBox.Location = new System.Drawing.Point(252, 180); this.ServerMoveDownTextBox.Name = "ServerMoveDownTextBox"; this.ServerMoveDownTextBox.ReadOnly = true; - this.ServerMoveDownTextBox.Size = new System.Drawing.Size(344, 29); + this.ServerMoveDownTextBox.Size = new System.Drawing.Size(339, 29); this.ServerMoveDownTextBox.TabIndex = 13; this.ServerMoveDownTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); this.ServerMoveDownTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); @@ -300,10 +294,10 @@ // RegHotkeysAtStartupCheckBox // this.RegHotkeysAtStartupCheckBox.AutoSize = true; - this.RegHotkeysAtStartupCheckBox.Location = new System.Drawing.Point(253, 246); - this.RegHotkeysAtStartupCheckBox.Margin = new System.Windows.Forms.Padding(4, 11, 11, 11); + this.RegHotkeysAtStartupCheckBox.Dock = System.Windows.Forms.DockStyle.Left; + this.RegHotkeysAtStartupCheckBox.Location = new System.Drawing.Point(252, 216); this.RegHotkeysAtStartupCheckBox.Name = "RegHotkeysAtStartupCheckBox"; - this.RegHotkeysAtStartupCheckBox.Size = new System.Drawing.Size(18, 17); + this.RegHotkeysAtStartupCheckBox.Size = new System.Drawing.Size(18, 29); this.RegHotkeysAtStartupCheckBox.TabIndex = 17; this.RegHotkeysAtStartupCheckBox.UseVisualStyleBackColor = true; // @@ -311,9 +305,10 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(120F, 120F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.ClientSize = new System.Drawing.Size(614, 326); + this.ClientSize = new System.Drawing.Size(582, 303); this.Controls.Add(this.tableLayoutPanel1); this.Font = new System.Drawing.Font("微软雅黑", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.Margin = new System.Windows.Forms.Padding(5, 6, 5, 6); this.MaximizeBox = false; this.MinimizeBox = false; diff --git a/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs b/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs index d535b523..2d318ac5 100644 --- a/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs @@ -59,12 +59,13 @@ this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(3); this.tableLayoutPanel1.RowCount = 4; this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.Size = new System.Drawing.Size(488, 465); + this.tableLayoutPanel1.Size = new System.Drawing.Size(482, 453); this.tableLayoutPanel1.TabIndex = 0; // // UrlListBox @@ -73,9 +74,10 @@ this.UrlListBox.Dock = System.Windows.Forms.DockStyle.Fill; this.UrlListBox.FormattingEnabled = true; this.UrlListBox.ItemHeight = 15; - this.UrlListBox.Location = new System.Drawing.Point(3, 3); + this.UrlListBox.Location = new System.Drawing.Point(13, 13); + this.UrlListBox.Margin = new System.Windows.Forms.Padding(10); this.UrlListBox.Name = "UrlListBox"; - this.UrlListBox.Size = new System.Drawing.Size(482, 344); + this.UrlListBox.Size = new System.Drawing.Size(456, 334); this.UrlListBox.TabIndex = 0; this.UrlListBox.SelectedIndexChanged += new System.EventHandler(this.UrlListBox_SelectedIndexChanged); // @@ -83,31 +85,32 @@ // this.label1.AutoSize = true; this.label1.Dock = System.Windows.Forms.DockStyle.Fill; - this.label1.Location = new System.Drawing.Point(3, 350); + this.label1.Location = new System.Drawing.Point(6, 357); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(156, 31); + this.label1.Size = new System.Drawing.Size(152, 31); this.label1.TabIndex = 1; this.label1.Text = "Online config URL"; - this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight; // // UrlTextBox // this.tableLayoutPanel1.SetColumnSpan(this.UrlTextBox, 2); this.UrlTextBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.UrlTextBox.Location = new System.Drawing.Point(165, 353); + this.UrlTextBox.Location = new System.Drawing.Point(164, 360); + this.UrlTextBox.Margin = new System.Windows.Forms.Padding(3, 3, 15, 3); this.UrlTextBox.Name = "UrlTextBox"; - this.UrlTextBox.Size = new System.Drawing.Size(320, 25); + this.UrlTextBox.Size = new System.Drawing.Size(300, 25); this.UrlTextBox.TabIndex = 2; // // UpdateButton // this.UpdateButton.Dock = System.Windows.Forms.DockStyle.Fill; - this.UpdateButton.Location = new System.Drawing.Point(20, 386); - this.UpdateButton.Margin = new System.Windows.Forms.Padding(20, 5, 20, 5); - this.UpdateButton.MaximumSize = new System.Drawing.Size(0, 32); - this.UpdateButton.MinimumSize = new System.Drawing.Size(0, 32); + this.UpdateButton.Location = new System.Drawing.Point(23, 391); + this.UpdateButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); + this.UpdateButton.MaximumSize = new System.Drawing.Size(0, 25); + this.UpdateButton.MinimumSize = new System.Drawing.Size(0, 25); this.UpdateButton.Name = "UpdateButton"; - this.UpdateButton.Size = new System.Drawing.Size(122, 32); + this.UpdateButton.Size = new System.Drawing.Size(118, 25); this.UpdateButton.TabIndex = 3; this.UpdateButton.Text = "Update"; this.UpdateButton.UseVisualStyleBackColor = true; @@ -116,12 +119,12 @@ // AddButton // this.AddButton.Dock = System.Windows.Forms.DockStyle.Fill; - this.AddButton.Location = new System.Drawing.Point(182, 386); - this.AddButton.Margin = new System.Windows.Forms.Padding(20, 5, 20, 5); - this.AddButton.MaximumSize = new System.Drawing.Size(0, 32); - this.AddButton.MinimumSize = new System.Drawing.Size(0, 32); + this.AddButton.Location = new System.Drawing.Point(181, 391); + this.AddButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); + this.AddButton.MaximumSize = new System.Drawing.Size(0, 25); + this.AddButton.MinimumSize = new System.Drawing.Size(0, 25); this.AddButton.Name = "AddButton"; - this.AddButton.Size = new System.Drawing.Size(122, 32); + this.AddButton.Size = new System.Drawing.Size(118, 25); this.AddButton.TabIndex = 4; this.AddButton.Text = "Add"; this.AddButton.UseVisualStyleBackColor = true; @@ -130,12 +133,12 @@ // DeleteButton // this.DeleteButton.Dock = System.Windows.Forms.DockStyle.Fill; - this.DeleteButton.Location = new System.Drawing.Point(344, 386); - this.DeleteButton.Margin = new System.Windows.Forms.Padding(20, 5, 20, 5); - this.DeleteButton.MaximumSize = new System.Drawing.Size(0, 32); - this.DeleteButton.MinimumSize = new System.Drawing.Size(0, 32); + this.DeleteButton.Location = new System.Drawing.Point(339, 391); + this.DeleteButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); + this.DeleteButton.MaximumSize = new System.Drawing.Size(0, 25); + this.DeleteButton.MinimumSize = new System.Drawing.Size(0, 25); this.DeleteButton.Name = "DeleteButton"; - this.DeleteButton.Size = new System.Drawing.Size(124, 32); + this.DeleteButton.Size = new System.Drawing.Size(120, 25); this.DeleteButton.TabIndex = 5; this.DeleteButton.Text = "Delete"; this.DeleteButton.UseVisualStyleBackColor = true; @@ -144,12 +147,12 @@ // OkButton // this.OkButton.Dock = System.Windows.Forms.DockStyle.Fill; - this.OkButton.Location = new System.Drawing.Point(182, 428); - this.OkButton.Margin = new System.Windows.Forms.Padding(20, 5, 20, 5); - this.OkButton.MaximumSize = new System.Drawing.Size(0, 32); - this.OkButton.MinimumSize = new System.Drawing.Size(0, 32); + this.OkButton.Location = new System.Drawing.Point(181, 422); + this.OkButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); + this.OkButton.MaximumSize = new System.Drawing.Size(0, 25); + this.OkButton.MinimumSize = new System.Drawing.Size(0, 25); this.OkButton.Name = "OkButton"; - this.OkButton.Size = new System.Drawing.Size(122, 32); + this.OkButton.Size = new System.Drawing.Size(118, 25); this.OkButton.TabIndex = 7; this.OkButton.Text = "OK"; this.OkButton.UseVisualStyleBackColor = true; @@ -158,12 +161,12 @@ // UpdateAllButton // this.UpdateAllButton.Dock = System.Windows.Forms.DockStyle.Fill; - this.UpdateAllButton.Location = new System.Drawing.Point(20, 428); - this.UpdateAllButton.Margin = new System.Windows.Forms.Padding(20, 5, 20, 5); - this.UpdateAllButton.MaximumSize = new System.Drawing.Size(0, 32); - this.UpdateAllButton.MinimumSize = new System.Drawing.Size(0, 32); + this.UpdateAllButton.Location = new System.Drawing.Point(23, 422); + this.UpdateAllButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); + this.UpdateAllButton.MaximumSize = new System.Drawing.Size(0, 25); + this.UpdateAllButton.MinimumSize = new System.Drawing.Size(0, 25); this.UpdateAllButton.Name = "UpdateAllButton"; - this.UpdateAllButton.Size = new System.Drawing.Size(122, 32); + this.UpdateAllButton.Size = new System.Drawing.Size(118, 25); this.UpdateAllButton.TabIndex = 6; this.UpdateAllButton.Text = "Update all"; this.UpdateAllButton.UseVisualStyleBackColor = true; @@ -172,12 +175,12 @@ // CancelButton // this.CancelButton.Dock = System.Windows.Forms.DockStyle.Fill; - this.CancelButton.Location = new System.Drawing.Point(344, 428); - this.CancelButton.Margin = new System.Windows.Forms.Padding(20, 5, 20, 5); - this.CancelButton.MaximumSize = new System.Drawing.Size(0, 32); - this.CancelButton.MinimumSize = new System.Drawing.Size(0, 32); + this.CancelButton.Location = new System.Drawing.Point(339, 422); + this.CancelButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); + this.CancelButton.MaximumSize = new System.Drawing.Size(0, 25); + this.CancelButton.MinimumSize = new System.Drawing.Size(0, 25); this.CancelButton.Name = "CancelButton"; - this.CancelButton.Size = new System.Drawing.Size(124, 32); + this.CancelButton.Size = new System.Drawing.Size(120, 25); this.CancelButton.TabIndex = 8; this.CancelButton.Text = "Cancel"; this.CancelButton.UseVisualStyleBackColor = true; @@ -187,8 +190,10 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(488, 465); + this.ClientSize = new System.Drawing.Size(482, 453); this.Controls.Add(this.tableLayoutPanel1); + this.MinimizeBox = false; + this.MinimumSize = new System.Drawing.Size(400, 400); this.Name = "OnlineConfigForm"; this.Text = "Online config"; this.tableLayoutPanel1.ResumeLayout(false); From 6889e9ba7e8eec614e23a1d6aaace01ac2695d6d Mon Sep 17 00:00:00 2001 From: database64128 Date: Thu, 10 Sep 2020 14:44:58 +0800 Subject: [PATCH 09/35] =?UTF-8?q?=F0=9F=A7=B9=20Cleanup=20and=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Deserialize the configuration using a constructor to set default values and initialize objects - Re-enable the UI when online config update failed --- shadowsocks-csharp/Model/Configuration.cs | 91 +++++++++++---------- shadowsocks-csharp/View/OnlineConfigForm.cs | 6 +- 2 files changed, 52 insertions(+), 45 deletions(-) diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index f4d9e35c..60df5410 100644 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -21,7 +21,6 @@ namespace Shadowsocks.Model public List onlineConfigSource; - // when strategy is set, index is ignored public string strategy; public int index; @@ -30,30 +29,69 @@ namespace Shadowsocks.Model public bool shareOverLan; public bool isDefault; public int localPort; - public bool portableMode = true; + public bool portableMode; public bool showPluginOutput; public string pacUrl; public bool useOnlinePac; - public bool secureLocalPac = true; + public bool secureLocalPac; public bool availabilityStatistics; public bool autoCheckUpdate; public bool checkPreRelease; public bool isVerboseLogging; // hidden options - public bool isIPv6Enabled = false; // for experimental ipv6 support + public bool isIPv6Enabled; // for experimental ipv6 support public bool generateLegacyUrl = false; // for pre-sip002 url compatibility public string geositeUrl; // for custom geosite source (and rule group) - public string geositeGroup = "geolocation-!cn"; - public bool geositeBlacklistMode = true; - + public string geositeGroup; + public bool geositeBlacklistMode; //public NLogConfig.LogLevel logLevel; public LogViewerConfig logViewer; public ProxyConfig proxy; public HotkeyConfig hotkey; + [JsonIgnore] + public bool updated; + + public Configuration() + { + version = UpdateChecker.Version; + strategy = ""; + index = 0; + global = false; + enabled = false; + shareOverLan = false; + isDefault = true; + localPort = 1080; + portableMode = true; + showPluginOutput = false; + pacUrl = ""; + useOnlinePac = false; + secureLocalPac = true; + availabilityStatistics = false; + autoCheckUpdate = false; + checkPreRelease = false; + isVerboseLogging = false; + + // hidden options + isIPv6Enabled = false; + generateLegacyUrl = false; + geositeUrl = ""; + geositeGroup = "geolocation-!cn"; + geositeBlacklistMode = true; + + logViewer = new LogViewerConfig(); + proxy = new ProxyConfig(); + hotkey = new HotkeyConfig(); + + updated = false; + + configs = new List(); + onlineConfigSource = new List(); + } + [JsonIgnore] NLogConfig nLogConfig; @@ -64,10 +102,6 @@ namespace Shadowsocks.Model private static readonly NLogConfig.LogLevel verboseLogLevel = NLogConfig.LogLevel.Debug; #endif - - [JsonIgnore] - public bool updated = false; - [JsonIgnore] public string localHost => GetLocalHost(); private string GetLocalHost() @@ -90,7 +124,6 @@ namespace Shadowsocks.Model localPort) : null; - public static void CheckServer(Server server) { CheckServer(server.server); @@ -125,23 +158,10 @@ namespace Shadowsocks.Model config.updated = true; } - if (config.configs == null) - config.configs = new List(); - if (config.onlineConfigSource == null) - config.onlineConfigSource = new List(); - if (config.configs.Count == 0) config.configs.Add(GetDefaultServer()); - if (config.localPort == 0) - config.localPort = 1080; - if (config.index == -1 && config.strategy == null) + if (config.index == -1 && string.IsNullOrEmpty(config.strategy)) config.index = 0; - if (config.logViewer == null) - config.logViewer = new LogViewerConfig(); - if (config.proxy == null) - config.proxy = new ProxyConfig(); - if (config.hotkey == null) - config.hotkey = new HotkeyConfig(); if (!System.Net.Sockets.Socket.OSSupportsIPv6) { config.isIPv6Enabled = false; // disable IPv6 if os not support @@ -154,20 +174,8 @@ namespace Shadowsocks.Model { if (!(e is FileNotFoundException)) logger.LogUsefulException(e); - config = new Configuration - { - index = 0, - isDefault = true, - localPort = 1080, - autoCheckUpdate = true, - configs = new List() - { - GetDefaultServer() - }, - logViewer = new LogViewerConfig(), - proxy = new ProxyConfig(), - hotkey = new HotkeyConfig(), - }; + config = new Configuration(); + config.configs.Add(GetDefaultServer()); } try @@ -199,12 +207,11 @@ namespace Shadowsocks.Model public static void Save(Configuration config) { config.configs = SortByOnlineConfig(config.configs); - config.version = UpdateChecker.Version; if (config.index >= config.configs.Count) config.index = config.configs.Count - 1; if (config.index < -1) config.index = -1; - if (config.index == -1 && config.strategy == null) + if (config.index == -1 && string.IsNullOrEmpty(config.strategy)) config.index = 0; config.isDefault = false; try diff --git a/shadowsocks-csharp/View/OnlineConfigForm.cs b/shadowsocks-csharp/View/OnlineConfigForm.cs index ab69546d..fca0ed57 100644 --- a/shadowsocks-csharp/View/OnlineConfigForm.cs +++ b/shadowsocks-csharp/View/OnlineConfigForm.cs @@ -82,11 +82,10 @@ namespace Shadowsocks.View private void AddButton_Click(object sender, EventArgs e) { if (string.IsNullOrWhiteSpace(UrlTextBox.Text)) return; - Commit(); - // string txt = UrlTextBox.Text; - UrlListBox.Items.Add(""); + UrlListBox.Items.Add(UrlTextBox.Text); UrlListBox.SelectedIndex = UrlListBox.Items.Count - 1; UrlTextBox.Text = ""; + Commit(); } private async void UpdateButton_Click(object sender, EventArgs e) @@ -101,6 +100,7 @@ namespace Shadowsocks.View if (!ok) { MessageBox.Show(I18N.GetString("online config failed to update")); + tableLayoutPanel1.Enabled = true; return; } if (old != current) controller.RemoveOnlineConfig(old); From 2fc5ac24bd3c926145433d1143ff84c442a19bdd Mon Sep 17 00:00:00 2001 From: database64128 Date: Mon, 14 Sep 2020 02:36:34 +0800 Subject: [PATCH 10/35] =?UTF-8?q?=F0=9F=94=A0=20Update=20translations=20fo?= =?UTF-8?q?r=20SIP008?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shadowsocks-csharp/Data/i18n.csv | 8 ++++++++ shadowsocks-csharp/View/OnlineConfigForm.Designer.cs | 8 ++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/shadowsocks-csharp/Data/i18n.csv b/shadowsocks-csharp/Data/i18n.csv index 6b345149..bc9c1f95 100644 --- a/shadowsocks-csharp/Data/i18n.csv +++ b/shadowsocks-csharp/Data/i18n.csv @@ -17,6 +17,7 @@ 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:// 링크 연결, Forward Proxy...,Прямой прокси…,正向代理设置...,正向 Proxy 設定...,フォワードプロキシの設定...,포워드 프록시,Forward-proxy… @@ -79,6 +80,13 @@ 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}" ,,,,,, +# Online Config Form,,,,,, +,,,,,, +Online config,,在线配置,線上配置,,, +Online config URL,,在线配置链接,線上配置鏈接,,, +&Update,,更新,更新,,, +U&pdate All,,全部更新,全部更新,,, +,,,,,, #Statistics Config,,,,,, ,,,,,, Enable Statistics,Включить сбор статистики,启用统计,,統計を有効にする,통계 활성화,Activer statistiques diff --git a/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs b/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs index 2d318ac5..d9787dde 100644 --- a/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs @@ -112,7 +112,7 @@ this.UpdateButton.Name = "UpdateButton"; this.UpdateButton.Size = new System.Drawing.Size(118, 25); this.UpdateButton.TabIndex = 3; - this.UpdateButton.Text = "Update"; + this.UpdateButton.Text = "&Update"; this.UpdateButton.UseVisualStyleBackColor = true; this.UpdateButton.Click += new System.EventHandler(this.UpdateButton_Click); // @@ -126,7 +126,7 @@ this.AddButton.Name = "AddButton"; this.AddButton.Size = new System.Drawing.Size(118, 25); this.AddButton.TabIndex = 4; - this.AddButton.Text = "Add"; + this.AddButton.Text = "&Add"; this.AddButton.UseVisualStyleBackColor = true; this.AddButton.Click += new System.EventHandler(this.AddButton_Click); // @@ -140,7 +140,7 @@ this.DeleteButton.Name = "DeleteButton"; this.DeleteButton.Size = new System.Drawing.Size(120, 25); this.DeleteButton.TabIndex = 5; - this.DeleteButton.Text = "Delete"; + this.DeleteButton.Text = "&Delete"; this.DeleteButton.UseVisualStyleBackColor = true; this.DeleteButton.Click += new System.EventHandler(this.DeleteButton_Click); // @@ -168,7 +168,7 @@ this.UpdateAllButton.Name = "UpdateAllButton"; this.UpdateAllButton.Size = new System.Drawing.Size(118, 25); this.UpdateAllButton.TabIndex = 6; - this.UpdateAllButton.Text = "Update all"; + this.UpdateAllButton.Text = "U&pdate All"; this.UpdateAllButton.UseVisualStyleBackColor = true; this.UpdateAllButton.Click += new System.EventHandler(this.UpdateAllButton_Click); // From 43581630f0beccd8842ee5b126c5526acfe7bd63 Mon Sep 17 00:00:00 2001 From: database64128 Date: Mon, 14 Sep 2020 02:40:28 +0800 Subject: [PATCH 11/35] =?UTF-8?q?=E2=9E=96=20Use=20HttpClient.Timeout=20fo?= =?UTF-8?q?r=20a=2015-second=20timeout?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs b/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs index 89ff2565..eacd170e 100644 --- a/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs +++ b/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs @@ -20,13 +20,13 @@ namespace Shadowsocks.Controller.Service { var httpClientHandler = new HttpClientHandler(); var httpClient = new HttpClient(httpClientHandler); + httpClient.Timeout = TimeSpan.FromSeconds(15); if (proxy != null) { httpClientHandler.Proxy = proxy; } - _ = Task.Delay(2000).ContinueWith(_ => httpClient.CancelPendingRequests()); string str = await httpClient.GetStringAsync(url); var ret = Get(str); From d19c5db77ed76d07172ae0ab1fc4b37919c7d064 Mon Sep 17 00:00:00 2001 From: database64128 Date: Fri, 18 Sep 2020 20:19:33 +0800 Subject: [PATCH 12/35] =?UTF-8?q?=F0=9F=94=84=20Retrieve=20server=20group?= =?UTF-8?q?=20from=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shadowsocks-csharp/View/ConfigForm.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index 846a89a9..dad4c535 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -203,6 +203,7 @@ namespace Shadowsocks.View plugin_args = PluginArgumentsTextBox.Text, remarks = RemarksTextBox.Text, timeout = timeout.Value, + group = GroupTextBox.Text }; return true; From 90d90f7cebfe7e07e077d061ef02f61316b001a6 Mon Sep 17 00:00:00 2001 From: Student Main Date: Mon, 21 Sep 2020 13:35:13 +0800 Subject: [PATCH 13/35] Simple cleanup proposed by Stzx --- .../Service/OnlineConfigResolver.cs | 87 +++++++++---------- 1 file changed, 41 insertions(+), 46 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs b/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs index eacd170e..ee48fdf5 100644 --- a/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs +++ b/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs @@ -3,83 +3,78 @@ using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; -using System.Text; using System.Threading.Tasks; -using NLog; -using Shadowsocks.Model; -using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using Shadowsocks.Model; namespace Shadowsocks.Controller.Service { public class OnlineConfigResolver { - private static Logger logger = LogManager.GetCurrentClassLogger(); - public static async Task> GetOnline(string url, IWebProxy proxy = null) { - var httpClientHandler = new HttpClientHandler(); - var httpClient = new HttpClient(httpClientHandler); - httpClient.Timeout = TimeSpan.FromSeconds(15); - - if (proxy != null) + var httpClientHandler = new HttpClientHandler() { - httpClientHandler.Proxy = proxy; - } + Proxy = proxy + }; + var httpClient = new HttpClient(httpClientHandler) + { + Timeout = TimeSpan.FromSeconds(15) + }; + + string server_json = await httpClient.GetStringAsync(url); - string str = await httpClient.GetStringAsync(url); + var servers = server_json.GetServers(); - var ret = Get(str); - foreach (var item in ret) + foreach (var server in servers) { - item.group = url; + server.group = url; } - return ret; - } - public static List Get(string json) - { - var t = JToken.Parse(json); - return SearchJToken(t).ToList(); + return servers.ToList(); } + } - private static IEnumerable SearchJArray(JArray a) - { - if (a == null) return Array.Empty(); - return a.SelectMany(SearchJToken).ToList(); - } + internal static class OnlineConfigResolverEx + { + private static readonly string[] BASIC_FORMAT = new[] { "server", "server_port", "password", "method" }; + + private static readonly IEnumerable EMPTY_SERVERS = Array.Empty(); + + internal static IEnumerable GetServers(this string json) => + JToken.Parse(json).SearchJToken().AsEnumerable(); - private static IEnumerable SearchJObject(JObject o) + private static IEnumerable SearchJArray(JArray array) => + array == null ? EMPTY_SERVERS : array.SelectMany(SearchJToken).ToList(); + + private static IEnumerable SearchJObject(JObject obj) { - var l = new List(); - if (o == null) return l; - if (IsServerObject(o)) - return new List { o.ToObject() }; + if (obj == null) + return EMPTY_SERVERS; + + if (BASIC_FORMAT.All(field => obj.ContainsKey(field))) + return new[] { obj.ToObject() }; - foreach (var kv in o) + var servers = new List(); + foreach (var kv in obj) { - JToken v = kv.Value; - l.AddRange(SearchJToken(v)); + var token = kv.Value; + servers.AddRange(SearchJToken(token)); } - return l; + return servers; } - private static IEnumerable SearchJToken(JToken t) + private static IEnumerable SearchJToken(this JToken token) { - switch (t.Type) + switch (token.Type) { default: return Array.Empty(); case JTokenType.Object: - return SearchJObject(t as JObject); + return SearchJObject(token as JObject); case JTokenType.Array: - return SearchJArray(t as JArray); + return SearchJArray(token as JArray); } } - - private static bool IsServerObject(JObject o) - { - return new[] { "server", "server_port", "password", "method" }.All(i => o.ContainsKey(i)); - } } } From 2002c29ee3a11a9ad060a21f6fedd57991ab9d26 Mon Sep 17 00:00:00 2001 From: database64128 Date: Sun, 11 Oct 2020 13:42:28 +0800 Subject: [PATCH 14/35] =?UTF-8?q?=F0=9F=93=83=20Exclude=20@cn=20from=20PAC?= =?UTF-8?q?=20proxied=20list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PAC proxied list only contains domain names from geolocation-!cn without a `cn` attribute --- .../Controller/Service/GeositeUpdater.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/GeositeUpdater.cs b/shadowsocks-csharp/Controller/Service/GeositeUpdater.cs index 8ec815d6..f076df96 100644 --- a/shadowsocks-csharp/Controller/Service/GeositeUpdater.cs +++ b/shadowsocks-csharp/Controller/Service/GeositeUpdater.cs @@ -39,15 +39,18 @@ namespace Shadowsocks.Controller private static HttpClient httpClient; private static readonly string GEOSITE_URL = "https://github.com/v2fly/domain-list-community/raw/release/dlc.dat"; private static readonly string GEOSITE_SHA256SUM_URL = "https://github.com/v2fly/domain-list-community/raw/release/dlc.dat.sha256sum"; + private static readonly DomainObject.Types.Attribute geositeExcludeAttribute; private static byte[] geositeDB; public static readonly Dictionary> Geosites = new Dictionary>(); static GeositeUpdater() { - //socketsHttpHandler = new SocketsHttpHandler(); - //httpClient = new HttpClient(socketsHttpHandler); - + geositeExcludeAttribute = new DomainObject.Types.Attribute + { + Key = "cn", + BoolValue = true + }; if (File.Exists(DATABASE_PATH) && new FileInfo(DATABASE_PATH).Length > 0) { geositeDB = File.ReadAllBytes(DATABASE_PATH); @@ -241,6 +244,9 @@ var __RULES__ = {JsonConvert.SerializeObject(gfwLines, Formatting.Indented)}; List ret = new List(domains.Count + 100);// 100 overhead foreach (var d in domains) { + if (d.Attribute.Contains(geositeExcludeAttribute)) + continue; + string domain = d.Value; switch (d.Type) From f34d039df705e82f188a6b8934dd970a8b99d731 Mon Sep 17 00:00:00 2001 From: database64128 Date: Sat, 19 Sep 2020 03:23:15 +0800 Subject: [PATCH 15/35] =?UTF-8?q?=F0=9F=8F=97=20Add=20ReactiveUI.WPF=20as?= =?UTF-8?q?=20MVVM=20framework?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shadowsocks-csharp/packages.config | 9 ++++++- shadowsocks-csharp/shadowsocks-csharp.csproj | 28 +++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/shadowsocks-csharp/packages.config b/shadowsocks-csharp/packages.config index 008d3c40..a888c1a9 100644 --- a/shadowsocks-csharp/packages.config +++ b/shadowsocks-csharp/packages.config @@ -3,22 +3,29 @@ + + + + + - + + + \ No newline at end of file diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index a8d99a26..1f9e1655 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -77,6 +77,9 @@ ..\packages\Costura.Fody.3.3.3\lib\net40\Costura.dll + + ..\packages\DynamicData.6.16.6\lib\net461\DynamicData.dll + ..\packages\GlobalHotKey.1.1.0\lib\GlobalHotKey.dll @@ -92,6 +95,16 @@ ..\packages\NLog.4.6.8\lib\net45\NLog.dll + + + ..\packages\ReactiveUI.11.5.35\lib\net461\ReactiveUI.dll + + + ..\packages\ReactiveUI.WPF.11.5.35\lib\net472\ReactiveUI.WPF.dll + + + ..\packages\Splat.9.5.20\lib\net461\Splat.dll + ..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll @@ -121,13 +134,16 @@ ..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll + + ..\packages\System.Reactive.4.4.1\lib\net46\System.Reactive.dll + ..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll True True - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll @@ -151,12 +167,22 @@ True + + ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + ..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll + + + + + ..\packages\ZXing.Net.0.16.5\lib\net47\zxing.dll From 3aaff9cc7ec158e366d2074eeb97b0f98a62d50b Mon Sep 17 00:00:00 2001 From: database64128 Date: Sat, 19 Sep 2020 03:26:43 +0800 Subject: [PATCH 16/35] =?UTF-8?q?=F0=9F=91=81=20ServerSharingView=20&=20Se?= =?UTF-8?q?rverSharingViewModel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use ElementHost in QRCodeForm - Cleanup: Server.Equals --- shadowsocks-csharp/Model/Server.cs | 6 +- .../View/QRCodeForm.Designer.cs | 66 +++-------- shadowsocks-csharp/View/QRCodeForm.cs | 55 --------- .../ViewModels/ServerSharingViewModel.cs | 109 ++++++++++++++++++ .../Views/ServerSharingView.xaml | 36 ++++++ .../Views/ServerSharingView.xaml.cs | 24 ++++ shadowsocks-csharp/shadowsocks-csharp.csproj | 10 ++ 7 files changed, 196 insertions(+), 110 deletions(-) create mode 100644 shadowsocks-csharp/ViewModels/ServerSharingViewModel.cs create mode 100644 shadowsocks-csharp/Views/ServerSharingView.xaml create mode 100644 shadowsocks-csharp/Views/ServerSharingView.xaml.cs diff --git a/shadowsocks-csharp/Model/Server.cs b/shadowsocks-csharp/Model/Server.cs index daa26395..fe0e3c04 100755 --- a/shadowsocks-csharp/Model/Server.cs +++ b/shadowsocks-csharp/Model/Server.cs @@ -58,11 +58,7 @@ namespace Shadowsocks.Model return server.GetHashCode() ^ server_port; } - public override bool Equals(object obj) - { - Server o2 = (Server)obj; - return server == o2.server && server_port == o2.server_port; - } + public override bool Equals(object obj) => obj is Server o2 && server == o2.server && server_port == o2.server_port; public override string ToString() { diff --git a/shadowsocks-csharp/View/QRCodeForm.Designer.cs b/shadowsocks-csharp/View/QRCodeForm.Designer.cs index 0dbc2da3..7e83616a 100755 --- a/shadowsocks-csharp/View/QRCodeForm.Designer.cs +++ b/shadowsocks-csharp/View/QRCodeForm.Designer.cs @@ -28,73 +28,39 @@ /// private void InitializeComponent() { - this.pictureBox1 = new System.Windows.Forms.PictureBox(); - this.listBox1 = new System.Windows.Forms.ListBox(); - this.textBoxURL = new System.Windows.Forms.TextBox(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.elementHost1 = new System.Windows.Forms.Integration.ElementHost(); + this.serverSharingView1 = new Shadowsocks.Views.ServerSharingView(); this.SuspendLayout(); // - // pictureBox1 + // elementHost1 // - this.pictureBox1.Location = new System.Drawing.Point(10, 10); - this.pictureBox1.Margin = new System.Windows.Forms.Padding(0); - this.pictureBox1.Name = "pictureBox1"; - this.pictureBox1.Size = new System.Drawing.Size(210, 210); - this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; - this.pictureBox1.TabIndex = 1; - this.pictureBox1.TabStop = false; - // - // listBox1 - // - this.listBox1.DisplayMember = "Value"; - this.listBox1.FormattingEnabled = true; - this.listBox1.ItemHeight = 12; - this.listBox1.Location = new System.Drawing.Point(224, 10); - this.listBox1.Name = "listBox1"; - this.listBox1.ScrollAlwaysVisible = true; - this.listBox1.Size = new System.Drawing.Size(227, 208); - this.listBox1.TabIndex = 2; - this.listBox1.ValueMember = "Key"; - this.listBox1.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged); - // - // textBoxURL - // - this.textBoxURL.Location = new System.Drawing.Point(10, 227); - this.textBoxURL.Name = "textBoxURL"; - this.textBoxURL.ReadOnly = true; - this.textBoxURL.Size = new System.Drawing.Size(441, 21); - this.textBoxURL.TabIndex = 3; - this.textBoxURL.Click += new System.EventHandler(this.textBoxURL_Click); + this.elementHost1.Dock = System.Windows.Forms.DockStyle.Fill; + this.elementHost1.Location = new System.Drawing.Point(0, 0); + this.elementHost1.Margin = new System.Windows.Forms.Padding(0); + this.elementHost1.Name = "elementHost1"; + this.elementHost1.Size = new System.Drawing.Size(600, 340); + this.elementHost1.TabIndex = 0; + this.elementHost1.Text = "elementHost1"; + this.elementHost1.Child = this.serverSharingView1; // // QRCodeForm // this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.AutoSize = true; - this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.BackColor = System.Drawing.Color.White; - this.ClientSize = new System.Drawing.Size(457, 257); - this.Controls.Add(this.textBoxURL); - this.Controls.Add(this.listBox1); - this.Controls.Add(this.pictureBox1); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.MaximizeBox = false; - this.MinimizeBox = false; + this.ClientSize = new System.Drawing.Size(600, 340); + this.Controls.Add(this.elementHost1); + this.Margin = new System.Windows.Forms.Padding(8); this.Name = "QRCodeForm"; - this.Padding = new System.Windows.Forms.Padding(10); this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "QRCode and URL"; this.Load += new System.EventHandler(this.QRCodeForm_Load); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); this.ResumeLayout(false); - this.PerformLayout(); - } #endregion - private System.Windows.Forms.PictureBox pictureBox1; - private System.Windows.Forms.ListBox listBox1; - private System.Windows.Forms.TextBox textBoxURL; + private System.Windows.Forms.Integration.ElementHost elementHost1; + private Views.ServerSharingView serverSharingView1; } } \ No newline at end of file diff --git a/shadowsocks-csharp/View/QRCodeForm.cs b/shadowsocks-csharp/View/QRCodeForm.cs index d8fc8c60..4ff0838a 100755 --- a/shadowsocks-csharp/View/QRCodeForm.cs +++ b/shadowsocks-csharp/View/QRCodeForm.cs @@ -27,64 +27,9 @@ namespace Shadowsocks.View this.Text = I18N.GetString("QRCode and URL"); } - private void GenQR(string ssconfig) - { - string qrText = ssconfig; - QRCode code = ZXing.QrCode.Internal.Encoder.encode(qrText, ErrorCorrectionLevel.M); - ByteMatrix m = code.Matrix; - int blockSize = Math.Max(pictureBox1.Height/m.Height, 1); - - var qrWidth = m.Width*blockSize; - var qrHeight = m.Height*blockSize; - var dWidth = pictureBox1.Width - qrWidth; - var dHeight = pictureBox1.Height - qrHeight; - var maxD = Math.Max(dWidth, dHeight); - pictureBox1.SizeMode = maxD >= 7*blockSize ? PictureBoxSizeMode.Zoom : PictureBoxSizeMode.CenterImage; - - Bitmap drawArea = new Bitmap((m.Width*blockSize), (m.Height*blockSize)); - using (Graphics g = Graphics.FromImage(drawArea)) - { - g.Clear(Color.White); - using (Brush b = new SolidBrush(Color.Black)) - { - for (int row = 0; row < m.Width; row++) - { - for (int col = 0; col < m.Height; col++) - { - if (m[row, col] != 0) - { - g.FillRectangle(b, blockSize*row, blockSize*col, blockSize, blockSize); - } - } - } - } - } - pictureBox1.Image = drawArea; - } - private void QRCodeForm_Load(object sender, EventArgs e) { - Configuration config = Configuration.Load(); - List> serverDatas = config.configs.Select( - server => - new KeyValuePair(server.GetURL(config.generateLegacyUrl), server.ToString()) - ).ToList(); - listBox1.DataSource = serverDatas; - int selectIndex = serverDatas.FindIndex(serverData => serverData.Key.StartsWith(code)); - if (selectIndex >= 0) listBox1.SetSelected(selectIndex, true); - } - - private void listBox1_SelectedIndexChanged(object sender, EventArgs e) - { - var url = (sender as ListBox)?.SelectedValue.ToString(); - GenQR(url); - textBoxURL.Text = url; - } - - private void textBoxURL_Click(object sender, EventArgs e) - { - textBoxURL.SelectAll(); } } } diff --git a/shadowsocks-csharp/ViewModels/ServerSharingViewModel.cs b/shadowsocks-csharp/ViewModels/ServerSharingViewModel.cs new file mode 100644 index 00000000..24e4096e --- /dev/null +++ b/shadowsocks-csharp/ViewModels/ServerSharingViewModel.cs @@ -0,0 +1,109 @@ +using ReactiveUI; +using Shadowsocks.Model; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Windows.Media.Imaging; + +namespace Shadowsocks.ViewModels +{ + public class ServerSharingViewModel : ReactiveObject + { + /// + /// The view model class for the server sharing user control. + /// + public ServerSharingViewModel() + { + _config = Configuration.Load(); + _servers = _config.configs; + _selectedServer = _servers.First(); + //_selectedServerUrlImage = new BitmapImage(); + UpdateUrlAndImage(); + } + + private readonly Configuration _config; + + private List _servers; + private Server _selectedServer; + private string _selectedServerUrl; + private BitmapImage _selectedServerUrlImage; + + /// + /// Called when SelectedServer changed + /// to update SelectedServerUrl and SelectedServerUrlImage + /// + private void UpdateUrlAndImage() + { + // update SelectedServerUrl + SelectedServerUrl = _selectedServer.GetURL(_config.generateLegacyUrl); + + // generate QR code + var qrCode = ZXing.QrCode.Internal.Encoder.encode(_selectedServerUrl, ZXing.QrCode.Internal.ErrorCorrectionLevel.L); + var byteMatrix = qrCode.Matrix; + + // paint bitmap + int blockSize = Math.Max(1024 / byteMatrix.Height, 1); + Bitmap drawArea = new Bitmap((byteMatrix.Width * blockSize), (byteMatrix.Height * blockSize)); + using (var graphics = Graphics.FromImage(drawArea)) + { + graphics.Clear(Color.White); + using (var solidBrush = new SolidBrush(Color.Black)) + { + for (int row = 0; row < byteMatrix.Width; row++) + { + for (int column = 0; column < byteMatrix.Height; column++) + { + if (byteMatrix[row, column] != 0) + { + graphics.FillRectangle(solidBrush, blockSize * row, blockSize * column, blockSize, blockSize); + } + } + } + } + } + + // transform to BitmapImage for binding + BitmapImage bitmapImage = new BitmapImage(); + using (MemoryStream memoryStream = new MemoryStream()) + { + drawArea.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp); + memoryStream.Position = 0; + bitmapImage.BeginInit(); + bitmapImage.StreamSource = memoryStream; + bitmapImage.CacheOption = BitmapCacheOption.OnLoad; + bitmapImage.EndInit(); + } + SelectedServerUrlImage = bitmapImage; + } + + public List Servers + { + get => _servers; + set => this.RaiseAndSetIfChanged(ref _servers, value); + } + + public Server SelectedServer + { + get => _selectedServer; + set + { + this.RaiseAndSetIfChanged(ref _selectedServer, value); + UpdateUrlAndImage(); + } + } + + public string SelectedServerUrl + { + get => _selectedServerUrl; + set => this.RaiseAndSetIfChanged(ref _selectedServerUrl, value); + } + + public BitmapImage SelectedServerUrlImage + { + get => _selectedServerUrlImage; + set => this.RaiseAndSetIfChanged(ref _selectedServerUrlImage, value); + } + } +} diff --git a/shadowsocks-csharp/Views/ServerSharingView.xaml b/shadowsocks-csharp/Views/ServerSharingView.xaml new file mode 100644 index 00000000..dbce7e27 --- /dev/null +++ b/shadowsocks-csharp/Views/ServerSharingView.xaml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/shadowsocks-csharp/Views/ServerSharingView.xaml.cs b/shadowsocks-csharp/Views/ServerSharingView.xaml.cs new file mode 100644 index 00000000..64aca9a5 --- /dev/null +++ b/shadowsocks-csharp/Views/ServerSharingView.xaml.cs @@ -0,0 +1,24 @@ +using Shadowsocks.ViewModels; +using System.Windows.Controls; +using System.Windows.Input; + +namespace Shadowsocks.Views +{ + /// + /// Interaction logic for ServerSharingView.xaml + /// + public partial class ServerSharingView : UserControl + { + public ServerSharingView() + { + InitializeComponent(); + + DataContext = new ServerSharingViewModel(); + } + + private void urlTextBox_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e) + { + urlTextBox.SelectAll(); + } + } +} diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 1f9e1655..c9414a2b 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -268,6 +268,7 @@ + Form @@ -320,6 +321,9 @@ Form + + ServerSharingView.xaml + Form @@ -416,6 +420,12 @@ true + + + Designer + MSBuild:Compile + + From 1c2ac2978ca4b8af54a61917e7f1f536b66b79f8 Mon Sep 17 00:00:00 2001 From: database64128 Date: Wed, 30 Sep 2020 16:59:19 +0800 Subject: [PATCH 17/35] =?UTF-8?q?=E2=9B=B2=20Use=20WPF=20window=20instead?= =?UTF-8?q?=20of=20WinForms=20ElementHost?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shadowsocks-csharp/ServerSharingWindow.xaml | 11 ++ .../ServerSharingWindow.xaml.cs | 27 ++++ shadowsocks-csharp/View/MenuViewController.cs | 18 ++- .../View/QRCodeForm.Designer.cs | 66 ---------- shadowsocks-csharp/View/QRCodeForm.cs | 35 ----- shadowsocks-csharp/View/QRCodeForm.resx | 120 ------------------ .../Views/ServerSharingView.xaml | 2 +- shadowsocks-csharp/shadowsocks-csharp.csproj | 17 ++- 8 files changed, 61 insertions(+), 235 deletions(-) create mode 100644 shadowsocks-csharp/ServerSharingWindow.xaml create mode 100644 shadowsocks-csharp/ServerSharingWindow.xaml.cs delete mode 100755 shadowsocks-csharp/View/QRCodeForm.Designer.cs delete mode 100755 shadowsocks-csharp/View/QRCodeForm.cs delete mode 100755 shadowsocks-csharp/View/QRCodeForm.resx diff --git a/shadowsocks-csharp/ServerSharingWindow.xaml b/shadowsocks-csharp/ServerSharingWindow.xaml new file mode 100644 index 00000000..6cc585c3 --- /dev/null +++ b/shadowsocks-csharp/ServerSharingWindow.xaml @@ -0,0 +1,11 @@ + + + diff --git a/shadowsocks-csharp/ServerSharingWindow.xaml.cs b/shadowsocks-csharp/ServerSharingWindow.xaml.cs new file mode 100644 index 00000000..f48e5eaa --- /dev/null +++ b/shadowsocks-csharp/ServerSharingWindow.xaml.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace Shadowsocks +{ + /// + /// Interaction logic for ServerSharingWindow.xaml + /// + public partial class ServerSharingWindow : Window + { + public ServerSharingWindow() + { + InitializeComponent(); + } + } +} diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index f73e2102..a2f971a3 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -65,6 +65,8 @@ namespace Shadowsocks.View private HotkeySettingsForm hotkeySettingsForm; private OnlineConfigForm onlineConfigForm; + private ServerSharingWindow serverSharingWindow; + // color definition for icon color transformation private readonly Color colorMaskBlue = Color.FromArgb(255, 25, 125, 191); private readonly Color colorMaskDarkSilver = Color.FromArgb(128, 192, 192, 192); @@ -741,10 +743,18 @@ namespace Shadowsocks.View private void QRCodeItem_Click(object sender, EventArgs e) { - QRCodeForm qrCodeForm = new QRCodeForm(controller.GetServerURLForCurrentServer()); - //qrCodeForm.Icon = this.Icon; - // TODO - qrCodeForm.Show(); + if (serverSharingWindow == null) + { + serverSharingWindow = new ServerSharingWindow(); + serverSharingWindow.Closed += ServerSharingWindow_Closed; + serverSharingWindow.Show(); + } + serverSharingWindow.Activate(); + } + + private void ServerSharingWindow_Closed(object sender, EventArgs e) + { + serverSharingWindow = null; } private void ScanQRCodeItem_Click(object sender, EventArgs e) diff --git a/shadowsocks-csharp/View/QRCodeForm.Designer.cs b/shadowsocks-csharp/View/QRCodeForm.Designer.cs deleted file mode 100755 index 7e83616a..00000000 --- a/shadowsocks-csharp/View/QRCodeForm.Designer.cs +++ /dev/null @@ -1,66 +0,0 @@ -namespace Shadowsocks.View -{ - partial class QRCodeForm - { - /// - /// 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.elementHost1 = new System.Windows.Forms.Integration.ElementHost(); - this.serverSharingView1 = new Shadowsocks.Views.ServerSharingView(); - this.SuspendLayout(); - // - // elementHost1 - // - this.elementHost1.Dock = System.Windows.Forms.DockStyle.Fill; - this.elementHost1.Location = new System.Drawing.Point(0, 0); - this.elementHost1.Margin = new System.Windows.Forms.Padding(0); - this.elementHost1.Name = "elementHost1"; - this.elementHost1.Size = new System.Drawing.Size(600, 340); - this.elementHost1.TabIndex = 0; - this.elementHost1.Text = "elementHost1"; - this.elementHost1.Child = this.serverSharingView1; - // - // QRCodeForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.BackColor = System.Drawing.Color.White; - this.ClientSize = new System.Drawing.Size(600, 340); - this.Controls.Add(this.elementHost1); - this.Margin = new System.Windows.Forms.Padding(8); - this.Name = "QRCodeForm"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "QRCode and URL"; - this.Load += new System.EventHandler(this.QRCodeForm_Load); - this.ResumeLayout(false); - } - - #endregion - - private System.Windows.Forms.Integration.ElementHost elementHost1; - private Views.ServerSharingView serverSharingView1; - } -} \ No newline at end of file diff --git a/shadowsocks-csharp/View/QRCodeForm.cs b/shadowsocks-csharp/View/QRCodeForm.cs deleted file mode 100755 index 4ff0838a..00000000 --- a/shadowsocks-csharp/View/QRCodeForm.cs +++ /dev/null @@ -1,35 +0,0 @@ -using ZXing.QrCode.Internal; -using Shadowsocks.Controller; -using Shadowsocks.Properties; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.IO; -using System.IO.Compression; -using System.Linq; -using System.Text; -using System.Windows.Forms; -using Shadowsocks.Model; - -namespace Shadowsocks.View -{ - public partial class QRCodeForm : Form - { - private string code; - - public QRCodeForm(string code) - { - this.code = code; - InitializeComponent(); - this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); - this.Text = I18N.GetString("QRCode and URL"); - } - - private void QRCodeForm_Load(object sender, EventArgs e) - { - - } - } -} diff --git a/shadowsocks-csharp/View/QRCodeForm.resx b/shadowsocks-csharp/View/QRCodeForm.resx deleted file mode 100755 index 29dcb1b3..00000000 --- a/shadowsocks-csharp/View/QRCodeForm.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/Views/ServerSharingView.xaml b/shadowsocks-csharp/Views/ServerSharingView.xaml index dbce7e27..763d9ed2 100644 --- a/shadowsocks-csharp/Views/ServerSharingView.xaml +++ b/shadowsocks-csharp/Views/ServerSharingView.xaml @@ -5,7 +5,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Shadowsocks.Views" mc:Ignorable="d" - d:DesignHeight="320" d:DesignWidth="600"> + d:DesignHeight="400" d:DesignWidth="660"> diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index c9414a2b..dc63c364 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -41,6 +41,7 @@ 1.0.0.%2a false true + {60DC8134-EBA5-43B8-BCC9-BB4BC16C2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} true @@ -256,6 +257,9 @@ + + ServerSharingWindow.xaml + @@ -312,12 +316,6 @@ ProxyForm.cs - - Form - - - QRCodeForm.cs - Form @@ -354,9 +352,6 @@ ProxyForm.cs - - QRCodeForm.cs - StatisticsStrategyConfigurationForm.cs @@ -421,6 +416,10 @@ + + Designer + MSBuild:Compile + Designer MSBuild:Compile From b6b70294b7c9b04792b35e15861cf0a66ffccc90 Mon Sep 17 00:00:00 2001 From: Beta Soft Date: Sat, 10 Oct 2020 00:01:18 +0800 Subject: [PATCH 18/35] OnlineConfigResolver: add User-Agent Signed-off-by: Beta Soft --- shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs b/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs index ee48fdf5..b2a2416f 100644 --- a/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs +++ b/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs @@ -22,6 +22,9 @@ namespace Shadowsocks.Controller.Service Timeout = TimeSpan.FromSeconds(15) }; + string userAgent = "ShadowsocksWindows/" + UpdateChecker.Version; + httpClient.DefaultRequestHeaders.Add("User-Agent", userAgent); + string server_json = await httpClient.GetStringAsync(url); var servers = server_json.GetServers(); From 608675f96e12cb3de13ab451f5b997783db1a057 Mon Sep 17 00:00:00 2001 From: database64128 Date: Mon, 12 Oct 2020 00:18:58 +0800 Subject: [PATCH 19/35] =?UTF-8?q?=E2=9A=99=20Allow=20configuration=20of=20?= =?UTF-8?q?User-Agent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - For OnlineConfigResolver and GeositeUpdater --- shadowsocks-csharp/Controller/Service/GeositeUpdater.cs | 2 ++ .../Controller/Service/OnlineConfigResolver.cs | 7 +++---- shadowsocks-csharp/Controller/ShadowsocksController.cs | 2 +- shadowsocks-csharp/Model/Configuration.cs | 8 ++++++++ 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/GeositeUpdater.cs b/shadowsocks-csharp/Controller/Service/GeositeUpdater.cs index f076df96..e4489f60 100644 --- a/shadowsocks-csharp/Controller/Service/GeositeUpdater.cs +++ b/shadowsocks-csharp/Controller/Service/GeositeUpdater.cs @@ -102,6 +102,8 @@ namespace Shadowsocks.Controller // because we can't change proxy on existing socketsHttpHandler instance httpClientHandler = new HttpClientHandler(); httpClient = new HttpClient(httpClientHandler); + if (!string.IsNullOrWhiteSpace(config.userAgentString)) + httpClient.DefaultRequestHeaders.Add("User-Agent", config.userAgentString); if (config.enabled) { httpClientHandler.Proxy = new WebProxy( diff --git a/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs b/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs index b2a2416f..457e2ab7 100644 --- a/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs +++ b/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs @@ -11,7 +11,7 @@ namespace Shadowsocks.Controller.Service { public class OnlineConfigResolver { - public static async Task> GetOnline(string url, IWebProxy proxy = null) + public static async Task> GetOnline(string url, string userAgentString, IWebProxy proxy = null) { var httpClientHandler = new HttpClientHandler() { @@ -21,9 +21,8 @@ namespace Shadowsocks.Controller.Service { Timeout = TimeSpan.FromSeconds(15) }; - - string userAgent = "ShadowsocksWindows/" + UpdateChecker.Version; - httpClient.DefaultRequestHeaders.Add("User-Agent", userAgent); + if (!string.IsNullOrWhiteSpace(userAgentString)) + httpClient.DefaultRequestHeaders.Add("User-Agent", userAgentString); string server_json = await httpClient.GetStringAsync(url); diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 935bf8ea..590485e0 100644 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -691,7 +691,7 @@ namespace Shadowsocks.Controller public async Task UpdateOnlineConfigInternal(string url) { - var onlineServer = await OnlineConfigResolver.GetOnline(url, _config.WebProxy); + var onlineServer = await OnlineConfigResolver.GetOnline(url, _config.userAgentString, _config.WebProxy); _config.configs = Configuration.SortByOnlineConfig( _config.configs .Where(c => c.group != url) diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index 60df5410..a11cc46b 100644 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -46,6 +46,7 @@ namespace Shadowsocks.Model public string geositeUrl; // for custom geosite source (and rule group) public string geositeGroup; public bool geositeBlacklistMode; + public string userAgent; //public NLogConfig.LogLevel logLevel; public LogViewerConfig logViewer; @@ -81,6 +82,7 @@ namespace Shadowsocks.Model geositeUrl = ""; geositeGroup = "geolocation-!cn"; geositeBlacklistMode = true; + userAgent = "ShadowsocksWindows/$version"; logViewer = new LogViewerConfig(); proxy = new ProxyConfig(); @@ -92,6 +94,9 @@ namespace Shadowsocks.Model onlineConfigSource = new List(); } + [JsonIgnore] + public string userAgentString; // $version substituted with numeral version in it + [JsonIgnore] NLogConfig nLogConfig; @@ -153,6 +158,7 @@ namespace Shadowsocks.Model string configContent = File.ReadAllText(CONFIG_FILE); config = JsonConvert.DeserializeObject(configContent); config.isDefault = false; + config.version = UpdateChecker.Version; if (UpdateChecker.Asset.CompareVersion(UpdateChecker.Version, config.version ?? "0") > 0) { config.updated = true; @@ -201,6 +207,8 @@ namespace Shadowsocks.Model logger.Error(e, "Cannot get the log level from NLog config file. Please check if the nlog config file exists with corresponding XML nodes."); } + config.userAgentString = config.userAgent.Replace("$version", config.version); + return config; } From 7e0a62e5261256c9f45a7279f8d9af574185b64f Mon Sep 17 00:00:00 2001 From: database64128 Date: Mon, 12 Oct 2020 02:06:28 +0800 Subject: [PATCH 20/35] =?UTF-8?q?=E2=AC=86=20Update=20CHANGES=20and=20bump?= =?UTF-8?q?=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGES | 6 ++++++ shadowsocks-csharp/Controller/Service/UpdateChecker.cs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index a175380c..d179e304 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +4.2.1.0 2020-10-12 +- SIP008 support (#2942) +- Exclude @cn from PAC proxied list (#2982) +- Transition to WPF: ReactiveUI and ServerSharingView (#2959) +- User-Agent for OnlineConfigResolver and GeositeUpdater (#2978) + 4.2.0.1 2020-09-26 - Fix domain rule handling in PAC script (#2956) diff --git a/shadowsocks-csharp/Controller/Service/UpdateChecker.cs b/shadowsocks-csharp/Controller/Service/UpdateChecker.cs index 2df19ada..137d86df 100644 --- a/shadowsocks-csharp/Controller/Service/UpdateChecker.cs +++ b/shadowsocks-csharp/Controller/Service/UpdateChecker.cs @@ -26,7 +26,7 @@ namespace Shadowsocks.Controller public string LatestVersionLocalName; public event EventHandler CheckUpdateCompleted; - public const string Version = "4.2.0.1"; + public const string Version = "4.2.1.0"; private class CheckUpdateTimer : System.Timers.Timer { From 127cb9662a7c4c9769abfd0398484dd202e0324a Mon Sep 17 00:00:00 2001 From: database64128 Date: Mon, 12 Oct 2020 19:11:33 +0800 Subject: [PATCH 21/35] =?UTF-8?q?=F0=9F=A7=B9=20Cleanup=20and=20update=20d?= =?UTF-8?q?ependencies?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove StringEx.CS - Update all dependencies - Eliminate all warnings --- shadowsocks-csharp/Controller/HotkeyReg.cs | 2 +- .../Service/AvailabilityStatistics.cs | 2 +- .../Controller/Service/GeositeUpdater.cs | 8 +- .../Controller/Service/Sip003Plugin.cs | 3 +- .../Controller/ShadowsocksController.cs | 2 +- .../System/Hotkeys/HotkeyCallbacks.cs | 2 +- .../Controller/System/Hotkeys/Hotkeys.cs | 2 +- .../Controller/System/SystemProxy.cs | 2 +- .../Encryption/EncryptorFactory.cs | 2 +- shadowsocks-csharp/Model/Configuration.cs | 8 +- shadowsocks-csharp/Model/Server.cs | 12 +- shadowsocks-csharp/Proxy/HttpProxy.cs | 4 +- shadowsocks-csharp/StringEx.cs | 314 ------------------ .../Util/SystemProxy/Sysproxy.cs | 2 +- shadowsocks-csharp/Util/Util.cs | 2 +- shadowsocks-csharp/View/ConfigForm.cs | 2 +- shadowsocks-csharp/View/MenuViewController.cs | 6 +- .../View/OnlineConfigForm.Designer.cs | 2 +- shadowsocks-csharp/app.config | 22 +- shadowsocks-csharp/packages.config | 33 +- shadowsocks-csharp/shadowsocks-csharp.csproj | 69 ++-- test/ShadowsocksTest.csproj | 1 + test/app.config | 15 + 23 files changed, 111 insertions(+), 406 deletions(-) delete mode 100644 shadowsocks-csharp/StringEx.cs create mode 100644 test/app.config diff --git a/shadowsocks-csharp/Controller/HotkeyReg.cs b/shadowsocks-csharp/Controller/HotkeyReg.cs index 90a3dee9..2ebef212 100644 --- a/shadowsocks-csharp/Controller/HotkeyReg.cs +++ b/shadowsocks-csharp/Controller/HotkeyReg.cs @@ -50,7 +50,7 @@ namespace Shadowsocks.Controller var callback = _callback as HotKeys.HotKeyCallBackHandler; - if (hotkeyStr.IsNullOrEmpty()) + if (string.IsNullOrEmpty(hotkeyStr)) { HotKeys.UnregExistingHotkey(callback); onComplete?.Invoke(RegResult.UnregSuccess); diff --git a/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs b/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs index f6d9a3d6..112c5493 100644 --- a/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs +++ b/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs @@ -214,7 +214,7 @@ namespace Shadowsocks.Controller AppendRecord(id, record); } } - catch (Exception e) + catch { logger.Debug("config changed asynchrously, just ignore this server"); } diff --git a/shadowsocks-csharp/Controller/Service/GeositeUpdater.cs b/shadowsocks-csharp/Controller/Service/GeositeUpdater.cs index e4489f60..be604844 100644 --- a/shadowsocks-csharp/Controller/Service/GeositeUpdater.cs +++ b/shadowsocks-csharp/Controller/Service/GeositeUpdater.cs @@ -219,16 +219,14 @@ var __RULES__ = {JsonConvert.SerializeObject(gfwLines, Formatting.Indented)}; return abpContent; } - private static readonly IEnumerable IgnoredLineBegins = new[] { '!', '[' }; - private static List PreProcessGFWList(string content) { List valid_lines = new List(); - using (var sr = new StringReader(content)) + using (var stringReader = new StringReader(content)) { - foreach (var line in sr.NonWhiteSpaceLines()) + for (string line = stringReader.ReadLine(); line != null; line = stringReader.ReadLine()) { - if (line.BeginWithAny(IgnoredLineBegins)) + if (string.IsNullOrWhiteSpace(line) || line.StartsWith("!") || line.StartsWith("[")) continue; valid_lines.Add(line); } diff --git a/shadowsocks-csharp/Controller/Service/Sip003Plugin.cs b/shadowsocks-csharp/Controller/Service/Sip003Plugin.cs index a0048e14..7024c648 100644 --- a/shadowsocks-csharp/Controller/Service/Sip003Plugin.cs +++ b/shadowsocks-csharp/Controller/Service/Sip003Plugin.cs @@ -122,12 +122,13 @@ namespace Shadowsocks.Controller.Service public string ExpandEnvironmentVariables(string name, StringDictionary environmentVariables = null) { + name = name.ToLower(); // Expand the environment variables from the new process itself if (environmentVariables != null) { foreach(string key in environmentVariables.Keys) { - name = name.Replace($"%{key}%", environmentVariables[key], StringComparison.OrdinalIgnoreCase); + name = name.Replace($"%{key.ToLower()}%", environmentVariables[key]); } } // Also expand the environment variables from current main process (system) diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 590485e0..cb915ff7 100644 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -420,7 +420,7 @@ namespace Shadowsocks.Controller { try { - if (ssURL.IsNullOrEmpty() || ssURL.IsWhiteSpace()) + if (string.IsNullOrWhiteSpace(ssURL)) return false; var servers = Server.GetServers(ssURL); diff --git a/shadowsocks-csharp/Controller/System/Hotkeys/HotkeyCallbacks.cs b/shadowsocks-csharp/Controller/System/Hotkeys/HotkeyCallbacks.cs index cb60d739..7c94c93c 100644 --- a/shadowsocks-csharp/Controller/System/Hotkeys/HotkeyCallbacks.cs +++ b/shadowsocks-csharp/Controller/System/Hotkeys/HotkeyCallbacks.cs @@ -23,7 +23,7 @@ namespace Shadowsocks.Controller.Hotkeys /// public static Delegate GetCallback(string methodname) { - if (methodname.IsNullOrEmpty()) throw new ArgumentException(nameof(methodname)); + if (string.IsNullOrEmpty(methodname)) throw new ArgumentException(nameof(methodname)); MethodInfo dynMethod = typeof(HotkeyCallbacks).GetMethod(methodname, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase); return dynMethod == null ? null : Delegate.CreateDelegate(typeof(HotKeys.HotKeyCallBackHandler), Instance, dynMethod); diff --git a/shadowsocks-csharp/Controller/System/Hotkeys/Hotkeys.cs b/shadowsocks-csharp/Controller/System/Hotkeys/Hotkeys.cs index 45069321..a55591ef 100644 --- a/shadowsocks-csharp/Controller/System/Hotkeys/Hotkeys.cs +++ b/shadowsocks-csharp/Controller/System/Hotkeys/Hotkeys.cs @@ -110,7 +110,7 @@ namespace Shadowsocks.Controller.Hotkeys { try { - if (s.IsNullOrEmpty()) return null; + if (string.IsNullOrEmpty(s)) return null; int offset = s.LastIndexOf("+", StringComparison.OrdinalIgnoreCase); if (offset <= 0) return null; string modifierStr = s.Substring(0, offset).Trim(); diff --git a/shadowsocks-csharp/Controller/System/SystemProxy.cs b/shadowsocks-csharp/Controller/System/SystemProxy.cs index 1d61dd86..ee767e12 100644 --- a/shadowsocks-csharp/Controller/System/SystemProxy.cs +++ b/shadowsocks-csharp/Controller/System/SystemProxy.cs @@ -36,7 +36,7 @@ namespace Shadowsocks.Controller else { string pacUrl; - if (config.useOnlinePac && !config.pacUrl.IsNullOrEmpty()) + if (config.useOnlinePac && !string.IsNullOrEmpty(config.pacUrl)) { pacUrl = config.pacUrl; } diff --git a/shadowsocks-csharp/Encryption/EncryptorFactory.cs b/shadowsocks-csharp/Encryption/EncryptorFactory.cs index fcae221a..7e1d6264 100644 --- a/shadowsocks-csharp/Encryption/EncryptorFactory.cs +++ b/shadowsocks-csharp/Encryption/EncryptorFactory.cs @@ -68,7 +68,7 @@ namespace Shadowsocks.Encryption public static IEncryptor GetEncryptor(string method, string password) { - if (method.IsNullOrEmpty()) + if (string.IsNullOrEmpty(method)) { method = Model.Server.DefaultMethod; } diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index a11cc46b..cd16032b 100644 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -292,13 +292,13 @@ namespace Shadowsocks.Model private static void CheckPassword(string password) { - if (password.IsNullOrEmpty()) + if (string.IsNullOrEmpty(password)) throw new ArgumentException(I18N.GetString("Password can not be blank")); } public static void CheckServer(string server) { - if (server.IsNullOrEmpty()) + if (string.IsNullOrEmpty(server)) throw new ArgumentException(I18N.GetString("Server IP can not be blank")); } @@ -311,13 +311,13 @@ namespace Shadowsocks.Model public static void CheckProxyAuthUser(string user) { - if (user.IsNullOrEmpty()) + if (string.IsNullOrEmpty(user)) throw new ArgumentException(I18N.GetString("Auth user can not be blank")); } public static void CheckProxyAuthPwd(string pwd) { - if (pwd.IsNullOrEmpty()) + if (string.IsNullOrEmpty(pwd)) throw new ArgumentException(I18N.GetString("Auth pwd can not be blank")); } } diff --git a/shadowsocks-csharp/Model/Server.cs b/shadowsocks-csharp/Model/Server.cs index fe0e3c04..836d9d8d 100755 --- a/shadowsocks-csharp/Model/Server.cs +++ b/shadowsocks-csharp/Model/Server.cs @@ -62,13 +62,13 @@ namespace Shadowsocks.Model public override string ToString() { - if (server.IsNullOrEmpty()) + if (string.IsNullOrEmpty(server)) { return I18N.GetString("New server"); } string serverStr = $"{FormalHostName}:{server_port}"; - return remarks.IsNullOrEmpty() + return string.IsNullOrEmpty(remarks) ? serverStr : $"{remarks} ({serverStr})"; } @@ -99,7 +99,7 @@ namespace Shadowsocks.Model server_port ); - if (!plugin.IsNullOrWhiteSpace()) + if (!string.IsNullOrWhiteSpace(plugin)) { string pluginPart = plugin; @@ -112,7 +112,7 @@ namespace Shadowsocks.Model } } - if (!remarks.IsNullOrEmpty()) + if (!string.IsNullOrEmpty(remarks)) { tag = $"#{HttpUtility.UrlEncode(remarks, Encoding.UTF8)}"; } @@ -157,7 +157,7 @@ namespace Shadowsocks.Model Server server = new Server(); var base64 = match.Groups["base64"].Value.TrimEnd('/'); var tag = match.Groups["tag"].Value; - if (!tag.IsNullOrEmpty()) + if (!string.IsNullOrEmpty(tag)) { server.remarks = HttpUtility.UrlDecode(tag, Encoding.UTF8); } @@ -183,7 +183,7 @@ namespace Shadowsocks.Model public static Server ParseURL(string serverUrl) { string _serverUrl = serverUrl.Trim(); - if (!_serverUrl.BeginWith("ss://", StringComparison.InvariantCultureIgnoreCase)) + if (!_serverUrl.StartsWith("ss://", StringComparison.InvariantCultureIgnoreCase)) { return null; } diff --git a/shadowsocks-csharp/Proxy/HttpProxy.cs b/shadowsocks-csharp/Proxy/HttpProxy.cs index dd13b779..b7580f04 100644 --- a/shadowsocks-csharp/Proxy/HttpProxy.cs +++ b/shadowsocks-csharp/Proxy/HttpProxy.cs @@ -39,8 +39,6 @@ namespace Shadowsocks.Proxy public object AsyncState { get; set; } - public int BytesToRead; - public Exception ex { get; set; } } @@ -199,7 +197,7 @@ namespace Shadowsocks.Proxy } else { - if (line.IsNullOrEmpty()) + if (string.IsNullOrEmpty(line)) { return true; } diff --git a/shadowsocks-csharp/StringEx.cs b/shadowsocks-csharp/StringEx.cs deleted file mode 100644 index 96880e19..00000000 --- a/shadowsocks-csharp/StringEx.cs +++ /dev/null @@ -1,314 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Text; - -#if EXPOSE_EVERYTHING || EXPOSE_STRINGEX -public -#endif -static partial class StringEx -{ -#pragma warning disable 1591 - - public static StringComparison GlobalDefaultComparison { get; set; } = StringComparison.Ordinal; - - [ThreadStatic] - private static StringComparison? _DefaultComparison; - public static StringComparison DefaultComparison - { - get { return _DefaultComparison ?? GlobalDefaultComparison; } - set { _DefaultComparison = value; } - } - - #region basic String methods - - public static bool IsNullOrEmpty(this string value) - => string.IsNullOrEmpty(value); - - public static bool IsNullOrWhiteSpace(this string value) - => string.IsNullOrWhiteSpace(value); - - public static bool IsWhiteSpace(this string value) - { - foreach (var c in value) - { - if (char.IsWhiteSpace(c)) continue; - - return false; - } - return true; - } - -#if !PCL - public static string IsInterned(this string value) - { - if (value == null) - throw new ArgumentNullException(nameof(value)); - - return string.IsInterned(value); - } - - public static string Intern(this string value) - { - if (value == null) - throw new ArgumentNullException(nameof(value)); - - return string.Intern(value); - } -#endif - -#if UNSAFE - public static unsafe string ToLowerForASCII(this string value) - { - if (value.IsNullOrWhiteSpace()) - return value; - - value = string.Copy(value); - fixed (char* low = value) - { - var end = low + value.Length; - for (var p = low; p < end; p++) - { - var c = *p; - if (c < 'A' || c > 'Z') - continue; - *p = (char)(c + 0x20); - } - } - return value; - } - - public static unsafe string ToUpperForASCII(this string value) - { - if (value.IsNullOrWhiteSpace()) - return value; - - value = string.Copy(value); - fixed (char* low = value) - { - var end = low + value.Length; - for (var p = low; p < end; p++) - { - var c = *p; - if (c < 'a' || c > 'z') - continue; - *p = (char)(c - 0x20); - } - } - return value; - } -#else - public static string ToLowerForASCII(this string value) - { - if (value.IsNullOrWhiteSpace()) - return value; - - var sb = new StringBuilder(value.Length); - foreach (var c in value) - { - if (c < 'A' || c > 'Z') - sb.Append(c); - else - sb.Append((char)(c + 0x20)); - } - return sb.ToString(); - } - - public static string ToUpperForASCII(this string value) - { - if (value.IsNullOrWhiteSpace()) - return value; - - var sb = new StringBuilder(value.Length); - foreach (var c in value) - { - if (c < 'a' || c > 'z') - sb.Append(c); - else - sb.Append((char)(c - 0x20)); - } - return sb.ToString(); - } -#endif - - #endregion - - #region comparing - - #region Is - - public static bool Is(this string a, string b) - => string.Equals(a, b, DefaultComparison); - public static bool Is(this string a, string b, StringComparison comparisonType) - => string.Equals(a, b, comparisonType); - - #endregion - - #region BeginWith - - public static bool BeginWith(this string s, char c) - { - if (s.IsNullOrEmpty()) return false; - return s[0] == c; - } - public static bool BeginWithAny(this string s, IEnumerable chars) - { - if (s.IsNullOrEmpty()) return false; - return chars.Contains(s[0]); - } - public static bool BeginWithAny(this string s, params char[] chars) - => s.BeginWithAny(chars.AsEnumerable()); - - public static bool BeginWith(this string a, string b) - { - if (a == null || b == null) return false; - - return a.StartsWith(b, DefaultComparison); - } - public static bool BeginWith(this string a, string b, StringComparison comparisonType) - { - if (a == null || b == null) return false; - - return a.StartsWith(b, comparisonType); - } -#if !PCL - public static bool BeginWith(this string a, string b, bool ignoreCase, CultureInfo culture) - { - if (a == null || b == null) return false; - - return a.StartsWith(b, ignoreCase, culture); - } -#endif - - #endregion - - #region FinishWith - - public static bool FinishWith(this string s, char c) - { - if (s.IsNullOrEmpty()) return false; - return s.Last() == c; - } - public static bool FinishWithAny(this string s, IEnumerable chars) - { - if (s.IsNullOrEmpty()) return false; - return chars.Contains(s.Last()); - } - public static bool FinishWithAny(this string s, params char[] chars) - => s.FinishWithAny(chars.AsEnumerable()); - - public static bool FinishWith(this string a, string b) - { - if (a == null || b == null) return false; - - return a.EndsWith(b, DefaultComparison); - } - public static bool FinishWith(this string a, string b, StringComparison comparisonType) - { - if (a == null || b == null) return false; - - return a.EndsWith(b, comparisonType); - } -#if !PCL - public static bool FinishWith(this string a, string b, bool ignoreCase, CultureInfo culture) - { - if (a == null || b == null) return false; - - return a.EndsWith(b, ignoreCase, culture); - } -#endif - - #endregion - - #endregion - - #region ToLines - - public static IEnumerable ToLines(this TextReader reader) - { - string line; - while ((line = reader.ReadLine()) != null) - yield return line; - } - public static IEnumerable NonEmptyLines(this TextReader reader) - { - string line; - while ((line = reader.ReadLine()) != null) - { - if (line == "") continue; - yield return line; - } - } - public static IEnumerable NonWhiteSpaceLines(this TextReader reader) - { - string line; - while ((line = reader.ReadLine()) != null) - { - if (line.IsWhiteSpace()) continue; - yield return line; - } - } - - #endregion - - #region others - - private static readonly char[][] Quotes = new[] - { - "\"\"", - "''", - "“”", - "‘’", - "『』", - "「」", - "〖〗", - "【】", - }.Select(s => s.ToCharArray()).ToArray(); - public static string Enquote(this string value) - { - if (value == null) - return "(null)"; - - foreach (var pair in Quotes) - { - if (value.IndexOfAny(pair) < 0) - return pair[0] + value + pair[1]; - } - - return '"' + value.Replace("\\", @"\\").Replace("\"", @"\""") + '"'; - } - - public static string Replace(this string value, string find, string rep, StringComparison comparsionType) - { - if (find.IsNullOrEmpty()) - throw new ArgumentException(null, nameof(find)); - if (rep == null) - rep = ""; - if (value.IsNullOrEmpty()) - return value; - - var sb = new StringBuilder(value.Length); - - var last = 0; - var len = find.Length; - var idx = value.IndexOf(find, DefaultComparison); - while (idx != -1) - { - sb.Append(value.Substring(last, idx - last)); - sb.Append(rep); - idx += len; - - last = idx; - idx = value.IndexOf(find, idx, comparsionType); - } - sb.Append(value.Substring(last)); - - return sb.ToString(); - } - public static string ReplaceEx(this string value, string find, string rep) - => value.Replace(find, rep, DefaultComparison); - - #endregion -} diff --git a/shadowsocks-csharp/Util/SystemProxy/Sysproxy.cs b/shadowsocks-csharp/Util/SystemProxy/Sysproxy.cs index b1ffcac4..220576f6 100644 --- a/shadowsocks-csharp/Util/SystemProxy/Sysproxy.cs +++ b/shadowsocks-csharp/Util/SystemProxy/Sysproxy.cs @@ -212,7 +212,7 @@ namespace Shadowsocks.Util.SystemProxy if (arguments == "query") { - if (stdout.IsNullOrWhiteSpace() || stdout.IsNullOrEmpty()) + if (string.IsNullOrWhiteSpace(stdout)) { // we cannot get user settings throw new ProxyException(ProxyExceptionType.QueryReturnEmpty); diff --git a/shadowsocks-csharp/Util/Util.cs b/shadowsocks-csharp/Util/Util.cs index cbfed99b..a24ce2c2 100755 --- a/shadowsocks-csharp/Util/Util.cs +++ b/shadowsocks-csharp/Util/Util.cs @@ -238,7 +238,7 @@ namespace Shadowsocks.Util // we are building x86 binary for both x86 and x64, which will // cause problem when opening registry key // detect operating system instead of CPU - if (name.IsNullOrEmpty()) throw new ArgumentException(nameof(name)); + if (string.IsNullOrEmpty(name)) throw new ArgumentException(nameof(name)); try { RegistryKey userKey = RegistryKey.OpenBaseKey(hive, diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index dad4c535..ab029f7e 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -310,7 +310,7 @@ namespace Shadowsocks.View { password = null; string outPassword; - if ((outPassword = PasswordTextBox.Text).IsNullOrWhiteSpace()) + if (string.IsNullOrWhiteSpace(outPassword = PasswordTextBox.Text)) { if (!isSave && !isCopy && ServersListBox.Items.Count > 1 && I18N.GetString("New server").Equals(ServersListBox.Items[_lastSelectedIndex].ToString())) { diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index a2f971a3..8bcd6d9c 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -868,11 +868,11 @@ namespace Shadowsocks.View { if (!onlinePACItem.Checked) { - if (controller.GetConfigurationCopy().pacUrl.IsNullOrEmpty()) + if (string.IsNullOrEmpty(controller.GetConfigurationCopy().pacUrl)) { UpdateOnlinePACURLItem_Click(sender, e); } - if (!controller.GetConfigurationCopy().pacUrl.IsNullOrEmpty()) + if (!string.IsNullOrEmpty(controller.GetConfigurationCopy().pacUrl)) { localPACItem.Checked = false; onlinePACItem.Checked = true; @@ -889,7 +889,7 @@ namespace Shadowsocks.View I18N.GetString("Please input PAC Url"), I18N.GetString("Edit Online PAC URL"), origPacUrl, -1, -1); - if (!pacUrl.IsNullOrEmpty() && pacUrl != origPacUrl) + if (!string.IsNullOrEmpty(pacUrl) && pacUrl != origPacUrl) { controller.SavePACUrl(pacUrl); } diff --git a/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs b/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs index d9787dde..89b4f12a 100644 --- a/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs @@ -213,6 +213,6 @@ private System.Windows.Forms.Button DeleteButton; private System.Windows.Forms.Button OkButton; private System.Windows.Forms.Button UpdateAllButton; - private System.Windows.Forms.Button CancelButton; + private new System.Windows.Forms.Button CancelButton; } } \ No newline at end of file diff --git a/shadowsocks-csharp/app.config b/shadowsocks-csharp/app.config index f1118d57..af2e1137 100755 --- a/shadowsocks-csharp/app.config +++ b/shadowsocks-csharp/app.config @@ -1,22 +1,30 @@ - + -
+
- + - - + + - - + + + + + + + + + + diff --git a/shadowsocks-csharp/packages.config b/shadowsocks-csharp/packages.config index a888c1a9..cbfeadba 100644 --- a/shadowsocks-csharp/packages.config +++ b/shadowsocks-csharp/packages.config @@ -1,31 +1,30 @@  - + - - - + + + - - - + + + - - - + + - + - + - - - + + + - + - + \ No newline at end of file diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index dc63c364..6620a009 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -1,7 +1,7 @@  - - + + Debug AnyCPU @@ -69,31 +69,31 @@ app.manifest - - ..\packages\Caseless.Fody.1.8.3\lib\net452\Caseless.dll + + ..\packages\Caseless.Fody.1.9.0\lib\net452\Caseless.dll ..\packages\CommandLineParser.2.8.0\lib\net461\CommandLine.dll - - ..\packages\Costura.Fody.3.3.3\lib\net40\Costura.dll + + ..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll - - ..\packages\DynamicData.6.16.6\lib\net461\DynamicData.dll + + ..\packages\DynamicData.6.17.14\lib\net461\DynamicData.dll ..\packages\GlobalHotKey.1.1.0\lib\GlobalHotKey.dll - - ..\packages\Google.Protobuf.3.11.4\lib\net45\Google.Protobuf.dll + + ..\packages\Google.Protobuf.3.13.0\lib\net45\Google.Protobuf.dll - ..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll + ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll - ..\packages\NLog.4.6.8\lib\net45\NLog.dll + ..\packages\NLog.4.7.5\lib\net45\NLog.dll @@ -104,11 +104,11 @@ ..\packages\ReactiveUI.WPF.11.5.35\lib\net472\ReactiveUI.WPF.dll - ..\packages\Splat.9.5.20\lib\net461\Splat.dll + ..\packages\Splat.9.5.49\lib\net461\Splat.dll - - ..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll @@ -122,8 +122,8 @@ - - ..\packages\System.Memory.4.5.2\lib\netstandard2.0\System.Memory.dll + + ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll @@ -132,23 +132,23 @@ True - - ..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll ..\packages\System.Reactive.4.4.1\lib\net46\System.Reactive.dll - - ..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll + + ..\packages\System.Runtime.4.3.1\lib\net462\System.Runtime.dll True True - - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll - ..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll + ..\packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net463\System.Security.Cryptography.Algorithms.dll True True @@ -162,8 +162,8 @@ True True - - ..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll + + ..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll True True @@ -184,11 +184,11 @@ - - ..\packages\ZXing.Net.0.16.5\lib\net47\zxing.dll + + ..\packages\ZXing.Net.0.16.6\lib\net47\zxing.dll - - ..\packages\ZXing.Net.0.16.5\lib\net47\zxing.presentation.dll + + ..\packages\ZXing.Net.0.16.6\lib\net47\zxing.presentation.dll @@ -262,7 +262,6 @@ - @@ -427,14 +426,14 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + Mot de passe + + + Port + + + Type + + + adresse + + + Délai d'attente + + + Annuler + + + OK + + + Changer l'état de proxy système + + + Changer le mode de proxy système + + + Autoriser les clients du LAN + + + Afficher les journaux + + + Passer au serveur précédent + + + Passer au serveur suivant + + + Enregistrer tout + + + Enregistrer tout au démarrage + + + Ajouter + + + sauter la version + + + Copier le lien + + + retirer + + + mise à jour + + + copie + \ No newline at end of file diff --git a/shadowsocks-csharp/View/HotkeySettingsForm.resx b/shadowsocks-csharp/Localization/Strings.ja.resx similarity index 58% rename from shadowsocks-csharp/View/HotkeySettingsForm.resx rename to shadowsocks-csharp/Localization/Strings.ja.resx index 5813f883..4d8f997d 100644 --- a/shadowsocks-csharp/View/HotkeySettingsForm.resx +++ b/shadowsocks-csharp/Localization/Strings.ja.resx @@ -1,183 +1,180 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - - - False - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + パスワード + + + タイプ + + + アドレス + + + ポート + + + タイムアウト + + + キャンセル + + + OK + + + システム プロキシの状態を切り替える + + + プロキシモードを切り替える + + + LAN からのアクセスの許可を切り替える + + + ログの表示 + + + 前のサーバーに切り替える + + + 次のサーバーに切り替える + + + 全部登録する + + + 起動時にホットキーを登録する + + + 新規 + + + バージョンをスキップ + + + リンクをコピーする + + + 更新 + + + コピー + \ No newline at end of file diff --git a/shadowsocks-csharp/View/OnlineConfigForm.resx b/shadowsocks-csharp/Localization/Strings.ko.resx similarity index 74% rename from shadowsocks-csharp/View/OnlineConfigForm.resx rename to shadowsocks-csharp/Localization/Strings.ko.resx index 1af7de15..16df3925 100644 --- a/shadowsocks-csharp/View/OnlineConfigForm.resx +++ b/shadowsocks-csharp/Localization/Strings.ko.resx @@ -117,4 +117,64 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 비밀번호 + + + 유형 + + + 주소 + + + 포트 + + + 시간 초과 + + + 취소 + + + 확인 + + + 시스템 프록시 전환 + + + 시스템 프록시 모드 전환 + + + LAN으로부터 클라이언트 허용 + + + 로그 보기… + + + 이전 서버로 전환 + + + 다음 서버로 전환 + + + 모두 등록 + + + 시스템 시작 시 단축키 등록 + + + 추가 + + + 버전 건너 뛰기 + + + 링크 복사 + + + 새롭게 함 + + + + \ No newline at end of file diff --git a/shadowsocks-csharp/Localization/Strings.resx b/shadowsocks-csharp/Localization/Strings.resx new file mode 100644 index 00000000..17d6e307 --- /dev/null +++ b/shadowsocks-csharp/Localization/Strings.resx @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + Type + + + No proxy + + + SOCKS5 + + + HTTP + + + Details + + + Address + + + Port + + + Timeout + + + Credentials (optional) + + + Username + + + Password + + + _Save + + + _Cancel + + + _OK + + + Toggle system proxy + + + Toggle proxy mode + + + Allow clients from LAN + + + Open logs window + + + Switch to previous server + + + Switch to next server + + + Register hotkeys at startup + + + _Register all + + + _Update + + + Update all + + + _Copy link + + + Remove + + + _Add + + + An update is available. + + + Please read the release notes carefully. Then decide whether to update. + + + _Skip version + + + _Not now + + + _Copy + + + Forward Proxy + + + Server Sharing + + + Hotkeys + + + Online Configuration Delivery + + + VersionUpdate + + + Successfully updated the selected source! + + + Update failed. See the logs for more information. + + + Successfully updated all sources! + + + The following sources failed to update:\n\n + + \ No newline at end of file diff --git a/shadowsocks-csharp/Localization/Strings.ru.resx b/shadowsocks-csharp/Localization/Strings.ru.resx new file mode 100644 index 00000000..7c0ceb3d --- /dev/null +++ b/shadowsocks-csharp/Localization/Strings.ru.resx @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/Localization/Strings.zh-Hans.resx b/shadowsocks-csharp/Localization/Strings.zh-Hans.resx new file mode 100644 index 00000000..9ca554ed --- /dev/null +++ b/shadowsocks-csharp/Localization/Strings.zh-Hans.resx @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 不使用代理 + + + 类型 + + + 认证 (可选) + + + 详细设置 + + + 地址 + + + 保存 + + + 取消 + + + 用户名 + + + 密码 + + + 端口 + + + 超时 + + + 确定 + + + 全部注册 + + + 切换系统代理 + + + 切换代理模式 + + + 允许内网客户端连接 + + + 打开日志窗口 + + + 切换到上一个服务器 + + + 切换到下一个服务器 + + + 启动时注册快捷键 + + + 更新 + + + 全部更新 + + + 复制链接 + + + 移除 + + + 添加 + + + 跳过版本 + + + 暂不更新 + + + 发现可用更新 + + + 请仔细阅读发布信息,然后决定是否更新。 + + + 复制 + + + 前置代理 + + + 在线配置下发 + + + 热键 + + + 服务器分享 + + + 版本更新 + + + 成功更新选定来源! + + + 更新失败,请查看日志获取更多信息。 + + + 成功更新所有来源! + + + 下列来源更新失败:\n\n + + \ No newline at end of file diff --git a/shadowsocks-csharp/Localization/Strings.zh-Hant.resx b/shadowsocks-csharp/Localization/Strings.zh-Hant.resx new file mode 100644 index 00000000..91610dc5 --- /dev/null +++ b/shadowsocks-csharp/Localization/Strings.zh-Hant.resx @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 密碼 + + + Port + + + 類型 + + + 位址 + + + 逾時 + + + 取消 + + + 確定 + + + 切換系統 Proxy 狀態 + + + 切換系統 Proxy 模式 + + + 切換區域網路共用 + + + 顯示記錄檔 + + + 切換上一個伺服器 + + + 切換下一個伺服器 + + + 註冊所有快速鍵 + + + 啟動時註冊快速鍵 + + + 更新 + + + 全部更新 + + + 新增 + + + 跳過版本 + + + 暫不更新 + + + 發現可用更新 + + + 複製鏈接 + + + 複製 + + \ No newline at end of file diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index 9de8049b..322dca5e 100644 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -40,6 +40,7 @@ namespace Shadowsocks.Model public bool availabilityStatistics; public bool autoCheckUpdate; public bool checkPreRelease; + public string skippedUpdateVersion; // skip the update with this version number public bool isVerboseLogging; // hidden options @@ -53,7 +54,7 @@ namespace Shadowsocks.Model //public NLogConfig.LogLevel logLevel; public LogViewerConfig logViewer; - public ProxyConfig proxy; + public ForwardProxyConfig proxy; public HotkeyConfig hotkey; [JsonIgnore] @@ -78,6 +79,7 @@ namespace Shadowsocks.Model availabilityStatistics = false; autoCheckUpdate = false; checkPreRelease = false; + skippedUpdateVersion = ""; isVerboseLogging = false; // hidden options @@ -97,7 +99,7 @@ namespace Shadowsocks.Model userAgent = "ShadowsocksWindows/$version"; logViewer = new LogViewerConfig(); - proxy = new ProxyConfig(); + proxy = new ForwardProxyConfig(); hotkey = new HotkeyConfig(); firstRunOnNewVersion = false; @@ -193,7 +195,9 @@ namespace Shadowsocks.Model ResetGeositeProxiedGroup(ref config.geositeProxiedGroups); // Mark the first run of a new version. - if (UpdateChecker.Asset.CompareVersion(UpdateChecker.Version, config.version ?? "0") > 0) + var appVersion = new Version(UpdateChecker.Version); + var configVersion = new Version(config.version); + if (appVersion.CompareTo(configVersion) > 0) { config.firstRunOnNewVersion = true; } @@ -316,6 +320,12 @@ namespace Shadowsocks.Model geositeProxiedGroups.Add("geolocation-!cn"); } + public static void ResetUserAgent(Configuration config) + { + config.userAgent = "ShadowsocksWindows/$version"; + config.userAgentString = config.userAgent.Replace("$version", config.version); + } + public static Server AddDefaultServerOrServer(Configuration config, Server server = null, int? index = null) { if (config?.configs != null) @@ -368,17 +378,5 @@ namespace Shadowsocks.Model throw new ArgumentException( I18N.GetString("Timeout is invalid, it should not exceed {0}", maxTimeout)); } - - public static void CheckProxyAuthUser(string user) - { - if (string.IsNullOrEmpty(user)) - throw new ArgumentException(I18N.GetString("Auth user can not be blank")); - } - - public static void CheckProxyAuthPwd(string pwd) - { - if (string.IsNullOrEmpty(pwd)) - throw new ArgumentException(I18N.GetString("Auth pwd can not be blank")); - } } } diff --git a/shadowsocks-csharp/Model/ProxyConfig.cs b/shadowsocks-csharp/Model/ForwardProxyConfig.cs similarity index 90% rename from shadowsocks-csharp/Model/ProxyConfig.cs rename to shadowsocks-csharp/Model/ForwardProxyConfig.cs index da60b622..7a1d4ec5 100644 --- a/shadowsocks-csharp/Model/ProxyConfig.cs +++ b/shadowsocks-csharp/Model/ForwardProxyConfig.cs @@ -1,43 +1,43 @@ -using System; - -namespace Shadowsocks.Model -{ - [Serializable] - public class ProxyConfig - { - public const int PROXY_SOCKS5 = 0; - public const int PROXY_HTTP = 1; - - public const int MaxProxyTimeoutSec = 10; - private const int DefaultProxyTimeoutSec = 3; - - public bool useProxy; - public int proxyType; - public string proxyServer; - public int proxyPort; - public int proxyTimeout; - public bool useAuth; - public string authUser; - public string authPwd; - - public ProxyConfig() - { - useProxy = false; - proxyType = PROXY_SOCKS5; - proxyServer = ""; - proxyPort = 0; - proxyTimeout = DefaultProxyTimeoutSec; - useAuth = false; - authUser = ""; - authPwd = ""; - } - - public void CheckConfig() - { - if (proxyType < PROXY_SOCKS5 || proxyType > PROXY_HTTP) - { - proxyType = PROXY_SOCKS5; - } - } - } -} +using System; + +namespace Shadowsocks.Model +{ + [Serializable] + public class ForwardProxyConfig + { + public const int PROXY_SOCKS5 = 0; + public const int PROXY_HTTP = 1; + + public const int MaxProxyTimeoutSec = 10; + private const int DefaultProxyTimeoutSec = 3; + + public bool useProxy; + public int proxyType; + public string proxyServer; + public int proxyPort; + public int proxyTimeout; + public bool useAuth; + public string authUser; + public string authPwd; + + public ForwardProxyConfig() + { + useProxy = false; + proxyType = PROXY_SOCKS5; + proxyServer = ""; + proxyPort = 0; + proxyTimeout = DefaultProxyTimeoutSec; + useAuth = false; + authUser = ""; + authPwd = ""; + } + + public void CheckConfig() + { + if (proxyType < PROXY_SOCKS5 || proxyType > PROXY_HTTP) + { + proxyType = PROXY_SOCKS5; + } + } + } +} diff --git a/shadowsocks-csharp/Program.cs b/shadowsocks-csharp/Program.cs index 9e266105..a76633fd 100755 --- a/shadowsocks-csharp/Program.cs +++ b/shadowsocks-csharp/Program.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.IO; using System.IO.Pipes; using System.Net; +using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -10,10 +11,12 @@ using System.Windows.Forms; using CommandLine; using Microsoft.Win32; using NLog; +using ReactiveUI; using Shadowsocks.Controller; using Shadowsocks.Controller.Hotkeys; using Shadowsocks.Util; using Shadowsocks.View; +using Splat; namespace Shadowsocks { @@ -109,6 +112,10 @@ namespace Shadowsocks AutoStartup.RegisterForRestart(true); #endregion + // We would use this in v5. + // Parameters would have to be dropped from views' constructors (VersionUpdatePromptView) + //Locator.CurrentMutable.RegisterViewsForViewModels(Assembly.GetCallingAssembly()); + #if DEBUG // truncate privoxy log file while debugging string privoxyLogFilename = Utils.GetTempPath("privoxy.log"); diff --git a/shadowsocks-csharp/Properties/Resources.Designer.cs b/shadowsocks-csharp/Properties/Resources.Designer.cs index f3d0fbe1..3d0151b1 100644 --- a/shadowsocks-csharp/Properties/Resources.Designer.cs +++ b/shadowsocks-csharp/Properties/Resources.Designer.cs @@ -1,10 +1,10 @@ //------------------------------------------------------------------------------ // -// 此代码由工具生成。 -// 运行时版本:4.0.30319.42000 +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 // -// 对此文件的更改可能会导致不正确的行为,并且如果 -// 重新生成代码,这些更改将会丢失。 +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. // //------------------------------------------------------------------------------ @@ -13,16 +13,16 @@ namespace Shadowsocks.Properties { /// - /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// A strongly-typed resource class, for looking up localized strings, etc. /// - // 此类是由 StronglyTypedResourceBuilder - // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 - // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen - // (以 /str 作为命令选项),或重新生成 VS 项目。 + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { + public class Resources { private static global::System.Resources.ResourceManager resourceMan; @@ -33,10 +33,10 @@ namespace Shadowsocks.Properties { } /// - /// 返回此类使用的缓存的 ResourceManager 实例。 + /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { + public static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Shadowsocks.Properties.Resources", typeof(Resources).Assembly); @@ -47,11 +47,11 @@ namespace Shadowsocks.Properties { } /// - /// 重写当前线程的 CurrentUICulture 属性 - /// 重写当前线程的 CurrentUICulture 属性。 + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { + public static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } @@ -61,7 +61,7 @@ namespace Shadowsocks.Properties { } /// - /// 查找类似 /* eslint-disable */ + /// Looks up a localized string similar to /* eslint-disable */ ///// Was generated by gfwlist2pac in precise mode ///// https://github.com/clowwindy/gfwlist2pac /// @@ -69,25 +69,28 @@ namespace Shadowsocks.Properties { ///// 2019-02-08: Updated to support shadowsocks-windows user rules. /// ///var proxy = __PROXY__; - ///var userrules = __USERRULES__; - ///var rules = __RULES__; + ///var userrules = []; + ///var rules = []; /// - ////* - ///* This file is part of Adblock Plus <http://adblockplus.org/>, - ///* Copyright (C) 2006-2014 Eyeo GmbH - ///* - ///* Adblock Plus is free software: you can redistribute it and/or [字符串的其余部分被截断]"; 的本地化字符串。 + ///// convert to abp grammar + ///for (var i = 0; i < __RULES__.length; i++) { + /// var s = __RULES__[i]; + /// if (s.substring(0, 2) == "||") s += "^"; + /// rules.push(s); + ///} + /// + ///for (var i = 0; i < [rest of string was truncated]";. /// - internal static string abp_js { + public static string abp_js { get { return ResourceManager.GetString("abp_js", resourceCulture); } } /// - /// 查找 System.Byte[] 类型的本地化资源。 + /// Looks up a localized resource of type System.Byte[]. /// - internal static byte[] dlc_dat { + public static byte[] dlc_dat { get { object obj = ResourceManager.GetObject("dlc_dat", resourceCulture); return ((byte[])(obj)); @@ -95,7 +98,7 @@ namespace Shadowsocks.Properties { } /// - /// 查找类似 en,ru-RU,zh-CN,zh-TW,ja,ko,fr + /// Looks up a localized string similar to en,ru-RU,zh-CN,zh-TW,ja,ko,fr ///#Restart program to apply translation,,,,,, ///#This is comment line,,,,,, ///#Always keep language name at head of file,,,,,, @@ -107,18 +110,18 @@ namespace Shadowsocks.Properties { ///,,,,,, ///#Menu,,,,,, ///,,,,,, - ///System Proxy,Системный прокси-сервер,系统代理,系統代理,システムプロキシ,시스템 프록시,P [字符串的其余部分被截断]"; 的本地化字符串。 + ///System Proxy,Системный прокси-сервер,系统代理,系統代理,システムプロキシ,시스템 프록시,P [rest of string was truncated]";. /// - internal static string i18n_csv { + public static string i18n_csv { get { return ResourceManager.GetString("i18n_csv", resourceCulture); } } /// - /// 查找 System.Byte[] 类型的本地化资源。 + /// Looks up a localized resource of type System.Byte[]. /// - internal static byte[] libsscrypto_dll { + public static byte[] libsscrypto_dll { get { object obj = ResourceManager.GetObject("libsscrypto_dll", resourceCulture); return ((byte[])(obj)); @@ -126,22 +129,22 @@ namespace Shadowsocks.Properties { } /// - /// 查找类似 <?xml version="1.0" encoding="utf-8" ?> + /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> ///<!-- Warning: Configuration may reset after shadowsocks upgrade. --> ///<!-- If you messed it up, delete this file and Shadowsocks will create a new one. --> ///<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> /// <targets> /// <!-- This line is managed by Shadowsocks. Do not modify it unless you know what you are doing.--> - /// <target name="file" xsi:type="File" fileName="ss_win_temp\shadowsocks.log" writ [字符串的其余部分被截断]"; 的本地化字符串。 + /// <target name="file" xsi:type="File" fileName="ss_win_temp\shadowsocks.log" writ [rest of string was truncated]";. /// - internal static string NLog_config { + public static string NLog_config { get { return ResourceManager.GetString("NLog_config", resourceCulture); } } /// - /// 查找类似 listen-address __PRIVOXY_BIND_IP__:__PRIVOXY_BIND_PORT__ + /// Looks up a localized string similar to listen-address __PRIVOXY_BIND_IP__:__PRIVOXY_BIND_PORT__ ///toggle 0 ///logfile ss_privoxy.log ///show-on-task-bar 0 @@ -149,18 +152,18 @@ namespace Shadowsocks.Properties { ///forward-socks5 / __SOCKS_HOST__:__SOCKS_PORT__ . ///max-client-connections 2048 ///hide-console - /// 的本地化字符串。 + ///. /// - internal static string privoxy_conf { + public static string privoxy_conf { get { return ResourceManager.GetString("privoxy_conf", resourceCulture); } } /// - /// 查找 System.Byte[] 类型的本地化资源。 + /// Looks up a localized resource of type System.Byte[]. /// - internal static byte[] privoxy_exe { + public static byte[] privoxy_exe { get { object obj = ResourceManager.GetObject("privoxy_exe", resourceCulture); return ((byte[])(obj)); @@ -168,9 +171,9 @@ namespace Shadowsocks.Properties { } /// - /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// Looks up a localized resource of type System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap ss32Fill { + public static System.Drawing.Bitmap ss32Fill { get { object obj = ResourceManager.GetObject("ss32Fill", resourceCulture); return ((System.Drawing.Bitmap)(obj)); @@ -178,9 +181,9 @@ namespace Shadowsocks.Properties { } /// - /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// Looks up a localized resource of type System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap ss32In { + public static System.Drawing.Bitmap ss32In { get { object obj = ResourceManager.GetObject("ss32In", resourceCulture); return ((System.Drawing.Bitmap)(obj)); @@ -188,9 +191,9 @@ namespace Shadowsocks.Properties { } /// - /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// Looks up a localized resource of type System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap ss32Out { + public static System.Drawing.Bitmap ss32Out { get { object obj = ResourceManager.GetObject("ss32Out", resourceCulture); return ((System.Drawing.Bitmap)(obj)); @@ -198,9 +201,9 @@ namespace Shadowsocks.Properties { } /// - /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// Looks up a localized resource of type System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap ss32Outline { + public static System.Drawing.Bitmap ss32Outline { get { object obj = ResourceManager.GetObject("ss32Outline", resourceCulture); return ((System.Drawing.Bitmap)(obj)); @@ -208,9 +211,9 @@ namespace Shadowsocks.Properties { } /// - /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// Looks up a localized resource of type System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap ssw128 { + public static System.Drawing.Bitmap ssw128 { get { object obj = ResourceManager.GetObject("ssw128", resourceCulture); return ((System.Drawing.Bitmap)(obj)); @@ -218,9 +221,9 @@ namespace Shadowsocks.Properties { } /// - /// 查找 System.Byte[] 类型的本地化资源。 + /// Looks up a localized resource of type System.Byte[]. /// - internal static byte[] sysproxy_exe { + public static byte[] sysproxy_exe { get { object obj = ResourceManager.GetObject("sysproxy_exe", resourceCulture); return ((byte[])(obj)); @@ -228,9 +231,9 @@ namespace Shadowsocks.Properties { } /// - /// 查找 System.Byte[] 类型的本地化资源。 + /// Looks up a localized resource of type System.Byte[]. /// - internal static byte[] sysproxy64_exe { + public static byte[] sysproxy64_exe { get { object obj = ResourceManager.GetObject("sysproxy64_exe", resourceCulture); return ((byte[])(obj)); @@ -238,11 +241,11 @@ namespace Shadowsocks.Properties { } /// - /// 查找类似 ! Put user rules line by line in this file. + /// Looks up a localized string similar to ! Put user rules line by line in this file. ///! See https://adblockplus.org/en/filter-cheatsheet - /// 的本地化字符串。 + ///. /// - internal static string user_rule { + public static string user_rule { get { return ResourceManager.GetString("user_rule", resourceCulture); } diff --git a/shadowsocks-csharp/View/HotkeySettingsForm.cs b/shadowsocks-csharp/View/HotkeySettingsForm.cs deleted file mode 100644 index 58c0f6bd..00000000 --- a/shadowsocks-csharp/View/HotkeySettingsForm.cs +++ /dev/null @@ -1,190 +0,0 @@ -using Shadowsocks.Controller; -using Shadowsocks.Model; -using Shadowsocks.Properties; -using System; -using System.Drawing; -using System.Text; -using System.Windows.Forms; -using static Shadowsocks.Controller.HotkeyReg; - -namespace Shadowsocks.View -{ - public partial class HotkeySettingsForm : Form - { - private readonly ShadowsocksController _controller; - - // this is a copy of hotkey configuration that we are working on - private HotkeyConfig _modifiedHotkeyConfig; - - public HotkeySettingsForm(ShadowsocksController controller) - { - InitializeComponent(); - UpdateTexts(); - Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); - - _controller = controller; - _controller.ConfigChanged += controller_ConfigChanged; - - LoadCurrentConfiguration(); - } - - private void UpdateTexts() - { - I18N.TranslateForm(this); - } - - private void controller_ConfigChanged(object sender, EventArgs e) - { - LoadCurrentConfiguration(); - } - - private void LoadCurrentConfiguration() - { - _modifiedHotkeyConfig = _controller.GetCurrentConfiguration().hotkey; - SetConfigToUI(_modifiedHotkeyConfig); - } - - private void SetConfigToUI(HotkeyConfig config) - { - SwitchSystemProxyTextBox.Text = config.SwitchSystemProxy; - SwitchProxyModeTextBox.Text = config.SwitchSystemProxyMode; - SwitchAllowLanTextBox.Text = config.SwitchAllowLan; - ShowLogsTextBox.Text = config.ShowLogs; - ServerMoveUpTextBox.Text = config.ServerMoveUp; - ServerMoveDownTextBox.Text = config.ServerMoveDown; - RegHotkeysAtStartupCheckBox.Checked = config.RegHotkeysAtStartup; - } - - private void SaveConfig() - { - _controller.SaveHotkeyConfig(_modifiedHotkeyConfig); - } - - private HotkeyConfig GetConfigFromUI() - { - return new HotkeyConfig - { - SwitchSystemProxy = SwitchSystemProxyTextBox.Text, - SwitchSystemProxyMode = SwitchProxyModeTextBox.Text, - SwitchAllowLan = SwitchAllowLanTextBox.Text, - ShowLogs = ShowLogsTextBox.Text, - ServerMoveUp = ServerMoveUpTextBox.Text, - ServerMoveDown = ServerMoveDownTextBox.Text, - RegHotkeysAtStartup = RegHotkeysAtStartupCheckBox.Checked - }; - } - - /// - /// Capture hotkey - Press key - /// - private void HotkeyDown(object sender, KeyEventArgs e) - { - StringBuilder sb = new StringBuilder(); - //Combination key only - if (e.Modifiers != 0) - { - // XXX: Hotkey parsing depends on the sequence, more specifically, ModifierKeysConverter. - // Windows key is reserved by operating system, we deny this key. - if (e.Control) - { - sb.Append("Ctrl+"); - } - if (e.Alt) - { - sb.Append("Alt+"); - } - if (e.Shift) - { - sb.Append("Shift+"); - } - - Keys keyvalue = (Keys)e.KeyValue; - if ((keyvalue >= Keys.PageUp && keyvalue <= Keys.Down) || - (keyvalue >= Keys.A && keyvalue <= Keys.Z) || - (keyvalue >= Keys.F1 && keyvalue <= Keys.F12)) - { - sb.Append(e.KeyCode); - } - else if (keyvalue >= Keys.D0 && keyvalue <= Keys.D9) - { - sb.Append('D').Append((char)e.KeyValue); - } - else if (keyvalue >= Keys.NumPad0 && keyvalue <= Keys.NumPad9) - { - sb.Append("NumPad").Append((char)(e.KeyValue - 48)); - } - } - ((TextBox)sender).Text = sb.ToString(); - } - - /// - /// Capture hotkey - Release key - /// - private void HotkeyUp(object sender, KeyEventArgs e) - { - var tb = (TextBox)sender; - var content = tb.Text.TrimEnd(); - if (content.Length >= 1 && content[content.Length - 1] == '+') - { - tb.Text = ""; - } - } - - private void CancelButton_Click(object sender, EventArgs e) - { - this.Close(); - } - - private void OKButton_Click(object sender, EventArgs e) - { - _modifiedHotkeyConfig = GetConfigFromUI(); - // try to register, notify to change settings if failed - if (!RegisterAllHotkeys(_modifiedHotkeyConfig)) - { - MessageBox.Show(I18N.GetString("Register hotkey failed")); - } - - // All check passed, saving - SaveConfig(); - this.Close(); - } - - private void RegisterAllButton_Click(object sender, EventArgs e) - { - _modifiedHotkeyConfig = GetConfigFromUI(); - RegisterAllHotkeys(_modifiedHotkeyConfig); - } - - private bool RegisterAllHotkeys(HotkeyConfig hotkeyConfig) - { - return - RegHotkeyFromString(hotkeyConfig.SwitchSystemProxy, "SwitchSystemProxyCallback", result => HandleRegResult(hotkeyConfig.SwitchSystemProxy, SwitchSystemProxyLabel, result)) - && RegHotkeyFromString(hotkeyConfig.SwitchSystemProxyMode, "SwitchSystemProxyModeCallback", result => HandleRegResult(hotkeyConfig.SwitchSystemProxyMode, SwitchProxyModeLabel, result)) - && RegHotkeyFromString(hotkeyConfig.SwitchAllowLan, "SwitchAllowLanCallback", result => HandleRegResult(hotkeyConfig.SwitchAllowLan, SwitchAllowLanLabel, result)) - && RegHotkeyFromString(hotkeyConfig.ShowLogs, "ShowLogsCallback", result => HandleRegResult(hotkeyConfig.ShowLogs, ShowLogsLabel, result)) - && RegHotkeyFromString(hotkeyConfig.ServerMoveUp, "ServerMoveUpCallback", result => HandleRegResult(hotkeyConfig.ServerMoveUp, ServerMoveUpLabel, result)) - && RegHotkeyFromString(hotkeyConfig.ServerMoveDown, "ServerMoveDownCallback", result => HandleRegResult(hotkeyConfig.ServerMoveDown, ServerMoveDownLabel, result)); - } - - private void HandleRegResult(string hotkeyStr, Label label, RegResult result) - { - switch (result) - { - case RegResult.ParseError: - MessageBox.Show(I18N.GetString("Cannot parse hotkey: {0}", hotkeyStr)); - break; - case RegResult.UnregSuccess: - label.ResetBackColor(); - break; - case RegResult.RegSuccess: - label.BackColor = Color.Green; - break; - case RegResult.RegFailure: - label.BackColor = Color.Red; - break; - default: - break; - } - } - } -} \ No newline at end of file diff --git a/shadowsocks-csharp/View/HotkeySettingsForm.designer.cs b/shadowsocks-csharp/View/HotkeySettingsForm.designer.cs deleted file mode 100644 index 47f89946..00000000 --- a/shadowsocks-csharp/View/HotkeySettingsForm.designer.cs +++ /dev/null @@ -1,346 +0,0 @@ -namespace Shadowsocks.View -{ - partial class HotkeySettingsForm - { - /// - /// 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() - { - System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; - this.btnOK = new System.Windows.Forms.Button(); - this.btnCancel = new System.Windows.Forms.Button(); - this.btnRegisterAll = new System.Windows.Forms.Button(); - this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); - this.RegHotkeysAtStartupLabel = new System.Windows.Forms.Label(); - this.SwitchSystemProxyLabel = new System.Windows.Forms.Label(); - this.SwitchProxyModeLabel = new System.Windows.Forms.Label(); - this.SwitchAllowLanLabel = new System.Windows.Forms.Label(); - this.ShowLogsLabel = new System.Windows.Forms.Label(); - this.ServerMoveUpLabel = new System.Windows.Forms.Label(); - this.ServerMoveDownLabel = new System.Windows.Forms.Label(); - this.SwitchSystemProxyTextBox = new System.Windows.Forms.TextBox(); - this.SwitchProxyModeTextBox = new System.Windows.Forms.TextBox(); - this.SwitchAllowLanTextBox = new System.Windows.Forms.TextBox(); - this.ShowLogsTextBox = new System.Windows.Forms.TextBox(); - this.ServerMoveUpTextBox = new System.Windows.Forms.TextBox(); - this.ServerMoveDownTextBox = new System.Windows.Forms.TextBox(); - this.RegHotkeysAtStartupCheckBox = new System.Windows.Forms.CheckBox(); - flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); - flowLayoutPanel1.SuspendLayout(); - this.tableLayoutPanel1.SuspendLayout(); - this.SuspendLayout(); - // - // flowLayoutPanel1 - // - this.tableLayoutPanel1.SetColumnSpan(flowLayoutPanel1, 2); - flowLayoutPanel1.Controls.Add(this.btnOK); - flowLayoutPanel1.Controls.Add(this.btnCancel); - flowLayoutPanel1.Controls.Add(this.btnRegisterAll); - flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.BottomUp; - flowLayoutPanel1.Location = new System.Drawing.Point(0, 248); - flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); - flowLayoutPanel1.Name = "flowLayoutPanel1"; - flowLayoutPanel1.Padding = new System.Windows.Forms.Padding(0, 0, 20, 0); - flowLayoutPanel1.RightToLeft = System.Windows.Forms.RightToLeft.Yes; - flowLayoutPanel1.Size = new System.Drawing.Size(594, 52); - flowLayoutPanel1.TabIndex = 6; - // - // btnOK - // - this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; - this.btnOK.Location = new System.Drawing.Point(416, 9); - this.btnOK.Margin = new System.Windows.Forms.Padding(4); - this.btnOK.Name = "btnOK"; - this.btnOK.Size = new System.Drawing.Size(154, 39); - this.btnOK.TabIndex = 0; - this.btnOK.Text = "OK"; - this.btnOK.UseVisualStyleBackColor = true; - this.btnOK.Click += new System.EventHandler(this.OKButton_Click); - // - // btnCancel - // - this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.btnCancel.Location = new System.Drawing.Point(254, 9); - this.btnCancel.Margin = new System.Windows.Forms.Padding(4); - this.btnCancel.Name = "btnCancel"; - this.btnCancel.Size = new System.Drawing.Size(154, 39); - this.btnCancel.TabIndex = 1; - this.btnCancel.Text = "Cancel"; - this.btnCancel.UseVisualStyleBackColor = true; - this.btnCancel.Click += new System.EventHandler(this.CancelButton_Click); - // - // btnRegisterAll - // - this.btnRegisterAll.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.btnRegisterAll.Location = new System.Drawing.Point(92, 9); - this.btnRegisterAll.Margin = new System.Windows.Forms.Padding(4); - this.btnRegisterAll.Name = "btnRegisterAll"; - this.btnRegisterAll.Size = new System.Drawing.Size(154, 39); - this.btnRegisterAll.TabIndex = 2; - this.btnRegisterAll.Text = "Reg All"; - this.btnRegisterAll.UseVisualStyleBackColor = true; - this.btnRegisterAll.Click += new System.EventHandler(this.RegisterAllButton_Click); - // - // tableLayoutPanel1 - // - this.tableLayoutPanel1.ColumnCount = 2; - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel1.Controls.Add(this.RegHotkeysAtStartupLabel, 0, 6); - this.tableLayoutPanel1.Controls.Add(this.SwitchSystemProxyLabel, 0, 0); - this.tableLayoutPanel1.Controls.Add(this.SwitchProxyModeLabel, 0, 1); - this.tableLayoutPanel1.Controls.Add(this.SwitchAllowLanLabel, 0, 2); - this.tableLayoutPanel1.Controls.Add(this.ShowLogsLabel, 0, 3); - this.tableLayoutPanel1.Controls.Add(this.ServerMoveUpLabel, 0, 4); - this.tableLayoutPanel1.Controls.Add(this.ServerMoveDownLabel, 0, 5); - this.tableLayoutPanel1.Controls.Add(flowLayoutPanel1, 0, 7); - this.tableLayoutPanel1.Controls.Add(this.SwitchSystemProxyTextBox, 1, 0); - this.tableLayoutPanel1.Controls.Add(this.SwitchProxyModeTextBox, 1, 1); - this.tableLayoutPanel1.Controls.Add(this.SwitchAllowLanTextBox, 1, 2); - this.tableLayoutPanel1.Controls.Add(this.ShowLogsTextBox, 1, 3); - this.tableLayoutPanel1.Controls.Add(this.ServerMoveUpTextBox, 1, 4); - this.tableLayoutPanel1.Controls.Add(this.ServerMoveDownTextBox, 1, 5); - this.tableLayoutPanel1.Controls.Add(this.RegHotkeysAtStartupCheckBox, 1, 6); - this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; - this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); - this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(4); - this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.RowCount = 8; - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.16726F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.16726F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.16726F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.16726F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.7784F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.38949F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.16309F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25F)); - this.tableLayoutPanel1.Size = new System.Drawing.Size(582, 303); - this.tableLayoutPanel1.TabIndex = 0; - // - // RegHotkeysAtStartupLabel - // - this.RegHotkeysAtStartupLabel.AutoSize = true; - this.RegHotkeysAtStartupLabel.Dock = System.Windows.Forms.DockStyle.Right; - this.RegHotkeysAtStartupLabel.Location = new System.Drawing.Point(40, 213); - this.RegHotkeysAtStartupLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); - this.RegHotkeysAtStartupLabel.Name = "RegHotkeysAtStartupLabel"; - this.RegHotkeysAtStartupLabel.Size = new System.Drawing.Size(199, 35); - this.RegHotkeysAtStartupLabel.TabIndex = 16; - this.RegHotkeysAtStartupLabel.Text = "Reg Hotkeys At Startup"; - this.RegHotkeysAtStartupLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // - // SwitchSystemProxyLabel - // - this.SwitchSystemProxyLabel.AutoSize = true; - this.SwitchSystemProxyLabel.Dock = System.Windows.Forms.DockStyle.Right; - this.SwitchSystemProxyLabel.Location = new System.Drawing.Point(63, 0); - this.SwitchSystemProxyLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); - this.SwitchSystemProxyLabel.Name = "SwitchSystemProxyLabel"; - this.SwitchSystemProxyLabel.Size = new System.Drawing.Size(176, 35); - this.SwitchSystemProxyLabel.TabIndex = 0; - this.SwitchSystemProxyLabel.Text = "Switch system proxy"; - this.SwitchSystemProxyLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // - // SwitchProxyModeLabel - // - this.SwitchProxyModeLabel.AutoSize = true; - this.SwitchProxyModeLabel.Dock = System.Windows.Forms.DockStyle.Right; - this.SwitchProxyModeLabel.Location = new System.Drawing.Point(10, 35); - this.SwitchProxyModeLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); - this.SwitchProxyModeLabel.Name = "SwitchProxyModeLabel"; - this.SwitchProxyModeLabel.Size = new System.Drawing.Size(229, 35); - this.SwitchProxyModeLabel.TabIndex = 1; - this.SwitchProxyModeLabel.Text = "Switch system proxy mode"; - this.SwitchProxyModeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // - // SwitchAllowLanLabel - // - this.SwitchAllowLanLabel.AutoSize = true; - this.SwitchAllowLanLabel.Dock = System.Windows.Forms.DockStyle.Right; - this.SwitchAllowLanLabel.Location = new System.Drawing.Point(39, 70); - this.SwitchAllowLanLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); - this.SwitchAllowLanLabel.Name = "SwitchAllowLanLabel"; - this.SwitchAllowLanLabel.Size = new System.Drawing.Size(200, 35); - this.SwitchAllowLanLabel.TabIndex = 3; - this.SwitchAllowLanLabel.Text = "Allow Clients from LAN"; - this.SwitchAllowLanLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // - // ShowLogsLabel - // - this.ShowLogsLabel.AutoSize = true; - this.ShowLogsLabel.Dock = System.Windows.Forms.DockStyle.Right; - this.ShowLogsLabel.Location = new System.Drawing.Point(129, 105); - this.ShowLogsLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); - this.ShowLogsLabel.Name = "ShowLogsLabel"; - this.ShowLogsLabel.Size = new System.Drawing.Size(110, 35); - this.ShowLogsLabel.TabIndex = 4; - this.ShowLogsLabel.Text = "Show Logs..."; - this.ShowLogsLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // - // ServerMoveUpLabel - // - this.ServerMoveUpLabel.AutoSize = true; - this.ServerMoveUpLabel.Dock = System.Windows.Forms.DockStyle.Right; - this.ServerMoveUpLabel.Location = new System.Drawing.Point(25, 140); - this.ServerMoveUpLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); - this.ServerMoveUpLabel.Name = "ServerMoveUpLabel"; - this.ServerMoveUpLabel.Size = new System.Drawing.Size(214, 37); - this.ServerMoveUpLabel.TabIndex = 4; - this.ServerMoveUpLabel.Text = "Switch to previous server"; - this.ServerMoveUpLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // - // ServerMoveDownLabel - // - this.ServerMoveDownLabel.AutoSize = true; - this.ServerMoveDownLabel.Dock = System.Windows.Forms.DockStyle.Right; - this.ServerMoveDownLabel.Location = new System.Drawing.Point(60, 177); - this.ServerMoveDownLabel.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0); - this.ServerMoveDownLabel.Name = "ServerMoveDownLabel"; - this.ServerMoveDownLabel.Size = new System.Drawing.Size(179, 36); - this.ServerMoveDownLabel.TabIndex = 4; - this.ServerMoveDownLabel.Text = "Switch to next server"; - this.ServerMoveDownLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // - // SwitchSystemProxyTextBox - // - this.SwitchSystemProxyTextBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.SwitchSystemProxyTextBox.Location = new System.Drawing.Point(252, 3); - this.SwitchSystemProxyTextBox.Name = "SwitchSystemProxyTextBox"; - this.SwitchSystemProxyTextBox.ReadOnly = true; - this.SwitchSystemProxyTextBox.Size = new System.Drawing.Size(339, 29); - this.SwitchSystemProxyTextBox.TabIndex = 7; - this.SwitchSystemProxyTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); - this.SwitchSystemProxyTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); - // - // SwitchProxyModeTextBox - // - this.SwitchProxyModeTextBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.SwitchProxyModeTextBox.Location = new System.Drawing.Point(252, 38); - this.SwitchProxyModeTextBox.Name = "SwitchProxyModeTextBox"; - this.SwitchProxyModeTextBox.ReadOnly = true; - this.SwitchProxyModeTextBox.Size = new System.Drawing.Size(339, 29); - this.SwitchProxyModeTextBox.TabIndex = 8; - this.SwitchProxyModeTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); - this.SwitchProxyModeTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); - // - // SwitchAllowLanTextBox - // - this.SwitchAllowLanTextBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.SwitchAllowLanTextBox.Location = new System.Drawing.Point(252, 73); - this.SwitchAllowLanTextBox.Name = "SwitchAllowLanTextBox"; - this.SwitchAllowLanTextBox.ReadOnly = true; - this.SwitchAllowLanTextBox.Size = new System.Drawing.Size(339, 29); - this.SwitchAllowLanTextBox.TabIndex = 10; - this.SwitchAllowLanTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); - this.SwitchAllowLanTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); - // - // ShowLogsTextBox - // - this.ShowLogsTextBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.ShowLogsTextBox.Location = new System.Drawing.Point(252, 108); - this.ShowLogsTextBox.Name = "ShowLogsTextBox"; - this.ShowLogsTextBox.ReadOnly = true; - this.ShowLogsTextBox.Size = new System.Drawing.Size(339, 29); - this.ShowLogsTextBox.TabIndex = 11; - this.ShowLogsTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); - this.ShowLogsTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); - // - // ServerMoveUpTextBox - // - this.ServerMoveUpTextBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.ServerMoveUpTextBox.Location = new System.Drawing.Point(252, 143); - this.ServerMoveUpTextBox.Name = "ServerMoveUpTextBox"; - this.ServerMoveUpTextBox.ReadOnly = true; - this.ServerMoveUpTextBox.Size = new System.Drawing.Size(339, 29); - this.ServerMoveUpTextBox.TabIndex = 12; - this.ServerMoveUpTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); - this.ServerMoveUpTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); - // - // ServerMoveDownTextBox - // - this.ServerMoveDownTextBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.ServerMoveDownTextBox.Location = new System.Drawing.Point(252, 180); - this.ServerMoveDownTextBox.Name = "ServerMoveDownTextBox"; - this.ServerMoveDownTextBox.ReadOnly = true; - this.ServerMoveDownTextBox.Size = new System.Drawing.Size(339, 29); - this.ServerMoveDownTextBox.TabIndex = 13; - this.ServerMoveDownTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.HotkeyDown); - this.ServerMoveDownTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.HotkeyUp); - // - // RegHotkeysAtStartupCheckBox - // - this.RegHotkeysAtStartupCheckBox.AutoSize = true; - this.RegHotkeysAtStartupCheckBox.Dock = System.Windows.Forms.DockStyle.Left; - this.RegHotkeysAtStartupCheckBox.Location = new System.Drawing.Point(252, 216); - this.RegHotkeysAtStartupCheckBox.Name = "RegHotkeysAtStartupCheckBox"; - this.RegHotkeysAtStartupCheckBox.Size = new System.Drawing.Size(18, 29); - this.RegHotkeysAtStartupCheckBox.TabIndex = 17; - this.RegHotkeysAtStartupCheckBox.UseVisualStyleBackColor = true; - // - // HotkeySettingsForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(120F, 120F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.ClientSize = new System.Drawing.Size(582, 303); - this.Controls.Add(this.tableLayoutPanel1); - this.Font = new System.Drawing.Font("微软雅黑", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.Margin = new System.Windows.Forms.Padding(5, 6, 5, 6); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "HotkeySettingsForm"; - this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Edit Hotkeys..."; - flowLayoutPanel1.ResumeLayout(false); - this.tableLayoutPanel1.ResumeLayout(false); - this.tableLayoutPanel1.PerformLayout(); - this.ResumeLayout(false); - - } - - #endregion - private System.Windows.Forms.Label SwitchSystemProxyLabel; - private System.Windows.Forms.Label SwitchProxyModeLabel; - private System.Windows.Forms.Label SwitchAllowLanLabel; - private System.Windows.Forms.Label ShowLogsLabel; - private System.Windows.Forms.Label ServerMoveUpLabel; - private System.Windows.Forms.Label ServerMoveDownLabel; - private System.Windows.Forms.Button btnOK; - private System.Windows.Forms.Button btnCancel; - private System.Windows.Forms.TextBox ShowLogsTextBox; - private System.Windows.Forms.TextBox SwitchAllowLanTextBox; - private System.Windows.Forms.TextBox SwitchProxyModeTextBox; - private System.Windows.Forms.TextBox SwitchSystemProxyTextBox; - private System.Windows.Forms.TextBox ServerMoveUpTextBox; - private System.Windows.Forms.TextBox ServerMoveDownTextBox; - private System.Windows.Forms.Button btnRegisterAll; - private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; - private System.Windows.Forms.Label RegHotkeysAtStartupLabel; - private System.Windows.Forms.CheckBox RegHotkeysAtStartupCheckBox; - } -} \ No newline at end of file diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 8ba600ac..da3ea91e 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -1,5 +1,6 @@ using NLog; using Shadowsocks.Controller; +using Shadowsocks.Localization; using Shadowsocks.Model; using Shadowsocks.Properties; using Shadowsocks.Util; @@ -11,6 +12,8 @@ using System.IO; using System.Linq; using System.Text; using System.Windows.Forms; +using System.Windows.Forms.Integration; +using System.Windows.Threading; using ZXing; using ZXing.Common; using ZXing.QrCode; @@ -19,18 +22,14 @@ namespace Shadowsocks.View { public class MenuViewController { - private static Logger logger = LogManager.GetCurrentClassLogger(); - // yes this is just a menu view controller - // when config form is closed, it moves away from RAM - // and it should just do anything related to the config form + private readonly Logger logger = LogManager.GetCurrentClassLogger(); private ShadowsocksController controller; - private UpdateChecker updateChecker; + public UpdateChecker updateChecker; private NotifyIcon _notifyIcon; private Icon icon, icon_in, icon_out, icon_both, previousIcon; - private bool _isStartupChecking; private string _urlToOpen; private ContextMenu contextMenu1; @@ -61,12 +60,12 @@ namespace Shadowsocks.View private MenuItem onlineConfigItem; private ConfigForm configForm; - private ProxyForm proxyForm; private LogForm logForm; - private HotkeySettingsForm hotkeySettingsForm; - private OnlineConfigForm onlineConfigForm; private System.Windows.Window serverSharingWindow; + private System.Windows.Window hotkeysWindow; + private System.Windows.Window forwardProxyWindow; + private System.Windows.Window onlineConfigWindow; // color definition for icon color transformation private readonly Color colorMaskBlue = Color.FromArgb(255, 25, 125, 191); @@ -102,7 +101,7 @@ namespace Shadowsocks.View _notifyIcon.BalloonTipClosed += _notifyIcon_BalloonTipClosed; controller.TrafficChanged += controller_TrafficChanged; - this.updateChecker = new UpdateChecker(); + updateChecker = new UpdateChecker(); updateChecker.CheckUpdateCompleted += updateChecker_CheckUpdateCompleted; LoadCurrentConfiguration(); @@ -115,8 +114,7 @@ namespace Shadowsocks.View } else if (config.autoCheckUpdate) { - _isStartupChecking = true; - updateChecker.CheckUpdate(config, 3000); + Dispatcher.CurrentDispatcher.Invoke(() => updateChecker.CheckForVersionUpdate(3000)); } } @@ -383,36 +381,6 @@ namespace Shadowsocks.View } } - private void ShowProxyForm() - { - if (proxyForm != null) - { - proxyForm.Activate(); - } - else - { - proxyForm = new ProxyForm(controller); - proxyForm.Show(); - proxyForm.Activate(); - proxyForm.FormClosed += proxyForm_FormClosed; - } - } - - private void ShowHotKeySettingsForm() - { - if (hotkeySettingsForm != null) - { - hotkeySettingsForm.Activate(); - } - else - { - hotkeySettingsForm = new HotkeySettingsForm(controller); - hotkeySettingsForm.Show(); - hotkeySettingsForm.Activate(); - hotkeySettingsForm.FormClosed += hotkeySettingsForm_FormClosed; - } - } - private void ShowLogForm() { if (logForm != null) @@ -428,22 +396,6 @@ namespace Shadowsocks.View } } - private void ShowOnlineConfigForm() - { - - if (onlineConfigForm != null) - { - onlineConfigForm.Activate(); - } - else - { - onlineConfigForm = new OnlineConfigForm(controller); - onlineConfigForm.Show(); - onlineConfigForm.Activate(); - onlineConfigForm.FormClosed += onlineConfigForm_FormClosed; - } - } - void logForm_FormClosed(object sender, FormClosedEventArgs e) { logForm.Dispose(); @@ -468,24 +420,6 @@ namespace Shadowsocks.View } } - void proxyForm_FormClosed(object sender, FormClosedEventArgs e) - { - proxyForm.Dispose(); - proxyForm = null; - } - - void hotkeySettingsForm_FormClosed(object sender, FormClosedEventArgs e) - { - hotkeySettingsForm.Dispose(); - hotkeySettingsForm = null; - } - - void onlineConfigForm_FormClosed(object sender, FormClosedEventArgs e) - { - onlineConfigForm.Dispose(); - onlineConfigForm = null; - } - #endregion #region Misc @@ -500,23 +434,10 @@ namespace Shadowsocks.View void notifyIcon1_BalloonTipClicked(object sender, EventArgs e) { - if (updateChecker.NewVersionFound) - { - updateChecker.NewVersionFound = false; /* Reset the flag */ - if (File.Exists(updateChecker.LatestVersionLocalName)) - { - string argument = "/select, \"" + updateChecker.LatestVersionLocalName + "\""; - Process.Start("explorer.exe", argument); - } - } } private void _notifyIcon_BalloonTipClosed(object sender, EventArgs e) { - if (updateChecker.NewVersionFound) - { - updateChecker.NewVersionFound = false; /* Reset the flag */ - } } private void notifyIcon1_Click(object sender, MouseEventArgs e) @@ -541,8 +462,7 @@ namespace Shadowsocks.View Configuration config = controller.GetCurrentConfiguration(); if (config.firstRun) return; - _isStartupChecking = true; - updateChecker.CheckUpdate(config, 3000); + Dispatcher.CurrentDispatcher.Invoke(() => updateChecker.CheckForVersionUpdate(3000)); } public void ShowLogForm_HotKey() @@ -561,19 +481,83 @@ namespace Shadowsocks.View private void proxyItem_Click(object sender, EventArgs e) { - ShowProxyForm(); + if (forwardProxyWindow == null) + { + forwardProxyWindow = new System.Windows.Window() + { + Title = LocalizationProvider.GetLocalizedValue("ForwardProxy"), + Height = 400, + Width = 280, + MinHeight = 400, + MinWidth = 280, + Content = new ForwardProxyView() + }; + forwardProxyWindow.Closed += ForwardProxyWindow_Closed; + ElementHost.EnableModelessKeyboardInterop(forwardProxyWindow); + forwardProxyWindow.Show(); + } + forwardProxyWindow.Activate(); + } + + private void ForwardProxyWindow_Closed(object sender, EventArgs e) + { + forwardProxyWindow = null; } + public void CloseForwardProxyWindow() => forwardProxyWindow.Close(); + private void OnlineConfig_Click(object sender, EventArgs e) { - ShowOnlineConfigForm(); + if (onlineConfigWindow == null) + { + onlineConfigWindow = new System.Windows.Window() + { + Title = LocalizationProvider.GetLocalizedValue("OnlineConfigDelivery"), + Height = 510, + Width = 480, + MinHeight = 510, + MinWidth = 480, + Content = new OnlineConfigView() + }; + onlineConfigWindow.Closed += OnlineConfigWindow_Closed; + ElementHost.EnableModelessKeyboardInterop(onlineConfigWindow); + onlineConfigWindow.Show(); + } + onlineConfigWindow.Activate(); + } + + private void OnlineConfigWindow_Closed(object sender, EventArgs e) + { + onlineConfigWindow = null; } private void hotKeyItem_Click(object sender, EventArgs e) { - ShowHotKeySettingsForm(); + if (hotkeysWindow == null) + { + hotkeysWindow = new System.Windows.Window() + { + Title = LocalizationProvider.GetLocalizedValue("Hotkeys"), + Height = 260, + Width = 320, + MinHeight = 260, + MinWidth = 320, + Content = new HotkeysView() + }; + hotkeysWindow.Closed += HotkeysWindow_Closed; + ElementHost.EnableModelessKeyboardInterop(hotkeysWindow); + hotkeysWindow.Show(); + } + hotkeysWindow.Activate(); + } + + private void HotkeysWindow_Closed(object sender, EventArgs e) + { + hotkeysWindow = null; } + public void CloseHotkeysWindow() => hotkeysWindow.Close(); + private void ShareOverLANItem_Click(object sender, EventArgs e) { ShareOverLANItem.Checked = !ShareOverLANItem.Checked; @@ -750,12 +734,15 @@ namespace Shadowsocks.View { serverSharingWindow = new System.Windows.Window() { - Title = "Server Sharing", + Title = LocalizationProvider.GetLocalizedValue("ServerSharing"), Height = 400, Width = 660, + MinHeight = 400, + MinWidth = 660, Content = new ServerSharingView() }; serverSharingWindow.Closed += ServerSharingWindow_Closed; + ElementHost.EnableModelessKeyboardInterop(serverSharingWindow); serverSharingWindow.Show(); } serverSharingWindow.Activate(); @@ -1017,15 +1004,10 @@ namespace Shadowsocks.View void updateChecker_CheckUpdateCompleted(object sender, EventArgs e) { - if (updateChecker.NewVersionFound) - { - ShowBalloonTip(I18N.GetString("Shadowsocks {0} Update Found", updateChecker.LatestVersionNumber + updateChecker.LatestVersionSuffix), I18N.GetString("Click here to update"), ToolTipIcon.Info, 5000); - } - else if (!_isStartupChecking) + if (updateChecker.NewReleaseZipFilename == null) { ShowBalloonTip(I18N.GetString("Shadowsocks"), I18N.GetString("No update is available"), ToolTipIcon.Info, 5000); } - _isStartupChecking = false; } private void UpdateUpdateMenu() @@ -1049,9 +1031,9 @@ namespace Shadowsocks.View UpdateUpdateMenu(); } - private void checkUpdatesItem_Click(object sender, EventArgs e) + private async void checkUpdatesItem_Click(object sender, EventArgs e) { - updateChecker.CheckUpdate(controller.GetCurrentConfiguration()); + await updateChecker.CheckForVersionUpdate(); } private void AboutItem_Click(object sender, EventArgs e) diff --git a/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs b/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs deleted file mode 100644 index 89b4f12a..00000000 --- a/shadowsocks-csharp/View/OnlineConfigForm.Designer.cs +++ /dev/null @@ -1,218 +0,0 @@ -namespace Shadowsocks.View -{ - partial class OnlineConfigForm - { - /// - /// 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.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); - this.UrlListBox = new System.Windows.Forms.ListBox(); - this.label1 = new System.Windows.Forms.Label(); - this.UrlTextBox = new System.Windows.Forms.TextBox(); - this.UpdateButton = new System.Windows.Forms.Button(); - this.AddButton = new System.Windows.Forms.Button(); - this.DeleteButton = new System.Windows.Forms.Button(); - this.OkButton = new System.Windows.Forms.Button(); - this.UpdateAllButton = new System.Windows.Forms.Button(); - this.CancelButton = new System.Windows.Forms.Button(); - this.tableLayoutPanel1.SuspendLayout(); - this.SuspendLayout(); - // - // tableLayoutPanel1 - // - this.tableLayoutPanel1.ColumnCount = 3; - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); - this.tableLayoutPanel1.Controls.Add(this.UrlListBox, 0, 0); - this.tableLayoutPanel1.Controls.Add(this.label1, 0, 1); - this.tableLayoutPanel1.Controls.Add(this.UrlTextBox, 1, 1); - this.tableLayoutPanel1.Controls.Add(this.UpdateButton, 0, 2); - this.tableLayoutPanel1.Controls.Add(this.AddButton, 1, 2); - this.tableLayoutPanel1.Controls.Add(this.DeleteButton, 2, 2); - this.tableLayoutPanel1.Controls.Add(this.OkButton, 1, 3); - this.tableLayoutPanel1.Controls.Add(this.UpdateAllButton, 0, 3); - this.tableLayoutPanel1.Controls.Add(this.CancelButton, 2, 3); - this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; - this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); - this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(3); - this.tableLayoutPanel1.RowCount = 4; - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.Size = new System.Drawing.Size(482, 453); - this.tableLayoutPanel1.TabIndex = 0; - // - // UrlListBox - // - this.tableLayoutPanel1.SetColumnSpan(this.UrlListBox, 3); - this.UrlListBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.UrlListBox.FormattingEnabled = true; - this.UrlListBox.ItemHeight = 15; - this.UrlListBox.Location = new System.Drawing.Point(13, 13); - this.UrlListBox.Margin = new System.Windows.Forms.Padding(10); - this.UrlListBox.Name = "UrlListBox"; - this.UrlListBox.Size = new System.Drawing.Size(456, 334); - this.UrlListBox.TabIndex = 0; - this.UrlListBox.SelectedIndexChanged += new System.EventHandler(this.UrlListBox_SelectedIndexChanged); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Dock = System.Windows.Forms.DockStyle.Fill; - this.label1.Location = new System.Drawing.Point(6, 357); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(152, 31); - this.label1.TabIndex = 1; - this.label1.Text = "Online config URL"; - this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - // - // UrlTextBox - // - this.tableLayoutPanel1.SetColumnSpan(this.UrlTextBox, 2); - this.UrlTextBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.UrlTextBox.Location = new System.Drawing.Point(164, 360); - this.UrlTextBox.Margin = new System.Windows.Forms.Padding(3, 3, 15, 3); - this.UrlTextBox.Name = "UrlTextBox"; - this.UrlTextBox.Size = new System.Drawing.Size(300, 25); - this.UrlTextBox.TabIndex = 2; - // - // UpdateButton - // - this.UpdateButton.Dock = System.Windows.Forms.DockStyle.Fill; - this.UpdateButton.Location = new System.Drawing.Point(23, 391); - this.UpdateButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); - this.UpdateButton.MaximumSize = new System.Drawing.Size(0, 25); - this.UpdateButton.MinimumSize = new System.Drawing.Size(0, 25); - this.UpdateButton.Name = "UpdateButton"; - this.UpdateButton.Size = new System.Drawing.Size(118, 25); - this.UpdateButton.TabIndex = 3; - this.UpdateButton.Text = "&Update"; - this.UpdateButton.UseVisualStyleBackColor = true; - this.UpdateButton.Click += new System.EventHandler(this.UpdateButton_Click); - // - // AddButton - // - this.AddButton.Dock = System.Windows.Forms.DockStyle.Fill; - this.AddButton.Location = new System.Drawing.Point(181, 391); - this.AddButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); - this.AddButton.MaximumSize = new System.Drawing.Size(0, 25); - this.AddButton.MinimumSize = new System.Drawing.Size(0, 25); - this.AddButton.Name = "AddButton"; - this.AddButton.Size = new System.Drawing.Size(118, 25); - this.AddButton.TabIndex = 4; - this.AddButton.Text = "&Add"; - this.AddButton.UseVisualStyleBackColor = true; - this.AddButton.Click += new System.EventHandler(this.AddButton_Click); - // - // DeleteButton - // - this.DeleteButton.Dock = System.Windows.Forms.DockStyle.Fill; - this.DeleteButton.Location = new System.Drawing.Point(339, 391); - this.DeleteButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); - this.DeleteButton.MaximumSize = new System.Drawing.Size(0, 25); - this.DeleteButton.MinimumSize = new System.Drawing.Size(0, 25); - this.DeleteButton.Name = "DeleteButton"; - this.DeleteButton.Size = new System.Drawing.Size(120, 25); - this.DeleteButton.TabIndex = 5; - this.DeleteButton.Text = "&Delete"; - this.DeleteButton.UseVisualStyleBackColor = true; - this.DeleteButton.Click += new System.EventHandler(this.DeleteButton_Click); - // - // OkButton - // - this.OkButton.Dock = System.Windows.Forms.DockStyle.Fill; - this.OkButton.Location = new System.Drawing.Point(181, 422); - this.OkButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); - this.OkButton.MaximumSize = new System.Drawing.Size(0, 25); - this.OkButton.MinimumSize = new System.Drawing.Size(0, 25); - this.OkButton.Name = "OkButton"; - this.OkButton.Size = new System.Drawing.Size(118, 25); - this.OkButton.TabIndex = 7; - this.OkButton.Text = "OK"; - this.OkButton.UseVisualStyleBackColor = true; - this.OkButton.Click += new System.EventHandler(this.OkButton_Click); - // - // UpdateAllButton - // - this.UpdateAllButton.Dock = System.Windows.Forms.DockStyle.Fill; - this.UpdateAllButton.Location = new System.Drawing.Point(23, 422); - this.UpdateAllButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); - this.UpdateAllButton.MaximumSize = new System.Drawing.Size(0, 25); - this.UpdateAllButton.MinimumSize = new System.Drawing.Size(0, 25); - this.UpdateAllButton.Name = "UpdateAllButton"; - this.UpdateAllButton.Size = new System.Drawing.Size(118, 25); - this.UpdateAllButton.TabIndex = 6; - this.UpdateAllButton.Text = "U&pdate All"; - this.UpdateAllButton.UseVisualStyleBackColor = true; - this.UpdateAllButton.Click += new System.EventHandler(this.UpdateAllButton_Click); - // - // CancelButton - // - this.CancelButton.Dock = System.Windows.Forms.DockStyle.Fill; - this.CancelButton.Location = new System.Drawing.Point(339, 422); - this.CancelButton.Margin = new System.Windows.Forms.Padding(20, 3, 20, 3); - this.CancelButton.MaximumSize = new System.Drawing.Size(0, 25); - this.CancelButton.MinimumSize = new System.Drawing.Size(0, 25); - this.CancelButton.Name = "CancelButton"; - this.CancelButton.Size = new System.Drawing.Size(120, 25); - this.CancelButton.TabIndex = 8; - this.CancelButton.Text = "Cancel"; - this.CancelButton.UseVisualStyleBackColor = true; - this.CancelButton.Click += new System.EventHandler(this.CancelButton_Click); - // - // OnlineConfigForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(482, 453); - this.Controls.Add(this.tableLayoutPanel1); - this.MinimizeBox = false; - this.MinimumSize = new System.Drawing.Size(400, 400); - this.Name = "OnlineConfigForm"; - this.Text = "Online config"; - this.tableLayoutPanel1.ResumeLayout(false); - this.tableLayoutPanel1.PerformLayout(); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; - private System.Windows.Forms.ListBox UrlListBox; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.TextBox UrlTextBox; - private System.Windows.Forms.Button UpdateButton; - private System.Windows.Forms.Button AddButton; - private System.Windows.Forms.Button DeleteButton; - private System.Windows.Forms.Button OkButton; - private System.Windows.Forms.Button UpdateAllButton; - private new System.Windows.Forms.Button CancelButton; - } -} \ No newline at end of file diff --git a/shadowsocks-csharp/View/OnlineConfigForm.cs b/shadowsocks-csharp/View/OnlineConfigForm.cs deleted file mode 100644 index 344472da..00000000 --- a/shadowsocks-csharp/View/OnlineConfigForm.cs +++ /dev/null @@ -1,153 +0,0 @@ -using System; -using System.Data; -using System.Linq; -using System.Windows.Forms; -using Shadowsocks.Controller; -using Shadowsocks.Model; -using Shadowsocks.Properties; - -namespace Shadowsocks.View -{ - public partial class OnlineConfigForm : Form - { - private ShadowsocksController controller; - private Configuration config; - - public OnlineConfigForm(ShadowsocksController controller) - { - this.controller = controller; - InitializeComponent(); - LoadConfig(); - Icon = System.Drawing.Icon.FromHandle(Resources.ssw128.GetHicon()); - I18N.TranslateForm(this); - } - - private void LoadConfig() - { - config = controller.GetCurrentConfiguration(); - var idx = UrlListBox.SelectedIndex; - UrlListBox.Items.Clear(); - - foreach (var item in config.onlineConfigSource) - { - UrlListBox.Items.Add(item); - } - - if (idx >= UrlListBox.Items.Count) idx = 0; - if (idx < 0 && UrlListBox.Items.Count > 0) idx = 0; - if (UrlListBox.Items.Count == 0) return; - UrlListBox.SelectedIndex = idx; - SelectItem(); - } - - private void SelectItem() - { - UrlTextBox.Text = (string)UrlListBox.SelectedItem; - } - - private bool ValidateUrl() - { - try - { - var scheme = new Uri(UrlTextBox.Text).Scheme; - if (scheme != "http" && scheme != "https") return false; - if (UrlListBox.Items.OfType().Contains(UrlTextBox.Text)) return false; - } - catch - { - return false; - } - return true; - } - - private void Commit() - { - if (UrlListBox.SelectedIndex < 0) return; - if ((string)UrlListBox.SelectedItem == UrlTextBox.Text) - { - LoadConfig(); - return; - } - - if (ValidateUrl()) - { - - UrlListBox.Items[UrlListBox.SelectedIndex] = UrlTextBox.Text; - } - controller.SaveOnlineConfigSource(UrlListBox.Items.OfType().Where(s => !string.IsNullOrWhiteSpace(s)).Distinct()); - LoadConfig(); - return; - } - - private void AddButton_Click(object sender, EventArgs e) - { - if (string.IsNullOrWhiteSpace(UrlTextBox.Text)) return; - UrlListBox.Items.Add(UrlTextBox.Text); - UrlListBox.SelectedIndex = UrlListBox.Items.Count - 1; - UrlTextBox.Text = ""; - Commit(); - } - - private async void UpdateButton_Click(object sender, EventArgs e) - { - string old = (string)UrlListBox.SelectedItem; - // update content, also update online config - Commit(); - string current = (string)UrlListBox.SelectedItem; - if (UrlListBox.Items.Count == 0) return; - tableLayoutPanel1.Enabled = false; - bool ok = await controller.UpdateOnlineConfig(current); - if (!ok) - { - MessageBox.Show(I18N.GetString("online config failed to update")); - tableLayoutPanel1.Enabled = true; - return; - } - if (old != current) controller.RemoveOnlineConfig(old); - tableLayoutPanel1.Enabled = true; - } - - private void UrlListBox_SelectedIndexChanged(object sender, EventArgs e) - { - if (!UrlListBox.CanSelect) - { - return; - } - SelectItem(); - } - - private void DeleteButton_Click(object sender, EventArgs e) - { - if (UrlListBox.Items.Count == 0) return; - string url = (string)UrlListBox.SelectedItem; - if (!string.IsNullOrWhiteSpace(url)) - { - controller.RemoveOnlineConfig(url); - } - LoadConfig(); - } - - private async void UpdateAllButton_Click(object sender, EventArgs e) - { - if (UrlListBox.Items.Count == 0) return; - tableLayoutPanel1.Enabled = false; - int fail = await controller.UpdateAllOnlineConfig(); - if (fail > 0) - { - MessageBox.Show(I18N.GetString("{0} online config failed to update", fail)); - } - tableLayoutPanel1.Enabled = true; - } - - private void OkButton_Click(object sender, EventArgs e) - { - Commit(); - Close(); - } - - private void CancelButton_Click(object sender, EventArgs e) - { - Close(); - } - } -} diff --git a/shadowsocks-csharp/View/ProxyForm.Designer.cs b/shadowsocks-csharp/View/ProxyForm.Designer.cs deleted file mode 100644 index abbf6527..00000000 --- a/shadowsocks-csharp/View/ProxyForm.Designer.cs +++ /dev/null @@ -1,333 +0,0 @@ -namespace Shadowsocks.View -{ - partial class ProxyForm - { - /// - /// 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.MyCancelButton = new System.Windows.Forms.Button(); - this.OKButton = new System.Windows.Forms.Button(); - this.UseProxyCheckBox = new System.Windows.Forms.CheckBox(); - this.ProxyAddrLabel = new System.Windows.Forms.Label(); - this.ProxyServerTextBox = new System.Windows.Forms.TextBox(); - this.ProxyPortLabel = new System.Windows.Forms.Label(); - this.ProxyPortTextBox = new System.Windows.Forms.TextBox(); - this.ProxyTypeLabel = new System.Windows.Forms.Label(); - this.ProxyTypeComboBox = new System.Windows.Forms.ComboBox(); - this.ProxyTimeoutTextBox = new System.Windows.Forms.TextBox(); - this.ProxyTimeoutLabel = new System.Windows.Forms.Label(); - this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); - this.ProxyNotificationLabel = new System.Windows.Forms.Label(); - this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); - this.AuthUserLabel = new System.Windows.Forms.Label(); - this.AuthPwdLabel = new System.Windows.Forms.Label(); - this.UseAuthCheckBox = new System.Windows.Forms.CheckBox(); - this.AuthUserTextBox = new System.Windows.Forms.TextBox(); - this.AuthPwdTextBox = new System.Windows.Forms.TextBox(); - this.tableLayoutPanel1.SuspendLayout(); - this.flowLayoutPanel1.SuspendLayout(); - this.SuspendLayout(); - // - // MyCancelButton - // - this.MyCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.MyCancelButton.Location = new System.Drawing.Point(84, 3); - this.MyCancelButton.Margin = new System.Windows.Forms.Padding(3, 3, 0, 0); - this.MyCancelButton.Name = "MyCancelButton"; - this.MyCancelButton.Size = new System.Drawing.Size(75, 23); - this.MyCancelButton.TabIndex = 13; - this.MyCancelButton.Text = "Cancel"; - this.MyCancelButton.UseVisualStyleBackColor = true; - this.MyCancelButton.Click += new System.EventHandler(this.CancelButton_Click); - // - // OKButton - // - this.OKButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.OKButton.Location = new System.Drawing.Point(3, 3); - this.OKButton.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0); - this.OKButton.Name = "OKButton"; - this.OKButton.Size = new System.Drawing.Size(75, 23); - this.OKButton.TabIndex = 12; - this.OKButton.Text = "OK"; - this.OKButton.UseVisualStyleBackColor = true; - this.OKButton.Click += new System.EventHandler(this.OKButton_Click); - // - // UseProxyCheckBox - // - this.UseProxyCheckBox.Anchor = System.Windows.Forms.AnchorStyles.Left; - this.UseProxyCheckBox.AutoSize = true; - this.tableLayoutPanel1.SetColumnSpan(this.UseProxyCheckBox, 2); - this.UseProxyCheckBox.Location = new System.Drawing.Point(3, 6); - this.UseProxyCheckBox.Name = "UseProxyCheckBox"; - this.UseProxyCheckBox.Size = new System.Drawing.Size(78, 16); - this.UseProxyCheckBox.TabIndex = 0; - this.UseProxyCheckBox.Text = "Use Proxy"; - this.UseProxyCheckBox.UseVisualStyleBackColor = true; - this.UseProxyCheckBox.CheckedChanged += new System.EventHandler(this.UseProxyCheckBox_CheckedChanged); - // - // ProxyAddrLabel - // - this.ProxyAddrLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ProxyAddrLabel.AutoSize = true; - this.ProxyAddrLabel.Location = new System.Drawing.Point(3, 64); - this.ProxyAddrLabel.Name = "ProxyAddrLabel"; - this.ProxyAddrLabel.Size = new System.Drawing.Size(65, 12); - this.ProxyAddrLabel.TabIndex = 0; - this.ProxyAddrLabel.Text = "Proxy Addr"; - // - // ProxyServerTextBox - // - this.ProxyServerTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ProxyServerTextBox.Location = new System.Drawing.Point(74, 59); - this.ProxyServerTextBox.MaxLength = 512; - this.ProxyServerTextBox.Name = "ProxyServerTextBox"; - this.ProxyServerTextBox.Size = new System.Drawing.Size(138, 21); - this.ProxyServerTextBox.TabIndex = 1; - this.ProxyServerTextBox.WordWrap = false; - // - // ProxyPortLabel - // - this.ProxyPortLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ProxyPortLabel.AutoSize = true; - this.ProxyPortLabel.Location = new System.Drawing.Point(218, 64); - this.ProxyPortLabel.Name = "ProxyPortLabel"; - this.ProxyPortLabel.Size = new System.Drawing.Size(77, 12); - this.ProxyPortLabel.TabIndex = 2; - this.ProxyPortLabel.Text = "Proxy Port"; - // - // ProxyPortTextBox - // - this.ProxyPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ProxyPortTextBox.Location = new System.Drawing.Point(301, 59); - this.ProxyPortTextBox.MaxLength = 10; - this.ProxyPortTextBox.Name = "ProxyPortTextBox"; - this.ProxyPortTextBox.Size = new System.Drawing.Size(91, 21); - this.ProxyPortTextBox.TabIndex = 3; - this.ProxyPortTextBox.WordWrap = false; - // - // ProxyTypeLabel - // - this.ProxyTypeLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ProxyTypeLabel.AutoSize = true; - this.ProxyTypeLabel.Location = new System.Drawing.Point(3, 36); - this.ProxyTypeLabel.Name = "ProxyTypeLabel"; - this.ProxyTypeLabel.Size = new System.Drawing.Size(65, 12); - this.ProxyTypeLabel.TabIndex = 1; - this.ProxyTypeLabel.Text = "Proxy Type"; - // - // ProxyTypeComboBox - // - this.ProxyTypeComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ProxyTypeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.ProxyTypeComboBox.FormattingEnabled = true; - this.ProxyTypeComboBox.Items.AddRange(new object[] { - "SOCKS5", - "HTTP"}); - this.ProxyTypeComboBox.Location = new System.Drawing.Point(74, 33); - this.ProxyTypeComboBox.Margin = new System.Windows.Forms.Padding(3, 5, 3, 5); - this.ProxyTypeComboBox.Name = "ProxyTypeComboBox"; - this.ProxyTypeComboBox.Size = new System.Drawing.Size(138, 20); - this.ProxyTypeComboBox.TabIndex = 2; - this.ProxyTypeComboBox.SelectedIndexChanged += new System.EventHandler(this.ProxyTypeComboBox_SelectedIndexChanged); - // - // ProxyTimeoutTextBox - // - this.ProxyTimeoutTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ProxyTimeoutTextBox.Location = new System.Drawing.Point(301, 31); - this.ProxyTimeoutTextBox.Name = "ProxyTimeoutTextBox"; - this.ProxyTimeoutTextBox.Size = new System.Drawing.Size(91, 21); - this.ProxyTimeoutTextBox.TabIndex = 3; - // - // ProxyTimeoutLabel - // - this.ProxyTimeoutLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ProxyTimeoutLabel.AutoSize = true; - this.ProxyTimeoutLabel.Location = new System.Drawing.Point(218, 36); - this.ProxyTimeoutLabel.Name = "ProxyTimeoutLabel"; - this.ProxyTimeoutLabel.Size = new System.Drawing.Size(77, 12); - this.ProxyTimeoutLabel.TabIndex = 4; - this.ProxyTimeoutLabel.Text = "Timeout(Sec)"; - // - // tableLayoutPanel1 - // - this.tableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.tableLayoutPanel1.ColumnCount = 4; - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 60F)); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 40F)); - this.tableLayoutPanel1.Controls.Add(this.UseProxyCheckBox, 0, 0); - this.tableLayoutPanel1.Controls.Add(this.ProxyTypeLabel, 0, 1); - this.tableLayoutPanel1.Controls.Add(this.ProxyPortTextBox, 3, 2); - this.tableLayoutPanel1.Controls.Add(this.ProxyTypeComboBox, 1, 1); - this.tableLayoutPanel1.Controls.Add(this.ProxyTimeoutLabel, 2, 1); - this.tableLayoutPanel1.Controls.Add(this.ProxyPortLabel, 2, 2); - this.tableLayoutPanel1.Controls.Add(this.ProxyTimeoutTextBox, 3, 1); - this.tableLayoutPanel1.Controls.Add(this.ProxyServerTextBox, 1, 2); - this.tableLayoutPanel1.Controls.Add(this.ProxyAddrLabel, 0, 2); - this.tableLayoutPanel1.Controls.Add(this.ProxyNotificationLabel, 0, 3); - this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel1, 0, 6); - this.tableLayoutPanel1.Controls.Add(this.AuthUserLabel, 0, 5); - this.tableLayoutPanel1.Controls.Add(this.AuthPwdLabel, 2, 5); - this.tableLayoutPanel1.Controls.Add(this.UseAuthCheckBox, 0, 4); - this.tableLayoutPanel1.Controls.Add(this.AuthUserTextBox, 1, 5); - this.tableLayoutPanel1.Controls.Add(this.AuthPwdTextBox, 3, 5); - this.tableLayoutPanel1.Location = new System.Drawing.Point(15, 15); - this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.RowCount = 7; - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66713F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66713F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66713F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.6662F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.6662F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.6662F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.Size = new System.Drawing.Size(395, 204); - this.tableLayoutPanel1.TabIndex = 14; - // - // ProxyNotificationLabel - // - this.ProxyNotificationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ProxyNotificationLabel.AutoSize = true; - this.tableLayoutPanel1.SetColumnSpan(this.ProxyNotificationLabel, 4); - this.ProxyNotificationLabel.ForeColor = System.Drawing.Color.Red; - this.ProxyNotificationLabel.Location = new System.Drawing.Point(3, 92); - this.ProxyNotificationLabel.Name = "ProxyNotificationLabel"; - this.ProxyNotificationLabel.Size = new System.Drawing.Size(389, 12); - this.ProxyNotificationLabel.TabIndex = 5; - this.ProxyNotificationLabel.Text = "If server has a plugin, proxy will not be used"; - // - // flowLayoutPanel1 - // - this.flowLayoutPanel1.AutoSize = true; - this.flowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.tableLayoutPanel1.SetColumnSpan(this.flowLayoutPanel1, 4); - this.flowLayoutPanel1.Controls.Add(this.MyCancelButton); - this.flowLayoutPanel1.Controls.Add(this.OKButton); - this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Right; - this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft; - this.flowLayoutPanel1.Location = new System.Drawing.Point(233, 171); - this.flowLayoutPanel1.Name = "flowLayoutPanel1"; - this.flowLayoutPanel1.Size = new System.Drawing.Size(159, 30); - this.flowLayoutPanel1.TabIndex = 6; - // - // AuthUserLabel - // - this.AuthUserLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.AuthUserLabel.AutoSize = true; - this.AuthUserLabel.Location = new System.Drawing.Point(3, 148); - this.AuthUserLabel.Name = "AuthUserLabel"; - this.AuthUserLabel.Size = new System.Drawing.Size(65, 12); - this.AuthUserLabel.TabIndex = 7; - this.AuthUserLabel.Text = "User Name"; - // - // AuthPwdLabel - // - this.AuthPwdLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.AuthPwdLabel.AutoSize = true; - this.AuthPwdLabel.Location = new System.Drawing.Point(218, 148); - this.AuthPwdLabel.Name = "AuthPwdLabel"; - this.AuthPwdLabel.Size = new System.Drawing.Size(77, 12); - this.AuthPwdLabel.TabIndex = 8; - this.AuthPwdLabel.Text = "Password"; - // - // UseAuthCheckBox - // - this.UseAuthCheckBox.Anchor = System.Windows.Forms.AnchorStyles.Left; - this.UseAuthCheckBox.AutoSize = true; - this.tableLayoutPanel1.SetColumnSpan(this.UseAuthCheckBox, 2); - this.UseAuthCheckBox.Location = new System.Drawing.Point(3, 118); - this.UseAuthCheckBox.Name = "UseAuthCheckBox"; - this.UseAuthCheckBox.Size = new System.Drawing.Size(72, 16); - this.UseAuthCheckBox.TabIndex = 9; - this.UseAuthCheckBox.Text = "Use Auth"; - this.UseAuthCheckBox.UseVisualStyleBackColor = true; - this.UseAuthCheckBox.CheckedChanged += new System.EventHandler(this.UseAuthCheckBox_CheckedChanged); - // - // AuthUserTextBox - // - this.AuthUserTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.AuthUserTextBox.Location = new System.Drawing.Point(74, 143); - this.AuthUserTextBox.Name = "AuthUserTextBox"; - this.AuthUserTextBox.Size = new System.Drawing.Size(138, 21); - this.AuthUserTextBox.TabIndex = 10; - // - // AuthPwdTextBox - // - this.AuthPwdTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.AuthPwdTextBox.Location = new System.Drawing.Point(301, 143); - this.AuthPwdTextBox.Name = "AuthPwdTextBox"; - this.AuthPwdTextBox.PasswordChar = '*'; - this.AuthPwdTextBox.Size = new System.Drawing.Size(91, 21); - this.AuthPwdTextBox.TabIndex = 11; - // - // ProxyForm - // - this.AcceptButton = this.OKButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.AutoSize = true; - this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.CancelButton = this.MyCancelButton; - this.ClientSize = new System.Drawing.Size(448, 231); - this.Controls.Add(this.tableLayoutPanel1); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "ProxyForm"; - this.Padding = new System.Windows.Forms.Padding(12, 12, 12, 9); - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Edit Proxy"; - this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ProxyForm_FormClosed); - this.tableLayoutPanel1.ResumeLayout(false); - this.tableLayoutPanel1.PerformLayout(); - this.flowLayoutPanel1.ResumeLayout(false); - this.ResumeLayout(false); - - } - - #endregion - private System.Windows.Forms.CheckBox UseProxyCheckBox; - private System.Windows.Forms.Label ProxyAddrLabel; - private System.Windows.Forms.TextBox ProxyServerTextBox; - private System.Windows.Forms.Label ProxyPortLabel; - private System.Windows.Forms.TextBox ProxyPortTextBox; - private System.Windows.Forms.Button MyCancelButton; - private System.Windows.Forms.Button OKButton; - private System.Windows.Forms.Label ProxyTypeLabel; - private System.Windows.Forms.ComboBox ProxyTypeComboBox; - private System.Windows.Forms.TextBox ProxyTimeoutTextBox; - private System.Windows.Forms.Label ProxyTimeoutLabel; - private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; - private System.Windows.Forms.Label ProxyNotificationLabel; - private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; - private System.Windows.Forms.Label AuthUserLabel; - private System.Windows.Forms.Label AuthPwdLabel; - private System.Windows.Forms.CheckBox UseAuthCheckBox; - private System.Windows.Forms.TextBox AuthUserTextBox; - private System.Windows.Forms.TextBox AuthPwdTextBox; - } -} \ No newline at end of file diff --git a/shadowsocks-csharp/View/ProxyForm.cs b/shadowsocks-csharp/View/ProxyForm.cs deleted file mode 100644 index 240c38e1..00000000 --- a/shadowsocks-csharp/View/ProxyForm.cs +++ /dev/null @@ -1,176 +0,0 @@ -using System; -using System.Drawing; -using System.Windows.Forms; -using Shadowsocks.Controller; -using Shadowsocks.Model; -using Shadowsocks.Properties; - -namespace Shadowsocks.View -{ - public partial class ProxyForm : Form - { - private ShadowsocksController controller; - - // this is a copy of configuration that we are working on - private ProxyConfig _modifiedProxyConfig; - - public ProxyForm(ShadowsocksController controller) - { - this.Font = System.Drawing.SystemFonts.MessageBoxFont; - InitializeComponent(); - - UpdateTexts(); - this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); - - this.controller = controller; - controller.ConfigChanged += controller_ConfigChanged; - - UpdateEnabled(); - LoadCurrentConfiguration(); - } - - private void UpdateTexts() - { - I18N.TranslateForm(this); - } - - private void controller_ConfigChanged(object sender, EventArgs e) - { - LoadCurrentConfiguration(); - } - - private void LoadCurrentConfiguration() - { - _modifiedProxyConfig = controller.GetCurrentConfiguration().proxy; - UseProxyCheckBox.Checked = _modifiedProxyConfig.useProxy; - ProxyServerTextBox.Text = _modifiedProxyConfig.proxyServer; - ProxyPortTextBox.Text = _modifiedProxyConfig.proxyPort.ToString(); - ProxyTimeoutTextBox.Text = _modifiedProxyConfig.proxyTimeout.ToString(); - ProxyTypeComboBox.SelectedIndex = _modifiedProxyConfig.proxyType; - UseAuthCheckBox.Checked = _modifiedProxyConfig.useAuth; - AuthUserTextBox.Text = _modifiedProxyConfig.authUser; - AuthPwdTextBox.Text = _modifiedProxyConfig.authPwd; - } - - private void OKButton_Click(object sender, EventArgs e) - { - _modifiedProxyConfig.useProxy = UseProxyCheckBox.Checked; - if (_modifiedProxyConfig.useProxy) - { - if (!int.TryParse(ProxyPortTextBox.Text, out _modifiedProxyConfig.proxyPort)) - { - MessageBox.Show(I18N.GetString("Illegal port number format")); - return; - } - - if (!int.TryParse(ProxyTimeoutTextBox.Text, out _modifiedProxyConfig.proxyTimeout)) - { - MessageBox.Show(I18N.GetString("Illegal timeout format")); - return; - } - - _modifiedProxyConfig.proxyType = ProxyTypeComboBox.SelectedIndex; - - try - { - Configuration.CheckServer(_modifiedProxyConfig.proxyServer = ProxyServerTextBox.Text); - Configuration.CheckPort(_modifiedProxyConfig.proxyPort); - Configuration.CheckTimeout(_modifiedProxyConfig.proxyTimeout, ProxyConfig.MaxProxyTimeoutSec); - - _modifiedProxyConfig.useAuth = UseAuthCheckBox.Checked; - if (_modifiedProxyConfig.useAuth) - { - Configuration.CheckProxyAuthUser(_modifiedProxyConfig.authUser = AuthUserTextBox.Text); - Configuration.CheckProxyAuthPwd(_modifiedProxyConfig.authPwd = AuthPwdTextBox.Text); - } - } - catch (Exception ex) - { - MessageBox.Show(ex.Message); - return; - } - } - - controller.SaveProxy(_modifiedProxyConfig); - - this.Close(); - } - - private void CancelButton_Click(object sender, EventArgs e) - { - this.Close(); - } - - private void ProxyForm_FormClosed(object sender, FormClosedEventArgs e) - { - controller.ConfigChanged -= controller_ConfigChanged; - } - - private void UseProxyCheckBox_CheckedChanged(object sender, EventArgs e) - { - UpdateEnabled(); - } - - private void UpdateEnabled() - { - if (UseProxyCheckBox.Checked) - { - ProxyServerTextBox.Enabled = - ProxyPortTextBox.Enabled = - ProxyTimeoutTextBox.Enabled = - ProxyTypeComboBox.Enabled = true; - - if (ProxyTypeComboBox.SelectedIndex == ProxyConfig.PROXY_HTTP) - { - UseAuthCheckBox.Enabled = true; - - if (UseAuthCheckBox.Checked) - { - AuthUserTextBox.Enabled = - AuthPwdTextBox.Enabled = true; - } - else - { - AuthUserTextBox.Enabled = - AuthPwdTextBox.Enabled = false; - } - } - else - { - // TODO support for SOCK5 auth - UseAuthCheckBox.Enabled = - AuthUserTextBox.Enabled = - AuthPwdTextBox.Enabled = false; - } - } - else - { - ProxyServerTextBox.Enabled = - ProxyPortTextBox.Enabled = - ProxyTimeoutTextBox.Enabled = - ProxyTypeComboBox.Enabled = - UseAuthCheckBox.Enabled = - AuthUserTextBox.Enabled = - AuthPwdTextBox.Enabled = false; - } - } - - private void ProxyTypeComboBox_SelectedIndexChanged(object sender, EventArgs e) - { - // TODO support for SOCK5 auth - if (ProxyTypeComboBox.SelectedIndex != ProxyConfig.PROXY_HTTP) - { - UseAuthCheckBox.Checked = false; - AuthUserTextBox.Clear(); - AuthPwdTextBox.Clear(); - } - - UpdateEnabled(); - } - - private void UseAuthCheckBox_CheckedChanged(object sender, EventArgs e) - { - UpdateEnabled(); - } - } -} diff --git a/shadowsocks-csharp/ViewModels/ForwardProxyViewModel.cs b/shadowsocks-csharp/ViewModels/ForwardProxyViewModel.cs new file mode 100644 index 00000000..2d9e9bb0 --- /dev/null +++ b/shadowsocks-csharp/ViewModels/ForwardProxyViewModel.cs @@ -0,0 +1,125 @@ +using ReactiveUI; +using ReactiveUI.Fody.Helpers; +using ReactiveUI.Validation.Extensions; +using ReactiveUI.Validation.Helpers; +using Shadowsocks.Controller; +using Shadowsocks.Model; +using Shadowsocks.View; +using System.Linq; +using System.Reactive; +using System.Reactive.Linq; + +namespace Shadowsocks.ViewModels +{ + public class ForwardProxyViewModel : ReactiveValidationObject + { + public ForwardProxyViewModel() + { + _config = Program.MainController.GetCurrentConfiguration(); + _controller = Program.MainController; + _menuViewController = Program.MenuController; + + if (!_config.proxy.useProxy) + NoProxy = true; + else if (_config.proxy.proxyType == 0) + UseSocks5Proxy = true; + else + UseHttpProxy = true; + + Address = _config.proxy.proxyServer; + Port = _config.proxy.proxyPort; + Timeout = _config.proxy.proxyTimeout; + + Username = _config.proxy.authUser; + Password = _config.proxy.authPwd; + + AddressRule = this.ValidationRule( + viewModel => viewModel.Address, + address => !string.IsNullOrWhiteSpace(address), + "Address can't be empty or whitespaces."); + PortRule = this.ValidationRule( + viewModel => viewModel.Port, + port => port > 0 && port <= 65535, + port => $"{port} is out of range (0, 65535]."); + TimeoutRule = this.ValidationRule( + viewModel => viewModel.Timeout, + timeout => timeout > 0 && timeout <= 10, + timeout => $"{timeout} is out of range (0, 10]."); + + var authValid = this + .WhenAnyValue(x => x.Username, x => x.Password, (username, password) => new { Username = username, Password = password }) + .Select(x => string.IsNullOrWhiteSpace(x.Username) == string.IsNullOrWhiteSpace(x.Password)); + AuthRule = this.ValidationRule(authValid, "You must provide both username and password."); + + var canSave = this.IsValid(); + + Save = ReactiveCommand.Create(() => + { + _controller.SaveProxy(GetForwardProxyConfig()); + _menuViewController.CloseForwardProxyWindow(); + }, canSave); + Cancel = ReactiveCommand.Create(_menuViewController.CloseForwardProxyWindow); + } + + private readonly Configuration _config; + private readonly ShadowsocksController _controller; + private readonly MenuViewController _menuViewController; + + public ValidationHelper AddressRule { get; } + public ValidationHelper PortRule { get; } + public ValidationHelper TimeoutRule { get; } + public ValidationHelper AuthRule { get; } + + public ReactiveCommand Save { get; } + public ReactiveCommand Cancel { get; } + + [Reactive] + public bool NoProxy { get; set; } + + [Reactive] + public bool UseSocks5Proxy { get; set; } + + [Reactive] + public bool UseHttpProxy { get; set; } + + [Reactive] + public string Address { get; set; } + + [Reactive] + public int Port { get; set; } + + [Reactive] + public int Timeout { get; set; } + + [Reactive] + public string Username { get; set; } + + [Reactive] + public string Password { get; set; } + + private ForwardProxyConfig GetForwardProxyConfig() + { + var forwardProxyConfig = new ForwardProxyConfig() + { + proxyServer = Address, + proxyPort = Port, + proxyTimeout = Timeout, + authUser = Username, + authPwd = Password + }; + if (NoProxy) + forwardProxyConfig.useProxy = false; + else if (UseSocks5Proxy) + { + forwardProxyConfig.useProxy = true; + forwardProxyConfig.proxyType = 0; + } + else + { + forwardProxyConfig.useProxy = true; + forwardProxyConfig.proxyType = 1; + } + return forwardProxyConfig; + } + } +} diff --git a/shadowsocks-csharp/ViewModels/HotkeysViewModel.cs b/shadowsocks-csharp/ViewModels/HotkeysViewModel.cs new file mode 100644 index 00000000..141d2cf9 --- /dev/null +++ b/shadowsocks-csharp/ViewModels/HotkeysViewModel.cs @@ -0,0 +1,189 @@ +using ReactiveUI; +using ReactiveUI.Fody.Helpers; +using Shadowsocks.Controller; +using Shadowsocks.Model; +using Shadowsocks.View; +using System.Reactive; +using System.Text; +using System.Windows.Input; + +namespace Shadowsocks.ViewModels +{ + public class HotkeysViewModel : ReactiveObject + { + public HotkeysViewModel() + { + _config = Program.MainController.GetCurrentConfiguration(); + _controller = Program.MainController; + _menuViewController = Program.MenuController; + + HotkeySystemProxy = _config.hotkey.SwitchSystemProxy; + HotkeyProxyMode = _config.hotkey.SwitchSystemProxyMode; + HotkeyAllowLan = _config.hotkey.SwitchAllowLan; + HotkeyOpenLogs = _config.hotkey.ShowLogs; + HotkeySwitchPrev = _config.hotkey.ServerMoveUp; + HotkeySwitchNext = _config.hotkey.ServerMoveDown; + RegisterAtStartup = _config.hotkey.RegHotkeysAtStartup; + + HotkeySystemProxyStatus = "✔"; + HotkeyProxyModeStatus = "✔"; + HotkeyAllowLanStatus = "✔"; + HotkeyOpenLogsStatus = "✔"; + HotkeySwitchPrevStatus = "✔"; + HotkeySwitchNextStatus = "✔"; + + RegisterAll = ReactiveCommand.Create(() => RegisterAllAndUpdateStatus()); + Save = ReactiveCommand.Create(() => RegisterAllAndUpdateStatus(true)); + Cancel = ReactiveCommand.Create(_menuViewController.CloseHotkeysWindow); + } + + private readonly Configuration _config; + private readonly ShadowsocksController _controller; + private readonly MenuViewController _menuViewController; + + public ReactiveCommand RegisterAll { get; } + public ReactiveCommand Save { get; } + public ReactiveCommand Cancel { get; } + + [Reactive] + public string HotkeySystemProxy { get; set; } + + [Reactive] + public string HotkeyProxyMode { get; set; } + + [Reactive] + public string HotkeyAllowLan { get; set; } + + [Reactive] + public string HotkeyOpenLogs { get; set; } + + [Reactive] + public string HotkeySwitchPrev { get; set; } + + [Reactive] + public string HotkeySwitchNext { get; set; } + + [Reactive] + public bool RegisterAtStartup { get; set; } + + [Reactive] + public string HotkeySystemProxyStatus { get; set; } + + [Reactive] + public string HotkeyProxyModeStatus { get; set; } + + [Reactive] + public string HotkeyAllowLanStatus { get; set; } + + [Reactive] + public string HotkeyOpenLogsStatus { get; set; } + + [Reactive] + public string HotkeySwitchPrevStatus { get; set; } + + [Reactive] + public string HotkeySwitchNextStatus { get; set; } + + public void RecordKeyDown(int hotkeyIndex, KeyEventArgs keyEventArgs) + { + var recordedKeyStringBuilder = new StringBuilder(); + + // record modifiers + if ((Keyboard.Modifiers & ModifierKeys.Control) > 0) + recordedKeyStringBuilder.Append("Ctrl+"); + if ((Keyboard.Modifiers & ModifierKeys.Alt) > 0) + recordedKeyStringBuilder.Append("Alt+"); + if ((Keyboard.Modifiers & ModifierKeys.Shift) > 0) + recordedKeyStringBuilder.Append("Shift+"); + + // record other keys when at least one modifier is pressed + if (recordedKeyStringBuilder.Length > 0 && (keyEventArgs.Key < Key.LeftShift || keyEventArgs.Key > Key.RightAlt)) + recordedKeyStringBuilder.Append(keyEventArgs.Key); + + switch (hotkeyIndex) + { + case 0: + HotkeySystemProxy = recordedKeyStringBuilder.ToString(); + break; + case 1: + HotkeyProxyMode = recordedKeyStringBuilder.ToString(); + break; + case 2: + HotkeyAllowLan = recordedKeyStringBuilder.ToString(); + break; + case 3: + HotkeyOpenLogs = recordedKeyStringBuilder.ToString(); + break; + case 4: + HotkeySwitchPrev = recordedKeyStringBuilder.ToString(); + break; + case 5: + HotkeySwitchNext = recordedKeyStringBuilder.ToString(); + break; + } + } + + public void FinishOnKeyUp(int hotkeyIndex, KeyEventArgs keyEventArgs) + { + switch (hotkeyIndex) + { + case 0: + if (HotkeySystemProxy.EndsWith("+")) + HotkeySystemProxy = ""; + break; + case 1: + if (HotkeyProxyMode.EndsWith("+")) + HotkeyProxyMode = ""; + break; + case 2: + if (HotkeyAllowLan.EndsWith("+")) + HotkeyAllowLan = ""; + break; + case 3: + if (HotkeyOpenLogs.EndsWith("+")) + HotkeyOpenLogs = ""; + break; + case 4: + if (HotkeySwitchPrev.EndsWith("+")) + HotkeySwitchPrev = ""; + break; + case 5: + if (HotkeySwitchNext.EndsWith("+")) + HotkeySwitchNext = ""; + break; + } + } + + private void RegisterAllAndUpdateStatus(bool save = false) + { + HotkeySystemProxyStatus = HotkeyReg.RegHotkeyFromString(HotkeySystemProxy, "SwitchSystemProxyCallback") ? "✔" : "❌"; + HotkeyProxyModeStatus = HotkeyReg.RegHotkeyFromString(HotkeyProxyMode, "SwitchSystemProxyModeCallback") ? "✔" : "❌"; + HotkeyAllowLanStatus = HotkeyReg.RegHotkeyFromString(HotkeyAllowLan, "SwitchAllowLanCallback") ? "✔" : "❌"; + HotkeyOpenLogsStatus = HotkeyReg.RegHotkeyFromString(HotkeyOpenLogs, "ShowLogsCallback") ? "✔" : "❌"; + HotkeySwitchPrevStatus = HotkeyReg.RegHotkeyFromString(HotkeySwitchPrev, "ServerMoveUpCallback") ? "✔" : "❌"; + HotkeySwitchNextStatus = HotkeyReg.RegHotkeyFromString(HotkeySwitchNext, "ServerMoveDownCallback") ? "✔" : "❌"; + + if (HotkeySystemProxyStatus == "✔" && + HotkeyProxyModeStatus == "✔" && + HotkeyAllowLanStatus == "✔" && + HotkeyOpenLogsStatus == "✔" && + HotkeySwitchPrevStatus == "✔" && + HotkeySwitchNextStatus == "✔" && save) + { + _controller.SaveHotkeyConfig(GetHotkeyConfig); + _menuViewController.CloseHotkeysWindow(); + } + } + + private HotkeyConfig GetHotkeyConfig => new HotkeyConfig() + { + SwitchSystemProxy = HotkeySystemProxy, + SwitchSystemProxyMode = HotkeyProxyMode, + SwitchAllowLan = HotkeyAllowLan, + ShowLogs = HotkeyOpenLogs, + ServerMoveUp = HotkeySwitchPrev, + ServerMoveDown = HotkeySwitchNext, + RegHotkeysAtStartup = RegisterAtStartup + }; + } +} diff --git a/shadowsocks-csharp/ViewModels/OnlineConfigViewModel.cs b/shadowsocks-csharp/ViewModels/OnlineConfigViewModel.cs new file mode 100644 index 00000000..f803b351 --- /dev/null +++ b/shadowsocks-csharp/ViewModels/OnlineConfigViewModel.cs @@ -0,0 +1,115 @@ +using ReactiveUI; +using ReactiveUI.Fody.Helpers; +using ReactiveUI.Validation.Extensions; +using ReactiveUI.Validation.Helpers; +using Shadowsocks.Controller; +using Shadowsocks.Localization; +using Shadowsocks.Model; +using Shadowsocks.View; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Reactive; +using System.Reactive.Linq; +using System.Text; +using System.Windows; + +namespace Shadowsocks.ViewModels +{ + public class OnlineConfigViewModel : ReactiveValidationObject + { + public OnlineConfigViewModel() + { + _config = Program.MainController.GetCurrentConfiguration(); + _controller = Program.MainController; + _menuViewController = Program.MenuController; + + Sources = new ObservableCollection(_config.onlineConfigSource); + SelectedSource = ""; + Address = ""; + + // TODO in v5: if http:// show warning as materialDesign:HintAssist.HelperText + AddressRule = this.ValidationRule( + viewModel => viewModel.Address, + address => address.StartsWith("http://"), + "Warning: getting online configuration from plain HTTP sources is NOT secure!"); + + var canUpdateCopyRemove = this.WhenAnyValue( + x => x.SelectedSource, + selectedSource => !string.IsNullOrWhiteSpace(selectedSource)); + var canUpdateAll = this.WhenAnyValue( + x => x.Sources.Count, + count => count > 0); + var canAdd = this.WhenAnyValue( + x => x.Address, + address => Uri.IsWellFormedUriString(address, UriKind.Absolute) && + (address.StartsWith("https://") || address.StartsWith("http://"))); + + Update = ReactiveCommand.CreateFromTask(() => _controller.UpdateOnlineConfig(SelectedSource), canUpdateCopyRemove); + UpdateAll = ReactiveCommand.CreateFromTask(_controller.UpdateAllOnlineConfig, canUpdateAll); + CopyLink = ReactiveCommand.Create(() => Clipboard.SetText(SelectedSource), canUpdateCopyRemove); + Remove = ReactiveCommand.Create(() => + { + bool result; + var urlToRemove = SelectedSource; // save it here because SelectedSource is lost once we remove the selection + do + { + result = Sources.Remove(urlToRemove); + } while (result); + _controller.RemoveOnlineConfig(urlToRemove); + }, canUpdateCopyRemove); + Add = ReactiveCommand.Create(() => + { + Sources.Add(Address); + SelectedSource = Address; + _controller.SaveOnlineConfigSource(Sources.ToList()); + Address = ""; + }, canAdd); + + // TODO in v5: use MaterialDesignThemes snackbar messages + this.WhenAnyObservable(x => x.Update) + .Subscribe(x => + { + if (x) + MessageBox.Show(LocalizationProvider.GetLocalizedValue("sip008UpdateSuccess")); + else + MessageBox.Show(LocalizationProvider.GetLocalizedValue("sip008UpdateFailure")); + }); + this.WhenAnyObservable(x => x.UpdateAll) + .Subscribe(x => + { + if (x.Count == 0) + MessageBox.Show(LocalizationProvider.GetLocalizedValue("sip008UpdateAllSuccess")); + else + { + var stringBuilder = new StringBuilder(LocalizationProvider.GetLocalizedValue("sip008UpdateAllFailure")); + foreach (var url in x) + stringBuilder.AppendLine(url); + MessageBox.Show(stringBuilder.ToString()); + } + }); + } + + private readonly Configuration _config; + private readonly ShadowsocksController _controller; + private readonly MenuViewController _menuViewController; + + public ValidationHelper AddressRule { get; } + + public ReactiveCommand Update { get; } + public ReactiveCommand> UpdateAll { get; } + public ReactiveCommand CopyLink { get; } + public ReactiveCommand Remove { get; } + public ReactiveCommand Add { get; } + + [Reactive] + public ObservableCollection Sources { get; private set; } + + [Reactive] + public string SelectedSource { get; set; } + + [Reactive] + public string Address { get; set; } + } +} diff --git a/shadowsocks-csharp/ViewModels/ServerSharingViewModel.cs b/shadowsocks-csharp/ViewModels/ServerSharingViewModel.cs index 1ed4d785..f1375690 100644 --- a/shadowsocks-csharp/ViewModels/ServerSharingViewModel.cs +++ b/shadowsocks-csharp/ViewModels/ServerSharingViewModel.cs @@ -1,10 +1,13 @@ using ReactiveUI; +using ReactiveUI.Fody.Helpers; using Shadowsocks.Model; using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; +using System.Reactive; +using System.Windows; using System.Windows.Media.Imaging; namespace Shadowsocks.ViewModels @@ -17,18 +20,30 @@ namespace Shadowsocks.ViewModels public ServerSharingViewModel() { _config = Program.MainController.GetCurrentConfiguration(); - _servers = _config.configs; - _selectedServer = _servers.First(); - //_selectedServerUrlImage = new BitmapImage(); - UpdateUrlAndImage(); + Servers = _config.configs; + SelectedServer = Servers[0]; + + this.WhenAnyValue(x => x.SelectedServer) + .Subscribe(_ => UpdateUrlAndImage()); + + CopyLink = ReactiveCommand.Create(() => Clipboard.SetText(SelectedServerUrl)); } private readonly Configuration _config; - private List _servers; - private Server _selectedServer; - private string _selectedServerUrl; - private BitmapImage _selectedServerUrlImage; + public ReactiveCommand CopyLink { get; } + + [Reactive] + public List Servers { get; private set; } + + [Reactive] + public Server SelectedServer { get; set; } + + [Reactive] + public string SelectedServerUrl { get; private set; } + + [Reactive] + public BitmapImage SelectedServerUrlImage { get; private set; } /// /// Called when SelectedServer changed @@ -37,10 +52,10 @@ namespace Shadowsocks.ViewModels private void UpdateUrlAndImage() { // update SelectedServerUrl - SelectedServerUrl = _selectedServer.GetURL(_config.generateLegacyUrl); + SelectedServerUrl = SelectedServer.GetURL(_config.generateLegacyUrl); // generate QR code - var qrCode = ZXing.QrCode.Internal.Encoder.encode(_selectedServerUrl, ZXing.QrCode.Internal.ErrorCorrectionLevel.L); + var qrCode = ZXing.QrCode.Internal.Encoder.encode(SelectedServerUrl, ZXing.QrCode.Internal.ErrorCorrectionLevel.L); var byteMatrix = qrCode.Matrix; // paint bitmap @@ -77,33 +92,5 @@ namespace Shadowsocks.ViewModels } SelectedServerUrlImage = bitmapImage; } - - public List Servers - { - get => _servers; - set => this.RaiseAndSetIfChanged(ref _servers, value); - } - - public Server SelectedServer - { - get => _selectedServer; - set - { - this.RaiseAndSetIfChanged(ref _selectedServer, value); - UpdateUrlAndImage(); - } - } - - public string SelectedServerUrl - { - get => _selectedServerUrl; - set => this.RaiseAndSetIfChanged(ref _selectedServerUrl, value); - } - - public BitmapImage SelectedServerUrlImage - { - get => _selectedServerUrlImage; - set => this.RaiseAndSetIfChanged(ref _selectedServerUrlImage, value); - } } } diff --git a/shadowsocks-csharp/ViewModels/VersionUpdatePromptViewModel.cs b/shadowsocks-csharp/ViewModels/VersionUpdatePromptViewModel.cs new file mode 100644 index 00000000..0ae9f2d1 --- /dev/null +++ b/shadowsocks-csharp/ViewModels/VersionUpdatePromptViewModel.cs @@ -0,0 +1,34 @@ +using Newtonsoft.Json.Linq; +using ReactiveUI; +using Shadowsocks.Controller; +using System.Reactive; + +namespace Shadowsocks.ViewModels +{ + public class VersionUpdatePromptViewModel : ReactiveObject + { + public VersionUpdatePromptViewModel(JToken releaseObject) + { + _updateChecker = Program.MenuController.updateChecker; + _releaseObject = releaseObject; + ReleaseNotes = string.Concat( + $"# {((bool)_releaseObject["prerelease"] ? "⚠ Pre-release" : "ℹ Release")} {(string)_releaseObject["tag_name"] ?? "Failed to get tag name"}\r\n", + (string)_releaseObject["body"] ?? "Failed to get release notes"); + + Update = ReactiveCommand.CreateFromTask(_updateChecker.DoUpdate); + SkipVersion = ReactiveCommand.Create(_updateChecker.SkipUpdate); + NotNow = ReactiveCommand.Create(_updateChecker.CloseVersionUpdatePromptWindow); + } + + private readonly UpdateChecker _updateChecker; + private readonly JToken _releaseObject; + + public string ReleaseNotes { get; } + + public ReactiveCommand Update { get; } + + public ReactiveCommand SkipVersion { get; } + + public ReactiveCommand NotNow { get; } + } +} diff --git a/shadowsocks-csharp/Views/ForwardProxyView.xaml b/shadowsocks-csharp/Views/ForwardProxyView.xaml new file mode 100644 index 00000000..0c6a9319 --- /dev/null +++ b/shadowsocks-csharp/Views/ForwardProxyView.xaml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +