OSDN Git Service

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