diff --git a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs index 466d5e95..6a6c0451 100644 --- a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs +++ b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs @@ -2,7 +2,6 @@ using BetterGenshinImpact.GameTask.AutoPathing.Model; using BetterGenshinImpact.GameTask.AutoPathing.Model.Enum; using BetterGenshinImpact.GameTask.AutoTrackPath; -using BetterGenshinImpact.GameTask.Common; using BetterGenshinImpact.GameTask.Common.BgiVision; using BetterGenshinImpact.GameTask.Common.Map; using BetterGenshinImpact.GameTask.Model.Area; @@ -16,7 +15,6 @@ using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; -using BetterGenshinImpact.Helpers; using Vanara.PInvoke; using static BetterGenshinImpact.GameTask.Common.TaskControl; @@ -28,22 +26,59 @@ public class PathExecutor(CancellationTokenSource cts) public async Task Pathing(PathingTask task) { - _dpi = DpiHelper.ScaleY; - if (task.Positions.Count == 0) + _dpi = TaskContext.Instance().DpiScale; + if (!task.Positions.Any()) { Logger.LogWarning("没有路径点,寻路结束"); return; } - task.Positions.First().Type = WaypointType.Teleport.Code; + InitializePathing(task); - // 初始化查看地图 + var waypoints = ConvertWaypoints(task.Positions); + + await Delay(100, cts); + Navigation.WarmUp(); // 提前加载地图特征点 + + try + { + foreach (var waypoint in waypoints) + { + if (waypoint.Type == WaypointType.Teleport.Code) + { + await HandleTeleportWaypoint(waypoint); + } + else + { + // Path不用走得很近,Target需要接近,但都需要先移动到对应位置 + await MoveTo(waypoint); + + if (waypoint.Type == WaypointType.Target.Code || !string.IsNullOrEmpty(waypoint.Action)) + { + await MoveCloseTo(waypoint); + } + } + } + } + finally + { + // 不管咋样,松开所有按键 + Simulation.SendInput.Keyboard.KeyUp(User32.VK.VK_W); + Simulation.SendInput.Mouse.RightButtonUp(); + } + } + + private void InitializePathing(PathingTask task) + { + task.Positions.First().Type = WaypointType.Teleport.Code; WeakReferenceMessenger.Default.Send(new PropertyChangedMessage(this, "UpdateCurrentPathing", new object(), task)); + } - // 大地图传送的时候使用游戏坐标,追踪的时候应该使用2048地图图像坐标,这里临时做转换,后续改进 + private List ConvertWaypoints(List positions) + { var waypoints = new List(); - foreach (var waypoint in task.Positions) + foreach (var waypoint in positions) { if (waypoint.Type == WaypointType.Teleport.Code) { @@ -59,30 +94,14 @@ public class PathExecutor(CancellationTokenSource cts) (waypointCopy.X, waypointCopy.Y) = MapCoordinate.GameToMain2048(waypoint.X, waypoint.Y); waypoints.Add(waypointCopy); } + return waypoints; + } - await Delay(100, cts); - Navigation.WarmUp(); // 提前加载地图特征点 - - foreach (var waypoint in waypoints) - { - if (waypoint.Type == WaypointType.Teleport.Code) - { - // Logger.LogInformation("正在传送到{x},{y}", waypoint.X, waypoint.Y); - var (tpX, tpY) = await new TpTask(cts).Tp(waypoint.X, waypoint.Y); - var (tprX, tprY) = MapCoordinate.GameToMain2048(tpX, tpY); - EntireMap.Instance.SetPrevPosition((float)tprX, (float)tprY); // 通过上一个位置直接进行局部特征匹配 - continue; - } - - // Path不用走得很近,Target需要接近,但都需要先移动到对应位置 - - await MoveTo(waypoint); - - if (waypoint.Type == WaypointType.Target.Code || !string.IsNullOrEmpty(waypoint.Action)) - { - await MoveCloseTo(waypoint); - } - } + private async Task HandleTeleportWaypoint(Waypoint waypoint) + { + var (tpX, tpY) = await new TpTask(cts).Tp(waypoint.X, waypoint.Y); + var (tprX, tprY) = MapCoordinate.GameToMain2048(tpX, tpY); + EntireMap.Instance.SetPrevPosition((float)tprX, (float)tprY); // 通过上一个位置直接进行局部特征匹配 } private async Task MoveTo(Waypoint waypoint) @@ -90,7 +109,7 @@ public class PathExecutor(CancellationTokenSource cts) var screen = CaptureToRectArea(); var position = Navigation.GetPosition(screen); var targetOrientation = Navigation.GetTargetOrientation(waypoint, position); - Logger.LogInformation("粗略接近途经点,位置({x2},{y2})", waypoint.X, waypoint.Y); + Logger.LogInformation("粗略接近途经点,位置({x2},{y2})", $"{waypoint.X:F1}", $"{waypoint.Y:F1}"); await WaitUntilRotatedTo(targetOrientation, 5); var startTime = DateTime.UtcNow; var lastPositionRecord = DateTime.UtcNow; @@ -195,7 +214,7 @@ public class PathExecutor(CancellationTokenSource cts) var screen = CaptureToRectArea(); var position = Navigation.GetPosition(screen); var targetOrientation = Navigation.GetTargetOrientation(waypoint, position); - Logger.LogInformation("精确接近目标点,位置({x2},{y2})", waypoint.X, waypoint.Y); + Logger.LogInformation("精确接近目标点,位置({x2},{y2})", $"{waypoint.X:F1}", $"{waypoint.Y:F1}"); if (waypoint.MoveMode == MoveModeEnum.Fly.Code && waypoint.Action == ActionEnum.StopFlying.Code) { //下落攻击接近目的地 @@ -239,8 +258,6 @@ public class PathExecutor(CancellationTokenSource cts) { Simulation.SendInput.Keyboard.KeyUp(User32.VK.VK_W); } - // 不管咋样,抬起w键 - Simulation.SendInput.Keyboard.KeyUp(User32.VK.VK_W); } private int RotateTo(int targetOrientation, ImageRegion imageRegion, double controlRatio = 1) diff --git a/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs b/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs index 0c29bd44..5403802e 100644 --- a/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs +++ b/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs @@ -37,7 +37,7 @@ public class TpTask(CancellationTokenSource cts) { // 获取最近的传送点位置 var (x, y) = GetRecentlyTpPoint(tpX, tpY); - Logger.LogInformation("({TpX},{TpY}) 最近的传送点位置 ({X},{Y})", tpX, tpY, x, y); + Logger.LogInformation("({TpX},{TpY}) 最近的传送点位置 ({X},{Y})", $"{tpX:F1}", $"{tpY:F1}", $"{x:F1}", $"{y:F1}"); // M 打开地图识别当前位置,中心点为当前位置 using var ra1 = CaptureToRectArea(); diff --git a/BetterGenshinImpact/GameTask/TaskRunner.cs b/BetterGenshinImpact/GameTask/TaskRunner.cs index 9d5981d3..97a98215 100644 --- a/BetterGenshinImpact/GameTask/TaskRunner.cs +++ b/BetterGenshinImpact/GameTask/TaskRunner.cs @@ -94,7 +94,7 @@ public class TaskRunner Task.Run(() => RunAsync(action)); } - public async Task FireAndForgetAsync(Func action) + public async Task RunThreadAsync(Func action) { await Task.Run(() => RunAsync(action)); } diff --git a/BetterGenshinImpact/Helpers/DpiHelper.cs b/BetterGenshinImpact/Helpers/DpiHelper.cs index 2b618592..7abd2afb 100644 --- a/BetterGenshinImpact/Helpers/DpiHelper.cs +++ b/BetterGenshinImpact/Helpers/DpiHelper.cs @@ -8,6 +8,9 @@ namespace BetterGenshinImpact.Helpers; public class DpiHelper { + /// + /// 只能主线程调用 + /// public static float ScaleY => GetScaleY(); private static float GetScaleY() diff --git a/BetterGenshinImpact/Service/ScriptService.cs b/BetterGenshinImpact/Service/ScriptService.cs index 525feda1..e05df48d 100644 --- a/BetterGenshinImpact/Service/ScriptService.cs +++ b/BetterGenshinImpact/Service/ScriptService.cs @@ -44,7 +44,7 @@ public partial class ScriptService(HomePageViewModel homePageViewModel) : IScrip // 循环执行所有脚本 var timerOperation = hasTimer ? DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty : DispatcherTimerOperationEnum.UseSelfCaptureImage; await new TaskRunner(timerOperation) - .RunAsync(async () => + .RunThreadAsync(async () => { foreach (var project in projects) { @@ -145,7 +145,7 @@ public partial class ScriptService(HomePageViewModel homePageViewModel) : IScrip var timerOperation = hasTimer ? DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty : DispatcherTimerOperationEnum.UseSelfCaptureImage; await new TaskRunner(timerOperation) - .FireAndForgetAsync(async () => + .RunThreadAsync(async () => { foreach (var project in list) { diff --git a/BetterGenshinImpact/User/pick_black_lists.json b/BetterGenshinImpact/User/pick_black_lists.json index 745ff11c..ab9ee3c0 100644 --- a/BetterGenshinImpact/User/pick_black_lists.json +++ b/BetterGenshinImpact/User/pick_black_lists.json @@ -2,6 +2,7 @@ "石之轮", "幻想真境剧诗", "开始演奏", + "摆放巧像", "摹刻巧像", "摹刻码像", "募刻巧像", diff --git a/BetterGenshinImpact/ViewModel/Pages/MapPathingViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/MapPathingViewModel.cs index 738957b1..2a506794 100644 --- a/BetterGenshinImpact/ViewModel/Pages/MapPathingViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/MapPathingViewModel.cs @@ -28,6 +28,8 @@ public partial class MapPathingViewModel : ObservableObject, INavigationAware, I [ObservableProperty] private ObservableCollection _pathItems = []; + private MapViewer? _mapViewer; + private void InitScriptListViewData() { _pathItems.Clear(); @@ -106,6 +108,7 @@ public partial class MapPathingViewModel : ObservableObject, INavigationAware, I [RelayCommand] public void OnOpenMapViewer() { - new MapViewer().Show(); + _mapViewer ??= new MapViewer(); + _mapViewer.Show(); } }