OSDN Git Service

BurageSnapの起動が阻まれたときにエラーになるのを直す
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / MainForm.cs
index 8950f3b..ec4df4c 100644 (file)
@@ -14,6 +14,7 @@
 \r
 using System;\r
 using System.Collections.Generic;\r
+using System.ComponentModel;\r
 using System.Diagnostics;\r
 using System.Drawing;\r
 using System.Globalization;\r
@@ -36,11 +37,13 @@ namespace KancolleSniffer
         private readonly Config _config = new Config();\r
         private readonly ConfigDialog _configDialog;\r
         private readonly ProxyManager _proxyManager;\r
-        private readonly ToolTip _toolTip = new ToolTip {ShowAlways = true};\r
+        private readonly ResizableToolTip _toolTip = new ResizableToolTip {ShowAlways = true};\r
+        private readonly ResizableToolTip _toolTipQuest = new ResizableToolTip {ShowAlways = true, AutoPopDelay = 10000};\r
+        private readonly ResizableToolTip _tooltipCopy = new ResizableToolTip {AutomaticDelay = 0};\r
         private int _currentFleet;\r
         private bool _combinedFleet;\r
         private readonly Label[] _labelCheckFleets;\r
-        private readonly ShipLabels _shipLabels;\r
+        private readonly MainFormLabels _mainLabels;\r
         private readonly ListForm _listForm;\r
         private readonly NotificationManager _notificationManager;\r
         private bool _started;\r
@@ -48,9 +51,9 @@ namespace KancolleSniffer
         private string _debugLogFile;\r
         private IEnumerator<string> _playLog;\r
         private DateTime _prev, _now;\r
+        private bool _inSortie;\r
 \r
         private readonly ErrorDialog _errorDialog = new ErrorDialog();\r
-        private readonly KancolleDb _kancolleDb = new KancolleDb();\r
         private readonly ErrorLog _errorLog;\r
 \r
         public MainForm()\r
@@ -66,34 +69,76 @@ namespace KancolleSniffer
                 CurrentAutoScaleDimensions.Height / 12f);\r
 \r
             SetupFleetClick();\r
-            _shipLabels = new ShipLabels();\r
-            _shipLabels.CreateAkashiTimers(panelShipInfo);\r
-            _shipLabels.CreateShipLabels(panelShipInfo, ShowShipOnShipList);\r
-            _shipLabels.CreateAkashiTimers7(panel7Ships);\r
-            _shipLabels.CreateShipLabels7(panel7Ships, ShowShipOnShipList);\r
-            _shipLabels.CreateCombinedShipLabels(panelCombinedFleet, ShowShipOnShipList);\r
-            _shipLabels.CreateNDockLabels(panelDock, labelNDock_Click);\r
+            _mainLabels = new MainFormLabels();\r
+            _mainLabels.CreateAkashiTimers(panelShipInfo);\r
+            _mainLabels.CreateShipLabels(panelShipInfo, ShowShipOnShipList);\r
+            _mainLabels.CreateAkashiTimers7(panel7Ships);\r
+            _mainLabels.CreateShipLabels7(panel7Ships, ShowShipOnShipList);\r
+            _mainLabels.CreateCombinedShipLabels(panelCombinedFleet, ShowShipOnShipList);\r
+            _mainLabels.CreateNDockLabels(panelDock, labelNDock_Click);\r
             panelRepairList.CreateLabels(panelRepairList_Click);\r
-            labelPresetAkashiTimer.BackColor = ShipLabels.ColumnColors[1];\r
+            labelPresetAkashiTimer.BackColor = ShipLabel.ColumnColors[1];\r
             _listForm = new ListForm(_sniffer, _config) {Owner = this};\r
             _notificationManager = new NotificationManager(Alarm);\r
