OSDN Git Service

戦闘結果の計算に誤りがあるときにエラーを表示する
authorKazuhiro Fujieda <fujieda@users.osdn.me>
Fri, 24 Nov 2017 11:02:40 +0000 (20:02 +0900)
committerKazuhiro Fujieda <fujieda@users.osdn.me>
Fri, 24 Nov 2017 14:46:08 +0000 (23:46 +0900)
KancolleSniffer.Test/SnifferTest.cs
KancolleSniffer/MainForm.cs
KancolleSniffer/ShipInfo.cs
KancolleSniffer/ShipStatus.cs
KancolleSniffer/Sniffer.cs

index d3caef6..6763244 100644 (file)
@@ -117,6 +117,17 @@ namespace KancolleSniffer.Test
         }\r
 \r
         /// <summary>\r
+        /// 演習のあとのportで戦闘結果の検証を行わない\r
+        /// </summary>\r
+        [TestMethod]\r
+        public void NotVerifyBattleResultAfterPractice()\r
+        {\r
+            var sniffer = new Sniffer();\r
+            SniffLogFile(sniffer, "practice_001");\r
+            PAssert.That(() => sniffer.WrongBattleResult.Length == 0);\r
+        }\r
+\r
+        /// <summary>\r
         /// 出撃時に大破している艦娘がいたら警告する\r
         /// </summary>\r
         [TestMethod]\r
index b2c727f..8e27ebc 100644 (file)
@@ -103,11 +103,21 @@ namespace KancolleSniffer
             ProcessRequestMain(url, request, response);\r
         }\r
 \r
+        private List<string[]> _battleApiLog = new List<string[]>();\r
+\r
         private void ProcessRequestMain(string url, string request, string response)\r
         {\r
             try\r
             {\r
                 UpdateInfo(_sniffer.Sniff(url, request, JsonParser.Parse(response)));\r
+                SaveBattleApi(url, request, response);\r
+                if (_sniffer.WrongBattleResult.Length > 0)\r
+                {\r
+                    if (_errorDialog.ShowDialog(this,\r
+                            "戦闘結果の計算に誤りがあります。",\r
+                            GenerateBattleErrorLog()) == DialogResult.Abort)\r
+                        Application.Exit();\r
+                }\r
             }\r
             catch (RuntimeBinderException e)\r
             {\r
@@ -130,6 +140,28 @@ namespace KancolleSniffer
             }\r
         }\r
 \r
+        private void SaveBattleApi(string url, string request, string response)\r
+        {\r
+            if (_sniffer.Battle.BattleState == BattleState.Day)\r
+                _battleApiLog = new List<string[]> {new[] {url, request, response}};\r
+            if (_sniffer.Battle.BattleState == BattleState.Night || _sniffer.Battle.BattleState == BattleState.Result)\r
+                _battleApiLog.Add(new[] {url, request, response});\r
+        }\r
+\r
+        private string GenerateBattleErrorLog()\r
+        {\r
+            foreach (var logs in _battleApiLog)\r
+                RemoveSensitiveInformation(ref logs[1], ref logs[2]);\r
+            var version = string.Join(".", Application.ProductVersion.Split('.').Take(2));\r
+            var api = string.Join("\r\n", _battleApiLog.Select(logs => string.Join("\r\n", logs)));\r
+            var status = string.Join(" ",\r
+                from pair in _sniffer.WrongBattleResult\r
+                let assumed = pair.Assumed\r
+                let actual = pair.Actual\r
+                select $"[{assumed.Fleet}-{assumed.DeckIndex}] {assumed.Id}: {assumed.NowHp}->{actual.NowHp}");\r
+            return $"{DateTime.Now:g} {version}\r\n{api}\r\n{status}";\r
+        }\r
+\r
         private string GenerateErrorLog(string url, string request, string response, string exception)\r
         {\r
             RemoveSensitiveInformation(ref request, ref response);\r
index c517364..5b0ff5f 100644 (file)
@@ -65,6 +65,21 @@ namespace KancolleSniffer
         private int _hqLevel;\r
         private readonly List<int> _escapedShips = new List<int>();\r
         private int _combinedFleetType;\r
+        private ShipStatus[] _battleResult = new ShipStatus[0];\r
+\r
+        public class ShipStatusPair\r
+        {\r
+            public ShipStatus Assumed { get; set; }\r
+            public ShipStatus Actual { get; set; }\r
+\r
+            public ShipStatusPair(ShipStatus assumed, ShipStatus actual)\r
+            {\r
+                Assumed = assumed;\r
+                Actual = actual;\r
+            }\r
+        }\r
+\r
+        public ShipStatusPair[] WrongBattleResult { get; private set; } = new ShipStatusPair[0];\r
 \r
         public ShipInfo(ItemInfo itemInfo)\r
         {\r
@@ -92,6 +107,7 @@ namespace KancolleSniffer
                 if (json.api_combined_flag())\r
                     _combinedFleetType = (int)json.api_combined_flag;\r
                 _itemInfo.NowShips = ((object[])json.api_ship).Length;\r
+                VerifyBattleResult();\r
             }\r
             else if (json.api_data()) // ship2\r
             {\r
@@ -105,6 +121,7 @@ namespace KancolleSniffer
                 // 一隻分のデータしか来ないことがあるので艦娘数を数えない\r
                 InspectDeck(json.api_deck_data);\r
                 InspectShipData(json.api_ship_data);\r
+                VerifyBattleResult();\r
             }\r
             else if (json.api_ship()) // getshipとpowerup\r
             {\r
@@ -112,6 +129,21 @@ namespace KancolleSniffer
             }\r
         }\r
 \r
