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();
}