2 using System.Collections.Generic;
\r
7 using System.Windows.Forms;
\r
9 namespace KancolleSniffer
\r
25 private LogType _logType;
\r
26 private readonly ShipMaster _shipMaster;
\r
27 private readonly ShipInfo _shipInfo;
\r
28 private readonly ItemInfo _itemInfo;
\r
29 private Action<string, string, string> _writer;
\r
30 private Func<DateTime> _nowFunc;
\r
31 private const string DateTimeFormat = @"yyyy\-MM\-dd HH\:mm\:ss";
\r
32 private dynamic _battle;
\r
33 private dynamic _map;
\r
34 private dynamic _basic;
\r
35 private int _kdockId;
\r
36 private DateTime _prevTime;
\r
38 public Logger(ShipMaster master, ShipInfo ship, ItemInfo item)
\r
40 _shipMaster = master;
\r
43 _writer = new LogWriter().Write;
\r
44 _nowFunc = () => DateTime.Now;
\r
47 public void EnableLog(LogType type)
\r
52 public void SetWriter(Action<string, string, string> writer, Func<DateTime> nowFunc)
\r
58 public void InspectMissionResult(dynamic json)
\r
60 var r = (int)json.api_clear_result;
\r
61 var rstr = r == 2 ? "大成功" : r == 1 ? "成功" : "失敗";
\r
62 var material = new int[7];
\r
64 ((int[])json.api_get_material).CopyTo(material, 0);
\r
65 foreach (var i in new[] {1, 2})
\r
67 var attr = "api_get_item" + i;
\r
68 if (!json.IsDefined(attr) || json[attr].api_useitem_id != -1)
\r
70 var count = (int)json[attr].api_useitem_count;
\r
71 var flag = ((int[])json.api_useitem_flag)[i - 1];
\r
73 material[(int)Material.Bucket] = count;
\r
75 material[(int)Material.Burner] = count;
\r
77 material[(int)Material.Development] = count;
\r
79 if ((_logType & LogType.Mission) != 0)
\r
82 string.Join(",", _nowFunc().ToString(DateTimeFormat),
\r
83 rstr, json.api_quest_name, string.Join(",", material)),
\r
84 "日付,結果,遠征,燃料,弾薬,鋼材,ボーキ,開発資材,高速修復材,高速建造材");
\r
88 public void InspectMap(dynamic json)
\r
93 public void InspectBattle(dynamic json)
\r
95 if (!IsNightBattle(json))
\r
99 private bool IsNightBattle(dynamic json)
\r
101 return json.api_hougeki();
\r
104 public void InspectBattleResult(dynamic result)
\r
106 if ((_logType & LogType.Battle) == 0 || _map == null || _battle == null)
\r
108 _map = _battle = null;
\r
111 var fships = new List<string>();
\r
112 var deck = _shipInfo.GetDeck(_battle.api_dock_id() ? (int)_battle.api_dock_id - 1 : 0);
\r
113 fships.AddRange(deck.Select(id =>
\r
117 var s = _shipInfo[id];
\r
118 return string.Format("{0}(Lv{1}),{2}/{3}", s.Name, s.Level, s.NowHp, s.MaxHp);
\r
120 var edeck = ((int[])_battle.api_ship_ke).Skip(1).ToArray();
\r
121 var enowhp = ((int[])_battle.api_nowhps).Skip(7).ToArray();
\r
122 var emaxhp = ((int[])_battle.api_maxhps).Skip(7).ToArray();
\r
123 var eships = new List<string>();
\r
124 for (var i = 0; i < edeck.Count(); i++)
\r
126 eships.Add(edeck[i] == -1
\r
128 : string.Format("{0},{1}/{2}", _shipMaster[edeck[i]].Name, enowhp[i], emaxhp[i]));
\r
130 var cell = (int)_map.api_no;
\r
131 var boss = cell == (int)_map.api_bosscell_no || (int)_map.api_event_id == 5 ? "ボス" : "";
\r
132 _writer("海戦・ドロップ報告書", string.Join(",", _nowFunc().ToString(DateTimeFormat),
\r
133 result.api_quest_name,
\r
135 result.api_win_rank,
\r
136 BattleFormationName((int)_battle.api_formation[2]),
\r
137 FormationName(_battle.api_formation[0]),
\r
138 FormationName(_battle.api_formation[1]),
\r
139 result.api_enemy_info.api_deck_name,
\r
140 result.api_get_ship() ? result.api_get_ship.api_ship_type : "",
\r
141 result.api_get_ship() ? result.api_get_ship.api_ship_name : "",
\r
142 string.Join(",", fships),
\r
143 string.Join(",", eships)),
\r
144 "日付,海域,マス,ボス,ランク,艦隊行動,味方陣形,敵陣形,敵艦隊,ドロップ艦種,ドロップ艦娘," +
\r
145 "味方艦1,味方艦1HP,味方艦2,味方艦2HP,味方艦3,味方艦3HP,味方艦4,味方艦4HP,味方艦5,味方艦5HP,味方艦6,味方艦6HP," +
\r
146 "敵艦1,敵艦1HP,敵艦2,敵艦2HP,敵艦3,敵艦3HP,敵艦4,敵艦4HP,敵艦5,敵艦5HP,敵艦6,敵艦6HP"
\r
148 _map = _battle = null;
\r
151 private string FormationName(dynamic f)
\r
153 if (f is string) // 連合艦隊のときは文字列
\r
180 private static String BattleFormationName(int f)
\r
197 public void InspectBasic(dynamic json)
\r
202 public void InspectCreateItem(string request, dynamic json)
\r
204 if ((_logType & LogType.CreateItem) == 0)
\r
206 var values = HttpUtility.ParseQueryString(request);
\r
209 if (json.api_slot_item())
\r
211 var spec = _itemInfo.GetSpecByItemId((int)json.api_slot_item.api_slotitem_id);
\r
213 type = spec.TypeName;
\r
216 _nowFunc().ToString(DateTimeFormat) + "," +
\r
217 string.Join(",", name, type,
\r
218 values["api_item1"], values["api_item2"], values["api_item3"], values["api_item4"],
\r
219 Secretary(), _basic.api_level),
\r
220 "日付,開発装備,種別,燃料,弾薬,鋼材,ボーキ,秘書艦,司令部Lv");
\r
223 public void InspectCreateShip(string request)
\r
225 var values = HttpUtility.ParseQueryString(request);
\r
226 _kdockId = int.Parse(values["api_kdock_id"]);
\r
229 public void InspectKDock(dynamic json)
\r
231 if ((_logType & LogType.CreateShip) == 0 || _basic == null || _kdockId == 0)
\r
233 var kdock = ((dynamic[])json).First(e => e.api_id == _kdockId);
\r
234 var material = Enumerable.Range(1, 5).Select(i => (int)kdock["api_item" + i]).ToArray();
\r
235 var ship = _shipMaster[(int)kdock.api_created_ship_id];
\r
236 var avail = ((dynamic[])json).Count(e => (int)e.api_state == 0);
\r
238 _nowFunc().ToString(DateTimeFormat) + "," +
\r
239 string.Join(",", material.First() >= 1500 ? "大型艦建造" : "通常艦建造",
\r
240 ship.Name, ship.ShipTypeName, string.Join(",", material), avail, Secretary(), _basic.api_level),
\r
241 "日付,種類,名前,艦種,燃料,弾薬,鋼材,ボーキ,開発資材,空きドック,秘書艦,司令部Lv");
\r
245 private string Secretary()
\r
247 var ship = _shipInfo.GetShipStatuses(0)[0];
\r
248 return ship.Name + "(" + ship.Level + ")";
\r
251 public void InspectMaterial(dynamic json)
\r
253 if ((_logType & LogType.Material) == 0)
\r
255 var now = _nowFunc();
\r
256 if (now - _prevTime < TimeSpan.FromMinutes(10))
\r
259 var material = new int[8];
\r
260 foreach (var e in json)
\r
261 material[(int)e.api_id - 1] = (int)e.api_value;
\r
263 now.ToString(DateTimeFormat) + "," +
\r
264 string.Join(",", material) + ",",
\r
265 "日付,燃料,弾薬,鋼材,ボーキ,高速修復材,高速建造材,開発資材,改修資材");
\r
269 public class LogWriter
\r
271 private readonly IFile _file;
\r
273 public interface IFile
\r
275 string ReadAllText(string path);
\r
276 void AppendAllText(string path, string text);
\r
277 void Delete(string path);
\r
278 bool Exists(string path);
\r
281 private class FileWrapper : IFile
\r
283 // Shift_JISでないとExcelで文字化けする
\r
284 private readonly Encoding _encoding = Encoding.GetEncoding("Shift_JIS");
\r
286 public string ReadAllText(string path)
\r
288 return File.ReadAllText(path, _encoding);
\r
291 public void AppendAllText(string path, string text)
\r
293 File.AppendAllText(path, text, _encoding);
\r
296 public void Delete(string path)
\r
301 public bool Exists(string path)
\r
303 return File.Exists(path);
\r
307 public LogWriter(IFile file = null)
\r
309 _file = file ?? new FileWrapper();
\r
312 public void Write(string file, string s, string header)
\r
314 // ReSharper disable once AssignNullToNotNullAttribute
\r
315 var path = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), file);
\r
316 var csv = path + ".csv";
\r
317 var tmp = path + ".tmp";
\r
318 if (_file.Exists(tmp))
\r
322 _file.AppendAllText(csv, _file.ReadAllText(tmp));
\r
325 catch (IOException)
\r
329 if (!_file.Exists(csv))
\r
330 s = header + "\r\n" + s;
\r
331 foreach (var f in new[] {csv, tmp})
\r
335 _file.AppendAllText(f, s + "\r\n");
\r
338 catch (IOException)
\r