+        public void SaveBattleResult()\r
+        {\r
+            _battleResult = _decks.Where((deck, i) =>\r
+                    _inSortie[i] && !GetStatus(deck[0]).Spec.IsRepairShip)\r
+                .SelectMany(deck => deck.Select(GetStatus)).ToArray();\r
+        }\r
+\r
+        private void VerifyBattleResult()\r
+        {\r
+            WrongBattleResult = (from assumed in _battleResult\r
+                let actual = GetStatus(assumed.Id)\r
+                where assumed.NowHp != actual.NowHp select new ShipStatusPair(assumed, actual)).ToArray();\r
+            _battleResult = new ShipStatus[0];\r
+        }\r
+\r
         private void ClearShipInfo()\r
         {\r
             _shipInfo.Clear();\r
@@ -309,7 +341,8 @@ namespace KancolleSniffer
             s.Slot = s.Slot.Select(item => _itemInfo.GetStatus(item.Id)).ToArray();\r
             s.SlotEx = _itemInfo.GetStatus(s.SlotEx.Id);\r
             s.Escaped = _escapedShips.Contains(id);\r
-            s.Fleet = FindFleet(s.Id, out _);\r
+            s.Fleet = FindFleet(s.Id, out var idx);\r
+            s.DeckIndex = idx;\r
             s.CombinedFleetType = s.Fleet < 2 ? _combinedFleetType : 0;\r
             return s;\r
         }\r
@@ -341,7 +374,7 @@ namespace KancolleSniffer
                         select new ChargeStatus(_shipInfo[id]))\r
                     .Aggregate(\r
                         (result, next) =>\r
-                                new ChargeStatus(Max(result.Fuel, next.Fuel), Max(result.Bull, next.Bull)))\r
+                            new ChargeStatus(Max(result.Fuel, next.Fuel), Max(result.Bull, next.Bull)))\r
                 select new ChargeStatus(flag.Fuel != 0 ? flag.Fuel : others.Fuel + 5,\r
                     flag.Bull != 0 ? flag.Bull : others.Bull + 5)).ToArray();\r
 \r
@@ -359,7 +392,7 @@ namespace KancolleSniffer
         public double GetContactTriggerRate(int fleet)\r
             => GetShipStatuses(fleet).Where(ship => !ship.Escaped).SelectMany(ship =>\r
                 ship.Slot.Zip(ship.OnSlot, (slot, onslot) =>\r
-                        slot.Spec.ContactTriggerRate * slot.Spec.LoS * Sqrt(onslot))).Sum();\r
+                    slot.Spec.ContactTriggerRate * slot.Spec.LoS * Sqrt(onslot))).Sum();\r
 \r
         public ShipStatus[] GetRepairList(DockInfo dockInfo)\r
             => (from s in ShipList\r
index 9ee6e1a..f274ac5 100644 (file)
@@ -23,6 +23,7 @@ namespace KancolleSniffer
     {\r
         public int Id { get; set; }\r
         public int Fleet { get; set; }\r
+        public int DeckIndex { get; set; }\r
         public ShipSpec Spec { get; set; }\r
 \r
         public string Name => Spec.Name;\r
index 187a03f..00b4d64 100644 (file)
@@ -321,6 +321,7 @@ namespace KancolleSniffer
             }\r
             if (url.EndsWith("api_req_sortie/battleresult") || url.EndsWith("api_req_combined_battle/battleresult"))\r
             {\r
+                _shipInfo.SaveBattleResult();\r
                 _battleInfo.InspectBattleResult(data);\r
                 _exMapInfo.InspectBattleResult(data);\r
                 _logger.InspectBattleResult(data);\r
@@ -507,6 +508,8 @@ namespace KancolleSniffer
 \r
         public int[] GetDeck(int fleet) => _shipInfo.GetDeck(fleet);\r
 \r
+        public ShipInfo.ShipStatusPair[] WrongBattleResult => _shipInfo.WrongBattleResult;\r
+\r
         public int CombinedFleetType => _shipInfo.CombinedFleetType;\r
 \r
         public ChargeStatus[] ChargeStatuses => _shipInfo.ChargeStatuses;\r