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 Status _status = new Status();\r
35 \r
36         [Flags]\r
37         public enum Update\r
38         {\r
39             None = 0,\r
40             Start = 1,\r
41             Item = 2,\r
42             Ship = 4,\r
43             Timer = 8,\r
44             NDock = 16,\r
45             Mission = 32,\r
46             QuestList = 64,\r
47             Battle = 128,\r
48             All = 255\r
49         }\r
50 \r
51         public Sniffer()\r
52         {\r
53             _shipInfo = new ShipInfo(_shipMaster, _itemInfo);\r
54             _dockInfo = new DockInfo(_shipInfo, _itemInfo);\r
55             _akashiTimer = new AkashiTimer(_shipInfo, _itemInfo, _dockInfo);\r
56             _battleInfo = new BattleInfo(_shipMaster, _shipInfo, _itemInfo);\r
57         }\r
58 \r
59         public void SaveState()\r
60         {\r
61             _achievement.SaveState(_status);\r
62             _itemInfo.SaveState(_status);\r
63             _status.Save();\r
64         }\r
65 \r
66         public void LoadState()\r
67         {\r
68             _status.Load();\r
69             _achievement.LoadState(_status);\r
70             _itemInfo.LoadSate(_status);\r
71         }\r
72 \r
73         public Update Sniff(string url, string request, dynamic json)\r
74         {\r
75             var data = json.IsDefined("api_data") ? json.api_data : new object();\r
76 \r
77             if (url.EndsWith("api_start2"))\r
78             {\r
79                 _start = true;\r
80                 _shipMaster.Inspect(data.api_mst_ship);\r
81                 _shipMaster.InspectStype(data.api_mst_stype);\r
82                 _missionInfo.InspectMaster(data.api_mst_mission);\r
83                 _itemInfo.InspectMaster(data.api_mst_slotitem);\r
84                 return Update.Start;\r
85             }\r
86             if (!_start)\r
87                 return Update.None;\r
88             if (url.EndsWith("api_port/port"))\r
89             {\r
90                 _itemInfo.InspectBasic(data.api_basic);\r
91                 _itemInfo.InspectMaterial(data.api_material);\r
92                 _shipInfo.InspectShip(data);\r
93                 _missionInfo.InspectDeck(data.api_deck_port);\r
94                 _dockInfo.InspectNDock(data.api_ndock);\r
95                 _akashiTimer.SetTimer(true);\r
96                 _achievement.InspectBasic(data.api_basic);\r
97                 _battleInfo.InBattle = false;\r
98                 _battleInfo.HasDamagedShip = false;\r
99                 _shipInfo.ClearEscapedShips();\r
100                 return Update.All;\r
101             }\r
102             if (url.EndsWith("api_get_member/basic"))\r
103             {\r
104                 _itemInfo.InspectBasic(data);\r
105                 return Update.None;\r
106             }\r
107             if (url.EndsWith("api_get_member/slot_item"))\r
108             {\r
109                 _itemInfo.InspectSlotItem(data, true);\r
110                 return Update.None;\r
111             }\r
112             if (url.EndsWith("api_get_member/kdock"))\r
113             {\r
114                 _dockInfo.InspectKDock(data);\r
115                 return Update.Timer;\r
116             }\r
117             if (url.EndsWith("api_get_member/ndock"))\r
118             {\r
119                 _dockInfo.InspectNDock(data);\r
120                 _akashiTimer.SetTimer();\r
121                 return Update.NDock | Update.Timer | Update.Ship;\r
122             }\r
123             if (url.EndsWith("api_req_hensei/change"))\r
124             {\r
125                 _shipInfo.InspectChange(request);\r
126                 _akashiTimer.SetTimer();\r
127                 return Update.Ship;\r
128             }\r
129             if (url.EndsWith("api_get_member/questlist"))\r
130             {\r
131                 _questInfo.Inspect(data);\r
132                 return Update.QuestList;\r
133             }\r
134             if (url.EndsWith("api_get_member/deck"))\r
135             {\r
136                 _shipInfo.InspectDeck(data);\r
137                 _missionInfo.InspectDeck(data);\r
138                 _akashiTimer.SetTimer();\r
139                 return Update.Mission | Update.Timer;\r
140             }\r
141             if (url.EndsWith("api_get_member/ship2"))\r
142             {\r
143                 // ここだけjsonなので注意\r
144                 _shipInfo.InspectShip(json);\r
145                 _akashiTimer.SetTimer();\r
146                 _battleInfo.InBattle = false;\r
147                 return Update.Item | Update.Ship | Update.Battle;\r
148             }\r
149             if (url.EndsWith("api_get_member/ship3"))\r
150             {\r
151                 _shipInfo.InspectShip(data);\r
152                 _akashiTimer.SetTimer();\r
153                 return Update.Ship;\r
154             }\r
155             if (url.EndsWith("api_get_member/material"))\r
156             {\r
157                 _itemInfo.InspectMaterial(data);\r
158                 return Update.Item;\r
159             }\r
160             if (url.EndsWith("api_req_hokyu/charge"))\r
161             {\r
162                 _shipInfo.InspectCharge(data);\r
163                 return Update.Item | Update.Ship;\r
164             }\r
165             if (url.EndsWith("api_req_kousyou/createitem"))\r
166             {\r
167                 _itemInfo.InspectCreateItem(data);\r
168                 return Update.Item;\r
169             }\r
170             if (url.EndsWith("api_req_kousyou/getship"))\r
171             {\r
172                 _itemInfo.InspectGetShip(data);\r
173                 _shipInfo.InspectShip(data);\r
174                 _dockInfo.InspectKDock(data.api_kdock);\r
175                 return Update.Item | Update.Timer;\r
176             }\r
177             if (url.EndsWith("api_req_kousyou/destroyship"))\r
178             {\r
179                 _shipInfo.InspectDestroyShip(request, data);\r
180                 _akashiTimer.SetTimer();\r
181                 return Update.Item | Update.Ship;\r
182             }\r
183             if (url.EndsWith("api_req_kousyou/destroyitem2"))\r
184             {\r
185                 _itemInfo.InspectDestroyItem(request, data);\r
186                 return Update.Item;\r
187             }\r
188             if (url.EndsWith("api_req_kousyou/remodel_slot"))\r
189             {\r
190                 _itemInfo.InspectRemodelSlot(data);\r
191                 return Update.Item;\r
192             }\r
193             if (url.EndsWith("api_req_kaisou/powerup"))\r
194             {\r
195                 _shipInfo.InspectPowerup(request, data);\r
196                 _akashiTimer.SetTimer();\r
197                 return Update.Item | Update.Ship;\r
198             }\r
199             if (url.EndsWith("api_req_nyukyo/start"))\r
200             {\r
201                 _dockInfo.InspectNyukyo(request);\r
202                 _akashiTimer.SetTimer();\r
203                 return Update.Item | Update.Ship;\r
204             }\r
205             if (url.EndsWith("api_req_nyukyo/speedchange"))\r
206             {\r
207                 _dockInfo.InspectSpeedChange(request);\r
208                 return Update.NDock | Update.Timer | Update.Ship;\r
209             }\r
210             if (IsNormalBattleAPI(url))\r
211             {\r
212                 _battleInfo.InspectBattle(data);\r
213                 if (!url.EndsWith("api_req_practice/battle"))\r
214                     return Update.Battle;\r
215                 _shipInfo.StartSortie(request); // 演習を出撃中とみなす\r
216                 return Update.Battle | Update.Timer;\r
217             }\r
218             if (url.EndsWith("api_req_sortie/battleresult"))\r
219             {\r
220                 _battleInfo.CauseDamage();\r
221                 return Update.Ship;\r
222             }\r
223             if (url.EndsWith("api_req_practice/battle_result"))\r
224             {\r
225                 _battleInfo.CausePracticeDamage();\r
226                 return Update.Ship;\r
227             }\r
228             if (IsCombinedBattleAPI(url))\r
229             {\r
230                 _battleInfo.InspectCombinedBattle(data, url.EndsWith("battle_water"));\r
231                 return Update.Battle;\r
232             }\r
233             if (url.EndsWith("api_req_combined_battle/battleresult"))\r
234             {\r
235                 _battleInfo.InspectCombinedBattleResult(data);\r
236                 return Update.Ship;\r
237             }\r
238             if (url.EndsWith("api_req_combined_battle/goback_port"))\r
239             {\r
240                 _battleInfo.CauseCombinedBattleEscape();\r
241                 return Update.None;\r
242             }\r
243             if (url.EndsWith("api_req_map/start"))\r
244             {\r
245                 _shipInfo.StartSortie(request);\r
246                 return Update.Timer;\r
247             }\r
248             if (url.EndsWith("api_req_mission/result"))\r
249             {\r
250                 _itemInfo.InspectMissionResult(data);\r
251                 return Update.Item;\r
252             }\r
253             return Update.None;\r
254         }\r
255 \r
256         public bool IsBattleAPI(string url)\r
257         {\r
258             return IsNormalBattleAPI(url) || IsCombinedBattleAPI(url);\r
259         }\r
260 \r
261         public bool IsNormalBattleAPI(string url)\r
262         {\r
263             return url.EndsWith("api_req_sortie/battle") || url.EndsWith("api_req_practice/battle") ||\r
264                    url.EndsWith("api_req_battle_midnight/sp_midnight") ||\r
265                    url.EndsWith("api_req_practice/midnight_battle");\r
266         }\r
267 \r
268         public bool IsCombinedBattleAPI(string url)\r
269         {\r
270             return url.EndsWith("api_req_combined_battle/battle") ||\r
271                    url.EndsWith("api_req_combined_battle/airbattle") ||\r
272                    url.EndsWith("api_req_combined_battle/battle_water") ||\r
273                    url.EndsWith("api_req_combined_battle/midnight_battle") ||\r
274                    url.EndsWith("api_req_combined_battle/sp_midnight");\r
275         }\r
276 \r
277         public NameAndTimer[] NDock\r
278         {\r
279             get { return _dockInfo.NDock; }\r
280         }\r
281 \r
282         public RingTimer[] KDock\r
283         {\r
284             get { return _dockInfo.KDock; }\r
285         }\r
286 \r
287         public ItemInfo Item\r
288         {\r
289             get { return _itemInfo; }\r
290         }\r
291 \r
292         public QuestInfo.NameAndProgress[] Quests\r
293         {\r
294             get { return _questInfo.Quests; }\r
295         }\r
296 \r
297         public NameAndTimer[] Missions\r
298         {\r
299             get { return _missionInfo.Missions; }\r
300         }\r
301 \r
302         public DateTime GetConditionTimer(int fleet)\r
303         {\r
304             return _shipInfo.GetConditionTiemr(fleet);\r
305         }\r
306 \r
307         public int[] GetConditionNotice()\r
308         {\r
309             return _shipInfo.GetConditionNotice();\r
310         }\r
311 \r
312         public ShipStatus[] GetShipStatuses(int fleet)\r
313         {\r
314             return _shipInfo.GetShipStatuses(fleet);\r
315         }\r
316 \r
317         public ChargeStatus[] ChargeStatuses\r
318         {\r
319             get { return _shipInfo.ChargeStatuses; }\r
320         }\r
321 \r
322         public int GetAirSuperiority(int fleet)\r
323         {\r
324             return _shipInfo.GetAirSuperiority(fleet);\r
325         }\r
326 \r
327         public double GetFleetLineOfSights(int fleet)\r
328         {\r
329             return _shipInfo.GetLineOfSights(fleet);\r
330         }\r
331 \r
332         public ShipStatus[] DamagedShipList\r
333         {\r
334             get { return _shipInfo.GetDamagedShipList(_dockInfo); }\r
335         }\r
336 \r
337         public ShipStatus[] ShipList\r
338         {\r
339             get { return _shipInfo.ShipList; }\r
340         }\r
341 \r
342         public ShipType[] ShipTypeList\r
343         {\r
344             get { return _shipMaster.ShipTypeList; }\r
345         }\r
346 \r
347         public AkashiTimer.RepairSpan[] GetAkashiTimers(int fleet)\r
348         {\r
349             return _akashiTimer.GetTimers(fleet);\r
350         }\r
351 \r
352         public string[] GetAkashiTimerNotice()\r
353         {\r
354             return _akashiTimer.GetNotice();\r
355         }\r
356 \r
357         public Achievement Achievement\r
358         {\r
359             get { return _achievement; }\r
360         }\r
361 \r
362         public BattleInfo Battle\r
363         {\r
364             get { return _battleInfo; }\r
365         }\r
366     }\r
367 \r
368     public class NameAndTimer\r
369     {\r
370         public string Name { get; set; }\r
371         public RingTimer Timer { get; set; }\r
372 \r
373         public NameAndTimer()\r
374         {\r
375             Timer = new RingTimer();\r
376         }\r
377     }\r
378 \r
379     public class RingTimer\r
380     {\r
381         private DateTime _endTime;\r
382         private TimeSpan _rest;\r
383         private readonly TimeSpan _spare;\r
384 \r
385         public RingTimer(int spare = 60)\r
386         {\r
387             _spare = TimeSpan.FromSeconds(spare);\r
388         }\r
389 \r
390         public void SetEndTime(double time)\r
391         {\r
392             SetEndTime((int)time == 0\r
393                 ? DateTime.MinValue\r
394                 : new DateTime(1970, 1, 1).ToLocalTime().AddSeconds(time / 1000));\r
395         }\r
396 \r
397         public void SetEndTime(DateTime time)\r
398         {\r
399             _endTime = time;\r
400             if (_endTime == DateTime.MinValue)\r
401                 IsFinished = false;\r
402         }\r
403 \r
404         public void Update()\r
405         {\r
406             if (_endTime == DateTime.MinValue)\r
407             {\r
408                 _rest = TimeSpan.Zero;\r
409                 return;\r
410             }\r
411             _rest = _endTime - DateTime.Now;\r
412             if (_rest < TimeSpan.Zero)\r
413                 _rest = TimeSpan.Zero;\r
414             if (_rest > _spare || IsFinished)\r
415                 return;\r
416             IsFinished = true;\r
417             NeedRing = true;\r
418         }\r
419 \r
420         public bool IsFinished { get; private set; }\r
421         public bool NeedRing { get; set; }\r
422 \r
423         public override string ToString()\r
424         {\r
425             return _rest.Days == 0 ? _rest.ToString(@"hh\:mm\:ss") : _rest.ToString(@"d\.hh\:mm");\r
426         }\r
427     }\r
428 }