diff --git a/BetterGenshinImpact/Core/Monitor/DirectInputMonitor.cs b/BetterGenshinImpact/Core/Monitor/DirectInputMonitor.cs index d3659ca2..f617f06d 100644 --- a/BetterGenshinImpact/Core/Monitor/DirectInputMonitor.cs +++ b/BetterGenshinImpact/Core/Monitor/DirectInputMonitor.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace BetterGenshinImpact.Core.Monitor; -public class DirectInputMonitor +public class DirectInputMonitor : IDisposable { private bool _isRunning = true; @@ -36,7 +36,7 @@ public class DirectInputMonitor MouseState state = _mouse.GetCurrentState(); // Debug.WriteLine($"{state.X} {state.Y} {state.Buttons[0]} {state.Buttons[1]}"); GlobalKeyMouseRecord.Instance.GlobalHookMouseMoveBy(state); - Thread.Sleep(10); // 10ms, equivalent to CLOCKS_PER_SEC/100 + Thread.Sleep(5); // 10ms, equivalent to CLOCKS_PER_SEC/100 } }); } @@ -45,4 +45,9 @@ public class DirectInputMonitor { _isRunning = false; } + + public void Dispose() + { + _mouse.Dispose(); + } } diff --git a/BetterGenshinImpact/Core/Recorder/DirectInputCalibration.cs b/BetterGenshinImpact/Core/Recorder/DirectInputCalibration.cs index dc8e3ce0..e42930fe 100644 --- a/BetterGenshinImpact/Core/Recorder/DirectInputCalibration.cs +++ b/BetterGenshinImpact/Core/Recorder/DirectInputCalibration.cs @@ -21,6 +21,7 @@ namespace BetterGenshinImpact.Core.Recorder; /// /// DirectInput、鼠标移动距离、视角度数之间的校准 /// +[Obsolete] public class DirectInputCalibration { // 视角偏移移动单位 diff --git a/BetterGenshinImpact/Core/Recorder/GlobalKeyMouseRecord.cs b/BetterGenshinImpact/Core/Recorder/GlobalKeyMouseRecord.cs index 12b3c948..a43f4a85 100644 --- a/BetterGenshinImpact/Core/Recorder/GlobalKeyMouseRecord.cs +++ b/BetterGenshinImpact/Core/Recorder/GlobalKeyMouseRecord.cs @@ -1,30 +1,49 @@ -using System.Collections.Generic; -using System.Diagnostics; +using BetterGenshinImpact.Core.Monitor; +using BetterGenshinImpact.GameTask; +using BetterGenshinImpact.GameTask.Common; +using BetterGenshinImpact.GameTask.Common.Element.Assets; using BetterGenshinImpact.Model; using Gma.System.MouseKeyHook; -using System.Windows.Forms; -using BetterGenshinImpact.GameTask; -using BetterGenshinImpact.GameTask.Model.Area; -using OpenCvSharp; +using Microsoft.Extensions.Logging; using SharpDX.DirectInput; +using System; +using System.Collections.Generic; +using System.Windows.Forms; namespace BetterGenshinImpact.Core.Recorder; public class GlobalKeyMouseRecord : Singleton { + private readonly ILogger _logger = App.GetLogger(); + private KeyMouseRecorder? _recorder; private readonly Dictionary _keyDownState = new(); - // private Rect _captureAreaCenterRect; + private DirectInputMonitor? _directInputMonitor; + + private readonly System.Timers.Timer _timer = new(); + + private bool _isInMainUi = false; // 是否在主界面 + + public GlobalKeyMouseRecord() + { + _timer.Elapsed += Tick; + _timer.Interval = 50; // ms + } public KeyMouseRecorder StartRecord() { - _recorder = new KeyMouseRecorder(); + TaskTriggerDispatcher.Instance().StopTimer(); + _timer.Start(); + + _recorder = new KeyMouseRecorder(); + _directInputMonitor = new DirectInputMonitor(); + _directInputMonitor.Start(); + + _logger.LogInformation("录制:{Text}", "实时任务已暂停,录制已启动"); + _logger.LogInformation("注意:录制时遇到主界面(鼠标永远在界面中心)和其他界面(鼠标可自由移动,比如地图等)的切换,请把手离开鼠标等待录制模式切换日志"); - // var rect = TaskContext.Instance().SystemInfo.CaptureAreaRect; - // var centerPoint = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2); - // _captureAreaCenterRect = new Rect(centerPoint.X - 10, centerPoint.Y - 15, 20, 20); return _recorder; } @@ -32,11 +51,39 @@ public class GlobalKeyMouseRecord : Singleton { var macro = _recorder?.ToJsonMacro() ?? string.Empty; _recorder = null; + _directInputMonitor?.Stop(); + _directInputMonitor?.Dispose(); + _directInputMonitor = null; + + _timer.Stop(); + + _logger.LogInformation("录制:{Text}", "结束录制"); + + TaskTriggerDispatcher.Instance().StartTimer(); return macro; } + public void Tick(object? sender, EventArgs e) + { + var ra = TaskControl.CaptureToRectArea(); + var iconRa = ra.Find(ElementAssets.Instance.FriendChat); + var exist = iconRa.IsExist(); + if (exist != _isInMainUi) + { + _logger.LogInformation("录制:{Text}", exist ? "进入主界面,捕获鼠标相对移动" : "离开主界面,捕获鼠标绝对移动"); + } + _isInMainUi = exist; + iconRa.Dispose(); + ra.Dispose(); + } + public void GlobalHookKeyDown(KeyEventArgs e) { + if (e.KeyCode.ToString() == TaskContext.Instance().Config.HotKeyConfig.Test1Hotkey) + { + return; + } + if (_keyDownState.TryGetValue(e.KeyCode, out var v)) { if (v) @@ -52,15 +99,20 @@ public class GlobalKeyMouseRecord : Singleton { _keyDownState.Add(e.KeyCode, true); } - Debug.WriteLine($"KeyDown: {e.KeyCode}"); + // Debug.WriteLine($"KeyDown: {e.KeyCode}"); _recorder?.KeyDown(e); } public void GlobalHookKeyUp(KeyEventArgs e) { + if (e.KeyCode.ToString() == TaskContext.Instance().Config.HotKeyConfig.Test1Hotkey) + { + return; + } + if (_keyDownState.ContainsKey(e.KeyCode) && _keyDownState[e.KeyCode]) { - Debug.WriteLine($"KeyUp: {e.KeyCode}"); + // Debug.WriteLine($"KeyUp: {e.KeyCode}"); _keyDownState[e.KeyCode] = false; _recorder?.KeyUp(e); } @@ -80,21 +132,21 @@ public class GlobalKeyMouseRecord : Singleton public void GlobalHookMouseMoveTo(MouseEventExtArgs e) { - // if (_captureAreaCenterRect.Contains(e.X, e.Y)) - // { - // return; - // } + if (_isInMainUi) + { + return; + } // Debug.WriteLine($"MouseMove: {e.X}, {e.Y}"); - // _recorder?.MouseMoveTo(e); + _recorder?.MouseMoveTo(e); } public void GlobalHookMouseMoveBy(MouseState state) { - // Debug.WriteLine($"MouseMoveBy: {state.X}, {state.Y}"); - if (state is { X: 0, Y: 0 }) + if (state is { X: 0, Y: 0 } || !_isInMainUi) { return; } + // Debug.WriteLine($"MouseMoveBy: {state.X}, {state.Y}"); _recorder?.MouseMoveBy(state); } } diff --git a/BetterGenshinImpact/GameTask/Common/Element/Assets/1920x1080/friend_chat.png b/BetterGenshinImpact/GameTask/Common/Element/Assets/1920x1080/friend_chat.png new file mode 100644 index 00000000..4fcf93bd Binary files /dev/null and b/BetterGenshinImpact/GameTask/Common/Element/Assets/1920x1080/friend_chat.png differ diff --git a/BetterGenshinImpact/GameTask/Common/Element/Assets/ElementAssets.cs b/BetterGenshinImpact/GameTask/Common/Element/Assets/ElementAssets.cs index fd968643..149af1cc 100644 --- a/BetterGenshinImpact/GameTask/Common/Element/Assets/ElementAssets.cs +++ b/BetterGenshinImpact/GameTask/Common/Element/Assets/ElementAssets.cs @@ -21,6 +21,8 @@ public class ElementAssets : BaseAssets public RecognitionObject SpaceKey; public RecognitionObject XKey; + public RecognitionObject FriendChat; + private ElementAssets() { // 按钮 @@ -116,5 +118,15 @@ public class ElementAssets : BaseAssets RegionOfInterest = new Rect(CaptureRect.Width - (int)(210 * AssetScale), CaptureRect.Height - (int)(70 * AssetScale), (int)(60 * AssetScale), (int)(70 * AssetScale)), DrawOnWindow = false }.InitTemplate(); + + // 左下角的好友聊天icon + FriendChat = new RecognitionObject + { + Name = "FriendChat", + RecognitionType = RecognitionTypes.TemplateMatch, + TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "friend_chat.png"), + RegionOfInterest = new Rect(0, CaptureRect.Height - (int)(70 * AssetScale), (int)(83 * AssetScale), (int)(70 * AssetScale)), + DrawOnWindow = false + }.InitTemplate(); } } diff --git a/BetterGenshinImpact/ViewModel/Pages/HotKeyPageViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/HotKeyPageViewModel.cs index 48e4fb81..3ee58c8b 100644 --- a/BetterGenshinImpact/ViewModel/Pages/HotKeyPageViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/HotKeyPageViewModel.cs @@ -419,26 +419,23 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel // // if (GetGUIThreadInfo(threadid, ref lpgui)) // { - // if (lpgui.hwndCaret != 0) - // { - // _logger.LogInformation("输入状态"); - // return; - // } + // if (lpgui.hwndCaret != 0) + // { + // _logger.LogInformation("输入状态"); + // return; + // } // } // _logger.LogInformation("非输入状态"); if (!flag) { GlobalKeyMouseRecord.Instance.StartRecord(); - new DirectInputMonitor().Start(); - _logger.LogInformation("开始录制脚本"); flag = true; } else { m = GlobalKeyMouseRecord.Instance.StopRecord(); Debug.WriteLine("录制脚本结束:" + m); - _logger.LogInformation("录制脚本结束"); flag = false; } } @@ -451,6 +448,7 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel Config.HotKeyConfig.Test2HotkeyType, (_, _) => { + _logger.LogInformation("开始重放脚本"); Task.Run(async () => { await KeyMouseMacroPlayer.PlayMacro(m);