Example #1
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();
        }
        private static async Task <bool> TryUpload(string[] logLines, GameMetaData gameMetaData, GameStats game, bool submitFailure)
        {
            try
            {
                game?.HsReplay.UploadTry();
                var lines    = logLines.SkipWhile(x => !x.Contains("CREATE_GAME")).ToArray();
                var metaData = UploadMetaDataGenerator.Generate(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);
            }
        }
Example #3
0
        private void DeleteDeck(Deck deck, bool saveAndUpdate = true)
        {
            if (deck == null)
            {
                return;
            }

            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();
            }
            ListViewDeck.ItemsSource = null;
            Log.Info("Deleted deck: " + deck.Name);
        }
        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);
        }
        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);
        }
        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();
        }
Example #7
0
        //https://github.com/HearthSim/Hearthstone-Deck-Tracker/issues/2675
        private static void FixDeckStats()
        {
            var save = false;

            foreach (var d in DeckList.Instance.Decks.Where(d => d.DeckStats.DeckId != d.DeckId))
            {
                if (!DeckStatsList.Instance.DeckStats.TryGetValue(d.DeckId, out var deckStats))
                {
                    continue;
                }
                foreach (var game in deckStats.Games.ToList())
                {
                    deckStats.Games.Remove(game);
                    d.DeckStats.Games.Add(game);
                }
                save = true;
            }
            if (save)
            {
                DeckStatsList.Save();
                Core.MainWindow.DeckPickerList.UpdateDecks();
            }
        }
 private void StoryboardFadeOut_OnCompleted(object sender, EventArgs e)
 {
     if (_edited)
     {
         DeckStatsList.Save();
         if (Config.Instance.HearthStatsAutoUploadNewGames && HearthStatsAPI.IsLoggedIn)
         {
             var deck = DeckList.Instance.Decks.FirstOrDefault(d => d.DeckId == _game.DeckId);
             if (deck != null)
             {
                 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();
                     }
                 }
             }
         }
     }
     Close();
 }
Example #9
0
        internal async void BtnCloneSelectedVersion_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 MetroDialogSettings
            {
                AffirmativeButtonText = "clone history",
                NegativeButtonText = "do not clone history"
            })) == MessageDialogResult.Affirmative;
            var clone = (Deck)deck.CloneWithNewId(false);

            // bug #1316 - ResetVersions needs the current version as an argument
            clone.ResetVersions();
            clone.ResetHearthstatsIds();
            clone.Archived = false;

            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.Instance.Decks.Add(clone);
            DeckPickerList.UpdateDecks();
            DeckList.Save();


            var newStatsEntry = DeckStatsList.Instance.DeckStats.FirstOrDefault(ds => ds.BelongsToDeck(clone));

            if (newStatsEntry == null)
            {
                newStatsEntry = new DeckStats(clone);
                DeckStatsList.Instance.DeckStats.Add(newStatsEntry);
            }

            //clone game stats
            if (cloneStats)
            {
                foreach (var game in originalStatsEntry.Games)
                {
                    newStatsEntry.AddGameResult(game.CloneWithNewId());
                }
                Logger.WriteLine("cloned gamestats (version)", "Edit");
            }

            DeckStatsList.Save();
            //DeckPickerList.UpdateList();
            DeckPickerList.SelectDeckAndAppropriateView(clone);

            if (Config.Instance.HearthStatsAutoUploadNewDecks && HearthStatsAPI.IsLoggedIn)
            {
                HearthStatsManager.UploadDeckAsync(clone);
            }
        }
Example #10
0
        public async void SaveDeck(bool overwrite, SerializableVersion newVersion, bool workInProgressDeck = false)
        {
            var deckName = TextBoxDeckName.Text;

            if (string.IsNullOrEmpty(deckName))
            {
                var settings = new MessageDialogs.Settings {
                    AffirmativeButtonText = "Set", DefaultText = deckName
                };

                var name = await this.ShowInputAsync("No name set", "Please set a name for the deck", settings);

                if (string.IsNullOrEmpty(name))
                {
                    return;
                }

                deckName             = name;
                TextBoxDeckName.Text = name;
            }

            if (_newDeck.Cards.Sum(c => c.Count) != 30 && workInProgressDeck == false)
            {
                var settings = new MessageDialogs.Settings {
                    AffirmativeButtonText = "Yes", NegativeButtonText = "No"
                };

                var result =
                    await
                    this.ShowMessageAsync("Not 30 cards",
                                          $"Deck contains {_newDeck.Cards.Sum(c => c.Count)} cards. Is this what you want to save anyway?", MessageDialogStyle.AffirmativeAndNegative, settings);

                if (result != MessageDialogResult.Affirmative)
                {
                    return;
                }
            }

            var previousVersion = _newDeck.Version;

            if (overwrite && (_newDeck.Version != newVersion))
            {
                AddDeckHistory();
                _newDeck.Version                  = newVersion;
                _newDeck.SelectedVersion          = newVersion;
                _newDeck.HearthStatsDeckVersionId = "";
            }

            if (EditingDeck && overwrite)
            {
                DeckList.Instance.Decks.Remove(_newDeck);
            }

            var oldDeckName = _newDeck.Name;

            _newDeck.Name = deckName;

            var newDeckClone = (Deck)_newDeck.Clone();

            newDeckClone.Archived = false;

            DeckList.Instance.Decks.Add(newDeckClone);

            newDeckClone.LastEdited = DateTime.Now;

            DeckList.Save();

            Log.Info("Saved Decks");

            if (EditingDeck)
            {
                TagControlEdit.SetSelectedTags(new List <string>());
                if (deckName != oldDeckName)
                {
                    var statsEntry = DeckStatsList.Instance.DeckStats.FirstOrDefault(ds => ds.BelongsToDeck(_newDeck));
                    if (statsEntry != null)
                    {
                        if (overwrite)
                        {
                            statsEntry.Name = deckName;
                            Log.Info("Deck has new name, updated deckstats");
                            foreach (var game in statsEntry.Games)
                            {
                                game.DeckName = deckName;
                            }
                        }
                        else
                        {
                            var newStatsEntry = DeckStatsList.Instance.DeckStats.FirstOrDefault(ds => ds.BelongsToDeck(_newDeck));
                            if (newStatsEntry == null)
                            {
                                newStatsEntry = new DeckStats(_newDeck);
                                DeckStatsList.Instance.DeckStats.Add(newStatsEntry);
                            }
                            foreach (var game in statsEntry.Games)
                            {
                                newStatsEntry.AddGameResult(game.CloneWithNewId());
                            }
                            Log.Info("cloned gamestats for \"Set as new\"");
                        }
                        DeckStatsList.Save();
                    }
                }
            }


            if (Config.Instance.HearthStatsAutoUploadNewDecks && HearthStatsAPI.IsLoggedIn)
            {
                Log.Info("auto uploading new/edited deck");
                if (EditingDeck)
                {
                    if (previousVersion != newVersion)
                    {
                        HearthStatsManager.UploadVersionAsync(newDeckClone, _originalDeck.HearthStatsIdForUploading, background: true).Forget();
                    }
                    else
                    {
                        HearthStatsManager.UpdateDeckAsync(newDeckClone, background: true).Forget();
                    }
                }
                else
                {
                    HearthStatsManager.UploadDeckAsync(newDeckClone, background: true).Forget();
                }
            }

            if (EditingDeck)
            {
                DeckManagerEvents.OnDeckUpdated.Execute(newDeckClone);
            }
            else
            {
                DeckManagerEvents.OnDeckCreated.Execute(newDeckClone);
            }


            EditingDeck = false;

            foreach (var tag in _newDeck.Tags)
            {
                SortFilterDecksFlyout.AddSelectedTag(tag);
            }

            DeckPickerList.SelectDeckAndAppropriateView(newDeckClone);
            DeckPickerList.UpdateDecks(forceUpdate: new[] { newDeckClone });
            SelectDeck(newDeckClone, true);
            CloseNewDeck();
            ClearNewDeckSection();
        }
