OSDN Git Service

ログが壊れているときにグラフが表示されなくなったりするのを直す
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / MainForm.cs
index 8c4d1c5..dfb423c 100644 (file)
@@ -19,16 +19,13 @@ using System.Drawing;
 using System.Globalization;\r
 using System.IO;\r
 using System.Linq;\r
-using System.Net.Sockets;\r
 using System.Runtime.InteropServices;\r
 using System.Text;\r
 using System.Text.RegularExpressions;\r
 using System.Threading.Tasks;\r
 using System.Windows.Forms;\r
 using Microsoft.CSharp.RuntimeBinder;\r
-using Microsoft.Win32;\r
 using static System.Math;\r
-using Timer = System.Windows.Forms.Timer;\r
 \r
 namespace KancolleSniffer\r
 {\r
@@ -37,17 +34,17 @@ namespace KancolleSniffer
         private readonly Sniffer _sniffer = new Sniffer();\r
         private readonly Config _config = new Config();\r
         private readonly ConfigDialog _configDialog;\r
+        private readonly ProxyManager _proxyManager;\r
         private int _currentFleet;\r
         private bool _combinedFleet;\r
         private readonly Label[] _labelCheckFleets;\r
         private readonly ShipLabels _shipLabels;\r
         private readonly ListForm _listForm;\r
-        private readonly NoticeQueue _noticeQueue;\r
+        private readonly NotificationManager _notificationManager;\r
         private bool _started;\r
         private string _debugLogFile;\r
         private IEnumerator<string> _playLog;\r
-        private int _prevProxyPort;\r
-        private readonly SystemProxy _systemProxy = new SystemProxy();\r
+\r
         private readonly ErrorDialog _errorDialog = new ErrorDialog();\r
         private bool _missionFinishTimeMode;\r
         private bool _ndockFinishTimeMode;\r
@@ -74,8 +71,9 @@ namespace KancolleSniffer
             panelRepairList.CreateLabels(panelRepairList_Click);\r
             labelPresetAkashiTimer.BackColor = ShipLabels.ColumnColors[1];\r
             _listForm = new ListForm(_sniffer, _config) {Owner = this};\r
-            _noticeQueue = new NoticeQueue(Ring);\r
+            _notificationManager = new NotificationManager(Ring);\r
             _config.Load();\r
+            _proxyManager = new ProxyManager(_config, this);\r
             PerformZoom();\r
             _shipLabels.AdjustAkashiTimers();\r
             _sniffer.LoadState();\r
@@ -184,36 +182,28 @@ namespace KancolleSniffer
             ApplyDebugLogSetting();\r
             ApplyLogSetting();\r
             ApplyProxySetting();\r
-            SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;\r
             if (_config.KancolleDb.On)\r
                 _kancolleDb.Start(_config.KancolleDb.Token);\r
         }\r
 \r
-        private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)\r
-        {\r
-            if (e.Mode != PowerModes.Resume || !_config.Proxy.Auto)\r
-                return;\r
-            SystemProxy.Refresh();\r
-        }\r
-\r
         private void MainForm_FormClosing(object sender, FormClosingEventArgs e)\r
         {\r
+            using (var dialog = new ConfirmDialog())\r
+            {\r
+                if (dialog.ShowDialog(this) != DialogResult.Yes)\r
+                {\r
+                    e.Cancel = true;\r
+                    return;\r
+                }\r
+            }\r
             e.Cancel = false;\r
             _sniffer.FlashLog();\r
             _config.Location = (WindowState == FormWindowState.Normal ? Bounds : RestoreBounds).Location;\r
             _config.Save();\r
-            Task.Run(() => ShutdownProxy());\r
-            if (_config.Proxy.Auto)\r
-                _systemProxy.RestoreSettings();\r
-            SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;\r
+            _proxyManager.Shutdown();\r
             _kancolleDb.Stop();\r
         }\r
 \r
