diff --git a/Lurker.Test/Events/TradeEventTest.cs b/Lurker.Test/Events/TradeEventTest.cs index 19939425..beb287c2 100644 --- a/Lurker.Test/Events/TradeEventTest.cs +++ b/Lurker.Test/Events/TradeEventTest.cs @@ -114,6 +114,18 @@ public void TryParse_NoLocation() this.AssertLocation(new Location(), tradeEvent.Location); } + [TestMethod] + public void TryParse_NoStashTabName() + { + var line = $"{BaseLogLine} {ItemName} {Price} {League} (stash tab ; position: left 10, top 2)"; + var tradeEvent = TradeEvent.TryParse(line); + + Assert.AreEqual(PlayerName, tradeEvent.PlayerName); + Assert.AreEqual(ItemName, tradeEvent.ItemName); + this.AssertPrice(this.ExpectedPrice, tradeEvent.Price); + this.AssertLocation(new Location() { Top = 2, Left = 10, StashTabName = string.Empty }, tradeEvent.Location); + } + private void AssertPrice(Price expectedPrice, Price actualPrice) { Assert.AreEqual(expectedPrice.NumberOfCurrencies, actualPrice.NumberOfCurrencies); diff --git a/src/Lurker.Console/Lurker.Console.csproj b/src/Lurker.Console/Lurker.Console.csproj index 65553499..11af5b9d 100644 --- a/src/Lurker.Console/Lurker.Console.csproj +++ b/src/Lurker.Console/Lurker.Console.csproj @@ -37,8 +37,8 @@ ..\..\packages\ConfOxide.1.4.2.0\lib\net40\ConfOxide.dll - - ..\..\packages\Lurker.Patreon.1.0.0\lib\net48\Lurker.Patreon.dll + + ..\..\packages\Lurker.Patreon.1.0.1\lib\net48\Lurker.Patreon.dll ..\..\packages\Microsoft.Owin.2.0.2\lib\net45\Microsoft.Owin.dll diff --git a/src/Lurker.Console/packages.config b/src/Lurker.Console/packages.config index d5f92656..bb699fb2 100644 --- a/src/Lurker.Console/packages.config +++ b/src/Lurker.Console/packages.config @@ -1,7 +1,7 @@  - + diff --git a/src/Lurker.UI/Lurker.UI.csproj b/src/Lurker.UI/Lurker.UI.csproj index 6ca36b96..83f9a9d2 100644 --- a/src/Lurker.UI/Lurker.UI.csproj +++ b/src/Lurker.UI/Lurker.UI.csproj @@ -72,8 +72,8 @@ ..\..\packages\Hardcodet.NotifyIcon.Wpf.1.0.8\lib\net451\Hardcodet.Wpf.TaskbarNotification.dll - - ..\..\packages\Lurker.Patreon.1.0.0\lib\net48\Lurker.Patreon.dll + + ..\..\packages\Lurker.Patreon.1.0.1\lib\net48\Lurker.Patreon.dll ..\..\packages\MahApps.Metro.1.6.5\lib\net47\MahApps.Metro.dll diff --git a/src/Lurker.UI/ViewModels/SettingsViewModel.cs b/src/Lurker.UI/ViewModels/SettingsViewModel.cs index 74e5c0ab..dc13cda4 100644 --- a/src/Lurker.UI/ViewModels/SettingsViewModel.cs +++ b/src/Lurker.UI/ViewModels/SettingsViewModel.cs @@ -342,7 +342,17 @@ public async void LoginToPatreon() { using (this._currentPatreonService = new Patreon.PatreonService()) { + if (!this._currentPatreonService.IsConnected) + { + await this._currentPatreonService.Login(); + } + this.Pledging = await this._currentPatreonService.IsPledging(); + if (this.Pledging) + { + this.SearchEnabled = true; + } + this.NotifyOfPropertyChange("NotConnected"); } } @@ -395,10 +405,6 @@ protected async override void OnActivate() using (var service = new Patreon.PatreonService()) { this.Pledging = await service.IsPledging(); - if (!this.Pledging) - { - this._settingService.SearchEnabled = false; - } } } else @@ -406,6 +412,11 @@ protected async override void OnActivate() this.Pledging = false; } + if (!this.Pledging) + { + this.SearchEnabled = false; + } + this.AlertVolume = (int)(this._settingService.AlertVolume * 100); this.CheckForUpdate(); base.OnActivate(); diff --git a/src/Lurker.UI/packages.config b/src/Lurker.UI/packages.config index f6826a8e..9803fe27 100644 --- a/src/Lurker.UI/packages.config +++ b/src/Lurker.UI/packages.config @@ -7,7 +7,7 @@ - + diff --git a/src/Lurker/ClipboardLurker.cs b/src/Lurker/ClipboardLurker.cs index fb9daa53..137ec08e 100644 --- a/src/Lurker/ClipboardLurker.cs +++ b/src/Lurker/ClipboardLurker.cs @@ -17,9 +17,9 @@ namespace Lurker using System.Threading; using System.Threading.Tasks; using System.Windows; - using System.Windows.Input; using WindowsInput; using WK.Libraries.SharpClipboardNS; + using static Lurker.Native; public class ClipboardLurker: IDisposable { @@ -31,7 +31,7 @@ public class ClipboardLurker: IDisposable private SharpClipboard _clipboardMonitor; private string _lastClipboardText = string.Empty; private IKeyboardMouseEvents _keyboardEvent; - private PatreonService _patreonService; + private bool _isPledging; #endregion @@ -42,18 +42,25 @@ public class ClipboardLurker: IDisposable /// public ClipboardLurker(SettingsService settingsService) { - Clipboard.Clear(); - this._patreonService = new PatreonService(); + this.ClearClipboard(); this._simulator = new InputSimulator(); this._clipboardMonitor = new SharpClipboard(); this._settingsService = settingsService; + this._settingsService.OnSave += this.SettingsService_OnSave; this._keyboardEvent = Hook.GlobalEvents(); this._clipboardMonitor.ClipboardChanged += this.ClipboardMonitor_ClipboardChanged; - #if (!DEBUG) - this._keyboardEvent.MouseClick += this.KeyboardEvent_MouseClick; - #endif +#if (!DEBUG) + this._keyboardEvent.MouseClick += this.KeyboardEvent_MouseClick; +#endif + + var service = new PatreonService(); + service.IsPledging().ContinueWith(t => + { + this._isPledging = t.Result; + service.Dispose(); + }); } #endregion @@ -70,7 +77,7 @@ public ClipboardLurker(SettingsService settingsService) /// public event EventHandler NewOffer; -#endregion + #endregion #region Methods @@ -90,9 +97,23 @@ protected virtual void Dispose(bool disposing) { if (disposing) { - this._patreonService.Dispose(); this._keyboardEvent.Dispose(); this._clipboardMonitor.ClipboardChanged -= ClipboardMonitor_ClipboardChanged; + this._settingsService.OnSave -= this.SettingsService_OnSave; + } + } + + + /// + /// Handles the OnSave event of the SettingsService control. + /// + /// The source of the event. + /// The instance containing the event data. + private async void SettingsService_OnSave(object sender, EventArgs e) + { + using (var service = new PatreonService()) + { + this._isPledging = await service.IsPledging(); } } @@ -103,11 +124,16 @@ protected virtual void Dispose(bool disposing) /// The instance containing the event data. private void KeyboardEvent_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e) { - Task.Run(async () => + Task.Run(() => { + if (!this._settingsService.SearchEnabled || !this._isPledging || e.Button != System.Windows.Forms.MouseButtons.Left) + { + return; + } + if (Native.IsKeyPressed(Native.VirtualKeyStates.VK_SHIFT) && Native.IsKeyPressed(Native.VirtualKeyStates.VK_CONTROL)) { - await this.ParseItem(); + this.ParseItem(); } }); } @@ -135,7 +161,6 @@ private string GetClipboardText() Thread.Sleep(200); } } - }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); @@ -144,6 +169,33 @@ private string GetClipboardText() return clipboardText; } + /// + /// Clears the clipboard. + /// + private void ClearClipboard() + { + Thread thread = new Thread(() => + { + var retryCount = 3; + while (retryCount != 0) + { + try + { + Clipboard.Clear(); + break; + } + catch + { + retryCount--; + Thread.Sleep(200); + } + } + }); + thread.SetApartmentState(ApartmentState.STA); + thread.Start(); + thread.Join(); + } + /// /// Handles the ClipboardChanged event of the ClipboardMonitor control. /// @@ -176,26 +228,21 @@ private void ClipboardMonitor_ClipboardChanged(object sender, SharpClipboard.Cli /// /// Parses the item. /// - private async Task ParseItem() + private async void ParseItem() { - if (!this._settingsService.SearchEnabled) - { - return; - } - - if (!await this._patreonService.IsPledging()) - { - return; - } - PoeItem item = default; - - var retryCount = 3; + var retryCount = 2; for (int i = 0; i < retryCount; i++) { item = await this.GetItemInClipboard(); - if (item == null || !item.Identified) + if (item == null) + { + return; + } + + if (!item.Identified) { + await Task.Delay(50); continue; } @@ -208,13 +255,7 @@ private async Task ParseItem() } this.Newitem?.Invoke(this, item); - try - { - Clipboard.Clear(); - } - catch - { - } + this.ClearClipboard(); } /// @@ -224,7 +265,7 @@ private async Task ParseItem() private async Task GetItemInClipboard() { this._simulator.Keyboard.ModifiedKeyStroke(WindowsInput.Native.VirtualKeyCode.CONTROL, WindowsInput.Native.VirtualKeyCode.VK_C); - await Task.Delay(100); + await Task.Delay(20); return this._itemParser.Parse(this.GetClipboardText()); } diff --git a/src/Lurker/Events/TradeEvent.cs b/src/Lurker/Events/TradeEvent.cs index 677670c1..9dbb4334 100644 --- a/src/Lurker/Events/TradeEvent.cs +++ b/src/Lurker/Events/TradeEvent.cs @@ -165,12 +165,16 @@ public Location ParseLocation(string locationValue) } // tab name + var stashTabName = string.Empty; var tabValue = locationValue.GetLineBefore("\";"); - var index = tabValue.IndexOf("\""); - var stashTabName = tabValue.Substring(index + 1); + if (!string.IsNullOrEmpty(tabValue)) + { + var index = tabValue.IndexOf("\""); + stashTabName = tabValue.Substring(index + 1); + } // Position - var positionValue = locationValue.GetLineAfter("\";"); + var positionValue = locationValue.GetLineAfter(";"); var positionIndex = positionValue.IndexOf(PositionMarker); if (positionIndex != -1) diff --git a/src/Lurker/Lurker.csproj b/src/Lurker/Lurker.csproj index 44e67fbd..36175206 100644 --- a/src/Lurker/Lurker.csproj +++ b/src/Lurker/Lurker.csproj @@ -38,8 +38,8 @@ ..\..\packages\MouseKeyHook.5.6.0\lib\net40\Gma.System.MouseKeyHook.dll - - ..\..\packages\Lurker.Patreon.1.0.0\lib\net48\Lurker.Patreon.dll + + ..\..\packages\Lurker.Patreon.1.0.1\lib\net48\Lurker.Patreon.dll ..\..\packages\Microsoft.Owin.2.0.2\lib\net45\Microsoft.Owin.dll diff --git a/src/Lurker/Native.cs b/src/Lurker/Native.cs index 1bb0b310..8b107fa2 100644 --- a/src/Lurker/Native.cs +++ b/src/Lurker/Native.cs @@ -27,6 +27,7 @@ public static bool IsKeyPressed(VirtualKeyStates nVirtKey) } } + public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam); [DllImport("User32.dll")] public static extern short GetKeyState(VirtualKeyStates nVirtKey); @@ -34,6 +35,12 @@ public static bool IsKeyPressed(VirtualKeyStates nVirtKey) [DllImport("User32.dll")] public static extern int SetForegroundWindow(IntPtr point); + [DllImport("user32.dll", SetLastError = true)] + public static extern IntPtr SetWindowsHookEx(HookType hookType, HookProc lpfn, IntPtr hMod, uint dwThreadId); + + [DllImport("user32.dll")] + public static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); + [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow(); @@ -77,6 +84,25 @@ public struct Rect public int Bottom { get; set; } } + public enum HookType : int + { + WH_JOURNALRECORD = 0, + WH_JOURNALPLAYBACK = 1, + WH_KEYBOARD = 2, + WH_GETMESSAGE = 3, + WH_CALLWNDPROC = 4, + WH_CBT = 5, + WH_SYSMSGFILTER = 6, + WH_MOUSE = 7, + WH_HARDWARE = 8, + WH_DEBUG = 9, + WH_SHELL = 10, + WH_FOREGROUNDIDLE = 11, + WH_CALLWNDPROCRET = 12, + WH_KEYBOARD_LL = 13, + WH_MOUSE_LL = 14 + } + public enum VirtualKeyStates : int { VK_LBUTTON = 0x01, diff --git a/src/Lurker/packages.config b/src/Lurker/packages.config index 321a5ae7..04409d51 100644 --- a/src/Lurker/packages.config +++ b/src/Lurker/packages.config @@ -2,7 +2,7 @@ - +