Example #11
0
        private async void Window_Closing(object sender, CancelEventArgs e)
        {
            try
            {
                if (HearthStatsManager.SyncInProgress && !_closeAnyway)
                {
                    e.Cancel = true;
                    var result =
                        await
                        this.ShowMessageAsync("WARNING! Sync with HearthStats in progress!",
                                              "Closing Hearthstone Deck Tracker now can cause data inconsistencies. Are you sure?",
                                              MessageDialogStyle.AffirmativeAndNegative,
                                              new MessageDialogs.Settings {
                        AffirmativeButtonText = "close anyway", NegativeButtonText = "wait"
                    });

                    if (result == MessageDialogResult.Negative)
                    {
                        while (HearthStatsManager.SyncInProgress)
                        {
                            await Task.Delay(100);
                        }
                        await this.ShowMessage("Sync is complete.", "You can close Hearthstone Deck Tracker now.");
                    }
                    else
                    {
                        _closeAnyway = true;
                        Close();
                    }
                }
                Core.UpdateOverlay = false;
                Core.Update        = false;

                //wait for update to finish, might otherwise crash when overlay gets disposed
                for (var i = 0; i < 100; i++)
                {
                    if (Core.CanShutdown)
                    {
                        break;
                    }
                    await Task.Delay(50);
                }

                ReplayReader.CloseViewers();

                Config.Instance.SelectedTags = Config.Instance.SelectedTags.Distinct().ToList();
                //Config.Instance.ShowAllDecks = DeckPickerList.ShowAll;
                Config.Instance.SelectedDeckPickerClasses = DeckPickerList.SelectedClasses.ToArray();

                Config.Instance.WindowWidth       = (int)(Width - (GridNewDeck.Visibility == Visible ? GridNewDeck.ActualWidth : 0));
                Config.Instance.WindowHeight      = (int)(Height - _heightChangeDueToSearchBox);
                Config.Instance.TrackerWindowTop  = (int)Top;
                Config.Instance.TrackerWindowLeft = (int)(Left + (MovedLeft ?? 0));

                //position of add. windows is NaN if they were never opened.
                if (!double.IsNaN(Core.Windows.PlayerWindow.Left))
                {
                    Config.Instance.PlayerWindowLeft = (int)Core.Windows.PlayerWindow.Left;
                }
                if (!double.IsNaN(Core.Windows.PlayerWindow.Top))
                {
                    Config.Instance.PlayerWindowTop = (int)Core.Windows.PlayerWindow.Top;
                }
                Config.Instance.PlayerWindowHeight = (int)Core.Windows.PlayerWindow.Height;

                if (!double.IsNaN(Core.Windows.OpponentWindow.Left))
                {
                    Config.Instance.OpponentWindowLeft = (int)Core.Windows.OpponentWindow.Left;
                }
                if (!double.IsNaN(Core.Windows.OpponentWindow.Top))
                {
                    Config.Instance.OpponentWindowTop = (int)Core.Windows.OpponentWindow.Top;
                }
                Config.Instance.OpponentWindowHeight = (int)Core.Windows.OpponentWindow.Height;

                if (!double.IsNaN(Core.Windows.TimerWindow.Left))
                {
                    Config.Instance.TimerWindowLeft = (int)Core.Windows.TimerWindow.Left;
                }
                if (!double.IsNaN(Core.Windows.TimerWindow.Top))
                {
                    Config.Instance.TimerWindowTop = (int)Core.Windows.TimerWindow.Top;
                }
                Config.Instance.TimerWindowHeight = (int)Core.Windows.TimerWindow.Height;
                Config.Instance.TimerWindowWidth  = (int)Core.Windows.TimerWindow.Width;

                Core.TrayIcon.NotifyIcon.Visible = false;
                Core.Overlay.Close();
                await LogReaderManager.Stop(true);

                Core.Windows.TimerWindow.Shutdown();
                Core.Windows.PlayerWindow.Shutdown();
                Core.Windows.OpponentWindow.Shutdown();
                Config.Save();
                DeckList.Save();
                DeckStatsList.Save();
                PluginManager.SavePluginsSettings();
                PluginManager.Instance.UnloadPlugins();
            }
            catch (Exception)
            {
                //doesnt matter
            }
            finally
            {
                Application.Current.Shutdown();
            }
        }
        private async void SaveDeck(bool overwrite)
        {
            var deckName = TextBoxDeckName.Text;

            if (string.IsNullOrEmpty(deckName))
            {
                var settings = new MetroDialogSettings {
                    AffirmativeButtonText = "Set", DefaultText = deckName
                };

                var name = await this.ShowInputAsync("No name set", "Please set a name for the deck", settings);

                if (String.IsNullOrEmpty(name))
                {
                    return;
                }

                deckName             = name;
                TextBoxDeckName.Text = name;
            }

            while (DeckList.DecksList.Any(d => d.Name == deckName) && (!EditingDeck || !overwrite))
            {
                var settings = new MetroDialogSettings {
                    AffirmativeButtonText = "Set", DefaultText = deckName
                };
                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;
                }

                deckName             = name;
                TextBoxDeckName.Text = name;
            }

            if (_newDeck.Cards.Sum(c => c.Count) != 30)
            {
                var settings = new MetroDialogSettings {
                    AffirmativeButtonText = "Yes", NegativeButtonText = "No"
                };

                var result =
                    await
                    this.ShowMessageAsync("Not 30 cards",
                                          string.Format("Deck contains {0} cards. Is this what you want to save anyway?",
                                                        _newDeck.Cards.Sum(c => c.Count)),
                                          MessageDialogStyle.AffirmativeAndNegative, settings);

                if (result != MessageDialogResult.Affirmative)
                {
                    return;
                }
            }

            if (EditingDeck && overwrite)
            {
                DeckList.DecksList.Remove(_newDeck);
                DeckPickerList.RemoveDeck(_newDeck);
            }

            var oldDeckName = _newDeck.Name;

            _newDeck.Name = deckName;
            _newDeck.Tags = TagControlEdit.GetTags();

            var newDeckClone = (Deck)_newDeck.Clone();

            DeckList.DecksList.Add(newDeckClone);

            newDeckClone.LastEdited = DateTime.Now;

            WriteDecks();
            Logger.WriteLine("Saved Decks");

            if (EditingDeck)
            {
                TagControlEdit.SetSelectedTags(new List <string>());
                if (deckName != oldDeckName)
                {
                    var statsEntry = DeckStatsList.Instance.DeckStats.FirstOrDefault(d => d.Name == oldDeckName);
                    if (statsEntry != null)
                    {
                        if (overwrite)
                        {
                            statsEntry.Name = deckName;
                            Logger.WriteLine("Deck has new name, updated deckstats");
                        }
                        else
                        {
                            var newStatsEntry = DeckStatsList.Instance.DeckStats.FirstOrDefault(d => d.Name == deckName);
                            if (newStatsEntry == null)
                            {
                                newStatsEntry = new DeckStats(deckName);
                                DeckStatsList.Instance.DeckStats.Add(newStatsEntry);
                            }
                            foreach (var game in statsEntry.Games)
                            {
                                newStatsEntry.AddGameResult(game.CloneWithNewId());
                            }
                            Logger.WriteLine("cloned gamestats for \"Set as new\"");
                        }
                        DeckStatsList.Save();
                    }
                }
            }

            //after cloning the stats, otherwise new stats will be generated
            DeckPickerList.AddAndSelectDeck(newDeckClone);

            EditingDeck = false;

            foreach (var tag in _newDeck.Tags)
            {
                SortFilterDecksFlyout.AddSelectedTag(tag);
            }

            DeckPickerList.UpdateList();
            DeckPickerList.SelectDeck(newDeckClone);

            CloseNewDeck();
            ClearNewDeckSection();
        }
Example #13
0
        private async void DeleteGames(DataGrid dataGrid, bool overall)
        {
            MetroWindow window;

            if (Config.Instance.StatsInWindow)
            {
                window = Core.Windows.StatsWindow;
            }
            else
            {
                window = Helper.MainWindow;
            }

            var count = dataGrid.SelectedItems.Count;

            if (count == 1)
            {
                var selectedGame = dataGrid.SelectedItem as GameStats;
                if (selectedGame == null)
                {
                    return;
                }

                if (await window.ShowDeleteGameStatsMessage(selectedGame) != MessageDialogResult.Affirmative)
                {
                    return;
                }
                if (!overall)
                {
                    if (_deck.DeckStats.Games.Contains(selectedGame))
                    {
                        selectedGame.DeleteGameFile();
                        _deck.DeckStats.Games.Remove(selectedGame);
                        Logger.WriteLine("Deleted game " + selectedGame + "(overall=" + overall + ")", "DeckStatsControl");
                        DeckStatsList.Save();
                    }
                }
                else
                {
                    var deck = DeckList.Instance.Decks.FirstOrDefault(d => d.DeckStats.Games.Contains(selectedGame));
                    if (deck != null)
                    {
                        if (deck.DeckStats.Games.Contains(selectedGame))
                        {
                            selectedGame.DeleteGameFile();
                            deck.DeckStats.Games.Remove(selectedGame);
                            Logger.WriteLine("Deleted game " + selectedGame + "(overall=" + overall + ")", "DeckStatsControl");
                            DefaultDeckStats.Save();
                        }
                    }
                    else
                    {
                        var deckstats = DefaultDeckStats.Instance.DeckStats.FirstOrDefault(ds => ds.Games.Contains(selectedGame));
                        if (deckstats != null)
                        {
                            selectedGame.DeleteGameFile();
                            deckstats.Games.Remove(selectedGame);
                            Logger.WriteLine("Deleted game " + selectedGame + "(overall=" + overall + ")", "DeckStatsControl");
                            DefaultDeckStats.Save();
                        }
                    }
                }
                if (HearthStatsAPI.IsLoggedIn && selectedGame.HasHearthStatsId && await Core.MainWindow.ShowCheckHearthStatsMatchDeletionDialog())
                {
                    HearthStatsManager.DeleteMatchesAsync(new List <GameStats> {
                        selectedGame
                    });
                }
                //Core.MainWindow.DeckPickerList.Items.Refresh();
                Core.MainWindow.DeckPickerList.UpdateDecks();
                Refresh();
            }
            else if (count > 1)
            {
                if (await window.ShowDeleteMultipleGameStatsMessage(count) != MessageDialogResult.Affirmative)
                {
                    return;
                }
                var selectedGames = dataGrid.SelectedItems.Cast <GameStats>().Where(g => g != null).ToList();
                foreach (var selectedGame in selectedGames)
                {
                    if (!overall)
                    {
                        if (_deck.DeckStats.Games.Contains(selectedGame))
                        {
                            selectedGame.DeleteGameFile();
                            _deck.DeckStats.Games.Remove(selectedGame);
                            Logger.WriteLine("Deleted game " + selectedGame + "(overall=" + overall + ")", "DeckStatsControl");
                        }
                    }
                    else
                    {
                        var deck = DeckList.Instance.Decks.FirstOrDefault(d => d.DeckStats.Games.Contains(selectedGame));
                        if (deck != null)
                        {
                            if (deck.DeckStats.Games.Contains(selectedGame))
                            {
                                selectedGame.DeleteGameFile();
                                deck.DeckStats.Games.Remove(selectedGame);
                                Logger.WriteLine("Deleted game " + selectedGame + "(overall=" + overall + ")", "DeckStatsControl");
                            }
                        }
                        else
                        {
                            var deckstats = DefaultDeckStats.Instance.DeckStats.FirstOrDefault(ds => ds.Games.Contains(selectedGame));
                            if (deckstats != null)
                            {
                                selectedGame.DeleteGameFile();
                                deckstats.Games.Remove(selectedGame);
                                Logger.WriteLine("Deleted game " + selectedGame + "(overall=" + overall + ")", "DeckStatsControl");
                            }
                        }
                    }
                }

                if (HearthStatsAPI.IsLoggedIn && selectedGames.Any(g => g.HasHearthStatsId) &&
                    await Core.MainWindow.ShowCheckHearthStatsMatchDeletionDialog())
                {
                    HearthStatsManager.DeleteMatchesAsync(selectedGames);
                }
                DeckStatsList.Save();
                DefaultDeckStats.Save();
                Logger.WriteLine("Deleted " + count + " games", "DeckStatsControl");
                Core.MainWindow.DeckPickerList.UpdateDecks();
                Refresh();
            }
        }
