OSDN Git Service

バージョン12.11の準備
[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 KancolleSniffer.Util;\r
17 using System.Collections.Generic;\r
18 using System.Linq;\r
19 using KancolleSniffer.Log;\r
20 using KancolleSniffer.Model;\r
21 \r
22 namespace KancolleSniffer\r
23 {\r
24     public class Sniffer\r
25     {\r
26         private readonly ItemMaster _itemMaster = new ItemMaster();\r
27         private readonly ItemInventory _itemInventory = new ItemInventory();\r
28         private readonly ItemInfo _itemInfo;\r
29         private readonly ShipMaster _shipMaster = new ShipMaster();\r
30         private readonly ShipInventory _shipInventory = new ShipInventory();\r
31         private readonly ShipInfo _shipInfo;\r
32         private readonly MaterialInfo _materialInfo = new MaterialInfo();\r
33         private readonly QuestInfo _questInfo;\r
34         private readonly QuestCounter _questCounter;\r
35         private readonly QuestCountList _questCountList = new QuestCountList();\r
36         private readonly MissionInfo _missionInfo = new MissionInfo();\r
37         private readonly ConditionTimer _conditionTimer;\r
38         private readonly DockInfo _dockInfo;\r
39         private readonly AkashiTimer _akashiTimer;\r
40         private readonly Achievement _achievement = new Achievement();\r
41         private readonly BattleInfo _battleInfo;\r
42         private readonly Logger _logger;\r
43         private readonly ExMapInfo _exMapInfo = new ExMapInfo();\r
44         private readonly MiscTextInfo _miscTextInfo;\r
45         private readonly AirBase _airBase;\r
46         private readonly PresetDeck _presetDeck = new PresetDeck();\r
47         private readonly CellInfo _cellInfo = new CellInfo();\r
48         private readonly Status _status = new Status();\r
49         private bool _saveState;\r
50         private readonly List<IHaveState> _haveState;\r
51         private AdditionalData _additionalData;\r
52 \r
53         public interface IRepeatingTimerController\r
54         {\r
55             void Stop(string key);\r
56             void Stop(string key, int fleet);\r
57             void Suspend(string exception = null);\r
58             void Resume();\r
59         }\r
60 \r
61         public IRepeatingTimerController RepeatingTimerController { get; set; }\r
62 \r
63         public Dictionary<string, string> MapDictionary { get; } = new Dictionary<string, string>\r
64         {\r
65             {"南西作戦海域方面 バリ島沖", "42-1"},\r
66             {"西方作戦海域方面 マラッカ海峡北方", "42-2"},\r
67             {"西方作戦海域方面 セイロン島南西沖", "42-3"},\r
68             {"欧州作戦海域方面 地中海マルタ島沖", "42-4"},\r
69             {"欧州作戦海域方面 北海/北大西洋海域", "42-5"}\r
70         };\r
71 \r
72         [Flags]\r
73         public enum Update\r
74         {\r
75             None = 0,\r
76             Error = 1,\r
77             Start = 1 << 1,\r
78             Item = 1 << 2,\r
79             Ship = 1 << 3,\r
80             Timer = 1 << 4,\r
81             NDock = 1 << 5,\r
82             Mission = 1 << 6,\r
83             QuestList = 1 << 7,\r
84             Battle = 1 << 8,\r
85             Cell = 1 << 9,\r
86             All = (1 << 10) - 1\r
87         }\r
88 \r
89         public bool Started { get; private set; }\r
90 \r
91         public Sniffer(bool started = false)\r
92         {\r
93             Started = started;\r
94             _itemInfo = new ItemInfo(_itemMaster, _itemInventory);\r
95             _shipInfo = new ShipInfo(_shipMaster, _shipInventory, _itemInventory);\r
96             _conditionTimer = new ConditionTimer(_shipInfo);\r
97             _dockInfo = new DockInfo(_shipInventory, _materialInfo);\r
98             _akashiTimer = new AkashiTimer(_shipInfo, _dockInfo, _presetDeck);\r
99             _airBase = new AirBase(_itemInfo);\r
100             _battleInfo = new BattleInfo(_shipInfo, _itemInfo, _airBase);\r
101             _logger = new Logger(_shipInfo, _itemInfo, _battleInfo);\r
102             _questInfo = new QuestInfo(_questCountList);\r
103             _questCounter = new QuestCounter(_questInfo, _itemInventory, _shipInventory, _battleInfo);\r
104             _miscTextInfo = new MiscTextInfo(_shipInfo, _itemInfo);\r
105             _haveState = new List<IHaveState> {_achievement, _materialInfo, _conditionTimer, _exMapInfo, _questInfo};\r
106             AdditionalData = new AdditionalData();\r
107         }\r
108 \r
109         public AdditionalData AdditionalData\r
110         {\r
111             get => _additionalData;\r
112             private set\r
113             {\r
114                 _additionalData = value;\r
115                 _itemMaster.AdditionalData = value;\r
116                 _shipMaster.AdditionalData = value;\r
117             }\r
118         }\r
119 \r
120         public void SaveState()\r
121         {\r
122             if (!_saveState)\r
123                 return;\r
124             if (!_haveState.Any(x => x.NeedSave))\r
125                 return;\r
126             foreach (var x in _haveState)\r
127                 x.SaveState(_status);\r
128             _status.Save();\r
129         }\r
130 \r
131         public void LoadState()\r
132         {\r
133             _status.Load();\r
134             foreach (var x in _haveState)\r
135                 x.LoadState(_status);\r
136             _saveState = true;\r
137         }\r
138 \r
139         public Update Sniff(string url, string request, dynamic json)\r
140         {\r
141             if (!json.api_result())\r
142                 return Update.Error;\r
143             if ((int)json.api_result != 1)\r
144                 return Update.None;\r
145             var data = json.api_data() ? json.api_data : new object();\r
146 \r
147             if (url.Contains("api_start2"))\r
148             {\r
149                 return ApiStart(data);\r
150             }\r
151             if (!Started)\r
152                 return Update.None;\r
153 \r
154             if (url.EndsWith("api_port/port"))\r
155                 return ApiPort(data);\r
156             if (url.Contains("member"))\r
157                 return ApiMember(url, request,json);\r
158             if (url.Contains("kousyou"))\r
159                 return ApiKousyou(url, request, data);\r
160             if (url.Contains("practice"))\r
161                 return ApiPractice(url, request, data);\r
162             if (IsBattleAPI(url))\r
163                 return ApiBattle(url, request, data);\r
164             if (url.Contains("hensei"))\r
165                 return ApiHensei(url, request, data);\r
166             if (url.Contains("kaisou"))\r
167                 return ApiKaisou(url, request, data);\r
168             if (url.Contains("air_corps"))\r
169                 return ApiAirCorps(url, request, data);\r
170             if (url.Contains("map"))\r
171                 return ApiMap(url, request, data);\r
172             return ApiOthers(url, request, data);\r
173         }\r
174 \r
175         private static bool IsBattleAPI(string url)\r
176         {\r
177             return url.Contains("api_req_sortie/") ||\r
178                    url.Contains("api_req_battle_midnight/") ||\r
179                    url.Contains("api_req_combined_battle/");\r
180         }\r
181 \r
182         private Update ApiStart(dynamic data)\r
183         {\r
184             _shipInfo.InspectMaster(data);\r
185             _shipInfo.ClearBattleResult();\r
186             _missionInfo.InspectMaster(data.api_mst_mission);\r
187             _itemInfo.InspectMaster(data);\r
188             _exMapInfo.ResetIfNeeded();\r
189             _miscTextInfo.InspectMaster(data);\r
190             _logger.InspectMapInfoMaster(data.api_mst_mapinfo);\r
191             SetMapDictionary(data.api_mst_mapinfo);\r
192             _questCountList.SetMissionNames(data.api_mst_mission);\r
193             Started = true;\r
194             return Update.Start;\r
195         }\r
196 \r
197         private void SetMapDictionary(dynamic json)\r
198         {\r
199             foreach (var map in json)\r
200                 MapDictionary[map.api_name] = $"{map.api_maparea_id}-{map.api_no}";\r
201         }\r
202 \r
203         public interface IPort\r
204         {\r
205             void Port();\r
206         }\r
207 \r
208         private Update ApiPort(dynamic data)\r
209         {\r
210             _itemInfo.InspectBasic(data.api_basic);\r
211             _materialInfo.InspectMaterialPort(data.api_material);\r
212             _logger.InspectBasic(data.api_basic);\r
213             _logger.InspectMaterial(data.api_material);\r
214             _shipInfo.Port(data);\r
215             _missionInfo.InspectDeck(data.api_deck_port);\r
216             _questCounter.InspectDeck(data.api_deck_port);\r
217             _dockInfo.InspectNDock(data.api_ndock);\r
218             _achievement.InspectBasic(data.api_basic);\r
219             if (data.api_event_object())\r
220                 _airBase.InspectEventObject(data.api_event_object);\r
221             if (data.api_plane_info())\r
222                 _airBase.InspectPlaneInfo(data.api_plane_info);\r
223             foreach (var receiver in new IPort[]{_conditionTimer, _akashiTimer, _battleInfo, _miscTextInfo, _cellInfo})\r
224                 receiver.Port();\r
225             SaveState();\r
226             RepeatingTimerController?.Resume();\r
227             foreach (var s in new[] {"遠征終了", "入渠終了", "疲労回復", "泊地修理", "大破警告"})\r
228                 RepeatingTimerController?.Stop(s);\r
229             return Update.All;\r
230         }\r
231 \r
232         private Update ApiMember(string url, string request, dynamic json)\r
233         {\r
234             var data = json.api_data() ? json.api_data : new object();\r
235 \r
236             if (url.EndsWith("api_get_member/require_info"))\r
237             {\r
238                 _itemInfo.InspectSlotItem(data.api_slot_item, true);\r
239                 if (data.api_useitem())\r
240                     _itemInfo.InspectUseItem(data.api_useitem);\r
241                 _dockInfo.InspectKDock(data.api_kdock);\r
242                 return Update.None;\r
243             }\r
244             if (url.EndsWith("api_get_member/basic"))\r
245             {\r
246                 _itemInfo.InspectBasic(data);\r
247                 _logger.InspectBasic(data);\r
248                 return Update.None;\r
249             }\r
250             if (url.EndsWith("api_get_member/slot_item"))\r
251             {\r
252                 _itemInfo.InspectSlotItem(data, true);\r
253                 return Update.Item;\r
254             }\r
255             if (url.EndsWith("api_get_member/useitem"))\r
256             {\r
257                 if (data == null)\r
258                     return Update.None;\r
259                 _itemInfo.InspectUseItem(data);\r
260                 return Update.Item;\r
261             }\r
262             if (url.EndsWith("api_get_member/kdock"))\r
263             {\r
264                 _dockInfo.InspectKDock(data);\r
265                 _logger.InspectKDock(data);\r
266                 return Update.Timer;\r
267             }\r
268             if (url.EndsWith("api_get_member/ndock"))\r
269             {\r
270                 _dockInfo.InspectNDock(data);\r
271                 _conditionTimer.CheckCond();\r
272                 _akashiTimer.CheckFleet();\r
273                 RepeatingTimerController?.Stop("入渠終了");\r
274                 return Update.NDock | Update.Timer | Update.Ship;\r
275             }\r
276             if (url.EndsWith("api_get_member/questlist"))\r
277             {\r
278                 _questInfo.InspectQuestList(request, data);\r
279                 return Update.QuestList;\r
280             }\r
281             if (url.EndsWith("api_get_member/deck"))\r
282             {\r
283                 _shipInfo.InspectDeck(data);\r
284                 _missionInfo.InspectDeck(data);\r
285                 _akashiTimer.CheckFleet();\r
286                 _questCounter.InspectDeck(data);\r
287                 return Update.Mission | Update.Timer;\r
288             }\r
289             if (url.EndsWith("api_get_member/ship2"))\r
290             {\r
291                 // ここだけjsonなので注意\r
292                 _shipInfo.InspectShip(url, json);\r
293                 _akashiTimer.CheckFleet();\r
294                 _battleInfo.BattleState = BattleState.None;\r
295                 return Update.Item | Update.Ship;\r
296             }\r
297             if (url.EndsWith("api_get_member/ship_deck"))\r
298             {\r
299                 _shipInfo.InspectShip(url, data);\r
300                 _akashiTimer.CheckFleet();\r
301                 _battleInfo.BattleState = BattleState.None;\r
302                 return Update.Ship | Update.Item;\r
303             }\r
304             if (url.EndsWith("api_get_member/ship3"))\r
305             {\r
306                 _shipInfo.InspectShip(url, data);\r
307                 _akashiTimer.CheckFleet();\r
308                 _conditionTimer.CheckCond();\r
309                 return Update.Ship;\r
310             }\r
311             if (url.EndsWith("api_get_member/material"))\r
312             {\r
313                 _materialInfo.InspectMaterial(data);\r
314                 return Update.Item;\r
315             }\r
316             if (url.EndsWith("api_get_member/mapinfo"))\r
317             {\r
318                 _exMapInfo.InspectMapInfo(data);\r
319                 _miscTextInfo.InspectMapInfo(data);\r
320                 if (data.api_air_base())\r
321                     _airBase.Inspect(data.api_air_base);\r
322                 return Update.Item;\r
323             }\r
324             if (url.EndsWith("api_req_member/get_practice_enemyinfo"))\r
325             {\r
326                 _miscTextInfo.InspectPracticeEnemyInfo(data);\r
327                 return Update.Item;\r
328             }\r
329             if (url.EndsWith("api_get_member/preset_deck"))\r
330             {\r
331                 _presetDeck.Inspect(data);\r
332                 return Update.None;\r
333             }\r
334             if (url.EndsWith("api_get_member/base_air_corps"))\r
335             {\r
336                 _airBase.Inspect(data);\r
337                 return Update.Ship;\r
338             }\r
339             return Update.None;\r
340         }\r
341 \r
342         private Update ApiKousyou(string url, string request, dynamic data)\r
343         {\r
344             if (url.EndsWith("api_req_kousyou/createitem"))\r
345             {\r
346                 _itemInfo.InspectCreateItem(data);\r
347                 _materialInfo.InspectCreateIem(data);\r
348                 _logger.InspectCreateItem(request, data);\r
349                 _questCounter.InspectCreateItem(request);\r
350                 return Update.Item | Update.QuestList;\r
351             }\r
352             if (url.EndsWith("api_req_kousyou/getship"))\r
353             {\r
354                 _itemInfo.InspectGetShip(data);\r
355                 _shipInfo.InspectShip(url, data);\r
356                 _dockInfo.InspectKDock(data.api_kdock);\r
357                 _conditionTimer.CheckCond();\r
358                 RepeatingTimerController?.Stop("建造完了");\r
359                 return Update.Item | Update.Timer;\r
360             }\r
361             if (url.EndsWith("api_req_kousyou/destroyship"))\r
362             {\r
363                 _shipInfo.InspectDestroyShip(request);\r
364                 _materialInfo.InspectDestroyShip(data);\r
365                 _conditionTimer.CheckCond();\r
366                 _akashiTimer.CheckFleet();\r
367                 _questCounter.InspectDestroyShip(request);\r
368                 return Update.Item | Update.Ship | Update.QuestList;\r
369             }\r
370             if (url.EndsWith("api_req_kousyou/destroyitem2"))\r
371             {\r
372                 _questCounter.InspectDestroyItem(request); // 本当に削除される前\r
373                 _itemInfo.InspectDestroyItem(request);\r
374                 _materialInfo.InspectDestroyItem(data);\r
375                 return Update.Item | Update.QuestList;\r
376             }\r
377             if (url.EndsWith("api_req_kousyou/remodel_slot"))\r
378             {\r
379                 _logger.SetCurrentMaterial(_materialInfo.Current);\r
380                 _logger.InspectRemodelSlot(request, data); // 資材の差が必要なので_materialInfoより前\r
381                 _itemInfo.InspectRemodelSlot(data);\r
382                 _materialInfo.InspectRemodelSlot(data);\r
383                 _questCounter.CountRemodelSlot();\r
384                 return Update.Item | Update.QuestList;\r
385             }\r
386             if (url.EndsWith("api_req_kousyou/createship"))\r
387             {\r
388                 _logger.InspectCreateShip(request);\r
389                 _questCounter.CountCreateShip();\r
390                 return Update.QuestList;\r
391             }\r
392             if (url.EndsWith("api_req_kousyou/createship_speedchange"))\r
393             {\r
394                 _dockInfo.InspectCreateShipSpeedChange(request);\r
395                 return Update.Timer;\r
396             }\r
397             return Update.None;\r
398         }\r
399 \r
400         private Update ApiPractice(string url, string request, dynamic data)\r
401         {\r
402             if (url.EndsWith("api_req_practice/battle_result"))\r
403             {\r
404                 _battleInfo.InspectPracticeResult(data);\r
405                 _questCounter.InspectPracticeResult(data);\r
406                 return Update.Ship | Update.QuestList;\r
407             }\r
408             if (url.EndsWith("api_req_practice/battle"))\r
409             {\r
410                 _shipInfo.StartPractice(request);\r
411                 _questCounter.StartPractice(request);\r
412                 _cellInfo.StartPractice();\r
413                 _conditionTimer.InvalidateCond();\r
414                 RepeatingTimerController?.Suspend();\r
415             }\r
416             if (url.EndsWith("api_req_practice/battle") || url.EndsWith("api_req_practice/midnight_battle"))\r
417             {\r
418                 _battleInfo.InspectBattle(url, request, data);\r
419                 return Update.Ship | Update.Battle | Update.Timer;\r
420             }\r
421             return Update.None;\r
422         }\r
423 \r
424         private Update ApiBattle(string url, string request, dynamic data)\r
425         {\r
426             if (url.EndsWith("/battleresult"))\r
427             {\r
428                 _battleInfo.InspectBattleResult(data);\r
429                 _exMapInfo.InspectBattleResult(data);\r
430                 _logger.InspectBattleResult(data);\r
431                 _questCounter.InspectBattleResult(data);\r
432                 _miscTextInfo.InspectBattleResult(data);\r
433                 return Update.Ship | Update.QuestList;\r
434             }\r
435             if (url.EndsWith("/goback_port"))\r
436             {\r
437                 _battleInfo.CauseEscape();\r
438                 return Update.Ship;\r
439             }\r
440             _shipInfo.ClearBadlyDamagedShips();\r
441             RepeatingTimerController?.Stop("大破警告");\r
442             _battleInfo.InspectBattle(url, request, data);\r
443             _cellInfo.StartBattle();\r
444             return Update.Ship | Update.Battle;\r
445         }\r
446 \r
447         private Update ApiHensei(string url, string request, dynamic data)\r
448         {\r
449             if (url.EndsWith("api_req_hensei/change"))\r
450             {\r
451                 _shipInfo.InspectChange(request);\r
452                 _akashiTimer.InspectChange(request);\r
453                 return Update.Ship;\r
454             }\r
455             if (url.EndsWith("api_req_hensei/preset_select"))\r
456             {\r
457                 _shipInfo.InspectDeck(new[] {data});\r
458                 _akashiTimer.CheckFleet();\r
459                 return Update.Ship;\r
460             }\r
461             if (url.EndsWith("api_req_hensei/preset_register"))\r
462             {\r
463                 _presetDeck.InspectRegister(data);\r
464                 return Update.None;\r
465             }\r
466             if (url.EndsWith("api_req_hensei/preset_delete"))\r
467             {\r
468                 _presetDeck.InspectDelete(request);\r
469                 return Update.Timer;\r
470             }\r
471             if (url.EndsWith("api_req_hensei/combined"))\r
472             {\r
473                 _shipInfo.InspectCombined(request);\r
474                 return Update.Ship;\r
475             }\r
476             return Update.None;\r
477         }\r
478 \r
479         private Update ApiKaisou(string url, string request, dynamic data)\r
480         {\r
481             if (url.EndsWith("api_req_kaisou/powerup"))\r
482             {\r
483                 _questCounter.InspectPowerUp(request, data); // 艦種が必要なので艦が消える前\r
484                 _shipInfo.InspectPowerUp(request, data);\r
485                 _conditionTimer.CheckCond();\r
486                 _akashiTimer.CheckFleet();\r
487                 return Update.Item | Update.Ship | Update.QuestList;\r
488             }\r
489             if (url.EndsWith("api_req_kaisou/slot_exchange_index"))\r
490             {\r
491                 _shipInfo.InspectSlotExchange(data);\r
492                 return Update.Ship;\r
493             }\r
494             if (url.EndsWith("api_req_kaisou/slot_deprive"))\r
495             {\r
496                 _shipInfo.InspectSlotDeprive(data);\r
497                 return Update.Ship;\r
498             }\r
499             if (url.EndsWith("api_req_kaisou/marriage"))\r
500             {\r
501                 _shipInfo.InspectMarriage(data);\r
502                 return Update.Ship;\r
503             }\r
504             return Update.None;\r
505         }\r
506 \r
507         private Update ApiAirCorps(string url, string request, dynamic data)\r
508         {\r
509             if (url.EndsWith("api_req_air_corps/supply"))\r
510             {\r
511                 _materialInfo.InspectAirCorpsSupply(data);\r
512                 _airBase.InspectSupply(request, data);\r
513                 return Update.Item;\r
514             }\r
515             if (url.EndsWith("api_req_air_corps/set_plane"))\r
516             {\r
517                 _materialInfo.InspectAirCorpsSetPlane(data);\r
518                 _airBase.InspectSetPlane(request, data);\r
519                 return Update.Item | Update.Ship;\r
520             }\r
521             if (url.EndsWith("api_req_air_corps/set_action"))\r
522             {\r
523                 _airBase.InspectSetAction(request);\r
524                 return Update.Ship;\r
525             }\r
526             if (url.EndsWith("api_req_air_corps/expand_base"))\r
527             {\r
528                 _airBase.InspectExpandBase(request, data);\r
529                 return Update.Ship;\r
530             }\r
531             return Update.None;\r
532         }\r
533 \r
534         private Update ApiMap(string url, string request, dynamic data)\r
535         {\r
536             if (url.EndsWith("api_req_map/start"))\r
537             {\r
538                 _shipInfo.InspectMapStart(request); // 出撃中判定が必要なので_conditionTimerより前\r
539                 _conditionTimer.InvalidateCond();\r
540                 _exMapInfo.InspectMapStart(data);\r
541                 _battleInfo.InspectMapStart(data);\r
542                 _logger.InspectMapStart(data);\r
543                 _miscTextInfo.InspectMapStart(data);\r
544                 _questCounter.InspectMapStart(data);\r
545                 _cellInfo.InspectMapStart(data);\r
546                 RepeatingTimerController?.Suspend("大破警告");\r
547                 return Update.Timer | Update.Ship | Update.Cell;\r
548             }\r
549             if (url.EndsWith("api_req_map/next"))\r
550             {\r
551                 _exMapInfo.InspectMapNext(data);\r
552                 _battleInfo.InspectMapNext(data);\r
553                 _logger.InspectMapNext(data);\r
554                 _questCounter.InspectMapNext(data);\r
555                 _miscTextInfo.InspectMapNext(data);\r
556                 _cellInfo.InspectMapNext(data);\r
557                 return Update.Battle;\r
558             }\r
559             if (url.EndsWith("api_req_map/anchorage_repair"))\r
560             {\r
561                 _shipInfo.InspectAnchorageRepair(data);\r
562                 return Update.Ship;\r
563             }\r
564             return Update.None;\r
565         }\r
566 \r
567         private Update ApiOthers(string url, string request, dynamic data)\r
568         {\r
569             if (url.EndsWith("api_req_hokyu/charge"))\r
570             {\r
571                 _shipInfo.InspectCharge(data);\r
572                 _materialInfo.InspectCharge(data);\r
573                 _questCounter.CountCharge();\r
574                 return Update.Item | Update.Ship | Update.QuestList;\r
575             }\r
576             if (url.EndsWith("api_req_nyukyo/start"))\r
577             {\r
578                 _dockInfo.InspectNyukyo(request);\r
579                 _conditionTimer.CheckCond();\r
580                 _akashiTimer.CheckFleet();\r
581                 _questCounter.CountNyukyo();\r
582                 var ndock = HttpUtility.ParseQueryString(request)["api_ndock_id"];\r
583                 if (ndock != null && int.TryParse(ndock, out int id))\r
584                     RepeatingTimerController?.Stop("入渠終了", id - 1);\r
585                 return Update.Item | Update.Ship | Update.QuestList;\r
586             }\r
587             if (url.EndsWith("api_req_nyukyo/speedchange"))\r
588             {\r
589                 _dockInfo.InspectSpeedChange(request);\r
590                 _conditionTimer.CheckCond();\r
591                 return Update.NDock | Update.Timer | Update.Item | Update.Ship;\r
592             }\r
593             if (url.EndsWith("api_req_mission/start"))\r
594             {\r
595                 var deck = HttpUtility.ParseQueryString(request)["api_deck_id"];\r
596                 if (deck != null && int.TryParse(deck, out int id))\r
597                     RepeatingTimerController?.Stop("遠征終了", id - 1);\r
598                 return Update.None;\r
599             }\r
600             if (url.EndsWith("api_req_mission/result"))\r
601             {\r
602                 _materialInfo.InspectMissionResult(data);\r
603                 _logger.InspectMissionResult(data);\r
604                 _questCounter.InspectMissionResult(request, data);\r
605                 return Update.Item;\r
606             }\r
607             if (url.EndsWith("api_req_quest/stop"))\r
608             {\r
609                 _questInfo.InspectStop(request);\r
610                 return Update.QuestList;\r
611             }\r
612             if (url.EndsWith("api_req_quest/clearitemget"))\r
613             {\r
614                 _questInfo.InspectClearItemGet(request);\r
615                 _logger.InspectClearItemGet(data);\r
616                 return Update.QuestList;\r
617             }\r
618             return Update.None;\r
619         }\r
620 \r
621         public NameAndTimer[] NDock => _dockInfo.NDock;\r
622 \r
623         public AlarmTimer[] KDock => _dockInfo.KDock;\r
624 \r
625         public AlarmCounter ItemCounter => _itemInfo.Counter;\r
626 \r
627         public MaterialInfo Material => _materialInfo;\r
628 \r
629         public QuestStatus[] Quests => _questInfo.Quests;\r
630 \r
631         public void GetQuestNotifications(out string[] notify, out string[] stop) =>\r
632             _questInfo.GetNotifications(out notify, out stop);\r
633 \r
634         public NameAndTimer[] Missions => _missionInfo.Missions;\r
635 \r
636         public DateTime GetConditionTimer(int fleet) => _conditionTimer.GetTimer(fleet);\r
637 \r
638         public int[] GetConditionNotice(TimeStep step) => _conditionTimer.GetNotice(step);\r
639 \r
640         public AlarmCounter ShipCounter => _shipInfo.Counter;\r
641 \r
642         public IReadOnlyList<Fleet> Fleets => _shipInfo.Fleets;\r
643 \r
644         public int InSortie => _shipInfo.InSortie;\r
645 \r
646         public ShipInfo.ShipStatusPair[] BattleResultStatusDiff => _shipInfo.BattleResultDiff;\r
647 \r
648         public bool IsBattleResultError => _shipInfo.IsBattleResultError || _battleInfo.DisplayedResultRank.IsError;\r
649 \r
650         public ShipStatus[] BattleStartStatus => _shipInfo.BattleStartStatus;\r
651 \r
652         public bool IsCombinedFleet => _shipInfo.Fleets[0].CombinedType != 0;\r
653 \r
654         public ShipStatus[] RepairList => _shipInfo.GetRepairList(_dockInfo);\r
655 \r
656         public ShipStatus[] ShipList => _shipInfo.ShipList;\r
657 \r
658         public string[] BadlyDamagedShips => _shipInfo.BadlyDamagedShips;\r
659 \r
660         public bool WarnBadDamageWithDameCon\r
661         {\r
662             set => _shipInfo.WarnBadDamageWithDameCon = value;\r
663         }\r
664 \r
665         public ItemStatus[] ItemList\r
666         {\r
667             get\r
668             {\r
669                 _itemInfo.ClearHolder();\r
670                 _shipInfo.SetItemHolder();\r
671                 _airBase.SetItemHolder();\r
672                 return _itemInfo.ItemList;\r
673             }\r
674         }\r
675 \r
676         public AkashiTimer AkashiTimer => _akashiTimer;\r
677 \r
678         public Achievement Achievement => _achievement;\r
679 \r
680         public BattleInfo Battle => _battleInfo;\r
681 \r
682         public ExMapInfo ExMap => _exMapInfo;\r
683 \r
684         public string MiscText => _miscTextInfo.Text;\r
685 \r
686         public AirBase.BaseInfo[] AirBase => _airBase.AllBase;\r
687 \r
688         public CellInfo CellInfo => _cellInfo;\r
689 \r
690         public void SetLogWriter(Action<string, string, string> writer, Func<DateTime> nowFunc)\r
691         {\r
692             _logger.SetWriter(writer, nowFunc);\r
693         }\r
694 \r
695         public void EnableLog(LogType type)\r
696         {\r
697             _logger.EnableLog(type);\r
698         }\r
699 \r
700         public int MaterialLogInterval\r
701         {\r
702             set => _logger.MaterialLogInterval = value;\r
703         }\r
704 \r
705         public string LogOutputDir\r
706         {\r
707             set => _logger.OutputDir = value;\r
708         }\r
709 \r
710         public void FlashLog()\r
711         {\r
712             _logger.FlashLog();\r
713         }\r
714     }\r
715 }