}\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
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
}\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
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
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
// 一隻分のデータしか来ないことがあるので艦娘数を数えない\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
}\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
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
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
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
{\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
}\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
\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