From 059e21775f9b649129ec55186bc9359380ad029f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sun, 21 Jul 2024 20:38:06 +0800 Subject: [PATCH] unified capture image method --- .../Core/Recorder/DirectInputCalibration.cs | 258 +++++++++--------- .../GameTask/AutoDomain/AutoDomainTask.cs | 28 +- .../GameTask/AutoFight/AutoFightTask.cs | 2 +- .../GameTask/AutoFight/Model/Avatar.cs | 8 +- .../GameTask/AutoFight/OneKeyFightTask.cs | 2 +- .../AutoGeniusInvokation/Model/Duel.cs | 8 +- .../GameTask/AutoSkip/AutoTrackTask.cs | 14 +- .../AutoTrackPath/AutoTrackPathTask.cs | 18 +- .../AutoTrackPath/PathPointRecorder.cs | 2 +- .../GameTask/AutoTrackPath/TpTask.cs | 8 +- .../GameTask/Common/TaskControl.cs | 31 ++- .../GameTask/TaskTriggerDispatcher.cs | 19 +- .../Notification/NotificationHelper.cs | 2 +- 13 files changed, 210 insertions(+), 190 deletions(-) diff --git a/BetterGenshinImpact/Core/Recorder/DirectInputCalibration.cs b/BetterGenshinImpact/Core/Recorder/DirectInputCalibration.cs index 64aecdce..91599fd9 100644 --- a/BetterGenshinImpact/Core/Recorder/DirectInputCalibration.cs +++ b/BetterGenshinImpact/Core/Recorder/DirectInputCalibration.cs @@ -1,129 +1,129 @@ -using System; -using System.Diagnostics; -using System.Threading.Tasks; -using BetterGenshinImpact.Core.Monitor; -using BetterGenshinImpact.Core.Simulator; -using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception; -using BetterGenshinImpact.GameTask; -using BetterGenshinImpact.GameTask.Common.Element.Assets; -using BetterGenshinImpact.GameTask.Common.Map; -using BetterGenshinImpact.GameTask.Model.Area; -using BetterGenshinImpact.GameTask.Model.Enum; -using BetterGenshinImpact.View.Drawable; -using BetterGenshinImpact.ViewModel.Pages; -using Microsoft.Extensions.Logging; -using OpenCvSharp; -using Vanara.PInvoke; -using static BetterGenshinImpact.GameTask.Common.TaskControl; - -namespace BetterGenshinImpact.Core.Recorder; - -/// -/// DirectInput、鼠标移动距离、视角度数之间的校准 -/// -[Obsolete] -public class DirectInputCalibration -{ - // 视角偏移移动单位 - private const int CharMovingUnit = 500; - - public async void Start() - { - var hasLock = false; - try - { - hasLock = await TaskSemaphore.WaitAsync(0); - if (!hasLock) - { - Logger.LogError("启动视角校准功能失败:当前存在正在运行中的独立任务,请不要重复执行任务!"); - return; - } - - Init(); - - await Task.Run(() => - { - GetOffsetAngle(); - }); - } - catch (Exception e) - { - Logger.LogError(e.Message); - Logger.LogDebug(e.StackTrace); - } - finally - { - VisionContext.Instance().DrawContent.ClearAll(); - TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.NormalTrigger); - TaskSettingsPageViewModel.SetSwitchAutoFightButtonText(false); - Logger.LogInformation("→ {Text}", "视角校准结束"); - - if (hasLock) - { - TaskSemaphore.Release(); - } - } - } - - private void Init() - { - SystemControl.ActivateWindow(); - Logger.LogInformation("→ {Text}", "视角校准,启动!"); - TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.OnlyCacheCapture); - Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待缓存图像 - } - - public int GetOffsetAngle() - { - var directInputMonitor = new DirectInputMonitor(); - var ms1 = directInputMonitor.GetMouseState(); - Logger.LogInformation("当前鼠标状态:{X} {Y}", ms1.X, ms1.Y); - var angle1 = GetCharacterOrientationAngle(); - Simulation.SendInput.Mouse.MoveMouseBy(CharMovingUnit, 0); - Sleep(500); - - Simulation.SendInput.Keyboard.KeyDown(User32.VK.VK_W).Sleep(100).KeyUp(User32.VK.VK_W); - Sleep(1000); - - var ms2 = directInputMonitor.GetMouseState(); - Logger.LogInformation("当前鼠标状态:{X} {Y}", ms2.X, ms2.Y); - var angle2 = GetCharacterOrientationAngle(); - var angleOffset = angle2 - angle1; - var directInputXOffset = ms2.X - ms1.X; - Logger.LogInformation("横向移动偏移量校准:鼠标平移{CharMovingUnit}单位,角度转动{AngleOffset},DirectInput移动{DirectInputXOffset}", - CharMovingUnit, angleOffset, directInputXOffset); - - var angle2MouseMoveByX = CharMovingUnit * 1d / angleOffset; - var angle2DirectInputX = directInputXOffset * 1d / angleOffset; - Logger.LogInformation("校准结果:视角每移动1度,需要MouseMoveBy的距离{Angle2MouseMoveByX},需要DirectInput移动的单位{Angle2DirectInputX}", - angle2MouseMoveByX, angle2DirectInputX); - - return angleOffset; - } - - public Mat? GetMiniMapMat(ImageRegion ra) - { - var paimon = ra.Find(ElementAssets.Instance.PaimonMenuRo); - if (paimon.IsExist()) - { - return new Mat(ra.SrcMat, new Rect(paimon.X + 24, paimon.Y - 15, 210, 210)); - } - - return null; - } - - public int GetCharacterOrientationAngle() - { - var ra = GetRectAreaFromDispatcher(); - var miniMapMat = GetMiniMapMat(ra); - if (miniMapMat == null) - { - throw new InvalidOperationException("当前不在主界面"); - } - - var angle = CharacterOrientation.Compute(miniMapMat); - Logger.LogInformation("当前角度:{Angle}", angle); - // CameraOrientation.DrawDirection(ra, angle); - return angle; - } -} +// using System; +// using System.Diagnostics; +// using System.Threading.Tasks; +// using BetterGenshinImpact.Core.Monitor; +// using BetterGenshinImpact.Core.Simulator; +// using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception; +// using BetterGenshinImpact.GameTask; +// using BetterGenshinImpact.GameTask.Common.Element.Assets; +// using BetterGenshinImpact.GameTask.Common.Map; +// using BetterGenshinImpact.GameTask.Model.Area; +// using BetterGenshinImpact.GameTask.Model.Enum; +// using BetterGenshinImpact.View.Drawable; +// using BetterGenshinImpact.ViewModel.Pages; +// using Microsoft.Extensions.Logging; +// using OpenCvSharp; +// using Vanara.PInvoke; +// using static BetterGenshinImpact.GameTask.Common.TaskControl; +// +// namespace BetterGenshinImpact.Core.Recorder; +// +// /// +// /// DirectInput、鼠标移动距离、视角度数之间的校准 +// /// +// [Obsolete] +// public class DirectInputCalibration +// { +// // 视角偏移移动单位 +// private const int CharMovingUnit = 500; +// +// public async void Start() +// { +// var hasLock = false; +// try +// { +// hasLock = await TaskSemaphore.WaitAsync(0); +// if (!hasLock) +// { +// Logger.LogError("启动视角校准功能失败:当前存在正在运行中的独立任务,请不要重复执行任务!"); +// return; +// } +// +// Init(); +// +// await Task.Run(() => +// { +// GetOffsetAngle(); +// }); +// } +// catch (Exception e) +// { +// Logger.LogError(e.Message); +// Logger.LogDebug(e.StackTrace); +// } +// finally +// { +// VisionContext.Instance().DrawContent.ClearAll(); +// TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.NormalTrigger); +// TaskSettingsPageViewModel.SetSwitchAutoFightButtonText(false); +// Logger.LogInformation("→ {Text}", "视角校准结束"); +// +// if (hasLock) +// { +// TaskSemaphore.Release(); +// } +// } +// } +// +// private void Init() +// { +// SystemControl.ActivateWindow(); +// Logger.LogInformation("→ {Text}", "视角校准,启动!"); +// TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.OnlyCacheCapture); +// Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待缓存图像 +// } +// +// public int GetOffsetAngle() +// { +// var directInputMonitor = new DirectInputMonitor(); +// var ms1 = directInputMonitor.GetMouseState(); +// Logger.LogInformation("当前鼠标状态:{X} {Y}", ms1.X, ms1.Y); +// var angle1 = GetCharacterOrientationAngle(); +// Simulation.SendInput.Mouse.MoveMouseBy(CharMovingUnit, 0); +// Sleep(500); +// +// Simulation.SendInput.Keyboard.KeyDown(User32.VK.VK_W).Sleep(100).KeyUp(User32.VK.VK_W); +// Sleep(1000); +// +// var ms2 = directInputMonitor.GetMouseState(); +// Logger.LogInformation("当前鼠标状态:{X} {Y}", ms2.X, ms2.Y); +// var angle2 = GetCharacterOrientationAngle(); +// var angleOffset = angle2 - angle1; +// var directInputXOffset = ms2.X - ms1.X; +// Logger.LogInformation("横向移动偏移量校准:鼠标平移{CharMovingUnit}单位,角度转动{AngleOffset},DirectInput移动{DirectInputXOffset}", +// CharMovingUnit, angleOffset, directInputXOffset); +// +// var angle2MouseMoveByX = CharMovingUnit * 1d / angleOffset; +// var angle2DirectInputX = directInputXOffset * 1d / angleOffset; +// Logger.LogInformation("校准结果:视角每移动1度,需要MouseMoveBy的距离{Angle2MouseMoveByX},需要DirectInput移动的单位{Angle2DirectInputX}", +// angle2MouseMoveByX, angle2DirectInputX); +// +// return angleOffset; +// } +// +// public Mat? GetMiniMapMat(ImageRegion ra) +// { +// var paimon = ra.Find(ElementAssets.Instance.PaimonMenuRo); +// if (paimon.IsExist()) +// { +// return new Mat(ra.SrcMat, new Rect(paimon.X + 24, paimon.Y - 15, 210, 210)); +// } +// +// return null; +// } +// +// public int GetCharacterOrientationAngle() +// { +// var ra = GetRectAreaFromDispatcher(); +// var miniMapMat = GetMiniMapMat(ra); +// if (miniMapMat == null) +// { +// throw new InvalidOperationException("当前不在主界面"); +// } +// +// var angle = CharacterOrientation.Compute(miniMapMat); +// Logger.LogInformation("当前角度:{Angle}", angle); +// // CameraOrientation.DrawDirection(ra, angle); +// return angle; +// } +// } diff --git a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs index 97e41440..a3b8c636 100644 --- a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs +++ b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs @@ -74,7 +74,7 @@ public class AutoDomainTask Init(); NotificationHelper.SendTaskNotificationWithScreenshotUsing(b => b.Domain().Started().Build()); - var combatScenes = new CombatScenes().InitializeTeam(GetRectAreaFromDispatcher()); + var combatScenes = new CombatScenes().InitializeTeam(CaptureToRectArea()); // 前置进入秘境 EnterDomain(); @@ -185,7 +185,7 @@ public class AutoDomainTask { if (!combatScenes.CheckTeamInitialized()) { - combatScenes.InitializeTeam(GetRectAreaFromDispatcher()); + combatScenes.InitializeTeam(CaptureToRectArea()); if (!combatScenes.CheckTeamInitialized()) { throw new Exception("识别队伍角色失败,请在较暗背景下重试,比如游戏时间调整成夜晚。或者直接使用强制指定当前队伍角色的功能。"); @@ -197,7 +197,7 @@ public class AutoDomainTask { var fightAssets = AutoFightContext.Instance.FightAssets; - using var fRectArea = GetRectAreaFromDispatcher().Find(AutoPickAssets.Instance.FRo); + using var fRectArea = CaptureToRectArea().Find(AutoPickAssets.Instance.FRo); if (!fRectArea.IsEmpty()) { Simulation.SendInput.Keyboard.KeyPress(VK.VK_F); @@ -210,7 +210,7 @@ public class AutoDomainTask while (retryTimes < 20 && clickCount < 2) { retryTimes++; - using var confirmRectArea = GetRectAreaFromDispatcher().Find(fightAssets.ConfirmRa); + using var confirmRectArea = CaptureToRectArea().Find(fightAssets.ConfirmRa); if (!confirmRectArea.IsEmpty()) { confirmRectArea.Click(); @@ -231,7 +231,7 @@ public class AutoDomainTask while (retryTimes < 120) { retryTimes++; - using var cactRectArea = GetRectAreaFromDispatcher().Find(AutoFightContext.Instance.FightAssets.ClickAnyCloseTipRa); + using var cactRectArea = CaptureToRectArea().Find(AutoFightContext.Instance.FightAssets.ClickAnyCloseTipRa); if (!cactRectArea.IsEmpty()) { Sleep(1000, _taskParam.Cts); @@ -265,7 +265,7 @@ public class AutoDomainTask return; } - await Task.Run(() => + await Task.Run((Action)(() => { _simulator.KeyDown(VK.VK_W); Sleep(20); @@ -279,7 +279,7 @@ public class AutoDomainTask { while (!_taskParam.Cts.Token.IsCancellationRequested) { - using var fRectArea = GetRectAreaFromDispatcher().Find(AutoPickAssets.Instance.FRo); + using var fRectArea = Common.TaskControl.CaptureToRectArea().Find(AutoPickAssets.Instance.FRo); if (fRectArea.IsEmpty()) { Sleep(100, _taskParam.Cts); @@ -301,7 +301,7 @@ public class AutoDomainTask Simulation.SendInput.Keyboard.KeyUp(VK.VK_SHIFT); } } - }); + })); } private Task StartFight(CombatScenes combatScenes, List combatCommands) @@ -386,7 +386,7 @@ public class AutoDomainTask private bool IsDomainEnd() { - using var ra = GetRectAreaFromDispatcher(); + using var ra = CaptureToRectArea(); var endTipsRect = ra.DeriveCrop(AutoFightContext.Instance.FightAssets.EndTipsUpperRect); var text = OcrFactory.Paddle.Ocr(endTipsRect.SrcGreyMat); @@ -440,7 +440,7 @@ public class AutoDomainTask var backwardsAndForwardsCount = 0; while (!_taskParam.Cts.Token.IsCancellationRequested) { - var treeRect = DetectTree(GetRectAreaFromDispatcher()); + var treeRect = DetectTree(CaptureToRectArea()); if (treeRect != Rect.Empty) { var treeMiddleX = treeRect.X + treeRect.Width / 2; @@ -610,7 +610,7 @@ public class AutoDomainTask var started = false; while (!cts.Token.IsCancellationRequested) { - using var captureRegion = GetRectAreaFromDispatcher(); + using var captureRegion = CaptureToRectArea(); var angle = CameraOrientation.Compute(captureRegion.SrcGreyMat); CameraOrientation.DrawDirection(captureRegion, angle); if (angle is >= 356 or <= 4) @@ -685,7 +685,7 @@ public class AutoDomainTask break; } - var useCondensedResinRa = GetRectAreaFromDispatcher().Find(AutoFightContext.Instance.FightAssets.UseCondensedResinRa); + var useCondensedResinRa = CaptureToRectArea().Find(AutoFightContext.Instance.FightAssets.UseCondensedResinRa); if (!useCondensedResinRa.IsEmpty()) { useCondensedResinRa.Click(); @@ -710,7 +710,7 @@ public class AutoDomainTask GameCaptureRegion.GameRegionClick((size, scale) => (size.Width - 140 * scale, 53 * scale)); // 优先点击继续 - var ra = GetRectAreaFromDispatcher(); + var ra = CaptureToRectArea(); var confirmRectArea = ra.Find(AutoFightContext.Instance.FightAssets.ConfirmRa); if (!confirmRectArea.IsEmpty()) { @@ -764,7 +764,7 @@ public class AutoDomainTask var condensedResinCount = 0; var fragileResinCount = 0; - var ra = GetRectAreaFromDispatcher(); + var ra = CaptureToRectArea(); // 浓缩树脂 var condensedResinCountRa = ra.Find(AutoFightContext.Instance.FightAssets.CondensedResinCountRa); if (!condensedResinCountRa.IsEmpty()) diff --git a/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs b/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs index 77941912..50698691 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs @@ -38,7 +38,7 @@ public class AutoFightTask } Init(); - var combatScenes = new CombatScenes().InitializeTeam(GetRectAreaFromDispatcher()); + var combatScenes = new CombatScenes().InitializeTeam(CaptureToRectArea()); if (!combatScenes.CheckTeamInitialized()) { throw new Exception("识别队伍角色失败"); diff --git a/BetterGenshinImpact/GameTask/AutoFight/Model/Avatar.cs b/BetterGenshinImpact/GameTask/AutoFight/Model/Avatar.cs index b679e66a..c5db2167 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/Model/Avatar.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/Model/Avatar.cs @@ -128,7 +128,7 @@ public class Avatar return; } - var region = GetRectAreaFromDispatcher(); + var region = CaptureToRectArea(); ThrowWhenDefeated(region); var notActiveCount = CombatScenes.Avatars.Count(avatar => !avatar.IsActive(region)); @@ -152,7 +152,7 @@ public class Avatar { for (var i = 0; i < 10; i++) { - var region = GetRectAreaFromDispatcher(); + var region = CaptureToRectArea(); ThrowWhenDefeated(region); var notActiveCount = CombatScenes.Avatars.Count(avatar => !avatar.IsActive(region)); @@ -301,7 +301,7 @@ public class Avatar Sleep(200, Cts); - var region = GetRectAreaFromDispatcher(); + var region = CaptureToRectArea(); ThrowWhenDefeated(region); var cd = GetSkillCurrentCd(region); if (cd > 0) @@ -342,7 +342,7 @@ public class Avatar AutoFightContext.Instance.Simulator.KeyPress(User32.VK.VK_Q); Sleep(200, Cts); - var region = GetRectAreaFromDispatcher(); + var region = CaptureToRectArea(); ThrowWhenDefeated(region); var notActiveCount = CombatScenes.Avatars.Count(avatar => !avatar.IsActive(region)); if (notActiveCount == 0) diff --git a/BetterGenshinImpact/GameTask/AutoFight/OneKeyFightTask.cs b/BetterGenshinImpact/GameTask/AutoFight/OneKeyFightTask.cs index ee454340..5ac78f12 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/OneKeyFightTask.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/OneKeyFightTask.cs @@ -136,7 +136,7 @@ public class OneKeyFightTask : Singleton Sleep(TaskContext.Instance().Config.TriggerInterval * 2, cts); // 等待缓存图像 } - var imageRegion = GetRectAreaFromDispatcher(); + var imageRegion = CaptureToRectArea(); var combatScenes = new CombatScenes().InitializeTeam(imageRegion); if (!combatScenes.CheckTeamInitialized()) { diff --git a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs index 3ef11f31..524270fc 100644 --- a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs +++ b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs @@ -76,7 +76,7 @@ public class Duel LogScreenResolution(); _logger.LogInformation("========================================"); _logger.LogInformation("→ {Text}", "全自动七圣召唤,启动!"); - NotificationHelper.SendTaskNotificationUsing(b => b.GeniusInvocation().Started().WithScreenshot(TaskControl.CaptureGameBitmap()).Build()); + NotificationHelper.SendTaskNotificationUsing(b => b.GeniusInvocation().Started().Build()); GeniusInvokationControl.GetInstance().Init(taskParam); SystemControl.ActivateWindow(); @@ -304,13 +304,13 @@ public class Duel catch (TaskCanceledException ex) { _logger.LogInformation(ex.Message); - NotificationHelper.SendTaskNotificationUsing(b => b.GeniusInvocation().Cancelled().WithScreenshot(TaskControl.CaptureGameBitmap()).Build()); + NotificationHelper.SendTaskNotificationUsing(b => b.GeniusInvocation().Cancelled().Build()); } catch (NormalEndException ex) { _logger.LogInformation(ex.Message); _logger.LogInformation("对局结束"); - NotificationHelper.SendTaskNotificationUsing(b => b.GeniusInvocation().Success().WithScreenshot(TaskControl.CaptureGameBitmap()).Build()); + NotificationHelper.SendTaskNotificationUsing(b => b.GeniusInvocation().Success().Build()); } catch (System.Exception ex) { @@ -320,7 +320,7 @@ public class Duel { _logger.LogError(ex.StackTrace); } - NotificationHelper.SendTaskNotificationUsing(b => b.GeniusInvocation().Failure().WithScreenshot(TaskControl.CaptureGameBitmap()).Build()); + NotificationHelper.SendTaskNotificationUsing(b => b.GeniusInvocation().Failure().Build()); } finally { diff --git a/BetterGenshinImpact/GameTask/AutoSkip/AutoTrackTask.cs b/BetterGenshinImpact/GameTask/AutoSkip/AutoTrackTask.cs index cfc1e4e2..20ad7f2e 100644 --- a/BetterGenshinImpact/GameTask/AutoSkip/AutoTrackTask.cs +++ b/BetterGenshinImpact/GameTask/AutoSkip/AutoTrackTask.cs @@ -83,7 +83,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask private void TrackMission() { // 确认在主界面才会执行跟随任务 - var ra = GetRectAreaFromDispatcher(); + var ra = CaptureToRectArea(); var paimonMenuRa = ra.Find(ElementAssets.Instance.PaimonMenuRo); if (!paimonMenuRa.IsExist()) { @@ -122,7 +122,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask Sleep(1500, param.Cts); // 寻找所有传送点 - ra = GetRectAreaFromDispatcher(); + ra = CaptureToRectArea(); var tpPointList = MatchTemplateHelper.MatchMultiPicForOnePic(ra.SrcGreyMat, QuickTeleportAssets.Instance.MapChooseIconGreyMatList); if (tpPointList.Count > 0) { @@ -145,7 +145,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask // 等待自动传送完成 Sleep(2000, param.Cts); - if (Bv.IsInBigMapUi(GetRectAreaFromDispatcher())) + if (Bv.IsInBigMapUi(CaptureToRectArea())) { Logger.LogWarning("仍旧在大地图界面,传送失败"); } @@ -154,7 +154,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask Sleep(500, param.Cts); NewRetry.Do(() => { - if (!Bv.IsInMainUi(GetRectAreaFromDispatcher())) + if (!Bv.IsInMainUi(CaptureToRectArea())) { Logger.LogInformation("未进入到主界面,继续等待"); throw new RetryException("未进入到主界面"); @@ -180,7 +180,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_V); Sleep(3000, param.Cts); - var ra = GetRectAreaFromDispatcher(); + var ra = CaptureToRectArea(); var blueTrackPointRa = ra.Find(ElementAssets.Instance.BlueTrackPoint); if (blueTrackPointRa.IsExist()) { @@ -203,7 +203,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask bool wDown = false; while (!param.Cts.Token.IsCancellationRequested) { - var ra = GetRectAreaFromDispatcher(); + var ra = CaptureToRectArea(); var blueTrackPointRa = ra.Find(ElementAssets.Instance.BlueTrackPoint); if (blueTrackPointRa.IsExist()) { @@ -297,7 +297,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask private List OcrMissionTextRaList(Region paimonMenuRa) { - return GetRectAreaFromDispatcher().FindMulti(new RecognitionObject + return CaptureToRectArea().FindMulti(new RecognitionObject { RecognitionType = RecognitionTypes.Ocr, RegionOfInterest = new Rect(paimonMenuRa.X, paimonMenuRa.Y - 15 + 210, diff --git a/BetterGenshinImpact/GameTask/AutoTrackPath/AutoTrackPathTask.cs b/BetterGenshinImpact/GameTask/AutoTrackPath/AutoTrackPathTask.cs index e32fa9e6..e1bbf6ea 100644 --- a/BetterGenshinImpact/GameTask/AutoTrackPath/AutoTrackPathTask.cs +++ b/BetterGenshinImpact/GameTask/AutoTrackPath/AutoTrackPathTask.cs @@ -124,15 +124,15 @@ public class AutoTrackPathTask // 2. 等待传送完成 Sleep(1000); - NewRetry.Do(() => + NewRetry.Do((Action)(() => { - var ra = GetRectAreaFromDispatcher(); + var ra = TaskControl.CaptureToRectArea(); var miniMapMat = GetMiniMapMat(ra); if (miniMapMat == null) { throw new RetryException("等待传送完成"); } - }, TimeSpan.FromSeconds(1), 100); + }), TimeSpan.FromSeconds(1), 100); Logger.LogInformation("传送完成"); Sleep(1000); @@ -194,7 +194,7 @@ public class AutoTrackPathTask { while (!_taskParam.Cts.Token.IsCancellationRequested && !trackCts.Token.IsCancellationRequested) { - using var ra = GetRectAreaFromDispatcher(); + using var ra = CaptureToRectArea(); _motionStatus = Bv.GetMotionStatus(ra); // var miniMapMat = GetMiniMapMat(ra); @@ -222,7 +222,7 @@ public class AutoTrackPathTask var currIndex = 0; while (!_taskParam.Cts.IsCancellationRequested) { - var ra = GetRectAreaFromDispatcher(); + var ra = CaptureToRectArea(); var miniMapMat = GetMiniMapMat(ra); if (miniMapMat == null) { @@ -362,7 +362,7 @@ public class AutoTrackPathTask public int GetCharacterOrientationAngle() { - var ra = GetRectAreaFromDispatcher(); + var ra = CaptureToRectArea(); var miniMapMat = GetMiniMapMat(ra); if (miniMapMat == null) { @@ -417,7 +417,7 @@ public class AutoTrackPathTask var clickX = (int)((picX - picRect.X) / picRect.Width * captureRect.Width); var clickY = (int)((picY - picRect.Y) / picRect.Height * captureRect.Height); Logger.LogInformation("点击传送点:({X},{Y})", clickX, clickY); - using var ra = GetRectAreaFromDispatcher(); + using var ra = CaptureToRectArea(); ra.ClickTo(clickX, clickY); // 触发一次快速传送功能 @@ -514,7 +514,7 @@ public class AutoTrackPathTask public static Rect GetBigMapRect() { // 判断是否在地图界面 - using var ra = GetRectAreaFromDispatcher(); + using var ra = CaptureToRectArea(); using var mapScaleButtonRa = ra.Find(QuickTeleportAssets.Instance.MapScaleButtonRo); if (mapScaleButtonRa.IsExist()) { @@ -576,7 +576,7 @@ public class AutoTrackPathTask { GameCaptureRegion.GameRegionClick((rect, scale) => (rect.Width - 160 * scale, rect.Height - 60 * scale)); Sleep(200, _taskParam.Cts); - var ra = GetRectAreaFromDispatcher(); + var ra = CaptureToRectArea(); var list = ra.FindMulti(new RecognitionObject { RecognitionType = RecognitionTypes.Ocr, diff --git a/BetterGenshinImpact/GameTask/AutoTrackPath/PathPointRecorder.cs b/BetterGenshinImpact/GameTask/AutoTrackPath/PathPointRecorder.cs index d804a886..aee9b2cd 100644 --- a/BetterGenshinImpact/GameTask/AutoTrackPath/PathPointRecorder.cs +++ b/BetterGenshinImpact/GameTask/AutoTrackPath/PathPointRecorder.cs @@ -67,7 +67,7 @@ public class PathPointRecorder : Singleton try { Sleep(10, cts); - var ra = GetRectAreaFromDispatcher(); + var ra = CaptureToRectArea(); // 小地图匹配 var tar = ElementAssets.Instance.PaimonMenuRo.TemplateImageGreyMat!; diff --git a/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs b/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs index 3606d1d6..c4dd919a 100644 --- a/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs +++ b/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs @@ -44,7 +44,7 @@ public class TpTask(CancellationTokenSource cts) Logger.LogInformation("({TpX},{TpY}) 最近的传送点位置 ({X},{Y})", tpX, tpY, x, y); // M 打开地图识别当前位置,中心点为当前位置 - using var ra1 = GetRectAreaFromDispatcher(); + using var ra1 = CaptureToRectArea(); if (!Bv.IsInBigMapUi(ra1)) { Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_M); @@ -73,7 +73,7 @@ public class TpTask(CancellationTokenSource cts) var clickX = (int)((picX - picRect.X) / picRect.Width * captureRect.Width); var clickY = (int)((picY - picRect.Y) / picRect.Height * captureRect.Height); Logger.LogInformation("点击传送点:({X},{Y})", clickX, clickY); - using var ra = GetRectAreaFromDispatcher(); + using var ra = CaptureToRectArea(); ra.ClickTo(clickX, clickY); // 触发一次快速传送功能 @@ -174,7 +174,7 @@ public class TpTask(CancellationTokenSource cts) public Rect GetBigMapRect() { // 判断是否在地图界面 - using var ra = GetRectAreaFromDispatcher(); + using var ra = CaptureToRectArea(); using var mapScaleButtonRa = ra.Find(QuickTeleportAssets.Instance.MapScaleButtonRo); if (mapScaleButtonRa.IsExist()) { @@ -240,7 +240,7 @@ public class TpTask(CancellationTokenSource cts) { GameCaptureRegion.GameRegionClick((rect, scale) => (rect.Width - 160 * scale, rect.Height - 60 * scale)); await Delay(300, cts); - var ra = GetRectAreaFromDispatcher(); + var ra = CaptureToRectArea(); var list = ra.FindMulti(new RecognitionObject { RecognitionType = RecognitionTypes.Ocr, diff --git a/BetterGenshinImpact/GameTask/Common/TaskControl.cs b/BetterGenshinImpact/GameTask/Common/TaskControl.cs index b560678c..0fb5de20 100644 --- a/BetterGenshinImpact/GameTask/Common/TaskControl.cs +++ b/BetterGenshinImpact/GameTask/Common/TaskControl.cs @@ -104,7 +104,7 @@ public class TaskControl } } - private static Bitmap CaptureGameBitmap(IGameCapture? gameCapture) + public static Bitmap CaptureGameBitmap(IGameCapture? gameCapture) { var bitmap = gameCapture?.Capture(); // wgc 缓冲区设置的2 所以至少截图3次 @@ -140,12 +140,6 @@ public class TaskControl } } - [Obsolete] - public static Bitmap CaptureGameBitmap() - { - return CaptureGameBitmap(TaskTriggerDispatcher.GlobalGameCapture); - } - private static CaptureContent CaptureToContent(IGameCapture? gameCapture) { var bitmap = CaptureGameBitmap(gameCapture); @@ -158,10 +152,10 @@ public class TaskControl // return CaptureToContent(TaskTriggerDispatcher.GlobalGameCapture); // } - public static ImageRegion CaptureToRectArea() - { - return CaptureToContent(TaskTriggerDispatcher.GlobalGameCapture).CaptureRectArea; - } + // public static ImageRegion CaptureToRectArea() + // { + // return CaptureToContent(TaskTriggerDispatcher.GlobalGameCapture).CaptureRectArea; + // } // /// // /// 此方法 TaskDispatcher至少处于 DispatcherCaptureModeEnum.CacheCaptureWithTrigger 状态才能使用 @@ -173,12 +167,21 @@ public class TaskControl // return TaskTriggerDispatcher.Instance().GetLastCaptureContent(); // } + // /// + // /// 此方法 TaskDispatcher至少处于 DispatcherCaptureModeEnum.CacheCaptureWithTrigger 状态才能使用 + // /// + // /// + // public static ImageRegion GetRectAreaFromDispatcher() + // { + // return TaskTriggerDispatcher.Instance().GetLastCaptureContent().CaptureRectArea; + // } + /// - /// 此方法 TaskDispatcher至少处于 DispatcherCaptureModeEnum.CacheCaptureWithTrigger 状态才能使用 + /// 自动判断当前运行上下文中截图方式,并选择合适的截图方式返回 /// /// - public static ImageRegion GetRectAreaFromDispatcher() + public static ImageRegion CaptureToRectArea() { - return TaskTriggerDispatcher.Instance().GetLastCaptureContent().CaptureRectArea; + return TaskTriggerDispatcher.Instance().CaptureToRectArea(); } } diff --git a/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs b/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs index 0b4c8232..17317ef5 100644 --- a/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs +++ b/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs @@ -26,6 +26,8 @@ using BetterGenshinImpact.GameTask.AutoSkip.Model; using Vanara.PInvoke; using BetterGenshinImpact.GameTask.AutoMusicGame; using BetterGenshinImpact.GameTask.AutoTrackPath; +using BetterGenshinImpact.GameTask.Common; +using BetterGenshinImpact.GameTask.Model.Area; namespace BetterGenshinImpact.GameTask { @@ -331,7 +333,7 @@ namespace BetterGenshinImpact.GameTask } else { - var runningTriggers = _triggers.Where(t => t.IsEnabled); + var runningTriggers = _triggers!.Where(t => t.IsEnabled); if (hasBackgroundTriggerToRun) { runningTriggers = runningTriggers.Where(t => t.IsBackgroundRunning); @@ -458,6 +460,21 @@ namespace BetterGenshinImpact.GameTask return new CaptureContent(bitmap, _frameIndex, _timer.Interval); } + public ImageRegion CaptureToRectArea() + { + // 触发器启动的情况下优先使用触发器的截图 + if (_timer.Enabled && _dispatcherCacheCaptureMode is DispatcherCaptureModeEnum.OnlyCacheCapture or DispatcherCaptureModeEnum.CacheCaptureWithTrigger) + { + return GetLastCaptureContent().CaptureRectArea; + } + else + { + var bitmap = TaskControl.CaptureGameBitmap(GameCapture); + var content = new CaptureContent(bitmap, 0, 0); + return content.CaptureRectArea; + } + } + public void TakeScreenshot() { if (_dispatcherCacheCaptureMode is DispatcherCaptureModeEnum.OnlyCacheCapture or DispatcherCaptureModeEnum.CacheCaptureWithTrigger) diff --git a/BetterGenshinImpact/Service/Notification/NotificationHelper.cs b/BetterGenshinImpact/Service/Notification/NotificationHelper.cs index 44c35c15..88cccb12 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationHelper.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationHelper.cs @@ -22,7 +22,7 @@ public class NotificationHelper public static void SendTaskNotificationWithScreenshotUsing(Func builderFunc) { var builder = new TaskNotificationBuilder(); - var screenShot = (Bitmap)TaskControl.GetRectAreaFromDispatcher().SrcBitmap.Clone(); + var screenShot = (Bitmap)TaskControl.CaptureToRectArea().SrcBitmap.Clone(); Notify(builderFunc(builder.WithScreenshot(screenShot))); } }