Example #14
0
        private void MoveGameToOtherDeck(List <GameStats> selectedGames)
        {
            if (selectedGames == null)
            {
                return;
            }

            var heroes = new Dictionary <string, int>();

            foreach (var game in selectedGames)
            {
                if (!heroes.ContainsKey(game.PlayerHero))
                {
                    heroes.Add(game.PlayerHero, 0);
                }
                heroes[game.PlayerHero]++;
            }

            var heroPlayed      = heroes.Any() ? heroes.OrderByDescending(x => x.Value).First().Key : "Any";
            var possibleTargets = DeckList.Instance.Decks.Where(d => d.Class == heroPlayed || heroPlayed == "Any");

            var dialog = new MoveGameDialog(possibleTargets);

            if (Config.Instance.StatsInWindow)
            {
                dialog.Owner = Core.Windows.StatsWindow;
            }
            else
            {
                dialog.Owner = Helper.MainWindow;
            }

            dialog.ShowDialog();
            var selectedDeck = dialog.SelectedDeck;

            if (selectedDeck == null)
            {
                return;
            }
            foreach (var game in selectedGames)
            {
                var defaultDeck = DefaultDeckStats.Instance.DeckStats.FirstOrDefault(ds => ds.Games.Contains(game));
                if (defaultDeck != null)
                {
                    defaultDeck.Games.Remove(game);
                    DefaultDeckStats.Save();
                }
                else
                {
                    var deck = DeckList.Instance.Decks.FirstOrDefault(d => game.DeckId == d.DeckId);
                    if (deck != null)
                    {
                        deck.DeckStats.Games.Remove(game);
                    }
                }
                game.PlayerDeckVersion        = dialog.SelectedVersion;
                game.HearthStatsDeckVersionId = selectedDeck.GetVersion(dialog.SelectedVersion).HearthStatsDeckVersionId;
                game.DeckId   = selectedDeck.DeckId;
                game.DeckName = selectedDeck.Name;
                selectedDeck.DeckStats.Games.Add(game);
                if (HearthStatsAPI.IsLoggedIn && Config.Instance.HearthStatsAutoUploadNewGames)
                {
                    HearthStatsManager.MoveMatchAsync(game, selectedDeck, background: true);
                }
            }
            DeckStatsList.Save();
            DeckList.Save();
            Refresh();
            Core.MainWindow.DeckPickerList.UpdateDecks();
        }
        public static async Task <PostResult> PostMultipleGameResultsAsync(IEnumerable <GameStats> games, Deck deck)
        {
            var  validGames = games.Where(x => IsValidGame(x) && !x.HasHearthStatsId).ToList();
            long versionId;

            if (!long.TryParse(deck.HearthStatsDeckVersionId, out versionId))
            {
                Log.Error("invalid HearthStatsDeckVersionId");
                return(PostResult.Failed);
            }

            var     url      = BaseUrl + "/matches/multi_create?auth_token=" + _authToken;
            dynamic gameObjs = new ExpandoObject[validGames.Count];

            for (int i = 0; i < validGames.Count; i++)
            {
                gameObjs[i]                 = new ExpandoObject();
                gameObjs[i].mode            = validGames[i].GameMode.ToString();
                gameObjs[i].@class          = string.IsNullOrEmpty(validGames[i].PlayerHero) ? deck.Class : validGames[i].PlayerHero;
                gameObjs[i].result          = validGames[i].Result.ToString();
                gameObjs[i].coin            = validGames[i].Coin.ToString().ToLower();
                gameObjs[i].numturns        = validGames[i].Turns;
                gameObjs[i].duration        = (int)(validGames[i].EndTime - validGames[i].StartTime).TotalSeconds;
                gameObjs[i].deck_id         = deck.HearthStatsIdForUploading;
                gameObjs[i].deck_version_id = versionId;
                if (!string.IsNullOrEmpty(validGames[i].OpponentHero))
                {
                    gameObjs[i].oppclass = validGames[i].OpponentHero;
                }
                if (!string.IsNullOrEmpty(validGames[i].OpponentName))
                {
                    gameObjs[i].oppname = validGames[i].OpponentName;
                }
                if (!string.IsNullOrEmpty(validGames[i].Note))
                {
                    gameObjs[i].notes = validGames[i].Note;
                }
                if (validGames[i].GameMode == GameMode.Ranked && validGames[i].HasRank)
                {
                    gameObjs[i].ranklvl = validGames[i].Rank.ToString();
                }
                var opponentCards = validGames[i].GetOpponentDeck().Cards;
                if (opponentCards.Where(Database.IsActualCard).Any())
                {
                    gameObjs[i].oppcards = opponentCards.Where(Database.IsActualCard).Select(c => new { id = c.Id, count = c.Count }).ToArray();
                }
                gameObjs[i].created_at = validGames[i].StartTime.ToUniversalTime().ToString("s");
            }


            var data = JsonConvert.SerializeObject(new { deck_id = deck.HearthStatsIdForUploading, matches = gameObjs });

            try
            {
                var response = await PostAsync(url, data);

                dynamic json = JsonConvert.DeserializeObject(response);
                if (json.status.ToString() == "404")
                {
                    //deck does not exist on hearthstats
                    deck.ResetHearthstatsIds();
                    DeckList.Save();
                    deck.DeckStats.Games.ForEach(g => g.ResetHearthstatsIds());
                    DeckStatsList.Save();
                    return(PostResult.Failed);
                }
                if (json.status.ToString() != "200")
                {
                    Log.Error($"{json.message.ToString()} (Status code: {json.status.ToString()})");
                }

                for (int i = 0; i < validGames.Count; i++)
                {
                    if (json.data[i].status == "200")
                    {
                        validGames[i].HearthStatsId = json.data[i].data.id;
                        Log.Info("assigned id to match: " + validGames[i].HearthStatsId);
                    }
                    else
                    {
                        Log.Error($"Error uploading match {validGames[i]}: {json.data[i].status}");
                    }
                }
                return(PostResult.WasSuccess);
            }
            catch (Exception e)
            {
                Log.Error(e);
                return(PostResult.Failed);
            }
        }
