From c3f0c85f4312e2709a84e28b1c171d727618f12c Mon Sep 17 00:00:00 2001 From: huiyadanli Date: Wed, 4 Oct 2023 18:01:58 +0800 Subject: [PATCH] Add script --- .../Core/Config/ScriptConfig.cs | 29 ++++ BetterGenshinImpact/Core/MouseKeyMonitor.cs | 156 ++++++++++++++++++ .../{Simulator.cs => MySimulator.cs} | 2 +- .../Core/Simulator/PostMessageSimulator.cs | 37 ++++- .../ViewModel/MainWindowViewModel.cs | 19 +-- 5 files changed, 227 insertions(+), 16 deletions(-) create mode 100644 BetterGenshinImpact/Core/Config/ScriptConfig.cs create mode 100644 BetterGenshinImpact/Core/MouseKeyMonitor.cs rename BetterGenshinImpact/Core/Simulator/{Simulator.cs => MySimulator.cs} (88%) diff --git a/BetterGenshinImpact/Core/Config/ScriptConfig.cs b/BetterGenshinImpact/Core/Config/ScriptConfig.cs new file mode 100644 index 00000000..f7525754 --- /dev/null +++ b/BetterGenshinImpact/Core/Config/ScriptConfig.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BetterGenshinImpact.Core.Config +{ + public class ScriptConfig + { + /// + /// 长按空格变空格连发 + /// + public bool SpacePressHoldToContinuation { get; set; } = true; + /// + /// 空格连发时间间隔 + /// + public int SpaceFireInterval { get; set; } = 50; + + /// + /// 长按F变F连发 + /// + public bool FPressHoldToContinuation { get; set; } = true; + /// + /// F连发时间间隔 + /// + public int FFireInterval { get; set; } = 50; + } +} diff --git a/BetterGenshinImpact/Core/MouseKeyMonitor.cs b/BetterGenshinImpact/Core/MouseKeyMonitor.cs new file mode 100644 index 00000000..15e08d27 --- /dev/null +++ b/BetterGenshinImpact/Core/MouseKeyMonitor.cs @@ -0,0 +1,156 @@ +using BetterGenshinImpact.Core.Simulator; +using Gma.System.MouseKeyHook; +using System; +using System.Diagnostics; +using System.Windows.Forms; +using Vanara.PInvoke; + +namespace BetterGenshinImpact.Core; + +public class MouseKeyMonitor +{ + private IntPtr _hWnd; + + private IKeyboardMouseEvents? _globalHook; + + private readonly Random _random = new(); + + /// + /// 长按空格变空格连发 + /// + private readonly System.Timers.Timer _spaceTimer = new(); + /// + /// 长按F变F连发 + /// + private readonly System.Timers.Timer _fTimer = new(); + + /// + /// DateTime.MaxValue 代表没有按下 + /// + private DateTime _firstSpaceKeyDownTime = DateTime.MaxValue; + private DateTime _firstFKeyDownTime = DateTime.MaxValue; + + public void Subscribe(IntPtr gameHandle) + { + _hWnd = gameHandle; + // Note: for the application hook, use the Hook.AppEvents() instead + _globalHook = Hook.GlobalEvents(); + + + _globalHook.KeyDown += GlobalHookKeyDown; + _globalHook.KeyUp += GlobalHookKeyUp; + //_globalHook.MouseDownExt += GlobalHookMouseDownExt; + //_globalHook.KeyPress += GlobalHookKeyPress; + + _firstSpaceKeyDownTime = DateTime.MaxValue; + _spaceTimer.Interval = 50; + _spaceTimer.Elapsed += (sender, args) => + { + MySimulator.PostMessage(_hWnd).KeyPress(User32.VK.VK_SPACE); + _spaceTimer.Interval = _random.Next(50, 70); + }; + + _fTimer.Interval = 50; + _fTimer.Elapsed += (sender, args) => + { + MySimulator.PostMessage(_hWnd).KeyPress(User32.VK.VK_F); + _fTimer.Interval = _random.Next(50, 70); + }; + } + + + private void GlobalHookKeyDown(object? sender, KeyEventArgs e) + { + //Debug.WriteLine("KeyDown: \t{0}", e.KeyCode); + if (e.KeyCode == Keys.Space) + { + if (_firstSpaceKeyDownTime == DateTime.MaxValue) + { + _firstSpaceKeyDownTime = DateTime.Now; + } + else + { + var timeSpan = DateTime.Now - _firstSpaceKeyDownTime; + if (timeSpan.TotalMilliseconds > 300) + { + if (!_spaceTimer.Enabled) + { + _spaceTimer.Start(); + } + + } + } + } + else if(e.KeyCode == Keys.F) + { + if (_firstFKeyDownTime == DateTime.MaxValue) + { + _firstFKeyDownTime = DateTime.Now; + } + else + { + var timeSpan = DateTime.Now - _firstFKeyDownTime; + if (timeSpan.TotalMilliseconds > 200) + { + if (!_fTimer.Enabled) + { + _fTimer.Start(); + } + + } + } + } + } + + private void GlobalHookKeyUp(object? sender, KeyEventArgs e) + { + //Debug.WriteLine("KeyUp: \t{0}", e.KeyCode); + if (e.KeyCode == Keys.Space) + { + if (_firstSpaceKeyDownTime != DateTime.MaxValue) + { + var timeSpan = DateTime.Now - _firstSpaceKeyDownTime; + Debug.WriteLine($"Space按下时间:{timeSpan.TotalMilliseconds}ms"); + _firstSpaceKeyDownTime = DateTime.MaxValue; + _spaceTimer.Stop(); + + } + } + else if (e.KeyCode == Keys.F) + { + if (_firstFKeyDownTime != DateTime.MaxValue) + { + var timeSpan = DateTime.Now - _firstFKeyDownTime; + Debug.WriteLine($"F按下时间:{timeSpan.TotalMilliseconds}ms"); + _firstFKeyDownTime = DateTime.MaxValue; + _fTimer.Stop(); + + } + } + } + + //private void GlobalHookKeyPress(object? sender, KeyPressEventArgs e) + //{ + // Debug.WriteLine("KeyPress: \t{0}", e.KeyChar); + //} + + //private void GlobalHookMouseDownExt(object? sender, MouseEventExtArgs e) + //{ + // Debug.WriteLine("MouseDown: \t{0}; \t System Timestamp: \t{1}", e.Button, e.Timestamp); + + // // uncommenting the following line will suppress the middle mouse button click + // // if (e.Buttons == MouseButtons.Middle) { e.Handled = true; } + //} + + public void Unsubscribe() + { + if (_globalHook != null) + { + _globalHook.KeyDown -= GlobalHookKeyDown; + _globalHook.KeyUp -= GlobalHookKeyUp; + //_globalHook.MouseDownExt -= GlobalHookMouseDownExt; + //_globalHook.KeyPress -= GlobalHookKeyPress; + _globalHook.Dispose(); + } + } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Core/Simulator/Simulator.cs b/BetterGenshinImpact/Core/Simulator/MySimulator.cs similarity index 88% rename from BetterGenshinImpact/Core/Simulator/Simulator.cs rename to BetterGenshinImpact/Core/Simulator/MySimulator.cs index 5639d1a5..fdab9d6f 100644 --- a/BetterGenshinImpact/Core/Simulator/Simulator.cs +++ b/BetterGenshinImpact/Core/Simulator/MySimulator.cs @@ -2,7 +2,7 @@ namespace BetterGenshinImpact.Core.Simulator; -public class Simulator +public class MySimulator { public static PostMessageSimulator PostMessage(IntPtr hWnd) { diff --git a/BetterGenshinImpact/Core/Simulator/PostMessageSimulator.cs b/BetterGenshinImpact/Core/Simulator/PostMessageSimulator.cs index 24c96eb2..a0acd7df 100644 --- a/BetterGenshinImpact/Core/Simulator/PostMessageSimulator.cs +++ b/BetterGenshinImpact/Core/Simulator/PostMessageSimulator.cs @@ -1,15 +1,22 @@ using System; +using System.Formats.Asn1; using System.Threading; using Vanara.PInvoke; namespace BetterGenshinImpact.Core.Simulator; +/// +/// 虚拟键代码 +/// https://learn.microsoft.com/zh-cn/windows/win32/inputdev/virtual-key-codes +/// User32.VK.VK_SPACE 键盘空格键 +/// public class PostMessageSimulator { public static readonly uint WM_LBUTTONDOWN = 0x201; //按下鼠标左键 public static readonly uint WM_LBUTTONUP = 0x202; //释放鼠标左键 + private readonly IntPtr _hWnd; public PostMessageSimulator(IntPtr hWnd) @@ -22,27 +29,51 @@ public class PostMessageSimulator /// /// /// - public void LeftButtonClick(int x, int y) + public PostMessageSimulator LeftButtonClick(int x, int y) { IntPtr p = (y << 16) | x; User32.PostMessage(_hWnd, WM_LBUTTONDOWN, IntPtr.Zero, p); Thread.Sleep(100); User32.PostMessage(_hWnd, WM_LBUTTONUP, IntPtr.Zero, p); + return this; } /// /// 默认位置左键按下 /// - public void LeftButtonDown() + public PostMessageSimulator LeftButtonDown() { User32.PostMessage(_hWnd, WM_LBUTTONDOWN, IntPtr.Zero); + return this; } /// /// 默认位置左键释放 /// - public void LeftButtonUp() + public PostMessageSimulator LeftButtonUp() { User32.PostMessage(_hWnd, WM_LBUTTONUP, IntPtr.Zero); + return this; + } + + public PostMessageSimulator KeyPress(User32.VK vk) + { + //User32.PostMessage(_hWnd, User32.WindowMessage.WM_ACTIVATE, 1, 0); + User32.PostMessage(_hWnd, User32.WindowMessage.WM_KEYDOWN, (nint)vk, 0x1e0001); + User32.PostMessage(_hWnd, User32.WindowMessage.WM_CHAR, (nint)vk, 0x1e0001); + User32.PostMessage(_hWnd, User32.WindowMessage.WM_KEYUP, (nint)vk, (nint)0xc01e0001); + return this; + } + + public PostMessageSimulator KeyUp(User32.VK vk) + { + User32.PostMessage(_hWnd, User32.WindowMessage.WM_KEYUP, (nint)vk, (nint)0xc01e0001); + return this; + } + + public PostMessageSimulator Sleep(int ms) + { + Thread.Sleep(ms); + return this; } } \ No newline at end of file diff --git a/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs b/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs index 09f745c3..01a58349 100644 --- a/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs +++ b/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging; using System; using System.Diagnostics; using System.Windows; +using BetterGenshinImpact.Core; using CommunityToolkit.Mvvm.Messaging.Messages; using Vanara.PInvoke; @@ -24,20 +25,20 @@ namespace BetterGenshinImpact.ViewModel private MaskWindow? _maskWindow; private readonly ILogger _logger = App.GetLogger(); - private TaskDispatcher _taskDispatcher = new(); - + private readonly TaskDispatcher _taskDispatcher = new(); + private readonly MouseKeyMonitor _mouseKeyMonitor = new(); [RelayCommand] private void OnLoaded() { - //TestMask(); - //TestRect(); - //Debug.WriteLine(DpiHelper.ScaleY); + } [RelayCommand] private void OnClosed() { + _mouseKeyMonitor.Unsubscribe(); + OnStopTrigger(); _maskWindow?.Close(); Application.Current.Shutdown(); } @@ -78,7 +79,7 @@ namespace BetterGenshinImpact.ViewModel MessageBox.Show("未找到原神窗口"); return; } - + _mouseKeyMonitor.Subscribe(hWnd); _maskWindow = MaskWindow.Instance(hWnd); _taskDispatcher.Start(hWnd, SelectedMode.ToCaptureMode()); } @@ -86,12 +87,6 @@ namespace BetterGenshinImpact.ViewModel [RelayCommand] private void OnStopTrigger() { - if (SelectedMode == null) - { - MessageBox.Show("请选择捕获方式"); - return; - } - _maskWindow?.Hide(); _taskDispatcher.Stop(); }