public override void Register(QuestInfo rpQuest)
        {
            var rBattleResultApis = new[]
            {
                "api_req_sortie/battleresult",
                "api_req_combined_battle/battleresult",
            };
            SessionService.Instance.Subscribe(rBattleResultApis, r =>
            {
                ProgressInfo rProgressInfo;
                if (!QuestProgressService.Instance.Progresses.TryGetValue(rpQuest.ID, out rProgressInfo) || rProgressInfo.State != QuestState.Executing)
                    return;

                Process(rProgressInfo, BattleInfo.Current, r.GetData<RawBattleResult>());

                rProgressInfo.Progress = Math.Min(rProgressInfo.Progress, rProgressInfo.Quest.Total);
            });
        }
        internal BattleRecord(SQLiteConnection rpConnection) : base(rpConnection)
        {
            var rBattleApis = new[]
            {
                "api_req_sortie/battle",
                "api_req_battle_midnight/sp_midnight",
                "api_req_sortie/airbattle",
                "api_req_combined_battle/airbattle",
                "api_req_combined_battle/battle",
                "api_req_combined_battle/battle_water",
                "api_req_combined_battle/sp_midnight",
                "api_req_battle_midnight/battle",
                "api_req_combined_battle/midnight_battle",
            };
            DisposableObjects.Add(SessionService.Instance.Subscribe(rBattleApis, Process));

            var rBattleResultApis = new[]
            {
                "api_req_sortie/battleresult",
                "api_req_combined_battle/battleresult",
            };
            DisposableObjects.Add(SessionService.Instance.Subscribe(rBattleResultApis, r => ProcessResult((RawBattleResult)r.Data)));
        }
        internal FateRecords(SQLiteConnection rpConnection) : base(rpConnection)
        {
            DisposableObjects.Add(ApiService.SubscribeOnlyOnBeforeProcessStarted("api_req_kaisou/powerup", r =>
            {
                var rConsumedShips = r.Parameters["api_id_items"].Split(',').Select(rpID => KanColleGame.Current.Port.Ships[int.Parse(rpID)]).ToArray();
                var rConsumedEquipment = rConsumedShips.SelectMany(rpShip => rpShip.EquipedEquipment).ToArray();

                AddShipFate(rConsumedShips, Fate.ConsumedByModernization);
            }));
            DisposableObjects.Add(ApiService.SubscribeOnlyOnBeforeProcessStarted("api_req_kousyou/destroyship", r =>
            {
                var rShip = KanColleGame.Current.Port.Ships[int.Parse(r.Parameters["api_ship_id"])];

                AddShipFate(rShip, Fate.Dismantled);
            }));
            DisposableObjects.Add(ApiService.SubscribeOnlyOnBeforeProcessStarted("api_req_kousyou/destroyitem2", r =>
            {
                var rEquipmentIDs = r.Parameters["api_slotitem_ids"].Split(',').Select(int.Parse);

                AddEquipmentFate(rEquipmentIDs.Select(rpID => KanColleGame.Current.Port.Equipment[rpID]), Fate.Scrapped);
            }));
            DisposableObjects.Add(ApiService.SubscribeOnlyOnBeforeProcessStarted("api_req_kousyou/remodel_slot", r =>
            {
                var rData = (RawImprovementResult)r.Data;
                if (rData.ConsumedEquipmentID != null)
                {
                    var rConsumedEquipment = rData.ConsumedEquipmentID.Select(rpID => KanColleGame.Current.Port.Equipment[rpID]).ToArray();

                    RecordService.Instance?.Fate?.AddEquipmentFate(rConsumedEquipment, Fate.ConsumedByImprovement);
                }
            }));

            var rFirstStages = new[]
            {
                "api_req_sortie/battle",
                "api_req_battle_midnight/sp_midnight",
                "api_req_sortie/airbattle",
                "api_req_sortie/ld_airbattle",
                "api_req_combined_battle/airbattle",
                "api_req_combined_battle/battle",
                "api_req_combined_battle/battle_water",
                "api_req_combined_battle/sp_midnight",
                "api_req_combined_battle/ld_airbattle",
                "api_req_combined_battle/ec_battle",
                "api_req_combined_battle/each_battle",
                "api_req_combined_battle/each_battle_water",
            };
            DisposableObjects.Add(ApiService.Subscribe(rFirstStages, ProcessBattle));

            var rBattleResultApis = new[]
            {
                "api_req_sortie/battleresult",
                "api_req_combined_battle/battleresult",
            };
            DisposableObjects.Add(ApiService.Subscribe(rBattleResultApis, ProcessBattleResult));

            DisposableObjects.Add(ApiService.Subscribe("api_port/port", delegate
            {
                if (r_SunkShips.Count == 0)
                    return;

                var rAliveShips = r_SunkShips.Intersect(KanColleGame.Current.Port.Ships.Values);
                DeleteShipFate(rAliveShips);

                r_SunkShips.Clear();
            }));
        }