using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Cute; using UnityEngine; using Wizard.RoomMatch; using Wizard.Scripts.Network.Data.TableData.Arena.TwoPick; namespace Wizard.Battle.Recovery; public class RecoveryController { private NetworkBattleManagerBase _networkBattleMgr; private List _recoveryCoroutineList = new List(); private Matching _matchingInstance; public RecoveryDataHandler RecoveryDataHandlerInstance { get; private set; } public bool IsMariganFinished => Data.BattleRecoveryInfo.IsMulliganEnd; public RecoveryOperationInfo AIBattleRecoveryData { get; private set; } public event Action OnFinishRecoveringData; public event Action OnFinishRecoveryLogSync; public RecoveryController(RecoveryOperationInfo aiBattleRecoveryData = null) { AIBattleRecoveryData = aiBattleRecoveryData; Format format = Data.CurrentFormat; if (format == Format.Max && GameMgr.GetIns().GetDataMgr().IsDipslayHighRankFormat()) { format = PlayerStaticData.HighRankFormat(); } PlayerStaticData.LoadUserRankTexture(format); switch (GameMgr.GetIns().GetDataMgr().m_BattleType) { case DataMgr.BattleType.FreeBattle: _matchingInstance = new Matching_Free(); break; case DataMgr.BattleType.RankBattle: _matchingInstance = new Matching_RankMatch(); break; case DataMgr.BattleType.ColosseumNormal: case DataMgr.BattleType.ColosseumTwoPick: case DataMgr.BattleType.ColosseumHof: case DataMgr.BattleType.ColosseumWindFall: _matchingInstance = new Matching_Colosseum(); break; case DataMgr.BattleType.CompetitionNormal: case DataMgr.BattleType.CompetitionTwoPick: _matchingInstance = new Matching_Competition(); break; case DataMgr.BattleType.RoomBattle: ResetRoomInfo(NetworkDefine.ServerBattleType.OpenRoom, Data.BattleRecoveryInfo, RoomConnectController.BattleRule.Bo1, Format.Max, TwoPickFormat.None, isOpenDeckRule: false); break; case DataMgr.BattleType.RoomTwoPick: ResetRoomInfo(NetworkDefine.ServerBattleType.RoomTwoPick, Data.BattleRecoveryInfo, Data.BattleRecoveryInfo.BattleParameterInstance.Rule, Format.Max, Data.BattleRecoveryInfo.BattleParameterInstance.TwoPickFormat, isOpenDeckRule: false); break; case DataMgr.BattleType.TwoPickBackdraft: ResetRoomInfo(NetworkDefine.ServerBattleType.RoomTwoPick, Data.BattleRecoveryInfo, RoomConnectController.BattleRule.Bo1, Format.Max, Data.BattleRecoveryInfo.BattleParameterInstance.TwoPickFormat, isOpenDeckRule: false); break; case DataMgr.BattleType.TwoPick: _matchingInstance = new Matching_TwoPick(); break; case DataMgr.BattleType.Sealed: _matchingInstance = new Matching_Sealed(); break; } ConnectNode(); UIManager.GetInstance().StartCoroutine(WaitRealtimeObjectCreateToSetupRecoveryData()); } private void ResetRoomInfo(NetworkDefine.ServerBattleType battleType, BattleRecoveryInfo battleRecoveryInfo, RoomConnectController.BattleRule roomRule, Format format, TwoPickFormat deckFormatType, bool isOpenDeckRule) { _matchingInstance = new Matching_Room(battleRecoveryInfo._isConventionRoom, battleRecoveryInfo.IsGatheringRoom); (_matchingInstance as Matching_Room).SetBattleParameter(new BattleParameter(battleType, format, deckFormatType, roomRule, isOpenDeckRule)); RoomBase.SettingOpponentDispData(!Data.BattleRecoveryInfo.is_owner, Data.BattleRecoveryInfo.opponent_name, Data.BattleRecoveryInfo.opponent_emblem_id, Data.BattleRecoveryInfo.opponent_degree_id, Data.BattleRecoveryInfo.opponent_country_code, Data.BattleRecoveryInfo.opponent_rank, Data.BattleRecoveryInfo.IsOpponentOfficialUser, Data.BattleRecoveryInfo.OpponentHighFormatRank); } private IEnumerator WaitRealtimeObjectCreateToSetupRecoveryData() { while (ToolboxGame.RealTimeNetworkAgent == null) { _matchingInstance.UpdateOffLineMatching(); yield return null; } ToolboxGame.RealTimeNetworkAgent.IsNotPlayReceivingData = true; SetupRecoveryData(); } private void SetupRecoveryData() { ParseRecoveryData(); OnRecoveryReady(); ToolboxGame.RealTimeNetworkAgent.StartRecovery(Data.BattleRecoveryInfo.battle_id.ToString(), Data.BattleRecoveryInfo.Play_seq, Data.BattleRecoveryInfo.Pub_seq); if (!GameMgr.GetIns().IsAINetwork) { _recoveryCoroutineList.Add(UIManager.GetInstance().StartCoroutine(RealtimeOpenToRecoveryStart())); } _recoveryCoroutineList.Add(UIManager.GetInstance().StartCoroutine(WaitTillBattleCreate())); } private IEnumerator RealtimeOpenToRecoveryStart() { while (!ToolboxGame.RealTimeNetworkAgent.IsOpen()) { yield return null; } ToolboxGame.RealTimeNetworkAgent.EmitMsgPack(NetworkBattleDefine.NetworkBattleURI.RecoveryStart); } private IEnumerator WaitTillBattleCreate() { while (BattleManagerBase.GetIns() == null || BattleManagerBase.GetIns().SBattleLoad == null || !BattleManagerBase.GetIns().SBattleLoad.isLoadEnd || !ToolboxGame.RealTimeNetworkAgent.IsOpen()) { yield return null; } RecoveryEndToChangeBattleScene(); } private void RecoveryEndToChangeBattleScene() { _networkBattleMgr = BattleManagerBase.GetIns() as NetworkBattleManagerBase; ToolboxGame.RealTimeNetworkAgent.SetNetworkBattleMgr(_networkBattleMgr); BattleManagerBase.GetIns().OnStartOpening += delegate { _networkBattleMgr._recoveryController = this; RecoveryDataHandlerInstance = new RecoveryDataHandler(_networkBattleMgr, this.OnFinishRecoveringData, this.OnFinishRecoveryLogSync, AIBattleRecoveryData); RecoveryDataHandlerInstance.OnBattleReceived(); }; _matchingInstance.GotoBattle(); BattleManagerBase.GetIns().SBattleLoad.StartBattleScene(); } private void RecoveryReturnScene() { if (!_matchingInstance.GetMatchingDataReady()) { UIManager.GetInstance().OffViewAll(); } ToolboxGame.DestroyNetworkAgent(); if (_matchingInstance is Matching_Room) { RoomBase.ResetOpponentData(); } if (_matchingInstance.GetMatchingDataReady() && GameMgr.GetIns().GetBattleCtrl() != null) { UIManager.GetInstance().StartCoroutine(BattleEndCoroutin(ChangeScene)); return; } UIManager.GetInstance().CloseInSceneLoadingMatching(); ChangeScene(); } private void ChangeScene() { UIManager.ChangeViewSceneParam changeViewSceneParam = new UIManager.ChangeViewSceneParam(); changeViewSceneParam.OnFinishChangeView = delegate { UIManager.GetInstance().CloseInSceneLoadingMatching(); UIManager.GetInstance().CloseInSceneLoadingBattle(); }; UIManager.GetInstance().ChangeViewScene(UIManager.ViewScene.MyPage, changeViewSceneParam); } private IEnumerator BattleEndCoroutin(Action callback) { while (BattleManagerBase.GetIns() == null) { yield return null; } SBattleLoad battleLoad = BattleManagerBase.GetIns().SBattleLoad; while (!battleLoad.isLoadEnd) { yield return null; } yield return GameMgr.GetIns().GetBattleCtrl().BattleEnd(); callback(); } private void ConnectNode() { MatchingNetworkConnectChecker matchingNetworkConnectCheker = _matchingInstance._matchingNetworkConnectCheker; matchingNetworkConnectCheker.Start(); matchingNetworkConnectCheker.OnConnectError = ReturnTitle; string battleId = Data.BattleRecoveryInfo.battle_id.ToString(); if (GameMgr.GetIns().GetDataMgr().IsRoomBattleType()) { battleId = Data.BattleRecoveryInfo.roomId.ToString(); } matchingNetworkConnectCheker.SetBattleId(battleId); matchingNetworkConnectCheker.SetConnectOnly(); } private void ReturnTitle() { for (int i = 0; i < _recoveryCoroutineList.Count; i++) { Coroutine routine = _recoveryCoroutineList[i]; UIManager.GetInstance().StopCoroutine(routine); routine = null; } _recoveryCoroutineList.Clear(); SystemText systemText = Data.SystemText; DialogBase dialogBase = UIManager.GetInstance().CreateDialogClose(isSystem: true); dialogBase.SetSize(DialogBase.Size.M); dialogBase.SetTitleLabel(systemText.Get("ErrorHeader_0012")); dialogBase.SetText(systemText.Get("Error_0012")); dialogBase.AddButton(DialogBase.ButtonType.BackToTitle); dialogBase.SetPanelDepth(6000); dialogBase.SetFadeButtonEnabled(flag: false); dialogBase.onPushButton1 = (Action)Delegate.Combine(dialogBase.onPushButton1, (Action)delegate { if (_matchingInstance.GetMatchingDataReady() && GameMgr.GetIns().GetBattleCtrl() != null) { UIManager.GetInstance().StartCoroutine(BattleEndCoroutin(SoftwareReset)); } else { SoftwareReset(); } }); } private void SoftwareReset() { Wizard.SoftwareReset.exec(); } private void OnRecoveryReady() { UIManager.GetInstance().createInSceneLoadingMatching(notBlack: true); UIManager.GetInstance().closeInSceneLoading(); DataMgr dataMgr = GameMgr.GetIns().GetDataMgr(); List list = null; list = ((!GameMgr.GetIns().IsAINetwork) ? (from i in GameMgr.GetIns().GetNetworkUserInfoData().GetSelfDeck() select i.CardId).ToList() : AIBattleRecoveryData.SetupInfo.PlayerInfo.DeckCardInfos.Select((DeckCardInfo i) => i?.CardId.Value ?? 100011010).ToList()); dataMgr.SetCurrentDeckData(list); dataMgr.SetPlayerCharaId(Data.BattleRecoveryInfo.chara_id); dataMgr.SetPlayerSubClassID(Data.BattleRecoveryInfo.SubClassId); dataMgr.SetPlayerMyRotationInfo(Data.BattleRecoveryInfo.MyRotationId); dataMgr.SetPlayerSleeveId(Data.BattleRecoveryInfo.sleeve_id); dataMgr.SetSelectDeckFormat(Data.BattleRecoveryInfo.deck_format); if (GameMgr.GetIns().IsAINetwork) { List currentEnemyDeckData = AIBattleRecoveryData.SetupInfo.EnemyInfo.DeckCardInfos.Select((DeckCardInfo i) => i?.CardId.Value ?? 100011010).ToList(); dataMgr.SetCurrentEnemyDeckData(currentEnemyDeckData); dataMgr.SetEnemyCharaId(AIBattleRecoveryData.SetupInfo.EnemyInfo.CharaId); dataMgr.SetEnemySleeveId(AIBattleRecoveryData.SetupInfo.EnemyInfo.SleeveId); } else { List currentEnemyDeckData2 = (from i in GameMgr.GetIns().GetNetworkUserInfoData().GetOpponentDeck() select i.CardId).ToList(); dataMgr.SetCurrentEnemyDeckData(currentEnemyDeckData2); dataMgr.SetEnemyCharaId(Data.BattleRecoveryInfo.chara_id); dataMgr.SetEnemySubClassID(Data.BattleRecoveryInfo.OpponentSubClassId); dataMgr.SetEnemyMyRotationInfo(Data.BattleRecoveryInfo.OpponentMyRotationId); dataMgr.SetEnemySleeveId(Data.BattleRecoveryInfo.sleeve_id); } int playerClassId = dataMgr.GetPlayerClassId(); int selectDeckId = dataMgr.GetSelectDeckId(); bool num = PlayerPrefsWrapper.GetBool(PlayerPrefsWrapper.LAST_BATTLE_IS_TRIALDECK); _matchingInstance.FirstSetting(playerClassId, selectDeckId, isRecovery: true); if (num && (Data.BattleRecoveryInfo.BattleParameterInstance.TwoPickFormat != TwoPickFormat.Chaos || Data.BattleRecoveryInfo.BattleParameterInstance.TwoPickFormat != TwoPickFormat.BackdraftChaos)) { DeckData deckData = new DeckData(Format.Max, DeckAttributeType.TrialDeck); deckData.SetDeckID(selectDeckId); deckData.SetDeckClassID(playerClassId); deckData.SetCardIdList(list); deckData.SetDeckName(PlayerPrefsWrapper.GetValue(PlayerPrefsWrapper.LAST_BATTLE_NAME_TRIALDECK)); dataMgr.SetSelectDeckId(deckData.GetDeckID()); dataMgr.LastSelectDeckAttributeType = DeckAttributeType.TrialDeck; dataMgr.SetPlayerCharaIdBySkinId(deckData.GetSkinId()); } else if (dataMgr.IsTwoPickBattleType()) { DeckData deckData2 = new DeckData(); deckData2.SetDeckID(0); deckData2.SetDeckClassID(playerClassId); deckData2.SetDeckSleeveID(3000011L); deckData2.SetDeckName(GameMgr.GetIns().GetDataMgr().GetClanNameByKey(playerClassId)); deckData2.SetCardIdList(list); dataMgr.SetSelectDeckId(deckData2.GetDeckID()); dataMgr.LastSelectDeckAttributeType = DeckAttributeType.Invalid; dataMgr.SetPlayerCharaIdBySkinId(Data.BattleRecoveryInfo.chara_id); dataMgr._roomTwoPickDeckData = deckData2; if (dataMgr.m_BattleType == DataMgr.BattleType.TwoPickBackdraft) { Data.RoomTwoPickInfo.deckData.classId = dataMgr.GetEnemyClassId(); dataMgr._roomTwoPickDeckData.SetDeckClassID(dataMgr.GetEnemyClassId()); } else { Data.RoomTwoPickInfo.deckData.classId = playerClassId; } Data.RoomTwoPickInfo.deckData.entryId = 0; Data.RoomTwoPickInfo.deckData.isSelectCompleted = true; Data.RoomTwoPickInfo.deckData.cardIds = deckData2.GetCardIdList().ToArray(); Data.RoomTwoPickBeforeBattleInfo.SetSelfClassIdTwoPickDraftData(playerClassId); if (Data.BattleRecoveryInfo.BattleParameterInstance.TwoPickFormat == TwoPickFormat.Chaos || Data.BattleRecoveryInfo.BattleParameterInstance.TwoPickFormat == TwoPickFormat.BackdraftChaos) { CandidateChaos candidateChaos = Data.RoomTwoPickInfo.CandidateChaos; candidateChaos.SelectedChaosId = Data.BattleRecoveryInfo.ChaosId; candidateChaos.SelectedCharaId = Data.BattleRecoveryInfo.chara_id; candidateChaos.SelectedClassId = Data.BattleRecoveryInfo.class_id; } } if ((bool)ToolboxGame.RealTimeNetworkAgent) { CustomPreference.SetNodeServerURL(Data.BattleRecoveryInfo.node_server_url); } } private int DecideFirstUser(int id) { if (id == PlayerStaticData.UserViewerID) { return 0; } return 1; } private bool IsPlayer(int id) { if (id == PlayerStaticData.UserViewerID) { return true; } return false; } private void ParseRecoveryData() { int first_turn = Data.BattleRecoveryInfo.first_turn; GameMgr.GetIns().GetNetworkUserInfoData().TurnState = DecideFirstUser(first_turn); Dictionary info = ParseData(isPlayer: true); Dictionary info2 = ParseData(isPlayer: false); GameMgr.GetIns().SettingSelfInfo(info, isWatchReplayRecovery: true); GameMgr.GetIns().SettingOpponentInfo(info2, isWatchReplayRecovery: true); GameMgr.GetIns().GetNetworkUserInfoData().SetSelfDeck(Data.BattleRecoveryInfo.deck); } private Dictionary ParseData(bool isPlayer) { Dictionary dictionary = new Dictionary(); dictionary.Add("fieldId", Data.BattleRecoveryInfo.field_id); dictionary.Add("seed", Data.BattleRecoveryInfo.seed); if (isPlayer) { dictionary.Add("viewerId", Data.BattleRecoveryInfo.viewer_id); dictionary.Add("oppoId", Data.BattleRecoveryInfo.opponent_viewer_id); dictionary.Add("charaId", Data.BattleRecoveryInfo.chara_id); dictionary.Add("classId", Data.BattleRecoveryInfo.class_id); dictionary.Add("sleeveId", Data.BattleRecoveryInfo.sleeve_id); dictionary.Add("rank", Data.BattleRecoveryInfo.rank); dictionary.Add("degreeId", Data.BattleRecoveryInfo.degree_id); dictionary.Add("emblemId", Data.BattleRecoveryInfo.emblem_id); dictionary.Add("country_code", Data.BattleRecoveryInfo.country_code); dictionary.Add("userName", Data.BattleRecoveryInfo.name); dictionary.Add("isOfficial", Data.BattleRecoveryInfo.IsOfficialUser); dictionary.Add("chaosId", Data.BattleRecoveryInfo.ChaosId); dictionary.Add("subclassId", Data.BattleRecoveryInfo.SubClassId); dictionary.Add("rotationId", Data.BattleRecoveryInfo.MyRotationId); } else { dictionary.Add("viewerId", Data.BattleRecoveryInfo.viewer_id); dictionary.Add("charaId", Data.BattleRecoveryInfo.opponent_chara_id); dictionary.Add("classId", Data.BattleRecoveryInfo.opponent_class_id); dictionary.Add("sleeveId", Data.BattleRecoveryInfo.opponent_sleeve_id); dictionary.Add("rank", Data.BattleRecoveryInfo.opponent_rank); dictionary.Add("degreeId", Data.BattleRecoveryInfo.opponent_degree_id); dictionary.Add("emblemId", Data.BattleRecoveryInfo.opponent_emblem_id); dictionary.Add("country_code", Data.BattleRecoveryInfo.opponent_country_code); dictionary.Add("userName", Data.BattleRecoveryInfo.opponent_name); dictionary.Add("battlePoint", Data.BattleRecoveryInfo.opponent_battle_point); dictionary.Add("isMasterRank", Data.BattleRecoveryInfo.is_opponent_master_rank); dictionary.Add("masterPoint", Data.BattleRecoveryInfo.opponent_master_point); dictionary.Add("isOfficial", Data.BattleRecoveryInfo.IsOpponentOfficialUser); dictionary.Add("chaosId", Data.BattleRecoveryInfo.OpponentChaosId); dictionary.Add("subclassId", Data.BattleRecoveryInfo.OpponentSubClassId); dictionary.Add("rotationId", Data.BattleRecoveryInfo.OpponentMyRotationId); } dictionary.Add("isChaosSkinOverride", Data.BattleRecoveryInfo.IsChaosSkinOverride); return dictionary; } }