public AddGameDialog(GameStats game) { InitializeComponent(); _tcs = new TaskCompletionSource<GameStats>(); _editing = true; _game = game; if(game == null) return; ComboBoxResult.SelectedItem = game.Result; HeroClass heroClass; if(Enum.TryParse(game.OpponentHero, out heroClass)) ComboBoxOpponent.SelectedItem = heroClass; ComboBoxMode.SelectedItem = game.GameMode; ComboBoxRegion.SelectedItem = game.Region; if(game.GameMode == GameMode.Ranked) TextBoxRank.Text = game.Rank.ToString(); TextBoxRank.IsEnabled = game.GameMode == GameMode.Ranked; ComboBoxCoin.SelectedItem = game.Coin ? YesNo.Yes : YesNo.No; ComboBoxConceded.SelectedItem = game.WasConceded ? YesNo.Yes : YesNo.No; TextBoxTurns.Text = game.Turns.ToString(); TextBoxDuration.Text = game.Duration; TextBoxDuration.IsEnabled = false; TextBoxNote.Text = game.Note; TextBoxOppName.Text = game.OpponentName; BtnSave.Content = "save"; }
public static async Task<bool> Upload(string[] logLines, GameMetaData gameMetaData, GameStats game) { var log = string.Join(Environment.NewLine, logLines); var item = new UploaderItem(log.GetHashCode()); if(InProgress.Contains(item)) { Log.Info($"{item.Hash} already in progress. Waiting for it to complete..."); InProgress.Add(item); return await item.Success; } InProgress.Add(item); Log.Info($"Uploading {item.Hash}..."); var success = false; try { success = await TryUpload(logLines, gameMetaData, game, true); } catch(Exception ex) { Log.Error(ex); Influx.OnGameUploadFailed(); } Log.Info($"{item.Hash} complete. Success={success}"); foreach(var waiting in InProgress.Where(x => x.Hash == item.Hash)) waiting.Complete(success); InProgress.RemoveAll(x => x.Hash == item.Hash); return success; }
private static async Task<bool> TryUpload(string[] logLines, GameMetaData gameMetaData, GameStats game, bool submitFailure) { try { game?.HsReplay.UploadTry(); Influx.OnGameUpload(game?.HsReplay.UploadTries ?? 1); var lines = logLines.SkipWhile(x => !x.Contains("CREATE_GAME")).ToArray(); var metaData = UploadMetaDataGenerator.Generate(lines, gameMetaData, game); Log.Info("Creating upload request..."); var uploadRequest = await ApiWrapper.CreateUploadRequest(metaData); Log.Info("Upload Id: " + uploadRequest.ShortId); await ApiWrapper.UploadLog(uploadRequest, lines); Log.Info("Upload complete"); if(game != null) { game.HsReplay.UploadId = uploadRequest.ShortId; game.HsReplay.ReplayUrl = uploadRequest.ReplayUrl; if(DefaultDeckStats.Instance.DeckStats.Any(x => x.DeckId == game.DeckId)) DefaultDeckStats.Save(); else DeckStatsList.Save(); } return true; } catch(WebException ex) { Log.Error(ex); if(submitFailure) Influx.OnGameUploadFailed(ex.Status); return false; } }
public string Apply(GameStats game) { var name = ""; foreach(var token in Pattern) { var tokenLower = token.ToLower(); if(tokenLower == "{playerclass}") { name += game.PlayerHero; } else if(tokenLower == "{opponentclass}") { name += game.OpponentHero; } else if(tokenLower == "{playername}") { name += game.PlayerName; } else if(tokenLower == "{opponentname}") { name += game.OpponentName; } else if(tokenLower.Contains("{date:")) { name += ParseDate(token); } else { name += token; } } return name; }
public AddGameDialog(GameStats game) { InitializeComponent(); _tcs = new TaskCompletionSource<GameStats>(); _editing = true; _game = game; if(game == null) return; ComboBoxResult.SelectedItem = game.Result; HeroClass heroClass; if(!string.IsNullOrWhiteSpace(game.OpponentHero) && Enum.TryParse(game.OpponentHero, out heroClass)) ComboBoxOpponent.SelectedItem = heroClass; ComboBoxMode.SelectedItem = game.GameMode; ComboBoxFormat.SelectedItem = game.Format; ComboBoxRegion.SelectedItem = game.Region; if(game.GameMode == Ranked) { TextBoxRank.Text = game.Rank.ToString(); TextBoxLegendRank.Text = game.LegendRank.ToString(); } PanelRank.Visibility = PanelLegendRank.Visibility = game.GameMode == Ranked ? Visible : Collapsed; PanelFormat.Visibility = game.GameMode == Ranked || game.GameMode == Casual ? Visible : Collapsed; ComboBoxCoin.SelectedItem = game.Coin ? Yes : No; ComboBoxConceded.SelectedItem = game.WasConceded ? Yes : No; TextBoxTurns.Text = game.Turns.ToString(); TextBoxDuration.Text = game.Duration; TextBoxDuration.IsEnabled = false; TextBoxNote.Text = game.Note; TextBoxOppName.Text = game.OpponentName; TextBoxPlayerName.Text = game.PlayerName; BtnSave.Content = "save"; Title = "Edit game"; }
public AddGameDialog(Deck deck) { InitializeComponent(); _tcs = new TaskCompletionSource<GameStats>(); _editing = false; var lastGame = deck.DeckStats.Games.LastOrDefault(); if(deck.IsArenaDeck) { ComboBoxMode.SelectedItem = GameMode.Arena; ComboBoxMode.IsEnabled = false; TextBoxRank.IsEnabled = false; } else { ComboBoxMode.IsEnabled = true; TextBoxRank.IsEnabled = true; if(lastGame != null) { ComboBoxMode.SelectedItem = lastGame.GameMode; if(lastGame.GameMode == GameMode.Ranked) TextBoxRank.Text = lastGame.Rank.ToString(); } } if(lastGame != null && lastGame.Region != Region.UNKNOWN) ComboBoxRegion.SelectedItem = lastGame.Region; _deck = deck; _game = new GameStats(); BtnSave.Content = "add game"; }
//LocUtil.Get()} public static async Task<MessageDialogResult> ShowDeleteGameStatsMessage(this MetroWindow window, GameStats stats) => await window.ShowMessageAsync(LocUtil.Get(LocDeleteGameStatsTitle), stats + Environment.NewLine + Environment.NewLine + LocUtil.Get(LocDeleteGameStatsSure), AffirmativeAndNegative, new Settings { AffirmativeButtonText = LocUtil.Get(LocDeleteGameStatsButtonDelete), NegativeButtonText = LocUtil.Get(LocDeleteGameStatsButtonCancel) });
public static async Task<MessageDialogResult> ShowDeleteGameStatsMessage(MetroWindow window, GameStats stats) { var settings = new MetroDialogSettings {AffirmativeButtonText = "Yes", NegativeButtonText = "No"}; return await window.ShowMessageAsync("Delete Game", stats.Result + " vs " + stats.OpponentHero + "\nfrom " + stats.StartTime + "\n\nAre you sure?", MessageDialogStyle.AffirmativeAndNegative, settings); }
public NoteDialog(GameStats game) { InitializeComponent(); _game = game; CheckBoxEnterToSave.IsChecked = Config.Instance.EnterToSaveNote; Show(); Activate(); TextBoxNote.Focus(); _initialized = true; }
public static GameStats CreateGame(Guid deck, Region region, GameMode mode, int days) { var game = new GameStats(GameResult.Win, "Mage", "Mage"); game.DeckId = deck; game.Region = region; game.GameMode = mode; game.StartTime = DateTime.Now.Subtract(TimeSpan.FromDays(days)); return game; }
public NoteDialog(GameStats game, List<Image> screenshots) { InitializeComponent(); _game = game; CheckBoxEnterToSave.IsChecked = Config.Instance.EnterToSaveNote; Show(); Activate(); TextBoxNote.Focus(); ListBox_Images.DataContext = screenshots; _initialized = true; }
public NoteDialog(GameStats game) { InitializeComponent(); _game = game; CheckBoxEnterToSave.IsChecked = Config.Instance.EnterToSaveNote; TextBoxNote.Text = game.Note; DeckList.ItemsSource = game.OpponentCards .Select(x => new NoteCard(x)) .OrderBy(x => x.Cost); Show(); Activate(); TextBoxNote.Focus(); _initialized = true; }
internal static void ShowGameResultToast(string deckName, GameStats game) { if(game == null) return; var result = new ToastHelper(new GameResultToast(deckName, game)); if(Config.Instance.ShowReplayShareToast) { var replay = new ToastHelper(new ReplayToast(game)); GameResultToasts.Add(replay, result); ShowToast(result); ShowToast(replay); } else ShowToast(result); }
public static void SaveImage(GameStats game, Image screenshot, String note = null) { if(game != null) { if (!String.IsNullOrEmpty(note)) game.Note = note; DeckStatsList.Save(); if(Config.Instance.StatsInWindow) { ((DeckStatsControl)Helper.MainWindow.StatsWindow.FindName("StatsControl")).Refresh(); } else { ((DeckStatsControl)Helper.MainWindow.FindName("DeckStatsFlyout")).Refresh(); } if(screenshot != null) { try { var dir = Settings.Default.OutputDir; if(!Directory.Exists(dir)) { dir = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); } var pattern = Settings.Default.FileNamePattern; NamingPattern np = null; if(!NamingPattern.TryParse(pattern, out np)) Logger.WriteLine("Invalid file name pattern, using default", "EndGame"); var filename = np.Apply(game); SaveAsPng(screenshot.Full, Path.Combine(dir, filename)); } catch(Exception e) { Logger.WriteLine("Error saving image: " + e.Message, "EndGame"); } } else { Logger.WriteLine("Screenshot is null", "EndGame"); } } else { Logger.WriteLine("Game is null", "EndGame"); } }
public static async Task<bool> ShowReplay(GameStats game, bool showToast) { if(game == null) return false; if(Config.Instance.ForceLocalReplayViewer) { ReplayReader.LaunchReplayViewer(game.ReplayFile, false); return true; } Action<ReplayProgress> setToastStatus = null; if(game.HasReplayFile && !game.HsReplay.Uploaded) { if(showToast) setToastStatus = ToastManager.ShowReplayProgressToast(); var log = GetLogFromHdtReplay(game.ReplayFile).ToArray(); var validationResult = LogValidator.Validate(log); if(validationResult.IsValid) await LogUploader.Upload(log, null, game); else { Log.Error("Invalid log: " + validationResult.Reason); game.HsReplay.Unsupported = true; } if(DefaultDeckStats.Instance.DeckStats.Any(x => x.DeckId == game.DeckId)) DefaultDeckStats.Save(); else DeckStatsList.Save(); } if(game.HsReplay?.Uploaded ?? false) { setToastStatus?.Invoke(ReplayProgress.Complete); Helper.TryOpenUrl(game.HsReplay?.Url); } else if(game.HasReplayFile) { setToastStatus?.Invoke(ReplayProgress.Error); ReplayReader.LaunchReplayViewer(game.ReplayFile, true); } else { setToastStatus?.Invoke(ReplayProgress.Error); return false; } return true; }
public static UploadMetaData Generate(string[] log, GameMetaData gameMetaData, GameStats game) { var metaData = new UploadMetaData(); var playerInfo = GetPlayerInfo(log, game); if(playerInfo != null) { metaData.Player1 = playerInfo.Player1; metaData.Player2 = playerInfo.Player2; } if(!string.IsNullOrEmpty(gameMetaData?.ServerInfo?.Address)) metaData.ServerIp = gameMetaData.ServerInfo.Address; if(gameMetaData?.ServerInfo?.Port > 0) metaData.ServerPort = gameMetaData.ServerInfo.Port.ToString(); if(gameMetaData?.ServerInfo?.GameHandle > 0) metaData.GameHandle = gameMetaData.ServerInfo.GameHandle.ToString(); if(gameMetaData?.ServerInfo?.ClientHandle > 0) metaData.ClientHandle = gameMetaData.ServerInfo.ClientHandle.ToString(); if(!string.IsNullOrEmpty(gameMetaData?.ServerInfo?.SpectatorPassword)) metaData.SpectatePassword = gameMetaData.ServerInfo.SpectatorPassword; if(!string.IsNullOrEmpty(gameMetaData?.ServerInfo?.AuroraPassword)) metaData.AuroraPassword = gameMetaData.ServerInfo.AuroraPassword; if(!string.IsNullOrEmpty(gameMetaData?.ServerInfo?.Version)) metaData.ServerVersion = gameMetaData.ServerInfo.Version; if(game?.StartTime > DateTime.MinValue) metaData.MatchStart = game.StartTime.ToString("o"); if(game != null) metaData.GameType = game.GameType != GameType.GT_UNKNOWN ? (int)HearthDbConverter.GetBnetGameType(game.GameType, game.Format) : (int)HearthDbConverter.GetGameType(game.GameMode, game.Format); if(game?.Format != null) metaData.Format = (int)HearthDbConverter.GetFormatType(game.Format); metaData.SpectatorMode = game?.GameMode == GameMode.Spectator; metaData.Reconnected = gameMetaData?.Reconnected ?? false; metaData.Resumable = gameMetaData?.ServerInfo?.Resumable ?? false; metaData.FriendlyPlayerId = game?.FriendlyPlayerId > 0 ? game.FriendlyPlayerId : (playerInfo?.FriendlyPlayerId > 0 ? playerInfo?.FriendlyPlayerId : null); var scenarioId = game?.ScenarioId ?? gameMetaData?.ServerInfo?.Mission; if(scenarioId > 0) metaData.ScenarioId = scenarioId; var build = gameMetaData?.HearthstoneBuild ?? game?.HearthstoneBuild ?? (game != null ? BuildDates.GetByDate(game.StartTime) : null); if(build > 0) metaData.HearthstoneBuild = build; if(game?.BrawlSeasonId > 0) metaData.BrawlSeason = game.BrawlSeasonId; if(game?.RankedSeasonId > 0) metaData.LadderSeason = game.RankedSeasonId; return metaData; }
public GameResultToast(string deckName, [NotNull] GameStats game) { InitializeComponent(); InitializeComponent(); DeckName = deckName; _game = game; ComboBoxResult.ItemsSource = new[] { GameResult.Win, GameResult.Loss }; ComboBoxFormat.ItemsSource = new[] { Enums.Format.Standard, Enums.Format.Wild }; ComboBoxGameMode.ItemsSource = new[] { GameMode.Arena, GameMode.Brawl, GameMode.Casual, GameMode.Friendly, GameMode.Practice, GameMode.Ranked, GameMode.Spectator }; }
private static PlayerInfo GetPlayerInfo(string[] log, GameStats game) { var friendly = new UploadMetaData.Player(); var opposing = new UploadMetaData.Player(); if(game?.Rank > 0) friendly.Rank = game.Rank; if(game?.LegendRank > 0) friendly.LegendRank = game.LegendRank; if(game?.PlayerCardbackId > 0) friendly.Cardback = game.PlayerCardbackId; if(game?.Stars > 0) friendly.Stars = game.Stars; if(game?.PlayerCards.Sum(x => x.Count) == 30 && game?.PlayerCards.Sum(x => x.Unconfirmed) <= 24) { friendly.DeckList = game.PlayerCards.Where(x => x.Id != Database.UnknownCardId).SelectMany(x => Enumerable.Repeat(x.Id, x.Count)).ToArray(); if(game.HsDeckId > 0) friendly.DeckId = game.HsDeckId; } if(game?.ArenaWins > 0) friendly.Wins = game.ArenaWins; if(game?.ArenaLosses > 0) friendly.Losses = game.ArenaLosses; if(game?.OpponentRank > 0) opposing.Rank = game.OpponentRank; if(game?.OpponentLegendRank > 0) opposing.LegendRank = game.OpponentLegendRank; if(game?.OpponentCardbackId > 0) opposing.Cardback = game.OpponentCardbackId; if(game?.FriendlyPlayerId > 0) { return new PlayerInfo(game.FriendlyPlayerId == 1 ? friendly : opposing, game.FriendlyPlayerId == 2 ? friendly : opposing); } var player1Name = GetPlayer1Name(log); if(player1Name == game?.PlayerName) return new PlayerInfo(friendly, opposing, 1); if(player1Name == game?.OpponentName) return new PlayerInfo(opposing, friendly, 2); return null; }
private static void GenerateTestMatches() { _match1 = new GameStats(GameResult.Win, "Druid", "Druid"); _match1.Result = GameResult.Win; _match1.Rank = 20; _match1.Coin = true; _match1.DeckName = _deck1.Name; _match1.StartTime = DateTime.Now.AddMinutes(-5); _match1.EndTime = DateTime.Now; _match1.Region = Region.EU; _match1.GameMode = GameMode.Casual; _match1.PlayerName = "Epix"; _match1.OpponentName = "trigun"; _match1.Turns = 10; _match2 = new GameStats(GameResult.Win, "Priest", "Warlock"); _match2.Result = GameResult.Win; _match2.Rank = 19; _match2.Coin = true; _match2.DeckName = _deck2.Name; _match2.StartTime = DateTime.Now.AddMinutes(-7); _match2.EndTime = DateTime.Now; _match2.Region = Region.US; _match2.GameMode = GameMode.Casual; _match2.PlayerName = "Epix"; _match2.OpponentName = "trigun"; _match2.Turns = 10; _match3 = new GameStats(GameResult.Win, "Mage", "Warrior"); _match3.Result = GameResult.Win; _match3.Rank = 18; _match3.Coin = false; _match3.DeckName = _deck2.Name; _match3.StartTime = DateTime.Now.AddMinutes(-6); _match3.EndTime = DateTime.Now; _match3.Region = Region.ASIA; _match3.GameMode = GameMode.Casual; _match3.PlayerName = "Epix"; _match3.OpponentName = "trigun"; _match3.Turns = 10; }
public AddGameDialog(Deck deck) { InitializeComponent(); _tcs = new TaskCompletionSource<GameStats>(); _editing = false; var lastGame = deck.DeckStats.Games.LastOrDefault(); if(deck.IsArenaDeck) { ComboBoxMode.SelectedItem = Arena; ComboBoxMode.IsEnabled = false; } else { ComboBoxMode.IsEnabled = true; TextBoxRank.IsEnabled = true; TextBoxLegendRank.IsEnabled = true; if(lastGame != null) { ComboBoxFormat.SelectedItem = lastGame.Format; ComboBoxMode.SelectedItem = lastGame.GameMode; if(lastGame.GameMode == Ranked) { TextBoxRank.Text = lastGame.Rank.ToString(); TextBoxLegendRank.Text = lastGame.LegendRank.ToString(); } } } if(lastGame != null) { PanelRank.Visibility = PanelLegendRank.Visibility = lastGame.GameMode == Ranked ? Visible : Collapsed; PanelFormat.Visibility = lastGame.GameMode == Ranked || lastGame.GameMode == Casual ? Visible : Collapsed; TextBoxPlayerName.Text = lastGame.PlayerName; if(lastGame.Region != Region.UNKNOWN) ComboBoxRegion.SelectedItem = lastGame.Region; } _deck = deck; _game = new GameStats(); BtnSave.Content = "add game"; Title = _deck.Name; }
public static async Task<PostResult> UploadMatchAsync(GameStats game, Deck deck, bool saveFilesAfter = true, bool background = false) { Log.Info("trying to upload match: " + game); if(!HearthStatsAPI.IsLoggedIn) { Log.Error("not logged in"); return PostResult.Failed; } if(!HearthStatsAPI.IsValidGame(game)) return PostResult.Failed; if(background) AddBackgroundActivity(); if(!deck.HasHearthStatsId) { Log.Info("...deck has no HearthStats id, uploading deck"); var success = await UploadDeckAsync(deck); if(!success.Success) { Log.Error("deck could not be uploaded or did not return an id. Can not upload match."); if(background) RemoveBackgroundActivity(); return PostResult.Failed; } } var result = await HearthStatsAPI.PostGameResultAsync(game, deck); if(!result.Success && result.Retry) { await Task.Delay(RetryDelay); Log.Info("try #2 to upload match: " + game); result = await HearthStatsAPI.PostGameResultAsync(game, deck); } if(result.Success && saveFilesAfter) DeckStatsList.Save(); if(background) RemoveBackgroundActivity(); if(result.Success) Log.Info("success uploading match " + game); return result; }
public GameResultNotificationWindow(string deckName, [NotNull] GameStats game) { InitializeComponent(); DeckName = deckName; _game = game; ComboBoxResult.ItemsSource = new[] { GameResult.Win, GameResult.Loss }; ComboBoxFormat.ItemsSource = new[] { Enums.Format.Standard, Enums.Format.Wild }; ComboBoxGameMode.ItemsSource = new[] { GameMode.Arena, GameMode.Brawl, GameMode.Casual, GameMode.Friendly, GameMode.Practice, GameMode.Ranked, GameMode.Spectator }; UpdatePosition(); _startUpTime = DateTime.UtcNow; CloseAsync(); Log.Info("Now showing"); Activate(); }
public GameResultNotificationWindow(string deckName, [NotNull] GameStats game) { InitializeComponent(); DeckName = deckName; _game = game; ComboBoxOpponentClass.ItemsSource = Enum.GetValues(typeof(HeroClass)).Cast<HeroClass>().Select(x => new HeroClassWrapper(x)); ComboBoxResult.ItemsSource = new[] {GameResult.Win, GameResult.Loss}; ComboBoxGameMode.ItemsSource = new[] { GameMode.Arena, GameMode.Brawl, GameMode.Casual, GameMode.Friendly, GameMode.Practice, GameMode.Ranked, GameMode.Spectator }; UpdatePosition(); _startUpTime = DateTime.UtcNow; CloseAsync(); Logger.WriteLine("Now showing", "GameResultNotification"); Activate(); }
#pragma warning disable 4014 public static async void HandleGameEnd() { Helper.MainWindow.Overlay.HideTimers(); if(Game.CurrentGameStats == null) return; if(Game.CurrentGameMode == GameMode.Spectator && !Config.Instance.RecordSpectator) { Logger.WriteLine("Game is in Spectator mode, discarded. (Record Spectator disabled)", "GameEventHandler"); _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 = HsLogReader.Instance.GetTurnNumber(); if(Config.Instance.DiscardZeroTurnGame && Game.CurrentGameStats.Turns < 1) { Logger.WriteLine("Game has 0 turns, discarded. (DiscardZeroTurnGame)", "GameEventHandler"); _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.PlayerDrawn.All( c => c.IsStolen || 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)", "GameEventHandler"); 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", "GameEventHandler"); Game.CurrentGameStats.DeleteGameFile(); _assignedDeck = null; return; } } } else { Logger.WriteLine("Assigned current game to NO deck - selected deck does not match cards played (no dialog)", "GameEventHandler"); 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, "GameStats"); _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", "GameEventHandler"); Helper.MainWindow.ArchiveDeck(_assignedDeck, false); } if(HearthStatsAPI.IsLoggedIn && Config.Instance.HearthStatsAutoUploadNewGames) { if(Game.CurrentGameMode == GameMode.None) await GameModeDetection(300); //give the user 5 minutes to get out of the victory/defeat screen if(Game.CurrentGameMode == GameMode.Casual) await HsLogReader.Instance.RankedDetection(); if(Game.CurrentGameMode == GameMode.Ranked && !_lastGame.HasRank) await RankDetection(5); await GameModeSaved(15); if(Game.CurrentGameMode == GameMode.Arena) HearthStatsManager.UploadArenaMatchAsync(_lastGame, selectedDeck, background: true); if(Game.CurrentGameMode == GameMode.Brawl) { /* do nothing */ } else HearthStatsManager.UploadMatchAsync(_lastGame, selectedDeck, background: true); } _lastGame = null; } else { DefaultDeckStats.Instance.GetDeckStats(Game.PlayingAs).AddGameResult(Game.CurrentGameStats); Logger.WriteLine(string.Format("Assigned current deck to default {0} deck.", Game.PlayingAs), "GameStats"); _assignedDeck = null; } }
protected bool Equals(GameStats other) { return GameId.Equals(other.GameId); }
public GameStats CloneWithNewId() { var newGame = new GameStats(Result, OpponentHero) {StartTime = StartTime, EndTime = EndTime, Coin = Coin, GameMode = GameMode, Turns = Turns, _turnStats = LoadTurnStats()}; newGame.Save(); return newGame; }
public void AddGameResult(GameStats gameStats) { Games.Add(gameStats); }
public static async Task<bool> ShowEditGameDialog(this MetroWindow window, GameStats game) { if(game == null) return false; var dialog = new AddGameDialog(game); await window.ShowMetroDialogAsync(dialog, new MetroDialogSettings {AffirmativeButtonText = "save", NegativeButtonText = "cancel"}); var result = await dialog.WaitForButtonPressAsync(); await window.HideMetroDialogAsync(dialog); if(result == null) return false; if(Config.Instance.HearthStatsAutoUploadNewGames && HearthStatsAPI.IsLoggedIn) { var deck = DeckList.Instance.Decks.FirstOrDefault(d => d.DeckId == game.DeckId); if(deck != null) { if(game.GameMode == GameMode.Arena) HearthStatsManager.UpdateArenaMatchAsync(game, deck, true, true); else HearthStatsManager.UpdateMatchAsync(game, deck.GetVersion(game.PlayerDeckVersion), true, true); } } DeckStatsList.Save(); Core.MainWindow.DeckPickerList.UpdateDecks(); return true; }
public void Remove(GameStats game) => Remove(game.GameId);
public void Add(GameStats game) => Add(game.DeckId, game.GameId, game.PlayerHero);
protected bool Equals(GameStats other) => GameId.Equals(other.GameId);
#pragma warning disable 4014 public async void HandleGameEnd() { if(_game.CurrentGameStats == null || _handledGameEnd) { Logger.WriteLine("HandleGameEnd was already called.", "HandleGameEnd"); return; } //deal with instant concedes if(_game.CurrentGameMode == Casual || _game.CurrentGameMode == None) DetectRanks(); _handledGameEnd = true; TurnTimer.Instance.Stop(); Core.Overlay.HideTimers(); Logger.WriteLine("Game ended...", "HandleGameEnd"); if(_game.CurrentGameMode == Spectator && !Config.Instance.RecordSpectator) { if(Config.Instance.ReselectLastDeckUsed && DeckList.Instance.ActiveDeck == null) { Core.MainWindow.SelectLastUsedDeck(); Config.Instance.ReselectLastDeckUsed = false; Logger.WriteLine("ReselectLastUsedDeck set to false", "HandleGameEnd"); Config.Save(); } 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(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) {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)) { 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.ArenaRewardDialog && selectedDeck.IsArenaRunCompleted.HasValue && selectedDeck.IsArenaRunCompleted.Value) _arenaRewardDialog = new ArenaRewardDialog(selectedDeck); 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) { Logger.WriteLine("Waiting for game mode detection...", "HandleGameEnd"); await _game.GameModeDetection(); Logger.WriteLine("Detected game mode, 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 == Arena) HearthStatsManager.UploadArenaMatchAsync(_lastGame, selectedDeck, background: true); else if(_game.CurrentGameMode != Brawl) HearthStatsManager.UploadMatchAsync(_lastGame, selectedDeck, background: true); } _lastGame = null; } else { try { DefaultDeckStats.Instance.GetDeckStats(_game.Player.Class).AddGameResult(_game.CurrentGameStats); Logger.WriteLine($"Assigned current deck to default {_game.Player.Class} deck.", "HandleGameEnd"); } catch(Exception ex) { Logger.WriteLine("Error saving to DefaultDeckStats: " + ex, "HandleGameEnd"); } _assignedDeck = null; } if(Config.Instance.ReselectLastDeckUsed && selectedDeck == null) { Core.MainWindow.SelectLastUsedDeck(); Config.Instance.ReselectLastDeckUsed = false; Logger.WriteLine("ReselectLastUsedDeck set to false", "HandleGameEnd"); Config.Save(); } }
protected bool Equals(GameStats other) { return(GameId.Equals(other.GameId)); }
public static async Task<MessageDialogResult> ShowDeleteGameStatsMessage(this MetroWindow window, GameStats stats) => await window.ShowMessageAsync("Delete Game", $"{stats.Result} vs {stats.OpponentHero}\nfrom {stats.StartTime}\n\nAre you sure?", AffirmativeAndNegative, new Settings {AffirmativeButtonText = "Yes", NegativeButtonText = "No"});
public GameStats CloneWithNewId() { var newGame = new GameStats(Result, OpponentHero, PlayerHero) { StartTime = StartTime, EndTime = EndTime, Coin = Coin, GameMode = GameMode, Turns = Turns, _turnStats = LoadTurnStats(), PlayerName = PlayerName, OpponentName = OpponentName, ReplayFile = ReplayFile, WasConceded = WasConceded, VerifiedHeroes = VerifiedHeroes, PlayerDeckVersion = PlayerDeckVersion, IsClone = true }; newGame.Save(); return newGame; }