From b5d9ce1c9368fae24ae52a022520834648c559ed Mon Sep 17 00:00:00 2001 From: huiyadanli Date: Sun, 24 Sep 2023 00:52:28 +0800 Subject: [PATCH] feat: finsh auto skip --- .../BetterGenshinImpact.csproj | 3 + .../AutoSkip/Assets/1920x1080/menu.png | Bin 0 -> 2372 bytes .../AutoSkip/Assets/1920x1080/option.png | Bin 386 -> 480 bytes .../AutoSkip/Assets/1920x1080/stop_auto.png | Bin 313 -> 319 bytes .../AutoSkip/Assets/AutoSkipAssets.cs | 5 +- .../GameTask/AutoSkip/AutoSkipTrigger.cs | 51 ++++++--- .../GameTask/GameTaskManager.cs | 2 + BetterGenshinImpact/GameTask/SystemControl.cs | 28 +++++ BetterGenshinImpact/GameTask/TaskContext.cs | 37 +++++++ .../GameTask/TaskDispatcher.cs | 24 +++-- .../Utils/Extensions/PointExtension.cs | 48 +++++++++ BetterGenshinImpact/Utils/PrimaryScreen.cs | 99 ------------------ BetterGenshinImpact/View/MainWindow.xaml | 1 + .../ViewModel/MainWindowViewModel.cs | 79 +++++++++++--- Vision.Recognition/Helper/OpenCv/CutHelper.cs | 64 +++++++++++ Vision.Recognition/Task/BaseTaskThread.cs | 5 +- Vision.Recognition/Task/ITaskContext.cs | 18 ---- Vision.Recognition/Task/ITaskTrigger.cs | 3 +- Vision.WindowCapture/BitBlt/BitBltCapture.cs | 41 +++++--- 19 files changed, 335 insertions(+), 173 deletions(-) create mode 100644 BetterGenshinImpact/GameTask/AutoSkip/Assets/1920x1080/menu.png create mode 100644 BetterGenshinImpact/GameTask/TaskContext.cs create mode 100644 BetterGenshinImpact/Utils/Extensions/PointExtension.cs delete mode 100644 BetterGenshinImpact/Utils/PrimaryScreen.cs create mode 100644 Vision.Recognition/Helper/OpenCv/CutHelper.cs delete mode 100644 Vision.Recognition/Task/ITaskContext.cs diff --git a/BetterGenshinImpact/BetterGenshinImpact.csproj b/BetterGenshinImpact/BetterGenshinImpact.csproj index 6a180a35..2d6a15d8 100644 --- a/BetterGenshinImpact/BetterGenshinImpact.csproj +++ b/BetterGenshinImpact/BetterGenshinImpact.csproj @@ -34,6 +34,9 @@ + + Always + Always diff --git a/BetterGenshinImpact/GameTask/AutoSkip/Assets/1920x1080/menu.png b/BetterGenshinImpact/GameTask/AutoSkip/Assets/1920x1080/menu.png new file mode 100644 index 0000000000000000000000000000000000000000..c424325b17a4956f7802352e7609bfcff2721afa GIT binary patch literal 2372 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 delta 344 zcmV-e0jK`p1A+q~iBL{Q4GJ0x0000DNk~Le0000P000092nGNE0LMRv_>mzse-}wa zK~y+Ty^%dn!cY{3{kN#7K+s?j1g07j-DDv#CJrP_44Ob>fM|e}U|jsF3iu5aaloN9 zO<#LYdnN6i7FO1i_~;J=30o`} zO;FC}uz4I$(&@b*uqJtxJIcF>L-nGGK-kVg5-n1$)C9@lae?~0*gTFWnM{5l?`LVq z>P8ARd+0R%fric04vAvhGTz=l1xZ6`BNR)MK;Ao`c^u&;+Gq^L{;$`!E~@ZcPWSnh q^6u1@9CpK-JC*X8H<>3sNPs`1tV6n8=Tp`I00001(wiBL{Q4GJ0x0000DNk~Le0000J0000K2nGNE0B=DUUC4jWz=Z!>wyZ}Owtvqyph3}KNeD(5h-}!})hquyc_A!> zsSk`u1-lMx*zO&h;S%T=*{~JMYL;SE`p&-F##I+q*~ncl3<>Uscoe|Mu0>aLrfF zAN!wEPyv<)VGsYf|4WxGff(@Y!R7zX-qHW9okM^)6pS4_BK~jLv<_~-{Q2|$+q;Fs ze03TGiQ*Nojn8M|1Sq;=j;C&-aNkc|IHJiLJ)=)5?~C~49CcFaD4qg07t0k US^Qh&@Bjb+07*qoM6N<$f|q83`2YX_ diff --git a/BetterGenshinImpact/GameTask/AutoSkip/Assets/AutoSkipAssets.cs b/BetterGenshinImpact/GameTask/AutoSkip/Assets/AutoSkipAssets.cs index 1f326594..5370213a 100644 --- a/BetterGenshinImpact/GameTask/AutoSkip/Assets/AutoSkipAssets.cs +++ b/BetterGenshinImpact/GameTask/AutoSkip/Assets/AutoSkipAssets.cs @@ -10,7 +10,8 @@ namespace BetterGenshinImpact.GameTask.AutoSkip.Assets { public class AutoSkipAssets { - public static Mat StopAutoButtonMat = new(Global.Absolute("GameTask/AutoSkip/Assets/stop_auto.png"), ImreadModes.Grayscale); - public static Mat OptionMat = new(Global.Absolute("GameTask/AutoSkip/Assets/option.png"), ImreadModes.Grayscale); + public static Mat StopAutoButtonMat = new(Global.Absolute(@"GameTask\AutoSkip\Assets\1920x1080\stop_auto.png"), ImreadModes.Grayscale); + public static Mat OptionMat = new(Global.Absolute(@"GameTask\AutoSkip\Assets\1920x1080\option.png"), ImreadModes.Grayscale); + public static Mat MenuMat = new(Global.Absolute(@"GameTask\AutoSkip\Assets\1920x1080\menu.png"), ImreadModes.Grayscale); } } diff --git a/BetterGenshinImpact/GameTask/AutoSkip/AutoSkipTrigger.cs b/BetterGenshinImpact/GameTask/AutoSkip/AutoSkipTrigger.cs index b7b3591a..4e1947c0 100644 --- a/BetterGenshinImpact/GameTask/AutoSkip/AutoSkipTrigger.cs +++ b/BetterGenshinImpact/GameTask/AutoSkip/AutoSkipTrigger.cs @@ -1,5 +1,8 @@ using System; +using System.Diagnostics; using BetterGenshinImpact.GameTask.AutoSkip.Assets; +using BetterGenshinImpact.Utils.Extensions; +using Microsoft.Extensions.Logging; using OpenCvSharp; using Vision.Recognition.Helper.OpenCv; using Vision.Recognition.Task; @@ -9,44 +12,68 @@ namespace BetterGenshinImpact.GameTask.AutoSkip { public class AutoSkipTrigger : ITaskTrigger { + private ILogger _logger = App.GetLogger(); + public string Name => "自动剧情"; public bool IsEnabled { get; set; } public int Priority => 20; public bool IsExclusive => false; - public void Init(ITaskContext context) + public void Init() { - + IsEnabled = true; } public void OnCapture(Mat matSrc, int frameIndex) { - //TODO 切割图片加快效率 + if (frameIndex % 2 == 0) + { + return; + } + var grayMat = new Mat(); Cv2.CvtColor(matSrc, grayMat, ColorConversionCodes.BGR2GRAY); // 找左上角剧情自动的按钮 - var p1 = MatchTemplateHelper.FindSingleTarget(grayMat, AutoSkipAssets.StopAutoButtonMat); + var grayLeftTopMat = CutHelper.CutLeftTop(grayMat, grayMat.Width / 5, grayMat.Height / 5); + var p1 = MatchTemplateHelper.FindSingleTarget(grayLeftTopMat, AutoSkipAssets.StopAutoButtonMat, 0.9); if (p1 is { X: > 0, Y: > 0 }) { - //TODO 无效操作代码 需要替换 new InputSimulator().Keyboard.KeyPress(VirtualKeyCode.SPACE); - return; + Debug.WriteLine($"按下空格"); } + // 不存在则找右下的选项按钮 - var p2 = MatchTemplateHelper.FindSingleTarget(grayMat, AutoSkipAssets.OptionMat); + var grayRightBottomMat = CutHelper.CutRightBottom(grayMat, grayMat.Width / 2, grayMat.Height / 3 * 2); + var p2 = MatchTemplateHelper.FindSingleTarget(grayRightBottomMat, AutoSkipAssets.OptionMat); if (p2 is { X: > 0, Y: > 0 }) { - new InputSimulator().Mouse.MoveMouseTo(p2.X, p2.Y).LeftButtonClick(); - return; + // 不存在菜单的情况下 剧情在播放中 + var grayLeftTopMat2 = CutHelper.CutLeftTop(grayMat, grayMat.Width / 4, grayMat.Height / 4); + var pMenu = MatchTemplateHelper.FindSingleTarget(grayLeftTopMat2, AutoSkipAssets.MenuMat); + if (pMenu is { X: 0, Y: 0 }) + { + + p2 = p2.ToDesktopPositionOffset65535(grayMat.Width - grayMat.Width / 2, + grayMat.Height - grayMat.Height / 3 * 2); + new InputSimulator().Mouse.MoveMouseTo(p2.X, p2.Y).LeftButtonClick(); + _logger.LogInformation($"点击选项按钮:{p2}"); + Debug.WriteLine($"点击选项按钮:{p2}"); + return; + } + } - // 判断左上角的黑色像素个数 + + // 黑屏剧情要点击鼠标(多次) 几乎全黑的时候不用点击 var blackCount = OpenCvCommonHelper.CountGrayMatColor(grayMat, 0); var rate = blackCount * 1.0 / (grayMat.Width * grayMat.Height); - if (rate > 0.9) + if (rate > 0.7 && rate < 0.99) { - //TODO click center + var p3 = new Point(grayMat.Width / 2, grayMat.Height / 2).ToDesktopPosition65535(); + new InputSimulator().Mouse.MoveMouseTo(p3.X, p3.Y).LeftButtonClick(); + Debug.WriteLine($"点击黑屏剧情:{rate}"); return; } + // TODO 自动交付材料 } } } \ No newline at end of file diff --git a/BetterGenshinImpact/GameTask/GameTaskManager.cs b/BetterGenshinImpact/GameTask/GameTaskManager.cs index e55d9097..cb1cb906 100644 --- a/BetterGenshinImpact/GameTask/GameTaskManager.cs +++ b/BetterGenshinImpact/GameTask/GameTaskManager.cs @@ -33,6 +33,8 @@ namespace BetterGenshinImpact.GameTask List loadedTriggers = new(); loadedTriggers.Add(new AutoSkip.AutoSkipTrigger()); + loadedTriggers.ForEach(i => i.Init()); + return loadedTriggers.OrderByDescending(i => i.Priority).ToList(); } diff --git a/BetterGenshinImpact/GameTask/SystemControl.cs b/BetterGenshinImpact/GameTask/SystemControl.cs index 9a50e333..96f77f64 100644 --- a/BetterGenshinImpact/GameTask/SystemControl.cs +++ b/BetterGenshinImpact/GameTask/SystemControl.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Xml.Linq; using Vanara.PInvoke; @@ -50,5 +51,32 @@ namespace BetterGenshinImpact.GameTask return null; } } + + /// + /// 获取窗口位置 + /// + /// + /// + public static RECT GetWindowRect(IntPtr hWnd) + { + User32.GetWindowRect(hWnd, out var windowRect); + return windowRect; + } + + /// + /// 游戏本身分辨率获取 + /// + /// + /// + public static RECT GetGameScreenRect(IntPtr hWnd) + { + User32.GetClientRect(hWnd, out var clientRect); + return clientRect; + } + + //public static int GetCaptionHeight() + //{ + // return User32.GetSystemMetrics(User32.SystemMetric.SM_CYFRAME) + User32.GetSystemMetrics(User32.SystemMetric.SM_CYCAPTION); + //} } } \ No newline at end of file diff --git a/BetterGenshinImpact/GameTask/TaskContext.cs b/BetterGenshinImpact/GameTask/TaskContext.cs new file mode 100644 index 00000000..2247bcb0 --- /dev/null +++ b/BetterGenshinImpact/GameTask/TaskContext.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Vision.Recognition; + +namespace BetterGenshinImpact.GameTask +{ + /// + /// 任务上下文 + /// + public class TaskContext + { + + private static TaskContext? _uniqueInstance; + private static readonly object Locker = new(); + + private TaskContext() + { + } + + public static TaskContext Instance() + { + if (_uniqueInstance == null) + { + lock (Locker) + { + _uniqueInstance ??= new TaskContext(); + } + } + return _uniqueInstance; + } + + public IntPtr GameHandle { get; set; } + } +} diff --git a/BetterGenshinImpact/GameTask/TaskDispatcher.cs b/BetterGenshinImpact/GameTask/TaskDispatcher.cs index 5576979f..0af898a4 100644 --- a/BetterGenshinImpact/GameTask/TaskDispatcher.cs +++ b/BetterGenshinImpact/GameTask/TaskDispatcher.cs @@ -20,13 +20,13 @@ namespace BetterGenshinImpact.GameTask private readonly ILogger _logger = App.GetLogger(); private readonly Timer _timer = new(); - private List _triggers = new(); + private readonly List _triggers; private IWindowCapture? _capture; private int _frameIndex = 0; - private int _frameRate = 60; + private int _frameRate = 30; public TaskDispatcher() @@ -36,7 +36,7 @@ namespace BetterGenshinImpact.GameTask _timer.Elapsed += Tick; } - public void Start(CaptureMode mode, int frameRate) + public void Start(CaptureMode mode, int frameRate = 30) { IntPtr hWnd = SystemControl.FindGenshinImpactHandle(); if (hWnd == IntPtr.Zero) @@ -44,6 +44,7 @@ namespace BetterGenshinImpact.GameTask MessageBox.Show("未找到原神窗口"); return; } + TaskContext.Instance().GameHandle = hWnd; _frameRate = frameRate; @@ -63,22 +64,29 @@ namespace BetterGenshinImpact.GameTask public void Tick(object? sender, EventArgs e) { - if (_capture == null) + // 检查截图器是否初始化 + if (_capture == null || !_capture.IsCapturing) { _logger.LogError("截图器未初始化!"); Stop(); return; } + + // 检查游戏是否在前台 + if (!SystemControl.IsGenshinImpactActive()) + { + return; + } // 帧序号自增 1分钟后归零 _frameIndex = (_frameIndex + 1) % (_frameRate * 60); // 捕获游戏画面 - var sw = new Stopwatch(); - sw.Start(); + //var sw = new Stopwatch(); + //sw.Start(); var bitmap = _capture.Capture(); - sw.Stop(); - Debug.WriteLine("截图耗时:" + sw.ElapsedMilliseconds); + //sw.Stop(); + //Debug.WriteLine("截图耗时:" + sw.ElapsedMilliseconds); if (bitmap == null) { diff --git a/BetterGenshinImpact/Utils/Extensions/PointExtension.cs b/BetterGenshinImpact/Utils/Extensions/PointExtension.cs new file mode 100644 index 00000000..dc175843 --- /dev/null +++ b/BetterGenshinImpact/Utils/Extensions/PointExtension.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BetterGenshinImpact.GameTask; +using OpenCvSharp; +using Vision.Recognition.Helper.Simulator; + +namespace BetterGenshinImpact.Utils.Extensions +{ + public static class PointExtension + { + public static Point ToDesktopPosition(this Point point) + { + if (TaskContext.Instance().GameHandle == IntPtr.Zero) + { + return point; + } + + var rc = SystemControl.GetWindowRect(TaskContext.Instance().GameHandle); + return new Point(rc.X + point.X, rc.Y + point.Y); + } + + public static Point ToDesktopPosition65535(this Point point) + { + var p = point.ToDesktopPosition(); + return new Point(p.X * 65535 / PrimaryScreen.WorkingArea.Width, p.Y * 65535 / PrimaryScreen.WorkingArea.Height); + } + + public static Point ToDesktopPositionOffset(this Point point, int offsetX, int offsetY) + { + if (TaskContext.Instance().GameHandle == IntPtr.Zero) + { + return point; + } + + var rc = SystemControl.GetWindowRect(TaskContext.Instance().GameHandle); + return new Point(rc.X + point.X + offsetX, rc.Y + point.Y + offsetY); + } + + public static Point ToDesktopPositionOffset65535(this Point point, int offsetX, int offsetY) + { + var p = point.ToDesktopPositionOffset(offsetX, offsetY); + return new Point(p.X * 65535 / PrimaryScreen.WorkingArea.Width, p.Y * 65535 / PrimaryScreen.WorkingArea.Height); + } + } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Utils/PrimaryScreen.cs b/BetterGenshinImpact/Utils/PrimaryScreen.cs deleted file mode 100644 index d40c7c64..00000000 --- a/BetterGenshinImpact/Utils/PrimaryScreen.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Drawing; -using System.Runtime.InteropServices; -using Vanara.PInvoke; -using static Vanara.PInvoke.Gdi32; - -namespace BetterGenshinImpact.Utils -{ - public class PrimaryScreen - { - /// - /// 获取屏幕分辨率当前物理大小 - /// - public static Size WorkingArea - { - get - { - var hdc = User32.GetDC(IntPtr.Zero); - var size = new Size - { - Width = Gdi32.GetDeviceCaps(hdc, DeviceCap.HORZRES), - Height = Gdi32.GetDeviceCaps(hdc, DeviceCap.VERTRES) - }; - User32.ReleaseDC(IntPtr.Zero, hdc); - return size; - } - } - /// - /// 当前系统DPI_X 大小 一般为96 - /// - public static int DpiX - { - get - { - var hdc = User32.GetDC(IntPtr.Zero); - var dpiX = Gdi32.GetDeviceCaps(hdc, DeviceCap.LOGPIXELSX); - User32.ReleaseDC(IntPtr.Zero, hdc); - return dpiX; - } - } - /// - /// 当前系统DPI_Y 大小 一般为96 - /// - public static int DpiY - { - get - { - var hdc = User32.GetDC(IntPtr.Zero); - var dpiX = Gdi32.GetDeviceCaps(hdc, DeviceCap.LOGPIXELSY); - User32.ReleaseDC(IntPtr.Zero, hdc); - return dpiX; - } - } - /// - /// 获取真实设置的桌面分辨率大小 - /// - public static Size DESKTOP - { - get - { - var hdc = User32.GetDC(IntPtr.Zero); - var size = new Size - { - Width = Gdi32.GetDeviceCaps(hdc, DeviceCap.DESKTOPHORZRES), - Height = Gdi32.GetDeviceCaps(hdc, DeviceCap.DESKTOPVERTRES) - }; - User32.ReleaseDC(IntPtr.Zero, hdc); - return size; - } - } - - /// - /// 获取宽度缩放百分比 - /// - public static float ScaleX - { - get - { - var hdc = User32.GetDC(IntPtr.Zero); - var scaleX = (float)Gdi32.GetDeviceCaps(hdc, DeviceCap.DESKTOPHORZRES) / (float)Gdi32.GetDeviceCaps(hdc, DeviceCap.HORZRES); - User32.ReleaseDC(IntPtr.Zero, hdc); - return scaleX; - } - } - /// - /// 获取高度缩放百分比 - /// - public static float ScaleY - { - get - { - var hdc = User32.GetDC(IntPtr.Zero); - var scaleY = (float)Gdi32.GetDeviceCaps(hdc, DeviceCap.DESKTOPVERTRES) / (float)Gdi32.GetDeviceCaps(hdc, DeviceCap.VERTRES); - User32.ReleaseDC(IntPtr.Zero, hdc); - return scaleY; - } - } - } -} diff --git a/BetterGenshinImpact/View/MainWindow.xaml b/BetterGenshinImpact/View/MainWindow.xaml index 4e3492cc..86d233fe 100644 --- a/BetterGenshinImpact/View/MainWindow.xaml +++ b/BetterGenshinImpact/View/MainWindow.xaml @@ -26,5 +26,6 @@ +