#pragma warning disable 4014 public async void HandleGameEnd() { Core.Overlay.HideTimers(); if (_game.CurrentGameStats == null || _handledGameEnd) { Logger.WriteLine("HandleGameEnd was already called.", "HandleGameEnd"); return; } _handledGameEnd = true; Logger.WriteLine("Game ended...", "HandleGameEnd"); if (_game.CurrentGameMode == GameMode.Spectator && !Config.Instance.RecordSpectator) { Logger.WriteLine("Game is in Spectator mode, discarded. (Record Spectator disabled)", "HandleGameEnd"); _assignedDeck = null; return; } var player = _game.Entities.FirstOrDefault(e => e.Value.IsPlayer); var opponent = _game.Entities.FirstOrDefault(e => e.Value.HasTag(GAME_TAG.PLAYER_ID) && !e.Value.IsPlayer); if (player.Value != null) { _game.CurrentGameStats.PlayerName = player.Value.Name; } if (opponent.Value != null && CardIds.HeroIdDict.ContainsValue(_game.CurrentGameStats.OpponentHero)) { _game.CurrentGameStats.OpponentName = opponent.Value.Name; } else { _game.CurrentGameStats.OpponentName = _game.CurrentGameStats.OpponentHero; } _game.CurrentGameStats.Turns = LogReaderManager.GetTurnNumber(); if (Config.Instance.DiscardZeroTurnGame && _game.CurrentGameStats.Turns < 1) { Logger.WriteLine("Game has 0 turns, discarded. (DiscardZeroTurnGame)", "HandleGameEnd"); _assignedDeck = null; GameEvents.OnGameEnd.Execute(); return; } _game.CurrentGameStats.GameEnd(); GameEvents.OnGameEnd.Execute(); var selectedDeck = DeckList.Instance.ActiveDeck; if (selectedDeck != null) { if (Config.Instance.DiscardGameIfIncorrectDeck && !_game.Player.DrawnCards.All( c => c.IsCreated || selectedDeck.GetSelectedDeckVersion().Cards.Any(c2 => c.Id == c2.Id && c.Count <= c2.Count))) { if (Config.Instance.AskBeforeDiscardingGame) { var discardDialog = new DiscardGameDialog(_game.CurrentGameStats); discardDialog.Topmost = true; discardDialog.ShowDialog(); if (discardDialog.Result == DiscardGameDialogResult.Discard) { Logger.WriteLine("Assigned current game to NO deck - selected deck does not match cards played (dialogresult: discard)", "HandleGameEnd"); _game.CurrentGameStats.DeleteGameFile(); _assignedDeck = null; return; } if (discardDialog.Result == DiscardGameDialogResult.MoveToOther) { var moveDialog = new MoveGameDialog(DeckList.Instance.Decks.Where(d => d.Class == _game.CurrentGameStats.PlayerHero)); moveDialog.Topmost = true; moveDialog.ShowDialog(); var targetDeck = moveDialog.SelectedDeck; if (targetDeck != null) { selectedDeck = targetDeck; _game.CurrentGameStats.PlayerDeckVersion = moveDialog.SelectedVersion; _game.CurrentGameStats.HearthStatsDeckVersionId = targetDeck.GetVersion(moveDialog.SelectedVersion).HearthStatsDeckVersionId; //...continue as normal } else { Logger.WriteLine("No deck selected in move game dialog after discard dialog, discarding game", "HandleGameEnd"); _game.CurrentGameStats.DeleteGameFile(); _assignedDeck = null; return; } } } else { Logger.WriteLine("Assigned current game to NO deck - selected deck does not match cards played (no dialog)", "HandleGameEnd"); _game.CurrentGameStats.DeleteGameFile(); _assignedDeck = null; return; } } else { _game.CurrentGameStats.PlayerDeckVersion = DeckList.Instance.ActiveDeckVersion.Version; _game.CurrentGameStats.HearthStatsDeckVersionId = DeckList.Instance.ActiveDeckVersion.HearthStatsDeckVersionId; } _lastGame = _game.CurrentGameStats; selectedDeck.DeckStats.AddGameResult(_lastGame); selectedDeck.StatsUpdated(); if (Config.Instance.ShowNoteDialogAfterGame && !Config.Instance.NoteDialogDelayed && !_showedNoteDialog) { _showedNoteDialog = true; new NoteDialog(_game.CurrentGameStats); } Logger.WriteLine("Assigned current game to deck: " + selectedDeck.Name, "HandleGameEnd"); _assignedDeck = selectedDeck; // Unarchive the active deck after we have played a game with it if (_assignedDeck.Archived) { Logger.WriteLine("Automatically unarchiving deck " + selectedDeck.Name + " after assigning current game", "HandleGameEnd"); Core.MainWindow.ArchiveDeck(_assignedDeck, false); } if (HearthStatsAPI.IsLoggedIn && Config.Instance.HearthStatsAutoUploadNewGames) { if (_game.CurrentGameMode == GameMode.None) { Logger.WriteLine("Waiting for game mode detection...", "HandleGameEnd"); await _game.GameModeDetection(300); //give the user 5 minutes to get out of the victory/defeat screen Logger.WriteLine("Detected game mode, continuing.", "HandleGameEnd"); } if (_game.CurrentGameMode == GameMode.Casual) { Logger.WriteLine("CurrentGameMode=None, Waiting for ranked detection...", "HandleGameEnd"); await LogReaderManager.RankedDetection(); Logger.WriteLine("Done waiting for ranked detection, continuing.", "HandleGameEnd"); } if (_game.CurrentGameMode == GameMode.Ranked && !_lastGame.HasRank) { Logger.WriteLine("Waiting for rank detection...", "HandleGameEnd"); await RankDetection(5); Logger.WriteLine("Rank detected, continuing.", "HandleGameEnd"); } Logger.WriteLine("Waiting for game mode to be saved to game...", "HandleGameEnd"); await GameModeSaved(15); Logger.WriteLine("Game mode was saved, continuing.", "HandleGameEnd"); if (_game.CurrentGameMode == GameMode.Arena) { HearthStatsManager.UploadArenaMatchAsync(_lastGame, selectedDeck, background: true); } else if (_game.CurrentGameMode == GameMode.Brawl) { /* do nothing */ } else { HearthStatsManager.UploadMatchAsync(_lastGame, selectedDeck, background: true); } } _lastGame = null; } else { try { DefaultDeckStats.Instance.GetDeckStats(_game.Player.Class).AddGameResult(_game.CurrentGameStats); Logger.WriteLine(string.Format("Assigned current deck to default {0} deck.", _game.Player.Class), "HandleGameEnd"); } catch (Exception ex) { Logger.WriteLine("Error saving to DefaultDeckStats: " + ex, "HandleGameEnd"); } _assignedDeck = null; } }