Example #16
0
        private void SaveAndUpdateStats()
        {
            if (RecordCurrentGameMode)
            {
                if (Config.Instance.ShowNoteDialogAfterGame && Config.Instance.NoteDialogDelayed && !_showedNoteDialog)
                {
                    _showedNoteDialog = true;
                    new NoteDialog(_game.CurrentGameStats);
                }

                if (_game.CurrentGameStats != null)
                {
                    _game.CurrentGameStats.Turns = _game.GetTurnNumber();
                    if (Config.Instance.DiscardZeroTurnGame && _game.CurrentGameStats.Turns < 1)
                    {
                        Log.Info("Game has 0 turns, discarded. (DiscardZeroTurnGame)");
                        return;
                    }
                    if (_game.CurrentGameStats.GameMode != _game.CurrentGameMode)
                    {
                        _game.CurrentGameStats.GameMode = _game.CurrentGameMode;
                        Log.Info("Set CurrentGameStats.GameMode to " + _game.CurrentGameMode);
                    }
                    if (_game.CurrentGameStats.GameMode == Arena)
                    {
                        ArenaStats.Instance.UpdateArenaStats();
                        ArenaStats.Instance.UpdateArenaRuns();
                        ArenaStats.Instance.UpdateArenaStatsHighlights();
                    }
                    else
                    {
                        ConstructedStats.Instance.UpdateConstructedStats();
                    }
                }

                if (_assignedDeck == null)
                {
                    Log.Info("Saving DefaultDeckStats");
                    DefaultDeckStats.Save();
                }
                else
                {
                    _assignedDeck.StatsUpdated();
                    Log.Info("Saving DeckStats");
                    DeckStatsList.Save();
                }
                LastGames.Instance.Add(_game.CurrentGameStats);
                LastGames.Save();
            }
            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);
                Log.Info($"Gamemode {_game.CurrentGameMode} is not supposed to be saved. Removed game from {_assignedDeck}.");
            }
            else if (_assignedDeck == null)
            {
                var defaultDeck = DefaultDeckStats.Instance.GetDeckStats(_game.Player.Class);
                if (defaultDeck != null)
                {
                    defaultDeck.Games.Remove(_game.CurrentGameStats);
                    Log.Info($"Gamemode {_game.CurrentGameMode} is not supposed to be saved. Removed game from default {_game.Player.Class}.");
                }
            }
        }
        private void BtnMoveToOtherDeck_Click(object sender, RoutedEventArgs e)
        {
            var selectedGame = DataGridGames.SelectedItem as GameStats;

            if (selectedGame == null)
            {
                return;
            }

            var heroes = new Dictionary <string, int>();

            foreach (var turn in selectedGame.TurnStats)
            {
                foreach (var play in turn.Plays)
                {
                    if (!play.Type.ToString().Contains("Player"))
                    {
                        continue;
                    }
                    var hero = Game.GetCardFromId(play.CardId).PlayerClass;
                    if (hero == null)
                    {
                        continue;
                    }
                    if (!heroes.ContainsKey(hero))
                    {
                        heroes.Add(hero, 0);
                    }
                    heroes[hero]++;
                }
            }

            var heroPlayed = heroes.OrderByDescending(x => x.Value).First().Key;

            var possibleTargets = Helper.MainWindow.DeckList.DecksList.Where(d => d.Class == heroPlayed);

            var dialog = new MoveGameDialog(possibleTargets);

            if (Config.Instance.StatsInWindow)
            {
                dialog.Owner = Helper.MainWindow.StatsWindow;
            }
            else
            {
                dialog.Owner = Helper.MainWindow;
            }

            dialog.ShowDialog();
            var selectedDeck = dialog.SelectedDeck;

            if (selectedDeck == null)
            {
                return;
            }

            _deck.DeckStats.Games.Remove(selectedGame);
            selectedDeck.DeckStats.Games.Add(selectedGame);
            DeckStatsList.Save();
            Helper.MainWindow.WriteDecks();
            Refresh();
            Helper.MainWindow.DeckPickerList.UpdateList();
        }
        private async void BtnDelete_Click(object sender, RoutedEventArgs e)
        {
            if (_deck == null)
            {
                return;
            }

            MetroWindow window;

            if (Config.Instance.StatsInWindow)
            {
                window = Helper.MainWindow.StatsWindow;
            }
            else
            {
                window = Helper.MainWindow;
            }

            var count = DataGridGames.SelectedItems.Count;

            if (count == 1)
            {
                var selectedGame = DataGridGames.SelectedItem as GameStats;
                if (selectedGame == null)
                {
                    return;
                }

                if (await window.ShowDeleteGameStatsMessage(selectedGame) != MessageDialogResult.Affirmative)
                {
                    return;
                }

                if (_deck.DeckStats.Games.Contains(selectedGame))
                {
                    selectedGame.DeleteGameFile();
                    _deck.DeckStats.Games.Remove(selectedGame);
                    DeckStatsList.Save();
                    Logger.WriteLine("Deleted game: " + selectedGame);
                    Helper.MainWindow.DeckPickerList.Items.Refresh();
                    Refresh();
                }
            }
            else if (count > 1)
            {
                if (await window.ShowDeleteMultipleGameStatsMessage(count) != MessageDialogResult.Affirmative)
                {
                    return;
                }
                foreach (var selectedItem in DataGridGames.SelectedItems)
                {
                    var selectedGame = selectedItem as GameStats;
                    if (selectedGame == null)
                    {
                        continue;
                    }
                    if (!_deck.DeckStats.Games.Contains(selectedGame))
                    {
                        continue;
                    }
                    selectedGame.DeleteGameFile();
                    _deck.DeckStats.Games.Remove(selectedGame);
                }
                DeckStatsList.Save();
                Logger.WriteLine("Deleted " + count + " games");
                Helper.MainWindow.DeckPickerList.Items.Refresh();
                Refresh();
            }
        }
        /// <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);

            var count  = 0;
            var lockMe = new object();
            await Task.Run(() =>
            {
                Parallel.ForEach(games, (game, loopState) =>
                {
                    if (controller.IsCanceled)
                    {
                        loopState.Stop();
                    }
                    List <ReplayKeyPoint> replay = ReplayReader.LoadReplay(game.ReplayFile);
                    if (replay == null)
                    {
                        return;
                    }
                    var last = replay.LastOrDefault();
                    if (last == null)
                    {
                        return;
                    }
                    var opponent = last.Data.FirstOrDefault(x => x.IsOpponent);
                    if (opponent == null)
                    {
                        return;
                    }
                    game.OpponentName = opponent.Name;
                    lock (lockMe)
                    {
                        controller.SetProgress(1.0 * ++count / games.Count);
                    }
                });
            });

            await controller.CloseAsync();

            if (controller.IsCanceled)
            {
                var fix =
                    await
                    Core.MainWindow.ShowMessageAsync("Cancelled", "Fix remaining names on next start?", MessageDialogStyle.AffirmativeAndNegative,
                                                     new MetroDialogSettings { 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();
        }
Example #20
0
        private async void BtnCloneSelectedVersion_Click(object sender, RoutedEventArgs e)
        {
            var deck = DeckPickerList.GetSelectedDeckVersion();

            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 MetroDialogSettings
            {
                AffirmativeButtonText = "clone history",
                NegativeButtonText = "do not clone history"
            })) == MessageDialogResult.Affirmative;
            var clone = (Deck)deck.Clone();

            clone.ResetVersions();

            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 async Task <PostResult> PostGameResultAsync(GameStats game, Deck deck)
        {
            if (!IsValidGame(game))
            {
                return(PostResult.Failed);
            }
            if (!deck.HasHearthStatsId)
            {
                Log.Warn("can not upload game, deck has no hearthstats id");
                return(PostResult.Failed);
            }
            long versionId;

            if (!long.TryParse(deck.HearthStatsDeckVersionId, out versionId))
            {
                Log.Error("invalid HearthStatsDeckVersionId");
                return(PostResult.Failed);
            }
            Log.Info("uploading match: " + game);
            var url = BaseUrl + "/matches?auth_token=" + _authToken;

            dynamic gameObj = new ExpandoObject();

            gameObj.mode            = game.GameMode.ToString();
            gameObj.@class          = string.IsNullOrEmpty(game.PlayerHero) ? deck.Class : game.PlayerHero;
            gameObj.result          = game.Result.ToString();
            gameObj.coin            = game.Coin.ToString().ToLower();
            gameObj.numturns        = game.Turns;
            gameObj.duration        = (int)(game.EndTime - game.StartTime).TotalSeconds;
            gameObj.deck_id         = deck.HearthStatsIdForUploading;
            gameObj.deck_version_id = versionId;
            if (!string.IsNullOrEmpty(game.OpponentHero))
            {
                gameObj.oppclass = game.OpponentHero;
            }
            if (!string.IsNullOrEmpty(game.OpponentName))
            {
                gameObj.oppname = game.OpponentName;
            }
            if (!string.IsNullOrEmpty(game.Note))
            {
                gameObj.notes = game.Note;
            }
            if (game.GameMode == GameMode.Ranked && game.HasRank)
            {
                gameObj.ranklvl = game.Rank.ToString();
            }
            var opponentCards = game.GetOpponentDeck().Cards;

            if (opponentCards.Where(Database.IsActualCard).Any())
            {
                gameObj.oppcards = opponentCards.Where(Database.IsActualCard).Select(c => new { id = c.Id, count = c.Count }).ToArray();
            }
            gameObj.created_at = game.StartTime.ToUniversalTime().ToString("s");

            var data = JsonConvert.SerializeObject(gameObj);

            try
            {
                var response = await PostAsync(url, data);

                var json = JsonConvert.DeserializeObject(response);
                if (json.status.ToString() == "200")
                {
                    game.HearthStatsId = json.data.id;
                    Log.Info("assigned id to match: " + game.HearthStatsId);
                    return(PostResult.WasSuccess);
                }
                if (json.status.ToString() == "fail" && json.message.ToString().Contains("Deck could not be found"))
                {
                    //deck does not exist on hearthstats
                    deck.ResetHearthstatsIds();
                    DeckList.Save();
                    deck.DeckStats.Games.ForEach(g => g.ResetHearthstatsIds());
                    DeckStatsList.Save();
                }
                return(PostResult.Failed);
            }
            catch (Exception e)
            {
                Log.Error(e);
                return(PostResult.Failed);
            }
        }
        private void MoveGameToOtherDeck(GameStats selectedGame)
        {
            if (selectedGame == null)
            {
                return;
            }

            var heroes = new Dictionary <string, int>();

            foreach (var turn in selectedGame.TurnStats)
            {
                foreach (var play in turn.Plays)
                {
                    if (!play.Type.ToString().Contains("Player"))
                    {
                        continue;
                    }
                    var hero = Game.GetCardFromId(play.CardId).PlayerClass;
                    if (hero == null)
                    {
                        continue;
                    }
                    if (!heroes.ContainsKey(hero))
                    {
                        heroes.Add(hero, 0);
                    }
                    heroes[hero]++;
                }
            }


            var heroPlayed = heroes.Any() ? heroes.OrderByDescending(x => x.Value).First().Key : "Any";

            var possibleTargets = Helper.MainWindow.DeckList.DecksList.Where(d => d.Class == heroPlayed || heroPlayed == "Any");

            var dialog = new MoveGameDialog(possibleTargets);

            if (Config.Instance.StatsInWindow)
            {
                dialog.Owner = Helper.MainWindow.StatsWindow;
            }
            else
            {
                dialog.Owner = Helper.MainWindow;
            }

            dialog.ShowDialog();
            var selectedDeck = dialog.SelectedDeck;

            if (selectedDeck == null)
            {
                return;
            }
            var defaultDeck = DefaultDeckStats.Instance.DeckStats.FirstOrDefault(ds => ds.Games.Contains(selectedGame));

            if (defaultDeck != null)
            {
                defaultDeck.Games.Remove(selectedGame);
                DefaultDeckStats.Save();
            }
            else
            {
                _deck.DeckStats.Games.Remove(selectedGame);
            }
            selectedGame.PlayerDeckVersion = selectedDeck.Version;             //move to latest version
            selectedDeck.DeckStats.Games.Add(selectedGame);
            DeckStatsList.Save();
            Helper.MainWindow.WriteDecks();
            Refresh();
            Helper.MainWindow.DeckPickerList.UpdateList();
        }
Example #23
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"));
            //current version
            var games = filteredGames.Where(g => g.BelongsToDeckVerion(deck)).ToList();

            DataGridWinLoss.Items.Add(new WinLoss(games, "%", deck.Version));
            DataGridWinLoss.Items.Add(new WinLoss(games, "Win - Loss", deck.Version));
            //prev versions
            foreach (var v in deck.Versions.OrderByDescending(d => d.Version))
            {
                games = filteredGames.Where(g => g.BelongsToDeckVerion(v)).ToList();
                DataGridWinLoss.Items.Add(new WinLoss(games, "%", v.Version));
                DataGridWinLoss.Items.Add(new WinLoss(games, "Win - Loss", v.Version));
            }

            var defaultStats = DefaultDeckStats.Instance.GetDeckStats(deck.Class) ?? new DeckStats();

            DataGridWinLossClass.Items.Clear();
            var allGames =
                DeckList.Instance.Decks.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();
        }
        private async void DeleteGames(DataGrid dataGrid, bool overall)
        {
            MetroWindow window;

            if (Config.Instance.StatsInWindow)
            {
                window = Helper.MainWindow.StatsWindow;
            }
            else
            {
                window = Helper.MainWindow;
            }

            var count = dataGrid.SelectedItems.Count;

            if (count == 1)
            {
                var selectedGame = dataGrid.SelectedItem as GameStats;
                if (selectedGame == null)
                {
                    return;
                }

                if (await window.ShowDeleteGameStatsMessage(selectedGame) != MessageDialogResult.Affirmative)
                {
                    return;
                }
                if (!overall)
                {
                    if (_deck.DeckStats.Games.Contains(selectedGame))
                    {
                        selectedGame.DeleteGameFile();
                        _deck.DeckStats.Games.Remove(selectedGame);
                        Logger.WriteLine("Deleted game: " + selectedGame);
                        DeckStatsList.Save();
                    }
                }
                else
                {
                    var deck = Helper.MainWindow.DeckList.DecksList.FirstOrDefault(d => d.DeckStats.Games.Contains(selectedGame));
                    if (deck != null)
                    {
                        if (deck.DeckStats.Games.Contains(selectedGame))
                        {
                            selectedGame.DeleteGameFile();
                            deck.DeckStats.Games.Remove(selectedGame);
                            Logger.WriteLine("Deleted game: " + selectedGame);
                            DefaultDeckStats.Save();
                        }
                    }
                    else
                    {
                        var deckstats = DefaultDeckStats.Instance.DeckStats.FirstOrDefault(ds => ds.Games.Contains(selectedGame));
                        if (deckstats != null)
                        {
                            selectedGame.DeleteGameFile();
                            deckstats.Games.Remove(selectedGame);
                            Logger.WriteLine("Deleted game: " + selectedGame);
                            DefaultDeckStats.Save();
                        }
                    }
                }
                Helper.MainWindow.DeckPickerList.Items.Refresh();
                Refresh();
            }
            else if (count > 1)
            {
                if (await window.ShowDeleteMultipleGameStatsMessage(count) != MessageDialogResult.Affirmative)
                {
                    return;
                }
                foreach (var selectedItem in dataGrid.SelectedItems)
                {
                    var selectedGame = selectedItem as GameStats;
                    if (selectedGame == null)
                    {
                        continue;
                    }

                    if (!overall)
                    {
                        if (_deck.DeckStats.Games.Contains(selectedGame))
                        {
                            selectedGame.DeleteGameFile();
                            _deck.DeckStats.Games.Remove(selectedGame);
                            Logger.WriteLine("Deleted game: " + selectedGame);
                        }
                    }
                    else
                    {
                        var deck = Helper.MainWindow.DeckList.DecksList.FirstOrDefault(d => d.DeckStats.Games.Contains(selectedGame));
                        if (deck != null)
                        {
                            if (deck.DeckStats.Games.Contains(selectedGame))
                            {
                                selectedGame.DeleteGameFile();
                                deck.DeckStats.Games.Remove(selectedGame);
                                Logger.WriteLine("Deleted game: " + selectedGame);
                            }
                        }
                        else
                        {
                            var deckstats = DefaultDeckStats.Instance.DeckStats.FirstOrDefault(ds => ds.Games.Contains(selectedGame));
                            if (deckstats != null)
                            {
                                selectedGame.DeleteGameFile();
                                deckstats.Games.Remove(selectedGame);
                                Logger.WriteLine("Deleted game: " + selectedGame);
                            }
                        }
                    }
                }
                DeckStatsList.Save();
                DefaultDeckStats.Save();
                Logger.WriteLine("Deleted " + count + " games");
                Helper.MainWindow.DeckPickerList.Items.Refresh();
                Refresh();
            }
        }
