diff --git a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs index 08ac6c6f..252de922 100644 --- a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs +++ b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs @@ -2,6 +2,7 @@ using BetterGenshinImpact.Core.Recognition.OCR; using BetterGenshinImpact.Core.Recognition.ONNX; using BetterGenshinImpact.Core.Simulator; +using BetterGenshinImpact.GameTask.AutoEat; using BetterGenshinImpact.GameTask.AutoFight; using BetterGenshinImpact.GameTask.AutoFight.Assets; using BetterGenshinImpact.GameTask.AutoFight.Model; @@ -342,20 +343,26 @@ public class AutoDomainTask // 对局结束检测 var domainEndTask = DomainEndDetectionTask(cts); // TODO 自动吃药 - var autoEatTrigger = new AutoEat.AutoEatTrigger(); - var autoEatTask = new Task(() => { - while (!cts.Token.IsCancellationRequested) + if (GameTaskManager.TriggerDictionary != null && GameTaskManager.TriggerDictionary.TryGetValue("autoEat", out var trigger)) + { + var autoEatTrigger = trigger as AutoEatTrigger; + if (autoEatTrigger != null && autoEatTrigger.IsEnabled == true) { - autoEatTrigger.start(); - // 适当的延迟,防止高 CPU 占用 - Task.Delay(1000).Wait(); + var autoEatTask = new Task(() => + { + while (!cts.Token.IsCancellationRequested) + { + autoEatTrigger.start(); + // 适当的延迟,防止高 CPU 占用 + Task.Delay(autoEatTrigger.IntervalMs).Wait(); + } + }); + autoEatTask.Start(); } - }); + } combatTask.Start(); domainEndTask.Start(); - autoEatTask.Start(); - - return Task.WhenAll(combatTask, domainEndTask, autoEatTask); + return Task.WhenAll(combatTask, domainEndTask); } private void EndFightWait() diff --git a/BetterGenshinImpact/GameTask/AutoEat/AutoEatConfig.cs b/BetterGenshinImpact/GameTask/AutoEat/AutoEatConfig.cs new file mode 100644 index 00000000..b47dc8de --- /dev/null +++ b/BetterGenshinImpact/GameTask/AutoEat/AutoEatConfig.cs @@ -0,0 +1,26 @@ +using CommunityToolkit.Mvvm.ComponentModel; +using System; +using System.Collections.Generic; +using System.Text; + +namespace BetterGenshinImpact.GameTask.AutoEat; + + /// + ///自动吃加血药配置 + /// + [Serializable] +public partial class AutoEatConfig : ObservableObject +{ + /// + /// 触发器是否启用 + /// + [ObservableProperty] + private bool _enabled = false; + + /// + /// 触发器触发间隔 + /// + [ObservableProperty] + private int _intervalMs = 500; +} + diff --git a/BetterGenshinImpact/GameTask/AutoEat/AutoEatTrigger.cs b/BetterGenshinImpact/GameTask/AutoEat/AutoEatTrigger.cs new file mode 100644 index 00000000..91d37502 --- /dev/null +++ b/BetterGenshinImpact/GameTask/AutoEat/AutoEatTrigger.cs @@ -0,0 +1,81 @@ +using BetterGenshinImpact.Core.Simulator; +using BetterGenshinImpact.GameTask.AutoPick; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using Vanara.PInvoke; +using static System.Net.Mime.MediaTypeNames; + +namespace BetterGenshinImpact.GameTask.AutoEat; + +public class AutoEatTrigger : ITaskTrigger +{ + public string Name => "自动吃药"; + + public bool IsEnabled { get; set; } + + public int Priority => 10; + + public bool IsExclusive { get; set; } + + private int _frameIndex = 0; + + private User32.VK _pickVk = User32.VK.VK_Z; + private readonly ILogger _logger = App.GetLogger(); + + private DateTime _lastExecutionTime = DateTime.MinValue; // 记录上次执行的时间 + public int IntervalMs = 500; // 500ms 的执行间隔 + + public void Init() + { + IsEnabled = TaskContext.Instance().Config.AutoEatConfig.Enabled; + IntervalMs = TaskContext.Instance().Config.AutoEatConfig.IntervalMs; + IsExclusive = false; + } + + public void OnCapture(CaptureContent content) + { + var now = DateTime.Now; + // 判断是否已经超过了 500ms 的间隔 + if ((now - _lastExecutionTime).TotalMilliseconds < IntervalMs) + { + return; + } + // 获取位图对象 + var bitmap = content.SrcBitmap; + + // 获取 (808, 1010) 位置的像素颜色 + var pixelColor = bitmap.GetPixel(808, 1010); + + // 判断颜色是否是 (255, 90, 90) + if (pixelColor.R == 255 && pixelColor.G == 90 && pixelColor.B == 90) + { + // 模拟按键 "Z" + Simulation.SendInput.Keyboard.KeyPress(_pickVk); + _logger.LogInformation("按Z吃药"); + _lastExecutionTime = now; + // TODO 吃饱了会一直吃 + } + else + { + // _logger.LogInformation("识别的颜色 R:{R} G:{G} B:{B}",pixelColor.R, pixelColor.G, pixelColor.B); + } + } + + public void start() + { + // 帧序号自增 1分钟后归零(MaxFrameIndexSecond) + _frameIndex = (_frameIndex + 1) % (int)(CaptureContent.MaxFrameIndexSecond * 1000d / 50); + var bitmap = TaskTriggerDispatcher.GlobalGameCapture.Capture(); + if (bitmap == null) + { + _logger.LogWarning("截图失败!"); + return; + } + // 循环执行所有触发器 有独占状态的触发器的时候只执行独占触发器 + var content = new CaptureContent(bitmap, _frameIndex, 50); + OnCapture(content); + } +} diff --git a/BetterGenshinImpact/View/Pages/TriggerSettingsPage.xaml b/BetterGenshinImpact/View/Pages/TriggerSettingsPage.xaml index b7f3a453..5cc29f82 100644 --- a/BetterGenshinImpact/View/Pages/TriggerSettingsPage.xaml +++ b/BetterGenshinImpact/View/Pages/TriggerSettingsPage.xaml @@ -804,7 +804,7 @@ Grid.Column="0" Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}" TextWrapping="Wrap"> - 血红时自动吃药(不用时请关闭) + 血红时自动吃药。开启后自动秘境中也会生效。(使用时请保证z键带的是回血药,且数量足够)