@@ -0,0 +1,80 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Net; | |||
using System.Net.Http; | |||
using System.Threading.Tasks; | |||
using Newtonsoft.Json.Linq; | |||
using Shadowsocks.Model; | |||
namespace Shadowsocks.Controller.Service | |||
{ | |||
public class OnlineConfigResolver | |||
{ | |||
public static async Task<List<Server>> GetOnline(string url, IWebProxy proxy = null) | |||
{ | |||
var httpClientHandler = new HttpClientHandler() | |||
{ | |||
Proxy = proxy | |||
}; | |||
var httpClient = new HttpClient(httpClientHandler) | |||
{ | |||
Timeout = TimeSpan.FromSeconds(15) | |||
}; | |||
string server_json = await httpClient.GetStringAsync(url); | |||
var servers = server_json.GetServers(); | |||
foreach (var server in servers) | |||
{ | |||
server.group = url; | |||
} | |||
return servers.ToList(); | |||
} | |||
} | |||
internal static class OnlineConfigResolverEx | |||
{ | |||
private static readonly string[] BASIC_FORMAT = new[] { "server", "server_port", "password", "method" }; | |||
private static readonly IEnumerable<Server> EMPTY_SERVERS = Array.Empty<Server>(); | |||
internal static IEnumerable<Server> GetServers(this string json) => | |||
JToken.Parse(json).SearchJToken().AsEnumerable(); | |||
private static IEnumerable<Server> SearchJArray(JArray array) => | |||
array == null ? EMPTY_SERVERS : array.SelectMany(SearchJToken).ToList(); | |||
private static IEnumerable<Server> SearchJObject(JObject obj) | |||
{ | |||
if (obj == null) | |||
return EMPTY_SERVERS; | |||
if (BASIC_FORMAT.All(field => obj.ContainsKey(field))) | |||
return new[] { obj.ToObject<Server>() }; | |||
var servers = new List<Server>(); | |||
foreach (var kv in obj) | |||
{ | |||
var token = kv.Value; | |||
servers.AddRange(SearchJToken(token)); | |||
} | |||
return servers; | |||
} | |||
private static IEnumerable<Server> SearchJToken(this JToken token) | |||
{ | |||
switch (token.Type) | |||
{ | |||
default: | |||
return Array.Empty<Server>(); | |||
case JTokenType.Object: | |||
return SearchJObject(token as JObject); | |||
case JTokenType.Array: | |||
return SearchJArray(token as JArray); | |||
} | |||
} | |||
} | |||
} |
@@ -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; | |||
@@ -25,7 +26,7 @@ namespace Shadowsocks.Controller | |||
// handle user actions | |||
// manipulates UI | |||
// interacts with low level logic | |||
#region Member definition | |||
private Thread _trafficThread; | |||
private TCPListener _tcpListener; | |||
@@ -87,6 +88,7 @@ namespace Shadowsocks.Controller | |||
// Invoked when controller.Start(); | |||
public event EventHandler<UpdatedEventArgs> ProgramUpdated; | |||
#endregion | |||
public ShadowsocksController() | |||
{ | |||
@@ -102,6 +104,8 @@ namespace Shadowsocks.Controller | |||
}; | |||
} | |||
#region Basic | |||
public void Start(bool regHotkeys = true) | |||
{ | |||
if (_config.updated && regHotkeys) | |||
@@ -121,6 +125,115 @@ namespace Shadowsocks.Controller | |||
} | |||
} | |||
public void Stop() | |||
{ | |||
if (stopped) | |||
{ | |||
return; | |||
} | |||
stopped = true; | |||
_tcpListener?.Stop(); | |||
_udpListener?.Stop(); | |||
StopPlugins(); | |||
if (privoxyRunner != null) | |||
{ | |||
privoxyRunner.Stop(); | |||
} | |||
if (_config.enabled) | |||
{ | |||
SystemProxy.Update(_config, true, null); | |||
} | |||
} | |||
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); | |||
_tcpListener?.Stop(); | |||
_udpListener?.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); | |||
_tcpListener = new TCPListener(_config, new List<IStreamService> | |||
{ | |||
tcpRelay, | |||
_pacServer, | |||
new PortForwarder(privoxyRunner.RunningPort), | |||
}); | |||
_tcpListener.Start(); | |||
_udpListener = new UDPListener(_config, new List<IDatagramService> | |||
{ | |||
udpRelay, | |||
}); | |||
_udpListener.Start(); | |||
} | |||
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(); | |||
} | |||
protected void SaveConfig(Configuration newConfig) | |||
{ | |||
Configuration.Save(newConfig); | |||
Reload(); | |||
} | |||
protected void ReportError(Exception e) | |||
{ | |||
Errored?.Invoke(this, new ErrorEventArgs(e)); | |||
@@ -143,23 +256,6 @@ namespace Shadowsocks.Controller | |||
return _config; | |||
} | |||
public IList<IStrategy> 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(); | |||
@@ -174,32 +270,11 @@ namespace Shadowsocks.Controller | |||
return GetCurrentServer(); | |||
} | |||
public EndPoint GetPluginLocalEndPointIfConfigured(Server server) | |||
public void SelectServerIndex(int index) | |||
{ | |||
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; | |||
_config.index = index; | |||
_config.strategy = null; | |||
SaveConfig(_config); | |||
} | |||
public void SaveServers(List<Server> servers, int localPort, bool portableMode) | |||
@@ -210,56 +285,17 @@ namespace Shadowsocks.Controller | |||
Configuration.Save(_config); | |||
} | |||
public void SaveStrategyConfigurations(StatisticsStrategyConfiguration configuration) | |||
public void ToggleShareOverLAN(bool enabled) | |||
{ | |||
StatisticsConfiguration = configuration; | |||
StatisticsStrategyConfiguration.Save(configuration); | |||
} | |||
_config.shareOverLan = enabled; | |||
SaveConfig(_config); | |||
public bool AskAddServerBySSURL(string ssURL) | |||
{ | |||
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; | |||
ShareOverLANStatusChanged?.Invoke(this, new EventArgs()); | |||
} | |||
#endregion | |||
public bool AddServerBySSURL(string ssURL) | |||
{ | |||
try | |||
{ | |||
if (ssURL.IsNullOrEmpty() || ssURL.IsWhiteSpace()) | |||
return false; | |||
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; | |||
} | |||
} | |||
#region OS Proxy | |||
public void ToggleEnable(bool enabled) | |||
{ | |||
@@ -277,78 +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 | |||
SystemProxy.Update(_config, false, _pacServer); | |||
} | |||
VerboseLoggingStatusChanged?.Invoke(this, new EventArgs()); | |||
#endregion | |||
#region PAC | |||
private void PacDaemon_PACFileChanged(object sender, EventArgs e) | |||
{ | |||
UpdateSystemProxy(); | |||
} | |||
public void ToggleShowPluginOutput(bool enabled) | |||
private void PacServer_PACUpdateCompleted(object sender, GeositeResultEventArgs e) | |||
{ | |||
_config.showPluginOutput = enabled; | |||
SaveConfig(_config); | |||
UpdatePACFromGeositeCompleted?.Invoke(this, e); | |||
} | |||
ShowPluginOutputChanged?.Invoke(this, new EventArgs()); | |||
private void PacServer_PACUpdateError(object sender, ErrorEventArgs e) | |||
{ | |||
UpdatePACFromGeositeError?.Invoke(this, e); | |||
} | |||
public void SelectServerIndex(int index) | |||
private static readonly IEnumerable<char> IgnoredLineBegins = new[] { '!', '[' }; | |||
private void PacDaemon_UserRuleFileChanged(object sender, EventArgs e) | |||
{ | |||
_config.index = index; | |||
_config.strategy = null; | |||
SaveConfig(_config); | |||
GeositeUpdater.MergeAndWritePACFile(_config.geositeGroup, _config.geositeBlacklistMode); | |||
UpdateSystemProxy(); | |||
} | |||
public void SelectStrategy(string strategyID) | |||
public void CopyPacUrl() | |||
{ | |||
_config.index = -1; | |||
_config.strategy = strategyID; | |||
SaveConfig(_config); | |||
Clipboard.SetDataObject(_pacServer.PacUrl); | |||
} | |||
public void Stop() | |||
public void SavePACUrl(string pacUrl) | |||
{ | |||
if (stopped) | |||
{ | |||
return; | |||
} | |||
stopped = true; | |||
_tcpListener?.Stop(); | |||
_udpListener?.Stop(); | |||
StopPlugins(); | |||
if (privoxyRunner != null) | |||
{ | |||
privoxyRunner.Stop(); | |||
} | |||
if (_config.enabled) | |||
{ | |||
SystemProxy.Update(_config, true, null); | |||
} | |||
_config.pacUrl = pacUrl; | |||
SaveConfig(_config); | |||
ConfigChanged?.Invoke(this, new EventArgs()); | |||
} | |||
private void StopPlugins() | |||
public void UseOnlinePAC(bool useOnlinePac) | |||
{ | |||
foreach (var serverAndPlugin in _pluginsByServer) | |||
{ | |||
serverAndPlugin.Value?.Dispose(); | |||
} | |||
_pluginsByServer.Clear(); | |||
_config.useOnlinePac = useOnlinePac; | |||
SaveConfig(_config); | |||
ConfigChanged?.Invoke(this, new EventArgs()); | |||
} | |||
public void TouchPACFile() | |||
@@ -365,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) | |||
@@ -436,6 +491,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<IStrategy> 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) | |||
{ | |||
GetCurrentStrategy()?.UpdateLatency(args.server, args.latency); | |||
@@ -465,88 +564,9 @@ 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); | |||
_tcpListener?.Stop(); | |||
_udpListener?.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); | |||
_tcpListener = new TCPListener(_config, new List<IStreamService> | |||
{ | |||
tcpRelay, | |||
_pacServer, | |||
new PortForwarder(privoxyRunner.RunningPort), | |||
}); | |||
_tcpListener.Start(); | |||
_udpListener = new UDPListener(_config, new List<IDatagramService> | |||
{ | |||
udpRelay, | |||
}); | |||
_udpListener.Start(); | |||
} | |||
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); | |||
} | |||
#endregion | |||
ConfigChanged?.Invoke(this, new EventArgs()); | |||
UpdateSystemProxy(); | |||
} | |||
#region SIP003 | |||
private void StartPlugin() | |||
{ | |||
@@ -554,44 +574,53 @@ namespace Shadowsocks.Controller | |||
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<char> 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 Traffic Statistics | |||
private void StartTrafficStatistics(int queueMaxSize) | |||
@@ -634,5 +663,75 @@ namespace Shadowsocks.Controller | |||
#endregion | |||
#region SIP008 | |||
public async Task<int> UpdateOnlineConfigInternal(string url) | |||
{ | |||
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<bool> 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<int> UpdateAllOnlineConfig() | |||
{ | |||
var selected = GetCurrentServer(); | |||
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<string> vs) | |||
{ | |||
_config.onlineConfigSource = vs.ToList(); | |||
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 | |||
} | |||
} |
@@ -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 | |||
@@ -1,6 +1,8 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using System.Linq; | |||
using System.Net; | |||
using Newtonsoft.Json; | |||
using NLog; | |||
using Shadowsocks.Controller; | |||
@@ -17,6 +19,8 @@ namespace Shadowsocks.Model | |||
public List<Server> configs; | |||
public List<string> onlineConfigSource; | |||
// when strategy is set, index is ignored | |||
public string strategy; | |||
public int index; | |||
@@ -25,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<Server>(); | |||
onlineConfigSource = new List<string>(); | |||
} | |||
[JsonIgnore] | |||
NLogConfig nLogConfig; | |||
@@ -59,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() | |||
@@ -77,6 +116,14 @@ 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); | |||
@@ -111,20 +158,10 @@ namespace Shadowsocks.Model | |||
config.updated = true; | |||
} | |||
if (config.configs == null) | |||
config.configs = new List<Server>(); | |||
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 | |||
@@ -137,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<Server>() | |||
{ | |||
GetDefaultServer() | |||
}, | |||
logViewer = new LogViewerConfig(), | |||
proxy = new ProxyConfig(), | |||
hotkey = new HotkeyConfig(), | |||
}; | |||
config = new Configuration(); | |||
config.configs.Add(GetDefaultServer()); | |||
} | |||
try | |||
@@ -181,12 +206,12 @@ namespace Shadowsocks.Model | |||
public static void Save(Configuration config) | |||
{ | |||
config.version = UpdateChecker.Version; | |||
config.configs = SortByOnlineConfig(config.configs); | |||
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 | |||
@@ -214,6 +239,15 @@ namespace Shadowsocks.Model | |||
} | |||
} | |||
public static List<Server> SortByOnlineConfig(IEnumerable<Server> servers) | |||
{ | |||
var groups = servers.GroupBy(s => s.group); | |||
List<Server> ret = new List<Server>(); | |||
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) | |||
@@ -44,6 +44,10 @@ namespace Shadowsocks.Model | |||
[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() | |||
@@ -101,7 +101,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); | |||
@@ -110,7 +117,7 @@ namespace Shadowsocks | |||
{ | |||
MainController.AskAddServerBySSURL(Options.OpenUrl); | |||
} | |||
#endregion | |||
#endregion | |||
Application.Run(); | |||
@@ -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 | |||
@@ -85,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); | |||
@@ -104,13 +98,16 @@ | |||
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 = 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()); | |||
@@ -123,14 +120,16 @@ | |||
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.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
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); | |||
@@ -140,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(235, 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(235, 25); | |||
this.RemarksTextBox.Size = new System.Drawing.Size(205, 25); | |||
this.RemarksTextBox.TabIndex = 8; | |||
this.RemarksTextBox.WordWrap = false; | |||
// | |||
@@ -164,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); | |||
@@ -175,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); | |||
@@ -186,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); | |||
@@ -196,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(235, 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(235, 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(235, 25); | |||
this.PasswordTextBox.Size = new System.Drawing.Size(205, 25); | |||
this.PasswordTextBox.TabIndex = 2; | |||
this.PasswordTextBox.UseSystemPasswordChar = true; | |||
this.PasswordTextBox.WordWrap = false; | |||
@@ -233,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); | |||
@@ -242,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(235, 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; | |||
@@ -268,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(235, 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); | |||
@@ -289,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(235, 25); | |||
this.PluginOptionsTextBox.Size = new System.Drawing.Size(205, 25); | |||
this.PluginOptionsTextBox.TabIndex = 6; | |||
this.PluginOptionsTextBox.WordWrap = false; | |||
// | |||
@@ -303,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); | |||
@@ -315,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(235, 25); | |||
this.PluginArgumentsTextBox.Size = new System.Drawing.Size(205, 25); | |||
this.PluginArgumentsTextBox.TabIndex = 7; | |||
this.PluginArgumentsTextBox.WordWrap = false; | |||
// | |||
@@ -328,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); | |||
@@ -341,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); | |||
@@ -351,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); | |||
@@ -365,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(206, 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); | |||
@@ -374,11 +364,10 @@ | |||
// 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.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(94, 29); | |||
this.OKButton.Size = new System.Drawing.Size(87, 29); | |||
this.OKButton.TabIndex = 17; | |||
this.OKButton.Text = "OK"; | |||
this.OKButton.UseVisualStyleBackColor = true; | |||
@@ -387,11 +376,10 @@ | |||
// 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.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(94, 29); | |||
this.MyCancelButton.Size = new System.Drawing.Size(87, 29); | |||
this.MyCancelButton.TabIndex = 18; | |||
this.MyCancelButton.Text = "Cancel"; | |||
this.MyCancelButton.UseVisualStyleBackColor = true; | |||
@@ -399,12 +387,11 @@ | |||
// | |||
// ApplyButton | |||
// | |||
this.ApplyButton.Dock = System.Windows.Forms.DockStyle.Right; | |||
this.ApplyButton.Dock = System.Windows.Forms.DockStyle.Fill; | |||
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(468, 501); | |||
this.ApplyButton.Name = "ApplyButton"; | |||
this.ApplyButton.Size = new System.Drawing.Size(94, 29); | |||
this.ApplyButton.Size = new System.Drawing.Size(91, 29); | |||
this.ApplyButton.TabIndex = 19; | |||
this.ApplyButton.Text = "Apply"; | |||
this.ApplyButton.UseVisualStyleBackColor = true; | |||
@@ -412,11 +399,10 @@ | |||
// | |||
// 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.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; | |||
@@ -424,11 +410,10 @@ | |||
// | |||
// 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.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; | |||
@@ -438,76 +423,37 @@ | |||
// | |||
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.Margin = new System.Windows.Forms.Padding(15, 0, 0, 0); | |||
this.ServerGroupBox.Dock = System.Windows.Forms.DockStyle.Fill; | |||
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(408, 405); | |||
this.ServerGroupBox.Size = new System.Drawing.Size(370, 425); | |||
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.Location = new System.Drawing.Point(3, 3); | |||
this.ServersListBox.Name = "ServersListBox"; | |||
this.ServersListBox.Size = new System.Drawing.Size(206, 184); | |||
this.ServersListBox.Size = new System.Drawing.Size(180, 422); | |||
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.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; | |||
@@ -515,144 +461,135 @@ | |||
// | |||
// 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.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; | |||
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.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(8, 13); | |||
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.tableLayoutPanel5.SetColumnSpan(this.PortableModeCheckBox, 2); | |||
this.PortableModeCheckBox.Location = new System.Drawing.Point(8, 48); | |||
this.tableLayoutPanel7.SetColumnSpan(this.PortableModeCheckBox, 2); | |||
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"); | |||
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.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; | |||
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.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.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(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.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, 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; | |||
this.GroupLabel.Size = new System.Drawing.Size(47, 15); | |||
this.GroupLabel.TabIndex = 11; | |||
this.GroupLabel.Text = "Group"; | |||
// | |||
// GroupTextBox | |||
// | |||
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(205, 25); | |||
this.GroupTextBox.TabIndex = 12; | |||
// | |||
// ConfigForm | |||
// | |||
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(614, 548); | |||
this.Controls.Add(this.tableLayoutPanel2); | |||
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); | |||
@@ -662,13 +599,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 +626,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 +644,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; | |||
} | |||
} | |||
@@ -26,9 +26,6 @@ namespace Shadowsocks.View | |||
InitializeComponent(); | |||
EncryptionSelect.Items.AddRange(EncryptorFactory.ListAvaliableCiphers().ToArray()); | |||
// a dirty hack | |||
ServersListBox.Dock = DockStyle.Fill; | |||
tableLayoutPanel5.Dock = DockStyle.Fill; | |||
PerformLayout(); | |||
UpdateTexts(); | |||
@@ -125,6 +122,7 @@ namespace Shadowsocks.View | |||
plugin_args = PluginArgumentsTextBox.Text, | |||
remarks = RemarksTextBox.Text, | |||
timeout = timeout.Value, | |||
group = GroupTextBox.Text | |||
}; | |||
return true; | |||
@@ -332,6 +330,8 @@ namespace Shadowsocks.View | |||
RemarksTextBox.Text = server.remarks; | |||
TimeoutTextBox.Text = server.timeout.ToString(); | |||
GroupTextBox.Text = server.group; | |||
isChange = false; | |||
} | |||
@@ -120,4 +120,7 @@ | |||
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> | |||
<value>17, 17</value> | |||
</metadata> | |||
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> | |||
<value>17, 17</value> | |||
</metadata> | |||
</root> |
@@ -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); | |||
@@ -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; | |||
@@ -59,11 +59,13 @@ namespace Shadowsocks.View | |||
private ToolStripMenuItem VerboseLoggingToggleItem; | |||
private ToolStripMenuItem ShowPluginOutputToggleItem; | |||
private ToolStripMenuItem WriteI18NFileItem; | |||
private ToolStripMenuItem onlineConfigItem; | |||
private ConfigForm configForm; | |||
private ProxyForm proxyForm; | |||
private LogForm logForm; | |||
private HotkeySettingsForm hotkeySettingsForm; | |||
private OnlineConfigForm onlineConfigForm; | |||
@@ -120,37 +122,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() | |||
@@ -317,7 +288,8 @@ namespace Shadowsocks.View | |||
this.editOnlinePACItem = CreateToolStripMenuItem("Edit Online PAC URL...", new EventHandler(this.UpdateOnlinePACURLItem_Click)), | |||
}), | |||
this.proxyItem = CreateToolStripMenuItem("Forward Proxy...", new EventHandler(this.proxyItem_Click)), | |||
new ToolStripSeparator( ), | |||
this.onlineConfigItem = CreateToolStripMenuItem("Online Config...", new EventHandler(this.OnlineConfig_Click)), | |||
new ToolStripSeparator( ), | |||
this.AutoStartupItem = CreateToolStripMenuItem("Start on Boot", new EventHandler(this.AutoStartupItem_Click)), | |||
this.ProtocolHandlerItem = CreateToolStripMenuItem("Associate ss:// Links", new EventHandler(this.ProtocolHandlerItem_Click)), | |||
this.ShareOverLANItem = CreateToolStripMenuItem("Allow other Devices to connect", new EventHandler(this.ShareOverLANItem_Click)), | |||
@@ -343,99 +315,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() | |||
@@ -455,66 +369,7 @@ namespace Shadowsocks.View | |||
UpdateUpdateMenu(); | |||
} | |||
private void UpdateServersMenu() | |||
{ | |||
var items = ServersItem.DropDownItems; | |||
while (items[0] != SeperatorItem) | |||
{ | |||
items.RemoveAt(0); | |||
} | |||
int strategyCount = 0; | |||
foreach (var strategy in controller.GetStrategies()) | |||
{ | |||
if (!items.OfType<ToolStripItem>().Any(ts => ts.Text == strategy.Name)) | |||
{ | |||
ToolStripMenuItem item = new ToolStripMenuItem(strategy.Name); | |||
item.Tag = strategy.ID; | |||
item.Click += AStrategyItem_Click; | |||
items.Add(item); | |||
strategyCount++; | |||
} | |||
} | |||
if (!items.OfType<ToolStripSeparator>().Any(ts => ts.Tag?.ToString() == "-server-")) | |||
{ | |||
// user wants a seperator item between strategy and servers menugroup | |||
items.Add(new ToolStripSeparator() { Tag = "-server-" }); | |||
} | |||
int serverCount = 0; | |||
Configuration configuration = controller.GetConfigurationCopy(); | |||
foreach (var server in configuration.configs) | |||
{ | |||
if (Configuration.ChecksServer(server)) | |||
{ | |||
var name = server.ToString(); | |||
if (!items.OfType<ToolStripMenuItem>().Any(ts => ts.Text == name)) | |||
{ | |||
ToolStripMenuItem item = new ToolStripMenuItem(name); | |||
item.Tag = configuration.configs.FindIndex(s => s == server); | |||
item.Click += AServerItem_Click; | |||
items.Add(item); | |||
serverCount++; | |||
} | |||
} | |||
} | |||
foreach (var item in items) | |||
{ | |||
var menuItem = item as ToolStripMenuItem; | |||
if (menuItem == null || menuItem.Tag == null) continue; | |||
if ( | |||
menuItem.Tag.ToString() == configuration.index.ToString() | |||
|| menuItem.Tag.ToString() == configuration.strategy | |||
) | |||
{ | |||
menuItem.Checked = true; | |||
} | |||
else | |||
{ | |||
menuItem.Checked = false; | |||
} | |||
} | |||
} | |||
#region Forms | |||
private void ShowConfigForm() | |||
{ | |||
@@ -576,6 +431,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(); | |||
@@ -611,29 +482,43 @@ namespace Shadowsocks.View | |||
hotkeySettingsForm = null; | |||
} | |||
private void Config_Click(object sender, EventArgs e) | |||
void onlineConfigForm_FormClosed(object sender, FormClosedEventArgs e) | |||
{ | |||
ShowConfigForm(); | |||
onlineConfigForm.Dispose(); | |||
onlineConfigForm = null; | |||
} | |||
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) | |||
{ | |||
Utils.OpenInBrowser("https://github.com/shadowsocks/shadowsocks-windows"); | |||
if (updateChecker.NewVersionFound) | |||
{ | |||
updateChecker.NewVersionFound = false; /* Reset the flag */ | |||
} | |||
} | |||
private void notifyIcon1_Click(object sender, MouseEventArgs e) | |||
@@ -653,24 +538,109 @@ namespace Shadowsocks.View | |||
} | |||
} | |||
private void EnableItem_Click(object sender, EventArgs e) | |||
private void CheckUpdateForFirstRun() | |||
{ | |||
controller.ToggleEnable(false); | |||
Configuration config = controller.GetConfigurationCopy(); | |||
UpdateSystemProxyItemsEnabledStatus(config); | |||
if (config.isDefault) return; | |||
_isStartupChecking = true; | |||
updateChecker.CheckUpdate(config, 3000); | |||
} | |||
private void UpdateSystemProxyItemsEnabledStatus(Configuration config) | |||
public void ShowLogForm_HotKey() | |||
{ | |||
disableItem.Checked = !config.enabled; | |||
if (!config.enabled) | |||
{ | |||
globalModeItem.Checked = false; | |||
PACModeItem.Checked = false; | |||
} | |||
else | |||
{ | |||
globalModeItem.Checked = config.global; | |||
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); | |||
Configuration config = controller.GetConfigurationCopy(); | |||
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; | |||
if (!config.enabled) | |||
{ | |||
globalModeItem.Checked = false; | |||
PACModeItem.Checked = false; | |||
} | |||
else | |||
{ | |||
globalModeItem.Checked = config.global; | |||
PACModeItem.Checked = !config.global; | |||
} | |||
@@ -694,25 +664,69 @@ 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.DropDownItems; | |||
while (items[0] != SeperatorItem) | |||
{ | |||
items.RemoveAt(0); | |||
} | |||
int strategyCount = 0; | |||
foreach (var strategy in controller.GetStrategies()) | |||
{ | |||
if (!items.OfType<ToolStripItem>().Any(ts => ts.Text == strategy.Name)) | |||
{ | |||
ToolStripMenuItem item = new ToolStripMenuItem(strategy.Name); | |||
item.Tag = strategy.ID; | |||
item.Click += AStrategyItem_Click; | |||
items.Add(item); | |||
strategyCount++; | |||
} | |||
} | |||
if (!items.OfType<ToolStripSeparator>().Any(ts => ts.Tag?.ToString() == "-server-")) | |||
{ | |||
// user wants a seperator item between strategy and servers menugroup | |||
items.Add(new ToolStripSeparator() { Tag = "-server-" }); | |||
} | |||
int serverCount = 0; | |||
Configuration configuration = controller.GetConfigurationCopy(); | |||
foreach (var server in configuration.configs) | |||
{ | |||
if (Configuration.ChecksServer(server)) | |||
{ | |||
var name = server.ToString(); | |||
if (!items.OfType<ToolStripMenuItem>().Any(ts => ts.Text == name)) | |||
{ | |||
ToolStripMenuItem item = new ToolStripMenuItem(name); | |||
item.Tag = configuration.configs.FindIndex(s => s == server); | |||
item.Click += AServerItem_Click; | |||
items.Add(item); | |||
serverCount++; | |||
} | |||
} | |||
} | |||
private void EditUserRuleFileForGeositeItem_Click(object sender, EventArgs e) | |||
{ | |||
controller.TouchUserRuleFile(); | |||
foreach (var item in items) | |||
{ | |||
var menuItem = item as ToolStripMenuItem; | |||
if (menuItem == null || menuItem.Tag == null) continue; | |||
if ( | |||
menuItem.Tag.ToString() == configuration.index.ToString() | |||
|| menuItem.Tag.ToString() == configuration.strategy | |||
) | |||
{ | |||
menuItem.Checked = true; | |||
} | |||
else | |||
{ | |||
menuItem.Checked = false; | |||
} | |||
} | |||
} | |||
private void AServerItem_Click(object sender, EventArgs e) | |||
@@ -727,21 +741,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); | |||
Utils.OpenInBrowser(_urlToOpen); | |||
} | |||
private void StatisticsConfigItem_Click(object sender, EventArgs e) | |||
@@ -850,34 +862,9 @@ namespace Shadowsocks.View | |||
} | |||
} | |||
void splash_FormClosed(object sender, FormClosedEventArgs e) | |||
{ | |||
ShowConfigForm(); | |||
} | |||
void openURLFromQRCode(object sender, FormClosedEventArgs e) | |||
{ | |||
Utils.OpenInBrowser(_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) | |||
{ | |||
@@ -911,17 +898,10 @@ namespace Shadowsocks.View | |||
private void UpdateOnlinePACURLItem_Click(object sender, EventArgs e) | |||
{ | |||
string origPacUrl = controller.GetConfigurationCopy().pacUrl; | |||
#if NET472 | |||
string pacUrl = Microsoft.VisualBasic.Interaction.InputBox( | |||
I18N.GetString("Please input PAC Url"), | |||
I18N.GetString("Edit Online PAC URL"), | |||
origPacUrl, -1, -1); | |||
#else | |||
string pacUrl = ViewUtils.InputBox( | |||
I18N.GetString("Please input PAC Url"), | |||
I18N.GetString("Edit Online PAC URL"), | |||
origPacUrl, -1, -1); | |||
#endif | |||
if (!pacUrl.IsNullOrEmpty() && pacUrl != origPacUrl) | |||
{ | |||
controller.SavePACUrl(pacUrl); | |||
@@ -958,6 +938,95 @@ 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() | |||
{ | |||
Configuration configuration = controller.GetConfigurationCopy(); | |||
@@ -984,24 +1053,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(); | |||
Utils.OpenInBrowser("https://github.com/shadowsocks/shadowsocks-windows"); | |||
} | |||
public void ShowLogForm_HotKey() | |||
{ | |||
ShowLogForm(); | |||
} | |||
#endregion | |||
} | |||
} |
@@ -0,0 +1,218 @@ | |||
namespace Shadowsocks.View | |||
{ | |||
partial class OnlineConfigForm | |||
{ | |||
/// <summary> | |||
/// Required designer variable. | |||
/// </summary> | |||
private System.ComponentModel.IContainer components = null; | |||
/// <summary> | |||
/// Clean up any resources being used. | |||
/// </summary> | |||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> | |||
protected override void Dispose(bool disposing) | |||
{ | |||
if (disposing && (components != null)) | |||
{ | |||
components.Dispose(); | |||
} | |||
base.Dispose(disposing); | |||
} | |||
#region Windows Form Designer generated code | |||
/// <summary> | |||
/// Required method for Designer support - do not modify | |||
/// the contents of this method with the code editor. | |||
/// </summary> | |||
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 System.Windows.Forms.Button CancelButton; | |||
} | |||
} |
@@ -0,0 +1,153 @@ | |||
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.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; | |||
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<string>().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<string>().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(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,120 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<root> | |||
<!-- | |||
Microsoft ResX Schema | |||
Version 2.0 | |||
The primary goals of this format is to allow a simple XML format | |||
that is mostly human readable. The generation and parsing of the | |||
various data types are done through the TypeConverter classes | |||
associated with the data types. | |||
Example: | |||
... ado.net/XML headers & schema ... | |||
<resheader name="resmimetype">text/microsoft-resx</resheader> | |||
<resheader name="version">2.0</resheader> | |||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> | |||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> | |||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> | |||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> | |||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> | |||
<value>[base64 mime encoded serialized .NET Framework object]</value> | |||
</data> | |||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> | |||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> | |||
<comment>This is a comment</comment> | |||
</data> | |||
There are any number of "resheader" rows that contain simple | |||
name/value pairs. | |||
Each data row contains a name, and value. The row also contains a | |||
type or mimetype. Type corresponds to a .NET class that support | |||
text/value conversion through the TypeConverter architecture. | |||
Classes that don't support this are serialized and stored with the | |||
mimetype set. | |||
The mimetype is used for serialized objects, and tells the | |||
ResXResourceReader how to depersist the object. This is currently not | |||
extensible. For a given mimetype the value must be set accordingly: | |||
Note - application/x-microsoft.net.object.binary.base64 is the format | |||
that the ResXResourceWriter will generate, however the reader can | |||
read any of the formats listed below. | |||
mimetype: application/x-microsoft.net.object.binary.base64 | |||
value : The object must be serialized with | |||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter | |||
: and then encoded with base64 encoding. | |||
mimetype: application/x-microsoft.net.object.soap.base64 | |||
value : The object must be serialized with | |||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter | |||
: and then encoded with base64 encoding. | |||
mimetype: application/x-microsoft.net.object.bytearray.base64 | |||
value : The object must be serialized into a byte array | |||
: using a System.ComponentModel.TypeConverter | |||
: and then encoded with base64 encoding. | |||
--> | |||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |||
<xsd:element name="root" msdata:IsDataSet="true"> | |||
<xsd:complexType> | |||
<xsd:choice maxOccurs="unbounded"> | |||
<xsd:element name="metadata"> | |||
<xsd:complexType> | |||
<xsd:sequence> | |||
<xsd:element name="value" type="xsd:string" minOccurs="0" /> | |||
</xsd:sequence> | |||
<xsd:attribute name="name" use="required" type="xsd:string" /> | |||
<xsd:attribute name="type" type="xsd:string" /> | |||
<xsd:attribute name="mimetype" type="xsd:string" /> | |||
<xsd:attribute ref="xml:space" /> | |||
</xsd:complexType> | |||
</xsd:element> | |||
<xsd:element name="assembly"> | |||
<xsd:complexType> | |||
<xsd:attribute name="alias" type="xsd:string" /> | |||
<xsd:attribute name="name" type="xsd:string" /> | |||
</xsd:complexType> | |||
</xsd:element> | |||
<xsd:element name="data"> | |||
<xsd:complexType> | |||
<xsd:sequence> | |||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |||
</xsd:sequence> | |||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |||
<xsd:attribute ref="xml:space" /> | |||
</xsd:complexType> | |||
</xsd:element> | |||
<xsd:element name="resheader"> | |||
<xsd:complexType> | |||
<xsd:sequence> | |||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
</xsd:sequence> | |||
<xsd:attribute name="name" type="xsd:string" use="required" /> | |||
</xsd:complexType> | |||
</xsd:element> | |||
</xsd:choice> | |||
</xsd:complexType> | |||
</xsd:element> | |||
</xsd:schema> | |||
<resheader name="resmimetype"> | |||
<value>text/microsoft-resx</value> | |||
</resheader> | |||
<resheader name="version"> | |||
<value>2.0</value> | |||
</resheader> | |||
<resheader name="reader"> | |||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
</resheader> | |||
<resheader name="writer"> | |||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
</resheader> | |||
</root> |