Example #25
0
        public void LoadOverallStats()
        {
            var needToSaveDeckStats = false;

            DataGridOverallWinLoss.Items.Clear();
            DataGridOverallGames.Items.Clear();
            var sortedCol = DataGridOverallGames.Columns.FirstOrDefault(col => col.SortDirection != null);
            var total     = new List <GameStats>();
            var modified  = false;
            var classes   = Enum.GetNames(typeof(HeroClass)).Concat(DefaultDeckStats.Instance.DeckStats.Select(x => x.Name)).Distinct();

            foreach (var @class in classes)
            {
                var allGames = new List <GameStats>();
                if (Config.Instance.StatsOverallFilterDeckMode == FilterDeckMode.WithDeck ||
                    Config.Instance.StatsOverallFilterDeckMode == FilterDeckMode.All)
                {
                    allGames.AddRange(DeckList.Instance.Decks.Where(x => x.Class == @class && MatchesTagFilters(x)).SelectMany(d => d.DeckStats.Games));
                }
                if (Config.Instance.StatsOverallFilterDeckMode == FilterDeckMode.WithoutDeck ||
                    Config.Instance.StatsOverallFilterDeckMode == FilterDeckMode.All)
                {
                    allGames.AddRange(DefaultDeckStats.Instance.GetDeckStats(@class).Games);
                }

                allGames = FilterGames(allGames).Where(g => !g.IsClone).ToList();

                total.AddRange(allGames);
                DataGridOverallWinLoss.Items.Add(new WinLoss(allGames, CheckboxPercent.IsChecked ?? true, @class));

                foreach (var game in allGames)
                {
                    if (string.IsNullOrEmpty(game.PlayerHero))
                    {
                        //for some reason this does not get loaded after saving it to the xml
                        game.PlayerHero     = @class;
                        needToSaveDeckStats = true;
                    }
                    if (!game.VerifiedHeroes && VerifyHeroes(game))
                    {
                        modified = true;
                    }
                    if ((Config.Instance.StatsOverallFilterPlayerHeroClass == HeroClassAll.All ||
                         game.PlayerHero == Config.Instance.StatsOverallFilterPlayerHeroClass.ToString()) &&
                        (Config.Instance.StatsFilterOpponentHeroClass == HeroClassAll.All ||
                         game.OpponentHero == Config.Instance.StatsFilterOpponentHeroClass.ToString()))
                    {
                        DataGridOverallGames.Items.Add(game);
                    }
                }
            }
            if (needToSaveDeckStats || modified)
            {
                DeckStatsList.Save();
            }
            DataGridOverallWinLoss.Items.Add(new WinLoss(total, CheckboxPercent.IsChecked ?? true, "Total"));
            if (sortedCol != null)
            {
                var prevSorted = DataGridOverallGames.Columns.FirstOrDefault(col => col.Header == sortedCol.Header);
                if (prevSorted != null)
                {
                    prevSorted.SortDirection = sortedCol.SortDirection;
                }
            }
            DataGridOverallGames.Items.Refresh();
        }
        private async void Window_Closing(object sender, CancelEventArgs e)
        {
            try
            {
                Log.Info("Shutting down...");
                Influx.OnAppExit(Helper.GetCurrentVersion());
                Core.UpdateOverlay = false;
                Core.Update        = false;

                //wait for update to finish, might otherwise crash when overlay gets disposed
                for (var i = 0; i < 100; i++)
                {
                    if (Core.CanShutdown)
                    {
                        break;
                    }
                    await Task.Delay(50);
                }

                Config.Instance.SelectedTags = Config.Instance.SelectedTags.Distinct().ToList();
                //Config.Instance.ShowAllDecks = DeckPickerList.ShowAll;
                Config.Instance.SelectedDeckPickerClasses = DeckPickerList.SelectedClasses.ToArray();

                Config.Instance.WindowWidth       = (int)(Width - (GridNewDeck.Visibility == Visible ? GridNewDeck.ActualWidth : 0));
                Config.Instance.WindowHeight      = (int)(Height - _heightChangeDueToSearchBox);
                Config.Instance.TrackerWindowTop  = (int)Top;
                Config.Instance.TrackerWindowLeft = (int)(Left + (MovedLeft ?? 0));

                //position of add. windows is NaN if they were never opened.
                if (!double.IsNaN(Core.Windows.PlayerWindow.Left))
                {
                    Config.Instance.PlayerWindowLeft = (int)Core.Windows.PlayerWindow.Left;
                }
                if (!double.IsNaN(Core.Windows.PlayerWindow.Top))
                {
                    Config.Instance.PlayerWindowTop = (int)Core.Windows.PlayerWindow.Top;
                }
                Config.Instance.PlayerWindowHeight = (int)Core.Windows.PlayerWindow.Height;

                if (!double.IsNaN(Core.Windows.OpponentWindow.Left))
                {
                    Config.Instance.OpponentWindowLeft = (int)Core.Windows.OpponentWindow.Left;
                }
                if (!double.IsNaN(Core.Windows.OpponentWindow.Top))
                {
                    Config.Instance.OpponentWindowTop = (int)Core.Windows.OpponentWindow.Top;
                }
                Config.Instance.OpponentWindowHeight = (int)Core.Windows.OpponentWindow.Height;

                if (!double.IsNaN(Core.Windows.TimerWindow.Left))
                {
                    Config.Instance.TimerWindowLeft = (int)Core.Windows.TimerWindow.Left;
                }
                if (!double.IsNaN(Core.Windows.TimerWindow.Top))
                {
                    Config.Instance.TimerWindowTop = (int)Core.Windows.TimerWindow.Top;
                }
                Config.Instance.TimerWindowHeight = (int)Core.Windows.TimerWindow.Height;
                Config.Instance.TimerWindowWidth  = (int)Core.Windows.TimerWindow.Width;

                Core.TrayIcon.NotifyIcon.Visible = false;
                Core.Overlay.Close();
                await Core.StopLogWacher();

                Core.Windows.TimerWindow.Shutdown();
                Core.Windows.PlayerWindow.Shutdown();
                Core.Windows.OpponentWindow.Shutdown();
                Config.Save();
                DeckList.Save();
                DeckStatsList.Save();
                PluginManager.SavePluginsSettings();
                PluginManager.Instance.UnloadPlugins();
            }
            catch (Exception)
            {
                //doesnt matter
            }
            finally
            {
                Application.Current.Shutdown();
            }
        }
