OSDN Git Service

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