OSDN Git Service

e4dad0c79ac693dcdd17d6ccf1048931579ca07c
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / Sniffer.cs
1 // Copyright (C) 2013, 2014, 2015 Kazuhiro Fujieda <fujieda@users.osdn.me>\r
2 // \r
3 // Licensed under the Apache License, Version 2.0 (the "License");\r
4 // you may not use this file except in compliance with the License.\r
5 // You may obtain a copy of the License at\r
6 //\r
7 //    http://www.apache.org/licenses/LICENSE-2.0\r
8 //\r
9 // Unless required by applicable law or agreed to in writing, software\r
10 // distributed under the License is distributed on an "AS IS" BASIS,\r
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
12 // See the License for the specific language governing permissions and\r
13 // limitations under the License.\r
14 \r
15 using System;\r
16 using System.Collections.Generic;\r
17 using System.Linq;\r
18 \r
19 namespace KancolleSniffer\r
20 {\r
21     public class Sniffer\r
22     {\r
23         private bool _start;\r
24         private readonly ItemInfo _itemInfo = new ItemInfo();\r
25         private readonly MaterialInfo _materialInfo = new MaterialInfo();\r
26         private readonly QuestInfo _questInfo;\r
27         private readonly MissionInfo _missionInfo = new MissionInfo();\r
28         private readonly ShipMaster _shipMaster = new ShipMaster();\r
29         private readonly ShipInfo _shipInfo;\r
30         private readonly ConditionTimer _conditionTimer;\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 Logger _logger;\r
36         private readonly ExMapInfo _exMapInfo = new ExMapInfo();\r
37         private readonly MiscTextInfo _miscTextInfo;\r
38         private readonly BaseAirCoprs _baseAirCoprs;\r
39         private readonly PresetDeck _presetDeck = new PresetDeck();\r
40         private readonly CellInfo _cellInfo = new CellInfo();\r
41         private readonly Status _status = new Status();\r
42         private bool _saveState;\r
43         private readonly List<IHaveState> _haveState;\r
44         private AdditionalData _additionalData;\r
45 \r
46         public interface IRepeatingTimerController\r
47         {\r
48             void Stop(string key);\r
49             void Stop(string key, int fleet);\r
50             void Suspend(string exception = null);\r
51             void Resume();\r
52         }\r
53 \r
54         public IRepeatingTimerController RepeatingTimerController { get; set; }\r
55 \r
56         [Flags]\r
57         public enum Update\r
58         {\r
59             None = 0,\r
60             Error = 1 << 0,\r
61             Start = 1 << 1,\r
62             Item = 1 << 2,\r
63             Ship = 1 << 3,\r
64             Timer = 1 << 4,\r
65             NDock = 1 << 5,\r
66             Mission = 1 << 6,\r
67             QuestList = 1 << 7,\r
68             Battle = 1 << 8,\r
69             Cell = 1 << 9,\r
70             All = (1 << 10) - 1\r
71         }\r
72 \r
73         public Sniffer(bool start = false)\r
74         {\r
75             _start = start;\r
76             _shipInfo = new ShipInfo(_shipMaster, _itemInfo);\r
77             _conditionTimer = new ConditionTimer(_shipInfo);\r
78             _dockInfo = new DockInfo(_shipInfo, _materialInfo);\r
79             _akashiTimer = new AkashiTimer(_shipInfo, _dockInfo, _presetDeck);\r
80             _battleInfo = new BattleInfo(_shipInfo, _itemInfo);\r
81             _logger = new Logger(_shipInfo, _itemInfo, _battleInfo);\r
82             _questInfo = new QuestInfo(_itemInfo, _battleInfo);\r
83             _baseAirCoprs = new BaseAirCoprs(_itemInfo);\r
84             _miscTextInfo = new MiscTextInfo(_shipInfo, _itemInfo);\r
85             _haveState = new List<IHaveState> {_achievement, _materialInfo, _conditionTimer, _exMapInfo, _questInfo};\r
86             AdditionalData = new AdditionalData();\r
87         }\r
88 \r
89         public AdditionalData AdditionalData\r
90         {\r
91             get => _additionalData;\r
92             set\r
93             {\r
94                 _additionalData = value;\r
95                 _shipMaster.AdditionalData = value;\r
96                 _itemInfo.AdditionalData = value;\r
97             }\r
98         }\r
99 \r
100         public void SaveState()\r
101         {\r
102             if (!_saveState)\r
103                 return;\r
104             if (!_haveState.Any(x => x.NeedSave))\r
105                 return;\r
106             foreach (var x in _haveState)\r
107                 x.SaveState(_status);\r
108             _status.Save();\r
109         }\r
110 \r
111         public void LoadState()\r
112         {\r
113             _status.Load();\r
114             foreach (var x in _haveState)\r
115                 x.LoadState(_status);\r
116             _saveState = true;\r
117         }\r
118 \r
119         public Update Sniff(string url, string request, dynamic json)\r
120         {\r
121             if (!json.api_result())\r
122                 return Update.Error;\r
123             if ((int)json.api_result != 1)\r
124                 return Update.None;\r
125             var data = json.api_data() ? json.api_data : new object();\r
126 \r
127             if (url.EndsWith("api_start2"))\r
128             {\r
129                 return ApiStart(data);\r
130             }\r
131             if (!_start)\r
132                 return Update.None;\r
133 \r
134             if (url.EndsWith("api_port/port"))\r
135                 return ApiPort(data);\r
136             if (url.Contains("member"))\r
137                 return ApiMember(url, json);\r
138             if (url.Contains("kousyou"))\r
139                 return ApiKousyou(url, request, data);\r
140             if (url.Contains("battle") || url.Contains("sortie"))\r
141                 return ApiBattle(url, request, data);\r
142             if (url.Contains("hensei"))\r
143                 return ApiHensei(url, request, data);\r
144             if (url.Contains("air_corps"))\r
145                 return ApiAirCorps(url, request, data);\r
146             return ApiOthers(url, request, data);\r
147         }\r
148 \r
149         private Update ApiStart(dynamic data)\r
150         {\r
151             _shipInfo.InspectMaster(data);\r
152             _missionInfo.InspectMaster(data.api_mst_mission);\r
153             _itemInfo.InspectMaster(data);\r
154             _exMapInfo.ResetIfNeeded();\r
155             _miscTextInfo.InspectMaster(data);\r
156             _start = true;\r
157             return Update.Start;\r
158         }\r
159 \r
160         private Update ApiPort(dynamic data)\r
161         {\r
162             _itemInfo.InspectBasic(data.api_basic);\r
163             _materialInfo.InspectMaterialPort(data.api_material);\r
164             _logger.InspectBasic(data.api_basic);\r
165             _logger.InspectMaterial(data.api_material);\r
166             _shipInfo.InspectShip(data);\r
167             _shipInfo.ClearBadlyDamagedShips();\r
168             _conditionTimer.CalcRegenTime();\r
169             _missionInfo.InspectDeck(data.api_deck_port);\r
170             _questInfo.InspectDeck(data.api_deck_port);\r
171             _dockInfo.InspectNDock(data.api_ndock);\r
172             _akashiTimer.Port();\r
173             _achievement.InspectBasic(data.api_basic);\r
174             if (data.api_parallel_quest_count()) // 昔のログにはないので\r
175                 _questInfo.AcceptMax = (int)data.api_parallel_quest_count;\r
176             if (data.api_event_object())\r
177                 _baseAirCoprs.InspectEventObject(data.api_event_object);\r
178             if (data.api_plane_info())\r
179                 _baseAirCoprs.InspectPlaneInfo(data.api_plane_info);\r
180             _battleInfo.CleanupResult();\r
181             _battleInfo.BattleState = BattleState.None;\r
182             _shipInfo.ClearEscapedShips();\r
183             _miscTextInfo.Port();\r
184             _cellInfo.Port();\r
185             SaveState();\r
186             RepeatingTimerController?.Resume();\r
187             foreach (var s in new[] {"遠征終了", "入渠終了", "疲労回復", "泊地修理", "大破警告"})\r
188                 RepeatingTimerController?.Stop(s);\r
189             return Update.All;\r
190         }\r
191 \r
192         private Update ApiMember(string url, dynamic json)\r
193         {\r
194             var data = json.api_data() ? json.api_data : new object();\r
195 \r
196             if (url.EndsWith("api_get_member/require_info"))\r
197             {\r
198                 _itemInfo.InspectSlotItem(data.api_slot_item, true);\r
199                 _dockInfo.InspectKDock(data.api_kdock);\r
200                 return Update.None;\r
201             }\r
202             if (url.EndsWith("api_get_member/basic"))\r
203             {\r
204                 _itemInfo.InspectBasic(data);\r
205                 _logger.InspectBasic(data);\r
206                 return Update.None;\r
207             }\r
208             if (url.EndsWith("api_get_member/slot_item"))\r
209             {\r
210                 _itemInfo.InspectSlotItem(data, true);\r
211                 return Update.Item;\r
212             }\r
213             if (url.EndsWith("api_get_member/kdock"))\r
214             {\r
215                 _dockInfo.InspectKDock(data);\r
216                 _logger.InspectKDock(data);\r
217                 return Update.Timer;\r
218             }\r
219             if (url.EndsWith("api_get_member/ndock"))\r
220             {\r
221                 _dockInfo.InspectNDock(data);\r
222                 _conditionTimer.CheckCond();\r
223                 _akashiTimer.CheckFleet();\r
224                 RepeatingTimerController?.Stop("入渠終了");\r
225                 return Update.NDock | Update.Timer | Update.Ship;\r
226             }\r
227             if (url.EndsWith("api_get_member/questlist"))\r
228             {\r
229                 _questInfo.InspectQuestList(data);\r
230                 return Update.QuestList;\r
231             }\r
232             if (url.EndsWith("api_get_member/deck"))\r
233             {\r
234                 _shipInfo.InspectDeck(data);\r
235                 _missionInfo.InspectDeck(data);\r
236                 _akashiTimer.CheckFleet();\r
237                 _questInfo.InspectDeck(data);\r
238                 return Update.Mission | Update.Timer;\r
239             }\r
240             if (url.EndsWith("api_get_member/ship2"))\r
241             {\r
242                 // ここだけjsonなので注意\r
243                 _shipInfo.InspectShip(json);\r
244                 _akashiTimer.CheckFleet();\r
245                 _battleInfo.BattleState = BattleState.None;\r
246                 return Update.Item | Update.Ship | Update.Battle;\r
247             }\r
248             if (url.EndsWith("api_get_member/ship_deck"))\r
249             {\r
250                 _shipInfo.InspectShip(data);\r
251                 _akashiTimer.CheckFleet();\r
252                 _battleInfo.BattleState = BattleState.None;\r
253                 return Update.Ship | Update.Battle | Update.Item;\r
254             }\r
255             if (url.EndsWith("api_get_member/ship3"))\r
256             {\r
257                 _shipInfo.InspectShip(data);\r
258                 _akashiTimer.CheckFleet();\r
259                 _conditionTimer.CheckCond();\r
260                 return Update.Ship;\r
261             }\r
262             if (url.EndsWith("api_get_member/material"))\r
263             {\r
264                 _materialInfo.InspectMaterial(data);\r
265                 return Update.Item;\r
266             }\r
267             if (url.EndsWith("api_get_member/mapinfo"))\r
268             {\r
269                 _exMapInfo.InspectMapInfo(data);\r
270                 _miscTextInfo.InspectMapInfo(data);\r
271                 if (data.api_air_base())\r
272                     _baseAirCoprs.Inspect(data.api_air_base);\r
273                 return Update.Item;\r
274             }\r
275             if (url.EndsWith("api_req_member/get_practice_enemyinfo"))\r
276             {\r
277                 _miscTextInfo.InspectPracticeEnemyInfo(data);\r
278                 return Update.Item;\r
279             }\r
280             if (url.EndsWith("api_get_member/preset_deck"))\r
281             {\r
282                 _presetDeck.Inspect(data);\r
283                 return Update.None;\r
284             }\r
285             if (url.EndsWith("api_get_member/base_air_corps"))\r
286             {\r
287                 _baseAirCoprs.Inspect(data);\r
288                 return Update.Ship;\r
289             }\r
290             return Update.None;\r
291         }\r
292 \r
293         private Update ApiKousyou(string url, string request, dynamic data)\r
294         {\r
295             if (url.EndsWith("api_req_kousyou/createitem"))\r
296             {\r
297                 _itemInfo.InspectCreateItem(data);\r
298                 _materialInfo.InspectCreateIem(data);\r
299                 _logger.InspectCreateItem(request, data);\r
300                 _questInfo.CountCreateItem();\r
301                 return Update.Item | Update.QuestList;\r
302             }\r
303             if (url.EndsWith("api_req_kousyou/getship"))\r
304             {\r
305                 _itemInfo.InspectGetShip(data);\r
306                 _shipInfo.InspectShip(data);\r
307                 _dockInfo.InspectKDock(data.api_kdock);\r
308                 _conditionTimer.CheckCond();\r
309                 RepeatingTimerController?.Stop("建造完了");\r
310                 return Update.Item | Update.Timer;\r
311             }\r
312             if (url.EndsWith("api_req_kousyou/destroyship"))\r
313             {\r
314                 _shipInfo.InspectDestroyShip(request, data);\r
315                 _materialInfo.InspectDestroyShip(data);\r
316                 _conditionTimer.CheckCond();\r
317                 _akashiTimer.CheckFleet();\r
318                 _questInfo.InspectDestroyShip(request);\r
319                 return Update.Item | Update.Ship | Update.QuestList;\r
320             }\r
321             if (url.EndsWith("api_req_kousyou/destroyitem2"))\r
322             {\r
323                 _questInfo.InspectDestroyItem(request, data); // 本当に削除される前\r
324                 _itemInfo.InspectDestroyItem(request, data);\r
325                 _materialInfo.InspectDestroyItem(data);\r
326                 return Update.Item | Update.QuestList;\r
327             }\r
328             if (url.EndsWith("api_req_kousyou/remodel_slot"))\r
329             {\r
330                 _logger.SetCurrentMaterial(_materialInfo.Current);\r
331                 _logger.InspectRemodelSlot(request, data); // 資材の差が必要なので_materialInfoより前\r
332                 _itemInfo.InspectRemodelSlot(data);\r
333                 _materialInfo.InspectRemodelSlot(data);\r
334                 _questInfo.CountRemodelSlot();\r
335                 return Update.Item | Update.QuestList;\r
336             }\r
337             if (url.EndsWith("api_req_kousyou/createship"))\r
338             {\r
339                 _logger.InspectCreateShip(request);\r
340                 _questInfo.CountCreateShip();\r
341                 return Update.QuestList;\r
342             }\r
343             if (url.EndsWith("api_req_kousyou/createship_speedchange"))\r
344             {\r
345                 _dockInfo.InspectCreateShipSpeedChange(request);\r
346                 return Update.Timer;\r
347             }\r
348             return Update.None;\r
349         }\r
350 \r
351         private Update ApiBattle(string url, string request, dynamic data)\r
352         {\r
353             if (IsNormalBattleAPI(url) || IsCombinedBattleAPI(url))\r
354             {\r
355                 _battleInfo.InspectBattle(url, request, data);\r
356                 _logger.InspectBattle(data);\r
357                 _cellInfo.StartBattle();\r
358                 return Update.Ship | Update.Battle;\r
359             }\r
360             if (url.EndsWith("api_req_practice/battle") || url.EndsWith("api_req_practice/midnight_battle"))\r
361             {\r
362                 if (url.EndsWith("/battle"))\r
363                 {\r
364                     _shipInfo.StartPractice(request);\r
365                     _questInfo.StartPractice(request);\r
366                     _cellInfo.StartPractice();\r
367                     _conditionTimer.InvalidateCond();\r
368                     RepeatingTimerController?.Suspend();\r
369                 }\r
370                 _battleInfo.InspectBattle(url, request, data);\r
371                 return Update.Ship | Update.Battle | Update.Timer;\r
372             }\r
373             if (url.EndsWith("api_req_sortie/battleresult") || url.EndsWith("api_req_combined_battle/battleresult"))\r
374             {\r
375                 _battleInfo.InspectBattleResult(data);\r
376                 _exMapInfo.InspectBattleResult(data);\r
377                 _logger.InspectBattleResult(data);\r
378                 _questInfo.InspectBattleResult(data);\r
379                 _miscTextInfo.InspectBattleResult(data);\r
380                 return Update.Ship | Update.QuestList;\r
381             }\r
382             if (url.EndsWith("api_req_practice/battle_result"))\r
383             {\r
384                 _battleInfo.InspectPracticeResult(data);\r
385                 _questInfo.InspectPracticeResult(data);\r
386                 return Update.Ship | Update.QuestList;\r
387             }\r
388             if (url.EndsWith("/goback_port"))\r
389             {\r
390                 _battleInfo.CauseEscape();\r
391                 return Update.Ship;\r
392             }\r
393             _battleInfo.BattleState = BattleState.Unknown;\r
394             return Update.None;\r
395         }\r
396 \r
397         private bool IsNormalBattleAPI(string url)\r
398         {\r
399             return url.EndsWith("api_req_sortie/battle") ||\r
400                    url.EndsWith("api_req_sortie/airbattle") ||\r
401                    url.EndsWith("api_req_sortie/ld_airbattle") ||\r
402                    url.EndsWith("api_req_battle_midnight/battle") ||\r
403                    url.EndsWith("api_req_battle_midnight/sp_midnight");\r
404         }\r
405 \r
406         private bool IsCombinedBattleAPI(string url)\r
407         {\r
408             return url.EndsWith("api_req_combined_battle/battle") ||\r
409                    url.EndsWith("api_req_combined_battle/airbattle") ||\r
410                    url.EndsWith("api_req_combined_battle/ld_airbattle") ||\r
411                    url.EndsWith("api_req_combined_battle/battle_water") ||\r
412                    url.EndsWith("api_req_combined_battle/midnight_battle") ||\r
413                    url.EndsWith("api_req_combined_battle/sp_midnight") ||\r
414                    url.EndsWith("api_req_combined_battle/ec_battle") ||\r
415                    url.EndsWith("api_req_combined_battle/ec_midnight_battle") ||\r
416                    url.EndsWith("api_req_combined_battle/ec_night_to_day") ||\r
417                    url.EndsWith("api_req_combined_battle/each_battle") ||\r
418                    url.EndsWith("api_req_combined_battle/each_battle_water");\r
419         }\r
420 \r
421         private Update ApiHensei(string url, string request, dynamic data)\r
422         {\r
423             if (url.EndsWith("api_req_hensei/change"))\r
424             {\r
425                 _shipInfo.InspectChange(request);\r
426                 _akashiTimer.InspectChange(request);\r
427                 return Update.Ship;\r
428             }\r
429             if (url.EndsWith("api_req_hensei/preset_select"))\r
430             {\r
431                 _shipInfo.InspectDeck(new[] {data});\r
432                 _akashiTimer.CheckFleet();\r
433                 return Update.Ship;\r
434             }\r
435             if (url.EndsWith("api_req_hensei/preset_register"))\r
436             {\r
437                 _presetDeck.InspectRegister(data);\r
438                 return Update.None;\r
439             }\r
440             if (url.EndsWith("api_req_hensei/preset_delete"))\r
441             {\r
442                 _presetDeck.InspectDelete(request);\r
443                 return Update.Timer;\r
444             }\r
445             if (url.EndsWith("api_req_hensei/combined"))\r
446             {\r
447                 _shipInfo.InspectCombined(request);\r
448                 return Update.Ship;\r
449             }\r
450             return Update.None;\r
451         }\r
452 \r
453         private Update ApiAirCorps(string url, string request, dynamic data)\r
454         {\r
455             if (url.EndsWith("api_req_air_corps/supply"))\r
456             {\r
457                 _materialInfo.InspectAirCorpsSupply(data);\r
458                 _baseAirCoprs.InspectSupply(request, data);\r
459                 return Update.Item;\r
460             }\r
461             if (url.EndsWith("api_req_air_corps/set_plane"))\r
462             {\r
463                 _materialInfo.InspectAirCorpsSetPlane(data);\r
464                 _baseAirCoprs.InspectSetPlane(request, data);\r
465                 return Update.Item | Update.Ship;\r
466             }\r
467             if (url.EndsWith("api_req_air_corps/set_action"))\r
468             {\r
469                 _baseAirCoprs.InspectSetAction(request);\r
470                 return Update.Ship;\r
471             }\r
472             if (url.EndsWith("api_req_air_corps/expand_base"))\r
473             {\r
474                 _baseAirCoprs.InspectExpandBase(request, data);\r
475                 return Update.Ship;\r
476             }\r
477             return Update.None;\r
478         }\r
479 \r
480         private Update ApiOthers(string url, string request, dynamic data)\r
481         {\r
482             if (url.EndsWith("api_req_hokyu/charge"))\r
483             {\r
484                 _shipInfo.InspectCharge(data);\r
485                 _materialInfo.InspectCharge(data);\r
486                 _questInfo.CountCharge();\r
487                 return Update.Item | Update.Ship | Update.QuestList;\r
488             }\r
489             if (url.EndsWith("api_req_kaisou/powerup"))\r
490             {\r
491                 _shipInfo.InspectPowerup(request, data);\r
492                 _conditionTimer.CheckCond();\r
493                 _akashiTimer.CheckFleet();\r
494                 _questInfo.InspectPowerup(data);\r
495                 return Update.Item | Update.Ship | Update.QuestList;\r
496             }\r
497             if (url.EndsWith("api_req_kaisou/slot_exchange_index"))\r
498             {\r
499                 _shipInfo.InspectSlotExchange(request, data);\r
500                 return Update.Ship;\r
501             }\r
502             if (url.EndsWith("api_req_kaisou/slot_deprive"))\r
503             {\r
504                 _shipInfo.InspectSlotDeprive(data);\r
505                 return Update.Ship;\r
506             }\r
507             if (url.EndsWith("api_req_nyukyo/start"))\r
508             {\r
509                 _dockInfo.InspectNyukyo(request);\r
510                 _conditionTimer.CheckCond();\r
511                 _akashiTimer.CheckFleet();\r
512                 _questInfo.CountNyukyo();\r
513                 var ndock = HttpUtility.ParseQueryString(request)["api_ndock_id"];\r
514                 if (ndock != null && int.TryParse(ndock, out int id))\r
515                     RepeatingTimerController?.Stop("入渠終了", id - 1);\r
516                 return Update.Item | Update.Ship | Update.QuestList;\r
517             }\r
518             if (url.EndsWith("api_req_nyukyo/speedchange"))\r
519             {\r
520                 _dockInfo.InspectSpeedChange(request);\r
521                 _conditionTimer.CheckCond();\r
522                 return Update.NDock | Update.Timer | Update.Item | Update.Ship;\r
523             }\r
524             if (url.EndsWith("api_req_map/start"))\r
525             {\r
526                 _shipInfo.InspectMapStart(request); // 出撃中判定が必要なので_conditionTimerより前\r
527                 _conditionTimer.InvalidateCond();\r
528                 _exMapInfo.InspectMapStart(data);\r
529                 _battleInfo.InspectMapStart(data);\r
530                 _logger.InspectMapStart(data);\r
531                 _miscTextInfo.InspectMapStart(data);\r
532                 _questInfo.InspectMapStart(data);\r
533                 _cellInfo.InspectMapStart(data);\r
534                 RepeatingTimerController?.Suspend("大破警告");\r
535                 return Update.Timer | Update.Ship | Update.Cell;\r
536             }\r
537             if (url.EndsWith("api_req_map/next"))\r
538             {\r
539                 _exMapInfo.InspectMapNext(data);\r
540                 _battleInfo.InspectMapNext(data);\r
541                 _logger.InspectMapNext(data);\r
542                 _questInfo.InspectMapNext(data);\r
543                 _miscTextInfo.InspectMapNext(data);\r
544                 _cellInfo.InspectMapNext(data);\r
545                 return Update.Cell;\r
546             }\r
547             if (url.EndsWith("api_req_mission/start"))\r
548             {\r
549                 var deck = HttpUtility.ParseQueryString(request)["api_deck_id"];\r
550                 if (deck != null && int.TryParse(deck, out int id))\r
551                     RepeatingTimerController?.Stop("遠征終了", id - 1);\r
552                 return Update.None;\r
553             }\r
554             if (url.EndsWith("api_req_mission/result"))\r
555             {\r
556                 _materialInfo.InspectMissionResult(data);\r
557                 _logger.InspectMissionResult(data);\r
558                 _questInfo.InspectMissionResult(request, data);\r
559                 return Update.Item;\r
560             }\r
561             if (url.EndsWith("api_req_quest/stop"))\r
562             {\r
563                 _questInfo.InspectStop(request);\r
564                 return Update.QuestList;\r
565             }\r
566             if (url.EndsWith("api_req_quest/clearitemget"))\r
567             {\r
568                 _questInfo.InspectClearItemGet(request);\r
569                 _logger.InspectClearItemGet(data);\r
570                 return Update.QuestList;\r
571             }\r
572             return Update.None;\r
573         }\r
574 \r
575         public NameAndTimer[] NDock => _dockInfo.NDock;\r
576 \r
577         public AlarmTimer[] KDock => _dockInfo.KDock;\r
578 \r
579         public ItemInfo Item => _itemInfo;\r
580 \r
581         public MaterialInfo Material => _materialInfo;\r
582 \r
583         public QuestStatus[] Quests => _questInfo.Quests;\r
584 \r
585         public void ClearQuests() => _questInfo.ClearQuests();\r
586 \r
587         public NameAndTimer[] Missions => _missionInfo.Missions;\r
588 \r
589         public DateTime GetConditionTimer(int fleet) => _conditionTimer.GetTimer(fleet);\r
590 \r
591         public int[] GetConditionNotice(DateTime prev, DateTime now) => _conditionTimer.GetNotice(prev, now);\r
592 \r
593         public Fleet[] Fleets => _shipInfo.Fleets;\r
594 \r
595         public ShipInfo.ShipStatusPair[] BattleResultStatusDiff => _shipInfo.BattleResultDiff;\r
596 \r
597         public bool IsBattleResultStatusError => _shipInfo.IsBattleResultError;\r
598 \r
599         public ShipStatus[] BattleStartStatus => _shipInfo.BattleStartStatus;\r
600 \r
601         public bool IsCombinedFleet => _shipInfo.Fleets[0].CombinedType != 0;\r
602 \r
603         public ShipStatus[] RepairList => _shipInfo.GetRepairList(_dockInfo);\r
604 \r
605         public ShipStatus[] ShipList => _shipInfo.ShipList;\r
606 \r
607         public string[] BadlyDamagedShips => _shipInfo.BadlyDamagedShips;\r
608 \r
609         public ItemStatus[] ItemList\r
610         {\r
611             get\r
612             {\r
613                 _itemInfo.ClearHolder();\r
614                 _shipInfo.SetItemHolder();\r
615                 _baseAirCoprs.SetItemHolder();\r
616                 return _itemInfo.ItemList;\r
617             }\r
618         }\r
619 \r
620         public AkashiTimer AkashiTimer => _akashiTimer;\r
621 \r
622         public Achievement Achievement => _achievement;\r
623 \r
624         public BattleInfo Battle => _battleInfo;\r
625 \r
626         public ExMapInfo ExMap => _exMapInfo;\r
627 \r
628         public string MiscText => _miscTextInfo.Text;\r
629 \r
630         public BaseAirCoprs.BaseInfo[] BaseAirCorps => _baseAirCoprs.AllAirCorps;\r
631 \r
632         public CellInfo CellInfo => _cellInfo;\r
633 \r
634         public void SetLogWriter(Action<string, string, string> writer, Func<DateTime> nowFunc)\r
635         {\r
636             _logger.SetWriter(writer, nowFunc);\r
637         }\r
638 \r
639         public void SkipMaster()\r
640         {\r
641             _start = true;\r
642         }\r
643 \r
644         public void EnableLog(LogType type)\r
645         {\r
646             _logger.EnableLog(type);\r
647         }\r
648 \r
649         public int MaterialLogInterval\r
650         {\r
651             set => _logger.MaterialLogInterval = value;\r
652         }\r
653 \r
654         public string LogOutputDir\r
655         {\r
656             set => _logger.OutputDir = value;\r
657         }\r
658 \r
659         public void FlashLog()\r
660         {\r
661             _logger.FlashLog();\r
662         }\r
663     }\r
664 }