Example #27
0
        private async void SaveDeck(bool overwrite, SerializableVersion newVersion)
        {
            var deckName = TextBoxDeckName.Text;

            if (string.IsNullOrEmpty(deckName))
            {
                var settings = new MetroDialogSettings {
                    AffirmativeButtonText = "Set", DefaultText = deckName
                };

                var name = await this.ShowInputAsync("No name set", "Please set a name for the deck", settings);

                if (String.IsNullOrEmpty(name))
                {
                    return;
                }

                deckName             = name;
                TextBoxDeckName.Text = name;
            }

            /*while(DeckList.DecksList.Any(d => d.Name == deckName) && (!EditingDeck || !overwrite))
             * {
             *      var settings = new MetroDialogSettings {AffirmativeButtonText = "Set", DefaultText = deckName};
             *      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;
             *
             *      deckName = name;
             *      TextBoxDeckName.Text = name;
             * }*/

            if (_newDeck.Cards.Sum(c => c.Count) != 30)
            {
                var settings = new MetroDialogSettings {
                    AffirmativeButtonText = "Yes", NegativeButtonText = "No"
                };

                var result =
                    await
                    this.ShowMessageAsync("Not 30 cards",
                                          string.Format("Deck contains {0} cards. Is this what you want to save anyway?",
                                                        _newDeck.Cards.Sum(c => c.Count)), MessageDialogStyle.AffirmativeAndNegative, settings);

                if (result != MessageDialogResult.Affirmative)
                {
                    return;
                }
            }

            var previousVersion = _newDeck.Version;

            if (overwrite && (_newDeck.Version != newVersion))
            {
                AddDeckHistory();
                _newDeck.Version                  = newVersion;
                _newDeck.SelectedVersion          = newVersion;
                _newDeck.HearthStatsDeckVersionId = "";
                //UpdateDeckHistoryPanel(_newDeck, false);
            }

            if (EditingDeck && overwrite)
            {
                DeckList.Instance.Decks.Remove(_newDeck);
                //DeckPickerList.RemoveDeck(_newDeck);
            }

            var oldDeckName = _newDeck.Name;

            _newDeck.Name = deckName;

            var newDeckClone = (Deck)_newDeck.Clone();

            newDeckClone.Archived = false;

            DeckList.Instance.Decks.Add(newDeckClone);

            newDeckClone.LastEdited = DateTime.Now;

            DeckList.Save();

            Logger.WriteLine("Saved Decks", "SaveDeck");

            if (EditingDeck)
            {
                TagControlEdit.SetSelectedTags(new List <string>());
                if (deckName != oldDeckName)
                {
                    var statsEntry = DeckStatsList.Instance.DeckStats.FirstOrDefault(ds => ds.BelongsToDeck(_newDeck));
                    if (statsEntry != null)
                    {
                        if (overwrite)
                        {
                            statsEntry.Name = deckName;
                            Logger.WriteLine("Deck has new name, updated deckstats", "SaveDeck");
                        }
                        else
                        {
                            var newStatsEntry = DeckStatsList.Instance.DeckStats.FirstOrDefault(ds => ds.BelongsToDeck(_newDeck));
                            if (newStatsEntry == null)
                            {
                                newStatsEntry = new DeckStats(_newDeck);
                                DeckStatsList.Instance.DeckStats.Add(newStatsEntry);
                            }
                            foreach (var game in statsEntry.Games)
                            {
                                newStatsEntry.AddGameResult(game.CloneWithNewId());
                            }
                            Logger.WriteLine("cloned gamestats for \"Set as new\"", "SaveDeck");
                        }
                        DeckStatsList.Save();
                    }
                }
            }


            if (Config.Instance.HearthStatsAutoUploadNewDecks && HearthStatsAPI.IsLoggedIn)
            {
                Logger.WriteLine("auto uploading new/edited deck", "SaveDeck");
                if (EditingDeck)
                {
                    if (previousVersion != newVersion)
                    {
                        HearthStatsManager.UploadVersionAsync(newDeckClone, _originalDeck.HearthStatsIdForUploading, background: true);
                    }
                    else
                    {
                        HearthStatsManager.UpdateDeckAsync(newDeckClone, background: true);
                    }
                }
                else
                {
                    HearthStatsManager.UploadDeckAsync(newDeckClone, background: true);
                }
            }

            //after cloning the stats, otherwise new stats will be generated
            //DeckPickerList.AddAndSelectDeck(newDeckClone);

            EditingDeck = false;

            foreach (var tag in _newDeck.Tags)
            {
                SortFilterDecksFlyout.AddSelectedTag(tag);
            }

            DeckPickerList.SelectDeckAndAppropriateView(newDeckClone);
            CloseNewDeck();
            ClearNewDeckSection();
        }
        public static async void SyncAsync(bool forceFullSync = false, bool background = false)
        {
            Logger.WriteLine(string.Format("starting sync process: forceFullSync={0}, background={1}", forceFullSync, background),
                             "HearthStatsManager");
            if (!HearthStatsAPI.IsLoggedIn)
            {
                Logger.WriteLine("error: not logged in", "HearthStatsManager");
                return;
            }
            try
            {
                if (SyncInProgress)
                {
                    Logger.WriteLine("error: sync already in progress", "HearthStatsManager");
                    return;
                }
                SyncInProgress = true;
                if (background)
                {
                    AddBackgroundActivity();
                }

                var controller = background
                                                         ? null : await Core.MainWindow.ShowProgressAsync("Syncing...", "Checking HearthStats for new decks...");

                Logger.WriteLine("Checking HearthStats for new decks...", "HearthStatsManager");
                var localDecks  = DeckList.Instance.Decks;
                var remoteDecks = await DownloadDecksAsync(forceFullSync);

                if (remoteDecks.Any())
                {
                    var newDecks = remoteDecks.Where(deck => localDecks.All(localDeck => localDeck.HearthStatsId != deck.HearthStatsId)).ToList();
                    if (newDecks.Any())
                    {
                        Core.MainWindow.FlyoutHearthStatsDownload.IsOpen = true;
                        if (!background)
                        {
                            await controller.CloseAsync();
                        }
                        newDecks = await Core.MainWindow.HearthStatsDownloadDecksControl.LoadDecks(newDecks);

                        foreach (var deck in newDecks)
                        {
                            DeckList.Instance.Decks.Add(deck);
                            Logger.WriteLine("saved new deck " + deck, "HearthStatsManager");
                        }
                        DeckList.Save();
                        Core.MainWindow.DeckPickerList.UpdateDecks();
                        Core.MainWindow.DeckPickerList.UpdateArchivedClassVisibility();
                        background = false;
                    }
                    if (!background)
                    {
                        if (controller == null || !controller.IsOpen)
                        {
                            controller = await Core.MainWindow.ShowProgressAsync("Syncing...", "Checking for new versions...");
                        }
                        else
                        {
                            controller.SetMessage("Checking for new versions...");
                        }
                    }
                    Logger.WriteLine("Checking for new versions...", "HearthStatsManager");
                    var decksWithNewVersions =
                        remoteDecks.Where(
                            deck =>
                            localDecks.Any(
                                localDeck =>
                                localDeck.HasHearthStatsId && deck.HearthStatsId == localDeck.HearthStatsId &&
                                localDeck.GetMaxVerion() != deck.GetMaxVerion())).ToList();
                    if (decksWithNewVersions.Any())
                    {
                        foreach (var deck in decksWithNewVersions)
                        {
                            var currentDeck = localDecks.FirstOrDefault(d => d.HasHearthStatsId && d.HearthStatsId == deck.HearthStatsId);
                            if (currentDeck == null)
                            {
                                continue;
                            }
                            var originalDeck = (Deck)currentDeck.Clone();
                            var versions     =
                                deck.VersionsIncludingSelf.Where(v => !currentDeck.VersionsIncludingSelf.Contains(v))
                                .OrderBy(v => v)
                                .Select(v => deck.GetVersion(v))
                                .Where(v => v != null)
                                .ToList();
                            if (versions.Any())
                            {
                                foreach (var newVersion in versions)
                                {
                                    var clone = (Deck)currentDeck.Clone();
                                    currentDeck.Version                  = newVersion.Version;
                                    currentDeck.SelectedVersion          = newVersion.Version;
                                    currentDeck.HearthStatsDeckVersionId = newVersion.HearthStatsDeckVersionId;
                                    currentDeck.Versions.Add(clone);
                                }
                                Logger.WriteLine(
                                    string.Format("saved {0} new versions ({1}) to {2}", versions.Count,
                                                  versions.Select(v => v.Version.ToString()).Aggregate((c, n) => c + ", " + n), deck),
                                    "HearthStatsManager");
                            }
                        }
                        DeckList.Save();
                        Core.MainWindow.DeckPickerList.UpdateDecks();
                        Core.MainWindow.DeckPickerList.UpdateArchivedClassVisibility();
                    }
                    if (!background)
                    {
                        if (controller == null || !controller.IsOpen)
                        {
                            controller = await Core.MainWindow.ShowProgressAsync("Syncing...", "Checking for edited decks...");
                        }
                        else
                        {
                            controller.SetMessage("Checking for edited decks...");
                        }
                    }
                    Logger.WriteLine("Checking for edited decks...", "HearthStatsManager");
                    var editedDecks =
                        remoteDecks.Where(
                            r =>
                            localDecks.Any(
                                l =>
                                l.HasHearthStatsId && l.HearthStatsId == r.HearthStatsId && r.LastEdited > l.LastEdited &&
                                (l.Name != r.Name || !(new HashSet <string>(l.Tags).SetEquals(r.Tags)) || l.Note != r.Note ||
                                 (l - r).Count > 0))).ToList();
                    if (editedDecks.Any())
                    {
                        foreach (var deck in editedDecks)
                        {
                            var localDeck = localDecks.FirstOrDefault(d => d.HasHearthStatsId && d.HearthStatsId == deck.HearthStatsId);
                            if (localDeck != null)
                            {
                                //localDeck = (Deck)localDeck.Clone();
                                localDeck.Name = deck.Name;
                                localDeck.Tags = deck.Tags;
                                localDeck.Note = deck.Note;
                                localDeck.Cards.Clear();
                                foreach (var card in deck.Cards)
                                {
                                    localDeck.Cards.Add((Card)card.Clone());
                                }
                                Logger.WriteLine("edited latest version of " + localDeck, "HearthStatsManager");
                            }
                        }
                        Core.MainWindow.DeckPickerList.UpdateDecks();
                        Core.MainWindow.DeckPickerList.UpdateArchivedClassVisibility();
                        DeckList.Save();
                        Logger.WriteLine("edited " + editedDecks.Count + " decks", "HearthStatsManager");
                    }
                }

                if (!background)
                {
                    if (controller == null || !controller.IsOpen)
                    {
                        controller = await Core.MainWindow.ShowProgressAsync("Syncing...", "Checking HearthStats for new matches...");
                    }
                    else
                    {
                        controller.SetMessage("Checking HearthStats for new matches...");
                    }
                }
                Logger.WriteLine("Checking HearthStats for new matches...", "HearthStatsManager");
                var newGames = await DownloadGamesAsync(forceFullSync);

                if (newGames.Any())
                {
                    foreach (var game in newGames)
                    {
                        var deck =
                            DeckList.Instance.Decks.FirstOrDefault(
                                d =>
                                d.VersionsIncludingSelf.Select(v => d.GetVersion(v.Major, v.Minor))
                                .Where(v => v != null && v.HasHearthStatsDeckVersionId)
                                .Any(v => game.HearthStatsDeckVersionId == v.HearthStatsDeckVersionId));
                        if (deck == null)
                        {
                            //deck_version_id seems to be null for older matches
                            deck = DeckList.Instance.Decks.FirstOrDefault(d => d.HasHearthStatsId && game.HearthStatsDeckId == d.HearthStatsId);
                            if (deck != null)
                            {
                                game.HearthStatsDeckVersionId = deck.HearthStatsDeckVersionId;
                            }
                        }
                        if (deck == null)
                        {
                            Logger.WriteLine(string.Format("no deck found for match {0}", game), "HearthStatsManager");
                            continue;
                        }
                        if (deck.DeckStats.Games.Any(g => g.HearthStatsId == game.HearthStatsId))
                        {
                            Logger.WriteLine(string.Format("deck {0} already has match {1}", deck, game), "HearthStatsManager");
                            continue;
                        }
                        var deckVersion =
                            deck.VersionsIncludingSelf.Select(deck.GetVersion)
                            .FirstOrDefault(v => v.HearthStatsDeckVersionId == game.HearthStatsDeckVersionId);
                        if (deckVersion == null)
                        {
                            continue;
                        }
                        Logger.WriteLine(string.Format("added match {0} to version {1} of deck {2}", game, deck.Version.ShortVersionString, deck),
                                         "HearthStatsManager");
                        game.PlayerDeckVersion = deckVersion.Version;
                        deck.DeckStats.AddGameResult(game);
                    }
                    DeckStatsList.Save();
                    Core.MainWindow.DeckPickerList.UpdateDecks();
                    Core.MainWindow.DeckPickerList.UpdateArchivedClassVisibility();
                    Core.MainWindow.DeckStatsFlyout.LoadOverallStats();
                }

                if (!background)
                {
                    controller.SetMessage("Checking for new local decks...");
                }
                Logger.WriteLine("Checking for new local decks...", "HearthStatsManager");
                var newLocalDecks = localDecks.Where(deck => !deck.HasHearthStatsId && deck.IsArenaDeck != true).ToList();
                if (newLocalDecks.Any(d => d.SyncWithHearthStats != false))
                {
                    var uploaded = 0;
                    var total    = newLocalDecks.Count;
                    Logger.WriteLine("found " + newLocalDecks.Count + " new decks", "HearthStatsManager");
                    if (!background)
                    {
                        await controller.CloseAsync();
                    }
                    Core.MainWindow.FlyoutHearthStatsUpload.IsOpen = true;
                    newLocalDecks = await Core.MainWindow.HearthStatsUploadDecksControl.LoadDecks(newLocalDecks);

                    if (newLocalDecks.Any())
                    {
                        controller = await Core.MainWindow.ShowProgressAsync("Syncing...", "Uploading " + newLocalDecks.Count + " new decks...");

                        Logger.WriteLine("Uploading " + newLocalDecks.Count + " new decks...", "HearthStatsManager");
                        await Task.Run(() =>
                        {
                            Parallel.ForEach(newLocalDecks, deck =>
                            {
                                UploadDeck(deck, false);

                                if (controller != null)
                                {
                                    Core.MainWindow.Dispatcher.BeginInvoke(new Action(() => { controller.SetProgress(1.0 * (++uploaded) / total); }));
                                }
                            });
                        });

                        DeckList.Save();                         //save new ids
                        background = false;
                    }
                }

                if (!background)
                {
                    if (controller == null || !controller.IsOpen)
                    {
                        controller = await Core.MainWindow.ShowProgressAsync("Syncing...", "Checking for new local versions...");
                    }
                    else
                    {
                        controller.SetMessage("Checking for new local versions...");
                    }
                }

                Logger.WriteLine("Checking for new local versions...", "HearthStatsManager");
                var localNewVersions =
                    localDecks.Where(x => x.HasHearthStatsId)
                    .SelectMany(
                        x =>
                        x.VersionsIncludingSelf.Select(x.GetVersion)
                        .Where(v => !v.HasHearthStatsDeckVersionId)
                        .Select(v => new { version = v, hearthStatsId = x.HearthStatsIdForUploading }))
                    .ToList();
                if (localNewVersions.Any())
                {
                    var uploaded = 0;
                    var total    = localNewVersions.Count;
                    if (!background)
                    {
                        controller.SetMessage("Uploading " + localNewVersions.Count + " new versions...");
                    }
                    Logger.WriteLine("Uploading " + localNewVersions.Count + " new versions...", "HearthStatsManager");
                    //this can't happen in parallel (?)
                    foreach (var v in localNewVersions)
                    {
                        var result = await UploadVersionAsync(v.version, v.hearthStatsId, false);

                        if (!result.Success && result.Retry)
                        {
                            await Task.Delay(RetryDelay);
                            await UploadVersionAsync(v.version, v.hearthStatsId, false);

                            if (controller != null)
                            {
                                Core.MainWindow.Dispatcher.BeginInvoke(new Action(() => { controller.SetProgress(1.0 * (++uploaded) / total); }));
                            }
                        }
                    }
                    DeckList.Save();
                }
                if (!background)
                {
                    controller.SetMessage("Checking for edited local decks...");
                }
                Logger.WriteLine("Checking for edited local decks...", "HearthStatsManager");

                var editedLocalDecks =
                    localDecks.Where(
                        l =>
                        remoteDecks.Any(
                            r =>
                            r.HasHearthStatsId && r.HearthStatsId == l.HearthStatsId && l.LastEdited > r.LastEdited &&
                            (r.Name != l.Name || !(new HashSet <string>(r.Tags).SetEquals(l.Tags)) || r.Note != l.Note ||
                             (r - l).Count > 0))).ToList();
                if (editedLocalDecks.Any())
                {
                    if (!background)
                    {
                        controller.SetMessage("Updating " + editedLocalDecks.Count + " decks...");
                    }
                    Logger.WriteLine("Updating " + editedLocalDecks.Count + " decks...", "HearthStatsManager");
                    foreach (var deck in editedLocalDecks)
                    {
                        await UpdateDeckAsync(deck);
                    }
                    Logger.WriteLine("updated " + editedLocalDecks.Count + " decks", "HearthStatsManager");
                }

                if (!background)
                {
                    controller.SetMessage("Checking for new local matches...");
                }
                Logger.WriteLine("Checking for new local matches...", "HearthStatsManager");

                var newMatches =
                    DeckList.Instance.Decks.Where(d => d.SyncWithHearthStats == true && d.HasHearthStatsId)
                    .SelectMany(d => d.DeckStats.Games.Where(g => !g.HasHearthStatsId).Select(g => new { deck = d, game = g }))
                    .ToList();
                if (newMatches.Any())
                {
                    var uploaded = 0;
                    var total    = newMatches.Count;
                    if (!background)
                    {
                        controller.SetMessage("Uploading " + newMatches.Count + " new matches...");
                    }
                    Logger.WriteLine("Uploading " + newMatches.Count + " new matches...", "HearthStatsManager");
                    await Task.Run(() =>
                    {
                        var groupedMatchObs =
                            newMatches.Select(
                                match =>
                                new
                        {
                            match.game,
                            deckVersion =
                                (match.game.HasHearthStatsDeckVersionId
                                                                                           ? (match.deck.VersionsIncludingSelf.Where(v => v != null)
                                                                                              .Select(match.deck.GetVersion)
                                                                                              .FirstOrDefault(
                                                                                                  d =>
                                                                                                  d.HasHearthStatsDeckVersionId &&
                                                                                                  d.HearthStatsDeckVersionId == match.game.HearthStatsDeckVersionId)
                                                                                              ?? match.deck.GetVersion(match.game.PlayerDeckVersion))
                                                                                           : (match.game.PlayerDeckVersion != null ? match.deck.GetVersion(match.game.PlayerDeckVersion) : match.deck))
                        }).Where(x => x.deckVersion != null).GroupBy(x => x.deckVersion.HearthStatsDeckVersionId);

                        Parallel.ForEach(groupedMatchObs, matches =>
                        {
                            UploadMultipleMatches(matches.Select(m => m.game), matches.First().deckVersion, false);
                            if (controller != null)
                            {
                                Core.MainWindow.Dispatcher.BeginInvoke(
                                    new Action(
                                        () => { controller.SetProgress(1.0 * (uploaded += matches.Count()) / total); }));
                            }
                        });
                    });

                    DeckStatsList.Save();
                }
                Config.Instance.LastHearthStatsDecksSync = DateTime.Now.ToUnixTime() - 600;                 //10 minute overlap
                Config.Instance.LastHearthStatsGamesSync = DateTime.Now.ToUnixTime() - 600;
                Config.Save();
                if (!background)
                {
                    await controller.CloseAsync();
                }

                RemoveBackgroundActivity();
                SyncInProgress = false;
                Logger.WriteLine("finished sync process", "HearthStatsManager");
            }
            catch (Exception e)
            {
                Logger.WriteLine("There was an error syncing with HearthStats:\n" + e, "HearthStatsManager");
                SyncInProgress = false;
            }
        }
        private async void BtnSaveDeck_Click(object sender, RoutedEventArgs e)
        {
            //NewDeck.Cards =
            //	new ObservableCollection<Card>(
            //		NewDeck.Cards.OrderBy(c => c.Cost).ThenByDescending(c => c.Type).ThenBy(c => c.Name).ToList());
            //ListViewNewDeck.ItemsSource = NewDeck.Cards;
            var deckName = TextBoxDeckName.Text;

            if (EditingDeck)
            {
                var settings = new MetroDialogSettings {
                    AffirmativeButtonText = "Overwrite", NegativeButtonText = "Save as new"
                };
                var result =
                    await
                    this.ShowMessageAsync("Saving deck", "How do you wish to save the deck?", MessageDialogStyle.AffirmativeAndNegative,
                                          settings);

                if (result == MessageDialogResult.Affirmative)
                {
                    SaveDeck(true);
                }
                else if (result == MessageDialogResult.Negative)
                {
                    SaveDeck(false);
                }
            }
            else if (DeckList.DecksList.Any(d => d.Name == deckName))
            {
                var settings = new MetroDialogSettings {
                    AffirmativeButtonText = "Overwrite", NegativeButtonText = "Set new name"
                };
                var result =
                    await
                    this.ShowMessageAsync("A deck with that name already exists", "Overwriting the deck can not be undone!",
                                          MessageDialogStyle.AffirmativeAndNegative, settings);

                if (result == MessageDialogResult.Affirmative)
                {
                    Deck oldDeck;
                    while ((oldDeck = DeckList.DecksList.FirstOrDefault(d => d.Name == deckName)) != null)
                    {
                        var deckStats = DeckStatsList.Instance.DeckStats.FirstOrDefault(ds => ds.Name == oldDeck.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: " + oldDeck.Name);
                        }
                        DeckList.DecksList.Remove(oldDeck);
                        DeckPickerList.RemoveDeck(oldDeck);
                    }

                    SaveDeck(true);
                }
                else if (result == MessageDialogResult.Negative)
                {
                    SaveDeck(false);
                }
            }
            else
            {
                SaveDeck(false);
            }

            editedDeckName = string.Empty;
        }
