From fafaefaf59cd5fa981630c048cd9c47cc1b83a5b Mon Sep 17 00:00:00 2001 From: database64128 Date: Sun, 7 Mar 2021 00:25:00 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=AE=20Remove=20unused=20projects?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shadowsocks-csharp/CommandLineOption.cs | 10 - .../Controller/ShadowsocksController.cs | 733 ------------ shadowsocks-csharp/Data/i18n.csv | 157 --- shadowsocks-csharp/Model/Configuration.cs | 382 ------- shadowsocks-csharp/Program.cs | 215 ---- .../View/ConfigForm.Designer.cs | 652 ----------- shadowsocks-csharp/View/ConfigForm.cs | 552 --------- shadowsocks-csharp/View/ConfigForm.resx | 126 --- shadowsocks-csharp/View/InputBox.Designer.cs | 100 -- shadowsocks-csharp/View/InputBox.cs | 24 - shadowsocks-csharp/View/InputBox.resx | 120 -- shadowsocks-csharp/View/LogForm.Designer.cs | 332 ------ shadowsocks-csharp/View/LogForm.cs | 447 -------- shadowsocks-csharp/View/LogForm.resx | 150 --- shadowsocks-csharp/View/MenuViewController.cs | 1001 ----------------- shadowsocks-csharp/app.config | 73 -- shadowsocks-csharp/app.manifest | 76 -- shadowsocks-csharp/packages.config | 19 - shadowsocks-csharp/shadowsocks-csharp.csproj | 75 -- shadowsocks-windows.sln | 13 +- test/App.config | 14 - test/CachedNetworkStreamTest.cs | 84 -- test/CryptographyTest.cs | 141 --- test/ProcessEnvironment.cs | 713 ------------ test/ShadowsocksTest.csproj | 34 - test/Sip003PluginTest.cs | 221 ---- test/TestUtils.cs | 41 - test/UnitTest.cs | 45 - test/UrlTest.cs | 252 ----- 29 files changed, 1 insertion(+), 6801 deletions(-) delete mode 100644 shadowsocks-csharp/CommandLineOption.cs delete mode 100644 shadowsocks-csharp/Controller/ShadowsocksController.cs delete mode 100644 shadowsocks-csharp/Data/i18n.csv delete mode 100644 shadowsocks-csharp/Model/Configuration.cs delete mode 100755 shadowsocks-csharp/Program.cs delete mode 100755 shadowsocks-csharp/View/ConfigForm.Designer.cs delete mode 100755 shadowsocks-csharp/View/ConfigForm.cs delete mode 100755 shadowsocks-csharp/View/ConfigForm.resx delete mode 100644 shadowsocks-csharp/View/InputBox.Designer.cs delete mode 100644 shadowsocks-csharp/View/InputBox.cs delete mode 100644 shadowsocks-csharp/View/InputBox.resx delete mode 100644 shadowsocks-csharp/View/LogForm.Designer.cs delete mode 100644 shadowsocks-csharp/View/LogForm.cs delete mode 100644 shadowsocks-csharp/View/LogForm.resx delete mode 100644 shadowsocks-csharp/View/MenuViewController.cs delete mode 100755 shadowsocks-csharp/app.config delete mode 100755 shadowsocks-csharp/app.manifest delete mode 100644 shadowsocks-csharp/packages.config delete mode 100644 shadowsocks-csharp/shadowsocks-csharp.csproj delete mode 100644 test/App.config delete mode 100644 test/CachedNetworkStreamTest.cs delete mode 100644 test/CryptographyTest.cs delete mode 100644 test/ProcessEnvironment.cs delete mode 100644 test/ShadowsocksTest.csproj delete mode 100644 test/Sip003PluginTest.cs delete mode 100644 test/TestUtils.cs delete mode 100755 test/UnitTest.cs delete mode 100644 test/UrlTest.cs diff --git a/shadowsocks-csharp/CommandLineOption.cs b/shadowsocks-csharp/CommandLineOption.cs deleted file mode 100644 index 1ab23ec4..00000000 --- a/shadowsocks-csharp/CommandLineOption.cs +++ /dev/null @@ -1,10 +0,0 @@ -using CommandLine; - -namespace Shadowsocks -{ - public class CommandLineOption - { - [Option("open-url",Required = false,HelpText = "Add an ss:// URL")] - public string OpenUrl { get; set; } - } -} \ No newline at end of file diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs deleted file mode 100644 index c2f1b5be..00000000 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ /dev/null @@ -1,733 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Net.Sockets; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using System.Web; -using System.Windows.Forms; -using NLog; -using Shadowsocks.Controller.Service; -using Shadowsocks.Controller.Strategy; -using Shadowsocks.Model; -using Shadowsocks.Util; -using WPFLocalizeExtension.Engine; - -namespace Shadowsocks.Controller -{ - public class ShadowsocksController - { - private readonly Logger logger; - private readonly HttpClient httpClient; - - // controller: - // handle user actions - // manipulates UI - // interacts with low level logic - #region Member definition - private Thread _trafficThread; - - private TCPListener _tcpListener; - private UDPListener _udpListener; - private PACDaemon _pacDaemon; - private PACServer _pacServer; - private Configuration _config; - private StrategyManager _strategyManager; - private PrivoxyRunner privoxyRunner; - private readonly ConcurrentDictionary _pluginsByServer; - - private long _inboundCounter = 0; - private long _outboundCounter = 0; - public long InboundCounter => Interlocked.Read(ref _inboundCounter); - public long OutboundCounter => Interlocked.Read(ref _outboundCounter); - public Queue trafficPerSecondQueue; - - private bool stopped = false; - - public class PathEventArgs : EventArgs - { - public string Path; - } - - public class UpdatedEventArgs : EventArgs - { - public string OldVersion; - public string NewVersion; - } - - public class TrafficPerSecond - { - public long inboundCounter; - public long outboundCounter; - public long inboundIncreasement; - public long outboundIncreasement; - } - - public event EventHandler ConfigChanged; - public event EventHandler EnableStatusChanged; - public event EventHandler EnableGlobalChanged; - public event EventHandler ShareOverLANStatusChanged; - public event EventHandler VerboseLoggingStatusChanged; - public event EventHandler ShowPluginOutputChanged; - public event EventHandler TrafficChanged; - - // when user clicked Edit PAC, and PAC file has already created - public event EventHandler PACFileReadyToOpen; - public event EventHandler UserRuleFileReadyToOpen; - - public event EventHandler UpdatePACFromGeositeCompleted; - - public event ErrorEventHandler UpdatePACFromGeositeError; - - public event ErrorEventHandler Errored; - - // Invoked when controller.Start(); - public event EventHandler ProgramUpdated; - #endregion - - public ShadowsocksController() - { - logger = LogManager.GetCurrentClassLogger(); - httpClient = new HttpClient(); - _config = Configuration.Load(); - Configuration.Process(ref _config); - _strategyManager = new StrategyManager(this); - _pluginsByServer = new ConcurrentDictionary(); - StartTrafficStatistics(61); - - ProgramUpdated += (o, e) => - { - // version update precedures - if (e.OldVersion == "4.3.0.0" || e.OldVersion == "4.3.1.0") - _config.geositeDirectGroups.Add("private"); - - logger.Info($"Updated from {e.OldVersion} to {e.NewVersion}"); - }; - } - - #region Basic - - public void Start(bool systemWakeUp = false) - { - if (_config.firstRunOnNewVersion && !systemWakeUp) - { - ProgramUpdated.Invoke(this, new UpdatedEventArgs() - { - OldVersion = _config.version, - NewVersion = UpdateChecker.Version, - }); - // delete pac.txt when regeneratePacOnUpdate is true - if (_config.regeneratePacOnUpdate) - try - { - File.Delete(PACDaemon.PAC_FILE); - logger.Info("Deleted pac.txt from previous version."); - } - catch (Exception e) - { - logger.LogUsefulException(e); - } - // finish up first run of new version - _config.firstRunOnNewVersion = false; - _config.version = UpdateChecker.Version; - Configuration.Save(_config); - } - Reload(); - if (!systemWakeUp) - HotkeyReg.RegAllHotkeys(); - } - - 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(); - Configuration.Process(ref _config); - - NLogConfig.LoadConfiguration(); - - logger.Info($"WPF Localization Extension|Current culture: {LocalizeDictionary.CurrentCulture}"); - - // set User-Agent for httpClient - try - { - if (!string.IsNullOrWhiteSpace(_config.userAgentString)) - httpClient.DefaultRequestHeaders.Add("User-Agent", _config.userAgentString); - } - catch - { - // reset userAgent to default and reapply - Configuration.ResetUserAgent(_config); - httpClient.DefaultRequestHeaders.Add("User-Agent", _config.userAgentString); - } - - 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; - - _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.OnInbound += UpdateInboundCounter; - tcpRelay.OnOutbound += UpdateOutboundCounter; - tcpRelay.OnFailed += (o, e) => GetCurrentStrategy()?.SetFailure(e.server); - - UDPRelay udpRelay = new UDPRelay(this); - _tcpListener = new TCPListener(_config, new List - { - tcpRelay, - _pacServer, - new PortForwarder(privoxyRunner.RunningPort), - }); - _tcpListener.Start(); - _udpListener = new UDPListener(_config, new List - { - 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)); - } - - public HttpClient GetHttpClient() => httpClient; - public Server GetCurrentServer() => _config.GetCurrentServer(); - public Configuration GetCurrentConfiguration() => _config; - - public Server GetAServer(IStrategyCallerType type, IPEndPoint localIPEndPoint, EndPoint destEndPoint) - { - IStrategy strategy = GetCurrentStrategy(); - if (strategy != null) - { - return strategy.GetAServer(type, localIPEndPoint, destEndPoint); - } - if (_config.index < 0) - { - _config.index = 0; - } - return GetCurrentServer(); - } - - public void SaveServers(List servers, int localPort, bool portableMode) - { - _config.configs = servers; - _config.localPort = localPort; - _config.portableMode = portableMode; - Configuration.Save(_config); - } - - public void SelectServerIndex(int index) - { - _config.index = index; - _config.strategy = null; - SaveConfig(_config); - } - - public void ToggleShareOverLAN(bool enabled) - { - _config.shareOverLan = enabled; - SaveConfig(_config); - - ShareOverLANStatusChanged?.Invoke(this, new EventArgs()); - } - - #endregion - - #region OS Proxy - - public void ToggleEnable(bool enabled) - { - _config.enabled = enabled; - SaveConfig(_config); - - EnableStatusChanged?.Invoke(this, new EventArgs()); - } - - public void ToggleGlobal(bool global) - { - _config.global = global; - SaveConfig(_config); - - EnableGlobalChanged?.Invoke(this, new EventArgs()); - } - - public void SaveProxy(ForwardProxyConfig proxyConfig) - { - _config.proxy = proxyConfig; - SaveConfig(_config); - } - - private void UpdateSystemProxy() - { - SystemProxy.Update(_config, false, _pacServer); - } - - #endregion - - #region PAC - - private void PacDaemon_PACFileChanged(object sender, EventArgs e) - { - UpdateSystemProxy(); - } - - private void PacServer_PACUpdateCompleted(object sender, GeositeResultEventArgs e) - { - UpdatePACFromGeositeCompleted?.Invoke(this, e); - } - - private void PacServer_PACUpdateError(object sender, ErrorEventArgs e) - { - UpdatePACFromGeositeError?.Invoke(this, e); - } - - private static readonly IEnumerable IgnoredLineBegins = new[] { '!', '[' }; - private void PacDaemon_UserRuleFileChanged(object sender, EventArgs e) - { - GeositeUpdater.MergeAndWritePACFile(_config.geositeDirectGroups, _config.geositeProxiedGroups, _config.geositePreferDirect); - UpdateSystemProxy(); - } - - public void CopyPacUrl() - { - Clipboard.SetDataObject(_pacServer.PacUrl); - } - - public void SavePACUrl(string pacUrl) - { - _config.pacUrl = pacUrl; - SaveConfig(_config); - - ConfigChanged?.Invoke(this, new EventArgs()); - } - - public void UseOnlinePAC(bool useOnlinePac) - { - _config.useOnlinePac = useOnlinePac; - SaveConfig(_config); - - ConfigChanged?.Invoke(this, new EventArgs()); - } - - public void TouchPACFile() - { - string pacFilename = _pacDaemon.TouchPACFile(); - - PACFileReadyToOpen?.Invoke(this, new PathEventArgs() { Path = pacFilename }); - } - - public void TouchUserRuleFile() - { - string userRuleFilename = _pacDaemon.TouchUserRuleFile(); - - UserRuleFileReadyToOpen?.Invoke(this, new PathEventArgs() { Path = userRuleFilename }); - } - - public void ToggleSecureLocalPac(bool enabled) - { - _config.secureLocalPac = enabled; - SaveConfig(_config); - - ConfigChanged?.Invoke(this, new EventArgs()); - } - - public void ToggleRegeneratePacOnUpdate(bool enabled) - { - _config.regeneratePacOnUpdate = enabled; - SaveConfig(_config); - ConfigChanged?.Invoke(this, new EventArgs()); - } - - #endregion - - #region SIP002 - - 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; - } - - public bool AddServerBySSURL(string ssURL) - { - try - { - if (string.IsNullOrWhiteSpace(ssURL)) - 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; - } - } - - public string GetServerURLForCurrentServer() - { - return GetCurrentServer().GetURL(_config.generateLegacyUrl); - } - - #endregion - - #region Misc - - public void ToggleVerboseLogging(bool enabled) - { - _config.isVerboseLogging = enabled; - SaveConfig(_config); - NLogConfig.LoadConfiguration(); // reload nlog - - VerboseLoggingStatusChanged?.Invoke(this, new EventArgs()); - } - - public void ToggleCheckingUpdate(bool enabled) - { - _config.autoCheckUpdate = enabled; - Configuration.Save(_config); - - ConfigChanged?.Invoke(this, new EventArgs()); - } - - public void ToggleCheckingPreRelease(bool enabled) - { - _config.checkPreRelease = enabled; - Configuration.Save(_config); - ConfigChanged?.Invoke(this, new EventArgs()); - } - - public void SaveSkippedUpdateVerion(string version) - { - _config.skippedUpdateVersion = version; - Configuration.Save(_config); - } - - public void SaveLogViewerConfig(LogViewerConfig newConfig) - { - _config.logViewer = newConfig; - newConfig.SaveSize(); - Configuration.Save(_config); - - ConfigChanged?.Invoke(this, new EventArgs()); - } - - public void SaveHotkeyConfig(HotkeyConfig newConfig) - { - _config.hotkey = newConfig; - SaveConfig(_config); - - ConfigChanged?.Invoke(this, new EventArgs()); - } - - #endregion - - #region Strategy - - public void SelectStrategy(string strategyID) - { - _config.index = -1; - _config.strategy = strategyID; - SaveConfig(_config); - } - - public IList GetStrategies() - { - return _strategyManager.GetStrategies(); - } - - public IStrategy GetCurrentStrategy() - { - foreach (var strategy in _strategyManager.GetStrategies()) - { - if (strategy.ID == _config.strategy) - { - return strategy; - } - } - return null; - } - - public void UpdateInboundCounter(object sender, SSTransmitEventArgs args) - { - GetCurrentStrategy()?.UpdateLastRead(args.server); - Interlocked.Add(ref _inboundCounter, args.length); - } - - public void UpdateOutboundCounter(object sender, SSTransmitEventArgs args) - { - GetCurrentStrategy()?.UpdateLastWrite(args.server); - Interlocked.Add(ref _outboundCounter, args.length); - } - - #endregion - - #region SIP003 - - private void StartPlugin() - { - var server = _config.GetCurrentServer(); - GetPluginLocalEndPointIfConfigured(server); - } - - private void StopPlugins() - { - foreach (var serverAndPlugin in _pluginsByServer) - { - serverAndPlugin.Value?.Dispose(); - } - _pluginsByServer.Clear(); - } - - public EndPoint GetPluginLocalEndPointIfConfigured(Server server) - { - var plugin = _pluginsByServer.GetOrAdd( - server, - x => Sip003Plugin.CreateIfConfigured(x, _config.showPluginOutput)); - - if (plugin == null) - { - return null; - } - - try - { - if (plugin.StartIfNeeded()) - { - logger.Info( - $"Started SIP003 plugin for {server.Identifier()} on {plugin.LocalEndPoint} - PID: {plugin.ProcessId}"); - } - } - catch (Exception ex) - { - logger.Error("Failed to start SIP003 plugin: " + ex.Message); - throw; - } - - return plugin.LocalEndPoint; - } - - public void ToggleShowPluginOutput(bool enabled) - { - _config.showPluginOutput = enabled; - SaveConfig(_config); - - ShowPluginOutputChanged?.Invoke(this, new EventArgs()); - } - - #endregion - - #region Traffic Statistics - - private void StartTrafficStatistics(int queueMaxSize) - { - trafficPerSecondQueue = new Queue(); - for (int i = 0; i < queueMaxSize; i++) - { - trafficPerSecondQueue.Enqueue(new TrafficPerSecond()); - } - _trafficThread = new Thread(new ThreadStart(() => TrafficStatistics(queueMaxSize))) - { - IsBackground = true - }; - _trafficThread.Start(); - } - - private void TrafficStatistics(int queueMaxSize) - { - TrafficPerSecond previous, current; - while (true) - { - previous = trafficPerSecondQueue.Last(); - current = new TrafficPerSecond - { - inboundCounter = InboundCounter, - outboundCounter = OutboundCounter - }; - current.inboundIncreasement = current.inboundCounter - previous.inboundCounter; - current.outboundIncreasement = current.outboundCounter - previous.outboundCounter; - - trafficPerSecondQueue.Enqueue(current); - if (trafficPerSecondQueue.Count > queueMaxSize) - trafficPerSecondQueue.Dequeue(); - - TrafficChanged?.Invoke(this, new EventArgs()); - - Thread.Sleep(1000); - } - } - - #endregion - - #region SIP008 - - - public async Task UpdateOnlineConfigInternal(string url) - { - var onlineServer = await OnlineConfigResolver.GetOnline(url); - _config.configs = Configuration.SortByOnlineConfig( - _config.configs - .Where(c => c.group != url) - .Concat(onlineServer) - ); - logger.Info($"updated {onlineServer.Count} server from {url}"); - return onlineServer.Count; - } - - public async Task UpdateOnlineConfig(string url) - { - var selected = GetCurrentServer(); - try - { - int count = await UpdateOnlineConfigInternal(url); - } - catch (Exception e) - { - logger.LogUsefulException(e); - return false; - } - _config.index = _config.configs.IndexOf(selected); - SaveConfig(_config); - return true; - } - - public async Task> UpdateAllOnlineConfig() - { - var selected = GetCurrentServer(); - var failedUrls = new List(); - foreach (var url in _config.onlineConfigSource) - { - try - { - await UpdateOnlineConfigInternal(url); - } - catch (Exception e) - { - logger.LogUsefulException(e); - failedUrls.Add(url); - } - } - - _config.index = _config.configs.IndexOf(selected); - SaveConfig(_config); - return failedUrls; - } - - public void SaveOnlineConfigSource(List sources) - { - _config.onlineConfigSource = sources; - SaveConfig(_config); - } - - public void RemoveOnlineConfig(string url) - { - _config.onlineConfigSource.RemoveAll(v => v == url); - _config.configs = Configuration.SortByOnlineConfig( - _config.configs.Where(c => c.group != url) - ); - SaveConfig(_config); - } - - #endregion - } -} diff --git a/shadowsocks-csharp/Data/i18n.csv b/shadowsocks-csharp/Data/i18n.csv deleted file mode 100644 index 8a3a6689..00000000 --- a/shadowsocks-csharp/Data/i18n.csv +++ /dev/null @@ -1,157 +0,0 @@ -en,ru-RU,zh-CN,zh-TW,ja,ko,fr -#Restart program to apply translation,,,,,, -#This is comment line,,,,,, -#Always keep language name at head of file,,,,,, -#Language name is output in log,,,,,, -"#You can find it by search ""Current language is:""",,,,,, -#Please use UTF-8 with BOM encoding so we can edit it in Excel,,,,,, -,,,,,, -Shadowsocks,Shadowsocks,Shadowsocks,Shadowsocks,Shadowsocks,Shadowsocks,Shadowsocks -,,,,,, -#Menu,,,,,, -,,,,,, -System Proxy,Системный прокси-сервер,系统代理,系統代理,システムプロキシ,시스템 프록시,Proxy système -Disable,Отключен,禁用,禁用,無効,비활성화,Désactiver -PAC,Сценарий настройки (PAC),PAC 模式,PAC 模式,PACモード,프록시 자동 구성 (PAC),PAC -Global,Для всей системы,全局模式,全局模式,グローバルプロキシ,전역,Global -Servers,Серверы,服务器,伺服器,サーバー,서버,Serveurs -Edit Servers...,Редактировать серверы…,编辑服务器...,編輯伺服器...,サーバーの編集...,서버 수정…,Éditer serveurs… -Online Config...,,在线配置...,線上配置...,,, -Start on Boot,Автозагрузка,开机启动,開機啟動,システム起動時に実行,시스템 시작 시에 시작하기,Démarrage automatique -Associate ss:// Links,Ассоциированный ss:// Ссылки,关联 ss:// 链接,關聯 ss:// 鏈接,ss:// リンクの関連付け,ss:// 링크 연결, -Forward Proxy...,Прямой прокси…,正向代理设置...,正向 Proxy 設定...,フォワードプロキシの設定...,포워드 프록시,Forward-proxy… -Allow other Devices to connect,Общий доступ к подключению,允许其他设备连入,允許其他裝置連入,他のデバイスからの接続を許可する,다른 기기에서 연결 허용,Autoriser d'autres appareils à se connecter -Local PAC,Локальный PAC,使用本地 PAC,使用本機 PAC,ローカル PAC,로컬 프록시 자동 구성,PAC local -Online PAC,Удаленный PAC,使用在线 PAC,使用線上 PAC,オンライン PAC,온라인 프록시 자동 구성,PAC en ligne -Edit Local PAC File...,Редактировать локальный PAC…,编辑本地 PAC 文件...,編輯本機 PAC 檔案...,ローカル PAC ファイルの編集...,로컬 프록시 자동 구성 파일 수정,Modifier le fichier PAC local ... -Update Local PAC from Geosite,Обновить локальный PAC из Geosite,从 Geosite 更新本地 PAC,從 Geosite 更新本機 PAC,Geosite からローカル PAC を更新,Geosite에서 로컬 프록시 자동 구성 파일 업데이트,Mettre à jour le PAC local à partir de Geosite -Edit User Rule for Geosite...,Редактировать свои правила для Geosite,编辑 Geosite 的用户规则...,編輯 Geosite 的使用者規則...,ユーザールールの編集...,Geosite 사용자 수정,Modifier la règle utilisateur pour Geosite ... -Secure Local PAC,Безопасный URL локального PAC,保护本地 PAC,安全本機 PAC,ローカル PAC を保護,로컬 프록시 자동 구성 파일 암호화,Sécuriser PAC local -Regenerate local PAC on version update,,版本更新后重新生成本地 PAC,版本更新後重新生成本地 PAC,,, -Copy Local PAC URL,Копировать URL локального PAC,复制本地 PAC 网址,複製本機 PAC 網址,ローカル PAC URL をコピー,로컬 프록시 자동 구성 파일 URL 복사,Copier l'URL du PAC local -Share Server Config...,Поделиться конфигурацией сервера…,分享服务器配置...,分享伺服器設定檔...,サーバーの設定を共有...,서버 설정 공유,Partager la configuration du serveur ... -Scan QRCode from Screen...,Сканировать QRCode с экрана…,扫描屏幕上的二维码...,掃描螢幕上的 QR 碼...,画面から QR コードをスキャン...,화면에서 QR코드 스캔,Scanner le QRCode à partir de l'écran ... -Import URL from Clipboard...,Импорт адреса из буфера обмена…,从剪贴板导入URL...,從剪貼簿匯入 URL...,クリップボードから URL をインポート...,클립보드에서 URL 가져오기…,Importer l'URL du presse-papiers ... -Availability Statistics,Статистика доступности,统计可用性,統計可用性,可用性の統計,가용성 통계,Statistiques de disponibilité -Show Logs...,Показать журнал…,显示日志...,顯示記錄檔...,ログの表示...,로그 보기…,Afficher les journaux ... -Verbose Logging,Подробный журнал,详细记录日志,詳細資訊記錄,詳細なログを記録,자세한 로깅 사용,Journalisation détaillée -Updates...,Обновления…,更新...,更新...,アップデート...,업데이트…,Mettre à jour… -Check for Updates...,Проверить обновления…,检查更新,檢查更新,アップデートを確認...,업데이트 확인하기…,Vérifier les mises à jour ... -Check for Updates at Startup,Проверять при запуске,启动时检查更新,啟動時檢查更新,起動時にアップデートを確認,시스템 시작 시 업데이트 확인하기,Vérifier les mises à jour au démarrage -Check Pre-release Version,Проверять предрелизные версии,检查测试版更新,檢查發行前版本更新,ベータ版のアップデートも確認,개발 버전 업데이트 확인하기,Vérifier la version préliminaire -Edit Hotkeys...,Горячие клавиши…,编辑快捷键...,編輯快速鍵...,ホットキーの編集...,단축키 수정…,Modifier les raccourcis clavier ... -About...,О программе…,关于...,關於...,Shadowsocks について...,정보…,A propos -Help,Помощь,帮助,說明,ヘルプ,도움말,Aide -Quit,Выход,退出,結束,終了,종료,Quitter -Edit Servers,Редактирование серверов,编辑服务器,編輯伺服器,サーバーの編集,서버 수정,Éditer serveurs -Load Balance,Балансировка нагрузки,负载均衡,負載平衡,サーバーロードバランス,로드밸런싱,Répartition de charge -High Availability,Высокая доступность,高可用,高可用性,高可用性,고가용성,Haute disponibilité -Show Plugin Output,События плагинов в журнале,显示插件输出,,プラグインの出力情報を表示,플러그인 출력 보이기,Afficher la sortie du plugin -Write translation template,Создать шаблон для перевода,写入翻译模板,,翻訳テンプレートファイルを書き込む,번역 템플릿 쓰기,Écrire un modèle de traduction -,,,,,, -# Config Form,,,,,, -,,,,,, -Statistics configuration,Настройки статистики,统计配置,,統計の設定,통계 설정,Configuration des statistiques -&Add,Добавить,添加(&A),新增 (&A),新規 (&A),추가 (&A),Ajouter -&Delete,Удалить,删除(&D),移除 (&D),削除 (&D),삭제 (&D),Supprimer -Dupli&cate,Дублир-ть,复制(&C),複製 (&C),コピー (&C),복제 (&C),Dupliquer -Server,Сервер,服务器,伺服器,サーバー,서버,Serveur -Server IP,IP-адрес,服务器地址,伺服器位址,サーバーアドレス,서버 IP,Serveur IP -Server Port,Порт,服务器端口,伺服器連接埠,サーバーポート,서버 포트,Port de serveur -Password,Пароль,密码,密碼,パスワード,비밀번호,Mot de passe -Show Password,Показать пароль,显示密码,顯示密碼,パスワードを表示する,비밀번호 보이기,Montrer le mot de passe -Encryption,Шифрование,加密,加密,暗号化,암호화,Chiffrement -Plugin Program,Плагин,插件程序,外掛程式,プラグインプログラム,플러그인 프로그램,Programme de plugin -Plugin Options,Опции плагина,插件选项,外掛程式選項,プラグインのオプション,플러그인 설정,Options de plugin -Need Plugin Argument,Требуются аргументы,需要命令行参数,,コマンドライン引数を有効にする,플러그인 인자가 필요함,Besoin d'un argument de plugin -Plugin Arguments,Аргументы,插件参数,外掛程式參數,プラグインの引数,플러그인 인자,Arguments du plugin -Proxy Port,Порт прокси,代理端口,Proxy 連接埠,プロキシポート,프록시 포트,Port proxy -Portable Mode,Переносимый режим,便携模式,便攜模式,ポータブルモード,포터블 모드,Mode portable -Restart required,Требуется перезапуск программы,需要重新启动SS,需要重新啟動SS,再起動が必要,재시작이 필요합니다,Redémarrage nécessaire -Remarks,Примечания,备注,註解,付記,알림,Remarques -Timeout(Sec),Таймаут(сек),超时(秒),逾時 (秒),タイムアウト (秒),시간 초과 (초),Délai d'attente(sec) -OK,ОК,确定,確定,OK,확인,OK -Cancel,Отмена,取消,取消,キャンセル,취소,Annuler -Apply,Применить,应用,應用,適用,적용,Appliquer -New server,Новый сервер,未配置的服务器,新伺服器,新規サーバー,새 서버,Nouveau serveur -Move &Up,Выше,上移(&U),上移 (&U),上に移動 (&U),위로 (&U),Monter -Move D&own,Ниже,下移(&O),下移 (&O),下に移動 (&O),아래로 (&O),Descendre -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}" -,,,,,, -# Log Form,,,,,, -,,,,,, -&File,Файл,文件(&F),檔案 (&F),ファイル (&F),파일 (&F),Fichier -&Open Location,Расположение файла,在资源管理器中打开(&O),在檔案總管中開啟 (&O),ファイルの場所を開く (&O),위치 열기 (&O),Ouvrier -E&xit,Выход,退出(&X),結束 (&X),終了 (&X),종료 (&X),Quitter -&View,Вид,视图(&V),檢視 (&V),表示 (&V),보기 (&V),Afficher -&Clear Logs,Очистить журнал,清空日志(&C),清除記錄檔 (&C),ログの削除 (&C),로그 초기화 (&C),Effacer les journaux -Change &Font,Шрифт…,设置字体(&F),變更字型 (&F),フォント (&F),글꼴 변경 (&F),Définir la police -&Wrap Text,Перенос строк,自动换行(&W),自動換行 (&W),右端で折り返す (&W),텍스트 감싸기 (&W),Retour à la ligne -&Top Most,Поверх всех окон,置顶(&T),置頂 (&T),常に最前面に表示 (&T),상단 우선 (Top Most) (&T),Metter en haut -&Show Toolbar,Панель инструментов,显示工具栏(&S),顯示工具列 (&S),ツールバーの表示 (&S),툴바 보여주기 (&S),Afficher la barre d'outils -Log Viewer,Просмотр журнала,日志查看器,記錄檔檢視器,ログビューア,로그 뷰어,Visionneuse de journaux -Inbound,Входящая,入站,輸入,受信,"인바운드 (Rx, 다운로드)",Entrant -Outbound,Исходящая,出站,輸出,送信,"아웃바운드 (Tx, 업로드)",Sortant -,,,,,, -# QRCode Form,,,,,, -,,,,,, -QRCode and URL,QRCode и URL,二维码与 URL,QR 碼與 URL,QR コードと URL,QR코드와 URL,QRCode et URL -,,,,,, -# PAC Url Form,,,,,, -,,,,,, -Edit Online PAC URL,Изменение URL удаленного PAC,编辑在线 PAC 网址,編輯線上 PAC 網址,オンライン PAC URL の編集,온라인 프록시 자동 구성 URL 수정,Modifier l'URL du PAC en ligne -Edit Online PAC URL...,Редактировать URL удаленного PAC…,编辑在线 PAC 网址...,編輯線上 PAC 網址...,オンライン PAC URL の編集...,온라인 프록시 자동 구성 URL 수정…,Modifier l'URL du PAC en ligne ... -Please input PAC Url,Введите URL адрес для PAC-файла,请输入 PAC 网址,請輸入 PAC 網址,PAC URLを入力して下さい,프록시 자동 구성 URL을 입력하세요,Veuillez saisir l'URL PAC -,,,,,, -# Messages,,,,,, -,,,,,, -Shadowsocks Error: {0},Ошибка Shadowsocks: {0},Shadowsocks 错误: {0},Shadowsocks 錯誤: {0},Shadowsocks エラー: {0},Shadowsocks 오류: {0},Erreur shadowsocks: {0} -Port {0} already in use,Порт {0} уже используется,端口 {0} 已被占用,連接埠號碼 {0} 已被使用,ポート番号 {0} は既に使用されています。,{0}번 포트는 이미 사용 중입니다.,Port {0} déjà utilisé -Port {0} is reserved by system,Порт {0} зарезервирован системой,端口 {0} 是系统保留端口,連接埠號碼 {0} 由系統保留, ポート番号 {0} はシステムによって予約されています,{0}번 포트는 시스템에서 사용 중입니다.,Port {0} réservé par le système -Invalid server address,Неверный адрес сервера,非法服务器地址,無效伺服器位址,サーバーアドレスが無効です。,올바르지 않은 서버 주소입니다.,Adresse de serveur non valide -Illegal port number format,Неверный числовой формат порта,非法端口格式,無效連接埠號碼格式,ポート番号のフォーマットが無効です。,올바르지 않은 포트 번호 형식입니다.,Format de numéro de port illégal -Illegal timeout format,Неверный формат таймаута,非法超时格式,無效逾時格式,タイムアウト値のフォーマットが無効です。,올바르지 않은 시간 초과 형식입니다.,Format de délai d'attente illégal -Server IP can not be blank,IP-адрес сервера не может быть пустым,服务器 IP 不能为空,伺服器 IP 不能為空,サーバー IP が指定されていません。,서버 IP는 비어있으면 안됩니다.,L'adresse IP du serveur ne peut pas être vide -Password can not be blank,Пароль не может быть пустым,密码不能为空,密碼不能為空,パスワードが指定されていません。,비밀번호는 비어있으면 안됩니다.,Le mot de passe ne peut pas être vide -Port out of range,Порт выходит за допустимый диапазон,端口超出范围,連接埠號碼超出範圍,ポート番号は範囲外です。,올바른 포트 범위가 아닙니다.,Port hors de portée -Port can't be 8123,Адрес порта 8123 не может быть использован,端口不能为 8123,連接埠號碼不能為 8123,8123 番以外のポート番号を指定して下さい。,8123번 포트는 사용할 수 없습니다.,Le port ne peut pas être 8123 -No update is available,Обновлений не обнаружено,没有可用的更新,沒有可用的更新,お使いのバージョンは最新です。,사용 가능한 업데이트가 없습니다.,Aucune mise à jour n'est disponible -Shadowsocks is here,Shadowsocks находится здесь,Shadowsocks 在这里,Shadowsocks 在這裡,Shadowsocks はここです。,Shadowsocks는 여기에 있습니다,Veuillez trouver Shadowsocks ici -You can turn on/off Shadowsocks in the context menu,Вы можете управлять Shadowsocks из контекстного меню,可以在右键菜单中开关 Shadowsocks,可以在右鍵選項單中開關 Shadowsocks,コンテキストメニューを使って、Shadowsocks を有効または無効にすることができます。,프로그램 메뉴에서 Shadowsocks를 끄고 켤 수 있습니다.,Vous pouvez activer / désactiver Shadowsocks dans le menu contextuel -System Proxy Enabled,Системный прокси включен,系统代理已启用,系統 Proxy 已啟用,システム プロキシが有効です。,시스템 프록시가 활성화되었습니다.,Proxy système activé -System Proxy Disabled,Системный прокси отключен,系统代理未启用,系統 Proxy 未啟用,システム プロキシが無効です。,시스템 프록시가 비활성화되었습니다.,Proxy système désactivé -Failed to update PAC file ,Не удалось обновить PAC файл,更新 PAC 文件失败,更新 PAC 檔案失敗,PAC の更新に失敗しました。,프록시 자동 구성 파일을 업데이트하는데 실패했습니다.,Impossible de mettre à jour le fichier PAC -PAC updated,PAC файл обновлен,更新 PAC 成功,更新 PAC 成功,PAC を更新しました。,프록시 자동 구성 파일이 업데이트되었습니다.,PAC mis à jour -No updates found. Please report to Geosite if you have problems with it.,Обновлений не найдено. Сообщите авторам Geosite если у вас возникли проблемы.,未发现更新。如有问题请提交给 Geosite。,未發現更新。如有問題請報告至 Geosite。,お使いのバージョンは最新です。問題がある場合は、GFWList に報告して下さい。,사용 가능한 업데이트를 찾지 못했습니다. 문제가 있다면 Geosite로 전송해주세요.,Aucune mise à jour trouvée. Veuillez signaler à Geosite si vous avez des problèmes concernant. -No QRCode found. Try to zoom in or move it to the center of the screen.,QRCode не обнаружен. Попробуйте увеличить изображение или переместить его в центр экрана.,未发现二维码,尝试把它放大或移动到靠近屏幕中间的位置,未發現 QR 碼,嘗試把它放大或移動到靠近熒幕中間的位置,QR コードが見つかりませんでした。コードを大きくするか、画面の中央に移動して下さい。,QR코드를 찾을 수 없습니다. 가운데로 화면을 이동시키거나 확대해보세요.,Aucun QRCode trouvé. Essayez de zoomer ou de le déplacer vers le centre de l'écran. -Shadowsocks is already running.,Shadowsocks уже запущен.,Shadowsocks 已经在运行。,Shadowsocks 已經在執行。,Shadowsocks 実行中,Shadowsocks가 이미 실행 중입니다.,Shadowsocks est déjà en cours d'exécution. -Find Shadowsocks icon in your notify tray.,Значок Shadowsocks можно найти в области уведомлений.,请在任务栏里寻找 Shadowsocks 图标。,請在工作列裡尋找 Shadowsocks 圖示。,通知領域には Shadowsocks のアイコンがあります。,트레이에서 Shadowsocks를 찾아주세요.,Trouvez l'icône Shadowsocks dans votre barre de notification. -"If you want to start multiple Shadowsocks, make a copy in another directory.","Если вы хотите запустить несколько копий Shadowsocks одновременно, создайте отдельную папку на каждую копию.",如果想同时启动多个,可以另外复制一份到别的目录。,如果想同時啟動多個,可以另外複製一份至別的目錄。,複数起動したい場合は、プログラムファイルを別のフォルダーにコピーしてから、もう一度実行して下さい。,"만약 여러 개의 Shadowsocks를 사용하고 싶으시다면, 파일을 다른 곳에 복사해주세요.","Si vous souhaitez démarrer plusieurs Shadowsocks, faites une copie dans un autre répertoire." -Invalid QR Code content: {0},,无效二维码内容: {0},無效二維碼內容: {0},,, -Failed to update registry,Не удалось обновить запись в реестре,无法修改注册表,無法修改登錄檔,レジストリの更新に失敗しました。,레지스트리를 업데이트하는데에 실패했습니다.,Impossible de mettre à jour de la base de registre -Import from URL: {0} ?,импортировать из адреса: {0} ?,从URL导入: {0} ?,從URL匯入: {0} ?,{0}:このURLからインポートしますか?,, -Successfully imported from {0},Успешно импортировано из {0},导入成功:{0},導入成功:{0},{0}:インポートしました。,, -Failed to import. Please check if the link is valid.,,导入失败,请检查链接是否有效。,導入失敗,請檢查鏈接是否有效。,インポートに失敗しました。リンクの有効性を確認してください。,, -System Proxy On: ,Системный прокси:,系统代理已启用:,系統 Proxy 已啟用:,システム プロキシが有効:,시스템 프록시 활성화됨: ,Proxy système activé: -Running: Port {0},Запущен на порту {0},正在运行:端口 {0},正在執行:連接埠號碼 {0},実行中:ポート {0},실행 중: 포트 {0}번,En cours d'exécution: port {0} -"Unexpected error, shadowsocks will exit. Please report to","Непредвиденная ошибка, пожалуйста сообщите на",非预期错误,Shadowsocks将退出。请提交此错误到,非預期錯誤,Shadowsocks 將結束。請報告此錯誤至,予想外のエラーが発生したため、Shadowsocks を終了します。詳しくは下記までお問い合わせ下さい:,알 수 없는 오류로 Shadowsocks가 종료될 것입니다. 오류를 여기로 제보해주세요:,Shadowsocks va quitter en présence d/érreur inattendue. Veuillez signaler à -"Unsupported operating system, use Windows Vista at least.","Операционная система не поддерживается, минимальные системные требования: Windows Vista или выше.",不支持的操作系统版本,最低需求为Windows Vista。,不支援的作業系統版本,最低需求為 Windows Vista。,お使いの OS はサポートされていません。Windows Vista 以降の OS で実行して下さい。,지원하지 않는 운영체제입니다. 최소 Windows Vista가 필요합니다.,"Système d'exploitation incompatible, veuillez utiliser Windows Vista ou ultérieure." -"Unsupported .NET Framework, please update to {0} or later.","Версия .NET Framework не поддерживается, минимальные системные требования: {0} или выше.",当前 .NET Framework 版本过低,请升级至{0}或更新版本。,目前 .NET Framework 版本過低,最低需求為{0}。,お使いの .NET Framework はサポートされていません。{0} 以降のバンジョーをインストールして下さい。,지원하지 않는 .NET 프레임워크입니다. {0} 또는 상위 버전으로 업데이트해주세요.,".NET Framework incompatible, veuillez mettre à jour vers {0} ou ultérieure." -Proxy request failed,Не удалось выполнить запрос,代理请求失败,Proxy 要求失敗,プロキシリクエストが失敗しました。,프록시 요청에 실패했습니다.,Échec de la demande de proxy -Proxy handshake failed,Не удалось выполнить хэндшейк,代理握手失败,Proxy 交握失敗,プロキシ ハンドシェイクに失敗しました。,프록시 핸드쉐이크에 실패했습니다.,Échec de la prise de contact par proxy -Register hotkey failed,Не удалось применить настройки горячих клавиш,注册快捷键失败,註冊快速鍵失敗,ホットキーの登錄に失敗しました。,단축키 등록에 실패했습니다.,Échec de l'enregistrement du raccourci clavier -Cannot parse hotkey: {0},Не удалось распознать следующие горячие клавиши: {0},解析快捷键失败: {0},剖析快速鍵失敗: {0},ホットキーを解析できません: {0},단축키를 해석할 수 없습니다: {0},Impossible d'analyser le raccourci clavier: {0} -"Timeout is invalid, it should not exceed {0}",Таймаут не может превышать значение {0},超时无效,不应超过 {0},逾時無效,不應超過 {0},タイムアウト値が無効です。{0} 以下の値を指定して下さい。,올바르지 않은 시간 초과 설정입니다. {0}을 초과하지 않아야 합니다.,"Le délai d'attente invalide, il ne doit pas dépasser {0}" -Cannot find the plugin program file,Файл плагина не найден,找不到插件程序文件,找不到外掛程式文件,プラグインプログラムが見つかりません,플러그인 프로그램 파일을 찾을 수 없습니다.,Impossible de trouver le fichier du programme du plugin -,,,,,, -Operation failure,Операция завершилась неудачей,操作失败,,操作に失敗しました,작업에 실패했습니다.,Operation failure -Auto save failed,Автоматическое сохранение не удалось,自动保存失败,,オートセーブに失敗しました,자동 저장에 실패했습니다.,Échec de l'enregistrement automatique -Whether to discard unconfigured servers,Внесенные изменения будут утеряны,是否丢弃未配置的服务器,,未設定のサーバーを破棄しますか,구성되지 않은 서버 설정 변경 사항을 폐기하시겠습니까?,Eliminer les serveurs non configurés ou non -"Invalid server address, Cannot automatically save or discard changes",Неверный адрес сервера. Невозможно сохранить или отменить изменения,非法服务器地址,无法自动保存,是否丢弃修改,,サーバーアドレスが無効なため、オートセーブできません。変更を破棄しますか,"서버 주소가 올바르지 않아 자동 저장 할 수 없습니다, 변경 사항을 폐기하시겠습니까?","Adresse de serveur invalide, impossible d'enregistrer ou d'annuler automatiquement les modifications" -"Illegal port number format, Cannot automatically save or discard changes",Неверный числовой адрес порта. Невозможно сохранить или отменить изменения,非法端口格式,无法自动保存,是否丢弃修改,,ポート番号のフォーマットが無効なため、オートセーブできません。変更を破棄しますか,"포트 번호가 올바르지 않아 자동 저장 할 수 없습니다, 변경 사항을 폐기하시겠습니까?","Format de numéro de port illégal, impossible d'enregistrer ou d'annuler automatiquement les modifications" -"Password can not be blank, Cannot automatically save or discard changes",Пароль не может быть пустым. Невозможно сохранить или отменить изменения,密码不能为空,无法自动保存,是否丢弃修改,,サーバーアドレスが無効なため、オートセーブできません。変更を破棄しますか,"비밀번호를 입력하지 않아 자동 저장 할 수 없습니다, 변경 사항을 폐기하시겠습니까?","Le mot de passe ne peut pas être vide, impossible d'enregistrer ou d'annuler automatiquement les modifications" -"Illegal timeout format, Cannot automatically save or discard changes",Неверный формат таймаута. Невозможно сохранить или отменить изменения,非法超时格式,无法自动保存,是否丢弃修改,,パスワードが指定されていないため、オートセーブできません。変更を破棄しますか,시간 초과 형식이 올바르지 않아 자동 저장 할 수 없습니다. 변경 사항을 폐기하시겠습니까?,"Format de délai d'attente illégal, impossible d'enregistrer ou d'annuler automatiquement les modifications" -,,,,タイムアウト値のフォーマットが無効なため、オートセーブできません。変更を破棄しますか,, -"Error occured when process proxy setting, do you want reset current setting and retry?",Произошла ошибка при обработке настроек. Хотите сбросить текущие настройки и попробовать снова?,处理代理设置时发生错误,是否重置当前代理设置并重试?,,プロキシ設定の処理にエラーが発生しました、現在のプロキシ設定をリセットし、再試行してもいいですか,프록시 설정을 처리하는데에 오류가 발생했습니다. 현재 설정을 폐기하고 다시 시도하시겠습니까?,Une erreur s'est produite lors du processus de configuration du proxy. Voulez-vous réinitialiser le paramètre actuel et réessayer? -"Unrecoverable proxy setting error occured, see log for detail","Произошла серьезная ошибка, подробности можно узнать в журналах",发生不可恢复的代理设置错误,查看日志以取得详情,,プロキシ設定に回復不能なエラーが発生しました、ログで詳細をご確認ください,복구 불가능한 프록시 설정 오류가 발생했습니다. 자세한 정보는 로그를 참조하세요.,"Une erreur de paramètre de proxy irrécupérable s'est produite, consultez le journal pour plus de détails" diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs deleted file mode 100644 index 9e4cabda..00000000 --- a/shadowsocks-csharp/Model/Configuration.cs +++ /dev/null @@ -1,382 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Windows; -using Newtonsoft.Json; -using NLog; -using Shadowsocks.Controller; - -namespace Shadowsocks.Model -{ - [Serializable] - public class Configuration - { - [JsonIgnore] - private static readonly Logger logger = LogManager.GetCurrentClassLogger(); - - public string version; - - public List configs; - - public List onlineConfigSource; - - // when strategy is set, index is ignored - public string strategy; - public int index; - public bool global; - public bool enabled; - public bool shareOverLan; - public bool firstRun; - public int localPort; - public bool portableMode; - public bool showPluginOutput; - public string pacUrl; - - public bool useOnlinePac; - public bool secureLocalPac; // enable secret for PAC server - public bool regeneratePacOnUpdate; // regenerate pac.txt on version update - public bool autoCheckUpdate; - public bool checkPreRelease; - public string skippedUpdateVersion; // skip the update with this version number - public bool isVerboseLogging; - - // hidden options - public bool isIPv6Enabled; // for experimental ipv6 support - public bool generateLegacyUrl; // for pre-sip002 url compatibility - public string geositeUrl; // for custom geosite source (and rule group) - public List geositeDirectGroups; // groups of domains that we connect without the proxy - public List geositeProxiedGroups; // groups of domains that we connect via the proxy - public bool geositePreferDirect; // a.k.a blacklist mode - public string userAgent; - - //public NLogConfig.LogLevel logLevel; - public LogViewerConfig logViewer; - public ForwardProxyConfig proxy; - public HotkeyConfig hotkey; - - [JsonIgnore] - public bool firstRunOnNewVersion; - - public Configuration() - { - version = UpdateChecker.Version; - strategy = ""; - index = 0; - global = false; - enabled = false; - shareOverLan = false; - firstRun = true; - localPort = 1080; - portableMode = true; - showPluginOutput = false; - pacUrl = ""; - useOnlinePac = false; - secureLocalPac = true; - regeneratePacOnUpdate = true; - autoCheckUpdate = false; - checkPreRelease = false; - skippedUpdateVersion = ""; - isVerboseLogging = false; - - // hidden options - isIPv6Enabled = false; - generateLegacyUrl = false; - geositeUrl = ""; - geositeDirectGroups = new List() - { - "private", - "cn", - "geolocation-!cn@cn", - }; - geositeProxiedGroups = new List() - { - "geolocation-!cn", - }; - geositePreferDirect = false; - userAgent = "ShadowsocksWindows/$version"; - - logViewer = new LogViewerConfig(); - proxy = new ForwardProxyConfig(); - hotkey = new HotkeyConfig(); - - firstRunOnNewVersion = false; - - configs = new List(); - onlineConfigSource = new List(); - } - - [JsonIgnore] - public string userAgentString; // $version substituted with numeral version in it - - [JsonIgnore] - NLogConfig nLogConfig; - - private static readonly string CONFIG_FILE = "gui-config.json"; -#if DEBUG - private static readonly NLogConfig.LogLevel verboseLogLevel = NLogConfig.LogLevel.Trace; -#else - private static readonly NLogConfig.LogLevel verboseLogLevel = NLogConfig.LogLevel.Debug; -#endif - - [JsonIgnore] - public string LocalHost => isIPv6Enabled ? "[::1]" : "127.0.0.1"; - - public Server GetCurrentServer() - { - if (index >= 0 && index < configs.Count) - return configs[index]; - else - return GetDefaultServer(); - } - - public WebProxy WebProxy => enabled - ? new WebProxy( - isIPv6Enabled - ? $"[{IPAddress.IPv6Loopback}]" - : IPAddress.Loopback.ToString(), - localPort) - : null; - - /// - /// Used by multiple forms to validate a server. - /// Communication is done by throwing exceptions. - /// - /// - public static void CheckServer(Server server) - { - CheckServer(server.server); - CheckPort(server.server_port); - CheckPassword(server.password); - CheckTimeout(server.timeout, Server.MaxServerTimeoutSec); - } - - /// - /// Loads the configuration from file. - /// - /// An Configuration object. - public static Configuration Load() - { - Configuration config; - if (File.Exists(CONFIG_FILE)) - { - try - { - string configContent = File.ReadAllText(CONFIG_FILE); - config = JsonConvert.DeserializeObject(configContent, new JsonSerializerSettings() - { - ObjectCreationHandling = ObjectCreationHandling.Replace - }); - return config; - } - catch (Exception e) - { - if (!(e is FileNotFoundException)) - logger.LogUsefulException(e); - } - } - config = new Configuration(); - return config; - } - - /// - /// Process the loaded configurations and set up things. - /// - /// A reference of Configuration object. - public static void Process(ref Configuration config) - { - // Verify if the configured geosite groups exist. - // Reset to default if ANY one of the configured group doesn't exist. - if (!ValidateGeositeGroupList(config.geositeDirectGroups)) - ResetGeositeDirectGroup(ref config.geositeDirectGroups); - if (!ValidateGeositeGroupList(config.geositeProxiedGroups)) - ResetGeositeProxiedGroup(ref config.geositeProxiedGroups); - - // Mark the first run of a new version. - var appVersion = new Version(UpdateChecker.Version); - var configVersion = new Version(config.version); - if (appVersion.CompareTo(configVersion) > 0) - { - config.firstRunOnNewVersion = true; - } - // Add an empty server configuration - if (config.configs.Count == 0) - config.configs.Add(GetDefaultServer()); - // Selected server - if (config.index == -1 && string.IsNullOrEmpty(config.strategy)) - config.index = 0; - if (config.index >= config.configs.Count) - config.index = config.configs.Count - 1; - // Check OS IPv6 support - if (!System.Net.Sockets.Socket.OSSupportsIPv6) - config.isIPv6Enabled = false; - config.proxy.CheckConfig(); - // Replace $version with the version number. - config.userAgentString = config.userAgent.Replace("$version", config.version); - - // NLog log level - try - { - config.nLogConfig = NLogConfig.LoadXML(); - switch (config.nLogConfig.GetLogLevel()) - { - case NLogConfig.LogLevel.Fatal: - case NLogConfig.LogLevel.Error: - case NLogConfig.LogLevel.Warn: - case NLogConfig.LogLevel.Info: - config.isVerboseLogging = false; - break; - case NLogConfig.LogLevel.Debug: - case NLogConfig.LogLevel.Trace: - config.isVerboseLogging = true; - break; - } - } - catch (Exception e) - { - MessageBox.Show($"Cannot get the log level from NLog config file. Please check if the nlog config file exists with corresponding XML nodes.\n{e.Message}"); - } - } - - /// - /// Saves the Configuration object to file. - /// - /// A Configuration object. - public static void Save(Configuration config) - { - config.configs = SortByOnlineConfig(config.configs); - - FileStream configFileStream = null; - StreamWriter configStreamWriter = null; - try - { - configFileStream = File.Open(CONFIG_FILE, FileMode.Create); - configStreamWriter = new StreamWriter(configFileStream); - var jsonString = JsonConvert.SerializeObject(config, Formatting.Indented); - configStreamWriter.Write(jsonString); - configStreamWriter.Flush(); - // NLog - config.nLogConfig.SetLogLevel(config.isVerboseLogging ? verboseLogLevel : NLogConfig.LogLevel.Info); - NLogConfig.SaveXML(config.nLogConfig); - } - catch (Exception e) - { - logger.LogUsefulException(e); - } - finally - { - if (configStreamWriter != null) - configStreamWriter.Dispose(); - if (configFileStream != null) - configFileStream.Dispose(); - } - } - - public static List SortByOnlineConfig(IEnumerable servers) - { - var groups = servers.GroupBy(s => s.group); - List ret = new List(); - ret.AddRange(groups.Where(g => string.IsNullOrEmpty(g.Key)).SelectMany(g => g)); - ret.AddRange(groups.Where(g => !string.IsNullOrEmpty(g.Key)).SelectMany(g => g)); - return ret; - } - - /// - /// Validates if the groups in the list are all valid. - /// - /// The list of groups to validate. - /// - /// True if all groups are valid. - /// False if any one of them is invalid. - /// - public static bool ValidateGeositeGroupList(List groups) - { - foreach (var geositeGroup in groups) - if (!GeositeUpdater.CheckGeositeGroup(geositeGroup)) // found invalid group - { -#if DEBUG - logger.Debug($"Available groups:"); - foreach (var group in GeositeUpdater.Geosites.Keys) - logger.Debug($"{group}"); -#endif - logger.Warn($"The Geosite group {geositeGroup} doesn't exist. Resetting to default groups."); - return false; - } - return true; - } - - public static void ResetGeositeDirectGroup(ref List geositeDirectGroups) - { - geositeDirectGroups.Clear(); - geositeDirectGroups.Add("private"); - geositeDirectGroups.Add("cn"); - geositeDirectGroups.Add("geolocation-!cn@cn"); - } - - public static void ResetGeositeProxiedGroup(ref List geositeProxiedGroups) - { - geositeProxiedGroups.Clear(); - geositeProxiedGroups.Add("geolocation-!cn"); - } - - public static void ResetUserAgent(Configuration config) - { - config.userAgent = "ShadowsocksWindows/$version"; - config.userAgentString = config.userAgent.Replace("$version", config.version); - } - - public static Server AddDefaultServerOrServer(Configuration config, Server server = null, int? index = null) - { - if (config?.configs != null) - { - server = (server ?? GetDefaultServer()); - - config.configs.Insert(index.GetValueOrDefault(config.configs.Count), server); - - //if (index.HasValue) - // config.configs.Insert(index.Value, server); - //else - // config.configs.Add(server); - } - return server; - } - - public static Server GetDefaultServer() - { - return new Server(); - } - - public static void CheckPort(int port) - { - if (port <= 0 || port > 65535) - throw new ArgumentException(I18N.GetString("Port out of range")); - } - - public static void CheckLocalPort(int port) - { - CheckPort(port); - if (port == 8123) - throw new ArgumentException(I18N.GetString("Port can't be 8123")); - } - - private static void CheckPassword(string password) - { - if (string.IsNullOrEmpty(password)) - throw new ArgumentException(I18N.GetString("Password can not be blank")); - } - - public static void CheckServer(string server) - { - if (string.IsNullOrEmpty(server)) - throw new ArgumentException(I18N.GetString("Server IP can not be blank")); - } - - public static void CheckTimeout(int timeout, int maxTimeout) - { - if (timeout <= 0 || timeout > maxTimeout) - throw new ArgumentException( - I18N.GetString("Timeout is invalid, it should not exceed {0}", maxTimeout)); - } - } -} diff --git a/shadowsocks-csharp/Program.cs b/shadowsocks-csharp/Program.cs deleted file mode 100755 index 8b1803e4..00000000 --- a/shadowsocks-csharp/Program.cs +++ /dev/null @@ -1,215 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.IO.Pipes; -using System.Net; -using System.Reflection; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using System.Windows.Forms; -using CommandLine; -using Microsoft.Win32; -using NLog; -using ReactiveUI; -using Shadowsocks.Controller; -using Shadowsocks.Controller.Hotkeys; -using Shadowsocks.Util; -using Shadowsocks.View; -using Splat; -using WPFLocalizeExtension.Engine; - -namespace Shadowsocks -{ - internal static class Program - { - private static readonly Logger logger = LogManager.GetCurrentClassLogger(); - - public static ShadowsocksController MainController { get; private set; } - public static MenuViewController MenuController { get; private set; } - public static CommandLineOption Options { get; private set; } - public static string[] Args { get; private set; } - - // https://github.com/dotnet/runtime/issues/13051#issuecomment-510267727 - public static readonly string ExecutablePath = Process.GetCurrentProcess().MainModule?.FileName; - public static readonly string WorkingDirectory = Path.GetDirectoryName(ExecutablePath); - - private static readonly Mutex mutex = new Mutex(true, $"Shadowsocks_{ExecutablePath.GetHashCode()}"); - - /// - /// 应用程序的主入口点。 - /// - [STAThread] - static void Main(string[] args) - { - #region Single Instance and IPC - bool hasAnotherInstance = !mutex.WaitOne(TimeSpan.Zero, true); - - // store args for further use - Args = args; - Parser.Default.ParseArguments(args) - .WithParsed(opt => Options = opt) - .WithNotParsed(e => e.Output()); - - if (hasAnotherInstance) - { - if (!string.IsNullOrWhiteSpace(Options.OpenUrl)) - { - IPCService.RequestOpenUrl(Options.OpenUrl); - } - else - { - MessageBox.Show(I18N.GetString("Find Shadowsocks icon in your notify tray.") - + Environment.NewLine - + I18N.GetString("If you want to start multiple Shadowsocks, make a copy in another directory."), - I18N.GetString("Shadowsocks is already running.")); - } - return; - } - #endregion - - #region Enviroment Setup - Directory.SetCurrentDirectory(WorkingDirectory); - // todo: initialize the NLog configuartion - Model.NLogConfig.TouchAndApplyNLogConfig(); - #endregion - - #region Event Handlers Setup - - Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); - // handle UI exceptions - Application.ThreadException += Application_ThreadException; - // handle non-UI exceptions - AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; - Application.ApplicationExit += Application_ApplicationExit; - SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - AutoStartup.RegisterForRestart(true); - - #endregion - - // See https://github.com/dotnet/runtime/issues/13051 - // we have to do this for self-contained executables - Directory.SetCurrentDirectory(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)); - - // We would use this in v5. - // Parameters would have to be dropped from views' constructors (VersionUpdatePromptView) - //Locator.CurrentMutable.RegisterViewsForViewModels(Assembly.GetCallingAssembly()); - - // Workaround for hosting WPF controls in a WinForms app. - // We have to manually set the culture for the LocalizeDictionary instance. - // https://stackoverflow.com/questions/374518/localizing-a-winforms-application-with-embedded-wpf-user-controls - // https://stackoverflow.com/questions/14668640/wpf-localize-extension-translate-window-at-run-time - LocalizeDictionary.Instance.Culture = Thread.CurrentThread.CurrentCulture; - -#if DEBUG - // truncate privoxy log file while debugging - string privoxyLogFilename = Utils.GetTempPath("privoxy.log"); - if (File.Exists(privoxyLogFilename)) - using (new FileStream(privoxyLogFilename, FileMode.Truncate)) { } -#endif - MainController = new ShadowsocksController(); - MenuController = new MenuViewController(MainController); - - HotKeys.Init(MainController); - MainController.Start(); - - // 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); - - if (!string.IsNullOrWhiteSpace(Options.OpenUrl)) - { - MainController.AskAddServerBySSURL(Options.OpenUrl); - } -#endregion - - Application.Run(); - - } - - private static int exited = 0; - private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) - { - if (Interlocked.Increment(ref exited) == 1) - { - string errMsg = e.ExceptionObject.ToString(); - logger.Error(errMsg); - MessageBox.Show( - $"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{errMsg}", - "Shadowsocks non-UI Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - Application.Exit(); - } - } - - private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) - { - if (Interlocked.Increment(ref exited) == 1) - { - string errorMsg = $"Exception Detail: {Environment.NewLine}{e.Exception}"; - logger.Error(errorMsg); - MessageBox.Show( - $"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{errorMsg}", - "Shadowsocks UI Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - Application.Exit(); - } - } - - private static void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e) - { - switch (e.Mode) - { - case PowerModes.Resume: - logger.Info("os wake up"); - if (MainController != null) - { - Task.Factory.StartNew(() => - { - Thread.Sleep(10 * 1000); - try - { - MainController.Start(true); - logger.Info("controller started"); - } - catch (Exception ex) - { - logger.LogUsefulException(ex); - } - }); - } - break; - case PowerModes.Suspend: - if (MainController != null) - { - MainController.Stop(); - logger.Info("controller stopped"); - } - logger.Info("os suspend"); - break; - } - } - - private static void Application_ApplicationExit(object sender, EventArgs e) - { - // detach static event handlers - Application.ApplicationExit -= Application_ApplicationExit; - SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged; - Application.ThreadException -= Application_ThreadException; - HotKeys.Destroy(); - if (MainController != null) - { - MainController.Stop(); - MainController = null; - } - } - } -} diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs deleted file mode 100755 index 3d5794a7..00000000 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ /dev/null @@ -1,652 +0,0 @@ -namespace Shadowsocks.View -{ - partial class ConfigForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); - this.PluginOptionsLabel = new System.Windows.Forms.Label(); - this.PluginTextBox = new System.Windows.Forms.TextBox(); - this.RemarksTextBox = new System.Windows.Forms.TextBox(); - this.IPLabel = new System.Windows.Forms.Label(); - this.ServerPortLabel = new System.Windows.Forms.Label(); - this.PasswordLabel = new System.Windows.Forms.Label(); - this.IPTextBox = new System.Windows.Forms.TextBox(); - this.ServerPortTextBox = new System.Windows.Forms.TextBox(); - this.PasswordTextBox = new System.Windows.Forms.TextBox(); - this.EncryptionLabel = new System.Windows.Forms.Label(); - this.EncryptionSelect = new System.Windows.Forms.ComboBox(); - this.TimeoutLabel = new System.Windows.Forms.Label(); - this.TimeoutTextBox = new System.Windows.Forms.TextBox(); - this.PluginLabel = new System.Windows.Forms.Label(); - this.PluginOptionsTextBox = new System.Windows.Forms.TextBox(); - this.ShowPasswdCheckBox = new System.Windows.Forms.CheckBox(); - this.PluginArgumentsTextBox = new System.Windows.Forms.TextBox(); - this.PluginArgumentsLabel = new System.Windows.Forms.Label(); - this.RemarksLabel = new System.Windows.Forms.Label(); - this.NeedPluginArgCheckBox = new System.Windows.Forms.CheckBox(); - this.panel2 = new System.Windows.Forms.Panel(); - this.OKButton = new System.Windows.Forms.Button(); - this.MyCancelButton = new System.Windows.Forms.Button(); - this.ApplyButton = new System.Windows.Forms.Button(); - this.DeleteButton = new System.Windows.Forms.Button(); - this.AddButton = new System.Windows.Forms.Button(); - this.ServerGroupBox = new System.Windows.Forms.GroupBox(); - this.ServersListBox = new System.Windows.Forms.ListBox(); - this.MoveDownButton = new System.Windows.Forms.Button(); - this.MoveUpButton = new System.Windows.Forms.Button(); - this.ProxyPortTextBox = new System.Windows.Forms.TextBox(); - this.ProxyPortLabel = new System.Windows.Forms.Label(); - this.PortableModeCheckBox = new System.Windows.Forms.CheckBox(); - 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.tableLayoutPanel7.SuspendLayout(); - this.SuspendLayout(); - // - // tableLayoutPanel1 - // - this.tableLayoutPanel1.AutoSize = true; - 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(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); - this.tableLayoutPanel1.Controls.Add(this.IPLabel, 0, 0); - this.tableLayoutPanel1.Controls.Add(this.ServerPortLabel, 0, 1); - this.tableLayoutPanel1.Controls.Add(this.PasswordLabel, 0, 2); - this.tableLayoutPanel1.Controls.Add(this.IPTextBox, 1, 0); - this.tableLayoutPanel1.Controls.Add(this.ServerPortTextBox, 1, 1); - this.tableLayoutPanel1.Controls.Add(this.PasswordTextBox, 1, 2); - this.tableLayoutPanel1.Controls.Add(this.EncryptionLabel, 0, 4); - this.tableLayoutPanel1.Controls.Add(this.EncryptionSelect, 1, 4); - this.tableLayoutPanel1.Controls.Add(this.TimeoutLabel, 0, 11); - this.tableLayoutPanel1.Controls.Add(this.TimeoutTextBox, 1, 11); - this.tableLayoutPanel1.Controls.Add(this.PluginLabel, 0, 5); - this.tableLayoutPanel1.Controls.Add(this.PluginOptionsTextBox, 1, 6); - 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.NeedPluginArgCheckBox, 1, 7); - 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 = 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()); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - 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(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, 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); - this.PluginOptionsLabel.TabIndex = 6; - this.PluginOptionsLabel.Text = "Plugin Options"; - this.toolTip1.SetToolTip(this.PluginOptionsLabel, "Environment variables for plugin program"); - // - // PluginTextBox - // - 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(205, 25); - this.PluginTextBox.TabIndex = 5; - this.PluginTextBox.WordWrap = false; - // - // RemarksTextBox - // - 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(205, 25); - this.RemarksTextBox.TabIndex = 8; - this.RemarksTextBox.WordWrap = false; - // - // IPLabel - // - this.IPLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.IPLabel.AutoSize = true; - 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); - this.IPLabel.TabIndex = 0; - this.IPLabel.Text = "Server IP"; - // - // ServerPortLabel - // - this.ServerPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.ServerPortLabel.AutoSize = true; - 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); - this.ServerPortLabel.TabIndex = 1; - this.ServerPortLabel.Text = "Server Port"; - // - // PasswordLabel - // - this.PasswordLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.PasswordLabel.AutoSize = true; - 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); - this.PasswordLabel.TabIndex = 2; - this.PasswordLabel.Text = "Password"; - this.PasswordLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // - // IPTextBox - // - 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(205, 25); - this.IPTextBox.TabIndex = 0; - this.IPTextBox.WordWrap = false; - // - // ServerPortTextBox - // - 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(205, 25); - this.ServerPortTextBox.TabIndex = 1; - this.ServerPortTextBox.WordWrap = false; - // - // PasswordTextBox - // - this.PasswordTextBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.PasswordTextBox.Font = new System.Drawing.Font("Consolas", 9F); - this.PasswordTextBox.Location = new System.Drawing.Point(150, 69); - this.PasswordTextBox.MaxLength = 256; - this.PasswordTextBox.Name = "PasswordTextBox"; - this.PasswordTextBox.Size = new System.Drawing.Size(205, 25); - this.PasswordTextBox.TabIndex = 2; - this.PasswordTextBox.UseSystemPasswordChar = true; - this.PasswordTextBox.WordWrap = false; - // - // EncryptionLabel - // - this.EncryptionLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.EncryptionLabel.AutoSize = true; - 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); - this.EncryptionLabel.TabIndex = 4; - this.EncryptionLabel.Text = "Encryption"; - // - // EncryptionSelect - // - 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(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(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, 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; - this.TimeoutLabel.Size = new System.Drawing.Size(103, 15); - this.TimeoutLabel.TabIndex = 9; - this.TimeoutLabel.Text = "Timeout(Sec)"; - // - // TimeoutTextBox - // - 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(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, 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); - this.PluginLabel.TabIndex = 5; - this.PluginLabel.Text = "Plugin Program"; - // - // PluginOptionsTextBox - // - 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(205, 25); - this.PluginOptionsTextBox.TabIndex = 6; - this.PluginOptionsTextBox.WordWrap = false; - // - // ShowPasswdCheckBox - // - 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, 101); - this.ShowPasswdCheckBox.Margin = new System.Windows.Forms.Padding(4); - this.ShowPasswdCheckBox.Name = "ShowPasswdCheckBox"; - this.ShowPasswdCheckBox.Size = new System.Drawing.Size(133, 19); - this.ShowPasswdCheckBox.TabIndex = 3; - this.ShowPasswdCheckBox.Text = "Show Password"; - this.ShowPasswdCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - this.ShowPasswdCheckBox.UseVisualStyleBackColor = true; - this.ShowPasswdCheckBox.CheckedChanged += new System.EventHandler(this.ShowPasswdCheckBox_CheckedChanged); - // - // PluginArgumentsTextBox - // - 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(205, 25); - this.PluginArgumentsTextBox.TabIndex = 7; - this.PluginArgumentsTextBox.WordWrap = false; - // - // PluginArgumentsLabel - // - this.PluginArgumentsLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.PluginArgumentsLabel.AutoSize = true; - 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); - this.PluginArgumentsLabel.TabIndex = 7; - this.PluginArgumentsLabel.Text = "Plugin Arguments"; - this.toolTip1.SetToolTip(this.PluginArgumentsLabel, "Not a SIP003 standard. Used as CLI arguments.\r\nMandatory:\r\n%SS_LOCAL_HOST%, %SS_L" + - "OCAL_PORT%, %SS_REMOTE_HOST%, %SS_REMOTE_PORT%\r\nOptional:\r\n%SS_PLUGIN_OPTIONS%"); - // - // RemarksLabel - // - this.RemarksLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.RemarksLabel.AutoSize = true; - 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); - this.RemarksLabel.TabIndex = 8; - this.RemarksLabel.Text = "Remarks"; - // - // NeedPluginArgCheckBox - // - this.NeedPluginArgCheckBox.AutoSize = true; - 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); - this.NeedPluginArgCheckBox.TabIndex = 10; - this.NeedPluginArgCheckBox.Text = "Need Plugin Argument"; - this.NeedPluginArgCheckBox.UseVisualStyleBackColor = true; - this.NeedPluginArgCheckBox.CheckedChanged += new System.EventHandler(this.UsePluginArgCheckBox_CheckedChanged); - // - // panel2 - // - 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(190, 229); - this.panel2.Margin = new System.Windows.Forms.Padding(4); - this.panel2.Name = "panel2"; - this.panel2.Size = new System.Drawing.Size(0, 0); - this.panel2.TabIndex = 1; - // - // OKButton - // - this.OKButton.DialogResult = System.Windows.Forms.DialogResult.OK; - 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(87, 29); - this.OKButton.TabIndex = 17; - this.OKButton.Text = "OK"; - this.OKButton.UseVisualStyleBackColor = true; - this.OKButton.Click += new System.EventHandler(this.OKButton_Click); - // - // MyCancelButton - // - this.MyCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - 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(87, 29); - this.MyCancelButton.TabIndex = 18; - this.MyCancelButton.Text = "Cancel"; - this.MyCancelButton.UseVisualStyleBackColor = true; - this.MyCancelButton.Click += new System.EventHandler(this.CancelButton_Click); - // - // ApplyButton - // - this.ApplyButton.Dock = System.Windows.Forms.DockStyle.Fill; - this.ApplyButton.Enabled = false; - this.ApplyButton.Location = new System.Drawing.Point(468, 501); - this.ApplyButton.Name = "ApplyButton"; - this.ApplyButton.Size = new System.Drawing.Size(91, 29); - this.ApplyButton.TabIndex = 19; - this.ApplyButton.Text = "Apply"; - this.ApplyButton.UseVisualStyleBackColor = true; - this.ApplyButton.Click += new System.EventHandler(this.ApplyButton_Click); - // - // DeleteButton - // - 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(87, 29); - this.DeleteButton.TabIndex = 13; - this.DeleteButton.Text = "&Delete"; - this.DeleteButton.UseVisualStyleBackColor = true; - this.DeleteButton.Click += new System.EventHandler(this.DeleteButton_Click); - // - // AddButton - // - 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(87, 29); - this.AddButton.TabIndex = 12; - this.AddButton.Text = "&Add"; - this.AddButton.UseVisualStyleBackColor = true; - this.AddButton.Click += new System.EventHandler(this.AddButton_Click); - // - // ServerGroupBox - // - 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.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(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(3, 3); - this.ServersListBox.Name = "ServersListBox"; - this.ServersListBox.Size = new System.Drawing.Size(180, 422); - this.ServersListBox.TabIndex = 11; - this.ServersListBox.SelectedIndexChanged += new System.EventHandler(this.ServersListBox_SelectedIndexChanged); - // - // MoveDownButton - // - this.MoveDownButton.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(87, 29); - this.MoveDownButton.TabIndex = 16; - this.MoveDownButton.Text = "Move D&own"; - this.MoveDownButton.UseVisualStyleBackColor = true; - this.MoveDownButton.Click += new System.EventHandler(this.MoveDownButton_Click); - // - // MoveUpButton - // - 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(87, 29); - this.MoveUpButton.TabIndex = 15; - this.MoveUpButton.Text = "Move &Up"; - this.MoveUpButton.UseVisualStyleBackColor = true; - this.MoveUpButton.Click += new System.EventHandler(this.MoveUpButton_Click); - // - // ProxyPortTextBox - // - 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(178, 25); - this.ProxyPortTextBox.TabIndex = 10; - this.ProxyPortTextBox.WordWrap = false; - // - // ProxyPortLabel - // - this.ProxyPortLabel.AutoSize = true; - 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(85, 35); - this.ProxyPortLabel.TabIndex = 10; - this.ProxyPortLabel.Text = "Proxy Port"; - this.ProxyPortLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - // - // PortableModeCheckBox - // - this.PortableModeCheckBox.AutoSize = true; - 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(178, 27); - this.PortableModeCheckBox.TabIndex = 11; - this.PortableModeCheckBox.Text = "Portable Mode"; - this.toolTip1.SetToolTip(this.PortableModeCheckBox, "restart required"); - this.PortableModeCheckBox.UseVisualStyleBackColor = true; - // - // DuplicateButton - // - 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(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.CancelButton = this.MyCancelButton; - this.ClientSize = new System.Drawing.Size(582, 553); - this.Controls.Add(this.tableLayoutPanel7); - this.Controls.Add(this.panel2); - this.Margin = new System.Windows.Forms.Padding(4); - this.MinimizeBox = false; - this.MinimumSize = new System.Drawing.Size(400, 575); - this.Name = "ConfigForm"; - 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); - this.Shown += new System.EventHandler(this.ConfigForm_Shown); - this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ConfigForm_KeyDown); - this.tableLayoutPanel1.ResumeLayout(false); - this.tableLayoutPanel1.PerformLayout(); - this.ServerGroupBox.ResumeLayout(false); - this.ServerGroupBox.PerformLayout(); - this.tableLayoutPanel7.ResumeLayout(false); - this.tableLayoutPanel7.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; - private System.Windows.Forms.Label IPLabel; - private System.Windows.Forms.Label ServerPortLabel; - private System.Windows.Forms.Label PasswordLabel; - private System.Windows.Forms.TextBox IPTextBox; - private System.Windows.Forms.TextBox ServerPortTextBox; - private System.Windows.Forms.Label EncryptionLabel; - private System.Windows.Forms.ComboBox EncryptionSelect; - private System.Windows.Forms.Panel panel2; - private System.Windows.Forms.Button OKButton; - private System.Windows.Forms.Button MyCancelButton; - private System.Windows.Forms.Button ApplyButton; - private System.Windows.Forms.Button DeleteButton; - private System.Windows.Forms.Button AddButton; - private System.Windows.Forms.GroupBox ServerGroupBox; - private System.Windows.Forms.ListBox ServersListBox; - private System.Windows.Forms.TextBox RemarksTextBox; - private System.Windows.Forms.Label RemarksLabel; - private System.Windows.Forms.TextBox ProxyPortTextBox; - private System.Windows.Forms.Label ProxyPortLabel; - private System.Windows.Forms.Button MoveDownButton; - private System.Windows.Forms.Button MoveUpButton; - private System.Windows.Forms.Button DuplicateButton; - private System.Windows.Forms.Label TimeoutLabel; - private System.Windows.Forms.TextBox TimeoutTextBox; - private System.Windows.Forms.Label PluginOptionsLabel; - private System.Windows.Forms.TextBox PluginTextBox; - private System.Windows.Forms.Label PluginLabel; - private System.Windows.Forms.TextBox PluginOptionsTextBox; - private System.Windows.Forms.CheckBox ShowPasswdCheckBox; - private System.Windows.Forms.TextBox PasswordTextBox; - private System.Windows.Forms.TextBox PluginArgumentsTextBox; - private System.Windows.Forms.Label PluginArgumentsLabel; - private System.Windows.Forms.ToolTip toolTip1; - private System.Windows.Forms.CheckBox PortableModeCheckBox; - private System.Windows.Forms.CheckBox NeedPluginArgCheckBox; - private System.Windows.Forms.TableLayoutPanel tableLayoutPanel7; - private System.Windows.Forms.Label GroupLabel; - private System.Windows.Forms.TextBox GroupTextBox; - } -} - diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs deleted file mode 100755 index 85d17d2d..00000000 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ /dev/null @@ -1,552 +0,0 @@ -using Shadowsocks.Controller; -using Shadowsocks.Encryption; -using Shadowsocks.Model; -using Shadowsocks.Properties; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Windows.Forms; - -namespace Shadowsocks.View -{ - public partial class ConfigForm : Form - { - private ShadowsocksController controller; - - // this is a copy of configuration that we are working on - private Configuration _modifiedConfiguration; - private int _lastSelectedIndex = -1; - - private bool isChange = false; - - public ConfigForm(ShadowsocksController controller) - { - Font = SystemFonts.MessageBoxFont; - InitializeComponent(); - EncryptionSelect.Items.AddRange(EncryptorFactory.ListAvaliableCiphers().ToArray()); - - PerformLayout(); - - UpdateTexts(); - SetupValueChangedListeners(); - Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); - - this.controller = controller; - controller.ConfigChanged += Controller_ConfigChanged; - - LoadCurrentConfiguration(); - } - - private void UpdateTexts() - { - I18N.TranslateForm(this); - toolTip1.SetToolTip(PortableModeCheckBox, I18N.GetString("Restart required")); - } - - private void SetupValueChangedListeners() - { - IPTextBox.TextChanged += ConfigValueChanged; - ProxyPortTextBox.TextChanged += ConfigValueChanged; - PasswordTextBox.TextChanged += ConfigValueChanged; - EncryptionSelect.SelectedIndexChanged += ConfigValueChanged; - PluginTextBox.TextChanged += ConfigValueChanged; - PluginArgumentsTextBox.TextChanged += ConfigValueChanged; - PluginOptionsTextBox.TextChanged += ConfigValueChanged; - RemarksTextBox.TextChanged += ConfigValueChanged; - TimeoutTextBox.TextChanged += ConfigValueChanged; - PortableModeCheckBox.CheckedChanged += ConfigValueChanged; - ServerPortTextBox.TextChanged += ConfigValueChanged; - } - - private void Controller_ConfigChanged(object sender, EventArgs e) - { - LoadCurrentConfiguration(); - } - - private void ConfigValueChanged(object sender, EventArgs e) - { - isChange = true; - ApplyButton.Enabled = true; - } - - private bool ValidateAndSaveSelectedServerDetails(bool isSave = false, bool isCopy = false) - { - try - { - if (_lastSelectedIndex == -1 || _lastSelectedIndex >= _modifiedConfiguration.configs.Count) - { - return true; - } - - bool verify = GetServerDetailsFromUI(out Server server, isSave, isCopy); - - if (server != null) - { - if (isSave || isCopy) - Configuration.CheckServer(server); - - _modifiedConfiguration.configs[_lastSelectedIndex] = server; - } - return verify; - } - catch (Exception ex) - { - MessageBox.Show(ex.Message); - } - return false; - } - - private bool GetServerDetailsFromUI(out Server server, bool isSave = false, bool isCopy = false) - { - server = null; - - bool? checkIP = false; - bool? checkPort = false; - bool? checkPassword = false; - bool? checkTimeout = false; - - if ((checkIP = CheckIPTextBox(out string address, isSave, isCopy)).GetValueOrDefault(false) && address != null - && (checkPort = CheckServerPortTextBox(out int? addressPort, isSave, isCopy)).GetValueOrDefault(false) && addressPort.HasValue - && (checkPassword = CheckPasswordTextBox(out string serverPassword, isSave, isCopy)).GetValueOrDefault(false) && serverPassword != null - && (checkTimeout = CheckTimeoutTextBox(out int? timeout, isSave, isCopy)).GetValueOrDefault(false) && timeout.HasValue) - { - server = new Server() - { - server = address, - server_port = addressPort.Value, - password = serverPassword, - method = ((CipherInfo)EncryptionSelect.SelectedItem).Name, - plugin = PluginTextBox.Text, - plugin_opts = PluginOptionsTextBox.Text, - plugin_args = PluginArgumentsTextBox.Text, - remarks = RemarksTextBox.Text, - timeout = timeout.Value, - group = GroupTextBox.Text - }; - - return true; - } - - if (checkIP == null || checkPort == null || checkTimeout == null) - { - _modifiedConfiguration.configs.RemoveAt(_lastSelectedIndex); - ServersListBox.SelectedIndexChanged -= ServersListBox_SelectedIndexChanged; - - int lastIndex = ServersListBox.SelectedIndex; - - LoadServerNameListToUI(_modifiedConfiguration); - - _lastSelectedIndex = (ServersListBox.SelectedIndex = (_lastSelectedIndex == ServersListBox.Items.Count ? lastIndex : lastIndex - 1)); - - ServersListBox.SelectedIndexChanged += ServersListBox_SelectedIndexChanged; - return true; - } - else - return false; - } - - #region GetServerDetailsFromUI Check - - private bool? CheckIPTextBox(out string address, bool isSave, bool isCopy) - { - address = null; - string outAddress; - if (Uri.CheckHostName(outAddress = IPTextBox.Text.Trim()) == UriHostNameType.Unknown) - { - if (!isSave && !isCopy && ServersListBox.Items.Count > 1 && I18N.GetString("New server").Equals(ServersListBox.Items[_lastSelectedIndex].ToString())) - { - DialogResult result = MessageBox.Show(I18N.GetString("Whether to discard unconfigured servers"), I18N.GetString("Operation failure"), MessageBoxButtons.OKCancel); - - if (result == DialogResult.OK) - return null; - } - else if (isChange && !isSave && !isCopy) - { - var result = MessageBox.Show(I18N.GetString("Invalid server address, Cannot automatically save or discard changes"), I18N.GetString("Auto save failed"), MessageBoxButtons.OKCancel); - - if (result == DialogResult.Cancel) - return false; - else - { - address = _modifiedConfiguration.configs[_lastSelectedIndex].server; - return true; - } - } - else - { - MessageBox.Show(I18N.GetString("Invalid server address"), I18N.GetString("Operation failure")); - IPTextBox.Focus(); - } - return false; - } - else - { - address = outAddress; - } - return true; - } - - private bool? CheckServerPortTextBox(out int? addressPort, bool isSave, bool isCopy) - { - addressPort = null; - if (!int.TryParse(ServerPortTextBox.Text, out int outaddressPort)) - { - if (!isSave && !isCopy && ServersListBox.Items.Count > 1 && I18N.GetString("New server").Equals(ServersListBox.Items[_lastSelectedIndex].ToString())) - { - DialogResult result = MessageBox.Show(I18N.GetString("Whether to discard unconfigured servers"), I18N.GetString("Operation failure"), MessageBoxButtons.OKCancel); - - if (result == DialogResult.OK) - return null; - } - else if (isChange && !isSave && !isCopy) - { - var result = MessageBox.Show(I18N.GetString("Illegal port number format, Cannot automatically save or discard changes"), I18N.GetString("Auto save failed"), MessageBoxButtons.OKCancel); - - if (result == DialogResult.Cancel) - return false; - else - { - addressPort = _modifiedConfiguration.configs[_lastSelectedIndex].server_port; - return true; - } - } - else - { - MessageBox.Show(I18N.GetString("Illegal port number format"), I18N.GetString("Operation failure")); - ServerPortTextBox.Focus(); - } - return false; - } - else - { - addressPort = outaddressPort; - } - return true; - } - - private bool? CheckPasswordTextBox(out string password, bool isSave, bool isCopy) - { - password = null; - string outPassword; - if (string.IsNullOrWhiteSpace(outPassword = PasswordTextBox.Text)) - { - if (!isSave && !isCopy && ServersListBox.Items.Count > 1 && I18N.GetString("New server").Equals(ServersListBox.Items[_lastSelectedIndex].ToString())) - { - DialogResult result = MessageBox.Show(I18N.GetString("Whether to discard unconfigured servers"), I18N.GetString("Operation failure"), MessageBoxButtons.OKCancel); - - if (result == DialogResult.OK) - return null; - } - else if (isChange && !isSave && !isCopy) - { - var result = MessageBox.Show(I18N.GetString("Password can not be blank, Cannot automatically save or discard changes"), I18N.GetString("Auto save failed"), MessageBoxButtons.OKCancel); - - if (result == DialogResult.Cancel) - return false; - else - { - password = _modifiedConfiguration.configs[_lastSelectedIndex].password; - return true; - } - } - else - { - MessageBox.Show(I18N.GetString("Password can not be blank"), I18N.GetString("Operation failure")); - PasswordTextBox.Focus(); - } - return false; - } - else - { - password = outPassword; - } - return true; - } - - private bool? CheckTimeoutTextBox(out int? timeout, bool isSave, bool isCopy) - { - timeout = null; - if (!int.TryParse(TimeoutTextBox.Text, out int outTimeout)) - { - if (!isSave && !isCopy && ServersListBox.Items.Count > 1 && I18N.GetString("New server").Equals(ServersListBox.Items[_lastSelectedIndex].ToString())) - { - DialogResult result = MessageBox.Show(I18N.GetString("Whether to discard unconfigured servers"), I18N.GetString("Operation failure"), MessageBoxButtons.OKCancel); - - if (result == DialogResult.OK) - return null; - } - else if (isChange && !isSave && !isCopy) - { - var result = MessageBox.Show(I18N.GetString("Illegal timeout format, Cannot automatically save or discard changes"), I18N.GetString("Auto save failed"), MessageBoxButtons.OKCancel); - - if (result == DialogResult.Cancel) - return false; - else - { - timeout = _modifiedConfiguration.configs[_lastSelectedIndex].timeout; - return true; - } - } - else - { - MessageBox.Show(I18N.GetString("Illegal timeout format"), I18N.GetString("Operation failure")); - TimeoutTextBox.Focus(); - } - return false; - } - else - { - timeout = outTimeout; - } - return true; - } - - #endregion - - private void LoadSelectedServerDetails() - { - if (ServersListBox.SelectedIndex >= 0 && ServersListBox.SelectedIndex < _modifiedConfiguration.configs.Count) - { - Server server = _modifiedConfiguration.configs[ServersListBox.SelectedIndex]; - SetServerDetailsToUI(server); - } - } - - private void SetServerDetailsToUI(Server server) - { - IPTextBox.Text = server.server; - ServerPortTextBox.Text = server.server_port.ToString(); - PasswordTextBox.Text = server.password; - EncryptionSelect.SelectedItem = EncryptorFactory.GetCipherInfo(server.method ?? Server.DefaultMethod); - PluginTextBox.Text = server.plugin; - PluginOptionsTextBox.Text = server.plugin_opts; - PluginArgumentsTextBox.Text = server.plugin_args; - - bool showPluginArgInput = !string.IsNullOrEmpty(server.plugin_args); - NeedPluginArgCheckBox.Checked = showPluginArgInput; - ShowHidePluginArgInput(showPluginArgInput); - - RemarksTextBox.Text = server.remarks; - TimeoutTextBox.Text = server.timeout.ToString(); - - GroupTextBox.Text = server.group; - - isChange = false; - } - - private void ShowHidePluginArgInput(bool show) - { - PluginArgumentsTextBox.Visible = show; - PluginArgumentsLabel.Visible = show; - } - - private void LoadServerNameListToUI(Configuration configuration) - { - ServersListBox.Items.Clear(); - foreach (Server server in configuration.configs) - { - ServersListBox.Items.Add(server.ToString()); - } - } - - private void LoadCurrentConfiguration() - { - _modifiedConfiguration = controller.GetCurrentConfiguration(); - LoadServerNameListToUI(_modifiedConfiguration); - - _lastSelectedIndex = _modifiedConfiguration.index; - if (_lastSelectedIndex < 0 || _lastSelectedIndex >= ServersListBox.Items.Count) - { - _lastSelectedIndex = 0; - } - - ServersListBox.SelectedIndex = _lastSelectedIndex; - UpdateButtons(); - LoadSelectedServerDetails(); - - ProxyPortTextBox.Text = _modifiedConfiguration.localPort.ToString(); - PortableModeCheckBox.Checked = _modifiedConfiguration.portableMode; - - ApplyButton.Enabled = false; - } - - private bool SaveValidConfiguration() - { - if (!ValidateAndSaveSelectedServerDetails(isSave: true)) - { - return false; - } - - int localPort = int.Parse(ProxyPortTextBox.Text); - Configuration.CheckLocalPort(localPort); - _modifiedConfiguration.localPort = localPort; - - _modifiedConfiguration.portableMode = PortableModeCheckBox.Checked; - - controller.SaveServers(_modifiedConfiguration.configs, _modifiedConfiguration.localPort, _modifiedConfiguration.portableMode); - // SelectedIndex remains valid - // We handled this in event handlers, e.g. Add/DeleteButton, SelectedIndexChanged - // and move operations - controller.SelectServerIndex(ServersListBox.SelectedIndex); - return true; - } - - private void ConfigForm_KeyDown(object sender, KeyEventArgs e) - { - // Sometimes the users may hit enter key by mistake, and the form will close without saving entries. - - if (e.KeyCode == Keys.Enter) - { - SaveValidConfiguration(); - } - } - - private void ServersListBox_SelectedIndexChanged(object sender, EventArgs e) - { - if (!ServersListBox.CanSelect) - { - return; - } - if (_lastSelectedIndex == ServersListBox.SelectedIndex) - { - // we are moving back to oldSelectedIndex or doing a force move - return; - } - if (!ValidateAndSaveSelectedServerDetails()) - { - // why this won't cause stack overflow? - ServersListBox.SelectedIndex = _lastSelectedIndex; - return; - } - if (_lastSelectedIndex >= 0 && _lastSelectedIndex < _modifiedConfiguration.configs.Count) - { - ServersListBox.Items[_lastSelectedIndex] = _modifiedConfiguration.configs[_lastSelectedIndex].ToString(); - } - UpdateButtons(); - LoadSelectedServerDetails(); - _lastSelectedIndex = ServersListBox.SelectedIndex; - } - - private void AddButton_Click(object sender, EventArgs e) - { - if (ValidateAndSaveSelectedServerDetails(isSave: true)) - { - Configuration.AddDefaultServerOrServer(_modifiedConfiguration); - LoadServerNameListToUI(_modifiedConfiguration); - _lastSelectedIndex = (ServersListBox.SelectedIndex = _modifiedConfiguration.configs.Count - 1); - } - } - - private void DuplicateButton_Click(object sender, EventArgs e) - { - if (ValidateAndSaveSelectedServerDetails(isCopy: true)) - { - Server currServer = _modifiedConfiguration.configs[_lastSelectedIndex]; - Configuration.AddDefaultServerOrServer(_modifiedConfiguration, currServer, _lastSelectedIndex + 1); - LoadServerNameListToUI(_modifiedConfiguration); - _lastSelectedIndex = (ServersListBox.SelectedIndex = (_lastSelectedIndex + 1)); - } - } - - private void DeleteButton_Click(object sender, EventArgs e) - { - _modifiedConfiguration.configs.RemoveAt(_lastSelectedIndex); - - if (_modifiedConfiguration.configs.Count == 0) - { - Configuration.AddDefaultServerOrServer(_modifiedConfiguration); - } - - LoadServerNameListToUI(_modifiedConfiguration); - ServersListBox.SelectedIndexChanged -= ServersListBox_SelectedIndexChanged; - - _lastSelectedIndex = (ServersListBox.SelectedIndex = (_lastSelectedIndex >= _modifiedConfiguration.configs.Count ? (_modifiedConfiguration.configs.Count - 1) : _lastSelectedIndex)); - - ServersListBox.SelectedIndexChanged += ServersListBox_SelectedIndexChanged; - LoadSelectedServerDetails(); - - UpdateButtons(); - } - - private void UpdateButtons() - { - DeleteButton.Enabled = (ServersListBox.Items.Count > 0); - MoveUpButton.Enabled = (ServersListBox.SelectedIndex > 0); - MoveDownButton.Enabled = (ServersListBox.SelectedIndex < ServersListBox.Items.Count - 1); - } - - private void MoveUpButton_Click(object sender, EventArgs e) - { - if (ServersListBox.SelectedIndex > 0) - { - MoveConfigItem(-1); // -1 means move backward - } - } - - private void MoveDownButton_Click(object sender, EventArgs e) - { - if (ServersListBox.SelectedIndex < ServersListBox.Items.Count - 1) - { - MoveConfigItem(+1); // +1 means move forward - } - } - - private void MoveConfigItem(int step) - { - var server = _modifiedConfiguration.configs[_lastSelectedIndex]; - var newIndex = _lastSelectedIndex + step; - - _modifiedConfiguration.configs.RemoveAt(_lastSelectedIndex); - _modifiedConfiguration.configs.Insert(newIndex, server); - - ServersListBox.BeginUpdate(); - - LoadServerNameListToUI(_modifiedConfiguration); - - _lastSelectedIndex = newIndex; - ServersListBox.SelectedIndex = newIndex; - ServersListBox.EndUpdate(); - - UpdateButtons(); - } - - private void OKButton_Click(object sender, EventArgs e) - { - if (SaveValidConfiguration()) - { - Close(); - } - } - - private void CancelButton_Click(object sender, EventArgs e) - { - Close(); - } - - private void ApplyButton_Click(object sender, EventArgs e) - { - SaveValidConfiguration(); - } - - private void ConfigForm_Shown(object sender, EventArgs e) - { - IPTextBox.Focus(); - } - - private void ConfigForm_FormClosed(object sender, FormClosedEventArgs e) - { - controller.ConfigChanged -= Controller_ConfigChanged; - } - - private void ShowPasswdCheckBox_CheckedChanged(object sender, EventArgs e) - { - PasswordTextBox.UseSystemPasswordChar = !ShowPasswdCheckBox.Checked; - } - - private void UsePluginArgCheckBox_CheckedChanged(object sender, EventArgs e) - { - ShowHidePluginArgInput(NeedPluginArgCheckBox.Checked); - } - } -} diff --git a/shadowsocks-csharp/View/ConfigForm.resx b/shadowsocks-csharp/View/ConfigForm.resx deleted file mode 100755 index 6dfd76d8..00000000 --- a/shadowsocks-csharp/View/ConfigForm.resx +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - - 17, 17 - - \ No newline at end of file diff --git a/shadowsocks-csharp/View/InputBox.Designer.cs b/shadowsocks-csharp/View/InputBox.Designer.cs deleted file mode 100644 index 5e9f3328..00000000 --- a/shadowsocks-csharp/View/InputBox.Designer.cs +++ /dev/null @@ -1,100 +0,0 @@ -namespace Shadowsocks.View -{ - partial class InputBox - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.label1 = new System.Windows.Forms.Label(); - this.textBox1 = new System.Windows.Forms.TextBox(); - this.btnOK = new System.Windows.Forms.Button(); - this.button2 = new System.Windows.Forms.Button(); - this.SuspendLayout(); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(12, 9); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(55, 15); - this.label1.TabIndex = 0; - this.label1.Text = "label1"; - // - // textBox1 - // - this.textBox1.Location = new System.Drawing.Point(13, 51); - this.textBox1.Name = "textBox1"; - this.textBox1.Size = new System.Drawing.Size(484, 25); - this.textBox1.TabIndex = 1; - // - // btnOK - // - this.btnOK.Location = new System.Drawing.Point(321, 91); - this.btnOK.Name = "btnOK"; - this.btnOK.Size = new System.Drawing.Size(75, 31); - this.btnOK.TabIndex = 2; - this.btnOK.Text = "OK"; - this.btnOK.UseVisualStyleBackColor = true; - // - // button2 - // - this.button2.Location = new System.Drawing.Point(422, 91); - this.button2.Name = "button2"; - this.button2.Size = new System.Drawing.Size(75, 31); - this.button2.TabIndex = 3; - this.button2.Text = "Cancel"; - this.button2.UseVisualStyleBackColor = true; - // - // InputBox - // - this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(554, 134); - this.Controls.Add(this.button2); - this.Controls.Add(this.btnOK); - this.Controls.Add(this.textBox1); - this.Controls.Add(this.label1); - this.DoubleBuffered = true; - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "InputBox"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "InputBox"; - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label label1; - private System.Windows.Forms.TextBox textBox1; - private System.Windows.Forms.Button btnOK; - private System.Windows.Forms.Button button2; - } -} \ No newline at end of file diff --git a/shadowsocks-csharp/View/InputBox.cs b/shadowsocks-csharp/View/InputBox.cs deleted file mode 100644 index a8f315fc..00000000 --- a/shadowsocks-csharp/View/InputBox.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace Shadowsocks.View -{ - internal partial class InputBox : Form - { - public InputBox() - { - InitializeComponent(); - } - - internal string Prompt { get { return label1.Text; } set { label1.Text = value; } } - internal string Response { get { return textBox1.Text; } set { textBox1.Text = value; } } - - } -} diff --git a/shadowsocks-csharp/View/InputBox.resx b/shadowsocks-csharp/View/InputBox.resx deleted file mode 100644 index 29dcb1b3..00000000 --- a/shadowsocks-csharp/View/InputBox.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/shadowsocks-csharp/View/LogForm.Designer.cs b/shadowsocks-csharp/View/LogForm.Designer.cs deleted file mode 100644 index 365a9bb1..00000000 --- a/shadowsocks-csharp/View/LogForm.Designer.cs +++ /dev/null @@ -1,332 +0,0 @@ -namespace Shadowsocks.View -{ - partial class LogForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea(); - System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend(); - System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series(); - System.Windows.Forms.DataVisualization.Charting.Series series2 = new System.Windows.Forms.DataVisualization.Charting.Series(); - this.LogMessageTextBox = new System.Windows.Forms.TextBox(); - this.MainMenu = new System.Windows.Forms.MenuStrip(); - this.FileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.OpenLocationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ExitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ViewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ClearLogsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ChangeFontToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.WrapTextToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.TopMostToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolStripMenuItemSeparater = new System.Windows.Forms.ToolStripMenuItem(); - this.ShowToolbarToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.TopMostCheckBox = new System.Windows.Forms.CheckBox(); - this.ChangeFontButton = new System.Windows.Forms.Button(); - this.ClearLogsButton = new System.Windows.Forms.Button(); - this.WrapTextCheckBox = new System.Windows.Forms.CheckBox(); - this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); - this.ToolbarFlowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel(); - this.splitContainer1 = new System.Windows.Forms.SplitContainer(); - this.trafficChart = new System.Windows.Forms.DataVisualization.Charting.Chart(); - this.tableLayoutPanel1.SuspendLayout(); - this.ToolbarFlowLayoutPanel.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); - this.splitContainer1.Panel1.SuspendLayout(); - this.splitContainer1.Panel2.SuspendLayout(); - this.splitContainer1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.trafficChart)).BeginInit(); - this.SuspendLayout(); - // - // LogMessageTextBox - // - this.LogMessageTextBox.BackColor = System.Drawing.Color.Black; - this.LogMessageTextBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.LogMessageTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.LogMessageTextBox.ForeColor = System.Drawing.Color.White; - this.LogMessageTextBox.Location = new System.Drawing.Point(0, 0); - this.LogMessageTextBox.MaxLength = 2147483647; - this.LogMessageTextBox.Multiline = true; - this.LogMessageTextBox.Name = "LogMessageTextBox"; - this.LogMessageTextBox.ReadOnly = true; - this.LogMessageTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both; - this.LogMessageTextBox.Size = new System.Drawing.Size(378, 74); - this.LogMessageTextBox.TabIndex = 0; - // - // MainMenu - // - this.MainMenu.Items.AddRange(new System.Windows.Forms.ToolStripMenuItem[] { - this.FileToolStripMenuItem, - this.ViewToolStripMenuItem}); - // - // FileToolStripMenuItem - // - this.FileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripMenuItem[] { - this.OpenLocationToolStripMenuItem, - this.ExitToolStripMenuItem}); - this.FileToolStripMenuItem.Text = "&File"; - // - // OpenLocationToolStripMenuItem - // - this.OpenLocationToolStripMenuItem.Text = "&Open Location"; - this.OpenLocationToolStripMenuItem.Click += new System.EventHandler(this.OpenLocationToolStripMenuItem_Click); - // - // ExitToolStripMenuItem - // - this.ExitToolStripMenuItem.Text = "E&xit"; - this.ExitToolStripMenuItem.Click += new System.EventHandler(this.ExitToolStripMenuItem_Click); - // - // ViewToolStripMenuItem - // - this.ViewToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripMenuItem[] { - this.ClearLogsToolStripMenuItem, - this.ChangeFontToolStripMenuItem, - this.WrapTextToolStripMenuItem, - this.TopMostToolStripMenuItem, - this.ToolStripMenuItemSeparater, - this.ShowToolbarToolStripMenuItem}); - this.ViewToolStripMenuItem.Text = "&View"; - // - // ClearLogsToolStripMenuItem - // - this.ClearLogsToolStripMenuItem.Text = "&Clear Logs"; - this.ClearLogsToolStripMenuItem.Click += new System.EventHandler(this.ClearLogsToolStripMenuItem_Click); - // - // ChangeFontToolStripMenuItem - // - this.ChangeFontToolStripMenuItem.Text = "Change &Font"; - this.ChangeFontToolStripMenuItem.Click += new System.EventHandler(this.ChangeFontToolStripMenuItem_Click); - // - // WrapTextToolStripMenuItem - // - this.WrapTextToolStripMenuItem.Text = "&Wrap Text"; - this.WrapTextToolStripMenuItem.Click += new System.EventHandler(this.WrapTextToolStripMenuItem_Click); - // - // TopMostToolStripMenuItem - // - this.TopMostToolStripMenuItem.Text = "&Top Most"; - this.TopMostToolStripMenuItem.Click += new System.EventHandler(this.TopMostToolStripMenuItem_Click); - // - // ToolStripMenuItemSeparater - // - this.ToolStripMenuItemSeparater.Text = "-"; - // - // ShowToolbarToolStripMenuItem - // - this.ShowToolbarToolStripMenuItem.Text = "&Show Toolbar"; - this.ShowToolbarToolStripMenuItem.Click += new System.EventHandler(this.ShowToolbarToolStripMenuItem_Click); - // - // TopMostCheckBox - // - this.TopMostCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left))); - this.TopMostCheckBox.AutoSize = true; - this.TopMostCheckBox.Location = new System.Drawing.Point(249, 3); - this.TopMostCheckBox.Name = "TopMostCheckBox"; - this.TopMostCheckBox.Size = new System.Drawing.Size(72, 23); - this.TopMostCheckBox.TabIndex = 3; - this.TopMostCheckBox.Text = "&Top Most"; - this.TopMostCheckBox.UseVisualStyleBackColor = true; - this.TopMostCheckBox.CheckedChanged += new System.EventHandler(this.TopMostCheckBox_CheckedChanged); - // - // ChangeFontButton - // - this.ChangeFontButton.AutoSize = true; - this.ChangeFontButton.Location = new System.Drawing.Point(84, 3); - this.ChangeFontButton.Name = "ChangeFontButton"; - this.ChangeFontButton.Size = new System.Drawing.Size(75, 23); - this.ChangeFontButton.TabIndex = 2; - this.ChangeFontButton.Text = "&Font"; - this.ChangeFontButton.UseVisualStyleBackColor = true; - this.ChangeFontButton.Click += new System.EventHandler(this.ChangeFontButton_Click); - // - // ClearLogsButton - // - this.ClearLogsButton.AutoSize = true; - this.ClearLogsButton.Location = new System.Drawing.Point(3, 3); - this.ClearLogsButton.Name = "ClearLogsButton"; - this.ClearLogsButton.Size = new System.Drawing.Size(75, 23); - this.ClearLogsButton.TabIndex = 1; - this.ClearLogsButton.Text = "&Clear Logs"; - this.ClearLogsButton.UseVisualStyleBackColor = true; - this.ClearLogsButton.Click += new System.EventHandler(this.ClearLogsButton_Click); - // - // WrapTextCheckBox - // - this.WrapTextCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left))); - this.WrapTextCheckBox.AutoSize = true; - this.WrapTextCheckBox.Location = new System.Drawing.Point(165, 3); - this.WrapTextCheckBox.Name = "WrapTextCheckBox"; - this.WrapTextCheckBox.Size = new System.Drawing.Size(78, 23); - this.WrapTextCheckBox.TabIndex = 0; - this.WrapTextCheckBox.Text = "&Wrap Text"; - this.WrapTextCheckBox.UseVisualStyleBackColor = true; - this.WrapTextCheckBox.CheckedChanged += new System.EventHandler(this.WrapTextCheckBox_CheckedChanged); - // - // tableLayoutPanel1 - // - this.tableLayoutPanel1.ColumnCount = 1; - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel1.Controls.Add(this.ToolbarFlowLayoutPanel, 0, 0); - this.tableLayoutPanel1.Controls.Add(this.splitContainer1, 0, 1); - this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; - this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); - this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.RowCount = 2; - 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(384, 161); - this.tableLayoutPanel1.TabIndex = 2; - // - // ToolbarFlowLayoutPanel - // - this.ToolbarFlowLayoutPanel.AutoSize = true; - this.ToolbarFlowLayoutPanel.Controls.Add(this.ClearLogsButton); - this.ToolbarFlowLayoutPanel.Controls.Add(this.ChangeFontButton); - this.ToolbarFlowLayoutPanel.Controls.Add(this.WrapTextCheckBox); - this.ToolbarFlowLayoutPanel.Controls.Add(this.TopMostCheckBox); - this.ToolbarFlowLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill; - this.ToolbarFlowLayoutPanel.Location = new System.Drawing.Point(3, 3); - this.ToolbarFlowLayoutPanel.Name = "ToolbarFlowLayoutPanel"; - this.ToolbarFlowLayoutPanel.Size = new System.Drawing.Size(378, 29); - this.ToolbarFlowLayoutPanel.TabIndex = 2; - // - // splitContainer1 - // - this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; - this.splitContainer1.Location = new System.Drawing.Point(3, 38); - this.splitContainer1.Name = "splitContainer1"; - this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; - // - // splitContainer1.Panel1 - // - this.splitContainer1.Panel1.Controls.Add(this.LogMessageTextBox); - // - // splitContainer1.Panel2 - // - this.splitContainer1.Panel2.Controls.Add(this.trafficChart); - this.splitContainer1.Size = new System.Drawing.Size(378, 120); - this.splitContainer1.SplitterDistance = 74; - this.splitContainer1.TabIndex = 3; - // - // trafficChart - // - chartArea1.AxisX.LabelStyle.Enabled = false; - chartArea1.AxisX.MajorGrid.Interval = 5D; - chartArea1.AxisX.MajorGrid.LineColor = System.Drawing.Color.LightGray; - chartArea1.AxisX.MajorTickMark.Enabled = false; - chartArea1.AxisX.Maximum = 61D; - chartArea1.AxisX.Minimum = 1D; - chartArea1.AxisY.IntervalAutoMode = System.Windows.Forms.DataVisualization.Charting.IntervalAutoMode.VariableCount; - chartArea1.AxisY.LabelAutoFitMaxFontSize = 8; - chartArea1.AxisY.LabelStyle.Interval = 0D; - chartArea1.AxisY.MajorGrid.LineColor = System.Drawing.Color.LightGray; - chartArea1.AxisY.MajorTickMark.Enabled = false; - chartArea1.AxisY2.MajorGrid.LineColor = System.Drawing.Color.LightGray; - chartArea1.AxisY2.Minimum = 0D; - chartArea1.Name = "ChartArea1"; - this.trafficChart.ChartAreas.Add(chartArea1); - this.trafficChart.Dock = System.Windows.Forms.DockStyle.Fill; - legend1.MaximumAutoSize = 25F; - legend1.Name = "Legend1"; - this.trafficChart.Legends.Add(legend1); - this.trafficChart.Location = new System.Drawing.Point(0, 0); - this.trafficChart.Name = "trafficChart"; - this.trafficChart.Palette = System.Windows.Forms.DataVisualization.Charting.ChartColorPalette.None; - series1.BorderWidth = 2; - series1.ChartArea = "ChartArea1"; - series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Spline; - series1.Color = System.Drawing.Color.FromArgb(255, 128, 0); - series1.IsXValueIndexed = true; - series1.Legend = "Legend1"; - series1.Name = "Inbound"; - series2.BorderWidth = 2; - series2.ChartArea = "ChartArea1"; - series2.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Spline; - series2.Color = System.Drawing.Color.FromArgb(128, 128, 255); - series2.IsXValueIndexed = true; - series2.Legend = "Legend1"; - series2.Name = "Outbound"; - this.trafficChart.Series.Add(series1); - this.trafficChart.Series.Add(series2); - this.trafficChart.Size = new System.Drawing.Size(378, 42); - this.trafficChart.TabIndex = 0; - this.trafficChart.Text = "chart1"; - // - // LogForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.ClientSize = new System.Drawing.Size(384, 161); - this.Controls.Add(this.tableLayoutPanel1); - this.MainMenuStrip = this.MainMenu; - this.MinimumSize = new System.Drawing.Size(400, 200); - this.Name = "LogForm"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Log Viewer"; - this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.LogForm_FormClosing); - this.Load += new System.EventHandler(this.LogForm_Load); - this.Shown += new System.EventHandler(this.LogForm_Shown); - this.tableLayoutPanel1.ResumeLayout(false); - this.tableLayoutPanel1.PerformLayout(); - this.ToolbarFlowLayoutPanel.ResumeLayout(false); - this.ToolbarFlowLayoutPanel.PerformLayout(); - this.splitContainer1.Panel1.ResumeLayout(false); - this.splitContainer1.Panel1.PerformLayout(); - this.splitContainer1.Panel2.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); - this.splitContainer1.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.trafficChart)).EndInit(); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.TextBox LogMessageTextBox; - private System.Windows.Forms.MenuStrip MainMenu; - private System.Windows.Forms.ToolStripMenuItem FileToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem OpenLocationToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem ExitToolStripMenuItem; - private System.Windows.Forms.CheckBox WrapTextCheckBox; - private System.Windows.Forms.Button ClearLogsButton; - private System.Windows.Forms.Button ChangeFontButton; - private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; - private System.Windows.Forms.CheckBox TopMostCheckBox; - private System.Windows.Forms.ToolStripMenuItem ViewToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem ClearLogsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem ChangeFontToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem WrapTextToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem TopMostToolStripMenuItem; - private System.Windows.Forms.FlowLayoutPanel ToolbarFlowLayoutPanel; - private System.Windows.Forms.ToolStripMenuItem ToolStripMenuItemSeparater; - private System.Windows.Forms.ToolStripMenuItem ShowToolbarToolStripMenuItem; - private System.Windows.Forms.SplitContainer splitContainer1; - private System.Windows.Forms.DataVisualization.Charting.Chart trafficChart; - } -} \ No newline at end of file diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs deleted file mode 100644 index 937553b7..00000000 --- a/shadowsocks-csharp/View/LogForm.cs +++ /dev/null @@ -1,447 +0,0 @@ -using System; -using System.Drawing; -using System.IO; -using System.Windows.Forms; -using System.Windows.Forms.DataVisualization.Charting; -using System.Collections.Generic; -using System.Linq; - -using Shadowsocks.Controller; -using Shadowsocks.Properties; -using Shadowsocks.Model; -using Shadowsocks.Util; -using System.Text; -using NLog; - -namespace Shadowsocks.View -{ - public partial class LogForm : Form - { - private static Logger logger = LogManager.GetCurrentClassLogger(); - - long lastOffset; - string filename; - Timer timer; - const int BACK_OFFSET = 65536; - ShadowsocksController controller; - - // global traffic update lock, make it static - private static readonly object _lock = new object(); - - #region Traffic Chart - Queue trafficInfoQueue = new Queue(); - const int queueMaxLength = 60; - long lastInbound, lastOutbound; - long maxSpeed = 0, lastMaxSpeed = 0; - const long minScale = 50; - BandwidthScaleInfo bandwidthScale; - List inboundPoints = new List(); - List outboundPoints = new List(); - TextAnnotation inboundAnnotation = new TextAnnotation(); - TextAnnotation outboundAnnotation = new TextAnnotation(); - #endregion - - public LogForm(ShadowsocksController controller) - { - this.controller = controller; - - InitializeComponent(); - Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); - - var nLogConfig = NLogConfig.LoadXML(); - try - { - this.filename = nLogConfig.GetLogFileName(); - } - catch(Exception) - { - // failed to get the file name - } - if (string.IsNullOrEmpty(this.filename)) - { - LogMessageTextBox.AppendText("Cannot get the log file name from NLog config file. Please check if the nlog config file exists with corresponding XML nodes."); - } - - LogViewerConfig config = controller.GetCurrentConfiguration().logViewer; - - topMostTrigger = config.topMost; - wrapTextTrigger = config.wrapText; - toolbarTrigger = config.toolbarShown; - LogMessageTextBox.BackColor = config.BackgroundColor; - LogMessageTextBox.ForeColor = config.TextColor; - LogMessageTextBox.Font = config.Font; - - controller.TrafficChanged += controller_TrafficChanged; - - UpdateTexts(); - } - - private void UpdateTrafficChart() - { - lock (_lock) - { - if (trafficInfoQueue.Count == 0) - return; - - inboundPoints.Clear(); - outboundPoints.Clear(); - maxSpeed = 0; - foreach (var trafficInfo in trafficInfoQueue) - { - inboundPoints.Add(trafficInfo.inbound); - outboundPoints.Add(trafficInfo.outbound); - maxSpeed = Math.Max(maxSpeed, Math.Max(trafficInfo.inbound, trafficInfo.outbound)); - } - lastInbound = trafficInfoQueue.Last().inbound; - lastOutbound = trafficInfoQueue.Last().outbound; - } - - if (maxSpeed > 0) - { - lastMaxSpeed -= lastMaxSpeed / 32; - maxSpeed = Math.Max(minScale, Math.Max(maxSpeed, lastMaxSpeed)); - lastMaxSpeed = maxSpeed; - } - else - { - maxSpeed = lastMaxSpeed = minScale; - } - - bandwidthScale = Utils.GetBandwidthScale(maxSpeed); - - // re-scale the original data points, since it is List, .ForEach does not work - inboundPoints = inboundPoints.Select(p => p / bandwidthScale.unit).ToList(); - outboundPoints = outboundPoints.Select(p => p / bandwidthScale.unit).ToList(); - - if (trafficChart.IsHandleCreated) - { - trafficChart.Series["Inbound"].Points.DataBindY(inboundPoints); - trafficChart.Series["Outbound"].Points.DataBindY(outboundPoints); - trafficChart.ChartAreas[0].AxisY.LabelStyle.Format = "{0:0.##} " + bandwidthScale.unitName; - trafficChart.ChartAreas[0].AxisY.Maximum = bandwidthScale.value; - inboundAnnotation.AnchorDataPoint = trafficChart.Series["Inbound"].Points.Last(); - inboundAnnotation.Text = Utils.FormatBandwidth(lastInbound); - outboundAnnotation.AnchorDataPoint = trafficChart.Series["Outbound"].Points.Last(); - outboundAnnotation.Text = Utils.FormatBandwidth(lastOutbound); - trafficChart.Annotations.Clear(); - trafficChart.Annotations.Add(inboundAnnotation); - trafficChart.Annotations.Add(outboundAnnotation); - } - } - - private void controller_TrafficChanged(object sender, EventArgs e) - { - lock (_lock) - { - if (trafficInfoQueue.Count == 0) - { - // Init an empty queue - for (int i = 0; i < queueMaxLength; i++) - { - trafficInfoQueue.Enqueue(new TrafficInfo(0, 0)); - } - - foreach (var trafficPerSecond in controller.trafficPerSecondQueue) - { - trafficInfoQueue.Enqueue(new TrafficInfo(trafficPerSecond.inboundIncreasement, - trafficPerSecond.outboundIncreasement)); - if (trafficInfoQueue.Count > queueMaxLength) - trafficInfoQueue.Dequeue(); - } - } - else - { - var lastTraffic = controller.trafficPerSecondQueue.Last(); - trafficInfoQueue.Enqueue(new TrafficInfo(lastTraffic.inboundIncreasement, - lastTraffic.outboundIncreasement)); - if (trafficInfoQueue.Count > queueMaxLength) - trafficInfoQueue.Dequeue(); - } - } - } - - private void UpdateTexts() - { - I18N.TranslateForm(this); - trafficChart.Series["Inbound"].LegendText = I18N.GetString("Inbound"); - trafficChart.Series["Outbound"].LegendText = I18N.GetString("Outbound"); - } - - private void Timer_Tick(object sender, EventArgs e) - { - UpdateContent(); - UpdateTrafficChart(); - } - - private void InitContent() - { - if (string.IsNullOrEmpty(filename) || !File.Exists(filename)) - return; - using (StreamReader reader = new StreamReader(new FileStream(filename, - FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) - { - if (reader.BaseStream.Length > BACK_OFFSET) - { - reader.BaseStream.Seek(-BACK_OFFSET, SeekOrigin.End); - reader.ReadLine(); - } - - string line = ""; - StringBuilder appendText = new StringBuilder(1024); - while ((line = reader.ReadLine()) != null) - appendText.AppendLine(line); - - LogMessageTextBox.AppendText(appendText.ToString()); - LogMessageTextBox.ScrollToCaret(); - - lastOffset = reader.BaseStream.Position; - } - } - - private void UpdateContent() - { - this.Text = I18N.GetString("Log Viewer") + - $" [in: {Utils.FormatBytes(controller.InboundCounter)}, out: {Utils.FormatBytes(controller.OutboundCounter)}]"; - - if (string.IsNullOrEmpty(filename) || !File.Exists(filename)) - return; - try - { - using (StreamReader reader = new StreamReader(new FileStream(filename, - FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) - { - reader.BaseStream.Seek(lastOffset, SeekOrigin.Begin); - - string line = ""; - bool changed = false; - StringBuilder appendText = new StringBuilder(128); - while ((line = reader.ReadLine()) != null) - { - changed = true; - appendText.AppendLine(line); - } - - if (changed) - { - LogMessageTextBox.AppendText(appendText.ToString()); - LogMessageTextBox.ScrollToCaret(); - } - - lastOffset = reader.BaseStream.Position; - } - } - catch (FileNotFoundException) - { - } - } - - private void LogForm_Load(object sender, EventArgs e) - { - InitContent(); - - timer = new Timer(); - timer.Interval = 100; - timer.Tick += Timer_Tick; - timer.Start(); - - LogViewerConfig config = controller.GetCurrentConfiguration().logViewer; - - Height = config.Height; - Width = config.Width; - Top = config.BestTop; - Left = config.BestLeft; - if (config.Maximized) - { - WindowState = FormWindowState.Maximized; - } - - topMostTriggerLock = true; - TopMost = TopMostToolStripMenuItem.Checked = TopMostCheckBox.Checked = topMostTrigger; - topMostTriggerLock = false; - - wrapTextTriggerLock = true; - LogMessageTextBox.WordWrap = WrapTextToolStripMenuItem.Checked = WrapTextCheckBox.Checked = wrapTextTrigger; - wrapTextTriggerLock = false; - - ToolbarFlowLayoutPanel.Visible = ShowToolbarToolStripMenuItem.Checked = toolbarTrigger; - } - - private void LogForm_FormClosing(object sender, FormClosingEventArgs e) - { - timer.Stop(); - controller.TrafficChanged -= controller_TrafficChanged; - LogViewerConfig config = controller.GetCurrentConfiguration().logViewer; - - config.topMost = topMostTrigger; - config.wrapText = wrapTextTrigger; - config.toolbarShown = toolbarTrigger; - config.Font = LogMessageTextBox.Font; - config.BackgroundColor = LogMessageTextBox.BackColor; - config.TextColor = LogMessageTextBox.ForeColor; - if (WindowState != FormWindowState.Minimized && !(config.Maximized = WindowState == FormWindowState.Maximized)) - { - config.Top = Top; - config.Left = Left; - config.Height = Height; - config.Width = Width; - } - controller.SaveLogViewerConfig(config); - } - - private void OpenLocationToolStripMenuItem_Click(object sender, EventArgs e) - { - string argument = "/select, \"" + filename + "\""; - logger.Debug(argument); - System.Diagnostics.Process.Start("explorer.exe", argument); - } - - private void ExitToolStripMenuItem_Click(object sender, EventArgs e) - { - Close(); - } - - private void LogForm_Shown(object sender, EventArgs e) - { - LogMessageTextBox.ScrollToCaret(); - } - - #region Clean up the content in LogMessageTextBox. - private void DoClearLogs() - { - try - { - File.Delete(filename); - } - catch { } - lastOffset = 0; - LogMessageTextBox.Clear(); - } - - private void ClearLogsToolStripMenuItem_Click(object sender, EventArgs e) - { - DoClearLogs(); - } - - private void ClearLogsButton_Click(object sender, EventArgs e) - { - DoClearLogs(); - } - #endregion - - #region Change the font settings applied in LogMessageTextBox. - private void DoChangeFont() - { - try - { - FontDialog fd = new FontDialog(); - fd.Font = LogMessageTextBox.Font; - if (fd.ShowDialog() == DialogResult.OK) - { - LogMessageTextBox.Font = new Font(fd.Font.FontFamily, fd.Font.Size, fd.Font.Style); - } - } - catch (Exception ex) - { - logger.LogUsefulException(ex); - MessageBox.Show(ex.Message); - } - } - - private void ChangeFontToolStripMenuItem_Click(object sender, EventArgs e) - { - DoChangeFont(); - } - - private void ChangeFontButton_Click(object sender, EventArgs e) - { - DoChangeFont(); - } - #endregion - - #region Trigger the log messages to wrapable, or not. - bool wrapTextTrigger = false; - bool wrapTextTriggerLock = false; - - private void TriggerWrapText() - { - wrapTextTriggerLock = true; - - wrapTextTrigger = !wrapTextTrigger; - LogMessageTextBox.WordWrap = wrapTextTrigger; - LogMessageTextBox.ScrollToCaret(); - WrapTextToolStripMenuItem.Checked = WrapTextCheckBox.Checked = wrapTextTrigger; - - wrapTextTriggerLock = false; - } - - private void WrapTextToolStripMenuItem_Click(object sender, EventArgs e) - { - if (!wrapTextTriggerLock) - { - TriggerWrapText(); - } - } - - private void WrapTextCheckBox_CheckedChanged(object sender, EventArgs e) - { - if (!wrapTextTriggerLock) - { - TriggerWrapText(); - } - } - #endregion - - #region Trigger the window to top most, or not. - bool topMostTrigger = false; - bool topMostTriggerLock = false; - - private void TriggerTopMost() - { - topMostTriggerLock = true; - - topMostTrigger = !topMostTrigger; - TopMost = topMostTrigger; - TopMostToolStripMenuItem.Checked = TopMostCheckBox.Checked = topMostTrigger; - - topMostTriggerLock = false; - } - - private void TopMostCheckBox_CheckedChanged(object sender, EventArgs e) - { - if (!topMostTriggerLock) - { - TriggerTopMost(); - } - } - - private void TopMostToolStripMenuItem_Click(object sender, EventArgs e) - { - if (!topMostTriggerLock) - { - TriggerTopMost(); - } - } - #endregion - - private bool toolbarTrigger = false; - - private void ShowToolbarToolStripMenuItem_Click(object sender, EventArgs e) - { - toolbarTrigger = !toolbarTrigger; - ToolbarFlowLayoutPanel.Visible = toolbarTrigger; - ShowToolbarToolStripMenuItem.Checked = toolbarTrigger; - } - - private class TrafficInfo - { - public long inbound; - public long outbound; - - public TrafficInfo(long inbound, long outbound) - { - this.inbound = inbound; - this.outbound = outbound; - } - } - } -} diff --git a/shadowsocks-csharp/View/LogForm.resx b/shadowsocks-csharp/View/LogForm.resx deleted file mode 100644 index 1f26a603..00000000 --- a/shadowsocks-csharp/View/LogForm.resx +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - True - - - 17, 17 - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - 39 - - \ No newline at end of file diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs deleted file mode 100644 index 12801cff..00000000 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ /dev/null @@ -1,1001 +0,0 @@ -using NLog; -using Shadowsocks.Controller; -using Shadowsocks.Localization; -using Shadowsocks.Model; -using Shadowsocks.Properties; -using Shadowsocks.Util; -using Shadowsocks.Util.SystemProxy; -using Shadowsocks.Views; -using System; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Linq; -using System.Text; -using System.Windows.Forms; -using System.Windows.Forms.Integration; -using System.Windows.Threading; -using ZXing; -using ZXing.Common; -using ZXing.QrCode; - -namespace Shadowsocks.View -{ - public class MenuViewController - { - private readonly Logger logger = LogManager.GetCurrentClassLogger(); - - private ShadowsocksController controller; - public UpdateChecker updateChecker; - - private NotifyIcon _notifyIcon; - private Icon icon, icon_in, icon_out, icon_both, previousIcon; - - private bool _isStartupCheck; - private string _urlToOpen; - - private ContextMenuStrip contextMenu1; - private ToolStripMenuItem disableItem; - private ToolStripMenuItem AutoStartupItem; - private ToolStripMenuItem ShareOverLANItem; - private ToolStripSeparator SeperatorItem; - private ToolStripMenuItem ConfigItem; - private ToolStripMenuItem ProtocolHandlerItem; - private ToolStripMenuItem ServersItem; - private ToolStripMenuItem globalModeItem; - private ToolStripMenuItem PACModeItem; - private ToolStripMenuItem localPACItem; - private ToolStripMenuItem onlinePACItem; - private ToolStripMenuItem editLocalPACItem; - private ToolStripMenuItem updateFromGeositeItem; - private ToolStripMenuItem editGFWUserRuleItem; - private ToolStripMenuItem editOnlinePACItem; - private ToolStripMenuItem secureLocalPacUrlToggleItem; - private ToolStripMenuItem regenerateLocalPacOnUpdateItem; - private ToolStripMenuItem autoCheckUpdatesToggleItem; - private ToolStripMenuItem checkPreReleaseToggleItem; - private ToolStripMenuItem proxyItem; - private ToolStripMenuItem hotKeyItem; - private ToolStripMenuItem VerboseLoggingToggleItem; - private ToolStripMenuItem ShowPluginOutputToggleItem; - private ToolStripMenuItem WriteI18NFileItem; - private ToolStripMenuItem onlineConfigItem; - - private ConfigForm configForm; - private LogForm logForm; - - private System.Windows.Window serverSharingWindow; - private System.Windows.Window hotkeysWindow; - private System.Windows.Window forwardProxyWindow; - private System.Windows.Window onlineConfigWindow; - - // color definition for icon color transformation - private readonly Color colorMaskBlue = Color.FromArgb(255, 25, 125, 191); - private readonly Color colorMaskDarkSilver = Color.FromArgb(128, 192, 192, 192); - private readonly Color colorMaskLightSilver = Color.FromArgb(192, 192, 192); - private readonly Color colorMaskEclipse = Color.FromArgb(192, 64, 64, 64); - - public MenuViewController(ShadowsocksController controller) - { - this.controller = controller; - - LoadMenu(); - - controller.EnableStatusChanged += controller_EnableStatusChanged; - controller.ConfigChanged += controller_ConfigChanged; - controller.PACFileReadyToOpen += controller_FileReadyToOpen; - controller.UserRuleFileReadyToOpen += controller_FileReadyToOpen; - controller.ShareOverLANStatusChanged += controller_ShareOverLANStatusChanged; - controller.VerboseLoggingStatusChanged += controller_VerboseLoggingStatusChanged; - controller.ShowPluginOutputChanged += controller_ShowPluginOutputChanged; - controller.EnableGlobalChanged += controller_EnableGlobalChanged; - controller.Errored += controller_Errored; - controller.UpdatePACFromGeositeCompleted += controller_UpdatePACFromGeositeCompleted; - controller.UpdatePACFromGeositeError += controller_UpdatePACFromGeositeError; - - _notifyIcon = new NotifyIcon(); - UpdateTrayIconAndNotifyText(); - _notifyIcon.Visible = true; - _notifyIcon.ContextMenuStrip = contextMenu1; - _notifyIcon.BalloonTipClicked += notifyIcon1_BalloonTipClicked; - _notifyIcon.MouseClick += notifyIcon1_Click; - _notifyIcon.MouseDoubleClick += notifyIcon1_DoubleClick; - _notifyIcon.BalloonTipClosed += _notifyIcon_BalloonTipClosed; - controller.TrafficChanged += controller_TrafficChanged; - - updateChecker = new UpdateChecker(); - updateChecker.CheckUpdateCompleted += updateChecker_CheckUpdateCompleted; - - LoadCurrentConfiguration(); - - Configuration config = controller.GetCurrentConfiguration(); - - if (config.firstRun) - { - ShowConfigForm(); - } - else if (config.autoCheckUpdate) - { - _isStartupCheck = true; - Dispatcher.CurrentDispatcher.Invoke(() => updateChecker.CheckForVersionUpdate(3000)); - } - } - - #region Tray Icon - - private void UpdateTrayIconAndNotifyText() - { - Configuration config = controller.GetCurrentConfiguration(); - bool enabled = config.enabled; - bool global = config.global; - - Color colorMask = SelectColorMask(enabled, global); - Size iconSize = SelectIconSize(); - - UpdateIconSet(colorMask, iconSize, out icon, out icon_in, out icon_out, out icon_both); - - previousIcon = icon; - _notifyIcon.Icon = previousIcon; - - string serverInfo = null; - if (controller.GetCurrentStrategy() != null) - { - serverInfo = controller.GetCurrentStrategy().Name; - } - else - { - serverInfo = config.GetCurrentServer().ToString(); - } - // show more info by hacking the P/Invoke declaration for NOTIFYICONDATA inside Windows Forms - string text = I18N.GetString("Shadowsocks") + " " + UpdateChecker.Version + "\n" + - (enabled ? - I18N.GetString("System Proxy On: ") + (global ? I18N.GetString("Global") : I18N.GetString("PAC")) : - I18N.GetString("Running: Port {0}", config.localPort)) // this feedback is very important because they need to know Shadowsocks is running - + "\n" + serverInfo; - if (text.Length > 127) - { - text = text.Substring(0, 126 - 3) + "..."; - } - ViewUtils.SetNotifyIconText(_notifyIcon, text); - } - - /// - /// Determine the icon size based on the screen DPI. - /// - /// - /// https://stackoverflow.com/a/40851713/2075611 - private Size SelectIconSize() - { - Size size = new Size(32, 32); - int dpi = ViewUtils.GetScreenDpi(); - if (dpi < 97) - { - // dpi = 96; - size = new Size(16, 16); - } - else if (dpi < 121) - { - // dpi = 120; - size = new Size(20, 20); - } - else if (dpi < 145) - { - // dpi = 144; - size = new Size(24, 24); - } - else - { - // dpi = 168; - size = new Size(28, 28); - } - return size; - } - - private Color SelectColorMask(bool isProxyEnabled, bool isGlobalProxy) - { - Color colorMask = Color.White; - - Utils.WindowsThemeMode currentWindowsThemeMode = Utils.GetWindows10SystemThemeSetting(); - - if (isProxyEnabled) - { - if (isGlobalProxy) // global - { - colorMask = colorMaskBlue; - } - else // PAC - { - if (currentWindowsThemeMode == Utils.WindowsThemeMode.Light) - { - colorMask = colorMaskEclipse; - } - } - } - else // disabled - { - if (currentWindowsThemeMode == Utils.WindowsThemeMode.Light) - { - colorMask = colorMaskDarkSilver; - } - else - { - colorMask = colorMaskLightSilver; - } - } - - return colorMask; - } - - private void UpdateIconSet(Color colorMask, Size size, - out Icon icon, out Icon icon_in, out Icon icon_out, out Icon icon_both) - { - Bitmap iconBitmap; - - // generate the base icon - iconBitmap = ViewUtils.ChangeBitmapColor(Resources.ss32Fill, colorMask); - iconBitmap = ViewUtils.AddBitmapOverlay(iconBitmap, Resources.ss32Outline); - - icon = Icon.FromHandle(ViewUtils.ResizeBitmap(iconBitmap, size.Width, size.Height).GetHicon()); - icon_in = Icon.FromHandle(ViewUtils.ResizeBitmap(ViewUtils.AddBitmapOverlay(iconBitmap, Resources.ss32In), size.Width, size.Height).GetHicon()); - icon_out = Icon.FromHandle(ViewUtils.ResizeBitmap(ViewUtils.AddBitmapOverlay(iconBitmap, Resources.ss32In), size.Width, size.Height).GetHicon()); - icon_both = Icon.FromHandle(ViewUtils.ResizeBitmap(ViewUtils.AddBitmapOverlay(iconBitmap, Resources.ss32In, Resources.ss32Out), size.Width, size.Height).GetHicon()); - } - - #endregion - - #region ToolStripMenuItems and MenuGroups - - private ToolStripMenuItem CreateToolStripMenuItem(string text, EventHandler click) - { - return new ToolStripMenuItem(I18N.GetString(text), null, click); - } - - private ToolStripMenuItem CreateMenuGroup(string text, ToolStripItem[] items) - { - return new ToolStripMenuItem(I18N.GetString(text), null, items); - } - - private void LoadMenu() - { - this.contextMenu1 = new ContextMenuStrip(); - contextMenu1.Items.AddRange(new ToolStripItem[]{ - CreateMenuGroup("System Proxy", new ToolStripMenuItem[] { - this.disableItem = CreateToolStripMenuItem("Disable", new EventHandler(this.EnableItem_Click)), - this.PACModeItem = CreateToolStripMenuItem("PAC", new EventHandler(this.PACModeItem_Click)), - this.globalModeItem = CreateToolStripMenuItem("Global", new EventHandler(this.GlobalModeItem_Click)) - }), - this.ServersItem = CreateMenuGroup("Servers", new ToolStripItem [] { - this.SeperatorItem = new ToolStripSeparator(), - this.ConfigItem = CreateToolStripMenuItem("Edit Servers...", new EventHandler(this.Config_Click)), - new ToolStripSeparator(), - CreateToolStripMenuItem("Share Server Config...", new EventHandler(this.QRCodeItem_Click)), - CreateToolStripMenuItem("Scan QRCode from Screen...", new EventHandler(this.ScanQRCodeItem_Click)), - CreateToolStripMenuItem("Import URL from Clipboard...", new EventHandler(this.ImportURLItem_Click)) - }), - CreateMenuGroup("PAC ", new ToolStripItem[] { - this.localPACItem = CreateToolStripMenuItem("Local PAC", new EventHandler(this.LocalPACItem_Click)), - this.onlinePACItem = CreateToolStripMenuItem("Online PAC", new EventHandler(this.OnlinePACItem_Click)), - new ToolStripSeparator(), - this.editLocalPACItem = CreateToolStripMenuItem("Edit Local PAC File...", new EventHandler(this.EditPACFileItem_Click)), - this.updateFromGeositeItem = CreateToolStripMenuItem("Update Local PAC from Geosite", new EventHandler(this.UpdatePACFromGeositeItem_Click)), - this.editGFWUserRuleItem = CreateToolStripMenuItem("Edit User Rule for Geosite...", new EventHandler(this.EditUserRuleFileForGeositeItem_Click)), - this.secureLocalPacUrlToggleItem = CreateToolStripMenuItem("Secure Local PAC", new EventHandler(this.SecureLocalPacUrlToggleItem_Click)), - this.regenerateLocalPacOnUpdateItem = CreateToolStripMenuItem("Regenerate local PAC on version update", new EventHandler(this.RegenerateLocalPacOnUpdateItem_Click)), - CreateToolStripMenuItem("Copy Local PAC URL", new EventHandler(this.CopyLocalPacUrlItem_Click)), - this.editOnlinePACItem = CreateToolStripMenuItem("Edit Online PAC URL...", new EventHandler(this.UpdateOnlinePACURLItem_Click)), - }), - this.proxyItem = CreateToolStripMenuItem("Forward Proxy...", new EventHandler(this.proxyItem_Click)), - 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)), - new ToolStripSeparator( ), - this.hotKeyItem = CreateToolStripMenuItem("Edit Hotkeys...", new EventHandler(this.hotKeyItem_Click)), - CreateMenuGroup("Help", new ToolStripItem[] { - CreateToolStripMenuItem("Show Logs...", new EventHandler(this.ShowLogItem_Click)), - this.VerboseLoggingToggleItem = CreateToolStripMenuItem( "Verbose Logging", new EventHandler(this.VerboseLoggingToggleItem_Click) ), - this.ShowPluginOutputToggleItem = CreateToolStripMenuItem("Show Plugin Output", new EventHandler(this.ShowPluginOutputToggleItem_Click)), - this.WriteI18NFileItem = CreateToolStripMenuItem("Write translation template",new EventHandler(WriteI18NFileItem_Click)), - CreateMenuGroup("Updates...", new ToolStripItem[] { - CreateToolStripMenuItem("Check for Updates...", new EventHandler(this.checkUpdatesItem_Click)), - new ToolStripSeparator(), - this.autoCheckUpdatesToggleItem = CreateToolStripMenuItem("Check for Updates at Startup", new EventHandler(this.autoCheckUpdatesToggleItem_Click)), - this.checkPreReleaseToggleItem = CreateToolStripMenuItem("Check Pre-release Version", new EventHandler(this.checkPreReleaseToggleItem_Click)), - }), - CreateToolStripMenuItem("About...", new EventHandler(this.AboutItem_Click)), - }), - new ToolStripSeparator(), - CreateToolStripMenuItem("Quit", new EventHandler(this.Quit_Click)) - }); - } - - #endregion - - 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, ErrorEventArgs e) - { - MessageBox.Show(e.GetException().ToString(), I18N.GetString("Shadowsocks Error: {0}", e.GetException().Message)); - } - - private void controller_ConfigChanged(object sender, EventArgs e) - { - LoadCurrentConfiguration(); - UpdateTrayIconAndNotifyText(); - } - - private void LoadCurrentConfiguration() - { - Configuration config = controller.GetCurrentConfiguration(); - UpdateServersMenu(); - UpdateSystemProxyItemsEnabledStatus(config); - ShareOverLANItem.Checked = config.shareOverLan; - VerboseLoggingToggleItem.Checked = config.isVerboseLogging; - ShowPluginOutputToggleItem.Checked = config.showPluginOutput; - AutoStartupItem.Checked = AutoStartup.Check(); - ProtocolHandlerItem.Checked = ProtocolHandler.Check(); - onlinePACItem.Checked = onlinePACItem.Enabled && config.useOnlinePac; - localPACItem.Checked = !onlinePACItem.Checked; - secureLocalPacUrlToggleItem.Checked = config.secureLocalPac; - regenerateLocalPacOnUpdateItem.Checked = config.regeneratePacOnUpdate; - UpdatePACItemsEnabledStatus(); - UpdateUpdateMenu(); - } - - #region Forms - - private void ShowConfigForm() - { - if (configForm != null) - { - configForm.Activate(); - } - else - { - configForm = new ConfigForm(controller); - configForm.Show(); - configForm.Activate(); - configForm.FormClosed += configForm_FormClosed; - } - } - - private void ShowLogForm() - { - if (logForm != null) - { - logForm.Activate(); - } - else - { - logForm = new LogForm(controller); - logForm.Show(); - logForm.Activate(); - logForm.FormClosed += logForm_FormClosed; - } - } - - void logForm_FormClosed(object sender, FormClosedEventArgs e) - { - logForm.Dispose(); - logForm = null; - } - - void configForm_FormClosed(object sender, FormClosedEventArgs e) - { - configForm.Dispose(); - configForm = null; - var config = controller.GetCurrentConfiguration(); - if (config.firstRun) - { - CheckUpdateForFirstRun(); - ShowBalloonTip( - I18N.GetString("Shadowsocks is here"), - I18N.GetString("You can turn on/off Shadowsocks in the context menu"), - ToolTipIcon.Info, - 0 - ); - config.firstRun = false; - } - } - - #endregion - - #region Misc - - void ShowBalloonTip(string title, string content, ToolTipIcon icon, int timeout) - { - _notifyIcon.BalloonTipTitle = title; - _notifyIcon.BalloonTipText = content; - _notifyIcon.BalloonTipIcon = icon; - _notifyIcon.ShowBalloonTip(timeout); - } - - void notifyIcon1_BalloonTipClicked(object sender, EventArgs e) - { - } - - private void _notifyIcon_BalloonTipClosed(object sender, EventArgs e) - { - } - - private void notifyIcon1_Click(object sender, MouseEventArgs e) - { - UpdateTrayIconAndNotifyText(); - if (e.Button == MouseButtons.Middle) - { - ShowLogForm(); - } - } - - private void notifyIcon1_DoubleClick(object sender, MouseEventArgs e) - { - if (e.Button == MouseButtons.Left) - { - ShowConfigForm(); - } - } - - private void CheckUpdateForFirstRun() - { - Configuration config = controller.GetCurrentConfiguration(); - if (config.firstRun) - return; - _isStartupCheck = true; - Dispatcher.CurrentDispatcher.Invoke(() => updateChecker.CheckForVersionUpdate(3000)); - } - - public void ShowLogForm_HotKey() - { - ShowLogForm(); - } - - #endregion - - #region Main menu - - void controller_ShareOverLANStatusChanged(object sender, EventArgs e) - { - ShareOverLANItem.Checked = controller.GetCurrentConfiguration().shareOverLan; - } - - private void proxyItem_Click(object sender, EventArgs e) - { - if (forwardProxyWindow == null) - { - forwardProxyWindow = new System.Windows.Window() - { - Title = LocalizationProvider.GetLocalizedValue("ForwardProxy"), - Height = 400, - Width = 280, - MinHeight = 400, - MinWidth = 280, - Content = new ForwardProxyView() - }; - forwardProxyWindow.Closed += ForwardProxyWindow_Closed; - ElementHost.EnableModelessKeyboardInterop(forwardProxyWindow); - forwardProxyWindow.Show(); - } - forwardProxyWindow.Activate(); - } - - private void ForwardProxyWindow_Closed(object sender, EventArgs e) - { - forwardProxyWindow = null; - } - - public void CloseForwardProxyWindow() => forwardProxyWindow.Close(); - - private void OnlineConfig_Click(object sender, EventArgs e) - { - if (onlineConfigWindow == null) - { - onlineConfigWindow = new System.Windows.Window() - { - Title = LocalizationProvider.GetLocalizedValue("OnlineConfigDelivery"), - Height = 510, - Width = 480, - MinHeight = 510, - MinWidth = 480, - Content = new OnlineConfigView() - }; - onlineConfigWindow.Closed += OnlineConfigWindow_Closed; - ElementHost.EnableModelessKeyboardInterop(onlineConfigWindow); - onlineConfigWindow.Show(); - } - onlineConfigWindow.Activate(); - } - - private void OnlineConfigWindow_Closed(object sender, EventArgs e) - { - onlineConfigWindow = null; - } - - private void hotKeyItem_Click(object sender, EventArgs e) - { - if (hotkeysWindow == null) - { - hotkeysWindow = new System.Windows.Window() - { - Title = LocalizationProvider.GetLocalizedValue("Hotkeys"), - Height = 260, - Width = 320, - MinHeight = 260, - MinWidth = 320, - Content = new HotkeysView() - }; - hotkeysWindow.Closed += HotkeysWindow_Closed; - ElementHost.EnableModelessKeyboardInterop(hotkeysWindow); - hotkeysWindow.Show(); - } - hotkeysWindow.Activate(); - } - - private void HotkeysWindow_Closed(object sender, EventArgs e) - { - hotkeysWindow = null; - } - - public void CloseHotkeysWindow() => hotkeysWindow.Close(); - - private void ShareOverLANItem_Click(object sender, EventArgs e) - { - ShareOverLANItem.Checked = !ShareOverLANItem.Checked; - 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.GetCurrentConfiguration().enabled; - } - - private void EnableItem_Click(object sender, EventArgs e) - { - controller.ToggleEnable(false); - Configuration config = controller.GetCurrentConfiguration(); - UpdateSystemProxyItemsEnabledStatus(config); - } - - void controller_EnableGlobalChanged(object sender, EventArgs e) - { - globalModeItem.Checked = controller.GetCurrentConfiguration().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; - } - - globalModeItem.Enabled = WinINet.operational; - PACModeItem.Enabled = WinINet.operational; - } - - private void GlobalModeItem_Click(object sender, EventArgs e) - { - controller.ToggleEnable(true); - controller.ToggleGlobal(true); - Configuration config = controller.GetCurrentConfiguration(); - UpdateSystemProxyItemsEnabledStatus(config); - } - - private void PACModeItem_Click(object sender, EventArgs e) - { - controller.ToggleEnable(true); - controller.ToggleGlobal(false); - Configuration config = controller.GetCurrentConfiguration(); - UpdateSystemProxyItemsEnabledStatus(config); - } - - #endregion - - #region Server - - 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().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().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.GetCurrentConfiguration(); - foreach (var server in configuration.configs) - { - try - { - Configuration.CheckServer(server); - var name = server.ToString(); - if (!items.OfType().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++; - } - } - catch - { - } - } - - 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) - { - ToolStripMenuItem item = (ToolStripMenuItem)sender; - controller.SelectServerIndex((int)item.Tag); - } - - private void AStrategyItem_Click(object sender, EventArgs e) - { - ToolStripMenuItem item = (ToolStripMenuItem)sender; - controller.SelectStrategy((string)item.Tag); - } - - private void Config_Click(object sender, EventArgs e) - { - ShowConfigForm(); - } - - void openURLFromQRCode() - { - Utils.OpenInBrowser(_urlToOpen); - } - - private void QRCodeItem_Click(object sender, EventArgs e) - { - if (serverSharingWindow == null) - { - serverSharingWindow = new System.Windows.Window() - { - Title = LocalizationProvider.GetLocalizedValue("ServerSharing"), - Height = 400, - Width = 660, - MinHeight = 400, - MinWidth = 660, - Content = new ServerSharingView() - }; - serverSharingWindow.Closed += ServerSharingWindow_Closed; - ElementHost.EnableModelessKeyboardInterop(serverSharingWindow); - serverSharingWindow.Show(); - } - serverSharingWindow.Activate(); - } - - private void ServerSharingWindow_Closed(object sender, EventArgs e) - { - serverSharingWindow = null; - } - - private void ScanQRCodeItem_Click(object sender, EventArgs e) - { - var result = Utils.ScanQRCodeFromScreen(); - if (result != null) - { - if (result.ToLowerInvariant().StartsWith("http://") || result.ToLowerInvariant().StartsWith("https://")) - { - _urlToOpen = result; - openURLFromQRCode(); - } - else if (controller.AddServerBySSURL(result)) - { - ShowConfigForm(); - } - else - { - MessageBox.Show(I18N.GetString("Invalid QR Code content: {0}", result)); - } - return; - } - else - MessageBox.Show(I18N.GetString("No QRCode found. Try to zoom in or move it to the center of the screen.")); - } - - private void ImportURLItem_Click(object sender, EventArgs e) - { - if (controller.AskAddServerBySSURL(Clipboard.GetText(TextDataFormat.Text))) - { - ShowConfigForm(); - } - } - - #endregion - - #region PAC - - private void LocalPACItem_Click(object sender, EventArgs e) - { - if (!localPACItem.Checked) - { - localPACItem.Checked = true; - onlinePACItem.Checked = false; - controller.UseOnlinePAC(false); - UpdatePACItemsEnabledStatus(); - } - } - - private void OnlinePACItem_Click(object sender, EventArgs e) - { - if (!onlinePACItem.Checked) - { - if (string.IsNullOrEmpty(controller.GetCurrentConfiguration().pacUrl)) - { - UpdateOnlinePACURLItem_Click(sender, e); - } - if (!string.IsNullOrEmpty(controller.GetCurrentConfiguration().pacUrl)) - { - localPACItem.Checked = false; - onlinePACItem.Checked = true; - controller.UseOnlinePAC(true); - } - UpdatePACItemsEnabledStatus(); - } - } - - private void UpdateOnlinePACURLItem_Click(object sender, EventArgs e) - { - string origPacUrl = controller.GetCurrentConfiguration().pacUrl; - string pacUrl = ViewUtils.InputBox( - I18N.GetString("Please input PAC Url"), - I18N.GetString("Edit Online PAC URL"), - origPacUrl, -1, -1); - if (!string.IsNullOrEmpty(pacUrl) && pacUrl != origPacUrl) - { - controller.SavePACUrl(pacUrl); - } - } - - private void SecureLocalPacUrlToggleItem_Click(object sender, EventArgs e) - { - Configuration configuration = controller.GetCurrentConfiguration(); - controller.ToggleSecureLocalPac(!configuration.secureLocalPac); - } - - private void RegenerateLocalPacOnUpdateItem_Click(object sender, EventArgs e) - { - var config = controller.GetCurrentConfiguration(); - controller.ToggleRegeneratePacOnUpdate(!config.regeneratePacOnUpdate); - } - - private void CopyLocalPacUrlItem_Click(object sender, EventArgs e) - { - controller.CopyPacUrl(); - } - - private void UpdatePACItemsEnabledStatus() - { - if (this.localPACItem.Checked) - { - this.editLocalPACItem.Enabled = true; - this.updateFromGeositeItem.Enabled = true; - this.editGFWUserRuleItem.Enabled = true; - this.editOnlinePACItem.Enabled = false; - } - else - { - this.editLocalPACItem.Enabled = false; - this.updateFromGeositeItem.Enabled = false; - this.editGFWUserRuleItem.Enabled = false; - this.editOnlinePACItem.Enabled = true; - } - } - - 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.GetCurrentConfiguration().isVerboseLogging; - } - - void controller_ShowPluginOutputChanged(object sender, EventArgs e) - { - ShowPluginOutputToggleItem.Checked = controller.GetCurrentConfiguration().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 (!_isStartupCheck && updateChecker.NewReleaseZipFilename == null) - { - ShowBalloonTip(I18N.GetString("Shadowsocks"), I18N.GetString("No update is available"), ToolTipIcon.Info, 5000); - } - _isStartupCheck = false; - } - - private void UpdateUpdateMenu() - { - Configuration configuration = controller.GetCurrentConfiguration(); - autoCheckUpdatesToggleItem.Checked = configuration.autoCheckUpdate; - checkPreReleaseToggleItem.Checked = configuration.checkPreRelease; - } - - private void autoCheckUpdatesToggleItem_Click(object sender, EventArgs e) - { - Configuration configuration = controller.GetCurrentConfiguration(); - controller.ToggleCheckingUpdate(!configuration.autoCheckUpdate); - UpdateUpdateMenu(); - } - - private void checkPreReleaseToggleItem_Click(object sender, EventArgs e) - { - Configuration configuration = controller.GetCurrentConfiguration(); - controller.ToggleCheckingPreRelease(!configuration.checkPreRelease); - UpdateUpdateMenu(); - } - - private async void checkUpdatesItem_Click(object sender, EventArgs e) - { - await updateChecker.CheckForVersionUpdate(); - } - - private void AboutItem_Click(object sender, EventArgs e) - { - Utils.OpenInBrowser("https://github.com/shadowsocks/shadowsocks-windows"); - } - - #endregion - } -} diff --git a/shadowsocks-csharp/app.config b/shadowsocks-csharp/app.config deleted file mode 100755 index b6020414..00000000 --- a/shadowsocks-csharp/app.config +++ /dev/null @@ -1,73 +0,0 @@ - - - - -
- - - - - - - 600 - - - 400 - - - True - - - 0 - - - 0 - - - - - diff --git a/shadowsocks-csharp/app.manifest b/shadowsocks-csharp/app.manifest deleted file mode 100755 index 9050e27f..00000000 --- a/shadowsocks-csharp/app.manifest +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PerMonitorV2, PerMonitor, System - true - - - - - - - diff --git a/shadowsocks-csharp/packages.config b/shadowsocks-csharp/packages.config deleted file mode 100644 index 2c063931..00000000 --- a/shadowsocks-csharp/packages.config +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj deleted file mode 100644 index 33854a69..00000000 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ /dev/null @@ -1,75 +0,0 @@ - - - - WinExe - netcoreapp3.1 - true - true - clowwindy & community 2020 - Shadowsocks.Legacy - Shadowsocks Legacy Project - 4.3.0.0 - shadowsocks.ico - Shadowsocks.Program - app.manifest - Shadowsocks.Legacy - - - - - - - - - - - - - all - - - - all - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - - - - - - - - - - - - - True - True - Settings.settings - - - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - \ No newline at end of file diff --git a/shadowsocks-windows.sln b/shadowsocks-windows.sln index b66c3070..00fe9425 100644 --- a/shadowsocks-windows.sln +++ b/shadowsocks-windows.sln @@ -3,13 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.29709.97 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "shadowsocks-csharp", "shadowsocks-csharp\shadowsocks-csharp.csproj", "{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShadowsocksTest", "test\ShadowsocksTest.csproj", "{45913187-0685-4903-B250-DCEF0479CD86}" - ProjectSection(ProjectDependencies) = postProject - {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062} = {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062} - EndProjectSection -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7BD54B24-BBD7-4DD8-99EF-DAEE6684B673}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig @@ -39,7 +32,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shadowsocks.WPF.Tests", "Sh EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shadowsocks.CLI", "Shadowsocks.CLI\Shadowsocks.CLI.csproj", "{78EB3006-81B0-4C13-9B80-E91766874A57}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shadowsocks.Protocol", "Shadowsocks.Protocol\Shadowsocks.Protocol.csproj", "{94DE5045-4D09-437B-BDE3-679FCAF07A2D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shadowsocks.Protocol", "Shadowsocks.Protocol\Shadowsocks.Protocol.csproj", "{94DE5045-4D09-437B-BDE3-679FCAF07A2D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -47,10 +40,6 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|Any CPU.ActiveCfg = Release|Any CPU - {45913187-0685-4903-B250-DCEF0479CD86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {45913187-0685-4903-B250-DCEF0479CD86}.Release|Any CPU.ActiveCfg = Release|Any CPU {DFE11C77-62FA-4011-8398-38626C02E382}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DFE11C77-62FA-4011-8398-38626C02E382}.Debug|Any CPU.Build.0 = Debug|Any CPU {DFE11C77-62FA-4011-8398-38626C02E382}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/test/App.config b/test/App.config deleted file mode 100644 index 620550c5..00000000 --- a/test/App.config +++ /dev/null @@ -1,14 +0,0 @@ - - - -
- - - - - - - - - - \ No newline at end of file diff --git a/test/CachedNetworkStreamTest.cs b/test/CachedNetworkStreamTest.cs deleted file mode 100644 index c1391866..00000000 --- a/test/CachedNetworkStreamTest.cs +++ /dev/null @@ -1,84 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using Shadowsocks.Controller; - -namespace Shadowsocks.Test -{ - [TestClass] - public class CachedNetworkStreamTest - { - byte[] b0 = new byte[256]; - byte[] b1 = new byte[256]; - byte[] b2 = new byte[1024]; - - // [TestInitialize] - [TestInitialize] - public void init() - { - for (int i = 0; i < 256; i++) - { - b0[i] = (byte)i; - b1[i] = (byte)(255 - i); - } - - b0.CopyTo(b2, 0); - b1.CopyTo(b2, 256); - b0.CopyTo(b2, 512); - } - - [TestMethod] - public void StreamTest() - { - using MemoryStream ms = new MemoryStream(b2); - using CachedNetworkStream s = new CachedNetworkStream(ms); - - byte[] o = new byte[128]; - - Assert.AreEqual(128, s.Read(o, 0, 128)); - TestUtils.ArrayEqual(b0[0..128], o); - - Assert.AreEqual(64, s.Read(o, 0, 64)); - TestUtils.ArrayEqual(b0[128..192], o[0..64]); - - s.Seek(0, SeekOrigin.Begin); - Assert.AreEqual(64, s.Read(o, 0, 64)); - TestUtils.ArrayEqual(b0[0..64], o[0..64]); - // refuse to go out of cached range - Assert.ThrowsException(() => - { - s.Seek(193, SeekOrigin.Begin); - }); - Assert.AreEqual(128, s.Read(o, 0, 128)); - TestUtils.ArrayEqual(b0[64..192], o); - - Assert.IsTrue(s.CanSeek); - Assert.AreEqual(128, s.Read(o, 0, 128)); - TestUtils.ArrayEqual(b0[192..256], o[0..64]); - TestUtils.ArrayEqual(b1[0..64], o[64..128]); - - Assert.IsFalse(s.CanSeek); - // refuse to go back when non-cache data has been read - Assert.ThrowsException(() => - { - s.Seek(0, SeekOrigin.Begin); - }); - - // read in non-cache range - Assert.AreEqual(64, s.Read(o, 0, 64)); - s.Read(o, 0, 128); - Assert.AreEqual(512, s.Position); - - Assert.AreEqual(128, s.Read(o, 0, 128)); - TestUtils.ArrayEqual(b0[0..128], o); - s.Read(o, 0, 128); - s.Read(o, 0, 128); - s.Read(o, 0, 128); - - // read at eos - Assert.AreEqual(0, s.Read(o, 0, 128)); - } - } -} diff --git a/test/CryptographyTest.cs b/test/CryptographyTest.cs deleted file mode 100644 index 07e18d67..00000000 --- a/test/CryptographyTest.cs +++ /dev/null @@ -1,141 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Shadowsocks.Encryption; -using Shadowsocks.Encryption.Stream; -using Shadowsocks.Encryption.AEAD; -using System; -using System.Collections.Generic; -using System.Threading; - -namespace Shadowsocks.Test -{ - [TestClass] - public class CryptographyTest - { - readonly Random random = new Random(); - - - [TestMethod] - public void TestMD5() - { - for (int len = 1; len < 64; len++) - { - System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create(); - byte[] bytes = new byte[len]; - random.NextBytes(bytes); - string md5str = Convert.ToBase64String(md5.ComputeHash(bytes)); - string md5str2 = Convert.ToBase64String(CryptoUtils.MD5(bytes)); - Assert.IsTrue(md5str == md5str2); - } - } - - #region Encryptor test tools - private void SingleEncryptionTestCase(IEncryptor encryptor, IEncryptor decryptor, int length) - { - RNG.Reload(); - byte[] plain = new byte[length]; - byte[] cipher = new byte[plain.Length + 100];// AEAD with IPv4 address type needs +100 - byte[] plain2 = new byte[plain.Length + 16]; - - random.NextBytes(plain); - int outLen = encryptor.Encrypt(plain, cipher); - int outLen2 = decryptor.Decrypt(plain2, cipher.AsSpan(0, outLen)); - //encryptor.Encrypt(plain, length, cipher, out int outLen); - //decryptor.Decrypt(cipher, outLen, plain2, out int outLen2); - Assert.AreEqual(length, outLen2); - TestUtils.ArrayEqual(plain.AsSpan(0, length).ToArray(), plain2.AsSpan(0, length).ToArray()); - } - - const string password = "barfoo!"; - - private void RunSingleEncryptionThread(Type enc, Type dec, string method) - { - var ector = enc.GetConstructor(new Type[] { typeof(string), typeof(string) }); - var dctor = dec.GetConstructor(new Type[] { typeof(string), typeof(string) }); - try - { - IEncryptor encryptor = (IEncryptor)ector.Invoke(new object[] { method, password }); - IEncryptor decryptor = (IEncryptor)dctor.Invoke(new object[] { method, password }); - - for (int i = 0; i < 16; i++) - { - RunEncryptionRound(encryptor, decryptor); - } - } - catch - { - encryptionFailed = true; - throw; - } - } - private static bool encryptionFailed = false; - - private void TestEncryptionMethod(Type enc, string method) - { - TestEncryptionMethod(enc, enc, method); - } - private void TestEncryptionMethod(Type enc, Type dec, string method) - { - encryptionFailed = false; - - // run it once before the multi-threading test to initialize global tables - RunSingleEncryptionThread(enc, dec, method); - List threads = new List(); - for (int i = 0; i < 8; i++) - { - Thread t = new Thread(new ThreadStart(() => RunSingleEncryptionThread(enc, dec, method))); threads.Add(t); - t.Start(); - } - foreach (Thread t in threads) - { - t.Join(); - } - Assert.IsFalse(encryptionFailed); - } - #endregion - - // encryption test cases - private void RunEncryptionRound(IEncryptor encryptor, IEncryptor decryptor) - { - SingleEncryptionTestCase(encryptor, decryptor, 7); // for not aligned data - SingleEncryptionTestCase(encryptor, decryptor, 1000); - SingleEncryptionTestCase(encryptor, decryptor, 12333); - SingleEncryptionTestCase(encryptor, decryptor, 16384); - } - - [TestMethod] - public void TestAEADAesGcmNativeEncryption() - { - TestEncryptionMethod(typeof(AEADAesGcmNativeEncryptor), "aes-128-gcm"); - TestEncryptionMethod(typeof(AEADAesGcmNativeEncryptor), "aes-192-gcm"); - TestEncryptionMethod(typeof(AEADAesGcmNativeEncryptor), "aes-256-gcm"); - } - - [TestMethod] - public void TestAEADNaClEncryption() - { - TestEncryptionMethod(typeof(AEADNaClEncryptor), "chacha20-ietf-poly1305"); - TestEncryptionMethod(typeof(AEADNaClEncryptor), "xchacha20-ietf-poly1305"); - } - - [TestMethod] - public void TestStreamNativeEncryption() - { - TestEncryptionMethod(typeof(StreamPlainNativeEncryptor), "plain"); - TestEncryptionMethod(typeof(StreamRc4NativeEncryptor), "rc4"); - TestEncryptionMethod(typeof(StreamRc4NativeEncryptor), "rc4-md5"); - } - - [TestMethod] - public void TestStreamAesCfbBouncyCastleEncryption() - { - TestEncryptionMethod(typeof(StreamAesCfbBouncyCastleEncryptor), "aes-128-cfb"); - TestEncryptionMethod(typeof(StreamAesCfbBouncyCastleEncryptor), "aes-192-cfb"); - TestEncryptionMethod(typeof(StreamAesCfbBouncyCastleEncryptor), "aes-256-cfb"); - } - [TestMethod] - public void TestStreamChachaNaClEncryption() - { - TestEncryptionMethod(typeof(StreamChachaNaClEncryptor), "chacha20-ietf"); - } - } -} \ No newline at end of file diff --git a/test/ProcessEnvironment.cs b/test/ProcessEnvironment.cs deleted file mode 100644 index 106afee2..00000000 --- a/test/ProcessEnvironment.cs +++ /dev/null @@ -1,713 +0,0 @@ -/* *************************************************************************** - -The component allows to read the environment variables of another process -running in a Windows system. - -History: - - - v1.2.ss Add GetCommandLine for convenience. - - - v1.2: Added support for inspection of 64 bit processes from 32 bit host - - v1.1: Fixed issue with environment block size detection - - v1.0: Initial - - -****************************************************************************** - -The MIT License (MIT) - -Copyright (c) 2011-2014 Oleksiy Gapotchenko -Copyright (c) 2018 Shadowsocks Project - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*************************************************************************** */ - -using System; -using System.Collections.Specialized; -using System.Diagnostics; -using System.Linq; -using System.Management; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; - -namespace Shadowsocks.Test -{ - static class ProcessEnvironment - { - public static StringDictionary ReadEnvironmentVariables(this Process process) - { - return _GetEnvironmentVariablesCore(process.Handle); - } - - public static StringDictionary TryReadEnvironmentVariables(this Process process) - { - try - { - return ReadEnvironmentVariables(process); - } - catch - { - return null; - } - } - - public static string GetCommandLine(this Process process) - { - using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + process.Id)) - using (ManagementObjectCollection objects = searcher.Get()) - { - return objects.Cast().SingleOrDefault()?["CommandLine"]?.ToString(); - } - - } - - /// - /// Universal pointer. - /// - struct UniPtr - { - public UniPtr(IntPtr p) - { - Value = p.ToInt64(); - Size = IntPtr.Size; - } - - public UniPtr(long p) - { - Value = p; - Size = sizeof(long); - } - - public long Value; - public int Size; - - public static implicit operator IntPtr(UniPtr p) - { - return new IntPtr(p.Value); - } - - public static implicit operator UniPtr(IntPtr p) - { - return new UniPtr(p); - } - - public override string ToString() - { - return Value.ToString(); - } - - public bool FitsInNativePointer - { - get - { - return Size <= IntPtr.Size; - } - } - - public bool CanBeRepresentedByNativePointer - { - get - { - int actualSize = Size; - - if (actualSize == 8) - { - if (Value >> 32 == 0) - actualSize = 4; - } - - return actualSize <= IntPtr.Size; - } - } - - public long ToInt64() - { - return Value; - } - } - - static StringDictionary _GetEnvironmentVariablesCore(IntPtr hProcess) - { - var penv = _GetPenv(hProcess); - - const int maxEnvSize = 32767; - byte[] envData; - - if (penv.CanBeRepresentedByNativePointer) - { - int dataSize; - if (!_HasReadAccess(hProcess, penv, out dataSize)) - throw new Exception("Unable to read environment block."); - - if (dataSize > maxEnvSize) - dataSize = maxEnvSize; - - envData = new byte[dataSize]; - var res_len = IntPtr.Zero; - bool b = WindowsApi.ReadProcessMemory( - hProcess, - penv, - envData, - new IntPtr(dataSize), - ref res_len); - - if (!b || (int)res_len != dataSize) - throw new Exception("Unable to read environment block data."); - } - else if (penv.Size == 8 && IntPtr.Size == 4) - { - // Accessing 64 bit process under 32 bit host. - - int dataSize; - if (!_HasReadAccessWow64(hProcess, penv.ToInt64(), out dataSize)) - throw new Exception("Unable to read environment block with WOW64 API."); - - if (dataSize > maxEnvSize) - dataSize = maxEnvSize; - - envData = new byte[dataSize]; - long res_len = 0; - int result = WindowsApi.NtWow64ReadVirtualMemory64( - hProcess, - penv.ToInt64(), - envData, - dataSize, - ref res_len); - - if (result != WindowsApi.STATUS_SUCCESS || res_len != dataSize) - throw new Exception("Unable to read environment block data with WOW64 API."); - } - else - { - throw new Exception("Unable to access process memory due to unsupported bitness cardinality."); - } - - return _EnvToDictionary(envData); - } - - static StringDictionary _EnvToDictionary(byte[] env) - { - var result = new StringDictionary(); - - int len = env.Length; - if (len < 4) - return result; - - int n = len - 3; - for (int i = 0; i < n; ++i) - { - byte c1 = env[i]; - byte c2 = env[i + 1]; - byte c3 = env[i + 2]; - byte c4 = env[i + 3]; - - if (c1 == 0 && c2 == 0 && c3 == 0 && c4 == 0) - { - len = i + 3; - break; - } - } - - char[] environmentCharArray = Encoding.Unicode.GetChars(env, 0, len); - - for (int i = 0; i < environmentCharArray.Length; i++) - { - int startIndex = i; - while ((environmentCharArray[i] != '=') && (environmentCharArray[i] != '\0')) - { - i++; - } - if (environmentCharArray[i] != '\0') - { - if ((i - startIndex) == 0) - { - while (environmentCharArray[i] != '\0') - { - i++; - } - } - else - { - string str = new string(environmentCharArray, startIndex, i - startIndex); - i++; - int num3 = i; - while (environmentCharArray[i] != '\0') - { - i++; - } - string str2 = new string(environmentCharArray, num3, i - num3); - result[str] = str2; - } - } - } - - return result; - } - - static bool _TryReadIntPtr32(IntPtr hProcess, IntPtr ptr, out IntPtr readPtr) - { - bool result; - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - } - finally - { - int dataSize = sizeof(Int32); - var data = Marshal.AllocHGlobal(dataSize); - IntPtr res_len = IntPtr.Zero; - bool b = WindowsApi.ReadProcessMemory( - hProcess, - ptr, - data, - new IntPtr(dataSize), - ref res_len); - readPtr = new IntPtr(Marshal.ReadInt32(data)); - Marshal.FreeHGlobal(data); - if (!b || (int)res_len != dataSize) - result = false; - else - result = true; - } - return result; - } - - static bool _TryReadIntPtr(IntPtr hProcess, IntPtr ptr, out IntPtr readPtr) - { - bool result; - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - } - finally - { - int dataSize = IntPtr.Size; - var data = Marshal.AllocHGlobal(dataSize); - IntPtr res_len = IntPtr.Zero; - bool b = WindowsApi.ReadProcessMemory( - hProcess, - ptr, - data, - new IntPtr(dataSize), - ref res_len); - readPtr = Marshal.ReadIntPtr(data); - Marshal.FreeHGlobal(data); - if (!b || (int)res_len != dataSize) - result = false; - else - result = true; - } - return result; - } - - static bool _TryReadIntPtrWow64(IntPtr hProcess, long ptr, out long readPtr) - { - bool result; - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - } - finally - { - int dataSize = sizeof(long); - var data = Marshal.AllocHGlobal(dataSize); - long res_len = 0; - int status = WindowsApi.NtWow64ReadVirtualMemory64( - hProcess, - ptr, - data, - dataSize, - ref res_len); - readPtr = Marshal.ReadInt64(data); - Marshal.FreeHGlobal(data); - if (status != WindowsApi.STATUS_SUCCESS || res_len != dataSize) - result = false; - else - result = true; - } - return result; - } - - static UniPtr _GetPenv(IntPtr hProcess) - { - int processBitness = _GetProcessBitness(hProcess); - - if (processBitness == 64) - { - if (Environment.Is64BitProcess) - { - // Accessing 64 bit process under 64 bit host. - - IntPtr pPeb = _GetPeb64(hProcess); - - IntPtr ptr; - if (!_TryReadIntPtr(hProcess, pPeb + 0x20, out ptr)) - throw new Exception("Unable to read PEB."); - - IntPtr penv; - if (!_TryReadIntPtr(hProcess, ptr + 0x80, out penv)) - throw new Exception("Unable to read RTL_USER_PROCESS_PARAMETERS."); - - return penv; - } - else - { - // Accessing 64 bit process under 32 bit host. - - var pPeb = _GetPeb64(hProcess); - - long ptr; - if (!_TryReadIntPtrWow64(hProcess, pPeb.ToInt64() + 0x20, out ptr)) - throw new Exception("Unable to read PEB."); - - long penv; - if (!_TryReadIntPtrWow64(hProcess, ptr + 0x80, out penv)) - throw new Exception("Unable to read RTL_USER_PROCESS_PARAMETERS."); - - return new UniPtr(penv); - } - } - else - { - // Accessing 32 bit process under 32 bit host. - - IntPtr pPeb = _GetPeb32(hProcess); - - IntPtr ptr; - if (!_TryReadIntPtr32(hProcess, pPeb + 0x10, out ptr)) - throw new Exception("Unable to read PEB."); - - IntPtr penv; - if (!_TryReadIntPtr32(hProcess, ptr + 0x48, out penv)) - throw new Exception("Unable to read RTL_USER_PROCESS_PARAMETERS."); - - return penv; - } - } - - static int _GetProcessBitness(IntPtr hProcess) - { - if (Environment.Is64BitOperatingSystem) - { - bool wow64; - if (!WindowsApi.IsWow64Process(hProcess, out wow64)) - return 32; - if (wow64) - return 32; - return 64; - } - else - { - return 32; - } - } - - static IntPtr _GetPeb32(IntPtr hProcess) - { - if (Environment.Is64BitProcess) - { - var ptr = IntPtr.Zero; - int res_len = 0; - int pbiSize = IntPtr.Size; - int status = WindowsApi.NtQueryInformationProcess( - hProcess, - WindowsApi.ProcessWow64Information, - ref ptr, - pbiSize, - ref res_len); - if (res_len != pbiSize) - throw new Exception("Unable to query process information."); - return ptr; - } - else - { - return _GetPebNative(hProcess); - } - } - - static IntPtr _GetPebNative(IntPtr hProcess) - { - var pbi = new WindowsApi.PROCESS_BASIC_INFORMATION(); - int res_len = 0; - int pbiSize = Marshal.SizeOf(pbi); - int status = WindowsApi.NtQueryInformationProcess( - hProcess, - WindowsApi.ProcessBasicInformation, - ref pbi, - pbiSize, - ref res_len); - if (res_len != pbiSize) - throw new Exception("Unable to query process information."); - return pbi.PebBaseAddress; - } - - static UniPtr _GetPeb64(IntPtr hProcess) - { - if (Environment.Is64BitProcess) - { - return _GetPebNative(hProcess); - } - else - { - // Get PEB via WOW64 API. - var pbi = new WindowsApi.PROCESS_BASIC_INFORMATION_WOW64(); - int res_len = 0; - int pbiSize = Marshal.SizeOf(pbi); - int status = WindowsApi.NtWow64QueryInformationProcess64( - hProcess, - WindowsApi.ProcessBasicInformation, - ref pbi, - pbiSize, - ref res_len); - if (res_len != pbiSize) - throw new Exception("Unable to query process information."); - return new UniPtr(pbi.PebBaseAddress); - } - } - - static bool _HasReadAccess(IntPtr hProcess, IntPtr address, out int size) - { - size = 0; - - var memInfo = new WindowsApi.MEMORY_BASIC_INFORMATION(); - int result = WindowsApi.VirtualQueryEx( - hProcess, - address, - ref memInfo, - Marshal.SizeOf(memInfo)); - - if (result == 0) - return false; - - if (memInfo.Protect == WindowsApi.PAGE_NOACCESS || memInfo.Protect == WindowsApi.PAGE_EXECUTE) - return false; - - try - { - size = Convert.ToInt32(memInfo.RegionSize.ToInt64() - (address.ToInt64() - memInfo.BaseAddress.ToInt64())); - } - catch (OverflowException) - { - return false; - } - - if (size <= 0) - return false; - - return true; - } - - static bool _HasReadAccessWow64(IntPtr hProcess, long address, out int size) - { - size = 0; - - WindowsApi.MEMORY_BASIC_INFORMATION_WOW64 memInfo; - var memInfoType = typeof(WindowsApi.MEMORY_BASIC_INFORMATION_WOW64); - int memInfoLength = Marshal.SizeOf(memInfoType); - const int memInfoAlign = 8; - - long resultLength = 0; - int result; - - IntPtr hMemInfo = Marshal.AllocHGlobal(memInfoLength + memInfoAlign * 2); - try - { - // Align to 64 bits. - IntPtr hMemInfoAligned = new IntPtr(hMemInfo.ToInt64() & ~(memInfoAlign - 1L)); - - result = WindowsApi.NtWow64QueryVirtualMemory64( - hProcess, - address, - WindowsApi.MEMORY_INFORMATION_CLASS.MemoryBasicInformation, - hMemInfoAligned, - memInfoLength, - ref resultLength); - - memInfo = (WindowsApi.MEMORY_BASIC_INFORMATION_WOW64)Marshal.PtrToStructure(hMemInfoAligned, memInfoType); - } - finally - { - Marshal.FreeHGlobal(hMemInfo); - } - - if (result != WindowsApi.STATUS_SUCCESS) - return false; - - if (memInfo.Protect == WindowsApi.PAGE_NOACCESS || memInfo.Protect == WindowsApi.PAGE_EXECUTE) - return false; - - try - { - size = Convert.ToInt32(memInfo.RegionSize - (address - memInfo.BaseAddress)); - } - catch (OverflowException) - { - return false; - } - - if (size <= 0) - return false; - - return true; - } - - static class WindowsApi - { - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct PROCESS_BASIC_INFORMATION - { - public IntPtr Reserved1; - public IntPtr PebBaseAddress; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] - public IntPtr[] Reserved2; - public IntPtr UniqueProcessId; - public IntPtr Reserved3; - } - - public const int ProcessBasicInformation = 0; - public const int ProcessWow64Information = 26; - - [DllImport("ntdll.dll", SetLastError = true)] - public static extern int NtQueryInformationProcess( - IntPtr hProcess, - int pic, - ref PROCESS_BASIC_INFORMATION pbi, - int cb, - ref int pSize); - - [DllImport("ntdll.dll", SetLastError = true)] - public static extern int NtQueryInformationProcess( - IntPtr hProcess, - int pic, - ref IntPtr pi, - int cb, - ref int pSize); - - [DllImport("ntdll.dll", SetLastError = true)] - public static extern int NtQueryInformationProcess( - IntPtr hProcess, - int pic, - ref long pi, - int cb, - ref int pSize); - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct PROCESS_BASIC_INFORMATION_WOW64 - { - public long Reserved1; - public long PebBaseAddress; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] - public long[] Reserved2; - public long UniqueProcessId; - public long Reserved3; - } - - [DllImport("ntdll.dll", SetLastError = true)] - public static extern int NtWow64QueryInformationProcess64( - IntPtr hProcess, - int pic, - ref PROCESS_BASIC_INFORMATION_WOW64 pbi, - int cb, - ref int pSize); - - [DllImport("kernel32.dll", SetLastError = true)] - public static extern bool ReadProcessMemory( - IntPtr hProcess, - IntPtr lpBaseAddress, - [Out] byte[] lpBuffer, - IntPtr dwSize, - ref IntPtr lpNumberOfBytesRead); - - [DllImport("kernel32.dll", SetLastError = true)] - public static extern bool ReadProcessMemory( - IntPtr hProcess, - IntPtr lpBaseAddress, - IntPtr lpBuffer, - IntPtr dwSize, - ref IntPtr lpNumberOfBytesRead); - - [DllImport("ntdll.dll", SetLastError = true)] - public static extern int NtWow64ReadVirtualMemory64( - IntPtr hProcess, - long lpBaseAddress, - IntPtr lpBuffer, - long dwSize, - ref long lpNumberOfBytesRead); - - [DllImport("ntdll.dll", SetLastError = true)] - public static extern int NtWow64ReadVirtualMemory64( - IntPtr hProcess, - long lpBaseAddress, - [Out] byte[] lpBuffer, - long dwSize, - ref long lpNumberOfBytesRead); - - public const int STATUS_SUCCESS = 0; - - public const int PAGE_NOACCESS = 0x01; - public const int PAGE_EXECUTE = 0x10; - - [StructLayout(LayoutKind.Sequential)] - public struct MEMORY_BASIC_INFORMATION - { - public IntPtr BaseAddress; - public IntPtr AllocationBase; - public int AllocationProtect; - public IntPtr RegionSize; - public int State; - public int Protect; - public int Type; - } - - [DllImport("kernel32.dll")] - public static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, ref MEMORY_BASIC_INFORMATION lpBuffer, int dwLength); - - [StructLayout(LayoutKind.Sequential)] - public struct MEMORY_BASIC_INFORMATION_WOW64 - { - public long BaseAddress; - public long AllocationBase; - public int AllocationProtect; - public long RegionSize; - public int State; - public int Protect; - public int Type; - } - - public enum MEMORY_INFORMATION_CLASS - { - MemoryBasicInformation - } - - [DllImport("ntdll.dll")] - public static extern int NtWow64QueryVirtualMemory64( - IntPtr hProcess, - long lpAddress, - MEMORY_INFORMATION_CLASS memoryInformationClass, - IntPtr lpBuffer, // MEMORY_BASIC_INFORMATION_WOW64, pointer must be 64-bit aligned - long memoryInformationLength, - ref long returnLength); - - [DllImport("kernel32.dll")] - public static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process); - } - } -} diff --git a/test/ShadowsocksTest.csproj b/test/ShadowsocksTest.csproj deleted file mode 100644 index 6dd69a8b..00000000 --- a/test/ShadowsocksTest.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - netcoreapp3.1 - - false - - Shadowsocks.Legacy.Test - - - - 0 - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - diff --git a/test/Sip003PluginTest.cs b/test/Sip003PluginTest.cs deleted file mode 100644 index 3820c374..00000000 --- a/test/Sip003PluginTest.cs +++ /dev/null @@ -1,221 +0,0 @@ -using System; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Threading; -using System.Collections.Generic; -using Shadowsocks.Model; -using Shadowsocks.Controller.Service; -using System.Diagnostics; -using System.Net; - -namespace Shadowsocks.Test -{ - [TestClass] - public class Sip003PluginTest - { - string fake_plugin = "ftp"; - - [TestMethod] - public void TestSip003Plugin_NoPlugin() - { - - - var NoPlugin = Sip003Plugin.CreateIfConfigured( - new Server - { - server = "192.168.100.1", - server_port = 8888, - password = "test", - method = "bf-cfb" - }, - false); - - RunPluginSupportTest( - NoPlugin, - "", - "", - "", - "192.168.100.1", - 8888); - } - - [TestMethod] - public void TestSip003Plugin_Plugin() - { - var Plugin = Sip003Plugin.CreateIfConfigured( - new Server - { - server = "192.168.100.1", - server_port = 8888, - password = "test", - method = "bf-cfb", - plugin = fake_plugin - }, - false); - - RunPluginSupportTest( - Plugin, - fake_plugin, - "", - "", - "192.168.100.1", - 8888); - } - - [TestMethod] - public void TestSip003Plugin_PluginWithOpts() - { - var PluginWithOpts = Sip003Plugin.CreateIfConfigured( - new Server - { - server = "192.168.100.1", - server_port = 8888, - password = "test", - method = "bf-cfb", - plugin = fake_plugin, - plugin_opts = "_option" - }, - false); - - RunPluginSupportTest( - PluginWithOpts, - fake_plugin, - "_option", - "", - "192.168.100.1", - 8888); - } - - [TestMethod] - public void TestSip003Plugin_PluginWithArgs() - { - var PluginWithArgs = Sip003Plugin.CreateIfConfigured( - new Server - { - server = "192.168.100.1", - server_port = 8888, - password = "test", - method = "bf-cfb", - plugin = fake_plugin, - plugin_args = "_test" - }, - false); - - RunPluginSupportTest( - PluginWithArgs, - fake_plugin, - "", - "_test", - "192.168.100.1", - 8888); - } - - [TestMethod] - public void TestSip003Plugin_PluginWithOptsAndArgs() - { - var PluginWithOptsAndArgs = Sip003Plugin.CreateIfConfigured( - new Server - { - server = "192.168.100.1", - server_port = 8888, - password = "test", - method = "bf-cfb", - plugin = fake_plugin, - plugin_opts = "_option", - plugin_args = "_test" - }, - false); - - RunPluginSupportTest( - PluginWithOptsAndArgs, - fake_plugin, - "_option", - "_test", - "192.168.100.1", - 8888); - } - - [TestMethod] - public void TestSip003Plugin_PluginWithArgsReplaced() - { - var PluginWithArgsReplaced = Sip003Plugin.CreateIfConfigured( - new Server - { - server = "192.168.100.1", - server_port = 8888, - password = "test", - method = "bf-cfb", - plugin = fake_plugin, - plugin_args = "_test,%SS_REMOTE_HOST%" - }, - false); - - RunPluginSupportTest( - PluginWithArgsReplaced, - fake_plugin, - "", - "_test,192.168.100.1", - "192.168.100.1", - 8888); - } - - [TestMethod] - public void TestSip003Plugin_PluginWithOptsAndArgsReplaced() - { - var PluginWithOptsAndArgsReplaced = Sip003Plugin.CreateIfConfigured( - new Server - { - server = "192.168.100.1", - server_port = 8888, - password = "test", - method = "bf-cfb", - plugin = fake_plugin, - plugin_opts = "_option", - plugin_args = "_test,%SS_REMOTE_HOST%,%SS_PLUGIN_OPTIONS%" - }, - false); - - RunPluginSupportTest( - PluginWithOptsAndArgsReplaced, - fake_plugin, - "_option", - "_test,192.168.100.1,_option", - "192.168.100.1", - 8888); - } - - private static void RunPluginSupportTest(Sip003Plugin plugin, string pluginName, string pluginOpts, string pluginArgs, string serverAddress, int serverPort) - { - - if (string.IsNullOrWhiteSpace(pluginName)) return; - - plugin.StartIfNeeded(); - - Process[] processes = Process.GetProcessesByName(pluginName); - Assert.AreEqual(processes.Length, 1); - Process p = processes[0]; - - - var penv = ProcessEnvironment.ReadEnvironmentVariables(p); - var pcmd = ProcessEnvironment.GetCommandLine(p).Trim(); - pcmd = pcmd.IndexOf(' ') >= 0 ? pcmd.Substring(pcmd.IndexOf(' ') + 1) : ""; - - Assert.AreEqual(penv["SS_REMOTE_HOST"], serverAddress); - Assert.AreEqual(penv["SS_REMOTE_PORT"], serverPort.ToString()); - Assert.AreEqual(penv["SS_LOCAL_HOST"], IPAddress.Loopback.ToString()); - - int _ignored; - Assert.IsTrue(int.TryParse(penv["SS_LOCAL_PORT"], out _ignored)); - - Assert.AreEqual(penv["SS_PLUGIN_OPTIONS"], pluginOpts); - Assert.AreEqual(pcmd, pluginArgs); - - - plugin.Dispose(); - for (int i = 0; i < 50; i++) - { - if (Process.GetProcessesByName(pluginName).Length == 0) return; - Thread.Sleep(50); - } - } - } -} diff --git a/test/TestUtils.cs b/test/TestUtils.cs deleted file mode 100644 index b7ac979e..00000000 --- a/test/TestUtils.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.Collections.Generic; -using System.Text; - -namespace Shadowsocks.Test -{ - class TestUtils - { - public static void ArrayEqual(IEnumerable expected, IEnumerable actual, string msg = "") - { - var e1 = expected.GetEnumerator(); - var e2 = actual.GetEnumerator(); - int ctr = 0; - while (true) - { - var e1next = e1.MoveNext(); - var e2next = e2.MoveNext(); - - if (e1next && e2next) - { - Assert.AreEqual(e1.Current, e2.Current, "at " + ctr); - } - else if (!e1next && !e2next) - { - return; - } - else if (!e1next) - { - Assert.Fail($"actual longer than expected ({ctr}) {msg}"); - } - else - { - Assert.Fail($"actual shorter than expected ({ctr}) {msg}"); - } - ctr++; - } - } - - } -} diff --git a/test/UnitTest.cs b/test/UnitTest.cs deleted file mode 100755 index d3bcd868..00000000 --- a/test/UnitTest.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Shadowsocks.Controller; -using GlobalHotKey; -using System.Windows.Input; -using System.Threading; -using System.Collections.Generic; -using Shadowsocks.Controller.Hotkeys; -using System.Diagnostics; - - -namespace Shadowsocks.Test -{ - [TestClass] - public class UnitTest - { - [TestMethod] - public void TestHotKey2Str() - { - Assert.AreEqual("Ctrl+A", HotKeys.HotKey2Str(Key.A, ModifierKeys.Control)); - Assert.AreEqual("Ctrl+Alt+D2", HotKeys.HotKey2Str(Key.D2, (ModifierKeys.Alt | ModifierKeys.Control))); - Assert.AreEqual("Ctrl+Alt+Shift+NumPad7", HotKeys.HotKey2Str(Key.NumPad7, (ModifierKeys.Alt | ModifierKeys.Control | ModifierKeys.Shift))); - Assert.AreEqual("Ctrl+Alt+Shift+F6", HotKeys.HotKey2Str(Key.F6, (ModifierKeys.Alt | ModifierKeys.Control | ModifierKeys.Shift))); - Assert.AreNotEqual("Ctrl+Shift+Alt+F6", HotKeys.HotKey2Str(Key.F6, (ModifierKeys.Alt | ModifierKeys.Control | ModifierKeys.Shift))); - } - - [TestMethod] - public void TestStr2HotKey() - { - Assert.IsTrue(HotKeys.Str2HotKey("Ctrl+A").Equals(new HotKey(Key.A, ModifierKeys.Control))); - Assert.IsTrue(HotKeys.Str2HotKey("Ctrl+Alt+A").Equals(new HotKey(Key.A, (ModifierKeys.Control | ModifierKeys.Alt)))); - Assert.IsTrue(HotKeys.Str2HotKey("Ctrl+Shift+A").Equals(new HotKey(Key.A, (ModifierKeys.Control | ModifierKeys.Shift)))); - Assert.IsTrue(HotKeys.Str2HotKey("Ctrl+Alt+Shift+A").Equals(new HotKey(Key.A, (ModifierKeys.Control | ModifierKeys.Alt | ModifierKeys.Shift)))); - HotKey testKey0 = HotKeys.Str2HotKey("Ctrl+Alt+Shift+A"); - Assert.IsTrue(testKey0 != null && testKey0.Equals(new HotKey(Key.A, (ModifierKeys.Control | ModifierKeys.Alt | ModifierKeys.Shift)))); - HotKey testKey1 = HotKeys.Str2HotKey("Ctrl+Alt+Shift+F2"); - Assert.IsTrue(testKey1 != null && testKey1.Equals(new HotKey(Key.F2, (ModifierKeys.Control | ModifierKeys.Alt | ModifierKeys.Shift)))); - HotKey testKey2 = HotKeys.Str2HotKey("Ctrl+Shift+Alt+D7"); - Assert.IsTrue(testKey2 != null && testKey2.Equals(new HotKey(Key.D7, (ModifierKeys.Control | ModifierKeys.Alt | ModifierKeys.Shift)))); - HotKey testKey3 = HotKeys.Str2HotKey("Ctrl+Shift+Alt+NumPad7"); - Assert.IsTrue(testKey3 != null && testKey3.Equals(new HotKey(Key.NumPad7, (ModifierKeys.Control | ModifierKeys.Alt | ModifierKeys.Shift)))); - } - - } -} diff --git a/test/UrlTest.cs b/test/UrlTest.cs deleted file mode 100644 index 87eb369f..00000000 --- a/test/UrlTest.cs +++ /dev/null @@ -1,252 +0,0 @@ -using System; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Shadowsocks.Controller; -using System.Threading; -using System.Collections.Generic; -using Shadowsocks.Model; -using System.Diagnostics; - -namespace Shadowsocks.Test -{ - [TestClass] - public class UrlTest - { - Server server1, server1WithRemark, server1WithPlugin, server1WithPluginAndRemark; - string server1CanonUrl, server1WithRemarkCanonUrl, server1WithPluginCanonUrl, server1WithPluginAndRemarkCanonUrl; - - Server server2, server2WithRemark, server2WithPlugin, server2WithPluginAndRemark; - string server2CanonUrl, server2WithRemarkCanonUrl, server2WithPluginCanonUrl, server2WithPluginAndRemarkCanonUrl; - - - [TestInitialize] - public void PrepareTestData() - { - server1 = new Server - { - server = "192.168.100.1", - server_port = 8888, - password = "test", - method = "bf-cfb" - }; - server1CanonUrl = "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xMDAuMTo4ODg4"; - - // server2 has base64 padding - server2 = new Server - { - server = "192.168.1.1", - server_port = 8388, - password = "test", - method = "bf-cfb" - }; - server2CanonUrl = "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xLjE6ODM4OA=="; - - server1WithRemark = new Server - { - server = server1.server, - server_port = server1.server_port, - password = server1.password, - method = server1.method, - remarks = "example-server 1" - }; - server1WithRemarkCanonUrl = "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xMDAuMTo4ODg4#example-server+1"; - - server2WithRemark = new Server - { - server = server2.server, - server_port = server2.server_port, - password = server2.password, - method = server2.method, - remarks = "example-server 2" - }; - - server2WithRemarkCanonUrl = "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xLjE6ODM4OA==#example-server+2"; - - server1WithPlugin = new Server - { - server = server1.server, - server_port = server1.server_port, - password = server1.password, - method = server1.method, - plugin = "obfs-local", - plugin_opts = "obfs=http;obfs-host=google.com" - }; - server1WithPluginCanonUrl = - "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888/?plugin=obfs-local%3bobfs%3dhttp%3bobfs-host%3dgoogle.com"; - - server2WithPlugin = new Server - { - server = server2.server, - server_port = server2.server_port, - password = server2.password, - method = server2.method, - plugin = "obfs-local", - plugin_opts = "obfs=http;obfs-host=google.com" - }; - server2WithPluginCanonUrl = - "ss://YmYtY2ZiOnRlc3Q@192.168.1.1:8388/?plugin=obfs-local%3bobfs%3dhttp%3bobfs-host%3dgoogle.com"; - - server1WithPluginAndRemark = new Server - { - server = server1.server, - server_port = server1.server_port, - password = server1.password, - method = server1.method, - plugin = server1WithPlugin.plugin, - plugin_opts = server1WithPlugin.plugin_opts, - remarks = server1WithRemark.remarks - }; - server1WithPluginAndRemarkCanonUrl = - "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888/?plugin=obfs-local%3bobfs%3dhttp%3bobfs-host%3dgoogle.com#example-server+1"; - - server2WithPluginAndRemark = new Server - { - server = server2.server, - server_port = server2.server_port, - password = server2.password, - method = server2.method, - plugin = server2WithPlugin.plugin, - plugin_opts = server2WithPlugin.plugin_opts, - remarks = server2WithRemark.remarks - }; - server2WithPluginAndRemarkCanonUrl = - "ss://YmYtY2ZiOnRlc3Q@192.168.1.1:8388/?plugin=obfs-local%3bobfs%3dhttp%3bobfs-host%3dgoogle.com#example-server+2"; - } - - [TestMethod] - public void TestParseUrl_Server1() - { - RunParseShadowsocksUrlTest( - string.Join( - "\r\n", - server1CanonUrl, - "\r\n", - "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xMDAuMTo4ODg4/", - server1WithRemarkCanonUrl, - "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xMDAuMTo4ODg4/#example-server+1"), - new[] - { - server1, - server1, - server1WithRemark, - server1WithRemark - }); - - RunParseShadowsocksUrlTest( - string.Join( - "\r\n", - "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888", - "\r\n", - "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888/", - "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888#example-server+1", - "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888/#example-server+1", - server1WithPluginCanonUrl, - server1WithPluginAndRemarkCanonUrl, - "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888/?plugin=obfs-local%3bobfs%3dhttp%3bobfs-host%3dgoogle.com&unsupported=1#example-server+1"), - new[] - { - server1, - server1, - server1WithRemark, - server1WithRemark, - server1WithPlugin, - server1WithPluginAndRemark, - server1WithPluginAndRemark - }); - } - - - - [TestMethod] - public void TestParseUrl_Server2() - { - RunParseShadowsocksUrlTest( - string.Join( - "\r\n", - server2CanonUrl, - "\r\n", - "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xLjE6ODM4OA==/", - server2WithRemarkCanonUrl, - "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xLjE6ODM4OA==/#example-server+2"), - new[] - { - server2, - server2, - server2WithRemark, - server2WithRemark - }); - - RunParseShadowsocksUrlTest( - string.Join( - "\r\n", - "ss://YmYtY2ZiOnRlc3Q@192.168.1.1:8388", - "\r\n", - "ss://YmYtY2ZiOnRlc3Q@192.168.1.1:8388/", - "ss://YmYtY2ZiOnRlc3Q@192.168.1.1:8388#example-server+2", - "ss://YmYtY2ZiOnRlc3Q@192.168.1.1:8388/#example-server+2", - server2WithPluginCanonUrl, - server2WithPluginAndRemarkCanonUrl, - "ss://YmYtY2ZiOnRlc3Q@192.168.1.1:8388/?plugin=obfs-local%3bobfs%3dhttp%3bobfs-host%3dgoogle.com&unsupported=1#example-server+2"), - new[] - { - server2, - server2, - server2WithRemark, - server2WithRemark, - server2WithPlugin, - server2WithPluginAndRemark, - server2WithPluginAndRemark - }); - } - - - [TestMethod] - public void TestUrlGenerate() - { - var generateUrlCases = new Dictionary - { - [server1CanonUrl] = server1, - [server1WithRemarkCanonUrl] = server1WithRemark, - [server1WithPluginCanonUrl] = server1WithPlugin, - [server1WithPluginAndRemarkCanonUrl] = server1WithPluginAndRemark - }; - RunGenerateShadowsocksUrlTest(generateUrlCases); - } - - private static void RunParseShadowsocksUrlTest(string testCase, IReadOnlyList expected) - { - var actual = Server.GetServers(testCase); - if (actual.Count != expected.Count) - { - Assert.Fail("Wrong number of configs. Expected: {0}. Actual: {1}", expected.Count, actual.Count); - } - - for (int i = 0; i < expected.Count; i++) - { - var expectedServer = expected[i]; - var actualServer = actual[i]; - - Assert.AreEqual(expectedServer.server, actualServer.server); - Assert.AreEqual(expectedServer.server_port, actualServer.server_port); - Assert.AreEqual(expectedServer.password, actualServer.password); - Assert.AreEqual(expectedServer.method, actualServer.method); - Assert.AreEqual(expectedServer.plugin, actualServer.plugin); - Assert.AreEqual(expectedServer.plugin_opts, actualServer.plugin_opts); - Assert.AreEqual(expectedServer.remarks, actualServer.remarks); - Assert.AreEqual(expectedServer.timeout, actualServer.timeout); - } - } - - private static void RunGenerateShadowsocksUrlTest(IReadOnlyDictionary testCases) - { - foreach (var testCase in testCases) - { - string expected = testCase.Key; - Server config = testCase.Value; - - var actual = config.GetURL(true); - Assert.AreEqual(expected, actual); - } - } - - } -}