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, _missionInfo);\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                 _missionInfo.InspectMaster(data.api_mst_mission);\r
89                 _itemInfo.InspectMaster(data.api_mst_slotitem);\r
90                 return Update.Start;\r
91             }\r
92             if (!_start)\r
93                 return Update.None;\r
94             if (url.EndsWith("api_port/port"))\r
95             {\r
96                 _itemInfo.InspectBasic(data.api_basic);\r
97                 _itemInfo.InspectMaterial(data.api_material);\r
98                 _shipInfo.InspectShip(data);\r
99                 _missionInfo.InspectDeck(data.api_deck_port);\r
100                 _dockInfo.InspectNDock(data.api_ndock);\r
101                 _akashiTimer.SetTimer(true);\r
102                 _achievement.InspectBasic(data.api_basic);\r
103                 _battleInfo.InBattle = false;\r
104                 _battleInfo.HasDamagedShip = false;\r
105                 return Update.All;\r
106             }\r
107             if (url.EndsWith("api_get_member/basic"))\r
108             {\r
109                 _itemInfo.InspectBasic(data);\r
110                 return Update.None;\r
111             }\r
112             if (url.EndsWith("api_get_member/slot_item"))\r
113             {\r
114                 _itemInfo.InspectSlotItem(data, true);\r
115                 return Update.None;\r
116             }\r
117             if (url.EndsWith("api_get_member/kdock"))\r
118             {\r
119                 _dockInfo.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                 _missionInfo.InspectDeck(data);\r
142                 _akashiTimer.SetTimer();\r
143                 return Update.Mission | Update.Timer;\r
144             }\r
145             if (url.EndsWith("api_get_member/ship2"))\r
146             {\r
147                 // ここだけjsonなので注意\r
148                 _shipInfo.InspectShip(json);\r
149                 _akashiTimer.SetTimer();\r
150                 _battleInfo.InBattle = false;\r
151                 return Update.Item | Update.Ship | Update.Battle;\r
152             }\r
153             if (url.EndsWith("api_get_member/ship3"))\r
154             {\r
155                 _shipInfo.InspectShip(data);\r
156                 _akashiTimer.SetTimer();\r
157                 return Update.Ship;\r
158             }\r
159             if (url.EndsWith("api_get_member/material"))\r
160             {\r
161                 _itemInfo.InspectMaterial(data);\r
162                 return Update.Item;\r
163             }\r
164             if (url.EndsWith("api_req_hokyu/charge"))\r
165             {\r
166                 _shipInfo.InspectCharge(data);\r
167                 return Update.Item | Update.Ship;\r
168             }\r
169             if (url.EndsWith("api_req_kousyou/createitem"))\r
170             {\r
171                 _itemInfo.InspectCreateItem(data);\r
172                 return Update.Item;\r
173             }\r
174             if (url.EndsWith("api_req_kousyou/getship"))\r
175             {\r
176                 _itemInfo.InspectGetShip(data);\r
177                 _shipInfo.InspectShip(data);\r
178                 _dockInfo.InspectKDock(data.api_kdock);\r
179                 return Update.Item | Update.Timer;\r
180             }\r
181             if (url.EndsWith("api_req_kousyou/destroyship"))\r
182             {\r
183                 _shipInfo.InspectDestroyShip(request, data);\r
184                 _akashiTimer.SetTimer();\r
185                 return Update.Item | Update.Ship;\r
186             }\r
187             if (url.EndsWith("api_req_kousyou/destroyitem2"))\r
188             {\r
189                 _itemInfo.InspectDestroyItem(request, data);\r
190                 return Update.Item;\r
191             }\r
192             if (url.EndsWith("api_req_kaisou/powerup"))\r
193             {\r
194                 _shipInfo.InspectPowerup(request, data);\r
195                 return Update.Item | Update.Ship;\r
196             }\r
197             if (url.EndsWith("api_req_nyukyo/start"))\r
198             {\r
199                 _dockInfo.InspectNyukyo(request);\r
200                 return Update.Item | Update.Ship;\r
201             }\r
202             if (url.EndsWith("api_req_nyukyo/speedchange"))\r
203             {\r
204                 _dockInfo.InspectSpeedChange(request);\r
205                 return Update.NDock | Update.Timer | Update.Ship;\r
206             }\r
207             if (IsNormalBattleAPI(url))\r
208             {\r
209                 _battleInfo.InspectBattle(data);\r
210                 return Update.Battle;\r
211             }\r
212             if (url.EndsWith("api_req_sortie/battleresult") || url.EndsWith("api_req_practice/battleresult"))\r
213             {\r
214                 _battleInfo.CauseDamage();\r
215                 return Update.Ship;\r
216             }\r
217             if (url.EndsWith("api_req_mission/result"))\r
218             {\r
219                 _itemInfo.InspectMissionResult(data);\r
220                 return Update.Item;\r
221             }\r
222             if (IsCombinedBattleAPI(url))\r
223             {\r
224                 _battleInfo.InspectCombinedBattle(data);\r
225                 return Update.Battle;\r
226             }\r
227             if (url.EndsWith("api_req_combined_battle/battleresult"))\r
228             {\r
229                 _battleInfo.CauseDamageCombined();\r
230                 return Update.Ship;\r
231             }\r
232             return Update.None;\r
233         }\r
234 \r
235         public bool IsBattleAPI(string url)\r
236         {\r
237             return IsNormalBattleAPI(url) || IsCombinedBattleAPI(url);\r
238         }\r
239 \r
240         public bool IsNormalBattleAPI(string url)\r
241         {\r
242             return url.EndsWith("api_req_sortie/battle") || url.EndsWith("api_req_practice/battle") ||\r
243                    url.EndsWith("api_req_battle_midnight/sp_midnight") ||\r
244                    url.EndsWith("api_req_practice/midnight_battle");\r
245         }\r
246 \r
247         public bool IsCombinedBattleAPI(string url)\r
248         {\r
249             return url.EndsWith("api_req_combined_battle/battle") || url.EndsWith("api_req_combined_battle/airbattle") ||\r
250                    url.EndsWith("api_req_combined_battle/midnight_battle") ||\r
251                    url.EndsWith("api_req_combined_battle/sp_midnight");\r
252         }\r
253 \r
254         public NameAndTimer[] NDock\r
255         {\r
256             get { return _dockInfo.NDock; }\r
257         }\r
258 \r
259         public RingTimer[] KDock\r
260         {\r
261             get { return _dockInfo.KDock; }\r
262         }\r
263 \r
264         public ItemInfo Item\r
265         {\r
266             get { return _itemInfo; }\r
267         }\r
268 \r
269         public QuestInfo.NameAndProgress[] Quests\r
270         {\r
271             get { return _questInfo.Quests; }\r
272         }\r
273 \r
274         public NameAndTimer[] Missions\r
275         {\r
276             get { return _missionInfo.Missions; }\r
277         }\r
278 \r
279         public string[] GetConditionTimers(int fleet)\r
280         {\r
281             return _shipInfo.GetConditionTimers(fleet);\r
282         }\r
283 \r
284         public ShipStatus[] GetShipStatuses(int fleet)\r
285         {\r
286             return _shipInfo.GetShipStatuses(fleet);\r
287         }\r
288 \r
289         public ChargeStatus[] ChargeStatuses\r
290         {\r
291             get { return _shipInfo.ChargeStatuses; }\r
292         }\r
293 \r
294         public int GetAirSuperiority(int fleet)\r
295         {\r
296             return _shipInfo.GetAirSuperiority(fleet);\r
297         }\r
298 \r
299         public RepairStatus[] DamagedShipList\r
300         {\r
301             get { return _shipInfo.GetDamagedShipList(_dockInfo); }\r
302         }\r
303 \r
304         public DateTime GetAkashiStartTime(int fleet)\r
305         {\r
306             return _akashiTimer[fleet];\r
307         }\r
308 \r
309         public Achievement Achievement\r
310         {\r
311             get { return _achievement; }\r
312         }\r
313 \r
314         public BattleInfo Battle\r
315         {\r
316             get { return _battleInfo; }\r
317         }\r
318 \r
319         public string LogFile { get; set; }\r
320     }\r
321 \r
322     public class NameAndTimer\r
323     {\r
324         public string Name { get; set; }\r
325         public RingTimer Timer { get; set; }\r
326 \r
327         public NameAndTimer()\r
328         {\r
329             Timer = new RingTimer();\r
330         }\r
331     }\r
332 \r
333     public class RingTimer\r
334     {\r
335         private DateTime _endTime;\r
336         private TimeSpan _rest;\r
337         private readonly TimeSpan _spare;\r
338 \r
339         public RingTimer(int spare = 60)\r
340         {\r
341             _spare = TimeSpan.FromSeconds(spare);\r
342         }\r
343 \r
344         public void SetEndTime(double time)\r
345         {\r
346             SetEndTime((int)time == 0\r
347                 ? DateTime.MinValue\r
348                 : new DateTime(1970, 1, 1).ToLocalTime().AddSeconds(time / 1000));\r
349         }\r
350 \r
351         public void SetEndTime(DateTime time)\r
352         {\r
353             _endTime = time;\r
354             if (_endTime == DateTime.MinValue)\r
355                 IsFinished = false;\r
356         }\r
357 \r
358         public void Update()\r
359         {\r
360             if (_endTime == DateTime.MinValue)\r
361             {\r
362                 _rest = TimeSpan.Zero;\r
363                 return;\r
364             }\r
365             _rest = _endTime - DateTime.Now;\r
366             if (_rest < TimeSpan.Zero)\r
367                 _rest = TimeSpan.Zero;\r
368             if (_rest > _spare || IsFinished)\r
369                 return;\r
370             IsFinished = true;\r
371             NeedRing = true;\r
372         }\r
373 \r
374         public bool IsFinished { get; private set; }\r
375         public bool NeedRing { get; set; }\r
376 \r
377         public override string ToString()\r
378         {\r
379             return _rest.Days == 0 ? _rest.ToString(@"hh\:mm\:ss") : _rest.ToString(@"d\.hh\:mm");\r
380         }\r
381     }\r
382 }