1 // Copyright (C) 2018 Kazuhiro Fujieda <fujieda@users.osdn.me>
\r
3 // Licensed under the Apache License, Version 2.0 (the "License");
\r
4 // you may not use this file except in compliance with the License.
\r
5 // You may obtain a copy of the License at
\r
7 // http://www.apache.org/licenses/LICENSE-2.0
\r
9 // Unless required by applicable law or agreed to in writing, software
\r
10 // distributed under the License is distributed on an "AS IS" BASIS,
\r
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
12 // See the License for the specific language governing permissions and
\r
13 // limitations under the License.
\r
16 using System.Collections.Generic;
\r
18 using KancolleSniffer.Model;
\r
20 namespace KancolleSniffer.Log
\r
22 public class BattleLogger
\r
24 private readonly ItemInfo _itemInfo;
\r
25 private readonly BattleInfo _battleInfo;
\r
26 private readonly Action<string, string, string> _writer;
\r
27 private readonly Dictionary<int, string> _mapName = new Dictionary<int, string>();
\r
28 private readonly CellData _cell = new CellData();
\r
30 public BattleLogger(ItemInfo itemInfo, BattleInfo battleInfo, Action<string, string, string> writer)
\r
32 _itemInfo = itemInfo;
\r
33 _battleInfo = battleInfo;
\r
37 public void InspectMapInfoMaster(dynamic json)
\r
39 foreach (var entry in json)
\r
40 _mapName[(int)entry.api_id] = entry.api_name;
\r
43 private class CellData
\r
52 public void Set(dynamic json)
\r
54 Area = (int)json.api_maparea_id;
\r
55 Map = (int)json.api_mapinfo_no;
\r
56 Cell = json.api_no() ? (int)json.api_no : 0;
\r
57 Boss = (int)json.api_event_id == 5;
\r
58 Id = Area * 10 + Map;
\r
62 public void InspectMapStart(dynamic json)
\r
68 public void InspectMapNext(dynamic json)
\r
71 if (!json.api_destruction_battle())
\r
74 _cell.Start = false;
\r
77 public void InspectBattleResult(dynamic result)
\r
80 _cell.Start = false;
\r
83 private void WriteLog(dynamic result)
\r
85 var log = CreateLog(result);
\r
86 _writer("海戦・ドロップ報告書", log,
\r
87 "日付,海域,経路,ボス,ランク,艦隊行動,味方陣形,敵陣形,敵艦隊,ドロップ艦種,ドロップ艦娘," +
\r
88 "味方艦1,味方艦1HP,味方艦2,味方艦2HP,味方艦3,味方艦3HP,味方艦4,味方艦4HP,味方艦5,味方艦5HP,味方艦6,味方艦6HP," +
\r
89 "敵艦1,敵艦1HP,敵艦2,敵艦2HP,敵艦3,敵艦3HP,敵艦4,敵艦4HP,敵艦5,敵艦5HP,敵艦6,敵艦6HP," +
\r
90 "味方制空値,敵制空値,制空状態,マップ"
\r
94 private string CreateLog(dynamic result)
\r
96 var fShips = GenerateShipList(_battleInfo.Result.Friend, s => $"{s.Name}(Lv{s.Level})");
\r
97 var eShips = GenerateShipList(_battleInfo.Result.Enemy, s => $"{s.Name}");
\r
101 if (_battleInfo.BattleState != BattleState.AirRaid)
\r
104 boss = _cell.Start ? "出撃&ボス" : "ボス";
\r
106 var dropType = CreateDropType(result);
\r
107 var dropName = CreateDropName(result);
\r
108 var enemyName = result?.api_enemy_info.api_deck_name ?? "";
\r
109 var rank = result?.api_win_rank ?? _battleInfo.ResultRank;
\r
110 var fp = _battleInfo.FighterPower;
\r
111 var fPower = fp.Diff ? fp.RangeString : fp.Min.ToString();
\r
112 return string.Join(",",
\r
113 _mapName[_cell.Id],
\r
116 BattleFormationName(_battleInfo.Formation[2]),
\r
117 FormationName(_battleInfo.Formation[0]),
\r
118 FormationName(_battleInfo.Formation[1]),
\r
120 dropType, dropName,
\r
121 string.Join(",", fShips),
\r
122 string.Join(",", eShips),
\r
123 fPower, _battleInfo.EnemyFighterPower.AirCombat + _battleInfo.EnemyFighterPower.UnknownMark,
\r
124 AirControlLevelName(_battleInfo.AirControlLevel),
\r
125 $"{_cell.Area}-{_cell.Map}");
\r
128 private static string CreateDropType(dynamic result)
\r
130 if (result == null)
\r
132 var type = result.api_get_ship() ? (string)result.api_get_ship.api_ship_type : "";
\r
133 if (!result.api_get_useitem())
\r
135 return type == "" ? "アイテム" : type + "+アイテム";
\r
138 private string CreateDropName(dynamic result)
\r
140 if (result == null)
\r
142 var name = result.api_get_ship() ? (string)result.api_get_ship.api_ship_name : "";
\r
143 if (!result.api_get_useitem())
\r
145 var itemName = _itemInfo.GetUseItemName((int)result.api_get_useitem.api_useitem_id);
\r
146 return name == "" ? itemName : name + "+" + itemName;
\r
149 private static IEnumerable<string> GenerateShipList(BattleInfo.BattleResult.Combined fleet,
\r
150 Func<ShipStatus, string> toName)
\r
152 fleet = FillEmpty(fleet);
\r
153 if (fleet.Guard.Length > 0)
\r
155 return fleet.Main.Zip(fleet.Guard, (main, guard) =>
\r
157 if (main.Empty && guard.Empty)
\r
163 name = toName(main);
\r
164 hp = $"{main.NowHp}/{main.MaxHp}";
\r
170 name += toName(guard);
\r
171 hp += $"{guard.NowHp}/{guard.MaxHp}";
\r
173 return name + "," + hp;
\r
176 var ships = fleet.Main;
\r
177 if (fleet.Main.Length > 6)
\r
179 var result = new List<string>();
\r
180 for (var i = 0; i < 12 - ships.Length; i++)
\r
182 var ship = fleet.Main[i];
\r
183 result.Add($"{toName(ship)},{ship.NowHp}/{ship.MaxHp}");
\r
185 for (var i = 0; i < ships.Length - 6; i++)
\r
187 var s1 = ships[12 - ships.Length + i];
\r
188 var s2 = ships[6 + i];
\r
190 $"{toName(s1)}・{toName(s2)}," +
\r
191 $"{s1.NowHp}/{s1.MaxHp}・{s2.NowHp}/{s2.MaxHp}");
\r
195 return ships.Select(ship => ship.Empty ? "," : $"{toName(ship)},{ship.NowHp}/{ship.MaxHp}");
\r
198 private static BattleInfo.BattleResult.Combined FillEmpty(BattleInfo.BattleResult.Combined fleet)
\r
200 return new BattleInfo.BattleResult.Combined
\r
202 Main = FillEmpty(fleet.Main),
\r
203 Guard = FillEmpty(fleet.Guard)
\r
207 private static readonly ShipStatus[] Padding =
\r
208 Enumerable.Repeat(new ShipStatus(), ShipInfo.MemberCount).ToArray();
\r
210 private static ShipStatus[] FillEmpty(ShipStatus[] ships)
\r
212 return ships.Length > ShipInfo.MemberCount || ships.Length == 0
\r
214 : ships.Concat(Padding).Take(ShipInfo.MemberCount).ToArray();
\r
217 private string FormationName(dynamic f)
\r
219 if (f is string) // 連合艦隊のときは文字列
\r
248 private static string BattleFormationName(int f)
\r
265 private string AirControlLevelName(int level)
\r