OSDN Git Service

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