public void OnGUI() { if (GUILayout.Button("Submit")) { DeckList deckList = new DeckList(); deckList.Cards = CardChecked.Where(x => x.Value).Select((pair, _) => pair.Key.Name).ToArray(); PlayerPrefs.SetString(DECK_SAVE_KEY, deckList.SerializeProtoString()); onChooseDeck(deckList); this.enabled = false; } GUILayout.BeginHorizontal(); foreach (Slot slot in Enum.GetValues(typeof(Slot))) { GUILayout.BeginVertical(); GUILayout.Label(slot.ToString() + ":"); foreach (Card option in CardOptions[slot]) { CardChecked[option] = GUILayout.Toggle(CardChecked[option], new GUIContent(option.Name, option.Name)); } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); if (!string.IsNullOrEmpty(GUI.tooltip)) { lastMouseOver = CardByName[GUI.tooltip]; lastMouseOver.Charged = true; Card.Card = lastMouseOver; Card.Sprite.SetActive(true); } else { Card.Sprite.SetActive(false); } Card.Update(); }
public void Start() { CardOptions = new Dictionary<Slot, List<Card>>(); CardChecked = new Dictionary<Card, bool>(); CardByName = new Dictionary<string, Card>(); string lastSavedDeck = PlayerPrefs.GetString(DECK_SAVE_KEY, null); DeckList deckList = null; if (lastSavedDeck == null) { deckList = new DeckList(); } else { deckList = lastSavedDeck.DeserializeProtoString<DeckList>(); } foreach (Slot slot in Enum.GetValues(typeof(Slot))) { CardOptions[slot] = new List<Card>(); } foreach (Card card in Importer.Singleton.Cards) { CardOptions[card.Slot].Add(card); CardChecked[card] = deckList.Cards.Contains(card.Name); CardByName[card.Name] = card; } Morphid mockMorphid = new Morphid(); mockMorphid.Morphium = 10; lastMouseOver = null; Card.Owner = mockMorphid; Card.SnapToMouse(); }
public IEnumerable<Card> CardsBySlot(Slot slot, DeckList deckInfo) { foreach (Card c in Cards) { if (c.Slot == slot && deckInfo.Cards.Contains(c.Name)) { for (int i = 0; i < 1; i++) { yield return c.Copy(); } } } }
void Awake() { // New level will not destory this object. DontDestroyOnLoad(gameObject); // Ensure only one DeckList object. if (me == null) me = this; else DestroyImmediate(gameObject); }
public void Setup(DeckList deckInfo) { Slot[] Slots = Enum.GetValues(typeof(Slot)).Cast<Slot>().OrderBy(x => x.Order()).ToArray(); Cards = new Card[Slots.Count()]; Decks = new Deck[Slots.Count()]; for (int i = 0; i < Slots.Count(); i++) { Decks[i] = new Deck (){ Slot = Slots[i] }; Decks[i].Shuffle(deckInfo); Cards[i] = Decks[i].Draw(); if (Cards[i] != null) { Cards[i].Charged = true; } } }
public void SelectDeck(Deck deck, bool setActive) { if (DeckList.Instance.ActiveDeck != null) { DeckPickerList.ClearFromCache(DeckList.Instance.ActiveDeck); } if (deck != null) { //set up notes DeckNotesEditor.SetDeck(deck); var flyoutHeader = deck.Name.Length >= 20 ? string.Join("", deck.Name.Take(17)) + "..." : deck.Name; FlyoutNotes.Header = flyoutHeader; //set up tags TagControlEdit.SetSelectedTags(DeckPickerList.SelectedDecks); MenuItemQuickSetTag.ItemsSource = TagControlEdit.Tags; MenuItemQuickSetTag.Items.Refresh(); DeckPickerList.MenuItemQuickSetTag.ItemsSource = TagControlEdit.Tags; DeckPickerList.MenuItemQuickSetTag.Items.Refresh(); OnPropertyChanged(nameof(HsReplayButtonVisibility)); //set and save last used deck for class if (setActive) { while (DeckList.Instance.LastDeckClass.Any(ldc => ldc.Class == deck.Class)) { var lastSelected = DeckList.Instance.LastDeckClass.FirstOrDefault(ldc => ldc.Class == deck.Class); if (lastSelected != null) { DeckList.Instance.LastDeckClass.Remove(lastSelected); } else { break; } } if (Core.Initialized) { DeckList.Instance.LastDeckClass.Add(new DeckInfo { Class = deck.Class, Name = deck.Name, Id = deck.DeckId }); DeckList.Save(); } Log.Info($"Switched to deck: {deck.Name} ({deck.SelectedVersion.ShortVersionString})"); int useNoDeckMenuItem = Core.TrayIcon.NotifyIcon.ContextMenu.MenuItems.IndexOfKey(TrayIcon.UseNoDeckMenuItemName); Core.TrayIcon.NotifyIcon.ContextMenu.MenuItems[useNoDeckMenuItem].Checked = false; } } else { Core.Game.IsUsingPremade = false; if (DeckList.Instance.ActiveDeck != null) { DeckList.Instance.ActiveDeck.IsSelectedInGui = false; } DeckList.Instance.ActiveDeck = null; if (setActive) { DeckPickerList.DeselectDeck(); } var useNoDeckMenuItem = Core.TrayIcon.NotifyIcon.ContextMenu.MenuItems.IndexOfKey(TrayIcon.UseNoDeckMenuItemName); Core.TrayIcon.NotifyIcon.ContextMenu.MenuItems[useNoDeckMenuItem].Checked = true; } if (setActive) { UseDeck(deck); } DeckPickerList.SelectDeck(deck); UpdateDeckList(deck); EnableMenuItems(deck != null); ManaCurveMyDecks.SetDeck(deck); UpdatePanelVersionComboBox(deck); if (setActive) { Core.Overlay.ListViewPlayer.Items.Refresh(); Core.Windows.PlayerWindow.ListViewPlayer.Items.Refresh(); } DeckManagerEvents.OnDeckSelected.Execute(deck); }
internal DeckRegularDict <LifeCardGameCardInformation> YearCards() => DeckList.Where(items => items.CanBeInPlayerHandToBeginWith == false).ToRegularDeckDict();
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; } } if (EditingDeck && overwrite) { DeckList.Instance.Decks.Remove(_newDeck); } var previousVersion = _newDeck.Version; if (overwrite && (_newDeck.Version != newVersion)) { AddDeckHistory(); _newDeck.Version = newVersion; _newDeck.SelectedVersion = newVersion; _newDeck.HearthStatsDeckVersionId = ""; } 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) { DeckStats statsEntry; if (DeckStatsList.Instance.DeckStats.TryGetValue(_newDeck.DeckId, out statsEntry)) { if (overwrite) { statsEntry.Name = deckName; Log.Info("Deck has new name, updated deckstats"); foreach (var game in statsEntry.Games) { game.DeckName = deckName; } } else { DeckStats newStatsEntry; if (DeckStatsList.Instance.DeckStats.TryGetValue(_newDeck.DeckId, out newStatsEntry)) { newStatsEntry = new DeckStats(_newDeck); DeckStatsList.Instance.DeckStats.TryAdd(_newDeck.DeckId, 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(); }
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; } }
public static async Task <Deck> Import(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck(); var dname = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode( "//h1[contains(@class, 'panel-title')]").InnerText); deck.Name = Regex.Replace(dname, @"\s+", " "); // remove sequence of tabs var cards = doc.DocumentNode.SelectNodes("//div[contains(@class, 'cardname')]/span"); var deckExtra = doc.DocumentNode.SelectSingleNode("//div[contains(@class, 'deck_banner_description')]"); var deckInfo = deckExtra.SelectNodes("//span[contains(@class, 'midlarge')]/span"); // get class and tags if (deckInfo.Count == 3) { deck.Class = HttpUtility.HtmlDecode(deckInfo[1].InnerText).Trim(); var decktype = HttpUtility.HtmlDecode(deckInfo[2].InnerText).Trim(); if (!string.IsNullOrWhiteSpace(decktype) && decktype != "None" && Config.Instance.TagDecksOnImport) { if (!DeckList.Instance.AllTags.Contains(decktype)) { DeckList.Instance.AllTags.Add(decktype); DeckList.Save(); if (Core.MainWindow != null) // to avoid errors when running tests { Core.MainWindow.ReloadTags(); } } deck.Tags.Add(decktype); } } // TODO uncomment for standard/wild tags /* * var deckFormat = deckExtra.SelectSingleNode("//span[contains(@class, 'small')]").InnerText.Trim(); * if(!string.IsNullOrWhiteSpace(deckFormat) && Config.Instance.TagDecksOnImport) * { * var format = "Standard"; * if(Regex.IsMatch(deckFormat, @"Format:\s*Wild")) * format = "Wild"; * if(!DeckList.Instance.AllTags.Contains(format)) * { * DeckList.Instance.AllTags.Add(format); * DeckList.Save(); * if(Core.MainWindow != null) // to avoid errors when running tests * Core.MainWindow.ReloadTags(); * } * deck.Tags.Add(format); * } */ 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 = Database.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) { Log.Error(e); return(null); } }
public void SelectDeck(Deck deck, bool setActive) { if (DeckList.Instance.ActiveDeck != null) { DeckPickerList.ClearFromCache(DeckList.Instance.ActiveDeck); } if (deck != null) { //set up tags TagControlEdit.SetSelectedTags(DeckPickerList.SelectedDecks); DeckPickerList.MenuItemQuickSetTag.ItemsSource = TagControlEdit.Tags; DeckPickerList.MenuItemQuickSetTag.Items.Refresh(); OnPropertyChanged(nameof(HsReplayButtonVisibility)); //set and save last used deck for class if (setActive) { while (DeckList.Instance.LastDeckClass.Any(ldc => ldc.Class == deck.Class)) { var lastSelected = DeckList.Instance.LastDeckClass.FirstOrDefault(ldc => ldc.Class == deck.Class); if (lastSelected != null) { DeckList.Instance.LastDeckClass.Remove(lastSelected); } else { break; } } if (Core.Initialized) { DeckList.Instance.LastDeckClass.Add(new DeckInfo { Class = deck.Class, Name = deck.Name, Id = deck.DeckId }); DeckList.Save(); } Log.Info($"Switched to deck: {deck.Name} ({deck.SelectedVersion.ShortVersionString})"); Core.TrayIcon.MenuItemUseNoDeck.Checked = false; } if (FlyoutDeckScreenshot.IsOpen) { DeckScreenshotFlyout.Deck = deck.GetSelectedDeckVersion(); } if (FlyoutDeckExport.IsOpen) { DeckExportFlyout.Deck = deck.GetSelectedDeckVersion(); } if (FlyoutDeckHistory.IsOpen) { if (deck.HasVersions) { DeckHistoryFlyout.Deck = deck; } else { FlyoutDeckHistory.IsOpen = false; } } } else { Core.Game.IsUsingPremade = false; if (DeckList.Instance.ActiveDeck != null) { DeckList.Instance.ActiveDeck.IsSelectedInGui = false; } DeckList.Instance.ActiveDeck = null; if (setActive) { DeckPickerList.DeselectDeck(); } Core.TrayIcon.MenuItemUseNoDeck.Checked = true; } if (setActive) { UseDeck(deck); } DeckPickerList.SelectDeck(deck); UpdateDeckList(deck); ManaCurveMyDecks.SetDeck(deck); UpdatePanelVersionComboBox(deck); GroupBoxHsReplayDeckInfo.Visibility = deck?.IsArenaDeck == true || deck?.IsDungeonDeck == true ? Collapsed : Visible; if (setActive) { Core.Overlay.ListViewPlayer.Items.Refresh(); Core.Windows.PlayerWindow.ListViewPlayer.Items.Refresh(); } DeckManagerEvents.OnDeckSelected.Execute(deck); }
// This is called even before the Start function. I just wanted to perform the DontDestroyOnLoad // as early as possible. private void Awake() { //The Services class is just a static class that acts as a list of all the major systems in the game. //Right now, Services has three attributes: the gameController (this), the eventManager, and the // encounter. if (Services.gameController == null) { Object.DontDestroyOnLoad(this); /* * flowchartGameObject = GameObject.Find("Flowchart"); * Object.DontDestroyOnLoad(flowchartGameObject); * flowchart = flowchartGameObject.GetComponent<Fungus.Flowchart>(); */ cardInfo.ReadFromSpreadsheet(); Services.gameController = this; Services.eventManager = new EventManager(); //Services.allCardInformation = AllCardInformation(cardSpreadsheet); //These lines initialize the public attributes in the GameController partyDeck = new DeckList(); nextNPC = new Kelly(); //The gameController state machine is private, because this should be pretty much //the only script changing the game state at such a high level. _gameFSM = new FiniteStateMachine <GameController>(this); //PURELY FOR TESTING THE CARD ENCOUNTER SCENE. In the real game, we don't want to start playing // cards right away. Feel free to uncomment if you want to test the card game, but be mindful. #region /* * partyDeck.AddCard(new Bubbly()); //These lines add basic cards to the deck * partyDeck.AddCard(new Dance()); * partyDeck.AddCard(new Gutsy()); * partyDeck.AddCard(new PrivateTalk()); * partyDeck.AddCard(new Chat()); * partyDeck.AddCard(new Encourage()); */ partyDeck.AddCard(new Dance()); partyDeck.AddCard(new Chill()); partyDeck.AddCard(new Gutsy()); _gameFSM.TransitionTo <StartMenu>(); //_gameFSM = new FiniteStateMachine<GameController>(this); //This line creates a state machine for //_gameFSM.TransitionTo<CardGame>(); #endregion } else { this.enabled = false; } }
public void UpdateDeckList(DeckList list) { list.Serialize().Save(list.FilePath); }
private void CreateDecklistPDF() { AddToLog("Creating PDF..."); List <Card> tempList = DeckList.ToList <Card>(); string qrURL = "https://www.underworldsdb.com/shared.php?deck=0,"; int objectiveCount = 0; int gambitCount = 0; int upgradeCount = 0; foreach (Card currentCard in tempList) { switch (currentCard.Type) { case "Objective": objectiveCount++; break; case "Ploy": gambitCount++; break; case "Spell": gambitCount++; break; case "Upgrade": upgradeCount++; break; } } int maxRows = Math.Max(objectiveCount, Math.Max(gambitCount, upgradeCount)); maxRows = maxRows + 3; if (!Directory.Exists(_decklistsFolderFullPath)) { Directory.CreateDirectory(_decklistsFolderFullPath); } string datePrefix = DateTime.Now.ToString("yyyyMMdd_HHmmss_"); string decklistFileName; if (DeckName.Length > 0) { decklistFileName = datePrefix + DeckName + _decklistFileExtension; } else { decklistFileName = datePrefix + _decklistFile + _decklistFileExtension; } string decklistFileFullPath = _decklistsFolderFullPath + decklistFileName; AddToLog("PDF file: " + decklistFileFullPath); PdfWriter pdfWriter = new PdfWriter(decklistFileFullPath); PdfDocument pdfDocument = new PdfDocument(pdfWriter); Document document = new Document(pdfDocument, PageSize.A4); document.SetMargins(20, 20, 20, 20); Table table = new Table(3); table.SetWidth(UnitValue.CreatePercentValue(100)); PdfFont regular = PdfFontFactory.CreateFont(iText.IO.Font.Constants.StandardFonts.HELVETICA); PdfFont bold = PdfFontFactory.CreateFont(iText.IO.Font.Constants.StandardFonts.HELVETICA_BOLD); for (int row = 1; row <= maxRows; row++) { for (int col = 1; col <= 3; col++) { if (row == 1 && col == 2) { if (DeckName.Length > 0) { table.AddCell(createCell(DeckName, TextAlignment.CENTER, bold, false, false, false, false)); } else { table.AddCell(createCell("Decklist", TextAlignment.CENTER, bold, false, false, false, false)); } continue; } if (row == 2 && col == 1) { table.AddCell(createCell("Objectives (" + objectiveCount.ToString() + ")", TextAlignment.CENTER, bold, false, false, false, false)); continue; } if (row == 2 && col == 2) { table.AddCell(createCell("Gambits (" + gambitCount.ToString() + ")", TextAlignment.CENTER, bold, false, false, false, false)); continue; } if (row == 2 && col == 3) { table.AddCell(createCell("Upgrades (" + upgradeCount.ToString() + ")", TextAlignment.CENTER, bold, false, false, false, false)); continue; } if (row > 2 && row < maxRows) { if (col == 1) { bool bFound = false; for (int i = 0; i < tempList.Count; i++) { if (tempList[i].Type == "Objective") { bool championship = false; if (tempList[i].OrganisedPlay.Substring(0, 1) == "V") { championship = true; } bool restricted = false; if (tempList[i].Restricted == "Restricted") { restricted = true; } bool surge = false; if (tempList[i].ObjType == "Surge") { surge = true; } table.AddCell(createCell(tempList[i].Name, TextAlignment.LEFT, regular, true, championship, restricted, surge)); qrURL += tempList[i].Number + ","; tempList.RemoveAt(i); bFound = true; break; } } if (bFound) { continue; } } if (col == 2) { bool bFound = false; for (int i = 0; i < tempList.Count; i++) { if (tempList[i].Type == "Ploy" || tempList[i].Type == "Spell") { bool championship = false; if (tempList[i].OrganisedPlay.Substring(0, 1) == "V") { championship = true; } bool restricted = false; if (tempList[i].Restricted == "Restricted") { restricted = true; } table.AddCell(createCell(tempList[i].Name, TextAlignment.LEFT, regular, true, championship, restricted, false)); qrURL += tempList[i].Number + ","; tempList.RemoveAt(i); bFound = true; break; } } if (bFound) { continue; } } if (col == 3) { bool bFound = false; for (int i = 0; i < tempList.Count; i++) { if (tempList[i].Type == "Upgrade") { bool championship = false; if (tempList[i].OrganisedPlay.Substring(0, 1) == "V") { championship = true; } bool restricted = false; if (tempList[i].Restricted == "Restricted") { restricted = true; } table.AddCell(createCell(tempList[i].Name, TextAlignment.LEFT, regular, true, championship, restricted, false)); qrURL += tempList[i].Number + ","; tempList.RemoveAt(i); bFound = true; break; } } if (bFound) { continue; } } } if (row == maxRows && col == 1) { QrCodeEncodingOptions options = new QrCodeEncodingOptions(); options = new QrCodeEncodingOptions { DisableECI = true, CharacterSet = "UTF-8", Width = 150, Height = 150, }; var writer = new BarcodeWriter(); writer.Format = BarcodeFormat.QR_CODE; writer.Options = options; qrURL = qrURL.Remove(qrURL.Length - 1, 1); if (DeckName.Length > 0) { qrURL += "&deckname=" + DeckName.Replace(" ", "%20"); } if (qrURL.Length <= 2953) { Image img = writer.Write(qrURL); MemoryStream ms = new MemoryStream(); img.Save(ms, ImageFormat.Bmp); ImageData rawImage = ImageDataFactory.Create(ms.ToArray()); iText.Layout.Element.Image image = new iText.Layout.Element.Image(rawImage); table.AddCell(createCell(image, HorizontalAlignment.CENTER, 3)); } break; } table.AddCell(createCell("", TextAlignment.CENTER, regular, false, false, false, false)); } } document.Add(table); AddToLog("Finalizing..."); document.Close(); pdfWriter.Close(); AddToLog("Finished"); }
public IEnumerable <Type> GetDeck() { return(DeckList.AsReadOnly()); }
private void RemoveAllCardsFromDeckList() { DeckList.Clear(); }
private void RemoveCardFromDeckList(Card SelectedCard) { DeckList.Remove(SelectedCard); }
private void AddCardToDeckList(Card SelectedCard) { DeckList.Add(SelectedCard); }
public void SelectDeck(Deck deck, bool setActive) { if (DeckList.Instance.ActiveDeck != null) { DeckPickerList.ClearFromCache(DeckList.Instance.ActiveDeck); } if (deck != null) { //set up notes DeckNotesEditor.SetDeck(deck); var flyoutHeader = deck.Name.Length >= 20 ? string.Join("", deck.Name.Take(17)) + "..." : deck.Name; FlyoutNotes.Header = flyoutHeader; //set up tags TagControlEdit.SetSelectedTags(DeckPickerList.SelectedDecks); MenuItemQuickSetTag.ItemsSource = TagControlEdit.Tags; MenuItemQuickSetTag.Items.Refresh(); DeckPickerList.MenuItemQuickSetTag.ItemsSource = TagControlEdit.Tags; DeckPickerList.MenuItemQuickSetTag.Items.Refresh(); //set and save last used deck for class if (setActive) { while (DeckList.Instance.LastDeckClass.Any(ldc => ldc.Class == deck.Class)) { var lastSelected = DeckList.Instance.LastDeckClass.FirstOrDefault(ldc => ldc.Class == deck.Class); if (lastSelected != null) { DeckList.Instance.LastDeckClass.Remove(lastSelected); } else { break; } } DeckList.Instance.LastDeckClass.Add(new DeckInfo { Class = deck.Class, Name = deck.Name, Id = deck.DeckId }); DeckList.Save(); Logger.WriteLine("Switched to deck: " + deck.Name, "Tracker"); int useNoDeckMenuItem = Core.TrayIcon.NotifyIcon.ContextMenu.MenuItems.IndexOfKey(TrayIcon.UseNoDeckMenuItemName); Core.TrayIcon.NotifyIcon.ContextMenu.MenuItems[useNoDeckMenuItem].Checked = false; } } else { Core.Game.IsUsingPremade = false; if (DeckList.Instance.ActiveDeck != null) { DeckList.Instance.ActiveDeck.IsSelectedInGui = false; } DeckList.Instance.ActiveDeck = null; if (setActive) { DeckPickerList.DeselectDeck(); } var useNoDeckMenuItem = Core.TrayIcon.NotifyIcon.ContextMenu.MenuItems.IndexOfKey(TrayIcon.UseNoDeckMenuItemName); Core.TrayIcon.NotifyIcon.ContextMenu.MenuItems[useNoDeckMenuItem].Checked = true; } //set up stats var statsTitle = $"Stats{(deck == null ? "" : ": " + deck.Name)}"; Core.Windows.StatsWindow.Title = statsTitle; FlyoutDeckStats.Header = statsTitle; Core.Windows.StatsWindow.StatsControl.SetDeck(deck); DeckStatsFlyout.SetDeck(deck); if (setActive) { UseDeck(deck); } UpdateDeckList(deck); EnableMenuItems(deck != null); ManaCurveMyDecks.SetDeck(deck); UpdatePanelVersionComboBox(deck); if (setActive) { Core.Overlay.ListViewPlayer.Items.Refresh(); Core.Windows.PlayerWindow.ListViewPlayer.Items.Refresh(); } DeckManagerEvents.OnDeckSelected.Execute(deck); }
public void CreateDeckList(DeckList list) { string fileName = GetNextFilePath("decklist-"); list.Serialize().Save(fileName); }
protected void OnChooseDeck(DeckList deckList) { this.deckList = deckList; Connect(); }
public static bool CheckForClipboardImport() { try { if (Clipboard.ContainsText()) { var clipboardContent = Clipboard.GetText(); if (clipboardContent.StartsWith("netdeckimport") || clipboardContent.StartsWith("trackerimport")) { var clipboardLines = clipboardContent.Split('\n').ToList(); var deckName = clipboardLines.FirstOrDefault(line => line.StartsWith("name:")); if (!string.IsNullOrEmpty(deckName)) { clipboardLines.Remove(deckName); deckName = deckName.Replace("name:", "").Trim(); } var url = clipboardLines.FirstOrDefault(line => line.StartsWith("url:")); if (!string.IsNullOrEmpty(url)) { clipboardLines.Remove(url); url = url.Replace("url:", "").Trim(); } bool?isArenaDeck = null; var arena = clipboardLines.FirstOrDefault(line => line.StartsWith("arena:")); if (!string.IsNullOrEmpty(arena)) { clipboardLines.Remove(arena); if (bool.TryParse(arena.Replace("arena:", "").Trim(), out var isArena)) { isArenaDeck = isArena; } } var localized = false; var nonEnglish = clipboardLines.FirstOrDefault(line => line.StartsWith("nonenglish:")); if (!string.IsNullOrEmpty(nonEnglish)) { clipboardLines.Remove(nonEnglish); bool.TryParse(nonEnglish.Replace("nonenglish:", "").Trim(), out localized); } var tagsRaw = clipboardLines.FirstOrDefault(line => line.StartsWith("tags:")); var tags = new List <string>(); if (!string.IsNullOrEmpty(tagsRaw)) { clipboardLines.Remove(tagsRaw); tags = tagsRaw.Replace("tags:", "").Trim().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); } clipboardLines.RemoveAt(0); //"netdeckimport" / "trackerimport" var deck = StringImporter.Import(clipboardLines.Aggregate((c, n) => c + "\n" + n), localized); if (deck != null) { if (tags.Any()) { var reloadTags = false; foreach (var tag in tags) { if (!DeckList.Instance.AllTags.Contains(tag)) { DeckList.Instance.AllTags.Add(tag); reloadTags = true; } deck.Tags.Add(tag); } if (reloadTags) { DeckList.Save(); Core.MainWindow.ReloadTags(); } } if (isArenaDeck.HasValue) { deck.IsArenaDeck = isArenaDeck.Value; } deck.Url = url; deck.Name = deckName; if (Config.Instance.AutoSaveOnImport) { DeckManager.SaveDeck(deck); } else { Core.MainWindow.ShowDeckEditorFlyout(deck, true); } Core.MainWindow.ActivateWindow(); } Clipboard.Clear(); return(true); } } } catch (Exception e) { Log.Error(e); return(false); } return(false); }
private async void Window_Closing(object sender, CancelEventArgs e) { if (!ExitRequestedFromTray && Config.Instance.CloseToTray) { MinimizeToTray(); e.Cancel = true; return; } try { Log.Info("Shutting down..."); Influx.OnAppExit(Helper.GetCurrentVersion()); LiveDataManager.Stop(); 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; Config.Instance.WindowHeight = (int)(Height - _heightChangeDueToSearchBox); Config.Instance.TrackerWindowTop = (int)Top; Config.Instance.TrackerWindowLeft = (int)Left; //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(); } }
public static async Task <PostResult> PostGameResultAsync(GameStats game, Deck deck) { if (!IsValidGame(game)) { return(PostResult.Failed); } if (!deck.HasHearthStatsId) { Logger.WriteLine("can not upload game, deck has no hearthstats id", "HearthStatsAPI"); return(PostResult.Failed); } long versionId; if (!long.TryParse(deck.HearthStatsDeckVersionId, out versionId)) { Logger.WriteLine("error: invalid HearthStatsDeckVersionId", "HearthStatsAPI"); return(PostResult.Failed); } Logger.WriteLine("uploading match: " + game, "HearthStatsAPI"); var url = BaseUrl + "/api/v2/matches/hdt_new?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(); } gameObj.created_at = game.StartTime.ToString("s") + "Z"; var data = JsonConvert.SerializeObject(gameObj); try { var response = await PostAsync(url, data); var json = JsonConvert.DeserializeObject(response); if (json.status.ToString() == "success") { game.HearthStatsId = json.data.id; Logger.WriteLine("assigned id to match: " + game.HearthStatsId, "HearthStatsAPI"); 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) { Logger.WriteLine(e.ToString(), "HearthStatsAPI"); return(PostResult.Failed); } }
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].OpponentCards; if (opponentCards.Any()) { gameObjs[i].oppcards = opponentCards.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); } }
public IArchetypeJudge CreateArchetypeJudgeService(DeckList deckList) { return(new ArchetypeJudge(deckList)); }
public static async Task <PostResult> UploadDeckAsync(Deck deck, bool saveFilesAfter = true, bool background = false) { Logger.WriteLine("trying to upload deck " + deck, "HearthStatsManager"); if (!HearthStatsAPI.IsLoggedIn) { Logger.WriteLine("error: not logged in", "HearthStatsManager"); return(PostResult.Failed); } if (background) { AddBackgroundActivity(); } var first = deck.GetVersion(1, 0); if (!first.IsArenaDeck && first.HasHearthStatsId && !deck.HasHearthStatsId && !deck.HearthStatsIdsAlreadyReset) { first.HearthStatsId = first.HearthStatsIdForUploading; await HearthStatsAPI.DeleteDeckAsync(first); await Task.Delay(1000); //reset everything foreach (var version in deck.VersionsIncludingSelf.Select(deck.GetVersion)) { version.ResetHearthstatsIds(); foreach (var game in version.DeckStats.Games) { game.HearthStatsDeckId = null; game.HearthStatsDeckVersionId = null; game.HearthStatsId = null; } } } var result = await HearthStatsAPI.PostDeckAsync(first, deck); if (!result.Success && result.Retry) { await Task.Delay(RetryDelay); Logger.WriteLine("try #2 to upload deck " + deck, "HearthStatsManager"); result = await HearthStatsAPI.PostDeckAsync(first, deck); } if (result.Success) { var versions = deck.VersionsIncludingSelf.Where(v => v != new SerializableVersion(1, 0)) .Select(deck.GetVersion) .Where(d => d != null && !d.HasHearthStatsDeckVersionId) .ToList(); if (versions.Any()) { foreach (var v in versions) { await Task.Delay(VersionDelay); await UploadVersionAsync(v, first.HearthStatsIdForUploading, false); } deck.HearthStatsId = first.HearthStatsId; first.HearthStatsId = ""; first.HearthStatsIdForUploading = deck.HearthStatsId; } if (saveFilesAfter) { DeckList.Save(); } if (background) { RemoveBackgroundActivity(); } Logger.WriteLine("success uploading deck " + deck, "HearthStatsManager"); return(PostResult.WasSuccess); } if (background) { RemoveBackgroundActivity(); } return(PostResult.Failed); }
void OnUpdateDeckListEvent(UpdateDeckListEvent e) { dl = e.deckList; }
public UpdateDeckListEvent(DeckList deckList) { this.deckList = deckList; }
protected override void AfterShuffle() { //this is what runs after the cards shuffle. _clock1 !.NewGame(DeckList.ToRegularDeckDict()); }
public static async Task <Deck> Import(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck(); deck.Name = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode("/html/body/div/div[4]/div/div[2]/div/div[1]/h3").InnerText.Trim()); var cards = doc.DocumentNode.SelectNodes("//div[contains(@class, 'cardname')]/span"); var deckInfo = doc.DocumentNode.SelectSingleNode("//div[@id='subinfo']").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(); if (Core.MainWindow != null) // to avoid errors when running tests { Core.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 = Database.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) { Log.Error(e); return(null); } }
private async void DeleteDeck(Deck deck, bool saveAndUpdate = true) { if (deck == null) { return; } var deckStats = DeckStatsList.Instance.DeckStats.FirstOrDefault(ds => ds.BelongsToDeck(deck)); if (deckStats != null) { if (deckStats.Games.Any()) { if (Config.Instance.KeepStatsWhenDeletingDeck) { var defaultDeck = DefaultDeckStats.Instance.GetDeckStats(deck.Class); if (defaultDeck != null) { defaultDeck.Games.AddRange(deckStats.Games); } DefaultDeckStats.Save(); Logger.WriteLine(string.Format("Moved deckstats for deck {0} to default stats", deck.Name), "Edit"); } else { try { foreach (var game in deckStats.Games) { game.DeleteGameFile(); } Logger.WriteLine("Deleted games from deck: " + deck.Name, "Edit"); } catch (Exception) { Logger.WriteLine("Error deleting games", "Edit"); } } } DeckStatsList.Instance.DeckStats.Remove(deckStats); if (saveAndUpdate) { DeckStatsList.Save(); } Logger.WriteLine("Removed deckstats from deck: " + deck.Name, "Edit"); } if (HearthStatsAPI.IsLoggedIn && deck.HasHearthStatsId && await CheckHearthStatsDeckDeletion()) { HearthStatsManager.DeleteDeckAsync(deck, false, true); } DeckList.Instance.Decks.Remove(deck); if (saveAndUpdate) { DeckList.Save(); DeckPickerList.UpdateDecks(); DeckPickerList.UpdateArchivedClassVisibility(); } ListViewDeck.ItemsSource = null; Logger.WriteLine("Deleted deck: " + deck.Name, "Edit"); }
private async void ExportDeck(Deck deck) { if (Config.Instance.ShowExportingDialog) { var message = $"1) Create a new (or open an existing) {deck.Class} deck.\n\n2) Leave the deck creation screen open.\n\n3) Click 'Export' and do not move your mouse or type until done."; var result = await this.ShowMessageAsync("Export " + deck.Name + " to Hearthstone", message, AffirmativeAndNegative, new MessageDialogs.Settings { AffirmativeButtonText = "Export" }); if (result == MessageDialogResult.Negative) { return; } } HearthMirror.Objects.Deck openDeck; var settings = new MessageDialogs.Settings() { AffirmativeButtonText = "Continue", NegativeButtonText = "Cancel" }; while ((openDeck = Reflection.GetEditedDeck()) == null) { var result = await this.ShowMessageAsync("No open deck found", "Please open a deck for editing in Hearthstone before continuing.", AffirmativeAndNegative, settings); if (result == MessageDialogResult.Negative) { return; } } var missingCards = ExportingHelper.GetMissingCards(deck).ToList(); deck.MissingCards = missingCards; if (missingCards.Count > 0) { var result = await this.ShowMissingCardsMessage(deck, true); if (result == MessageDialogResult.Negative) { return; } } string selectedClass; while ((selectedClass = Database.GetCardFromId(openDeck.Hero).PlayerClass) != deck.Class) { var result = await this.ShowMessageAsync("Incorrect class", $"Open deck is a {selectedClass} deck, but we are trying to import a {deck.Class} deck. Please create a deck with the correct class before continuing.", AffirmativeAndNegative, settings); if (result == MessageDialogResult.Negative) { return; } openDeck = Reflection.GetEditedDeck(); } while (!deck.StandardViable && !openDeck.IsWild) { var result = await this.ShowMessageAsync("Not a wild deck", "Open deck is a standard deck, but we are importing a wild deck. Please switch the deck to wild before continuing.", AffirmativeAndNegative, settings); if (result == MessageDialogResult.Negative) { return; } openDeck = Reflection.GetEditedDeck(); } var controller = await this.ShowProgressAsync("Creating Deck", "Please do not move your mouse or type."); Topmost = false; await Task.Delay(500); var success = await DeckExporter.Export(deck, async() => { if (controller != null) { await controller.CloseAsync(); } ActivateWindow(); var result = await this.ShowMessageAsync("Importing interrupted", "Continue?", AffirmativeAndNegative, new MessageDialogs.Settings() { AffirmativeButtonText = "Continue", NegativeButtonText = "Cancel" }); if (result == MessageDialogResult.Affirmative) { controller = await this.ShowProgressAsync("Creating Deck", "Please do not move your mouse or type."); } return(result == MessageDialogResult.Affirmative); }); if (controller.IsOpen) { await controller.CloseAsync(); } if (success) { var hsDeck = Reflection.GetEditedDeck(); if (hsDeck != null) { var existingHsId = DeckList.Instance.Decks.Where(x => x.DeckId != deck.DeckId).FirstOrDefault(x => x.HsId == hsDeck.Id); if (existingHsId != null) { existingHsId.HsId = 0; } deck.HsId = hsDeck.Id; DeckList.Save(); } } }
private int AddNewGames(List <Game> games) { Common.Log.Debug($"Tracker: Adding {games.Count} new games"); Common.Log.Debug("Tracker: Refreshing deck status"); Reload <DeckStatsList>(); Reload <DefaultDeckStats>(); Reload <DeckList>(); var count = 0; foreach (var g in games) { var success = false; var name = g.Deck.Name.ToLowerInvariant(); var klass = GetClass(g); if (!string.IsNullOrWhiteSpace(name)) { // find a deck by name // add it if it exists (latest version) // if not create empty deck, and add to that var decks = DeckList.Instance.Decks; var deckMatches = decks.Where(d => d.Name.ToLowerInvariant() == name && d.Class.ToLower() == klass && !d.Archived); // if only a single match use that deck if (deckMatches.Count() == 1) { var match = deckMatches.First(); Common.Log.Debug($"Tracker: Matching deck found '{match.Name}' {match.DeckId}"); var gameStats = new GameStats(); // copy the game info g.CopyTo(gameStats); // add the matched deck to GameStats object gameStats.DeckId = match.DeckId; gameStats.DeckName = match.Name; // if no deck version matches use latest if (gameStats.PlayerDeckVersion == null || !match.VersionsIncludingSelf.Contains(gameStats.PlayerDeckVersion)) { gameStats.PlayerDeckVersion = match.GetMaxVerion(); } // if game id is empty create new one if (gameStats.GameId == Guid.Empty) { gameStats.GameId = Guid.NewGuid(); } // add game to hdt stats DeckStatsList.Instance.DeckStats[match.DeckId].AddGameResult(gameStats); success = true; Common.Log.Debug($"Tracker: Game added to {match.Name} stats"); } else { Common.Log.Debug($"Single deck matching '{name}' not found, using default stats"); } } if (!success) { // add to default class deck stats if (!string.IsNullOrEmpty(klass)) { var stats = DefaultDeckStats.Instance.GetDeckStats(klass); var gameStats = new GameStats(); g.CopyTo(gameStats); // if game id is empty create new one if (gameStats.GameId == Guid.Empty) { gameStats.GameId = Guid.NewGuid(); } stats.AddGameResult(gameStats); success = true; Common.Log.Debug($"Tracker: Game added to default {klass} stats"); } else { Common.Log.Debug($"Tracker: Failed to add game {g.Id}"); } } count += success ? 1 : 0; } Common.Log.Debug($"Tracker: Saving deck stats"); DeckList.Save(); DeckStatsList.Save(); DefaultDeckStats.Save(); return(count); }
public void AddMorphid(string guid, DeckList deckInfo) { Morphids[PlayerCount].GUID = guid; Morphids[PlayerCount].CardContainer.Setup(deckInfo); Morphids[PlayerCount].AttachmentContainer.Setup(); if (++PlayerCount >= NUM_PLAYERS) { ActivePlayer = UnityEngine.Random.Range(0, 1); } }
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.HasValue ? MovedLeft.Value : 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(); Core.Windows.TimerWindow.Shutdown(); Core.Windows.PlayerWindow.Shutdown(); Core.Windows.OpponentWindow.Shutdown(); Core.Windows.StatsWindow.Shutdown(); Config.Save(); DeckList.Save(); DeckStatsList.Save(); PluginManager.SavePluginsSettings(); PluginManager.Instance.UnloadPlugins(); } catch (Exception) { //doesnt matter } finally { Application.Current.Shutdown(); } }
private byte[] OnGetAccountInfo(GameSession session, byte[] body) { GetAccountInfo request = new GetAccountInfo(); using(Stream stream = new MemoryStream(body)) { request.Deserialize(stream); } Debug.WriteLine("LOG " + request.Request_); if(request.Request_ == GetAccountInfo.Request.CAMPAIGN_INFO) { ProfileProgress response = new ProfileProgress() { Progress = 6, BestForge = 0 }; return response.EncodeResponse(233); } if(request.Request_ == GetAccountInfo.Request.BOOSTERS) { BoosterList response = new BoosterList(); response.List.Add(new BoosterInfo() { Type = (int)BoosterType.Classic, Count = 10 }); response.List.Add(new BoosterInfo() { Type = (int)BoosterType.GvG, Count = 10 }); response.List.Add(new BoosterInfo() { Type = (int)BoosterType.TGT, Count = 10 }); return response.EncodeResponse(224); } if(request.Request_ == GetAccountInfo.Request.FEATURES) { GuardianVars response = new GuardianVars() { ShowUserUI = 1 }; return response.EncodeResponse(264); } if(request.Request_ == GetAccountInfo.Request.MEDAL_INFO) { MedalInfo response = new MedalInfo() { SeasonWins = 0, Stars = 0, Streak = 0, StarLevel = 1, LevelStart = 1, LevelEnd = 3, CanLose = false }; return response.EncodeResponse(232); } if(request.Request_ == GetAccountInfo.Request.NOTICES) { ProfileNotices response = new ProfileNotices(); return response.EncodeResponse(212); } if(request.Request_ == GetAccountInfo.Request.DECK_LIST) { DeckList response = new DeckList(); foreach(Deck deck in session.Server.Database.Table<Deck>().Where(d => d.DeckType == DeckType.PRECON_DECK)) { response.Decks.Add(deck.ToDeckInfo()); } foreach(Deck deck in session.Server.Database.Table<Deck>().Where(d => d.DeckType == DeckType.NORMAL_DECK && d.AccountID == session.Account.ID)) { response.Decks.Add(deck.ToDeckInfo()); } return response.EncodeResponse(202); } if(request.Request_ == GetAccountInfo.Request.COLLECTION) { Collection response = new Collection(); foreach(DbfCard card in session.Server.Database.Table<DbfCard>().Where(c => c.Collectible)) { response.Stacks.Add(new CardStack() { LatestInsertDate = DateTime.Now.ToPegasusDate(), NumSeen = 2, Count = 2, CardDef = new PegasusShared.CardDef() { Asset = card.ID, Premium = 0 } }); } return response.EncodeResponse(207); } if(request.Request_ == GetAccountInfo.Request.DECK_LIMIT) { ProfileDeckLimit response = new ProfileDeckLimit() { DeckLimit = 9 }; return response.EncodeResponse(231); } if(request.Request_ == GetAccountInfo.Request.CARD_VALUES) { CardValues response = new CardValues() { CardNerfIndex = 0 }; return response.EncodeResponse(260); } if(request.Request_ == GetAccountInfo.Request.ARCANE_DUST_BALANCE) { ArcaneDustBalance response = new ArcaneDustBalance() { Balance = 10000 }; return response.EncodeResponse(262); } if(request.Request_ == GetAccountInfo.Request.NOT_SO_MASSIVE_LOGIN) { NotSoMassiveLoginReply response = new NotSoMassiveLoginReply(); return response.EncodeResponse(300); } if(request.Request_ == GetAccountInfo.Request.REWARD_PROGRESS) { RewardProgress response = new RewardProgress() { SeasonEnd = new DateTime(DateTime.UtcNow.AddMonths(1).Year, DateTime.UtcNow.AddMonths(1).Month, 1, 7, 0, 0).ToPegasusDate(), WinsPerGold = 3, GoldPerReward = 10, MaxGoldPerDay = 100, SeasonNumber = 1, XpSoloLimit = 60, MaxHeroLevel = 60, NextQuestCancel = DateTime.UtcNow.ToPegasusDate(), EventTimingMod = 0.291667f }; return response.EncodeResponse(271); } if(request.Request_ == GetAccountInfo.Request.GOLD_BALANCE) { GoldBalance response = new GoldBalance() { Cap = 999999, CapWarning = 2000, CappedBalance = 9999, BonusBalance = 0 }; return response.EncodeResponse(278); } if(request.Request_ == GetAccountInfo.Request.HERO_XP) { HeroXP response = new HeroXP(); for(int i = 2; i < 11; i++) { response.XpInfos.Add(new HeroXPInfo() { ClassId = i, Level = 30, CurrXp = 420, MaxXp = 840 }); } return response.EncodeResponse(283); } if(request.Request_ == GetAccountInfo.Request.PLAYER_RECORD) { PlayerRecords response = new PlayerRecords(); return response.EncodeResponse(270); } if(request.Request_ == GetAccountInfo.Request.CARD_BACKS) { CardBacks response = new CardBacks() { DefaultCardBack = 0 }; foreach(DbfCardBack cardBack in session.Server.Database.Table<DbfCardBack>()) { response.CardBacks_.Add(cardBack.ID); } return response.EncodeResponse(236); } if(request.Request_ == GetAccountInfo.Request.FAVORITE_HEROES) { FavoriteHeroesResponse response = new FavoriteHeroesResponse(); foreach(FavoriteHero hero in session.Server.Database.Table<FavoriteHero>().Where(h => h.AccountID == session.Account.ID)) { response.FavoriteHeroes.Add(new PegasusShared.FavoriteHero() { ClassId = hero.ClassID, Hero = new PegasusShared.CardDef() { Asset = hero.CardID, Premium = hero.Premium, } }); } return response.EncodeResponse(318); } if(request.Request_ == GetAccountInfo.Request.ACCOUNT_LICENSES) { AccountLicensesInfoResponse response = new AccountLicensesInfoResponse(); return response.EncodeResponse(325); } if(request.Request_ == GetAccountInfo.Request.BOOSTER_TALLY) { BoosterTallyList response = new BoosterTallyList(); return response.EncodeResponse(313); } if(request.Request_ == GetAccountInfo.Request.MEDAL_HISTORY) { MedalHistory response = new MedalHistory(); response.Medals.Add(new MedalHistoryInfo() { LegendRank = 1, LevelEnd = 0, LevelStart = 0, Season = 1, StarLevel = 0, Stars = 0, When = new DateTime(DateTime.UtcNow.AddMonths(-1).Year, DateTime.UtcNow.AddMonths(-1).Month, 1, 7, 0, 0).ToPegasusDate() }); return response.EncodeResponse(234); } if(request.Request_ == GetAccountInfo.Request.PVP_QUEUE) { PlayQueue response = new PlayQueue() { Queue = new PlayQueueInfo() { GameType = BnetGameType.BGT_NORMAL } }; return response.EncodeResponse(286); } Debug.WriteLine("ERR AccountHandler.OnGetAccountInfo missing " + request.Request_); return null; }
// Constructors public pdfGenerator(DeckList deck) { decklist = deck; t = new Thread(() => { begin(); }); }