From f6d51956f7e0e4647b9cf6e58fe206efd4fd732b Mon Sep 17 00:00:00 2001 From: Kazuhiro Fujieda Date: Sun, 13 Sep 2015 21:19:52 +0900 Subject: [PATCH] =?utf8?q?8080=E3=81=8C=E4=BD=BF=E7=94=A8=E4=B8=AD?= =?utf8?q?=E3=81=AE=E3=81=A8=E3=81=8D=E3=81=AB=E3=83=9D=E3=83=BC=E3=83=88?= =?utf8?q?=E7=95=AA=E5=8F=B7=E3=82=92=E8=87=AA=E5=8B=95=E5=89=B2=E3=82=8A?= =?utf8?q?=E5=BD=93=E3=81=A6=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- KancolleSniffer/Config.cs | 1 + KancolleSniffer/ConfigDialog.Designer.cs | 1 - KancolleSniffer/ConfigDialog.cs | 34 ++++---- KancolleSniffer/LogServer.cs | 6 +- KancolleSniffer/MainForm.cs | 131 +++++++++++++++++++++---------- Nekoxy/HttpProxy.cs | 6 ++ TrotiNet/TcpServer.cs | 5 +- 7 files changed, 120 insertions(+), 64 deletions(-) diff --git a/KancolleSniffer/Config.cs b/KancolleSniffer/Config.cs index 664889e..217504e 100644 --- a/KancolleSniffer/Config.cs +++ b/KancolleSniffer/Config.cs @@ -28,6 +28,7 @@ namespace KancolleSniffer { public const int DefaultListenPort = 8080; public const string AutoConfigUrl = "https://kancollesniffer.osdn.jp/proxy.pac"; + public const string AutoConfigUrlWithPort = "https://kancollesniffer.osdn.jp/proxy.php?port="; public bool Auto { get; set; } public int Listen { get; set; } public bool UseUpstream { get; set; } diff --git a/KancolleSniffer/ConfigDialog.Designer.cs b/KancolleSniffer/ConfigDialog.Designer.cs index 79b310a..c2a785c 100644 --- a/KancolleSniffer/ConfigDialog.Designer.cs +++ b/KancolleSniffer/ConfigDialog.Designer.cs @@ -657,7 +657,6 @@ namespace KancolleSniffer this.radioButtonAutoConfigOn.TabIndex = 0; this.radioButtonAutoConfigOn.Text = "有効"; this.radioButtonAutoConfigOn.UseVisualStyleBackColor = true; - this.radioButtonAutoConfigOn.CheckedChanged += new System.EventHandler(this.radioButtonAutoConfigOn_CheckedChanged); // // textBoxListen // diff --git a/KancolleSniffer/ConfigDialog.cs b/KancolleSniffer/ConfigDialog.cs index 858f914..66e1119 100644 --- a/KancolleSniffer/ConfigDialog.cs +++ b/KancolleSniffer/ConfigDialog.cs @@ -40,7 +40,7 @@ namespace KancolleSniffer listBoxSoundFile.Items.AddRange(new object[] { "遠征終了", "入渠終了", "建造完了", "艦娘数超過", "装備数超過", - "大破警告", "泊地修理20分経過", "泊地修理進行", "泊地修理完了","疲労回復" + "大破警告", "泊地修理20分経過", "泊地修理進行", "泊地修理完了", "疲労回復" }); numericUpDownMaterialLogInterval.Maximum = 1440; } @@ -141,9 +141,10 @@ namespace KancolleSniffer if (!ValidatePorts(out listen, out outbound, out server)) return; DialogResult = DialogResult.OK; - - ApplyProxySettings(listen, outbound); - ApplyLogSettings(server); + if (!ApplyProxySettings(listen, outbound)) + DialogResult = DialogResult.None; + if (!ApplyLogSettings(server)) + DialogResult = DialogResult.None; ApplyDebugSettings(); _config.TopMost = checkBoxTopMost.Checked; @@ -206,25 +207,30 @@ namespace KancolleSniffer return true; } - private void ApplyProxySettings(int listen, int port) + private bool ApplyProxySettings(int listen, int port) { _config.Proxy.Auto = radioButtonAutoConfigOn.Checked; _config.Proxy.Listen = listen; _config.Proxy.UseUpstream = radioButtonUpstreamOn.Checked; if (_config.Proxy.UseUpstream) _config.Proxy.UpstreamPort = port; - _main.ApplyProxySetting(); + if (!_main.ApplyProxySetting()) + return false; + textBoxListen.Text = _config.Proxy.Listen.ToString(); + return true; } - private void ApplyLogSettings(int server) + private bool ApplyLogSettings(int server) { _config.Log.On = checkBoxOutput.Checked; _config.Log.MaterialLogInterval = (int)numericUpDownMaterialLogInterval.Value; _config.Log.OutputDir = textBoxOutput.Text; _config.Log.ServerOn = radioButtonServerOn.Checked; - if (_config.Log.ServerOn) - _config.Log.Listen = server; - _main.ApplyLogSetting(); + _config.Log.Listen = server; + if (!_main.ApplyLogSetting()) + return false; + textBoxServer.Text = _config.Log.Listen.ToString(); + return true; } private void ApplyDebugSettings() @@ -273,14 +279,6 @@ namespace KancolleSniffer Process.Start(Home); } - private void radioButtonAutoConfigOn_CheckedChanged(object sender, EventArgs e) - { - var on = ((RadioButton)sender).Checked; - textBoxListen.Enabled = !on; - if (on) - textBoxListen.Text = ProxyConfig.DefaultListenPort.ToString(); - } - private void radioButtonUpstreamOff_CheckedChanged(object sender, EventArgs e) { var off = ((RadioButton)sender).Checked; diff --git a/KancolleSniffer/LogServer.cs b/KancolleSniffer/LogServer.cs index 97f6378..509ce00 100644 --- a/KancolleSniffer/LogServer.cs +++ b/KancolleSniffer/LogServer.cs @@ -36,6 +36,8 @@ namespace KancolleSniffer public int Port { get; private set; } + public bool IsListening { get; private set; } + public string OutputDir { set { _outputDir = value; } @@ -43,13 +45,14 @@ namespace KancolleSniffer public LogServer(int port) { - Port = port; _listener = new TcpListener(IPAddress.Loopback, port); } public void Start() { _listener.Start(); + Port = ((IPEndPoint)_listener.LocalEndpoint).Port; + IsListening = true; new Thread(Listen).Start(); } @@ -231,6 +234,7 @@ namespace KancolleSniffer public void Stop() { + IsListening = false; _listener.Server.Close(); } } diff --git a/KancolleSniffer/MainForm.cs b/KancolleSniffer/MainForm.cs index e290a63..1f07af8 100644 --- a/KancolleSniffer/MainForm.cs +++ b/KancolleSniffer/MainForm.cs @@ -21,11 +21,12 @@ using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; +using System.Net.Sockets; using System.Runtime.InteropServices; using System.Text; using System.Threading; -using System.Windows.Forms; using System.Threading.Tasks; +using System.Windows.Forms; using Codeplex.Data; using Microsoft.CSharp.RuntimeBinder; using Microsoft.Win32; @@ -140,23 +141,10 @@ namespace KancolleSniffer ApplyDebugLogSetting(); ApplyLogSetting(); _sniffer.LoadState(); - if (_config.Proxy.Auto) - _systemProxy.SetAutoProxyUrl(ProxyConfig.AutoConfigUrl); - StartProxy(); + ApplyProxySetting(); SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; } - private void StartProxy() - { - if (_config.Proxy.UseUpstream) - { - HttpProxy.UpstreamProxyHost = "127.0.0.1"; - HttpProxy.UpstreamProxyPort = _config.Proxy.UpstreamPort; - } - HttpProxy.IsEnableUpstreamProxy = _config.Proxy.UseUpstream; - HttpProxy.Startup(_config.Proxy.Listen, false, false); - } - private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e) { if (e.Mode != PowerModes.Resume) @@ -179,10 +167,7 @@ namespace KancolleSniffer private void ShutdownProxy() { - lock (typeof (HttpProxy)) - { - HttpProxy.Shutdown(); - } + HttpProxy.Shutdown(); } private void MainForm_Resize(object sender, EventArgs e) @@ -237,45 +222,107 @@ namespace KancolleSniffer _debugLogFile = _config.DebugLogging ? _config.DebugLogFile : null; } - public void ApplyProxySetting() + public bool ApplyProxySetting() { - if (_config.Proxy.Auto != _prevProxy.Auto) - { - if (_config.Proxy.Auto) - _systemProxy.SetAutoProxyUrl(ProxyConfig.AutoConfigUrl); - else - _systemProxy.RestoreSettings(); - } - if (_config.Proxy.Listen != _prevProxy.Listen || + if (!_config.Proxy.Auto) + _systemProxy.RestoreSettings(); + var result = true; + if (!HttpProxy.IsInListening || _config.Proxy.Listen != _prevProxy.Listen || _config.Proxy.UseUpstream != _prevProxy.UseUpstream || _config.Proxy.UpstreamPort != _prevProxy.UpstreamPort) { - Task.Run(() => - { - ShutdownProxy(); - StartProxy(); - }); + ShutdownProxy(); + result = StartProxy(); + } + if (_config.Proxy.Auto && result) + { + _systemProxy.SetAutoProxyUrl(HttpProxy.LocalPort == 8080 + ? ProxyConfig.AutoConfigUrl + : ProxyConfig.AutoConfigUrlWithPort + HttpProxy.LocalPort); } _prevProxy = _config.Proxy.Clone(); + return result; } - public void ApplyLogSetting() + private bool StartProxy() { - if (_logServer != null && (!_config.Log.ServerOn || _config.Log.Listen != _logServer.Port)) + if (_config.Proxy.UseUpstream) { - _logServer.Stop(); - _logServer = null; + HttpProxy.UpstreamProxyHost = "127.0.0.1"; + HttpProxy.UpstreamProxyPort = _config.Proxy.UpstreamPort; } - if (_logServer == null && _config.Log.ServerOn) + HttpProxy.IsEnableUpstreamProxy = _config.Proxy.UseUpstream; + try { - _logServer = new LogServer(_config.Log.Listen); - _logServer.Start(); + HttpProxy.Startup(_config.Proxy.Listen, false, false); + } + catch (SocketException e) + { + if (e.SocketErrorCode != SocketError.AddressAlreadyInUse) + throw; + if (WarnConflictPortNumber("プロキシサーバー", _config.Proxy.Listen, _config.Proxy.Auto) == DialogResult.No || + !_config.Proxy.Auto) + { + _systemProxy.RestoreSettings(); + return false; + } + HttpProxy.Startup(0, false, false); + _config.Proxy.Listen = HttpProxy.LocalPort; + } + return true; + } + + private DialogResult WarnConflictPortNumber(string name, int port, bool auto) + { + var msg = $"{name}のポート番号{port}は他のアプリケーションが使用中です。"; + var cap = "ポート番号の衝突"; + return auto + ? MessageBox.Show(this, msg + "自動的に別の番号を割り当てますか?", cap, + MessageBoxButtons.YesNo, MessageBoxIcon.Question) + : MessageBox.Show(this, msg + "設定ダイアログでポート番号を変更してください。", cap, + MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + + public bool ApplyLogSetting() + { + var result = true; + if (_config.Log.ServerOn) + { + result = StartLogServer(); + } + else + { + _logServer?.Stop(); + _logServer = null; } - if (_logServer != null) - _logServer.OutputDir = _config.Log.OutputDir; _sniffer.EnableLog(_config.Log.On ? LogType.All : LogType.None); _sniffer.MaterialLogInterval = _config.Log.MaterialLogInterval; _sniffer.LogOutputDir = _config.Log.OutputDir; + return result; + } + + private bool StartLogServer() + { + var port = _config.Log.Listen; + if (_logServer?.Port == port) + return true; + _logServer?.Stop(); + _logServer = null; + try + { + _logServer = new LogServer(port); + _logServer.Start(); + } + catch (SocketException e) when (e.SocketErrorCode == SocketError.AddressAlreadyInUse) + { + if (WarnConflictPortNumber("閲覧サーバー", port, true) == DialogResult.No) + return false; + _logServer = new LogServer(0); + _logServer.Start(); + _config.Log.Listen = _logServer.Port; + } + _logServer.OutputDir = _config.Log.OutputDir; + return true; } public static bool IsVisibleOnAnyScreen(Rectangle rect) diff --git a/Nekoxy/HttpProxy.cs b/Nekoxy/HttpProxy.cs index 91aab8f..6cff6e0 100644 --- a/Nekoxy/HttpProxy.cs +++ b/Nekoxy/HttpProxy.cs @@ -62,6 +62,11 @@ namespace Nekoxy public static bool IsInListening => server != null && server.IsListening; /// + /// ローカルポート番号を取得する。 + /// + public static int LocalPort { get; private set; } + + /// /// 指定ポートで Listening を開始する。 /// Shutdown() を呼び出さずに2回目の Startup() を呼び出した場合、InvalidOperationException が発生する。 /// @@ -91,6 +96,7 @@ namespace Nekoxy server = new TcpServer(listeningPort, useIpV6); server.Start(TransparentProxyLogic.CreateProxy); server.InitListenFinished.WaitOne(); + LocalPort = server.LocalPort; if (server.InitListenException != null) throw server.InitListenException; } catch (Exception) diff --git a/TrotiNet/TcpServer.cs b/TrotiNet/TcpServer.cs index ecbce3b..9b39857 100644 --- a/TrotiNet/TcpServer.cs +++ b/TrotiNet/TcpServer.cs @@ -94,7 +94,7 @@ namespace TrotiNet /// /// Port used for local browser-proxy communication /// - protected int LocalPort; + public int LocalPort; /// /// Called every time a connection is accepted from the browser @@ -117,7 +117,7 @@ namespace TrotiNet /// public TcpServer(int localPort, bool bUseIPv6) { - if (localPort < 1) + if (localPort < 0) throw new ArgumentException("localPort"); LocalPort = localPort; @@ -295,6 +295,7 @@ namespace TrotiNet // Bind the socket to the local endpoint and listen for incoming // connections. ListeningSocket.Bind(localEndPoint); + LocalPort = ((IPEndPoint)ListeningSocket.LocalEndPoint).Port; ListeningSocket.Listen(1000); // Notify that the listening thread is up and running -- 2.11.0