Example #30
0
        public static async void SyncAsync(bool forceFullSync = false, bool background = false)
        {
            Logger.WriteLine(string.Format("starting sync process: forceFullSync={0}, background={1}", forceFullSync, background),
                             "HearthStatsManager");
            if (!HearthStatsAPI.IsLoggedIn)
            {
                Logger.WriteLine("error: not logged in", "HearthStatsManager");
                return;
            }
            try
            {
                if (_syncInProgress)
                {
                    Logger.WriteLine("error: sync already in progress", "HearthStatsManager");
                    return;
                }
                _syncInProgress = true;
                if (background)
                {
                    AddBackgroundActivity();
                }

                var controller = background
                                                         ? null : await Helper.MainWindow.ShowProgressAsync("Syncing...", "Checking HearthStats for new decks...");

                Logger.WriteLine("Checking HearthStats for new decks...", "HearthStatsManager");
                var localDecks  = DeckList.Instance.Decks;
                var remoteDecks = await DownloadDecksAsync(forceFullSync);

                if (remoteDecks.Any())
                {
                    var newDecks = remoteDecks.Where(deck => localDecks.All(localDeck => localDeck.HearthStatsId != deck.HearthStatsId)).ToList();
                    if (newDecks.Any())
                    {
                        Helper.MainWindow.FlyoutHearthStatsDownload.IsOpen = true;
                        if (!background)
                        {
                            await controller.CloseAsync();
                        }
                        newDecks = await Helper.MainWindow.HearthStatsDownloadDecksControl.LoadDecks(newDecks);

                        foreach (var deck in newDecks)
                        {
                            DeckList.Instance.Decks.Add(deck);
                            //Helper.MainWindow.DeckPickerList.AddDeck(deck);
                            Logger.WriteLine("saved new deck " + deck, "HearthStatsManager");
                        }
                        DeckList.Save();
                        Helper.MainWindow.DeckPickerList.UpdateDecks();
                        background = false;
                    }
                    if (!background)
                    {
                        if (controller == null || !controller.IsOpen)
                        {
                            controller = await Helper.MainWindow.ShowProgressAsync("Syncing...", "Checking for new versions...");
                        }
                        else
                        {
                            controller.SetMessage("Checking for new versions...");
                        }
                    }
                    Logger.WriteLine("Checking for new versions...", "HearthStatsManager");
                    var decksWithNewVersions =
                        remoteDecks.Where(
                            deck =>
                            localDecks.Any(
                                localDeck =>
                                localDeck.HasHearthStatsId && deck.HearthStatsId == localDeck.HearthStatsId &&
                                localDeck.GetMaxVerion() != deck.GetMaxVerion())).ToList();
                    if (decksWithNewVersions.Any())                    // TODO: TEST
                    {
                        foreach (var deck in decksWithNewVersions)
                        {
                            var currentDeck = localDecks.FirstOrDefault(d => d.HasHearthStatsId && d.HearthStatsId == deck.HearthStatsId);
                            if (currentDeck == null)
                            {
                                continue;
                            }
                            var originalDeck = (Deck)currentDeck.Clone();
                            var versions     =
                                deck.VersionsIncludingSelf.Where(v => !currentDeck.VersionsIncludingSelf.Contains(v))
                                .OrderBy(v => v)
                                .Select(v => deck.GetVersion(v))
                                .Where(v => v != null)
                                .ToList();
                            if (versions.Any())
                            {
                                foreach (var newVersion in versions)
                                {
                                    var clone = (Deck)currentDeck.Clone();
                                    currentDeck.Version                  = newVersion.Version;
                                    currentDeck.SelectedVersion          = newVersion.Version;
                                    currentDeck.HearthStatsDeckVersionId = newVersion.HearthStatsDeckVersionId;
                                    currentDeck.Versions.Add(clone);
                                }
                                //Helper.MainWindow.DeckPickerList.RemoveDeck(originalDeck);
                                //Helper.MainWindow.DeckPickerList.AddDeck(currentDeck);
                                Logger.WriteLine(
                                    string.Format("saved {0} new versions ({1}) to {2}", versions.Count,
                                                  versions.Select(v => v.Version.ToString()).Aggregate((c, n) => c + ", " + n), deck),
                                    "HearthStatsManager");
                            }
                        }
                        DeckList.Save();
                        Helper.MainWindow.DeckPickerList.UpdateDecks();
                    }
                    if (!background)
                    {
                        if (controller == null || !controller.IsOpen)
                        {
                            controller = await Helper.MainWindow.ShowProgressAsync("Syncing...", "Checking for edited decks...");
                        }
                        else
                        {
                            controller.SetMessage("Checking for edited decks...");
                        }
                    }
                    Logger.WriteLine("Checking for edited decks...", "HearthStatsManager");
                    var editedDecks =
                        remoteDecks.Where(
                            r =>
                            !localDecks.Any(
                                l =>
                                l.HasHearthStatsId && l.HearthStatsId == r.HearthStatsId &&
                                (l.Name != r.Name || l.Tags != r.Tags || l.Note != r.Note ||
                                 l.Cards.Any(lc => r.Cards.All(rc => !rc.EqualsWithCount(lc)))))).ToList();
                    if (editedDecks.Any())
                    {
                        foreach (var deck in editedDecks)
                        {
                            var localDeck = localDecks.FirstOrDefault(d => d.HasHearthStatsId && d.HearthStatsId == deck.HearthStatsId);
                            if (localDeck != null)
                            {
                                localDeck      = (Deck)localDeck.Clone();
                                localDeck.Name = deck.Name;
                                localDeck.Tags = deck.Tags;
                                localDeck.Note = deck.Note;
                                localDeck.Cards.Clear();
                                foreach (var card in deck.Cards)
                                {
                                    localDeck.Cards.Add((Card)card.Clone());
                                }
                                Logger.WriteLine("edited latest version of " + localDeck, "HearthStatsManager");
                            }
                        }
                        Helper.MainWindow.DeckPickerList.UpdateDecks();
                        DeckList.Save();
                        Logger.WriteLine("edited " + editedDecks.Count + " decks", "HearthStatsManager");
                    }
                }

                if (!background)
                {
                    if (controller == null || !controller.IsOpen)
                    {
                        controller = await Helper.MainWindow.ShowProgressAsync("Syncing...", "Checking HearthStats for new matches...");
                    }
                    else
                    {
                        controller.SetMessage("Checking HearthStats for new matches...");
                    }
                }
                Logger.WriteLine("Checking HearthStats for new matches...", "HearthStatsManager");
                var newGames = await DownloadGamesAsync(forceFullSync);

                if (newGames.Any())
                {
                    foreach (var game in newGames)
                    {
                        var deck =
                            DeckList.Instance.Decks.FirstOrDefault(
                                d =>
                                d.VersionsIncludingSelf.Select(v => d.GetVersion(v.Major, v.Minor))
                                .Where(v => v != null)
                                .Any(v => game.BelongsToDeckVerion(v)));
                        if (deck == null)
                        {
                            Logger.WriteLine(string.Format("no deck found for match {0}", game), "HearthStatsManager");
                            continue;
                        }
                        if (deck.DeckStats.Games.Any(g => g.HearthStatsId == game.HearthStatsId))
                        {
                            Logger.WriteLine(string.Format("deck {0} already has match {1}", deck, game), "HearthStatsManager");
                            continue;
                        }
                        Logger.WriteLine(string.Format("added match {0} to version {1} of deck {2}", game, deck.Version.ShortVersionString, deck),
                                         "HearthStatsManager");
                        deck.DeckStats.AddGameResult(game);
                    }
                    DeckStatsList.Save();
                    Helper.MainWindow.DeckPickerList.UpdateDecks();
                    Helper.MainWindow.DeckStatsFlyout.LoadOverallStats();
                }

                if (!background)
                {
                    controller.SetMessage("Checking for new local decks...");
                }
                Logger.WriteLine("Checking for new local decks...", "HearthStatsManager");
                var newLocalDecks = localDecks.Where(deck => !deck.HasHearthStatsId && deck.IsArenaDeck != true).ToList();
                if (newLocalDecks.Any(d => d.SyncWithHearthStats != false))
                {
                    Logger.WriteLine("found " + newLocalDecks.Count + " new decks", "HearthStatsManager");
                    if (!background)
                    {
                        await controller.CloseAsync();
                    }
                    Helper.MainWindow.FlyoutHearthStatsUpload.IsOpen = true;
                    newLocalDecks = await Helper.MainWindow.HearthStatsUploadDecksControl.LoadDecks(newLocalDecks);

                    if (newLocalDecks.Any())
                    {
                        controller = await Helper.MainWindow.ShowProgressAsync("Syncing...", "Uploading " + newLocalDecks.Count + " new decks...");

                        Logger.WriteLine("Uploading " + newLocalDecks.Count + " new decks...", "HearthStatsManager");
                        await Task.Run(() => { Parallel.ForEach(newLocalDecks, deck => UploadDeck(deck, false)); });

                        DeckList.Save();                         //save new ids
                        background = false;
                    }
                }

                if (!background)
                {
                    if (controller == null || !controller.IsOpen)
                    {
                        controller = await Helper.MainWindow.ShowProgressAsync("Syncing...", "Checking for new local versions...");
                    }
                    else
                    {
                        controller.SetMessage("Checking for new local versions...");
                    }
                }

                Logger.WriteLine("Checking for new local versions...", "HearthStatsManager");
                var localNewVersions =
                    localDecks.Where(x => x.HasHearthStatsId)
                    .SelectMany(
                        x =>
                        x.Versions.Where(v => !v.HasHearthStatsDeckVersionId)
                        .Select(v => new { version = v, hearthStatsId = x.HearthStatsId }))
                    .ToList();
                if (localNewVersions.Any())
                {
                    if (!background)
                    {
                        controller.SetMessage("Uploading " + localNewVersions.Count + " new versions...");
                    }
                    Logger.WriteLine("Uploading " + localNewVersions.Count + " new versions...", "HearthStatsManager");
                    //this can't happen in parallel (?)
                    foreach (var v in localNewVersions)
                    {
                        var result = await UploadVersionAsync(v.version, v.hearthStatsId, false);

                        if (!result.Success && result.Retry)
                        {
                            await Task.Delay(RetryDelay);
                            await UploadVersionAsync(v.version, v.hearthStatsId, false);
                        }
                    }
                    DeckList.Save();
                }
                if (!background)
                {
                    controller.SetMessage("Checking for new local matches...");
                }
                Logger.WriteLine("Checking for new local matches...", "HearthStatsManager");

                var newMatches =
                    DeckList.Instance.Decks.Where(d => d.SyncWithHearthStats == true && d.HasHearthStatsId)
                    .SelectMany(d => d.DeckStats.Games.Where(g => !g.HasHearthStatsId).Select(g => new { deck = d, game = g }))
                    .ToList();
                if (newMatches.Any())
                {
                    if (!background)
                    {
                        controller.SetMessage("Uploading " + newMatches.Count + " new matches...");
                    }
                    Logger.WriteLine("Uploading " + newMatches.Count + " new matches...", "HearthStatsManager");
                    await Task.Run(() => { Parallel.ForEach(newMatches, match => UploadMatch(match.game, match.deck, false)); });

                    DeckStatsList.Save();
                }
                Config.Instance.LastHearthStatsDecksSync = DateTime.Now.ToUnixTime() - 600;                 //10 minute overlap
                Config.Instance.LastHearthStatsGamesSync = DateTime.Now.ToUnixTime() - 600;
                Config.Save();
                if (!background)
                {
                    await controller.CloseAsync();
                }

                RemoveBackgroundActivity();
                _syncInProgress = false;
                Logger.WriteLine("finished sync process", "HearthStatsManager");
            }
            catch (Exception e)
            {
                Logger.WriteLine("There was an error syncing with HearthStats:\n" + e, "HearthStatsManager");
                _syncInProgress = false;
            }
        }