From dabdfa51f44333e59cd2d7892763bb24fcfa6603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sun, 5 May 2024 22:51:11 +0800 Subject: [PATCH] fix boundary overflow after switching game resolution --- .../AutoFishing/AutoFishingTrigger.cs | 140 +++++++++--------- .../GameTask/AutoPick/AutoPickTrigger.cs | 9 +- .../GameTask/AutoWood/AutoWoodTask.cs | 1 + .../GameTask/GameTaskManager.cs | 13 +- .../GameTask/Model/BaseAssets.cs | 26 ++++ .../QuickSereniteaPotTask.cs | 6 +- BetterGenshinImpact/Model/Singleton.cs | 6 +- 7 files changed, 118 insertions(+), 83 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoFishing/AutoFishingTrigger.cs b/BetterGenshinImpact/GameTask/AutoFishing/AutoFishingTrigger.cs index 69fba72f..18bdfecc 100644 --- a/BetterGenshinImpact/GameTask/AutoFishing/AutoFishingTrigger.cs +++ b/BetterGenshinImpact/GameTask/AutoFishing/AutoFishingTrigger.cs @@ -118,76 +118,76 @@ namespace BetterGenshinImpact.GameTask.AutoFishing } } - /// - /// 在“开始钓鱼”按钮上方安排一个我们的“开始自动钓鱼”按钮 - /// 点击按钮进入独占模式 - /// - /// - /// - [Obsolete] - private void DisplayButtonOnStartFishPageForExclusive(CaptureContent content) - { - VisionContext.Instance().DrawContent.RemoveRect("StartFishingButton"); - var info = TaskContext.Instance().SystemInfo; - var srcMat = content.CaptureRectArea.SrcMat; - var rightBottomMat = CropHelper.CutRightBottom(srcMat, srcMat.Width / 2, srcMat.Height / 2); - var list = CommonRecognition.FindGameButton(rightBottomMat); - if (list.Count > 0) - { - foreach (var rect in list) - { - var ro = new RecognitionObject() - { - Name = "StartFishingText", - RecognitionType = RecognitionTypes.OcrMatch, - RegionOfInterest = new Rect(srcMat.Width / 2, srcMat.Height / 2, srcMat.Width - srcMat.Width / 2, - srcMat.Height - srcMat.Height / 2), - AllContainMatchText = new List - { - "开始", "钓鱼" - }, - DrawOnWindow = false - }; - var ocrRaRes = content.CaptureRectArea.Find(ro); - if (ocrRaRes.IsEmpty()) - { - WeakReferenceMessenger.Default.Send(new PropertyChangedMessage(this, "RemoveButton", new object(), "开始自动钓鱼")); - } - else - { - VisionContext.Instance().DrawContent.PutRect("StartFishingButton", rect.ToWindowsRectangleOffset(srcMat.Width / 2, srcMat.Height / 2).ToRectDrawable()); - - var btnPosition = new Rect(rect.X + srcMat.Width / 2, rect.Y + srcMat.Height / 2 - rect.Height - 10, rect.Width, rect.Height); - var maskButton = new MaskButton("开始自动钓鱼", btnPosition, () => - { - VisionContext.Instance().DrawContent.RemoveRect("StartFishingButton"); - _logger.LogInformation("→ {Text}", "自动钓鱼,启动!"); - // 点击下面的按钮 - var rc = info.CaptureAreaRect; - Simulation.SendInputEx - .Mouse - .MoveMouseTo( - (rc.X + srcMat.Width * 1d / 2 + rect.X + rect.Width * 1d / 2) * 65535 / info.DesktopRectArea.Width, - (rc.Y + srcMat.Height * 1d / 2 + rect.Y + rect.Height * 1d / 2) * 65535 / info.DesktopRectArea.Height) - .LeftButtonClick(); - WeakReferenceMessenger.Default.Send(new PropertyChangedMessage(this, "RemoveButton", new object(), "开始自动钓鱼")); - // 启动要延时一会等待钓鱼界面切换 - Sleep(1000); - IsExclusive = true; - _switchBaitContinuouslyFrameNum = 0; - _waitBiteContinuouslyFrameNum = 0; - _noFishActionContinuouslyFrameNum = 0; - _isThrowRod = false; - }); - WeakReferenceMessenger.Default.Send(new PropertyChangedMessage(this, "AddButton", new object(), maskButton)); - } - } - } - else - { - WeakReferenceMessenger.Default.Send(new PropertyChangedMessage(this, "RemoveButton", new object(), "开始自动钓鱼")); - } - } + // /// + // /// 在“开始钓鱼”按钮上方安排一个我们的“开始自动钓鱼”按钮 + // /// 点击按钮进入独占模式 + // /// + // /// + // /// + // [Obsolete] + // private void DisplayButtonOnStartFishPageForExclusive(CaptureContent content) + // { + // VisionContext.Instance().DrawContent.RemoveRect("StartFishingButton"); + // var info = TaskContext.Instance().SystemInfo; + // var srcMat = content.CaptureRectArea.SrcMat; + // var rightBottomMat = CropHelper.CutRightBottom(srcMat, srcMat.Width / 2, srcMat.Height / 2); + // var list = CommonRecognition.FindGameButton(rightBottomMat); + // if (list.Count > 0) + // { + // foreach (var rect in list) + // { + // var ro = new RecognitionObject() + // { + // Name = "StartFishingText", + // RecognitionType = RecognitionTypes.OcrMatch, + // RegionOfInterest = new Rect(srcMat.Width / 2, srcMat.Height / 2, srcMat.Width - srcMat.Width / 2, + // srcMat.Height - srcMat.Height / 2), + // AllContainMatchText = new List + // { + // "开始", "钓鱼" + // }, + // DrawOnWindow = false + // }; + // var ocrRaRes = content.CaptureRectArea.Find(ro); + // if (ocrRaRes.IsEmpty()) + // { + // WeakReferenceMessenger.Default.Send(new PropertyChangedMessage(this, "RemoveButton", new object(), "开始自动钓鱼")); + // } + // else + // { + // VisionContext.Instance().DrawContent.PutRect("StartFishingButton", rect.ToWindowsRectangleOffset(srcMat.Width / 2, srcMat.Height / 2).ToRectDrawable()); + // + // var btnPosition = new Rect(rect.X + srcMat.Width / 2, rect.Y + srcMat.Height / 2 - rect.Height - 10, rect.Width, rect.Height); + // var maskButton = new MaskButton("开始自动钓鱼", btnPosition, () => + // { + // VisionContext.Instance().DrawContent.RemoveRect("StartFishingButton"); + // _logger.LogInformation("→ {Text}", "自动钓鱼,启动!"); + // // 点击下面的按钮 + // var rc = info.CaptureAreaRect; + // Simulation.SendInputEx + // .Mouse + // .MoveMouseTo( + // (rc.X + srcMat.Width * 1d / 2 + rect.X + rect.Width * 1d / 2) * 65535 / info.DesktopRectArea.Width, + // (rc.Y + srcMat.Height * 1d / 2 + rect.Y + rect.Height * 1d / 2) * 65535 / info.DesktopRectArea.Height) + // .LeftButtonClick(); + // WeakReferenceMessenger.Default.Send(new PropertyChangedMessage(this, "RemoveButton", new object(), "开始自动钓鱼")); + // // 启动要延时一会等待钓鱼界面切换 + // Sleep(1000); + // IsExclusive = true; + // _switchBaitContinuouslyFrameNum = 0; + // _waitBiteContinuouslyFrameNum = 0; + // _noFishActionContinuouslyFrameNum = 0; + // _isThrowRod = false; + // }); + // WeakReferenceMessenger.Default.Send(new PropertyChangedMessage(this, "AddButton", new object(), maskButton)); + // } + // } + // } + // else + // { + // WeakReferenceMessenger.Default.Send(new PropertyChangedMessage(this, "RemoveButton", new object(), "开始自动钓鱼")); + // } + // } //private bool OcrStartFishingForExclusive(CaptureContent content) //{ diff --git a/BetterGenshinImpact/GameTask/AutoPick/AutoPickTrigger.cs b/BetterGenshinImpact/GameTask/AutoPick/AutoPickTrigger.cs index 970ac3da..368b0ae2 100644 --- a/BetterGenshinImpact/GameTask/AutoPick/AutoPickTrigger.cs +++ b/BetterGenshinImpact/GameTask/AutoPick/AutoPickTrigger.cs @@ -1,19 +1,19 @@ using BetterGenshinImpact.Core.Config; +using BetterGenshinImpact.Core.Recognition.OCR; using BetterGenshinImpact.Core.Recognition.ONNX.SVTR; using BetterGenshinImpact.Core.Recognition.OpenCv; using BetterGenshinImpact.Core.Simulator; using BetterGenshinImpact.GameTask.AutoPick.Assets; +using BetterGenshinImpact.Helpers; +using BetterGenshinImpact.Service; using Microsoft.Extensions.Logging; using OpenCvSharp; using System; using System.Collections.Generic; using System.Diagnostics; using System.Text.Json; +using System.Text.RegularExpressions; using System.Windows.Forms; -using BetterGenshinImpact.Core.Recognition.OCR; -using BetterGenshinImpact.Helpers; -using WindowsInput; -using BetterGenshinImpact.Service; using Vanara.PInvoke; namespace BetterGenshinImpact.GameTask.AutoPick; @@ -159,6 +159,7 @@ public class AutoPickTrigger : ITaskTrigger speedTimer.Record("文字识别"); if (!string.IsNullOrEmpty(text)) { + text = Regex.Replace(text, @"^[\p{P} ]+|[\p{P} ]+$", ""); // 唯一一个动态拾取项,特殊处理,不拾取 if (text.Contains("生长时间")) { diff --git a/BetterGenshinImpact/GameTask/AutoWood/AutoWoodTask.cs b/BetterGenshinImpact/GameTask/AutoWood/AutoWoodTask.cs index 1b66616a..879bb2ba 100644 --- a/BetterGenshinImpact/GameTask/AutoWood/AutoWoodTask.cs +++ b/BetterGenshinImpact/GameTask/AutoWood/AutoWoodTask.cs @@ -34,6 +34,7 @@ public class AutoWoodTask public AutoWoodTask() { _login3rdParty = new(); + AutoWoodAssets.DestroyInstance(); _assets = AutoWoodAssets.Instance; } diff --git a/BetterGenshinImpact/GameTask/GameTaskManager.cs b/BetterGenshinImpact/GameTask/GameTaskManager.cs index 01e47e58..ba4083e3 100644 --- a/BetterGenshinImpact/GameTask/GameTaskManager.cs +++ b/BetterGenshinImpact/GameTask/GameTaskManager.cs @@ -9,9 +9,14 @@ using System.Linq; using BetterGenshinImpact.GameTask.AutoFight.Assets; using BetterGenshinImpact.GameTask.AutoFishing.Assets; using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Assets; +using BetterGenshinImpact.GameTask.AutoPick.Assets; using BetterGenshinImpact.GameTask.AutoSkip.Assets; +using BetterGenshinImpact.GameTask.AutoWood.Assets; +using BetterGenshinImpact.GameTask.Common.Element.Assets; using BetterGenshinImpact.GameTask.GameLoading; +using BetterGenshinImpact.GameTask.GameLoading.Assets; using BetterGenshinImpact.GameTask.Placeholder; +using BetterGenshinImpact.GameTask.QuickSereniteaPot.Assets; using BetterGenshinImpact.GameTask.QuickTeleport.Assets; using BetterGenshinImpact.View.Drawable; @@ -71,12 +76,16 @@ namespace BetterGenshinImpact.GameTask public static void ReloadAssets() { - AutoSkipAssets.DestroyInstance(); + AutoPickAssets.DestroyInstance(); AutoSkipAssets.DestroyInstance(); AutoFishingAssets.DestroyInstance(); QuickTeleportAssets.DestroyInstance(); - AutoFightAssets.DestroyInstance(); + AutoWoodAssets.DestroyInstance(); AutoGeniusInvokationAssets.DestroyInstance(); + AutoFightAssets.DestroyInstance(); + ElementAssets.DestroyInstance(); + QuickSereniteaPotAssets.DestroyInstance(); + GameLoadingAssets.DestroyInstance(); } /// diff --git a/BetterGenshinImpact/GameTask/Model/BaseAssets.cs b/BetterGenshinImpact/GameTask/Model/BaseAssets.cs index ec6d3f18..8caf5d84 100644 --- a/BetterGenshinImpact/GameTask/Model/BaseAssets.cs +++ b/BetterGenshinImpact/GameTask/Model/BaseAssets.cs @@ -1,5 +1,6 @@ using BetterGenshinImpact.Model; using OpenCvSharp; +using System.Threading; namespace BetterGenshinImpact.GameTask.Model; @@ -14,4 +15,29 @@ public class BaseAssets : Singleton where T : class { protected Rect CaptureRect => TaskContext.Instance().SystemInfo.ScaleMax1080PCaptureRect; protected double AssetScale => TaskContext.Instance().SystemInfo.AssetScale; + + // private int _gameWidth; + // private int _gameHeight; + // + // public new static T Instance + // { + // get + // { + // // 统一在这里处理 重新生成实例 + // if (_instance != null) + // { + // var r = TaskContext.Instance().SystemInfo.CaptureAreaRect; + // if (_instance is BaseAssets baseAssets) + // { + // if (baseAssets._gameWidth != r.Width || baseAssets._gameHeight != r.Height) + // { + // baseAssets._gameWidth = r.Width; + // baseAssets._gameHeight = r.Height; + // _instance = null; + // } + // } + // } + // return LazyInitializer.EnsureInitialized(ref _instance, ref syncRoot, CreateInstance); + // } + // } } diff --git a/BetterGenshinImpact/GameTask/QuickSereniteaPot/QuickSereniteaPotTask.cs b/BetterGenshinImpact/GameTask/QuickSereniteaPot/QuickSereniteaPotTask.cs index dc7d4054..1de96e9a 100644 --- a/BetterGenshinImpact/GameTask/QuickSereniteaPot/QuickSereniteaPotTask.cs +++ b/BetterGenshinImpact/GameTask/QuickSereniteaPot/QuickSereniteaPotTask.cs @@ -12,14 +12,12 @@ namespace BetterGenshinImpact.GameTask.QuickSereniteaPot; public class QuickSereniteaPotTask { - private static readonly QuickSereniteaPotAssets _assets = QuickSereniteaPotAssets.Instance; - private static void WaitForBagToOpen() { NewRetry.Do(() => { TaskControl.Sleep(1); - using var ra2 = TaskControl.CaptureToRectArea().Find(_assets.BagCloseButtonRo); + using var ra2 = TaskControl.CaptureToRectArea().Find(QuickSereniteaPotAssets.Instance.BagCloseButtonRo); if (ra2.IsEmpty()) { throw new RetryException("背包未打开"); @@ -32,7 +30,7 @@ public class QuickSereniteaPotTask NewRetry.Do(() => { TaskControl.Sleep(1); - using var ra2 = TaskControl.CaptureToRectArea().Find(_assets.SereniteaPotIconRo); + using var ra2 = TaskControl.CaptureToRectArea().Find(QuickSereniteaPotAssets.Instance.SereniteaPotIconRo); if (ra2.IsEmpty()) { throw new RetryException("未检测到壶"); diff --git a/BetterGenshinImpact/Model/Singleton.cs b/BetterGenshinImpact/Model/Singleton.cs index 16144631..21db3d98 100644 --- a/BetterGenshinImpact/Model/Singleton.cs +++ b/BetterGenshinImpact/Model/Singleton.cs @@ -11,12 +11,12 @@ namespace BetterGenshinImpact.Model; /// public class Singleton where T : class { - private static T? _instance; - private static object? syncRoot; + protected static T? _instance; + protected static object? syncRoot; public static T Instance => LazyInitializer.EnsureInitialized(ref _instance, ref syncRoot, CreateInstance); - private static T CreateInstance() + protected static T CreateInstance() { return (T)Activator.CreateInstance(typeof(T), true)!; }