-            try\r
-            {\r
-                _config.Load();\r
-            }\r
-            catch (Exception ex)\r
-            {\r
-                throw new ConfigFileException("設定ファイルが壊れています。", ex);\r
-            }\r
+            _config.Load();\r
             _proxyManager = new ProxyManager(_config, this);\r
             _errorLog = new ErrorLog(_sniffer);\r
             _proxyManager.UpdatePacFile();\r
             PerformZoom();\r
-            _shipLabels.AdjustAkashiTimers();\r
-            _sniffer.LoadState();\r
+            _mainLabels.AdjustAkashiTimers();\r
+            LoadData();\r
             _sniffer.RepeatingTimerController = new RepeatingTimerController(_notificationManager, _config);\r
         }\r
 \r
+        /// <summary>\r
+        /// パネルのz-orderがくるうのを避ける\r
+        /// https://stackoverflow.com/a/5777090/1429506\r
+        /// </summary>\r
+        private void MainForm_Shown(object sender, EventArgs e)\r
+        {\r
+            // ReSharper disable once NotAccessedVariable\r
+            IntPtr handle;\r
+            foreach (var panel in new[] {panelShipInfo, panel7Ships, panelCombinedFleet})\r
+                // ReSharper disable once RedundantAssignment\r
+                handle = panel.Handle;\r
+        }\r
+\r
+        private readonly FileSystemWatcher _watcher = new FileSystemWatcher\r
+        {\r
+            Path = AppDomain.CurrentDomain.BaseDirectory,\r
+            NotifyFilter = NotifyFilters.LastWrite\r
+        };\r
+\r
+        private readonly Timer _watcherTimer = new Timer {Interval = 1000};\r
+\r
+        private void LoadData()\r
+        {\r
+            var target = "";\r
+            _sniffer.LoadState();\r
+            DataLoader.LoadTpSpec();\r
+            _watcher.SynchronizingObject = this;\r
+            _watcherTimer.Tick += (sender, ev) =>\r
+            {\r
+                _watcherTimer.Stop();\r
+                switch (target)\r
+                {\r
+                    case "status.xml":\r
+                        _sniffer.LoadState();\r
+                        break;\r
+                    case "TP.csv":\r
+                        DataLoader.LoadTpSpec();\r
+                        break;\r
+                }\r
+            };\r
+            _watcher.Changed += (sender, ev) =>\r
+            {\r
+                target = ev.Name;\r
+                _watcherTimer.Stop();\r
+                _watcherTimer.Start();\r
+            };\r
+            _watcher.EnableRaisingEvents = true;\r
+        }\r
+\r
         private class RepeatingTimerController : Sniffer.IRepeatingTimerController\r
         {\r
             private readonly NotificationManager _manager;\r
@@ -128,7 +173,7 @@ namespace KancolleSniffer
 \r
         private void HttpProxy_AfterSessionComplete(HttpProxy.Session session)\r
         {\r
-            Invoke(new Action<HttpProxy.Session>(ProcessRequest), session);\r
+            BeginInvoke(new Action<HttpProxy.Session>(ProcessRequest), session);\r
         }\r
 \r
         private void ProcessRequest(HttpProxy.Session session)\r
@@ -143,8 +188,6 @@ namespace KancolleSniffer
                 WriteDebugLog(url, request, response);\r
                 return;\r
             }\r
-            if (_config.KancolleDb.On)\r
-                _kancolleDb.Send(url, request, response);\r
             response = UnescapeString(response.Remove(0, "svdata=".Length));\r
             WriteDebugLog(url, request, response);\r
             ProcessRequestMain(url, request, response);\r
@@ -163,28 +206,34 @@ namespace KancolleSniffer
                 if (_errorDialog.ShowDialog(this,\r
                         "艦これに仕様変更があったか、受信内容が壊れています。",\r
                         _errorLog.GenerateErrorLog(url, request, response, e.ToString())) == DialogResult.Abort)\r
