OSDN Git Service

装備一覧を表示する
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / Sniffer.cs
1 // Copyright (C) 2013, 2014 Kazuhiro Fujieda <fujieda@users.sourceforge.jp>\r
2 // \r
3 // This program is part of KancolleSniffer.\r
4 //\r
5 // KancolleSniffer is free software: you can redistribute it and/or modify\r
6 // it under the terms of the GNU General Public License as published by\r
7 // the Free Software Foundation, either version 3 of the License, or\r
8 // (at your option) any later version.\r
9 //\r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 //\r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, see <http://www.gnu.org/licenses/>.\r
17 \r
18 using System;\r
19 \r
20 namespace KancolleSniffer\r
21 {\r
22     public class Sniffer\r
23     {\r
24         private bool _start;\r
25         private readonly ShipMaster _shipMaster = new ShipMaster();\r
26         private readonly ItemInfo _itemInfo = new ItemInfo();\r
27         private readonly QuestInfo _questInfo = new QuestInfo();\r
28         private readonly MissionInfo _missionInfo = new MissionInfo();\r
29         private readonly ShipInfo _shipInfo;\r
30         private readonly DockInfo _dockInfo;\r
31         private readonly AkashiTimer _akashiTimer;\r
32         private readonly Achievement _achievement = new Achievement();\r
33         private readonly BattleInfo _battleInfo;\r
34         private readonly Logger _logger;\r
35         private readonly Status _status = new Status();\r
36 \r
37         [Flags]\r
38         public enum Update\r
39         {\r
40             None = 0,\r
41             Start = 1,\r
42             Item = 2,\r
43             Ship = 4,\r
44             Timer = 8,\r
45             NDock = 16,\r
46             Mission = 32,\r
47             QuestList = 64,\r
48             Battle = 128,\r
49             All = 255\r
50         }\r
51 \r
52         public Sniffer()\r
53         {\r
54             _shipInfo = new ShipInfo(_shipMaster, _itemInfo);\r
55             _dockInfo = new DockInfo(_shipInfo, _itemInfo);\r
56             _akashiTimer = new AkashiTimer(_shipInfo, _itemInfo, _dockInfo);\r
57             _battleInfo = new BattleInfo(_shipMaster, _shipInfo, _itemInfo);\r
58             _logger = new Logger(_shipMaster, _shipInfo, _itemInfo);\r
59         }\r
60 \r
61         public void SaveState()\r
62         {\r
63             _achievement.SaveState(_status);\r
64             _itemInfo.SaveState(_status);\r
65             _status.Save();\r
66         }\r
67 \r
68         public void LoadState()\r
69         {\r
70             _status.Load();\r
71             _achievement.LoadState(_status);\r
72             _itemInfo.LoadSate(_status);\r
73         }\r
74 \r
75         public Update Sniff(string url, string request, dynamic json)\r
76         {\r
77             var data = json.IsDefined("api_data") ? json.api_data : new object();\r
78 \r
79             if (url.EndsWith("api_start2"))\r
80             {\r
81                 _start = true;\r
82                 _shipMaster.Inspect(data);\r
83                 _missionInfo.InspectMaster(data.api_mst_mission);\r
84                 _itemInfo.InspectMaster(data);\r
85                 return Update.Start;\r
86             }\r
87             if (!_start)\r
88                 return Update.None;\r
89             if (url.EndsWith("api_port/port"))\r
90             {\r
91                 _itemInfo.InspectBasic(data.api_basic);\r
92                 _itemInfo.InspectMaterial(data.api_material);\r
93                 _logger.InspectBasic(data.api_basic);\r
94                 _logger.InspectMaterial(data.api_material);\r
95                 _shipInfo.InspectShip(data);\r
96                 _missionInfo.InspectDeck(data.api_deck_port);\r
97                 _dockInfo.InspectNDock(data.api_ndock);\r
98                 _akashiTimer.SetTimer(true);\r
99                 _achievement.InspectBasic(data.api_basic);\r
100                 _battleInfo.InBattle = false;\r
101                 _battleInfo.HasDamagedShip = false;\r
102                 _shipInfo.ClearEscapedShips();\r
103                 return Update.All;\r
104             }\r
105             if (url.EndsWith("api_get_member/basic"))\r
106             {\r
107                 _itemInfo.InspectBasic(data);\r
108                 _logger.InspectBasic(data);\r
109                 return Update.None;\r
110             }\r
111             if (url.EndsWith("api_get_member/slot_item"))\r
112             {\r
113                 _itemInfo.InspectSlotItem(data, true);\r
114                 return Update.None;\r
115             }\r
116             if (url.EndsWith("api_get_member/kdock"))\r
117             {\r
118                 _dockInfo.InspectKDock(data);\r
119                 _logger.InspectKDock(data);\r
120                 return Update.Timer;\r
121             }\r
122             if (url.EndsWith("api_get_member/ndock"))\r
123             {\r
124                 _dockInfo.InspectNDock(data);\r
125                 _akashiTimer.SetTimer();\r
126                 return Update.NDock | Update.Timer | Update.Ship;\r
127             }\r
128             if (url.EndsWith("api_req_hensei/change"))\r
129             {\r
130                 _shipInfo.InspectChange(request);\r
131                 _akashiTimer.SetTimer();\r
132                 return Update.Ship;\r
133             }\r
134             if (url.EndsWith("api_get_member/questlist"))\r
135             {\r
136                 _questInfo.Inspect(data);\r
137                 return Update.QuestList;\r
138             }\r
139             if (url.EndsWith("api_get_member/deck"))\r
140             {\r
141                 _shipInfo.InspectDeck(data);\r
142                 _missionInfo.InspectDeck(data);\r
143                 _akashiTimer.SetTimer();\r
144                 return Update.Mission | Update.Timer;\r
145             }\r
146             if (url.EndsWith("api_get_member/ship2"))\r
147             {\r
148                 // ここだけjsonなので注意\r
149                 _shipInfo.InspectShip(json);\r
150                 _akashiTimer.SetTimer();\r
151                 _battleInfo.InBattle = false;\r
152                 return Update.Item | Update.Ship | Update.Battle;\r
153             }\r
154             if (url.EndsWith("api_get_member/ship3"))\r
155             {\r
156                 _shipInfo.InspectShip(data);\r
157                 _akashiTimer.SetTimer();\r
158                 return Update.Ship;\r
159             }\r
160             if (url.EndsWith("api_get_member/material"))\r
161             {\r
162                 _itemInfo.InspectMaterial(data);\r
163                 return Update.Item;\r
164             }\r
165             if (url.EndsWith("api_req_hokyu/charge"))\r
166             {\r
167                 _shipInfo.InspectCharge(data);\r
168                 return Update.Item | Update.Ship;\r
169             }\r
170             if (url.EndsWith("api_req_kousyou/createitem"))\r
171             {\r
172                 _itemInfo.InspectCreateItem(data);\r
173                 _logger.InspectCreateItem(request, data);\r
174                 return Update.Item;\r
175             }\r
176             if (url.EndsWith("api_req_kousyou/getship"))\r
177             {\r
178                 _itemInfo.InspectGetShip(data);\r
179                 _shipInfo.InspectShip(data);\r
180                 _dockInfo.InspectKDock(data.api_kdock);\r
181                 return Update.Item | Update.Timer;\r
182             }\r
183             if (url.EndsWith("api_req_kousyou/destroyship"))\r
184             {\r
185                 _shipInfo.InspectDestroyShip(request, data);\r
186                 _akashiTimer.SetTimer();\r
187                 return Update.Item | Update.Ship;\r
188             }\r
189             if (url.EndsWith("api_req_kousyou/destroyitem2"))\r
190             {\r
191                 _itemInfo.InspectDestroyItem(request, data);\r
192                 return Update.Item;\r
193             }\r
194             if (url.EndsWith("api_req_kousyou/remodel_slot"))\r
195             {\r
196                 _itemInfo.InspectRemodelSlot(data);\r
197                 return Update.Item;\r
198             }\r
199             if (url.EndsWith("api_req_kousyou/createship"))\r
200             {\r
201                 _logger.InspectCreateShip(request);\r
202                 return Update.None;\r
203             }\r
204             if (url.EndsWith("api_req_kaisou/powerup"))\r
205             {\r
206                 _shipInfo.InspectPowerup(request, data);\r
207                 _akashiTimer.SetTimer();\r
208                 return Update.Item | Update.Ship;\r
209             }\r
210             if (url.EndsWith("api_req_nyukyo/start"))\r
211             {\r
212                 _dockInfo.InspectNyukyo(request);\r
213                 _akashiTimer.SetTimer();\r
214                 return Update.Item | Update.Ship;\r
215             }\r
216             if (url.EndsWith("api_req_nyukyo/speedchange"))\r
217             {\r
218                 _dockInfo.InspectSpeedChange(request);\r
219                 return Update.NDock | Update.Timer | Update.Ship;\r
220             }\r
221             if (IsNormalBattleAPI(url))\r
222             {\r
223                 _battleInfo.InspectBattle(data);\r
224                 if (!url.EndsWith("api_req_practice/battle"))\r
225                 {\r
226                     _logger.InspectBattle(data);\r
227                     return Update.Battle;\r
228                 }\r
229                 _shipInfo.StartSortie(request); // 演習を出撃中とみなす\r
230                 return Update.Battle | Update.Timer;\r
231             }\r
232             if (url.EndsWith("api_req_sortie/battleresult"))\r
233             {\r
234                 _battleInfo.CauseDamage();\r
235                 _logger.InspectBattleResult(data);\r
236                 return Update.Ship;\r
237             }\r
238             if (url.EndsWith("api_req_practice/battle_result"))\r
239             {\r
240                 _battleInfo.CausePracticeDamage();\r
241                 return Update.Ship;\r
242             }\r
243             if (IsCombinedBattleAPI(url))\r
244             {\r
245                 _battleInfo.InspectCombinedBattle(data, url.EndsWith("battle_water"));\r
246                 _logger.InspectBattle(data);\r
247                 return Update.Battle;\r
248             }\r
249             if (url.EndsWith("api_req_combined_battle/battleresult"))\r
250             {\r
251                 _battleInfo.InspectCombinedBattleResult(data);\r
252                 _logger.InspectBattleResult(data);\r
253                 return Update.Ship;\r
254             }\r
255             if (url.EndsWith("api_req_combined_battle/goback_port"))\r
256             {\r
257                 _battleInfo.CauseCombinedBattleEscape();\r
258                 return Update.None;\r
259             }\r
260             if (url.EndsWith("api_req_map/start"))\r
261             {\r
262                 _shipInfo.StartSortie(request);\r
263                 _logger.InspectMap(data);\r
264                 return Update.Timer;\r
265             }\r
266             if (url.EndsWith("api_req_map/next"))\r
267             {\r
268                 _logger.InspectMap(data);\r
269                 return Update.None;\r
270             }\r
271             if (url.EndsWith("api_req_mission/result"))\r
272             {\r
273                 _itemInfo.InspectMissionResult(data);\r
274                 _logger.InspectMissionResult(data);\r
275                 return Update.Item;\r
276             }\r
277             return Update.None;\r
278         }\r
279 \r
280         public bool IsBattleAPI(string url)\r
281         {\r
282             return IsNormalBattleAPI(url) || IsCombinedBattleAPI(url);\r
283         }\r
284 \r
285         public bool IsNormalBattleAPI(string url)\r
286         {\r
287             return url.EndsWith("api_req_sortie/battle") || url.EndsWith("api_req_practice/battle") ||\r
288                    url.EndsWith("api_req_battle_midnight/battle") ||\r
289                    url.EndsWith("api_req_battle_midnight/sp_midnight") ||\r
290                    url.EndsWith("api_req_practice/midnight_battle");\r
291         }\r
292 \r
293         public bool IsCombinedBattleAPI(string url)\r
294         {\r
295             return url.EndsWith("api_req_combined_battle/battle") ||\r
296                    url.EndsWith("api_req_combined_battle/airbattle") ||\r
297                    url.EndsWith("api_req_combined_battle/battle_water") ||\r
298                    url.EndsWith("api_req_combined_battle/midnight_battle") ||\r
299                    url.EndsWith("api_req_combined_battle/sp_midnight");\r
300         }\r
301 \r
302         public NameAndTimer[] NDock\r
303         {\r
304             get { return _dockInfo.NDock; }\r
305         }\r
306 \r
307         public RingTimer[] KDock\r
308         {\r
309             get { return _dockInfo.KDock; }\r
310         }\r
311 \r
312         public ItemInfo Item\r
313         {\r
314             get { return _itemInfo; }\r
315         }\r
316 \r
317         public QuestInfo.NameAndProgress[] Quests\r
318         {\r
319             get { return _questInfo.Quests; }\r
320         }\r
321 \r
322         public NameAndTimer[] Missions\r
323         {\r
324             get { return _missionInfo.Missions; }\r
325         }\r
326 \r
327         public DateTime GetConditionTimer(int fleet)\r
328         {\r
329             return _shipInfo.GetConditionTiemr(fleet);\r
330         }\r
331 \r
332         public int[] GetConditionNotice()\r
333         {\r
334             return _shipInfo.GetConditionNotice();\r
335         }\r
336 \r
337         public ShipStatus[] GetShipStatuses(int fleet)\r
338         {\r
339             return _shipInfo.GetShipStatuses(fleet);\r
340         }\r
341 \r
342         public int[] GetDeck(int fleet)\r
343         {\r
344             return _shipInfo.GetDeck(fleet);\r
345         }\r
346 \r
347         public ChargeStatus[] ChargeStatuses\r
348         {\r
349             get { return _shipInfo.ChargeStatuses; }\r
350         }\r
351 \r
352         public int GetAirSuperiority(int fleet)\r
353         {\r
354             return _shipInfo.GetAirSuperiority(fleet);\r
355         }\r
356 \r
357         public double GetFleetLineOfSights(int fleet)\r
358         {\r
359             return _shipInfo.GetLineOfSights(fleet);\r
360         }\r
361 \r
362         public ShipStatus[] DamagedShipList\r
363         {\r
364             get { return _shipInfo.GetDamagedShipList(_dockInfo); }\r
365         }\r
366 \r
367         public ShipStatus[] ShipList\r
368         {\r
369             get { return _shipInfo.ShipList; }\r
370         }\r
371 \r
372         public ItemStatus[] ItemList\r
373         {\r
374             get { return _itemInfo.GetItemList(_shipInfo); }\r
375         }\r
376 \r
377         public AkashiTimer.RepairSpan[] GetAkashiTimers(int fleet)\r
378         {\r
379             return _akashiTimer.GetTimers(fleet);\r
380         }\r
381 \r
382         public string[] GetAkashiTimerNotice()\r
383         {\r
384             return _akashiTimer.GetNotice();\r
385         }\r
386 \r
387         public Achievement Achievement\r
388         {\r
389             get { return _achievement; }\r
390         }\r
391 \r
392         public BattleInfo Battle\r
393         {\r
394             get { return _battleInfo; }\r
395         }\r
396 \r
397         public void SetLogWriter(Action<string, string, string> writer, Func<DateTime> nowFunc)\r
398         {\r
399             _logger.SetWriter(writer, nowFunc);\r
400         }\r
401 \r
402         public void SkipMaster()\r
403         {\r
404             _start = true;\r
405         }\r
406 \r
407         public void EnableLog(LogType type)\r
408         {\r
409             _logger.EnableLog(type);\r
410         }\r
411 \r
412         public int MaterialLogInterval\r
413         {\r
414             set { _logger.MaterialLogInterval = value; }\r
415         }\r
416 \r
417         public string LogOutputDir\r
418         {\r
419             set { _logger.OutputDir = value; }\r
420         }\r
421     }\r
422 \r
423     public class NameAndTimer\r
424     {\r
425         public string Name { get; set; }\r
426         public RingTimer Timer { get; set; }\r
427 \r
428         public NameAndTimer()\r
429         {\r
430             Timer = new RingTimer();\r
431         }\r
432     }\r
433 \r
434     public class RingTimer\r
435     {\r
436         private DateTime _endTime;\r
437         private TimeSpan _rest;\r
438         private readonly TimeSpan _spare;\r
439 \r
440         public RingTimer(int spare = 60)\r
441         {\r
442             _spare = TimeSpan.FromSeconds(spare);\r
443         }\r
444 \r
445         public void SetEndTime(double time)\r
446         {\r
447             SetEndTime((int)time == 0\r
448                 ? DateTime.MinValue\r
449                 : new DateTime(1970, 1, 1).ToLocalTime().AddSeconds(time / 1000));\r
450         }\r
451 \r
452         public void SetEndTime(DateTime time)\r
453         {\r
454             _endTime = time;\r
455             if (_endTime == DateTime.MinValue)\r
456                 IsFinished = false;\r
457         }\r
458 \r
459         public void Update()\r
460         {\r
461             if (_endTime == DateTime.MinValue)\r
462             {\r
463                 _rest = TimeSpan.Zero;\r
464                 return;\r
465             }\r
466             _rest = _endTime - DateTime.Now;\r
467             if (_rest < TimeSpan.Zero)\r
468                 _rest = TimeSpan.Zero;\r
469             if (_rest > _spare || IsFinished)\r
470                 return;\r
471             IsFinished = true;\r
472             NeedRing = true;\r
473         }\r
474 \r
475         public bool IsFinished { get; private set; }\r
476         public bool NeedRing { get; set; }\r
477 \r
478         public override string ToString()\r
479         {\r
480             return _rest.Days == 0 ? _rest.ToString(@"hh\:mm\:ss") : _rest.ToString(@"d\.hh\:mm");\r
481         }\r
482     }\r
483 }