-        private void ShutdownProxy()\r
-        {\r
-            HttpProxy.Shutdown();\r
-        }\r
-\r
         private void MainForm_Resize(object sender, EventArgs e)\r
         {\r
             ShowInTaskbar = !(_config.HideOnMinimized && WindowState == FormWindowState.Minimized);\r
@@ -285,59 +275,7 @@ namespace KancolleSniffer
 \r
         public bool ApplyProxySetting()\r
         {\r
-            if (!_config.Proxy.Auto)\r
-                _systemProxy.RestoreSettings();\r
-            if (_config.Proxy.UseUpstream)\r
-            {\r
-                HttpProxy.UpstreamProxyHost = "127.0.0.1";\r
-                HttpProxy.UpstreamProxyPort = _config.Proxy.UpstreamPort;\r
-            }\r
-            HttpProxy.IsEnableUpstreamProxy = _config.Proxy.UseUpstream;\r
-            var result = true;\r
-            if (!HttpProxy.IsInListening || _config.Proxy.Listen != _prevProxyPort)\r
-            {\r
-                ShutdownProxy();\r
-                result = StartProxy();\r
-            }\r
-            if (_config.Proxy.Auto && result)\r
-            {\r
-                _systemProxy.SetAutoProxyUrl($"http://localhost:{_config.Proxy.Listen}/proxy.pac");\r
-            }\r
-            _prevProxyPort = _config.Proxy.Listen;\r
-            return result;\r
-        }\r
-\r
-        private bool StartProxy()\r
-        {\r
-            try\r
-            {\r
-                HttpProxy.Startup(_config.Proxy.Listen, false, false);\r
-            }\r
-            catch (SocketException e)\r
-            {\r
-                if (e.SocketErrorCode != SocketError.AddressAlreadyInUse)\r
-                    throw;\r
-                if (WarnConflictPortNumber("プロキシサーバー", _config.Proxy.Listen, _config.Proxy.Auto) == DialogResult.No ||\r
-                    !_config.Proxy.Auto)\r
-                {\r
-                    _systemProxy.RestoreSettings();\r
-                    return false;\r
-                }\r
-                HttpProxy.Startup(0, false, false);\r
-                _config.Proxy.Listen = HttpProxy.LocalPort;\r
-            }\r
-            return true;\r
-        }\r
-\r
-        private DialogResult WarnConflictPortNumber(string name, int port, bool auto)\r
-        {\r
-            var msg = $"{name}のポート番号{port}は他のアプリケーションが使用中です。";\r
-            var cap = "ポート番号の衝突";\r
-            return auto\r
-                ? MessageBox.Show(this, msg + "自動的に別の番号を割り当てますか?", cap,\r
-                    MessageBoxButtons.YesNo, MessageBoxIcon.Question)\r
-                : MessageBox.Show(this, msg + "設定ダイアログでポート番号を変更してください。", cap,\r
-                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\r
+            return _proxyManager.ApplyConfig();\r
         }\r
 \r
         public void ApplyLogSetting()\r
@@ -434,7 +372,7 @@ namespace KancolleSniffer
             if (item.RingShips)\r
             {\r
                 var message = $"残り{_sniffer.Item.MaxShips - _sniffer.Item.NowShips:D}隻";\r
-                _noticeQueue.Enqueue("艦娘が多すぎます", message, "艦娘数超過");\r
+                _notificationManager.Enqueue("艦娘数超過", message);\r
                 item.RingShips = false;\r
             }\r
         }\r
@@ -447,7 +385,7 @@ namespace KancolleSniffer
             if (item.RingEquips)\r
             {\r
                 var message = $"残り{_sniffer.Item.MaxEquips - _sniffer.Item.NowEquips:D}個";\r
-                _noticeQueue.Enqueue("装備が多すぎます", message, "装備数超過");\r
+                _notificationManager.Enqueue("装備数超過", message);\r
                 item.RingEquips = false;\r
             }\r
         }\r
@@ -512,7 +450,7 @@ namespace KancolleSniffer
         private void NotifyDamagedShip()\r
         {\r
             if (_sniffer.BadlyDamagedShips.Any())\r
-                _noticeQueue.Enqueue("大破した艦娘がいます", string.Join(" ", _sniffer.BadlyDamagedShips), "大破警告");\r
+                _notificationManager.Enqueue("大破警告", string.Join(" ", _sniffer.BadlyDamagedShips));\r
         }\r
 \r
         private void NotifyAkashiTimer()\r
@@ -525,17 +463,16 @@ namespace KancolleSniffer
                 return;\r
             if (msgs[0].Proceeded == "20分経過しました。")\r
             {\r
-                _noticeQueue.Enqueue("泊地修理", msgs[0].Proceeded, "泊地修理20分経過");\r
+                _notificationManager.Enqueue("泊地修理20分経過", msgs[0].Proceeded);\r
                 msgs[0].Proceeded = "";\r
                 // 修理完了がいるかもしれないので続ける\r
             }\r
-            var fn = new[] {"第一艦隊", "第二艦隊", "第三艦隊", "第四艦隊"};\r
-            for (var i = 0; i < fn.Length; i++)\r
+            for (var i = 0; i < ShipInfo.FleetCount; i++)\r
             {\r
                 if (msgs[i].Proceeded != "")\r
-                    _noticeQueue.Enqueue("泊地修理 " + fn[i], "修理進行:" + msgs[i].Proceeded, "泊地修理進行");\r
+                    _notificationManager.Enqueue("泊地修理進行", i, msgs[i].Proceeded);\r
                 if (msgs[i].Completed != "")\r
-                    _noticeQueue.Enqueue("泊地修理 " + fn[i], "修理完了:" + msgs[i].Completed, "泊地修理完了");\r
+                    _notificationManager.Enqueue("泊地修理完了", i, msgs[i].Completed);\r
             }\r
         }\r
 \r
@@ -670,7 +607,7 @@ namespace KancolleSniffer
                 entry.label.Text = entry.Timer.ToString(_missionFinishTimeMode);\r
                 if (!entry.Timer.NeedRing)\r
                     continue;\r