-                    Application.Exit();\r
+                    Exit();\r
             }\r
             catch (LogIOException e)\r
             {\r
                 // ReSharper disable once PossibleNullReferenceException\r
                 if (_errorDialog.ShowDialog(this, e.Message, e.InnerException.ToString()) == DialogResult.Abort)\r
-                    Application.Exit();\r
+                    Exit();\r
             }\r
             catch (BattleResultError)\r
             {\r
                 if (_errorDialog.ShowDialog(this, "戦闘結果の計算に誤りがあります。",\r
                         _errorLog.GenerateBattleErrorLog()) == DialogResult.Abort)\r
-                    Application.Exit();\r
+                    Exit();\r
             }\r
             catch (Exception e)\r
             {\r
                 if (_errorDialog.ShowDialog(this, "エラーが発生しました。",\r
                         _errorLog.GenerateErrorLog(url, request, response, e.ToString())) == DialogResult.Abort)\r
-                    Application.Exit();\r
+                    Exit();\r
             }\r
         }\r
 \r
+        private void Exit()\r
+        {\r
+            _proxyManager.Shutdown();\r
+            Environment.Exit(1);\r
+        }\r
+\r
         private void WriteDebugLog(string url, string request, string response)\r
         {\r
             if (_debugLogFile != null)\r
@@ -243,15 +292,13 @@ namespace KancolleSniffer
             if (_config.HideOnMinimized && WindowState == FormWindowState.Minimized)\r
                 ShowInTaskbar = false;\r
             if (_config.ShowHpInPercent)\r
-                _shipLabels.ToggleHpPercent();\r
+                _mainLabels.ToggleHpPercent();\r
             if (_config.ShipList.Visible)\r
                 _listForm.Show();\r
             ApplyConfig();\r
             ApplyDebugLogSetting();\r
             ApplyLogSetting();\r
             ApplyProxySetting();\r
-            if (_config.KancolleDb.On)\r
-                _kancolleDb.Start(_config.KancolleDb.Token);\r
             CheckVersionUp((current, latest) =>\r
             {\r
                 if (double.Parse(latest) <= double.Parse(current))\r
@@ -301,11 +348,11 @@ namespace KancolleSniffer
             e.Cancel = false;\r
             _sniffer.FlashLog();\r
             _config.Location = (WindowState == FormWindowState.Normal ? Bounds : RestoreBounds).Location;\r
-            _config.ShowHpInPercent = _shipLabels.ShowHpInPercent;\r
+            _config.ShowHpInPercent = _mainLabels.ShowHpInPercent;\r
             _config.ShipList.Visible = _listForm.Visible && _listForm.WindowState == FormWindowState.Normal;\r
             _config.Save();\r
+            _sniffer.SaveState();\r
             _proxyManager.Shutdown();\r
-            _kancolleDb.Stop();\r
         }\r
 \r
         private void MainForm_Resize(object sender, EventArgs e)\r
@@ -335,6 +382,7 @@ namespace KancolleSniffer
         {\r
             if (_configDialog.ShowDialog(this) == DialogResult.OK)\r
             {\r
+                _config.Save();\r
                 ApplyConfig();\r
                 StopRepeatingTimer(_configDialog.RepeatSettingsChanged);\r
             }\r
@@ -354,11 +402,16 @@ namespace KancolleSniffer
             foreach (var control in new Control[]\r
             {\r
                 this, _listForm, labelLogin, linkLabelGuide,\r
-                _configDialog, contextMenuStripMain, _errorDialog\r
+                _configDialog, _configDialog.NotificationConfigDialog,\r
+                contextMenuStripMain, _errorDialog\r
             })\r
             {\r
                 control.Font = new Font(control.Font.FontFamily, control.Font.Size * _config.Zoom / 100);\r
             }\r
+            foreach (var toolTip in new[]{_toolTip, _toolTipQuest, _tooltipCopy})\r
+            {\r
+                toolTip.Font = new Font(toolTip.Font.FontFamily, toolTip.Font.Size * _config.Zoom / 100);\r
+            }\r
             ShipLabel.LatinFont = new Font("Tahoma", 8f * _config.Zoom / 100);\r
             var cur = CurrentAutoScaleDimensions;\r
             ShipLabel.ScaleFactor = new SizeF(ShipLabel.ScaleFactor.Width * cur.Width / prev.Width,\r
@@ -383,8 +436,6 @@ namespace KancolleSniffer
             _sniffer.Achievement.ResetHours = _config.ResetHours;\r
             labelAkashiRepair.Visible = labelAkashiRepairTimer.Visible =\r
                 labelPresetAkashiTimer.Visible = _config.UsePresetAkashi;\r
-            if (_config.KancolleDb.On)\r
-                _kancolleDb.Start(_config.KancolleDb.Token);\r
         }\r
 \r
         public void ApplyDebugLogSetting()\r
@@ -428,7 +479,7 @@ namespace KancolleSniffer
                 catch (Exception ex)\r
                 {\r
                     if (_errorDialog.ShowDialog(this, "エラーが発生しました。", ex.ToString()) == DialogResult.Abort)\r
-                        Application.Exit();\r
+                        Exit();\r
                 }\r
             }\r
             if (_playLog == null || _configDialog.Visible)\r
@@ -485,7 +536,7 @@ namespace KancolleSniffer
             if (ac >= 10000)\r
                 ac = 9999;\r
             labelAchievement.Text = ac >= 1000 ? ((int)ac).ToString("D") : ac.ToString("F1");\r
-            toolTipAchievement.SetToolTip(labelAchievement,\r
+            _toolTip.SetToolTip(labelAchievement,\r
                 "今月 " + _sniffer.Achievement.ValueOfMonth.ToString("F1") + "\n" +\r
                 "EO " + _sniffer.ExMap.Achievement);\r
             UpdateMaterialHistry();\r
@@ -552,6 +603,7 @@ namespace KancolleSniffer
 \r
         private void UpdateShipInfo()\r
         {\r
+            SetCurrentFleet();\r
             UpdatePanelShipInfo();\r
             NotifyDamagedShip();\r
             UpdateChargeInfo();\r
@@ -560,19 +612,43 @@ namespace KancolleSniffer
                 _listForm.UpdateList();\r
         }\r
 \r
+        private void SetCurrentFleet()\r
+        {\r
+            var inSortie = _sniffer.InSortie;\r
+            if (_inSortie || !inSortie.Any(x => x))\r
+            {\r
+                _inSortie = inSortie.Any(x => x);\r
+                return;\r
+            }\r
+            _inSortie = true;\r
+            if (inSortie[0] && inSortie[1])\r
+            {\r
+                _combinedFleet = true;\r
+                _currentFleet = 0;\r
+            }\r
+            else\r
+            {\r
+                _combinedFleet = false;\r
+                _currentFleet = Array.FindIndex(inSortie, x => x);\r
+            }\r
+        }\r
+\r
         private void UpdatePanelShipInfo()\r
         {\r
             var statuses = _sniffer.GetShipStatuses(_currentFleet);\r
             panel7Ships.Visible = statuses.Length == 7;\r
-            _shipLabels.SetShipLabels(statuses);\r
+            _mainLabels.SetShipLabels(statuses);\r
             if (_sniffer.CombinedFleetType == 0)\r
                 _combinedFleet = false;\r
             labelFleet1.Text = _combinedFleet ? "連合" : "第一";\r
             panelCombinedFleet.Visible = _combinedFleet;\r
             if (_combinedFleet)\r
-                _shipLabels.SetCombinedShipLabels(_sniffer.GetShipStatuses(0), _sniffer.GetShipStatuses(1));\r
+                _mainLabels.SetCombinedShipLabels(_sniffer.GetShipStatuses(0), _sniffer.GetShipStatuses(1));\r
+            for (var i = 0; i < _labelCheckFleets.Length; i++)\r
+                _labelCheckFleets[i].Visible = _currentFleet == i;\r
             UpdateAkashiTimer();\r
-            UpdateFighterPower(_combinedFleet);\r
+            var battle = _sniffer.Battle;\r
+            UpdateFighterPower(_combinedFleet && (battle.BattleState == BattleState.None || battle.EnemyIsCombined));\r
             UpdateLoS();\r
             UpdateCondTimers();\r
         }\r
@@ -596,8 +672,8 @@ namespace KancolleSniffer
                 : _sniffer.GetContactTriggerRate(_currentFleet);\r
             var text = "制空: " + (fp[0] == fp[1] ? $"{fp[0]}" : $"{fp[0]}~{fp[1]}") +\r
                        $" 触接: {cr * 100:f1}";\r
-            toolTipFighterPower.SetToolTip(labelFighterPower, text);\r
-            toolTipFighterPower.SetToolTip(labelFighterPowerCaption, text);\r
+            _toolTip.SetToolTip(labelFighterPower, text);\r
+            _toolTip.SetToolTip(labelFighterPowerCaption, text);\r
         }\r
 \r
         private void UpdateLoS()\r
@@ -605,8 +681,8 @@ namespace KancolleSniffer
             labelLoS.Text = RoundDown(_sniffer.GetFleetLineOfSights(_currentFleet, 1)).ToString("F1");\r
             var text = $"係数3: {RoundDown(_sniffer.GetFleetLineOfSights(_currentFleet, 3)):F1}\r\n" +\r
                        $"係数4: {RoundDown(_sniffer.GetFleetLineOfSights(_currentFleet, 4)):F1}";\r
-            toolTipLoS.SetToolTip(labelLoS, text);\r
-            toolTipLoS.SetToolTip(labelLoSCaption, text);\r
+            _toolTip.SetToolTip(labelLoS, text);\r
+            _toolTip.SetToolTip(labelLoSCaption, text);\r
         }\r
 \r
         private double RoundDown(double number)\r
@@ -647,8 +723,8 @@ namespace KancolleSniffer
             if (power.AirCombat != power.Interception)\r
             {\r
                 var text = "防空: " + power.Interception + power.UnknownMark;\r
-                toolTipFighterPower.SetToolTip(labelEnemyFighterPower, text);\r
-                toolTipFighterPower.SetToolTip(labelEnemyFighterPowerCaption, text);\r
+                _toolTip.SetToolTip(labelEnemyFighterPower, text);\r
+                _toolTip.SetToolTip(labelEnemyFighterPowerCaption, text);\r
             }\r
             UpdateFighterPower(_sniffer.CombinedFleetType > 0 && battle.EnemyIsCombined);\r
             labelFighterPower.ForeColor = new[]\r
@@ -682,7 +758,7 @@ namespace KancolleSniffer
 \r
         private void UpdateNDocLabels()\r
         {\r
-            _shipLabels.SetNDockLabels(_sniffer.NDock);\r
+            _mainLabels.SetNDockLabels(_sniffer.NDock);\r
         }\r
 \r
 \r
@@ -718,7 +794,7 @@ namespace KancolleSniffer
             for (var i = 0; i < _sniffer.NDock.Length; i++)\r
             {\r
                 var entry = _sniffer.NDock[i];\r
-                _shipLabels.SetNDockTimer(i, entry.Timer, _now, (_config.ShowEndTime & TimerKind.NDock) != 0);\r
+                _mainLabels.SetNDockTimer(i, entry.Timer, _now, (_config.ShowEndTime & TimerKind.NDock) != 0);\r
             }\r
             var kdock = new[] {labelConstruct1, labelConstruct2, labelConstruct3, labelConstruct4};\r
             for (var i = 0; i < kdock.Length; i++)\r
@@ -832,7 +908,7 @@ namespace KancolleSniffer
             if (_config.UsePresetAkashi)\r
                 UpdatePresetAkashiTimer();\r
             var statuses = _sniffer.GetShipStatuses(_currentFleet);\r
-            _shipLabels.SetAkashiTimer(statuses,\r
+            _mainLabels.SetAkashiTimer(statuses,\r
                 _sniffer.AkashiTimer.GetTimers(_currentFleet));\r
         }\r
 \r
@@ -906,7 +982,9 @@ namespace KancolleSniffer
 \r
         private void SetPreNotification(string key, int fleet, string subject)\r
         {\r
-            _notificationManager.Enqueue(key, fleet, subject, 0, true);\r
+            var spec = _config.Notifications[_notificationManager.KeyToName(key)];\r
+            if ((spec.Flags & NotificationType.Preliminary) != 0)\r
+                _notificationManager.Enqueue(key, fleet, subject, 0, true);\r
         }\r
 \r
         private void UpdateRepairList()\r
@@ -937,6 +1015,7 @@ namespace KancolleSniffer
                     category[i].BackColor = quests[i].Color;\r
                     name[i].Text = quests[i].Name;\r
                     progress[i].Text = $"{quests[i].Progress:D}%";\r
+                    _toolTipQuest.SetToolTip(name[i], quests[i].ToToolTip());\r
                     var c = quests[i].Count;\r
                     if (c.Id == 0)\r
                     {\r
@@ -953,6 +1032,7 @@ namespace KancolleSniffer
                 {\r
                     category[i].BackColor = DefaultBackColor;\r
                     name[i].Text = count[i].Text = progress[i].Text = "";\r
+                    _toolTipQuest.SetToolTip(name[i], "");\r
                     _toolTip.SetToolTip(count[i], "");\r
                 }\r
             }\r
@@ -1046,9 +1126,6 @@ namespace KancolleSniffer
             }\r
             _combinedFleet = false;\r
             _currentFleet = fleet;\r
