コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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();
            }
        }
コード例 #5
0
        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");
        }
コード例 #6
0
        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();
        }
コード例 #7
0
ファイル: Capture.cs プロジェクト: andburn/hs-lab
        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");
            }
        }
コード例 #8
0
 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");
     }
 }
コード例 #9
0
        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();
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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);
        }
コード例 #12
0
        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);
                }
            }
        }
コード例 #13
0
 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);
     }
 }
コード例 #14
0
 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();
 }
コード例 #15
0
        /// <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();
        }
コード例 #16
0
        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();
        }
コード例 #17
0
        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);
        }
コード例 #18
0
        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();
        }
コード例 #19
0
        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();
            }
        }
コード例 #20
0
        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();
        }
コード例 #21
0
        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);
        }
コード例 #22
0
        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);
        }
コード例 #23
0
        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);
        }
コード例 #24
0
        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();
        }
コード例 #25
0
        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);
            }
        }
コード例 #26
0
        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();
                }
            }
        }
コード例 #27
0
        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);
        }
コード例 #28
0
        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();
        }
コード例 #29
0
        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();
        }
コード例 #30
0
        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);
        }