-                _noticeQueue.Enqueue("遠征が終わりました", entry.Name, "遠征終了");\r
+                _notificationManager.Enqueue("遠征終了", entry.Name);\r
                 entry.Timer.NeedRing = false;\r
             }\r
             for (var i = 0; i < _sniffer.NDock.Length; i++)\r
@@ -680,7 +617,7 @@ namespace KancolleSniffer
                 _shipLabels.SetNDockTimer(i, entry.Timer, _ndockFinishTimeMode);\r
                 if (!entry.Timer.NeedRing)\r
                     continue;\r
-                _noticeQueue.Enqueue("入渠が終わりました", entry.Name, "入渠終了");\r
+                _notificationManager.Enqueue("入渠終了", entry.Name);\r
                 entry.Timer.NeedRing = false;\r
             }\r
             var kdock = new[] {labelConstruct1, labelConstruct2, labelConstruct3, labelConstruct4};\r
@@ -693,7 +630,7 @@ namespace KancolleSniffer
                 kdock[i].Text = timer.EndTime == DateTime.MinValue ? "" : timer.Rest.ToString(@"hh\:mm\:ss");\r
                 if (!timer.NeedRing)\r
                     continue;\r
-                _noticeQueue.Enqueue("建造が終わりました", $"第{i + 1:D}ドック", "建造完了");\r
+                _notificationManager.Enqueue("建造完了", $"第{i + 1:D}ドック");\r
                 timer.NeedRing = false;\r
             }\r
             UpdateCondTimers();\r
@@ -739,12 +676,11 @@ namespace KancolleSniffer
             var notice = _sniffer.GetConditionNotice();\r
             if (notice == null)\r
                 return;\r
-            var fn = new[] {"第一艦隊", "第二艦隊", "第三艦隊", "第四艦隊"};\r
-            for (var i = 0; i < fn.Length; i++)\r
+            for (var i = 0; i < ShipInfo.FleetCount; i++)\r
             {\r
                 if (!_config.NotifyConditions.Contains(notice[i]))\r
                     return;\r
-                _noticeQueue.Enqueue("疲労が回復しました", fn[i] + " cond" + notice[i].ToString("D"), "疲労回復");\r
+                _notificationManager.Enqueue("疲労回復" + notice[i], i, "cond" + notice[i]);\r
             }\r
         }\r
 \r
@@ -809,51 +745,21 @@ namespace KancolleSniffer
             }\r
         }\r
 \r
-        private class NoticeQueue\r
-        {\r
-            private readonly Action<string, string, string> _ring;\r
-            private readonly Queue<Tuple<string, string, string>> _queue = new Queue<Tuple<string, string, string>>();\r
-            private readonly Timer _timer = new Timer {Interval = 2000};\r
-\r
-            public NoticeQueue(Action<string, string, string> ring)\r
-            {\r
-                _ring = ring;\r
-                _timer.Tick += TimerOnTick;\r
-            }\r
-\r
-            private void TimerOnTick(object obj, EventArgs e)\r
-            {\r
-                if (_queue.Count == 0)\r
-                {\r
-                    _timer.Stop();\r
-                    return;\r
-                }\r
-                var notice = _queue.Dequeue();\r
-                _ring(notice.Item1, notice.Item2, notice.Item3);\r
-            }\r
-\r
-            public void Enqueue(string title, string message, string name)\r
-            {\r
-                if (_timer.Enabled)\r
-                {\r
-                    _queue.Enqueue(new Tuple<string, string, string>(title, message, name));\r
-                }\r
-                else\r
-                {\r
-                    _ring(title, message, name);\r
-                    _timer.Start();\r
-                }\r
-            }\r
-        }\r
-\r
-        private void Ring(string baloonTitle, string baloonMessage, string name)\r
+        private void Ring(string balloonTitle, string balloonMessage, string name)\r
         {\r
             if (_config.FlashWindow && (_config.Notifications[name] & NotificationType.FlashWindow) != 0)\r
                 Win32API.FlashWindow(Handle);\r
             if (_config.ShowBaloonTip && (_config.Notifications[name] & NotificationType.ShowBaloonTip) != 0)\r
-                notifyIconMain.ShowBalloonTip(20000, baloonTitle, baloonMessage, ToolTipIcon.Info);\r
+                notifyIconMain.ShowBalloonTip(20000, balloonTitle, balloonMessage, ToolTipIcon.Info);\r
             if (_config.PlaySound && (_config.Notifications[name] & NotificationType.PlaySound) != 0)\r
                 PlaySound(_config.Sounds[name], _config.Sounds.Volume);\r
+            if (_config.Pushbullet.On && (_config.Notifications[name] & NotificationType.Pushbullet) != 0)\r
+            {\r
+                Task.Run(() =>\r
+                {\r
+                    PushBullet.PushNote(_config.Pushbullet.Token, balloonTitle, balloonMessage);\r
+                });\r
+            }\r
         }\r
 \r
         [DllImport("winmm.dll")]\r