public static async Task SetDeckName(Deck deck, ExportingInfo info) { if(Config.Instance.ExportSetDeckName && !deck.TagList.ToLower().Contains("brawl")) { var name = deck.Name; if(Config.Instance.ExportAddDeckVersionToName) name += " " + deck.SelectedVersion.ShortVersionString; Logger.WriteLine("Setting deck name...", "DeckExporter"); var nameDeckPos = new Point((int)Helper.GetScaledXPos(Config.Instance.ExportNameDeckX, info.HsRect.Width, info.Ratio), (int)(Config.Instance.ExportNameDeckY * info.HsRect.Height)); await MouseActions.ClickOnPoint(info.HsHandle, nameDeckPos); //send enter and second click to make sure the current name gets selected SendKeys.SendWait("{ENTER}"); await MouseActions.ClickOnPoint(info.HsHandle, nameDeckPos); if(Config.Instance.ExportPasteClipboard) { Clipboard.SetText(name); SendKeys.SendWait("^v"); } else SendKeys.SendWait(name); SendKeys.SendWait("{ENTER}"); } }
{ _info = info; _onUnexpectedMousePos = onUnexpectedMousePos; } private Point _previousCursorPos = Point.Empty; public async Task ClickOnPoint(Point clientPoint) { if(!User32.IsHearthstoneInForeground() || (_onUnexpectedMousePos != null && _previousCursorPos != Point.Empty && (Math.Abs(_previousCursorPos.X - Cursor.Position.X) > 10 || Math.Abs(_previousCursorPos.Y - Cursor.Position.Y) > 10))) { if(!(_onUnexpectedMousePos == null || await _onUnexpectedMousePos())) throw new ExportingInterruptedException("Export interrupted, not continuing"); if((_info = await ExportingHelper.EnsureHearthstoneInForeground(_info)) == null) throw new ExportingInterruptedException("Export interrupted - could not re-focus hearthstone"); await Task.Delay(500); } User32.ClientToScreen(_info.HsHandle, ref clientPoint); Cursor.Position = _previousCursorPos = new Point(clientPoint.X, clientPoint.Y); Log.Debug("Clicking " + Cursor.Position); //mouse down if(SystemInformation.MouseButtonsSwapped) User32.mouse_event((uint)User32.MouseEventFlags.RightDown, 0, 0, 0, UIntPtr.Zero); else User32.mouse_event((uint)User32.MouseEventFlags.LeftDown, 0, 0, 0, UIntPtr.Zero); await Task.Delay(Config.Instance.DeckExportDelay); //mouse up if(SystemInformation.MouseButtonsSwapped)
public static async Task SetDeckName(Deck deck, ExportingInfo info) { if (Config.Instance.ExportSetDeckName && !deck.TagList.ToLower().Contains("brawl")) { var name = deck.Name; if (Config.Instance.ExportAddDeckVersionToName) { name += " " + deck.SelectedVersion.ShortVersionString; } Logger.WriteLine("Setting deck name...", "DeckExporter"); var nameDeckPos = new Point((int)Helper.GetScaledXPos(Config.Instance.ExportNameDeckX, info.HsRect.Width, info.Ratio), (int)(Config.Instance.ExportNameDeckY * info.HsRect.Height)); await MouseActions.ClickOnPoint(info.HsHandle, nameDeckPos); //send enter and second click to make sure the current name gets selected SendKeys.SendWait("{ENTER}"); await MouseActions.ClickOnPoint(info.HsHandle, nameDeckPos); if (Config.Instance.ExportPasteClipboard) { Clipboard.SetText(name); SendKeys.SendWait("^v"); } else { SendKeys.SendWait(name); } SendKeys.SendWait("{ENTER}"); } }
public static async Task SetDeckName(Deck deck, ExportingInfo info) { if(Config.Instance.ExportSetDeckName && !deck.TagList.ToLower().Contains("brawl")) { var name = Regex.Replace(deck.Name, @"[\(\)\{\}]", ""); if(name != deck.Name) Logger.WriteLine("Removed parenthesis/braces from deck name. New name: " + name, "DeckExporter"); if(Config.Instance.ExportAddDeckVersionToName) { var version = " " + deck.SelectedVersion.ShortVersionString; if(name.Length + version.Length > MaxLengthDeckName) name = name.Substring(0, MaxLengthDeckName - version.Length); name += version; } Logger.WriteLine("Setting deck name...", "DeckExporter"); var nameDeckPos = new Point((int)Helper.GetScaledXPos(Config.Instance.ExportNameDeckX, info.HsRect.Width, info.Ratio), (int)(Config.Instance.ExportNameDeckY * info.HsRect.Height)); await ClickOnPoint(info.HsHandle, nameDeckPos); //send enter and second click to make sure the current name gets selected SendKeys.SendWait("{ENTER}"); await ClickOnPoint(info.HsHandle, nameDeckPos); if(Config.Instance.ExportPasteClipboard) { Clipboard.SetText(name); SendKeys.SendWait("^v"); } else SendKeys.SendWait(name); SendKeys.SendWait("{ENTER}"); } }
/// <summary> /// Returns true if Hearthstone lost focus in the process /// </summary> public static async Task <bool> CreateDeck(Deck deck, ExportingInfo info) { Log.Info("Creating deck..."); deck.MissingCards.Clear(); foreach (var card in deck.Cards.ToSortedCardList()) { var missingCardsCount = await AddCardToDeck(card, info); if (missingCardsCount < 0) { return(true); } if (missingCardsCount > 0) { var missingCard = (Card)card.Clone(); missingCard.Count = missingCardsCount; deck.MissingCards.Add(missingCard); } } Log.Info(deck.MissingCards.Count + " missing cards"); if (deck.MissingCards.Any()) { DeckList.Save(); } return(false); }
public static async Task ClearFilters(ExportingInfo info) { if (!Config.Instance.EnableExportAutoFilter) { return; } await ClearManaFilter(info); await ClearSetsFilter(info); }
public static async Task<bool> Export(Deck deck) { if(deck == null) return false; var currentClipboard = ""; var altScreenCapture = Config.Instance.AlternativeScreenCapture; try { Log.Info("Exporting " + deck.GetDeckInfo()); if(Config.Instance.ExportPasteClipboard && Clipboard.ContainsText()) currentClipboard = Clipboard.GetText(); var info = new ExportingInfo(); LogDebugInfo(info); var inForeground = await ExportingHelper.EnsureHearthstoneInForeground(info.HsHandle); if(!inForeground) return false; Log.Info($"Waiting for {Config.Instance.ExportStartDelay} seconds before starting the export process"); await Task.Delay(Config.Instance.ExportStartDelay * 1000); if(!altScreenCapture) Core.Overlay.ForceHide(true); await ClearDeck(info); await SetDeckName(deck, info); await ClearFilters(info); var lostFocus = await CreateDeck(deck, info); if(lostFocus) return false; await ClearSearchBox(info.HsHandle, info.SearchBoxPos); if(Config.Instance.ExportPasteClipboard) Clipboard.Clear(); Log.Info("Success exporting deck."); return true; } catch(Exception e) { Log.Error("Error exporting deck: " + e); return false; } finally { if(!altScreenCapture) Core.Overlay.ForceHide(false); try { if(Config.Instance.ExportPasteClipboard && currentClipboard != "") Clipboard.SetText(currentClipboard); } catch(Exception ex) { Log.Error("Could not restore clipboard content after export: " + ex); } } }
private static void LogDebugInfo(ExportingInfo info) { Logger.WriteLine( string.Format( "HsHandle={0} HsRect={1} Ratio={2} SearchBoxPosX={3} SearchBoxPosY={4} CardPosX={5} Card2PosX={6} CardPosY={7} ExportPasteClipboard={8} ExportNameDeckX={9} ExportNameDeckY={10} PrioritizeGolden={11} DeckExportDelay={12} EnableExportAutoFilter={13} ExportZeroButtonX={14} ExportZeroButtonY={15}", info.HsHandle, info.HsRect, info.Ratio, Config.Instance.ExportSearchBoxX, Config.Instance.ExportSearchBoxY, Config.Instance.ExportCard1X, Config.Instance.ExportCard2X, Config.Instance.ExportCardsY, Config.Instance.ExportPasteClipboard, Config.Instance.ExportNameDeckX, Config.Instance.ExportNameDeckY, Config.Instance.PrioritizeGolden, Config.Instance.DeckExportDelay, Config.Instance.EnableExportAutoFilter, Config.Instance.ExportZeroButtonX, Config.Instance.ExportZeroButtonY), "DeckExporter"); }
public static async Task<bool> Export(Deck deck, Func<Task<bool>> onInterrupt) { if(deck == null) return false; var currentClipboard = ""; try { Log.Info("Exporting " + deck.GetDeckInfo()); if(Config.Instance.ExportPasteClipboard && Clipboard.ContainsText()) currentClipboard = Clipboard.GetText(); var info = new ExportingInfo(); LogDebugInfo(info); info = await ExportingHelper.EnsureHearthstoneInForeground(info); if(info == null) return false; LogDebugInfo(info); Log.Info($"Waiting for {Config.Instance.ExportStartDelay} seconds before starting the export process"); await Task.Delay(Config.Instance.ExportStartDelay*1000); var exporter = new ExportingActions(info, deck, onInterrupt); await exporter.ClearDeck(); await exporter.SetDeckName(); await exporter.ClearFilters(); await exporter.CreateDeck(); await exporter.ClearSearchBox(); if(Config.Instance.ExportPasteClipboard) Clipboard.Clear(); Log.Info("Success exporting deck."); return true; } catch(ExportingInterruptedException e) { Log.Warn(e.Message); return false; } catch(Exception e) { Log.Error("Error exporting deck: " + e); return false; } finally { try { if(Config.Instance.ExportPasteClipboard && currentClipboard != "") Clipboard.SetText(currentClipboard); } catch(Exception ex) { Log.Error("Could not restore clipboard content after export: " + ex); } } }
public ExportingActions(ExportingInfo info, Deck deck, Func <Task <bool> > onInterrupt) { _info = info; _deck = deck; _mouse = new MouseActions(info, onInterrupt); _clearCardPoint = new Point(GetScaledXPos(Config.Instance.ExportClearX), GetYPos(Config.Instance.ExportClearY)); _deckNamePoint = new Point(GetScaledXPos(Config.Instance.ExportNameDeckX), GetYPos(Config.Instance.ExportNameDeckY)); _card1Point = new Point((int)_info.CardPosX + CardPosOffset, (int)_info.CardPosY + CardPosOffset); _card2Point = new Point((int)_info.Card2PosX + CardPosOffset, (int)_info.CardPosY + CardPosOffset); _zeroManaCrystalPoint = new Point(GetScaledXPos(Config.Instance.ExportZeroButtonX), GetYPos(Config.Instance.ExportZeroButtonY)); _setFilterMenuPoint = new Point(GetScaledXPos(Config.Instance.ExportSetsButtonX), GetYPos(Config.Instance.ExportSetsButtonY)); _setFilterAllPoint = new Point(GetScaledXPos(Config.Instance.ExportAllSetsButtonX), GetYPos(Config.Instance.ExportStandardSetButtonY)); }
public static async Task ClearDeck(ExportingInfo info) { if(!Config.Instance.AutoClearDeck) return; var count = 0; Logger.WriteLine("Clearing deck...", "DeckExporter"); while(!IsDeckEmpty(info.HsHandle, info.HsRect.Width, info.HsRect.Height, info.Ratio)) { await ClickOnPoint(info.HsHandle, new Point((int)Helper.GetScaledXPos(Config.Instance.ExportClearX, info.HsRect.Width, info.Ratio), (int)(Config.Instance.ExportClearY * info.HsRect.Height))); if(count++ > 35) break; } }
public static async Task <ExportingInfo> EnsureHearthstoneInForeground(ExportingInfo info) { if (User32.IsHearthstoneInForeground()) { return(info); } User32.ShowWindow(info.HsHandle, User32.GetHearthstoneWindowState() == WindowState.Minimized ? User32.SwRestore : User32.SwShow); User32.SetForegroundWindow(info.HsHandle); await Task.Delay(500); if (User32.IsHearthstoneInForeground()) { return(new ExportingInfo()); } Core.MainWindow.ShowMessage("Exporting error", "Can't find Hearthstone window.").Forget(); Log.Error("Can't find Hearthstone window."); return(null); }
public static async Task Export(Deck deck) { if(deck == null) return; var currentClipboard = ""; try { Logger.WriteLine("Exporting " + deck.GetDeckInfo(), "DeckExporter"); if(Config.Instance.ExportPasteClipboard && Clipboard.ContainsText()) currentClipboard = Clipboard.GetText(); var info = new ExportingInfo(); LogDebugInfo(info); var inForeground = await ExportingHelper.EnsureHearthstoneInForeground(info.HsHandle); if(!inForeground) return; Logger.WriteLine($"Waiting for {Config.Instance.ExportStartDelay} seconds before starting the export process", "DeckExporter"); await Task.Delay(Config.Instance.ExportStartDelay * 1000); Core.Overlay.ForceHide(true); await ClearDeck(info); await SetDeckName(deck, info); await ClearFilters(info); var lostFocus = await CreateDeck(deck, info); if(lostFocus) return; await ClearSearchBox(info.HsHandle, info.SearchBoxPos); if(Config.Instance.ExportPasteClipboard) Clipboard.Clear(); Logger.WriteLine("Success exporting deck.", "DeckExporter"); } catch(Exception e) { Logger.WriteLine("Error exporting deck: " + e, "DeckExporter"); } finally { Core.Overlay.ForceHide(false); if(Config.Instance.ExportPasteClipboard && currentClipboard != "") Clipboard.SetText(currentClipboard); } }
public static async Task ClearSetsFilter(ExportingInfo info) { Logger.WriteLine("Clearing set filter...", "DeckExporter"); // Then ensure "All Sets" is selected var setsPoint = new Point((int)Helper.GetScaledXPos(Config.Instance.ExportSetsButtonX, info.HsRect.Width, info.Ratio), (int)(Config.Instance.ExportSetsButtonY * info.HsRect.Height)); // open sets menu await MouseActions.ClickOnPoint(info.HsHandle, setsPoint); // select "All Sets" await MouseActions.ClickOnPoint(info.HsHandle, new Point((int)Helper.GetScaledXPos(Config.Instance.ExportAllSetsButtonX, info.HsRect.Width, info.Ratio), (int)(Config.Instance.ExportAllSetsButtonY *info.HsRect.Height))); // close sets menu await MouseActions.ClickOnPoint(info.HsHandle, setsPoint); }
public static async Task ClearManaFilter(ExportingInfo info) { Log.Info("Clearing \"Zero\" crystal..."); // First, ensure mana filters are cleared var crystalPoint = new Point((int)Helper.GetScaledXPos(Config.Instance.ExportZeroButtonX, info.HsRect.Width, info.Ratio), (int)(Config.Instance.ExportZeroButtonY * info.HsRect.Height)); if (await IsZeroCrystalSelected(info.HsHandle, info.Ratio, info.HsRect.Width, info.HsRect.Height)) { // deselect it await ClickOnPoint(info.HsHandle, crystalPoint); } else { // select it and then unselect it (in case other crystals are on) await ClickOnPoint(info.HsHandle, crystalPoint); await ClickOnPoint(info.HsHandle, crystalPoint); } }
public static async Task SetDeckName(Deck deck, ExportingInfo info) { if (Config.Instance.ExportSetDeckName && !deck.TagList.ToLower().Contains("brawl")) { var name = Regex.Replace(deck.Name, @"[\(\)\{\}]", ""); if (name != deck.Name) { Log.Info("Removed parenthesis/braces from deck name. New name: " + name); } if (Config.Instance.ExportAddDeckVersionToName) { var version = " " + deck.SelectedVersion.ShortVersionString; if (name.Length + version.Length > MaxLengthDeckName) { name = name.Substring(0, MaxLengthDeckName - version.Length); } name += version; } Log.Info("Setting deck name..."); var nameDeckPos = new Point((int)Helper.GetScaledXPos(Config.Instance.ExportNameDeckX, info.HsRect.Width, info.Ratio), (int)(Config.Instance.ExportNameDeckY * info.HsRect.Height)); await ClickOnPoint(info.HsHandle, nameDeckPos); //send enter and second click to make sure the current name gets selected SendKeys.SendWait("{ENTER}"); await ClickOnPoint(info.HsHandle, nameDeckPos); if (Config.Instance.ExportPasteClipboard) { Clipboard.SetText(name); SendKeys.SendWait("^v"); } else { SendKeys.SendWait(name); } SendKeys.SendWait("{ENTER}"); } }
public static async Task ClearDeck(ExportingInfo info) { if (!Config.Instance.AutoClearDeck) { return; } var count = 0; Log.Info("Clearing deck..."); while (!await IsDeckEmpty(info.HsHandle, info.HsRect.Width, info.HsRect.Height, info.Ratio)) { await ClickOnPoint(info.HsHandle, new Point((int)Helper.GetScaledXPos(Config.Instance.ExportClearX, info.HsRect.Width, info.Ratio), (int)(Config.Instance.ExportClearY *info.HsRect.Height))); if (count++ > 35) { break; } } }
public static async Task ClearSetsFilter(ExportingInfo info) { Log.Info("Clearing set filter..."); // Then ensure "All Sets" is selected var setsPoint = new Point((int)Helper.GetScaledXPos(Config.Instance.ExportSetsButtonX, info.HsRect.Width, info.Ratio), (int)(Config.Instance.ExportSetsButtonY * info.HsRect.Height)); // open sets menu await ClickOnPoint(info.HsHandle, setsPoint); await Task.Delay(100); // select "All Sets" await ClickOnPoint(info.HsHandle, new Point( (int)Helper.GetScaledXPos(Config.Instance.ExportAllSetsButtonX, info.HsRect.Width, info.Ratio), (int)(Config.Instance.ExportStandardSetButtonY *info.HsRect.Height))); await Task.Delay(100); // close sets menu await ClickOnPoint(info.HsHandle, setsPoint); }
public static async Task <bool> Export(Deck deck, Func <Task <bool> > onInterrupt) { if (deck == null) { return(false); } var currentClipboard = ""; try { Log.Info("Exporting " + deck.GetDeckInfo()); if (Config.Instance.ExportPasteClipboard && Clipboard.ContainsText()) { currentClipboard = Clipboard.GetText(); } var info = new ExportingInfo(); LogDebugInfo(info); info = await ExportingHelper.EnsureHearthstoneInForeground(info); if (info == null) { return(false); } LogDebugInfo(info); Log.Info($"Waiting for {Config.Instance.ExportStartDelay} seconds before starting the export process"); await Task.Delay(Config.Instance.ExportStartDelay *1000); var exporter = new ExportingActions(info, deck, onInterrupt); await exporter.ClearDeck(); await exporter.SetDeckName(); await exporter.ClearFilters(); await exporter.CreateDeck(); await exporter.ClearSearchBox(); if (Config.Instance.ExportPasteClipboard) { Clipboard.Clear(); } Log.Info("Success exporting deck."); return(true); } catch (ExportingInterruptedException e) { Log.Warn(e.Message); return(false); } catch (Exception e) { Log.Error("Error exporting deck: " + e); return(false); } finally { try { if (Config.Instance.ExportPasteClipboard && currentClipboard != "") { Clipboard.SetText(currentClipboard); } } catch (Exception ex) { Log.Error("Could not restore clipboard content after export: " + ex); } } }
private static void LogDebugInfo(ExportingInfo info) => Log.Debug($"HsHandle={info.HsHandle} HsRect={info.HsRect} Ratio={info.Ratio} SearchBoxPosX={Config.Instance.ExportSearchBoxX} SearchBoxPosY={Config.Instance.ExportSearchBoxY} CardPosX={Config.Instance.ExportCard1X} Card2PosX={Config.Instance.ExportCard2X} CardPosY={Config.Instance.ExportCardsY} ExportPasteClipboard={Config.Instance.ExportPasteClipboard} ExportNameDeckX={Config.Instance.ExportNameDeckX} ExportNameDeckY={Config.Instance.ExportNameDeckY} PrioritizeGolden={Config.Instance.PrioritizeGolden} DeckExportDelay={Config.Instance.DeckExportDelay} EnableExportAutoFilter={Config.Instance.EnableExportAutoFilter} ExportZeroButtonX={Config.Instance.ExportZeroButtonX} ExportZeroButtonY={Config.Instance.ExportZeroButtonY} ForceClear={Config.Instance.ExportForceClear}");
public static async Task <bool> Export(Deck deck) { if (deck == null) { return(false); } var currentClipboard = ""; var altScreenCapture = Config.Instance.AlternativeScreenCapture; try { Log.Info("Exporting " + deck.GetDeckInfo()); if (Config.Instance.ExportPasteClipboard && Clipboard.ContainsText()) { currentClipboard = Clipboard.GetText(); } var info = new ExportingInfo(); LogDebugInfo(info); var inForeground = await ExportingHelper.EnsureHearthstoneInForeground(info.HsHandle); if (!inForeground) { return(false); } Log.Info($"Waiting for {Config.Instance.ExportStartDelay} seconds before starting the export process"); await Task.Delay(Config.Instance.ExportStartDelay * 1000); if (!altScreenCapture) { Core.Overlay.ForceHide(true); } await ClearDeck(info); await SetDeckName(deck, info); await ClearFilters(info); var lostFocus = await CreateDeck(deck, info); if (lostFocus) { return(false); } await ClearSearchBox(info.HsHandle, info.SearchBoxPos); if (Config.Instance.ExportPasteClipboard) { Clipboard.Clear(); } Log.Info("Success exporting deck."); return(true); } catch (Exception e) { Log.Error("Error exporting deck: " + e); return(false); } finally { if (!altScreenCapture) { Core.Overlay.ForceHide(false); } if (Config.Instance.ExportPasteClipboard && currentClipboard != "") { Clipboard.SetText(currentClipboard); } } }
///<summary> /// Returns -1 if Hearthstone loses focus /// </summary> public static async Task<int> AddCardToDeck(Card card, ExportingInfo info) { if(!User32.IsHearthstoneInForeground()) { Core.MainWindow.ShowMessage("Exporting aborted", "Hearthstone window lost focus.").Forget(); Logger.WriteLine("Exporting aborted, window lost focus", "DeckExporter"); return -1; } if(Config.Instance.ExportForceClear) await ClearSearchBox(info.HsHandle, info.SearchBoxPos); await ClickOnPoint(info.HsHandle, info.SearchBoxPos); if(Config.Instance.ExportPasteClipboard) { Clipboard.SetText(GetSearchString(card)); SendKeys.SendWait("^v"); } else SendKeys.SendWait(GetSearchString(card)); SendKeys.SendWait("{ENTER}"); Logger.WriteLine("try to export card: " + card, "DeckExporter"); await Task.Delay(Config.Instance.DeckExportDelay * 2); if(await CheckForSpecialCases(card, info.CardPosX + 50, info.Card2PosX + 50, info.CardPosY + 50, info.HsHandle)) return 0; //Check if Card exist in collection if(CardExists(info.HsHandle, (int)info.CardPosX, (int)info.CardPosY, info.HsRect.Width, info.HsRect.Height)) { //Check if a golden exist if(Config.Instance.PrioritizeGolden && CardExists(info.HsHandle, (int)info.Card2PosX, (int)info.CardPosY, info.HsRect.Width, info.HsRect.Height)) { await ClickOnPoint(info.HsHandle, new Point((int)info.Card2PosX + 50, (int)info.CardPosY + 50)); if(card.Count == 2) { await ClickOnPoint(info.HsHandle, new Point((int)info.Card2PosX + 50, (int)info.CardPosY + 50)); await ClickOnPoint(info.HsHandle, new Point((int)info.CardPosX + 50, (int)info.CardPosY + 50)); } } else { await ClickOnPoint(info.HsHandle, new Point((int)info.CardPosX + 50, (int)info.CardPosY + 50)); if(card.Count == 2) { //Check if two card are not available await Task.Delay(200 - Config.Instance.DeckExportDelay); if(CardHasLock(info.HsHandle, (int)(info.CardPosX + info.HsRect.Width * 0.048), (int)(info.CardPosY + info.HsRect.Height * 0.287), info.HsRect.Width, info.HsRect.Height)) { if(CardExists(info.HsHandle, (int)info.Card2PosX, (int)info.CardPosY, info.HsRect.Width, info.HsRect.Height)) { await ClickOnPoint(info.HsHandle, new Point((int)info.Card2PosX + 50, (int)info.CardPosY + 50)); return 0; } Logger.WriteLine("Only one copy found: " + card.Name, "DeckExporter"); return 1; } await ClickOnPoint(info.HsHandle, new Point((int)info.CardPosX + 50, (int)info.CardPosY + 50)); } } } else return card.Count; return 0; }
public static async Task ClearSetsFilter(ExportingInfo info) { Logger.WriteLine("Clearing set filter...", "DeckExporter"); // Then ensure "All Sets" is selected var setsPoint = new Point((int)Helper.GetScaledXPos(Config.Instance.ExportSetsButtonX, info.HsRect.Width, info.Ratio), (int)(Config.Instance.ExportSetsButtonY * info.HsRect.Height)); // open sets menu await ClickOnPoint(info.HsHandle, setsPoint); // select "All Sets" await ClickOnPoint(info.HsHandle, new Point( (int)Helper.GetScaledXPos(Config.Instance.ExportAllSetsButtonX, info.HsRect.Width, info.Ratio), (int)(Config.Instance.ExportAllSetsButtonY * info.HsRect.Height))); // close sets menu await ClickOnPoint(info.HsHandle, setsPoint); }
{ private ExportingInfo _info; private readonly Func<Task<bool>> _onUnexpectedMousePos;
public static async Task ClearManaFilter(ExportingInfo info) { Logger.WriteLine("Clearing \"Zero\" crystal...", "DeckExporter"); // First, ensure mana filters are cleared var crystalPoint = new Point((int)Helper.GetScaledXPos(Config.Instance.ExportZeroButtonX, info.HsRect.Width, info.Ratio), (int)(Config.Instance.ExportZeroButtonY * info.HsRect.Height)); if(IsZeroCrystalSelected(info.HsHandle, info.Ratio, info.HsRect.Width, info.HsRect.Height)) { // deselect it await ClickOnPoint(info.HsHandle, crystalPoint); } else { // select it and then unselect it (in case other crystals are on) await ClickOnPoint(info.HsHandle, crystalPoint); await ClickOnPoint(info.HsHandle, crystalPoint); } }
public static async Task ClearFilters(ExportingInfo info) { if(!Config.Instance.EnableExportAutoFilter) return; await ClearManaFilter(info); await ClearSetsFilter(info); }
/// <summary> /// Returns true if Hearthstone lost focus in the process /// </summary> public static async Task<bool> CreateDeck(Deck deck, ExportingInfo info) { Logger.WriteLine("Creating deck...", "DeckExporter"); deck.MissingCards.Clear(); foreach(var card in deck.Cards.ToSortedCardList()) { var missingCardsCount = await AddCardToDeck(card, info); if(missingCardsCount < 0) return true; if(missingCardsCount > 0) { var missingCard = (Card)card.Clone(); missingCard.Count = missingCardsCount; deck.MissingCards.Add(missingCard); } } Logger.WriteLine(deck.MissingCards.Count + " missing cards", "DeckExporter"); if(deck.MissingCards.Any()) DeckList.Save(); return false; }
///<summary> /// Returns -1 if Hearthstone loses focus /// </summary> public static async Task <int> AddCardToDeck(Card card, ExportingInfo info) { if (!User32.IsHearthstoneInForeground()) { Core.MainWindow.ShowMessage("Exporting aborted", "Hearthstone window lost focus.").Forget(); Log.Info("Exporting aborted, window lost focus"); return(-1); } if (Config.Instance.ExportForceClear) { await ClearSearchBox(info.HsHandle, info.SearchBoxPos); } await ClickOnPoint(info.HsHandle, info.SearchBoxPos); if (Config.Instance.ExportPasteClipboard) { Clipboard.SetText(GetSearchString(card)); SendKeys.SendWait("^v"); } else { SendKeys.SendWait(GetSearchString(card)); } SendKeys.SendWait("{ENTER}"); Log.Info("try to export card: " + card); await Task.Delay(Config.Instance.DeckExportDelay * 2); if (await CheckForSpecialCases(card, info.CardPosX + 50, info.Card2PosX + 50, info.CardPosY + 50, info.HsHandle)) { return(0); } //Check if Card exist in collection var cardExists = await CardExists(info.HsHandle, (int)info.CardPosX, (int)info.CardPosY, info.HsRect.Width, info.HsRect.Height); if (cardExists) { //Check if a golden exist if (Config.Instance.PrioritizeGolden && await CardExists(info.HsHandle, (int)info.Card2PosX, (int)info.CardPosY, info.HsRect.Width, info.HsRect.Height)) { await ClickOnPoint(info.HsHandle, new Point((int)info.Card2PosX + 50, (int)info.CardPosY + 50)); if (card.Count == 2) { await ClickOnPoint(info.HsHandle, new Point((int)info.Card2PosX + 50, (int)info.CardPosY + 50)); await ClickOnPoint(info.HsHandle, new Point((int)info.CardPosX + 50, (int)info.CardPosY + 50)); } } else { await ClickOnPoint(info.HsHandle, new Point((int)info.CardPosX + 50, (int)info.CardPosY + 50)); if (card.Count == 2) { //Check if two card are not available await Task.Delay(200 - Config.Instance.DeckExportDelay); if (await CardHasLock(info.HsHandle, (int)(info.CardPosX + info.HsRect.Width * 0.048), (int)(info.CardPosY + info.HsRect.Height * 0.287), info.HsRect.Width, info.HsRect.Height)) { var card2Exists = await CardExists(info.HsHandle, (int)info.Card2PosX, (int)info.CardPosY, info.HsRect.Width, info.HsRect.Height); if (card2Exists) { await ClickOnPoint(info.HsHandle, new Point((int)info.Card2PosX + 50, (int)info.CardPosY + 50)); return(0); } Log.Info("Only one copy found: " + card.Name); return(1); } await ClickOnPoint(info.HsHandle, new Point((int)info.CardPosX + 50, (int)info.CardPosY + 50)); } } } else { return(card.Count); } return(0); }
public static async Task Export(Deck deck) { if (deck == null) { return; } var currentClipboard = ""; try { Logger.WriteLine("Exporting " + deck.GetDeckInfo(), "DeckExporter"); if (Config.Instance.ExportPasteClipboard && Clipboard.ContainsText()) { currentClipboard = Clipboard.GetText(); } var info = new ExportingInfo(); LogDebugInfo(info); var inForeground = await ExportingHelper.EnsureHearthstoneInForeground(info.HsHandle); if (!inForeground) { return; } Logger.WriteLine("Waiting for " + Config.Instance.ExportStartDelay + " seconds before starting the export process", "DeckExporter"); await Task.Delay(Config.Instance.ExportStartDelay * 1000); Core.Overlay.ForceHide(true); await ExportingActions.ClearDeck(info); await ExportingActions.SetDeckName(deck, info); await ExportingActions.ClearFilters(info); var lostFocus = await ExportingActions.CreateDeck(deck, info); if (lostFocus) { return; } await ExportingActions.ClearSearchBox(info.HsHandle, info.SearchBoxPos); if (Config.Instance.ExportPasteClipboard) { Clipboard.Clear(); } Logger.WriteLine("Success exporting deck.", "DeckExporter"); } catch (Exception e) { Logger.WriteLine("Error exporting deck: " + e, "DeckExporter"); } finally { Core.Overlay.ForceHide(false); if (Config.Instance.ExportPasteClipboard && currentClipboard != "") { Clipboard.SetText(currentClipboard); } } }
private static void LogDebugInfo(ExportingInfo info) { Logger.WriteLine( $"HsHandle={info.HsHandle} HsRect={info.HsRect} Ratio={info.Ratio} SearchBoxPosX={Config.Instance.ExportSearchBoxX} SearchBoxPosY={Config.Instance.ExportSearchBoxY} CardPosX={Config.Instance.ExportCard1X} Card2PosX={Config.Instance.ExportCard2X} CardPosY={Config.Instance.ExportCardsY} ExportPasteClipboard={Config.Instance.ExportPasteClipboard} ExportNameDeckX={Config.Instance.ExportNameDeckX} ExportNameDeckY={Config.Instance.ExportNameDeckY} PrioritizeGolden={Config.Instance.PrioritizeGolden} DeckExportDelay={Config.Instance.DeckExportDelay} EnableExportAutoFilter={Config.Instance.EnableExportAutoFilter} ExportZeroButtonX={Config.Instance.ExportZeroButtonX} ExportZeroButtonY={Config.Instance.ExportZeroButtonY} ForceClear={Config.Instance.ExportForceClear}", "DeckExporter"); }
public static async Task<ExportingInfo> EnsureHearthstoneInForeground(ExportingInfo info) { if(User32.IsHearthstoneInForeground()) return info; User32.ShowWindow(info.HsHandle, User32.GetHearthstoneWindowState() == WindowState.Minimized ? User32.SwRestore : User32.SwShow); User32.SetForegroundWindow(info.HsHandle); await Task.Delay(500); if(User32.IsHearthstoneInForeground()) return new ExportingInfo(); Core.MainWindow.ShowMessage("Exporting error", "Can't find Hearthstone window.").Forget(); Log.Error("Can't find Hearthstone window."); return null; }