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