using BetterGenshinImpact.GameTask.Model.Area.Converter; using BetterGenshinImpact.View.Drawable; using OpenCvSharp; using System; using System.Diagnostics; using System.Drawing; using System.Threading; using Vanara.PInvoke; namespace BetterGenshinImpact.GameTask.Model.Area; /// /// 区域基类 /// 用于描述一个区域,可以是一个矩形,也可以是一个点 /// public class Region : IDisposable { public int X { get; set; } public int Y { get; set; } public int Width { get; set; } public int Height { get; set; } public int Top { get => Y; set => Y = value; } /// /// Gets the y-coordinate that is the sum of the Y and Height property values of this Rect structure. /// public int Bottom => Y + Height; /// /// Gets the x-coordinate of the left edge of this Rect structure. /// public int Left { get => X; set => X = value; } /// /// Gets the x-coordinate that is the sum of X and Width property values of this Rect structure. /// public int Right => X + Width; /// /// 存放OCR识别的结果文本 /// public string Text { get; set; } = string.Empty; public Region() { } public Region(int x, int y, int width, int height, Region? owner = null, INodeConverter? converter = null) { X = x; Y = y; Width = width; Height = height; Prev = owner; PrevConverter = converter; } public Region(Rect rect, Region? owner = null, INodeConverter? converter = null) : this(rect.X, rect.Y, rect.Width, rect.Height, owner, converter) { } public Region? Prev { get; } /// /// 本区域节点向上一个区域节点坐标的转换器 /// public INodeConverter? PrevConverter { get; } // public List? NextChildren { get; protected set; } /// /// 后台点击【自己】的中心 /// public void BackgroundClick() { User32.GetCursorPos(out var p); this.Move(); // 必须移动实际鼠标 TaskContext.Instance().PostMessageSimulator.LeftButtonClickBackground(); Thread.Sleep(10); DesktopRegion.DesktopRegionMove(p.X, p.Y); // 鼠标移动回原来位置 } /// /// 点击【自己】的中心 /// region.Derive(x,y).Click() 等效于 region.ClickTo(x,y) /// public void Click() { // 相对自己是 0, 0 坐标 ClickTo(0, 0, Width, Height); } /// /// 点击区域内【指定位置】 /// region.Derive(x,y).Click() 等效于 region.ClickTo(x,y) /// /// /// public void ClickTo(int x, int y) { ClickTo(x, y, 0, 0); } public void ClickTo(double dx, double dy) { var x = (int)Math.Round(dx); var y = (int)Math.Round(dy); ClickTo(x, y, 0, 0); } /// /// 点击区域内【指定矩形区域】的中心 /// /// /// /// /// /// public void ClickTo(int x, int y, int w, int h) { var res = ConvertRes.ConvertPositionToTargetRegion(x, y, w, h, this); res.TargetRegion.DesktopRegionClick(res.X, res.Y, res.Width, res.Height); } /// /// 移动到【自己】的中心 /// region.Derive(x,y).Move() 等效于 region.MoveTo(x,y) /// public void Move() { // 相对自己是 0, 0 坐标 MoveTo(0, 0, Width, Height); } /// /// 移动到区域内【指定位置】 /// region.Derive(x,y).Move() 等效于 region.MoveTo(x,y) /// /// /// public void MoveTo(int x, int y) { MoveTo(x, y, 0, 0); } /// /// 移动到区域内【指定矩形区域】的中心 /// /// /// /// /// /// public void MoveTo(int x, int y, int w, int h) { var res = ConvertRes.ConvertPositionToTargetRegion(x, y, w, h, this); res.TargetRegion.DesktopRegionMove(res.X, res.Y, res.Width, res.Height); } /// /// 直接在遮罩窗口绘制【自己】 /// /// /// public void DrawSelf(string name, Pen? pen = null) { // 相对自己是 0, 0 坐标 DrawRect(0, 0, Width, Height, name, pen); } /// /// 直接在遮罩窗口绘制当前区域下的【指定区域】 /// /// /// /// /// /// /// public void DrawRect(int x, int y, int w, int h, string name, Pen? pen = null) { var drawable = ToRectDrawable(x, y, w, h, name, pen); VisionContext.Instance().DrawContent.PutRect(name, drawable); } public void DrawRect(Rect rect, string name, Pen? pen = null) { var drawable = ToRectDrawable(rect.X, rect.Y, rect.Width, rect.Height, name, pen); VisionContext.Instance().DrawContent.PutRect(name, drawable); } /// /// 转换【自己】到遮罩窗口绘制矩形 /// /// /// /// public RectDrawable SelfToRectDrawable(string name, Pen? pen = null) { // 相对自己是 0, 0 坐标 return ToRectDrawable(0, 0, Width, Height, name, pen); } /// /// 转换【指定区域】到遮罩窗口绘制矩形 /// /// /// /// /// public RectDrawable ToRectDrawable(Rect rect, string name, Pen? pen = null) { return ToRectDrawable(rect.X, rect.Y, rect.Width, rect.Height, name, pen); } /// /// 转换【指定区域】到遮罩窗口绘制矩形 /// /// /// /// /// /// /// /// /// public RectDrawable ToRectDrawable(int x, int y, int w, int h, string name, Pen? pen = null) { var res = ConvertRes.ConvertPositionToTargetRegion(x, y, w, h, this); return res.TargetRegion.ConvertToRectDrawable(res.X, res.Y, res.Width, res.Height, pen, name); } /// /// 转换【指定直线】到遮罩窗口绘制直线 /// /// /// /// /// /// /// /// public LineDrawable ToLineDrawable(int x1, int y1, int x2, int y2, string name, Pen? pen = null) { var res1 = ConvertRes.ConvertPositionToTargetRegion(x1, y1, 0, 0, this); var res2 = ConvertRes.ConvertPositionToTargetRegion(x2, y2, 0, 0, this); return res1.TargetRegion.ConvertToLineDrawable(res1.X, res1.Y, res2.X, res2.Y, pen, name); } public void DrawLine(int x1, int y1, int x2, int y2, string name, Pen? pen = null) { var drawable = ToLineDrawable(x1, y1, x2, y2, name, pen); VisionContext.Instance().DrawContent.PutLine(name, drawable); } public Rect ConvertSelfPositionToGameCaptureRegion() { return ConvertPositionToGameCaptureRegion(X, Y, Width, Height); } public Rect ConvertPositionToGameCaptureRegion(int x, int y, int w, int h) { var res = ConvertRes.ConvertPositionToTargetRegion(x, y, w, h, this); return res.ToRect(); } public (int, int) ConvertPositionToGameCaptureRegion(int x, int y) { var res = ConvertRes.ConvertPositionToTargetRegion(x, y, 0, 0, this); return (res.X, res.Y); } public (int, int) ConvertPositionToDesktopRegion(int x, int y) { var res = ConvertRes.ConvertPositionToTargetRegion(x, y, 0, 0, this); return (res.X, res.Y); } public Rect ToRect() { return new Rect(X, Y, Width, Height); } /// /// 生成一个新的区域 /// 请使用 using var newRegion /// /// public ImageRegion ToImageRegion() { if (this is ImageRegion imageRegion) { Debug.WriteLine("ToImageRegion 但已经是 ImageRegion"); return imageRegion; } var res = ConvertRes.ConvertPositionToTargetRegion(0, 0, Width, Height, this); var newRegion = new ImageRegion(new Mat(res.TargetRegion.SrcMat, res.ToRect()), X, Y, Prev, PrevConverter); return newRegion; } public bool IsEmpty() { return Width == 0 && Height == 0 && X == 0 && Y == 0; } /// /// 语义化包装 /// /// public bool IsExist() { return !IsEmpty(); } public void Dispose() { // 子节点全部释放 // NextChildren?.ForEach(x => x.Dispose()); } /// /// 派生一个点类型的区域 /// /// /// /// public Region Derive(int x, int y) { return Derive(x, y, 0, 0); } /// /// 派生一个矩形类型的区域 /// /// /// /// /// /// public Region Derive(int x, int y, int w, int h) { return new Region(x, y, w, h, this, new TranslationConverter(x, y)); } public Region Derive(Rect rect) { return Derive(rect.X, rect.Y, rect.Width, rect.Height); } }