using System.Threading;\r
using System.Threading.Tasks;\r
using System.Windows.Forms;\r
+using DynaJson;\r
using KancolleSniffer.Log;\r
using KancolleSniffer.Model;\r
using KancolleSniffer.Net;\r
using KancolleSniffer.View;\r
using Microsoft.CSharp.RuntimeBinder;\r
using static System.Math;\r
+using Clipboard = KancolleSniffer.Util.Clipboard;\r
using Timer = System.Windows.Forms.Timer;\r
\r
namespace KancolleSniffer\r
private readonly ResizableToolTip _tooltipCopy = new ResizableToolTip {ShowAlways = false, AutomaticDelay = 0};\r
private int _currentFleet;\r
private bool _combinedFleet;\r
- private MainFormLabels _mainLabels;\r
+ private readonly MainShipLabels _mainLabels = new MainShipLabels();\r
private NumberAndHistory _numberAndHistory;\r
- private readonly ListForm _listForm;\r
+ private readonly ListFormGroup _listFormGroup;\r
+\r
private readonly NotificationManager _notificationManager;\r
private bool _started;\r
private bool _timerEnabled;\r
HttpProxy.AfterSessionComplete += HttpProxy_AfterSessionComplete;\r
Config.Load();\r
_configDialog = new ConfigDialog(this);\r
- _listForm = new ListForm(this);\r
+ _listFormGroup = new ListFormGroup(this);\r
_notificationManager = new NotificationManager(Alarm);\r
SetupView(_notificationManager);\r
_proxyManager = new ProxyManager(this);\r
SetupFleetClick();\r
CreateMainLabels();\r
CreateNumberAndHistory(manager);\r
- labelPresetAkashiTimer.BackColor = ShipLabel.ColumnColors[1];\r
+ labelPresetAkashiTimer.BackColor = CustomColors.ColumnColors.Bright;\r
+ SetupQuestPanel();\r
panelRepairList.CreateLabels(panelRepairList_Click);\r
- questPanel.NameLabelDoubleClick += labelQuest_DoubleClick;\r
+ ndockPanel.SetClickHandler(labelNDock_Click);\r
+ missionPanel.SetClickHandler(labelMission_Click);\r
PerformZoom();\r
- _mainLabels.AdjustAkashiTimers();\r
}\r
\r
private void SetScaleFactorOfDpiScaling()\r
{\r
var autoScaleDimensions = new SizeF(6f, 12f); // AutoScaleDimensionの初期値\r
- ShipLabel.ScaleFactor = new SizeF(CurrentAutoScaleDimensions.Width / autoScaleDimensions.Width,\r
+ Scaler.Factor = new SizeF(CurrentAutoScaleDimensions.Width / autoScaleDimensions.Width,\r
CurrentAutoScaleDimensions.Height / autoScaleDimensions.Height);\r
}\r
\r
+ private void SetupQuestPanel()\r
+ {\r
+ int prevHeight = questPanel.Height;\r
+ questPanel.CreateLabels(Config.QuestLines, labelQuest_DoubleClick);\r
+ Height += questPanel.Height - prevHeight;\r
+ }\r
+\r
private void CreateMainLabels()\r
{\r
- _mainLabels = new MainFormLabels(new MainFormPanels\r
+ _mainLabels.CreateAllShipLabels(new MainShipPanels\r
{\r
PanelShipInfo = panelShipInfo,\r
Panel7Ships = panel7Ships,\r
- PanelCombinedFleet = panelCombinedFleet,\r
- PanelNDock = panelDock\r
- });\r
- _mainLabels.CreateAllShipLabels(ShowShipOnShipList);\r
- _mainLabels.CreateNDockLabels(labelNDock_Click);\r
+ PanelCombinedFleet = panelCombinedFleet\r
+ }, ShowShipOnShipList);\r
}\r
\r
private void CreateNumberAndHistory(NotificationManager manager)\r
{\r
try\r
{\r
- UpdateInfo(Sniffer.Sniff(url, request, JsonParser.Parse(response)));\r
+ UpdateInfo(Sniffer.Sniff(url, request, JsonObject.Parse(response)));\r
_errorLog.CheckBattleApi(url, request, response);\r
}\r
\r
if (Config.ShowHpInPercent)\r
_mainLabels.ToggleHpPercent();\r
if (Config.ShipList.Visible)\r
- _listForm.Show();\r
+ _listFormGroup.Show();\r
ApplyConfig();\r
ApplyDebugLogSetting();\r
ApplyLogSetting();\r
{\r
if (!Config.ExitSilently)\r
{\r
- using (var dialog = new ConfirmDialog())\r
+ using var dialog = new ConfirmDialog();\r
+ if (dialog.ShowDialog(this) != DialogResult.Yes)\r
{\r
- if (dialog.ShowDialog(this) != DialogResult.Yes)\r
- {\r
- e.Cancel = true;\r
- return;\r
- }\r
+ e.Cancel = true;\r
+ return;\r
}\r
}\r
- _listForm.Close();\r
+ _listFormGroup.Close();\r
Sniffer.FlashLog();\r
Config.Location = (WindowState == FormWindowState.Normal ? Bounds : RestoreBounds).Location;\r
Config.ShowHpInPercent = _mainLabels.ShowHpInPercent;\r
\r
private void MainForm_Resize(object sender, EventArgs e)\r
{\r
- if (_listForm == null) // DPIが100%でないときにInitializeComponentから呼ばれるので\r
+ if (_listFormGroup == null) // DPIが100%でないときにInitializeComponentから呼ばれるので\r
return;\r
SuppressActivate.Start();\r
if (WindowState == FormWindowState.Minimized)\r
{\r
- _listForm.WindowState = FormWindowState.Minimized;\r
if (Config.HideOnMinimized)\r
- _listForm.ShowInTaskbar = ShowInTaskbar = false;\r
- }\r
- else if (_listForm.WindowState == FormWindowState.Minimized)\r
- {\r
- DoPaint();\r
- _listForm.ShowInTaskbar = true;\r
- _listForm.WindowState = FormWindowState.Normal;\r
+ ShowInTaskbar = false;\r
}\r
- }\r
-\r
- private void DoPaint()\r
- {\r
- Application.DoEvents();\r
+ _listFormGroup.Main.ChangeWindowState(WindowState);\r
}\r
\r
public TimeOutChecker SuppressActivate = new TimeOutChecker();\r
{\r
if (SuppressActivate.Check())\r
return;\r
- if (WindowState == FormWindowState.Minimized)\r
- return;\r
- _listForm.Owner = null;\r
- Owner = _listForm;\r
+ if (NeedRaise)\r
+ RaiseBothWindows();\r
+ }\r
+\r
+ private bool NeedRaise => _listFormGroup.Visible && WindowState != FormWindowState.Minimized;\r
+\r
+ private void RaiseBothWindows()\r
+ {\r
+ _listFormGroup.Main.Owner = null;\r
+ Owner = _listFormGroup.Main;\r
BringToFront();\r
Owner = null;\r
}\r
{\r
ShowInTaskbar = true;\r
WindowState = FormWindowState.Normal;\r
- TopMost = _listForm.TopMost = Config.TopMost; // 最前面に表示されなくなることがあるのを回避する\r
+ TopMost = _listFormGroup.TopMost = Config.TopMost; // 最前面に表示されなくなることがあるのを回避する\r
}\r
\r
private void ExitToolStripMenuItem_Click(object sender, EventArgs e)\r
private void PerformZoom()\r
{\r
if (Config.Zoom == 100)\r
+ {\r
+ ShipLabel.Name.BaseFont = Font;\r
+ ShipLabel.Name.LatinFont = LatinFont();\r
return;\r
+ }\r
var prev = CurrentAutoScaleDimensions;\r
foreach (var control in new Control[]\r
{\r
- this, _listForm, labelLogin, linkLabelGuide,\r
+ this, labelLogin, linkLabelGuide,\r
_configDialog, _configDialog.NotificationConfigDialog,\r
contextMenuStripMain, _errorDialog\r
})\r
{\r
- control.Font = new Font(control.Font.FontFamily, control.Font.Size * Config.Zoom / 100);\r
+ control.Font = ZoomFont(control.Font);\r
}\r
+ _listFormGroup.Font = ZoomFont(_listFormGroup.Font);\r
foreach (var toolTip in new[] {_toolTip, _tooltipCopy})\r
{\r
- toolTip.Font = new Font(toolTip.Font.FontFamily, toolTip.Font.Size * Config.Zoom / 100);\r
+ toolTip.Font = ZoomFont(toolTip.Font);\r
}\r
- ShipLabel.LatinFont = new Font("Tahoma", 8f * Config.Zoom / 100);\r
+ ShipLabel.Name.BaseFont = Font;\r
+ ShipLabel.Name.LatinFont = LatinFont();\r
var cur = CurrentAutoScaleDimensions;\r
- ShipLabel.ScaleFactor = new SizeF(ShipLabel.ScaleFactor.Width * cur.Width / prev.Width,\r
- ShipLabel.ScaleFactor.Height * cur.Height / prev.Height);\r
+ Scaler.Factor = Scaler.Scale(cur.Width / prev.Width, cur.Height / prev.Height);\r
+ }\r
+\r
+ private Font ZoomFont(Font font)\r
+ {\r
+ return new Font(font.FontFamily, font.Size * Config.Zoom / 100);\r
+ }\r
+\r
+ private Font LatinFont()\r
+ {\r
+ return new Font("Tahoma", 8f * Config.Zoom / 100);\r
}\r
\r
private void RestoreLocation()\r
private void ApplyConfig()\r
{\r
if (TopMost != Config.TopMost)\r
- TopMost = _listForm.TopMost = Config.TopMost;\r
+ TopMost = _listFormGroup.TopMost = Config.TopMost;\r
Sniffer.ShipCounter.Margin = Config.MarginShips;\r
_numberAndHistory.UpdateNumOfShips();\r
Sniffer.ItemCounter.Margin = Config.MarginEquips;\r
Sniffer.Achievement.ResetHours = Config.ResetHours;\r
labelAkashiRepair.Visible = labelAkashiRepairTimer.Visible =\r
labelPresetAkashiTimer.Visible = Config.UsePresetAkashi;\r
+ Sniffer.WarnBadDamageWithDameCon = Config.WarnBadDamageWithDameCon;\r
}\r
\r
public void ApplyDebugLogSetting()\r
\r
private void ShowShipOnShipList(object sender, EventArgs ev)\r
{\r
- if (!_listForm.Visible)\r
+ if (!_listFormGroup.Visible)\r
return;\r
var idx = (int)((Control)sender).Tag;\r
var ship = (_combinedFleet\r
? Sniffer.Fleets[0].Ships.Concat(Sniffer.Fleets[1].Ships).ToArray()\r
: Sniffer.Fleets[_currentFleet].Ships)[idx];\r
if (!ship.Empty)\r
- _listForm.ShowShip(ship.Id);\r
+ _listFormGroup.ShowShip(ship.Id);\r
}\r
\r
\r
private void UpdateItemInfo()\r
{\r
_numberAndHistory.Update();\r
- if (_listForm.Visible)\r
- _listForm.UpdateList();\r
+ if (_listFormGroup.Visible)\r
+ _listFormGroup.UpdateList();\r
}\r
\r
private void UpdateShipInfo()\r
UpdateChargeInfo();\r
UpdateRepairList();\r
UpdateMissionLabels();\r
- if (_listForm.Visible)\r
- _listForm.UpdateList();\r
+ if (_listFormGroup.Visible)\r
+ _listFormGroup.UpdateList();\r
}\r
\r
private bool _inSortie;\r
\r
private void SetCurrentFleet()\r
{\r
- var states = Sniffer.Fleets.Select(fleet => fleet.State).ToArray();\r
- var inSortie = states.Any(state => state >= FleetState.Sortie);\r
- if (_inSortie || !inSortie)\r
+ var inSortie = Sniffer.InSortie;\r
+ if (_inSortie || inSortie == -1)\r
{\r
- _inSortie = inSortie;\r
+ _inSortie = inSortie != -1;\r
return;\r
}\r
_inSortie = true;\r
- if (states[0] == FleetState.Sortie && states[1] == FleetState.Sortie)\r
+ if (inSortie == 10)\r
{\r
_combinedFleet = true;\r
_currentFleet = 0;\r
else\r
{\r
_combinedFleet = false;\r
- _currentFleet = Array.FindIndex(states, state => state >= FleetState.Sortie);\r
+ _currentFleet = inSortie;\r
}\r
}\r
\r
\r
private void NotifyDamagedShip()\r
{\r
+ _notificationManager.StopRepeat("大破警告");\r
if (!Sniffer.BadlyDamagedShips.Any())\r
return;\r
- _notificationManager.StopRepeat("大破警告");\r
SetNotification("大破警告", string.Join(" ", Sniffer.BadlyDamagedShips));\r
_notificationManager.Flash();\r
}\r
\r
- public void UpdateFighterPower(bool combined)\r
+ private void UpdateFighterPower(bool combined)\r
{\r
var fleets = Sniffer.Fleets;\r
var fp = combined\r
- ? fleets[0].FighterPower.Zip(fleets[1].FighterPower, (a, b) => a + b).ToArray()\r
+ ? fleets[0].FighterPower + fleets[1].FighterPower\r
: fleets[_currentFleet].FighterPower;\r
- labelFighterPower.Text = fp[0].ToString("D");\r
+ labelFighterPower.Text = fp.Min.ToString("D");\r
var cr = combined\r
? fleets[0].ContactTriggerRate + fleets[1].ContactTriggerRate\r
: fleets[_currentFleet].ContactTriggerRate;\r
- var text = "制空: " + (fp[0] == fp[1] ? $"{fp[0]}" : $"{fp[0]}~{fp[1]}") +\r
+ var text = "制空: " + (fp.Diff ? fp.RangeString : fp.Min.ToString()) +\r
$" 触接: {cr * 100:f1}";\r
_toolTip.SetToolTip(labelFighterPower, text);\r
_toolTip.SetToolTip(labelFighterPowerCaption, text);\r
private void UpdateBattleInfo()\r
{\r
ResetBattleInfo();\r
- _listForm.UpdateBattleResult();\r
- _listForm.UpdateAirBattleResult();\r
+ _listFormGroup.UpdateBattleResult();\r
+ _listFormGroup.UpdateAirBattleResult();\r
if (Sniffer.Battle.BattleState == BattleState.None)\r
return;\r
panelBattleInfo.BringToFront();\r
\r
private void UpdateCellInfo()\r
{\r
- _listForm.UpdateCellInfo();\r
+ _listFormGroup.UpdateCellInfo();\r
}\r
\r
private void ResetBattleInfo()\r
labelFormation.Text = "";\r
labelEnemyFighterPower.Text = "";\r
labelFighterPower.ForeColor = DefaultForeColor;\r
+ labelFighterPowerCaption.Text = "制空";\r
labelResultRank.Text = "判定";\r
panelBattleInfo.Visible = Sniffer.Battle.BattleState != BattleState.None;\r
}\r
\r
private void UpdateBattleFighterPower()\r
{\r
+ UpdateEnemyFighterPower();\r
var battle = Sniffer.Battle;\r
- var power = battle.EnemyFighterPower;\r
- labelEnemyFighterPower.Text = power.AirCombat + power.UnknownMark;\r
- if (power.AirCombat != power.Interception)\r
+ labelFighterPower.ForeColor = AirControlLevelColor(battle);\r
+ labelFighterPowerCaption.Text = AirControlLevelString(battle);\r
+ if (battle.BattleState == BattleState.AirRaid)\r
{\r
- var text = "防空: " + power.Interception + power.UnknownMark;\r
- _toolTip.SetToolTip(labelEnemyFighterPower, text);\r
- _toolTip.SetToolTip(labelEnemyFighterPowerCaption, text);\r
+ UpdateAirRaidFighterPower();\r
}\r
else\r
{\r
- _toolTip.SetToolTip(labelEnemyFighterPower, "");\r
- _toolTip.SetToolTip(labelEnemyFighterPowerCaption, "");\r
+ UpdateFighterPower(Sniffer.IsCombinedFleet && battle.EnemyIsCombined);\r
}\r
- UpdateFighterPower(Sniffer.IsCombinedFleet && battle.EnemyIsCombined);\r
- labelFighterPower.ForeColor = new[]\r
+ }\r
+\r
+ private void UpdateEnemyFighterPower()\r
+ {\r
+ var fp = Sniffer.Battle.EnemyFighterPower;\r
+ labelEnemyFighterPower.Text = fp.AirCombat + fp.UnknownMark;\r
+ var toolTip = fp.AirCombat == fp.Interception ? "" : "防空: " + fp.Interception + fp.UnknownMark;\r
+ _toolTip.SetToolTip(labelEnemyFighterPower, toolTip);\r
+ _toolTip.SetToolTip(labelEnemyFighterPowerCaption, toolTip);\r
+ }\r
+\r
+ private void UpdateAirRaidFighterPower()\r
+ {\r
+ var fp = Sniffer.Battle.FighterPower;\r
+ labelFighterPower.Text = fp.Min.ToString();\r
+ var toolTop = fp.Diff ? fp.RangeString : "";\r
+ _toolTip.SetToolTip(labelFighterPower, toolTop);\r
+ _toolTip.SetToolTip(labelFighterPowerCaption, toolTop);\r
+ }\r
+\r
+ private static Color AirControlLevelColor(BattleInfo battle)\r
+ {\r
+ return new[]\r
{DefaultForeColor, DefaultForeColor, CUDColors.Blue, CUDColors.Green, CUDColors.Orange, CUDColors.Red}[\r
- battle.AirControlLevel + 1];\r
+ battle.BattleState == BattleState.Night ? 0 : battle.AirControlLevel + 1];\r
+ }\r
+\r
+ private static string AirControlLevelString(BattleInfo battle)\r
+ {\r
+ return new[] {"制空", "拮抗", "確保", "優勢", "劣勢", "喪失"}[\r
+ battle.BattleState == BattleState.Night ? 0 : battle.AirControlLevel + 1];\r
}\r
\r
private void ShowResultRank()\r
var stat = Sniffer.Fleets[i].ChargeStatus;\r
fuelSq[i].ImageIndex = stat.Fuel;\r
bullSq[i].ImageIndex = stat.Bull;\r
+ var text = stat.Empty ? "" : $"燃{stat.FuelRatio * 100:f1}% 弾{stat.BullRatio * 100:f1}%";\r
+ _toolTip.SetToolTip(fuelSq[i], text);\r
+ _toolTip.SetToolTip(bullSq[i], text);\r
}\r
}\r
\r
private void UpdateNDocLabels()\r
{\r
- _mainLabels.SetNDockLabels(Sniffer.NDock);\r
+ ndockPanel.SetName(Sniffer.NDock);\r
SetNDockLabel();\r
}\r
\r
\r
private void UpdateMissionLabels()\r
{\r
- var nameLabels = new[] {labelMissionName1, labelMissionName2, labelMissionName3};\r
- var paramsLabels = new[] {labelMissionParams1, labelMissionParams2, labelMissionParams3};\r
- var names = Sniffer.Missions.Select(mission => mission.Name).ToArray();\r
- for (var i = 0; i < ShipInfo.FleetCount - 1; i++)\r
- {\r
- paramsLabels[i].Visible = false;\r
- if (string.IsNullOrEmpty(names[i]))\r
- {\r
- paramsLabels[i].Text = GenerateFleetParamsForMission(i + 1);\r
- paramsLabels[i].Visible = true;\r
- }\r
- nameLabels[i].Text = names[i];\r
- }\r
+ missionPanel.Update(Sniffer);\r
SetMissionLabel();\r
}\r
\r
labelMission.Text = (Config.ShowEndTime & TimerKind.Mission) != 0 ? "遠征終了" : "遠征";\r
}\r
\r
- private string GenerateFleetParamsForMission(int fleetNumber)\r
- {\r
- var result = new List<string>();\r
- var fleet = Sniffer.Fleets[fleetNumber];\r
- var kira = fleet.Ships.Count(ship => ship.Cond > 49);\r
- var plus = fleet.Ships[0].Cond > 49;\r
- if (kira > 0)\r
- result.Add($"キラ{kira}{(plus ? "+" : "")}");\r
- var drums = fleet.Ships.SelectMany(ship => ship.Slot).Count(item => item.Spec.IsDrum);\r
- var drumShips = fleet.Ships.Count(ship => ship.Slot.Any(item => item.Spec.IsDrum));\r
- if (drums > 0)\r
- result.Add($"ド{drums}({drumShips}隻)");\r
- if (fleet.DaihatsuBonus > 0)\r
- result.Add($"ダ{fleet.DaihatsuBonus * 100:f1}%");\r
- return string.Join(" ", result);\r
- }\r
-\r
private void labelMission_Click(object sender, EventArgs e)\r
{\r
Config.ShowEndTime ^= TimerKind.Mission;\r
\r
private void UpdateTimers()\r
{\r
- var mission = new[] {labelMission1, labelMission2, labelMission3};\r
- for (var i = 0; i < mission.Length; i++)\r
- {\r
- var entry = Sniffer.Missions[i];\r
- SetTimerColor(mission[i], entry.Timer, _now);\r
- mission[i].Text = entry.Timer.ToString(_now, (Config.ShowEndTime & TimerKind.Mission) != 0);\r
- }\r
- for (var i = 0; i < Sniffer.NDock.Length; i++)\r
- {\r
- var entry = Sniffer.NDock[i];\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
- {\r
- var timer = Sniffer.KDock[i];\r
- SetTimerColor(kdock[i], timer, _now);\r
- kdock[i].Text = timer.ToString(_now);\r
- }\r
+ missionPanel.UpdateTimers(Sniffer, _now, (Config.ShowEndTime & TimerKind.Mission) != 0);\r
+ ndockPanel.UpdateTimers(Sniffer, _now, (Config.ShowEndTime & TimerKind.NDock) != 0);\r
+ kdockPanel.UpdateTimers(Sniffer, _now);\r
UpdateCondTimers();\r
UpdateAkashiTimer();\r
_timerEnabled = true;\r
return;\r
}\r
var span = TimeSpan.FromSeconds(Ceiling((timer - _now).TotalSeconds));\r
- if (span >= TimeSpan.FromMinutes(9))\r
+ if (span >= TimeSpan.FromMinutes(9) && Config.NotifyConditions.Contains(40))\r
{\r
labelCondTimerTitle.Text = "cond40まで";\r
labelCondTimer.Text = (span - TimeSpan.FromMinutes(9)).ToString(@"mm\:ss");\r
private void UpdateQuestList()\r
{\r
questPanel.Update(Sniffer.Quests);\r
+ labelQuestCount.Text = Sniffer.Quests.Length.ToString();\r
+ SetQuestNotification();\r
+ }\r
+\r
+ private void SetQuestNotification()\r
+ {\r
Sniffer.GetQuestNotifications(out var notify, out var stop);\r
foreach (var questName in notify)\r
SetNotification("任務達成", 0, questName);\r
\r
private void ShipListToolStripMenuItem_Click(object sender, EventArgs e)\r
{\r
+ _listFormGroup.ShowOrCreate();\r
+ /*\r
_listForm.UpdateList();\r
_listForm.Show();\r
if (_listForm.WindowState == FormWindowState.Minimized)\r
_listForm.WindowState = FormWindowState.Normal;\r
_listForm.Activate();\r
+ */\r
}\r
\r
private void LogToolStripMenuItem_Click(object sender, EventArgs e)\r