private static DeckList Load() { #if(!SQUIRREL) SetupDeckListFile(); #endif var file = Config.Instance.DataDir + "PlayerDecks.xml"; DeckList instance; if(!File.Exists(file)) instance = new DeckList(); else { try { instance = XmlManager<DeckList>.Load(file); } catch(Exception ex) { Log.Error(ex); try { File.Move(file, Helper.GetValidFilePath(Config.Instance.DataDir, "PlayerDecks_corrupted", "xml")); } catch(Exception ex1) { Log.Error(ex1); } instance = BackupManager.TryRestore<DeckList>("PlayerDecks.xml") ?? new DeckList(); } } var save = false; if(!instance.AllTags.Contains("All")) { instance.AllTags.Add("All"); save = true; } if(!instance.AllTags.Contains("Favorite")) { if(instance.AllTags.Count > 1) instance.AllTags.Insert(1, "Favorite"); else instance.AllTags.Add("Favorite"); save = true; } if(!instance.AllTags.Contains("None")) { instance.AllTags.Add("None"); save = true; } if(save) Save(instance); instance.LoadActiveDeck(); return instance; }
//public Guid ActiveDeckId { get; set; } public static void Load() { var file = Config.Instance.DataDir + "PlayerDecks.xml"; if(!File.Exists(file)) return; try { _instance = XmlManager<DeckList>.Load(file); } catch(Exception) { //failed loading deckstats var corruptedFile = Helper.GetValidFilePath(Config.Instance.DataDir, "PlayerDecks_corrupted", "xml"); try { File.Move(file, corruptedFile); } catch(Exception) { throw new Exception( "Can not load or move PlayerDecks.xml file. Please manually delete the file in \"%appdata\\HearthstoneDeckTracker\"."); } //get latest backup file var backup = new DirectoryInfo(Config.Instance.DataDir).GetFiles("PlayerDecks_backup*").OrderByDescending(x => x.CreationTime).FirstOrDefault(); if(backup != null) { try { File.Copy(backup.FullName, file); _instance = XmlManager<DeckList>.Load(file); } catch(Exception ex) { throw new Exception( "Error restoring PlayerDecks backup. Please manually rename \"PlayerDecks_backup.xml\" to \"PlayerDecks.xml\" in \"%appdata\\HearthstoneDeckTracker\".", ex); } } else throw new Exception("PlayerDecks.xml is corrupted."); } var save = false; if(!Instance.AllTags.Contains("All")) { Instance.AllTags.Add("All"); save = true; } if(!Instance.AllTags.Contains("Favorite")) { if(Instance.AllTags.Count > 1) Instance.AllTags.Insert(1, "Favorite"); else Instance.AllTags.Add("Favorite"); save = true; } if(!Instance.AllTags.Contains("None")) { Instance.AllTags.Add("None"); save = true; } if(save) Save(); Instance.LoadActiveDeck(); }
private static void Save(DeckList instance) => XmlManager<DeckList>.Save(Config.Instance.DataDir + "PlayerDecks.xml", instance);
public static void ImportDecks(IEnumerable <ImportedDeck> decks, bool brawl, bool importNew = true, bool updateExisting = true, bool select = true) { Deck toSelect = null; foreach (var deck in decks) { if (deck.SelectedImportOption is NewDeck) { if (!importNew) { continue; } Log.Info($"Saving {deck.Deck.Name} as new deck."); var newDeck = new Deck { Class = deck.Class, Name = deck.Deck.Name, HsId = deck.Deck.Id, Cards = new ObservableCollection <Card>(deck.Deck.Cards.Select(x => { var card = Database.GetCardFromId(x.Id); card.Count = x.Count; return(card); })), LastEdited = DateTime.Now, IsArenaDeck = false }; if (brawl) { newDeck.Tags.Add("Brawl"); newDeck.Name = Helper.ParseDeckNameTemplate(Config.Instance.BrawlDeckNameTemplate, newDeck); } DeckList.Instance.Decks.Add(newDeck); toSelect = newDeck; } else { if (!updateExisting) { continue; } var existing = deck.SelectedImportOption as ExistingDeck; if (existing == null) { continue; } var target = existing.Deck; target.HsId = deck.Deck.Id; if (brawl && !target.Tags.Any(x => x.ToUpper().Contains("BRAWL"))) { target.Tags.Add("Brawl"); } if (existing.NewVersion.Major == 0) { Log.Info($"Assinging id to existing deck: {deck.Deck.Name}."); } else { Log.Info($"Saving {deck.Deck.Name} as {existing.NewVersion.ShortVersionString} (prev={target.Version.ShortVersionString})."); DeckList.Instance.Decks.Remove(target); var oldDeck = (Deck)target.Clone(); oldDeck.Versions = new List <Deck>(); if (!brawl) { target.Name = deck.Deck.Name; } target.LastEdited = DateTime.Now; target.Versions.Add(oldDeck); target.Version = existing.NewVersion; target.SelectedVersion = existing.NewVersion; target.Cards.Clear(); var cards = deck.Deck.Cards.Select(x => { var card = Database.GetCardFromId(x.Id); card.Count = x.Count; return(card); }); foreach (var card in cards) { target.Cards.Add(card); } var clone = (Deck)target.Clone(); DeckList.Instance.Decks.Add(clone); toSelect = clone; } } } DeckList.Save(); Core.MainWindow.DeckPickerList.UpdateDecks(); Core.MainWindow.UpdateIntroLabelVisibility(); if (select && toSelect != null) { Core.MainWindow.SelectDeck(toSelect, true); } Core.UpdatePlayerCards(true); }
//public Guid ActiveDeckId { get; set; } public static void Load() { var file = Config.Instance.DataDir + "PlayerDecks.xml"; if (!File.Exists(file)) { return; } try { _instance = XmlManager <DeckList> .Load(file); } catch (Exception) { //failed loading deckstats var corruptedFile = Helper.GetValidFilePath(Config.Instance.DataDir, "PlayerDecks_corrupted", "xml"); try { File.Move(file, corruptedFile); } catch (Exception) { throw new Exception( "Can not load or move PlayerDecks.xml file. Please manually delete the file in \"%appdata\\HearthstoneDeckTracker\"."); } //get latest backup file var backup = new DirectoryInfo(Config.Instance.DataDir).GetFiles("PlayerDecks_backup*").OrderByDescending(x => x.CreationTime).FirstOrDefault(); if (backup != null) { try { File.Copy(backup.FullName, file); _instance = XmlManager <DeckList> .Load(file); } catch (Exception ex) { throw new Exception( "Error restoring PlayerDecks backup. Please manually rename \"PlayerDecks_backup.xml\" to \"PlayerDecks.xml\" in \"%appdata\\HearthstoneDeckTracker\".", ex); } } else { throw new Exception("PlayerDecks.xml is corrupted."); } } var save = false; if (!Instance.AllTags.Contains("All")) { Instance.AllTags.Add("All"); save = true; } if (!Instance.AllTags.Contains("Favorite")) { if (Instance.AllTags.Count > 1) { Instance.AllTags.Insert(1, "Favorite"); } else { Instance.AllTags.Add("Favorite"); } save = true; } if (!Instance.AllTags.Contains("Arena")) { Instance.AllTags.Add("Arena"); save = true; } if (!Instance.AllTags.Contains("Constructed")) { Instance.AllTags.Add("Constructed"); save = true; } if (!Instance.AllTags.Contains("None")) { Instance.AllTags.Add("None"); save = true; } if (save) { Save(); } //Instance.ActiveDeck = Instance.Decks.FirstOrDefault(d => d.DeckId == Config.Instance.ActiveDeckId); }
public static async Task Export(Deck deck) { if (deck == null) { return; } try { Logger.WriteLine(string.Format("Exporting " + deck.GetDeckInfo()), "DeckExporter"); var hsHandle = User32.GetHearthstoneWindow(); if (!User32.IsHearthstoneInForeground()) { //restore window and bring to foreground User32.ShowWindow(hsHandle, User32.SwRestore); User32.SetForegroundWindow(hsHandle); //wait it to actually be in foreground, else the rect might be wrong await Task.Delay(500); } if (!User32.IsHearthstoneInForeground()) { MessageBox.Show("Can't find Heartstone window."); Logger.WriteLine("Can't find Hearthstone window.", "DeckExporter"); return; } Logger.WriteLine("Waiting for " + Config.Instance.ExportStartDelay + " seconds before starting the export process", "DeckExporter"); await Task.Delay(Config.Instance.ExportStartDelay * 1000); var hsRect = User32.GetHearthstoneRect(false); var ratio = (4.0 / 3.0) / ((double)hsRect.Width / hsRect.Height); var searchBoxPos = new Point((int)(GetXPos(Config.Instance.ExportSearchBoxX, hsRect.Width, ratio)), (int)(Config.Instance.ExportSearchBoxY * hsRect.Height)); var cardPosX = GetXPos(Config.Instance.ExportCard1X, hsRect.Width, ratio); var card2PosX = GetXPos(Config.Instance.ExportCard2X, hsRect.Width, ratio); var cardPosY = Config.Instance.ExportCardsY * hsRect.Height; Helper.MainWindow.Overlay.ForceHidden = true; Helper.MainWindow.Overlay.UpdatePosition(); if (Config.Instance.AutoClearDeck) { await ClearDeck(hsRect.Width, hsRect.Height, hsHandle, ratio); } if (Config.Instance.ExportSetDeckName) { await SetDeckName(deck.Name, ratio, hsRect.Width, hsRect.Height, hsHandle); } await ClickAllCrystal(ratio, hsRect.Width, hsRect.Height, hsHandle); Logger.WriteLine("Creating deck...", "DeckExporter"); deck.MissingCards.Clear(); foreach (var card in deck.Cards) { var missingCardsCount = await AddCardToDeck(card, searchBoxPos, cardPosX, card2PosX, cardPosY, hsRect.Height, hsRect.Width, hsHandle); if (missingCardsCount < 0) { return; } if (missingCardsCount > 0) { var missingCard = (Card)card.Clone(); missingCard.Count = missingCardsCount; deck.MissingCards.Add(missingCard); } } if (deck.MissingCards.Any()) { DeckList.Save(); } // Clear search field now all cards have been entered await ClickOnPoint(hsHandle, searchBoxPos); SendKeys.SendWait("{DELETE}"); SendKeys.SendWait("{ENTER}"); if (Config.Instance.ExportPasteClipboard) { Clipboard.Clear(); } Logger.WriteLine("Done creating deck.", "DeckExporter"); } catch (Exception e) { Logger.WriteLine("Error exporting deck: " + e.Message, "DeckExporter"); } finally { Helper.MainWindow.Overlay.ForceHidden = false; Helper.MainWindow.Overlay.UpdatePosition(); } }
private static void Save(DeckList instance) => XmlManager <DeckList> .Save(Config.Instance.DataDir + "PlayerDecks.xml", instance);
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 = Helper.MainWindow.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(); Helper.MainWindow.DeckPickerList.UpdateDecks(); }
public static void UpdateDungeonRunDeck(DungeonInfo info) { if (!Config.Instance.DungeonAutoImport) { return; } Log.Info($"Found dungeon run deck Set={((CardSet)info.CardSet).ToString()}"); var baseDeck = info.SelectedDeck ?? new List <int>(); var allCards = info.DbfIds?.ToList() ?? new List <int>(); if (baseDeck.All(x => allCards.Contains(x))) { if (info.PlayerChosenLoot > 0) { var loot = new[] { info.LootA, info.LootB, info.LootC }; var chosen = loot[info.PlayerChosenLoot - 1]; for (var i = 1; i < chosen.Count; i++) { allCards.Add(chosen[i]); } } if (info.PlayerChosenTreasure > 0) { allCards.Add(info.Treasure[info.PlayerChosenTreasure - 1]); } } else { allCards = baseDeck; } var cards = allCards.GroupBy(x => x).Select(x => { var card = Database.GetCardFromDbfId(x.Key, false); if (card == null) { return(null); } card.Count = x.Count(); return(card); }).Where(x => x != null).ToList(); var loadoutCardId = info.LoadoutCardId; var loadout = loadoutCardId != null?Database.GetCardFromId(loadoutCardId) : null; if (loadout != null && !allCards.Contains(loadout.DbfIf)) { cards.Add(loadout); } if (!Config.Instance.DungeonRunIncludePassiveCards) { cards.RemoveAll(c => !c.Collectible && c.HideStats); } var cardSet = (CardSet)info.CardSet; string playerClass = null; if (cardSet == CardSet.ULDUM && loadout != null) { playerClass = DungeonRun.GetUldumHeroPlayerClass(loadout.PlayerClass); } else { if (allCards.Count == 10) { playerClass = allCards.Select(x => Database.GetCardFromDbfId(x).PlayerClass).FirstOrDefault(x => x != null)?.ToUpperInvariant(); } if (playerClass == null) { playerClass = ((CardClass)info.HeroCardClass).ToString().ToUpperInvariant(); } } var deck = DeckList.Instance.Decks.FirstOrDefault(x => x.IsDungeonDeck && x.Class.ToUpperInvariant() == playerClass.ToUpperInvariant() && !(x.IsDungeonRunCompleted ?? false) && x.Cards.All(e => cards.Any(c => c.Id == e.Id && c.Count >= e.Count))); if (deck == null && (deck = CreateDungeonDeck(playerClass, cardSet, info.SelectedDeck, loadout)) == null) { Log.Info($"No existing deck - can't find default deck for {playerClass}"); return; } if (!info.RunActive && (cardSet == CardSet.ULDUM || cardSet == CardSet.DALARAN)) { Log.Info($"Inactive run for Set={cardSet.ToString()} - this is a new run"); return; } if (cards.All(c => deck.Cards.Any(e => c.Id == e.Id && c.Count == e.Count))) { Log.Info("No new cards"); return; } deck.Cards.Clear(); Helper.SortCardCollection(cards, false); foreach (var card in cards) { deck.Cards.Add(card); } deck.LastEdited = DateTime.Now; DeckList.Save(); Core.UpdatePlayerCards(true); Log.Info("Updated dungeon run deck"); }
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(); 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) { 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); } if (Config.Instance.SelectedDeckType != DeckType.All) { if (newDeckClone.IsArenaDeck && Config.Instance.SelectedDeckType != DeckType.Arena) { DeckPickerList.SelectDeckType(DeckType.Arena); } else if (!newDeckClone.IsArenaDeck && Config.Instance.SelectedDeckType != DeckType.Constructed) { DeckPickerList.SelectDeckType(DeckType.Constructed); } } if (!DeckPickerList.SelectedClasses.Contains(HeroClassAll.All)) { HeroClassAll deckClass; if (Enum.TryParse(newDeckClone.Class, out deckClass)) { if (!DeckPickerList.SelectedClasses.Contains(deckClass)) { DeckPickerList.SelectClasses(new List <HeroClassAll> { deckClass }); } } } DeckPickerList.UpdateDecks(); DeckPickerList.SelectDeck(newDeckClone); CloseNewDeck(); ClearNewDeckSection(); }
internal async void BtnCloneSelectedVersion_Click(object sender, RoutedEventArgs e) { var deck = DeckList.Instance.ActiveDeckVersion; 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); 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); } }
public async void SaveDeck(bool overwrite, SerializableVersion newVersion, bool workInProgressDeck = false) { 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; } if (_newDeck.Cards.Sum(c => c.Count) != 30 && workInProgressDeck == false) { 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 = ""; } 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(); 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"); 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()); } 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); 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(); }
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 = DeckList.Instance.Decks.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 selectedGame.HearthStatsDeckVersionId = selectedDeck.HearthStatsDeckVersionId; selectedDeck.DeckStats.Games.Add(selectedGame); DeckStatsList.Save(); DeckList.Save(); ; Refresh(); Helper.MainWindow.DeckPickerList.UpdateDecks(); if (HearthStatsAPI.IsLoggedIn && Config.Instance.HearthStatsAutoUploadNewGames) { HearthStatsManager.MoveMatchAsync(selectedGame, selectedDeck, background: true); } }
private static async Task<Deck> ImportHsTopdeck(string url) { try { var doc = await GetHtmlDoc(url); //<div id="leftbar"><div class="headbar"><div style="float:left">ViaGame House Cup #3</div> var tournament = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode("//div[@id='leftbar']/div[contains(@class, 'headbar')]/div").InnerText); // <div class="headbar"><div style="float:left">#5 - Hunter Face -<a href="search.php?q=ThijsNL&filter=current">ThijsNL</a> var deckName = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode("//div[@id='center']/div[@class='headbar']/div").InnerText.Trim()); var deck = new Deck(); deck.Name = tournament + " - " + deckName; //<div class="cardname" ... <span class="basic">2 Abusive Sergeant</span> var cards = doc.DocumentNode.SelectNodes("//div[contains(@class, 'cardname')]/span"); //<span class="midlarge"><span class="hunter">Hunter</span>-<span class="aggro">Aggro</span></span> var deckInfo = doc.DocumentNode.SelectSingleNode("//div[@id='contentfr']/div[@id='infos']").SelectNodes("//span[contains(@class, 'midlarge')]/span"); if (deckInfo.Count == 2) { deck.Class = HttpUtility.HtmlDecode(deckInfo[0].InnerText).Trim(); var decktype = HttpUtility.HtmlDecode(deckInfo[1].InnerText).Trim(); if(!String.IsNullOrEmpty(decktype) && decktype != "None" && Config.Instance.TagDecksOnImport) { if(!DeckList.Instance.AllTags.Contains(decktype)) { DeckList.Instance.AllTags.Add(decktype); DeckList.Save(); Helper.MainWindow.ReloadTags(); } deck.Tags.Add(decktype); } } foreach(var cardNode in cards) { var nameString = HttpUtility.HtmlDecode(cardNode.InnerText); var match = Regex.Match(nameString, @"^\s*(\d+)\s+(.*)\s*$"); if(match.Success) { var count = match.Groups[1].Value; var name = match.Groups[2].Value; var card = GameV2.GetCardFromName(name); card.Count = count.Equals("2") ? 2 : 1; deck.Cards.Add(card); if(string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") deck.Class = card.PlayerClass; } } return deck; } catch(Exception e) { Logger.WriteLine(e.ToString(), "DeckImporter"); return null; } }