-            foreach (var label in _labelCheckFleets)\r
-                label.Visible = false;\r
-            _labelCheckFleets[fleet].Visible = true;\r
             UpdatePanelShipInfo();\r
         }\r
 \r
@@ -1147,6 +1224,37 @@ namespace KancolleSniffer
             Process.Start("http://localhost:" + _config.Proxy.Listen + "/");\r
         }\r
 \r
+        private void labelClearQuest_Click(object sender, EventArgs e)\r
+        {\r
+            _sniffer.ClearQuests();\r
+            UpdateQuestList();\r
+        }\r
+\r
+        private void labelClearQuest_MouseDown(object sender, MouseEventArgs e)\r
+        {\r
+            labelClearQuest.BackColor = _activeButtonColor;\r
+        }\r
+\r
+        private void labelClearQuest_MouseUp(object sender, MouseEventArgs e)\r
+        {\r
+            labelClearQuest.BackColor = DefaultBackColor;\r
+        }\r
+\r
+        private void labelQuest_DoubleClick(object sender, EventArgs e)\r
+        {\r
+            var label = (Label)sender;\r
+            if (string.IsNullOrEmpty(label.Text))\r
+                return;\r
+            Clipboard.SetText(label.Text);\r
+            _tooltipCopy.Active = true;\r
+            _tooltipCopy.Show("コピーしました。", label);\r
+            Task.Run(async () =>\r
+            {\r
+                await Task.Delay(1000);\r
+                _tooltipCopy.Active = false;\r
+            });\r
+        }\r
+\r
         private void CaptureToolStripMenuItem_Click(object sender, EventArgs e)\r
         {\r
             try\r
@@ -1157,6 +1265,9 @@ namespace KancolleSniffer
             catch (FileNotFoundException)\r
             {\r
             }\r
+            catch (Win32Exception)\r
+            {\r
+            }\r
         }\r
     }\r
 }
\ No newline at end of file