public static async Task <bool> ShowReplay(GameStats game, bool showToast) { if (game == null) { return(false); } 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 { setToastStatus?.Invoke(ReplayProgress.Error); if (game.HsReplay?.Unsupported ?? false) { ErrorManager.AddError("Can not load replay", "Game has no valid replay."); } else { ErrorManager.AddError("Error uploading replay", "Please try again later."); } return(false); } return(true); }
internal async void BtnCloneSelectedVersion_Click(object sender, RoutedEventArgs e) { var deck = DeckPickerList.SelectedDecks.FirstOrDefault(); if (deck == null) { return; } deck = deck.GetSelectedDeckVersion(); var cloneStats = (await this.ShowMessageAsync("Clone game history?", "(Cloned games do not count towards class or overall stats.)", MessageDialogStyle.AffirmativeAndNegative, new MessageDialogs.Settings { AffirmativeButtonText = "clone history", NegativeButtonText = "do not clone history" })) == MessageDialogResult.Affirmative; var clone = (Deck)deck.CloneWithNewId(false); clone.ResetVersions(); clone.Archived = false; var originalStatsEntry = clone.DeckStats; DeckList.Instance.Decks.Add(clone); DeckPickerList.UpdateDecks(); DeckList.Save(); DeckStats newStatsEntry; if (!DeckStatsList.Instance.DeckStats.TryGetValue(clone.DeckId, out newStatsEntry)) { newStatsEntry = new DeckStats(clone); DeckStatsList.Instance.DeckStats.TryAdd(clone.DeckId, newStatsEntry); } //clone game stats if (cloneStats) { foreach (var game in originalStatsEntry.Games) { newStatsEntry.AddGameResult(game.CloneWithNewId()); } Log.Info("cloned gamestats (version)"); } DeckStatsList.Save(); //DeckPickerList.UpdateList(); DeckPickerList.SelectDeckAndAppropriateView(clone); }
public static async Task <PostResult> UploadMatchAsync(GameStats game, Deck deck, bool saveFilesAfter = true, bool background = false) { Logger.WriteLine("trying to upload match: " + game, "HearthStatsManager"); if (!HearthStatsAPI.IsLoggedIn) { Logger.WriteLine("error: not logged in", "HearthStatsManager"); return(PostResult.Failed); } if (!HearthStatsAPI.IsValidGame(game)) { return(PostResult.Failed); } if (background) { AddBackgroundActivity(); } if (!deck.HasHearthStatsId) { Logger.WriteLine("...deck has no HearthStats id, uploading deck", "HearthStatsManager"); var success = await UploadDeckAsync(deck); if (!success.Success) { Logger.WriteLine("error: deck could not be uploaded or did not return an id. Can not upload match.", "HearthStatsManager"); if (background) { RemoveBackgroundActivity(); } return(PostResult.Failed); } } var result = await HearthStatsAPI.PostGameResultAsync(game, deck); if (!result.Success && result.Retry) { await Task.Delay(RetryDelay); Logger.WriteLine("try #2 to upload match: " + game, "HearthStatsManager"); result = await HearthStatsAPI.PostGameResultAsync(game, deck); } if (result.Success && saveFilesAfter) { DeckStatsList.Save(); } if (background) { RemoveBackgroundActivity(); } if (result.Success) { Logger.WriteLine("success uploading match " + game, "HearthStatsManager"); } return(result); }
internal async void BtnCloneDeck_Click(object sender, RoutedEventArgs e) { var deck = DeckPickerList.SelectedDecks.FirstOrDefault(); if (deck == null) { return; } var cloneStats = (await this.ShowMessageAsync("Clone game history?", "(Cloned games do not count towards class or overall stats.)", MessageDialogStyle.AffirmativeAndNegative, new MessageDialogs.Settings { AffirmativeButtonText = "clone history", NegativeButtonText = "do not clone history" })) == MessageDialogResult.Affirmative; var clone = (Deck)deck.CloneWithNewId(false); clone.ResetHearthstatsIds(); clone.Versions.ForEach(v => v.ResetHearthstatsIds()); clone.Archived = false; var originalStats = deck.DeckStats; DeckList.Instance.Decks.Add(clone); DeckList.Save(); var newStatsEntry = DeckStatsList.Instance.DeckStats.FirstOrDefault(ds => ds.BelongsToDeck(clone)); if (newStatsEntry == null) { newStatsEntry = new DeckStats(clone); DeckStatsList.Instance.DeckStats.Add(newStatsEntry); } if (cloneStats) { foreach (var game in originalStats.Games) { newStatsEntry.AddGameResult(game.CloneWithNewId()); } Logger.WriteLine("cloned gamestats", "Edit"); } DeckStatsList.Save(); DeckPickerList.SelectDeckAndAppropriateView(clone); if (Config.Instance.HearthStatsAutoUploadNewDecks && HearthStatsAPI.IsLoggedIn) { HearthStatsManager.UploadDeckAsync(clone).Forget(); } }
private async void DeleteDeck(Deck deck) { if (deck == null) { return; } var deckStats = DeckStatsList.Instance.DeckStats.FirstOrDefault(ds => ds.BelongsToDeck(deck)); if (deckStats != null) { if (deckStats.Games.Any()) { if (Config.Instance.KeepStatsWhenDeletingDeck) { DefaultDeckStats.Instance.GetDeckStats(deck.Class).Games.AddRange(deckStats.Games); DefaultDeckStats.Save(); Logger.WriteLine(string.Format("Moved deckstats for deck {0} to default stats", deck.Name), "Edit"); } else { try { foreach (var game in deckStats.Games) { game.DeleteGameFile(); } Logger.WriteLine("Deleted games from deck: " + deck.Name, "Edit"); } catch (Exception) { Logger.WriteLine("Error deleting games", "Edit"); } } } DeckStatsList.Instance.DeckStats.Remove(deckStats); DeckStatsList.Save(); Logger.WriteLine("Removed deckstats from deck: " + deck.Name, "Edit"); } if (HearthStatsAPI.IsLoggedIn && deck.HasHearthStatsId && await CheckHearthStatsDeckDeletion()) { HearthStatsManager.DeleteDeckAsync(deck, false, true); } DeckList.Instance.Decks.Remove(deck); DeckList.Save(); ; //DeckPickerList.RemoveDeck(deck); DeckPickerList.UpdateDecks(); ListViewDeck.ItemsSource = null; Logger.WriteLine("Deleted deck: " + deck.Name, "Edit"); }
private async void BtnCloneDeck_Click(object sender, RoutedEventArgs e) { var cloneStats = (await this.ShowMessageAsync("Clone game stats?", "Cloned games do not count towards class or overall stats.", MessageDialogStyle.AffirmativeAndNegative, new MetroDialogSettings() { AffirmativeButtonText = "Yes", NegativeButtonText = "No" })) == MessageDialogResult.Affirmative; var clone = (Deck)DeckPickerList.SelectedDeck.Clone(); var originalStatsEntry = clone.DeckStats; while (DeckList.DecksList.Any(d => d.Name == clone.Name)) { var settings = new MetroDialogSettings { AffirmativeButtonText = "Set", DefaultText = clone.Name }; var name = await this.ShowInputAsync("Name already exists", "You already have a deck with that name, please select a different one.", settings); if (string.IsNullOrEmpty(name)) { return; } clone.Name = name; } DeckList.DecksList.Add(clone); DeckPickerList.AddAndSelectDeck(clone); WriteDecks(); var newStatsEntry = DeckStatsList.Instance.DeckStats.FirstOrDefault(d => d.Name == clone.Name); if (newStatsEntry == null) { newStatsEntry = new DeckStats(clone.Name); DeckStatsList.Instance.DeckStats.Add(newStatsEntry); } //clone game stats if (cloneStats) { foreach (var game in originalStatsEntry.Games) { newStatsEntry.AddGameResult(game.CloneWithNewId()); } Logger.WriteLine("cloned gamestats"); } DeckStatsList.Save(); DeckPickerList.UpdateList(); }
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)Hearthstone_Deck_Tracker.Core.Windows.StatsWindow.FindName("StatsControl")).Refresh(); //} //else //{ // ((DeckStatsControl)Hearthstone_Deck_Tracker.API.Core.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)) { Log.Info("Invalid file name pattern, using default", "EndGame"); } var filename = np.Apply(game); SaveAsPng(screenshot.Full, Path.Combine(dir, filename)); } catch (Exception e) { Log.Info("Error saving image: " + e.Message, "EndGame"); } } else { Log.Info("Screenshot is null", "EndGame"); } } else { Log.Info("Game is null", "EndGame"); } }
public void UpdateGameNote(string text) { if (API.Core.Game.IsRunning && API.Core.Game.CurrentGameStats != null) { API.Core.Game.CurrentGameStats.Note = text; Common.Log.Debug($"Tracker: Note set '{text}'"); DeckStatsList.Save(); } else { Common.Log.Debug("Tracker: Update Note, game not running"); } }
public void SetDeck(Deck deck) { _deck = deck; if (deck == null) { TabControlCurrentOverall.SelectedIndex = 1; TabItemDeck.Visibility = Visibility.Collapsed; TabItemOverall.Visibility = Visibility.Collapsed; StackPanelUnassignedFilter.Visibility = Visibility.Visible; return; } TabItemDeck.Visibility = Visibility.Visible; TabItemOverall.Visibility = Visibility.Visible; StackPanelUnassignedFilter.Visibility = TabControlCurrentOverall.SelectedIndex == 1 ? Visibility.Visible : Visibility.Collapsed; DataGridGames.Items.Clear(); var filteredGames = FilterGames(deck.DeckStats.Games).ToList(); var modified = false; foreach (var game in filteredGames) { if (!game.VerifiedHeroes && VerifyHeroes(game)) { modified = true; } if (Config.Instance.StatsFilterOpponentHeroClass == HeroClassAll.All || game.OpponentHero == Config.Instance.StatsFilterOpponentHeroClass.ToString()) { DataGridGames.Items.Add(game); } } if (modified) { DeckStatsList.Save(); } DataGridWinLoss.Items.Clear(); DataGridWinLoss.Items.Add(new WinLoss(filteredGames, "%")); DataGridWinLoss.Items.Add(new WinLoss(filteredGames, "Win - Loss")); var defaultStats = DefaultDeckStats.Instance.GetDeckStats(deck.Class) ?? new DeckStats(); DataGridWinLossClass.Items.Clear(); var allGames = Helper.MainWindow.DeckList.DecksList.Where(d => d.GetClass == _deck.GetClass) .SelectMany(d => FilterGames(d.DeckStats.Games).Where(g => !g.IsClone)) .Concat(FilterGames(defaultStats.Games)) .ToList(); DataGridWinLossClass.Items.Add(new WinLoss(allGames, "%")); DataGridWinLossClass.Items.Add(new WinLoss(allGames, "Win - Loss")); DataGridGames.Items.Refresh(); }
public static async Task <PostResult> UploadMultipleMatchesAsync(IEnumerable <GameStats> games, Deck deck, bool saveFilesAfter = true, bool background = false) { Logger.WriteLine(string.Format("trying to upload {0} matches for deck {1}", games.Count(), deck.Name), "HearthStatsManager"); if (!HearthStatsAPI.IsLoggedIn) { Logger.WriteLine("error: not logged in", "HearthStatsManager"); return(PostResult.Failed); } List <GameStats> validGames = games.Where(HearthStatsAPI.IsValidGame).ToList(); if (!validGames.Any()) { Logger.WriteLine("No valid games", "HearthStatsManager"); return(PostResult.Failed); } if (background) { AddBackgroundActivity(); } if (!deck.HasHearthStatsId) { Logger.WriteLine("...deck has no HearthStats id, uploading deck", "HearthStatsManager"); var success = await UploadDeckAsync(deck); if (!success.Success) { Logger.WriteLine("error: deck could not be uploaded or did not return an id. Can not upload match.", "HearthStatsManager"); if (background) { RemoveBackgroundActivity(); } return(PostResult.Failed); } } var result = await HearthStatsAPI.PostMultipleGameResultsAsync(validGames, deck); if (result.Success && saveFilesAfter) { DeckStatsList.Save(); } if (background) { RemoveBackgroundActivity(); } if (result.Success) { Logger.WriteLine("success uploading " + validGames.Count + " matches", "HearthStatsManager"); } return(result); }
public static async Task <PostResult> UploadArenaMatchAsync(GameStats game, Deck deck, bool saveFilesAfter = false, bool background = false) { Logger.WriteLine("trying to upload arena match: " + game, "HearthStatsManager"); if (!HearthStatsAPI.IsLoggedIn) { Logger.WriteLine("error: not logged in", "HearthStatsManager"); return(PostResult.Failed); } if (background) { AddBackgroundActivity(); } if (!deck.HasHearthStatsArenaId) { Logger.WriteLine("...deck has no HearthStatsArenaId, creating arena run", "HearthStatsManager"); var createRun = await CreateArenaRunAsync(deck, false, background); if (!createRun.Success) { Logger.WriteLine("error: could not create arena run.", "HearthStatsManager"); if (background) { RemoveBackgroundActivity(); } return(PostResult.Failed); } } var result = await HearthStatsAPI.PostArenaMatch(game, deck); if (!result.Success && result.Retry) { await Task.Delay(RetryDelay); Logger.WriteLine("try #2 to upload arena match: " + game, "HearthStatsManager"); result = await HearthStatsAPI.PostArenaMatch(game, deck); } if (result.Success && saveFilesAfter) { DeckStatsList.Save(); } if (background) { RemoveBackgroundActivity(); } if (result.Success) { Logger.WriteLine("success uploading arena match " + game, "HearthStatsManager"); } return(result); }
private static async Task CleanUpGameFiles(ProgressDialogController controller) { var count = 0; int gamesCount; var lockMe = new object(); var options = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }; await Task.Run(() => { var games = DeckStatsList.Instance.DeckStats.Values.SelectMany(x => x.Games).Concat(DefaultDeckStats.Instance.DeckStats.SelectMany(x => x.Games)).ToList(); gamesCount = games.Count; Parallel.ForEach(games, options, (game, loopState) => { if (controller.IsCanceled) { loopState.Stop(); return; } if (game.OpponentCards.Any()) { return; } var oppCards = GetOpponentDeck(game); if (oppCards.Any()) { game.SetOpponentCards(oppCards); } game.DeleteGameFile(); lock (lockMe) { controller.SetProgress(1.0 * ++count / gamesCount); } }); }); DeckStatsList.Save(); DefaultDeckStats.Save(); if (!controller.IsCanceled) { try { Directory.Delete(GamesDir, true); } catch (Exception e) { Log.Error(e); } } }
internal static bool Restore(FileInfo backup, bool reload, params string[] files) { try { var archive = new ZipArchive(backup.OpenRead(), ZipArchiveMode.Read); if (files.Length == 0) { archive.ExtractToDirectory(Config.Instance.DataDir, true); } else { foreach (var file in files.Where(x => Files.Contains(x))) { archive.GetEntry(file).ExtractToFile(Path.Combine(Config.Instance.DataDir, file), true); } } if (!reload) { return(true); } if (files.Length == 0 || files.Contains("config.xml")) { Config.Load(); Config.Save(); } if (files.Length == 0 || files.Contains("PlayerDecks.xml")) { DeckList.Reload(); DeckList.Save(); } if (files.Length == 0 || files.Contains("DeckStats.xml")) { DeckStatsList.Reload(); DeckStatsList.Save(); } if (files.Length == 0 || files.Contains("DefaultDeckStats.xml")) { DefaultDeckStats.Reload(); DefaultDeckStats.Save(); } return(true); } catch (Exception ex) { Log.Error(ex); return(false); } }
private static void ResolveDeckStatsIds() { foreach (var deckStats in DeckStatsList.Instance.DeckStats) { var deck = DeckList.Instance.Decks.FirstOrDefault(d => d.Name == deckStats.Name); if (deck != null) { deckStats.DeckId = deck.DeckId; deckStats.HearthStatsDeckId = deck.HearthStatsId; } } DeckStatsList.Save(); DeckList.Save(); Config.Instance.ResolvedDeckStatsIds = true; Config.Save(); }
/// <summary> /// v0.10.0 caused opponent names to be saved as the hero, rather than the name. /// </summary> private static async void ResolveOpponentNames() { var games = DeckStatsList.Instance.DeckStats.SelectMany(ds => ds.Games) .Where(g => g.HasReplayFile && Enum.GetNames(typeof(HeroClass)).Any(x => x == g.OpponentName)) .ToList(); if (!games.Any()) { Config.Instance.ResolvedOpponentNames = true; Config.Save(); return; } var controller = await Core.MainWindow.ShowProgressAsync("Fixing opponent names in recorded games...", "v0.10.0 caused opponent names to be set to their hero, rather than the actual name.\n\nThis may take a moment.\n\nYou can cancel to continue this at a later time (or not at all).", true); await FixOppNameAndClass(games, controller); await controller.CloseAsync(); if (controller.IsCanceled) { var fix = await Core.MainWindow.ShowMessageAsync("Cancelled", "Fix remaining names on next start?", MessageDialogStyle.AffirmativeAndNegative, new MessageDialogs.Settings { AffirmativeButtonText = "next time", NegativeButtonText = "don\'t fix" }); if (fix == MessageDialogResult.Negative) { Config.Instance.ResolvedOpponentNames = true; Config.Save(); } } else { Config.Instance.ResolvedOpponentNames = true; Config.Save(); } DeckStatsList.Save(); }
private async void ButtonEdit_OnClick(object sender, RoutedEventArgs e) { if (SelectedGame == null) { return; } var window = Helper.GetParentWindow(this); if (window == null) { return; } await window.ShowEditGameDialog(SelectedGame); DeckStatsList.Save(); DefaultDeckStats.Save(); }
private void DeleteDeck(Deck deck) { if (deck == null) { return; } var deckStats = DeckStatsList.Instance.DeckStats.FirstOrDefault(ds => ds.Name == deck.Name); if (deckStats != null) { if (deckStats.Games.Any()) { if (Config.Instance.KeepStatsWhenDeletingDeck) { DefaultDeckStats.Instance.GetDeckStats(deck.Class).Games.AddRange(deckStats.Games); DefaultDeckStats.Save(); Logger.WriteLine(string.Format("Moved deckstats for deck {0} to default stats", deck.Name)); } else { try { foreach (var game in deckStats.Games) { game.DeleteGameFile(); } Logger.WriteLine("Deleted games from deck: " + deck.Name); } catch (Exception) { Logger.WriteLine("Error deleting games"); } } } DeckStatsList.Instance.DeckStats.Remove(deckStats); DeckStatsList.Save(); Logger.WriteLine("Removed deckstats from deck: " + deck.Name); } DeckList.DecksList.Remove(deck); WriteDecks(); DeckPickerList.RemoveDeck(deck); ListViewDeck.ItemsSource = null; Logger.WriteLine("Deleted deck: " + deck.Name); }
private async void BtnCloneDeck_Click(object sender, RoutedEventArgs e) { var clone = (Deck)Helper.MainWindow.DeckPickerList.SelectedDeck.Clone(); var originalStatsEntry = clone.DeckStats; while (Helper.MainWindow.DeckList.DecksList.Any(d => d.Name == clone.Name)) { var settings = new MetroDialogSettings(); settings.AffirmativeButtonText = "Set"; settings.DefaultText = clone.Name; var name = await Helper.MainWindow.ShowInputAsync("Name already exists", "You already have a deck with that name, please select a different one.", settings); if (String.IsNullOrEmpty(name)) { return; } clone.Name = name; } Helper.MainWindow.DeckList.DecksList.Add(clone); Helper.MainWindow.DeckPickerList.AddAndSelectDeck(clone); Helper.MainWindow.WriteDecks(); //clone game stats var newStatsEntry = DeckStatsList.Instance.DeckStats.FirstOrDefault(d => d.Name == clone.Name); if (newStatsEntry == null) { newStatsEntry = new DeckStats(clone.Name); DeckStatsList.Instance.DeckStats.Add(newStatsEntry); } foreach (var game in originalStatsEntry.Games) { newStatsEntry.AddGameResult(game.CloneWithNewId()); } Logger.WriteLine("cloned gamestats"); DeckStatsList.Save(); Helper.MainWindow.DeckPickerList.UpdateList(); After_Click(); }
private static void SaveAndUpdateStats() { var statsControl = Config.Instance.StatsInWindow ? Helper.MainWindow.StatsWindow.StatsControl : Helper.MainWindow.DeckStatsFlyout; if (RecordCurrentGameMode) { if (Config.Instance.ShowNoteDialogAfterGame && Config.Instance.NoteDialogDelayed && !_showedNoteDialog) { _showedNoteDialog = true; new NoteDialog(Game.CurrentGameStats); } if (Game.CurrentGameStats != null) { Game.CurrentGameStats.Turns = HsLogReader.Instance.GetTurnNumber(); if (Config.Instance.DiscardZeroTurnGame && Game.CurrentGameStats.Turns < 1) { Logger.WriteLine("Game has 0 turns, discarded. (DiscardZeroTurnGame)", "GameEventHandler"); return; } Game.CurrentGameStats.GameMode = Game.CurrentGameMode; Logger.WriteLine("Set CurrentGameStats.GameMode to " + Game.CurrentGameMode, "GameEventHandler"); Game.CurrentGameStats = null; } if (_assignedDeck == null) { Logger.WriteLine("Saving DefaultDeckStats", "GameEventHandler"); DefaultDeckStats.Save(); } else { Logger.WriteLine("Saving DeckStats", "GameEventHandler"); DeckStatsList.Save(); } Helper.MainWindow.DeckPickerList.UpdateDecks(); statsControl.Refresh(); } else if (_assignedDeck != null && _assignedDeck.DeckStats.Games.Contains(Game.CurrentGameStats)) { //game was not supposed to be recorded, remove from deck again. _assignedDeck.DeckStats.Games.Remove(Game.CurrentGameStats); statsControl.Refresh(); } }
private async void BtnDeleteDeck_Click(object sender, RoutedEventArgs e) { var deck = Helper.MainWindow.DeckPickerList.SelectedDeck; if (deck != null) { var settings = new MetroDialogSettings(); settings.AffirmativeButtonText = "Yes"; settings.NegativeButtonText = "No"; var result = await Helper.MainWindow.ShowMessageAsync("Deleting " + deck.Name, "Are you Sure?", MessageDialogStyle.AffirmativeAndNegative, settings); if (result == MessageDialogResult.Affirmative) { try { var deckStats = DeckStatsList.Instance.DeckStats.FirstOrDefault(ds => ds.Name == deck.Name); if (deckStats != null) { foreach (var game in deckStats.Games) { game.DeleteGameFile(); } DeckStatsList.Instance.DeckStats.Remove(deckStats); DeckStatsList.Save(); Logger.WriteLine("Deleted deckstats for deck: " + deck.Name); } Helper.MainWindow.DeckList.DecksList.Remove(deck); Helper.MainWindow.WriteDecks(); Helper.MainWindow.DeckPickerList.RemoveDeck(deck); Helper.MainWindow.ListViewDeck.ItemsSource = null; Logger.WriteLine("Deleted deck: " + deck.Name); } catch (Exception) { Logger.WriteLine("Error deleting deck"); } } } After_Click(); }
internal async void ShowCloneDeckDialog(Deck deck) { if (deck == null) { return; } var cloneStats = (await this.ShowMessageAsync("Clone game history?", "(Cloned games do not count towards class or overall stats.)", MessageDialogStyle.AffirmativeAndNegative, new MessageDialogs.Settings { AffirmativeButtonText = "clone history", NegativeButtonText = "do not clone history" })) == MessageDialogResult.Affirmative; var clone = (Deck)deck.CloneWithNewId(false); clone.Archived = false; var originalStats = deck.DeckStats; DeckList.Instance.Decks.Add(clone); DeckList.Save(); DeckStats newStatsEntry; if (!DeckStatsList.Instance.DeckStats.TryGetValue(clone.DeckId, out newStatsEntry)) { newStatsEntry = new DeckStats(clone); DeckStatsList.Instance.DeckStats.TryAdd(clone.DeckId, newStatsEntry); } if (cloneStats) { foreach (var game in originalStats.Games) { newStatsEntry.AddGameResult(game.CloneWithNewId()); } Log.Info("cloned gamestats"); } DeckStatsList.Save(); DeckPickerList.SelectDeckAndAppropriateView(clone); }
private void DeleteDeck(Deck deck, bool saveAndUpdate = true) { if (deck == null) { return; } if (Equals(DeckList.Instance.ActiveDeck, deck)) { SelectDeck(null, true); } DeckStats deckStats; if (DeckStatsList.Instance.DeckStats.TryGetValue(deck.DeckId, out deckStats)) { if (deckStats.Games.Any()) { if (Config.Instance.KeepStatsWhenDeletingDeck) { var defaultDeck = DefaultDeckStats.Instance.GetDeckStats(deck.Class); defaultDeck?.Games.AddRange(deckStats.Games); DefaultDeckStats.Save(); Log.Info($"Moved deckstats for deck {deck.Name} to default stats"); } } DeckStatsList.Instance.DeckStats.TryRemove(deckStats.DeckId, out deckStats); if (saveAndUpdate) { DeckStatsList.Save(); } Log.Info("Removed deckstats from deck: " + deck.Name); } DeckList.Instance.Decks.Remove(deck); if (saveAndUpdate) { DeckList.Save(); DeckPickerList.UpdateDecks(); DeckPickerList.UpdateArchivedClassVisibility(); } Log.Info("Deleted deck: " + deck.Name); }
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); } DeckStatsList.Save(); Core.MainWindow.DeckPickerList.UpdateDecks(); return(true); }
private async void BtnEditNote_Click(object sender, RoutedEventArgs e) { var selected = DataGridGames.SelectedItem as GameStats; if (selected == null) { return; } var settings = new MetroDialogSettings(); settings.DefaultText = selected.Note; var newNote = await Helper.MainWindow.ShowInputAsync("Note", "", settings); if (newNote == null) { return; } selected.Note = newNote; DeckStatsList.Save(); Refresh(); }
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); } }
private void GameResultToast_OnUnloaded(object sender, RoutedEventArgs e) { if (!_edited) { return; } DeckStatsList.Save(); if (!Config.Instance.HearthStatsAutoUploadNewGames || !HearthStatsAPI.IsLoggedIn) { return; } var deck = DeckList.Instance.Decks.FirstOrDefault(d => d.DeckId == _game.DeckId); if (deck == null) { return; } if (_game.HasHearthStatsId) { if (_game.GameMode == GameMode.Arena) { HearthStatsManager.UpdateArenaMatchAsync(_game, deck, true, true); } else { HearthStatsManager.UpdateMatchAsync(_game, deck.GetVersion(_game.PlayerDeckVersion), true, true); } } else { if (_game.GameMode == GameMode.Arena) { HearthStatsManager.UploadArenaMatchAsync(_game, deck, true, true).Forget(); } else { HearthStatsManager.UploadMatchAsync(_game, deck.GetVersion(_game.PlayerDeckVersion), true, true).Forget(); } } }
public static async Task <bool> ShowAddGameDialog(this MetroWindow window, Deck deck) { if (deck == null) { return(false); } var dialog = new AddGameDialog(deck); await window.ShowMetroDialogAsync(dialog, new MetroDialogSettings { AffirmativeButtonText = "save", NegativeButtonText = "cancel" }); var game = await dialog.WaitForButtonPressAsync(); await window.HideMetroDialogAsync(dialog); if (game == null) { return(false); } deck.DeckStats.AddGameResult(game); DeckStatsList.Save(); Core.MainWindow.DeckPickerList.UpdateDecks(forceUpdate: new[] { deck }); return(true); }
private async void EditGame(GameStats game) { if (game == null) { return; } var dialog = new AddGameDialog(game); await Helper.MainWindow.ShowMetroDialogAsync(dialog, new MetroDialogSettings { AffirmativeButtonText = "save", NegativeButtonText = "cancel" }); var result = await dialog.WaitForButtonPressAsync(); await Helper.MainWindow.HideMetroDialogAsync(dialog); if (result == null) //cancelled { return; } Refresh(); 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(); Helper.MainWindow.DeckPickerList.UpdateDecks(); }
private static void ResolveDeckStatsIssue() { foreach (var deck in DeckList.Instance.Decks) { foreach (var deckVersion in deck.Versions) { if (deckVersion.DeckStats.Games.Any()) { var games = deckVersion.DeckStats.Games.ToList(); foreach (var game in games) { deck.DeckStats.AddGameResult(game); deckVersion.DeckStats.Games.Remove(game); } } } } foreach (var deckStats in DeckStatsList.Instance.DeckStats) { if (deckStats.Games.Any() && !DeckList.Instance.Decks.Any(d => deckStats.BelongsToDeck(d))) { var games = deckStats.Games.ToList(); foreach (var game in games) { var defaultStats = DefaultDeckStats.Instance.GetDeckStats(game.PlayerHero); if (defaultStats != null) { defaultStats.AddGameResult(game); deckStats.Games.Remove(game); } } } } DeckStatsList.Save(); Config.Instance.ResolvedDeckStatsIssue = true; Config.Save(); }
internal async void ShowDeleteDecksMessage(IEnumerable <Deck> decks) { if (decks == null) { return; } var decksList = decks.ToList(); if (!decksList.Any()) { return; } var settings = new MessageDialogs.Settings { AffirmativeButtonText = "Yes", NegativeButtonText = "No" }; var keepStatsInfo = Config.Instance.KeepStatsWhenDeletingDeck ? "The stats will be kept (can be changed in options)" : "The stats will be deleted (can be changed in options)"; var result = await this.ShowMessageAsync("Deleting " + (decksList.Count == 1 ? decksList.First().Name : decksList.Count + " decks"), "Are you Sure?\n" + keepStatsInfo, MessageDialogStyle.AffirmativeAndNegative, settings); if (result == MessageDialogResult.Negative) { return; } foreach (var deck in decksList) { DeleteDeck(deck, false); } DeckStatsList.Save(); DeckList.Save(); DeckPickerList.UpdateDecks(); DeckPickerList.UpdateArchivedClassVisibility(); DeckManagerEvents.OnDeckDeleted.Execute(decksList); }