using BetterGenshinImpact.Core.Config; using BetterGenshinImpact.Core.Recognition; using BetterGenshinImpact.Core.Recognition.OpenCv; using BetterGenshinImpact.GameTask.Common; using BetterGenshinImpact.GameTask.Model.Area; using BetterGenshinImpact.GameTask.QuickTeleport.Assets; using BetterGenshinImpact.Model; using Microsoft.Extensions.Logging; using OpenCvSharp; using System; using System.Linq; using System.Windows.Forms; namespace BetterGenshinImpact.GameTask.QuickTeleport; internal class QuickTeleportTrigger : ITaskTrigger { public string Name => "快速传送"; public bool IsEnabled { get; set; } public int Priority => 21; public bool IsExclusive { get; set; } private readonly QuickTeleportAssets _assets; private DateTime _prevClickOptionButtonTime = DateTime.MinValue; // private DateTime _prevClickTeleportButtonTime = DateTime.MinValue; private DateTime _prevExecute = DateTime.MinValue; private readonly QuickTeleportConfig _config; private readonly HotKeyConfig _hotkeyConfig; public QuickTeleportTrigger() { _assets = QuickTeleportAssets.Instance; _config = TaskContext.Instance().Config.QuickTeleportConfig; _hotkeyConfig = TaskContext.Instance().Config.HotKeyConfig; } public void Init() { IsEnabled = _config.Enabled; IsExclusive = false; } public void OnCapture(CaptureContent content) { if ((DateTime.Now - _prevExecute).TotalMilliseconds <= 300) { return; } // 快捷键传送配置启用的情况下,且快捷键按下的时候激活 if (_config.HotkeyTpEnabled && !string.IsNullOrEmpty(_hotkeyConfig.QuickTeleportTickHotkey)) { if (!IsHotkeyPressed()) { return; } } _prevExecute = DateTime.Now; IsExclusive = false; // 1.判断是否在地图界面 content.CaptureRectArea.Find(_assets.MapScaleButtonRo, _ => { IsExclusive = true; // 2. 判断是否有传送按钮 var hasTeleportButton = CheckTeleportButton(content.CaptureRectArea); if (!hasTeleportButton) { // 存在地图关闭按钮,说明未选中传送点,直接返回 var mapCloseRa = content.CaptureRectArea.Find(_assets.MapCloseButtonRo); if (!mapCloseRa.IsEmpty()) { return; } // 存在地图选择按钮,说明未选中传送点,直接返回 var mapChooseRa = content.CaptureRectArea.Find(_assets.MapChooseRo); if (!mapChooseRa.IsEmpty()) { return; } // 3. 循环判断选项列表是否有传送点 var hasMapChooseIcon = CheckMapChooseIcon(content); if (hasMapChooseIcon) { TaskControl.Sleep(_config.WaitTeleportPanelDelay); CheckTeleportButton(TaskControl.CaptureToRectArea(forceNew: true)); } } }); } private bool CheckTeleportButton(ImageRegion imageRegion) { var hasTeleportButton = false; imageRegion.Find(_assets.TeleportButtonRo, ra => { ra.Click(); hasTeleportButton = true; // if ((DateTime.Now - _prevClickTeleportButtonTime).TotalSeconds > 1) // { // TaskControl.Logger.LogInformation("快速传送:传送"); // } // _prevClickTeleportButtonTime = DateTime.Now; }); return hasTeleportButton; } /// /// 全匹配一遍并进行文字识别 /// 60ms ~200ms /// /// /// private bool CheckMapChooseIcon(CaptureContent content) { var hasMapChooseIcon = false; // 全匹配一遍 var rResultList = MatchTemplateHelper.MatchMultiPicForOnePic(content.CaptureRectArea.SrcGreyMat[_assets.MapChooseIconRoi], _assets.MapChooseIconGreyMatList); // 按高度排序 if (rResultList.Count > 0) { rResultList = [.. rResultList.OrderBy(x => x.Y)]; // 点击最高的 foreach (var iconRect in rResultList) { // 200宽度的文字区域 using var ra = content.CaptureRectArea.DeriveCrop(_assets.MapChooseIconRoi.X + iconRect.X + iconRect.Width, _assets.MapChooseIconRoi.Y + iconRect.Y - 8, 200, iconRect.Height + 16); using var textRegion = ra.Find(new RecognitionObject { // RecognitionType = RecognitionTypes.Ocr, RecognitionType = RecognitionTypes.ColorRangeAndOcr, LowerColor = new Scalar(249, 249, 249), // 只取白色文字 UpperColor = new Scalar(255, 255, 255), }); if (string.IsNullOrEmpty(textRegion.Text) || textRegion.Text.Length == 1) { continue; } if ((DateTime.Now - _prevClickOptionButtonTime).TotalMilliseconds > 500) { TaskControl.Logger.LogInformation("快速传送:点击 {Option}", textRegion.Text.Replace(">", "")); } _prevClickOptionButtonTime = DateTime.Now; TaskControl.Sleep(_config.TeleportListClickDelay); ra.Click(); hasMapChooseIcon = true; break; } } // List raResultList = new(); // foreach (var ro in _assets.MapChooseIconRoList) // { // var ra = content.CaptureRectArea.Find(ro); // if (!ra.IsEmpty()) // { // var text = GetOptionText(content.CaptureRectArea.SrcGreyMat, ra, 200); // if (string.IsNullOrEmpty(text) || text.Length == 1) // { // continue; // } // // if ((DateTime.Now - _prevClickOptionButtonTime).TotalMilliseconds > 500) // { // TaskControl.Logger.LogInformation("快速传送:点击 {Option}", text); // } // // _prevClickOptionButtonTime = DateTime.Now; // TaskControl.Sleep(_config.TeleportListClickDelay); // raResultList.Add(ra); // } // } // if (raResultList.Count > 0) // { // var highest = raResultList[0]; // foreach (var ra in raResultList) // { // if (ra.Y < highest.Y) // { // highest = ra; // } // } // // highest.ClickCenter(); // hasMapChooseIcon = true; // // foreach (var ra in raResultList) // { // ra.Dispose(); // } // } return hasMapChooseIcon; } // /// // /// 获取选项的文字 // /// // /// // /// // /// // /// // [Obsolete] // private string GetOptionText(Mat captureMat, Rect foundIconRect, int chatOptionTextWidth) // { // var textRect = new Rect(foundIconRect.X + foundIconRect.Width, foundIconRect.Y, chatOptionTextWidth, foundIconRect.Height); // using var mat = new Mat(captureMat, textRect); // var text = OcrFactory.Paddle.Ocr(mat); // return text; // } private bool IsHotkeyPressed() { if (HotKey.IsMouseButton(_hotkeyConfig.QuickTeleportTickHotkey)) { if (MouseHook.AllMouseHooks.TryGetValue((MouseButtons)Enum.Parse(typeof(MouseButtons), _hotkeyConfig.QuickTeleportTickHotkey), out var mouseHook)) { if (mouseHook.IsPressed) { return true; } } } else { if (KeyboardHook.AllKeyboardHooks.TryGetValue((Keys)Enum.Parse(typeof(Keys), _hotkeyConfig.QuickTeleportTickHotkey), out var keyboardHook)) { if (keyboardHook.IsPressed) { return true; } } } return false; } }