From 72a488cf777cb0a1f06899791cbe02cd379e92bc Mon Sep 17 00:00:00 2001 From: Xian55 <367101+Xian55@users.noreply.github.com> Date: Sat, 10 Dec 2022 14:09:32 +0100 Subject: [PATCH] CoreTests: Added Test_MinimapNodeFinder --- Core/BotController.cs | 3 +- Core/Minimap/MinimapNodeFinder.cs | 41 +++++----- .../Test_MinimapNodeFinder.cs | 77 +++++++++++++++++++ CoreTests/NpcNameFinder/Test_NpcNameFinder.cs | 2 +- CoreTests/Program.cs | 39 +++++++++- 5 files changed, 135 insertions(+), 27 deletions(-) create mode 100644 CoreTests/MinimapNodeFinder/Test_MinimapNodeFinder.cs diff --git a/Core/BotController.cs b/Core/BotController.cs index c4bb0b4e5..05f1381cd 100644 --- a/Core/BotController.cs +++ b/Core/BotController.cs @@ -162,7 +162,8 @@ private void ScreenshotThread() if (ClassConfig?.Mode == Mode.AttendedGather) { timestamp = Stopwatch.GetTimestamp(); - minimapNodeFinder.TryFind(); + WowScreen.UpdateMinimapBitmap(); + minimapNodeFinder.Update(); ScreenLatencys[tickCount % SIZE] = Stopwatch.GetElapsedTime(timestamp).TotalMilliseconds; } diff --git a/Core/Minimap/MinimapNodeFinder.cs b/Core/Minimap/MinimapNodeFinder.cs index b3ce2026b..0005629ea 100644 --- a/Core/Minimap/MinimapNodeFinder.cs +++ b/Core/Minimap/MinimapNodeFinder.cs @@ -16,12 +16,12 @@ namespace Core { public sealed class MinimapNodeFinder { - private readonly struct Point + private readonly struct PixelPoint { public readonly int X; public readonly int Y; - public Point(int x, int y) + public PixelPoint(int x, int y) { X = x; Y = y; @@ -44,20 +44,18 @@ public MinimapNodeFinder(ILogger logger, WowScreen wowScreen) this.wowScreen = wowScreen; } - public void TryFind() + public void Update() { - wowScreen.UpdateMinimapBitmap(); - var span = FindYellowPoints(); - ScorePoints(span, out Point best, out int amountAboveMin); + ScorePoints(span, out PixelPoint best, out int amountAboveMin); NodeEvent?.Invoke(this, new MinimapNodeEventArgs(best.X, best.Y, amountAboveMin)); } - private Span FindYellowPoints() + private Span FindYellowPoints() { const int SIZE = 100; - var pooler = ArrayPool.Shared; - Point[] points = pooler.Rent(SIZE); + var pooler = ArrayPool.Shared; + PixelPoint[] points = pooler.Rent(SIZE); Bitmap bitmap = wowScreen.MiniMapBitmap; @@ -69,14 +67,14 @@ private Span FindYellowPoints() int maxY = bitmap.Height - 6; Rectangle rect = new(minX, minY, maxX - minX, maxY - minY); - System.Drawing.Point center = rect.Centre(); + Point center = rect.Centre(); float radius = (maxX - minX) / 2f; int count = 0; unsafe { - BitmapData data = bitmap.LockBits(new Rectangle(System.Drawing.Point.Empty, bitmap.Size), + BitmapData data = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), DEBUG_MASK ? ImageLockMode.ReadWrite : ImageLockMode.ReadOnly, bitmap.PixelFormat); const int bytesPerPixel = 4; //Bitmap.GetPixelFormatSize(bitmap.PixelFormat) / 8; @@ -103,7 +101,7 @@ private Span FindYellowPoints() if (count >= SIZE) return; - points[count++] = new Point(x, y); + points[count++] = new PixelPoint(x, y); if (DEBUG_MASK) { @@ -120,14 +118,14 @@ private Span FindYellowPoints() if (count >= SIZE) { - logger.LogWarning("Too much yellow in this image!"); + //logger.LogWarning("Too much yellow in this image!"); } return points.AsSpan(0, count); - static bool IsValidSquareLocation(int x, int y, System.Drawing.Point center, float width) + static bool IsValidSquareLocation(int x, int y, Point center, float width) { - return Math.Sqrt(((x - center.X) * (x - center.X)) + ((y - center.Y) * (y - center.Y))) < width; + return MathF.Sqrt(((x - center.X) * (x - center.X)) + ((y - center.Y) * (y - center.Y))) < width; } static bool IsMatch(byte red, byte green, byte blue) @@ -136,11 +134,11 @@ static bool IsMatch(byte red, byte green, byte blue) } } - private static void ScorePoints(Span points, out Point best, out int amountAboveMin) + private static void ScorePoints(Span points, out PixelPoint best, out int amountAboveMin) { const int size = 5; - best = new Point(); + best = new PixelPoint(); amountAboveMin = 0; int maxIndex = -1; @@ -148,15 +146,16 @@ private static void ScorePoints(Span points, out Point best, out int amou for (int i = 0; i < points.Length; i++) { - Point pi = points[i]; + PixelPoint pi = points[i]; int score = 0; for (int j = 0; j < points.Length; j++) { - Point pj = points[j]; + PixelPoint pj = points[j]; - if (Math.Abs(pi.X - pj.X) < size || - Math.Abs(pi.Y - pj.Y) < size) + if (i != j && + (Math.Abs(pi.X - pj.X) < size || + Math.Abs(pi.Y - pj.Y) < size)) { score++; } diff --git a/CoreTests/MinimapNodeFinder/Test_MinimapNodeFinder.cs b/CoreTests/MinimapNodeFinder/Test_MinimapNodeFinder.cs new file mode 100644 index 000000000..bdd37dbff --- /dev/null +++ b/CoreTests/MinimapNodeFinder/Test_MinimapNodeFinder.cs @@ -0,0 +1,77 @@ +using System; +using System.Diagnostics; +using System.Drawing; + +using Core; + +using Game; + +using Microsoft.Extensions.Logging; + +#pragma warning disable 0162 +#pragma warning disable 8618 + +#nullable enable + +namespace CoreTests +{ + internal sealed class Test_MinimapNodeFinder : IDisposable + { + private const bool saveImage = false; + private const bool LogEachUpdate = false; + + private readonly ILogger logger; + + private readonly WowProcess wowProcess; + private readonly WowScreen wowScreen; + + private readonly MinimapNodeFinder minimapNodeFinder; + + private readonly Stopwatch stopwatch = new(); + + public Test_MinimapNodeFinder(ILogger logger) + { + this.logger = logger; + + wowProcess = new(); + wowScreen = new(logger, wowProcess); + + minimapNodeFinder = new(logger, wowScreen); + } + + public void Dispose() + { + wowScreen.Dispose(); + wowProcess.Dispose(); + } + + public void Execute() + { + if (LogEachUpdate) + stopwatch.Restart(); + + wowScreen.UpdateMinimapBitmap(); + + if (LogEachUpdate) + logger.LogInformation($"Capture: {stopwatch.ElapsedMilliseconds}ms"); + + if (LogEachUpdate) + stopwatch.Restart(); + + minimapNodeFinder.Update(); + + if (LogEachUpdate) + logger.LogInformation($"Update: {stopwatch.ElapsedMilliseconds}ms"); + + if (saveImage) + { + SaveImage(); + } + } + + private void SaveImage() + { + wowScreen.MiniMapBitmap.Save("minimap.png"); + } + } +} diff --git a/CoreTests/NpcNameFinder/Test_NpcNameFinder.cs b/CoreTests/NpcNameFinder/Test_NpcNameFinder.cs index 84ea9044a..a211cb3f9 100644 --- a/CoreTests/NpcNameFinder/Test_NpcNameFinder.cs +++ b/CoreTests/NpcNameFinder/Test_NpcNameFinder.cs @@ -36,7 +36,7 @@ public sealed class Test_NpcNameFinder : IDisposable private readonly StringBuilder stringBuilder = new(); private readonly Graphics paint; - private readonly System.Drawing.Bitmap paintBitmap; + private readonly Bitmap paintBitmap; private readonly Font font = new("Arial", 10); private readonly SolidBrush brush = new(Color.White); private readonly Pen whitePen = new(Color.White, 1); diff --git a/CoreTests/Program.cs b/CoreTests/Program.cs index 3daf40124..aca5c5e25 100644 --- a/CoreTests/Program.cs +++ b/CoreTests/Program.cs @@ -14,7 +14,7 @@ sealed class Program { private static Microsoft.Extensions.Logging.ILogger logger; - private const bool LogSelf = false; + private const bool LogOverall = false; private const bool ShowOverlay = false; private const int delay = 150; @@ -31,6 +31,7 @@ public static void Main() Test_NPCNameFinder(); //Test_Input(); //Test_CursorGrabber(); + //Test_MinimapNodeFinder(); } private static void Test_NPCNameFinder() @@ -51,19 +52,19 @@ private static void Test_NPCNameFinder() while (i < count) { - if (LogSelf) + if (LogOverall) timestamp = Stopwatch.GetTimestamp(); test.Execute(); - if (LogSelf) + if (LogOverall) sample[i] = Stopwatch.GetElapsedTime(timestamp).TotalMilliseconds; i++; Thread.Sleep(delay); } - if (LogSelf) + if (LogOverall) Log.Logger.Information($"sample: {count} | avg: {sample.Average(),0:0.00} | min: {sample.Min(),0:0.00} | max: {sample.Max(),0:0.00} | total: {sample.Sum()}"); } @@ -90,5 +91,35 @@ private static void Test_CursorGrabber() } } + private static void Test_MinimapNodeFinder() + { + using Test_MinimapNodeFinder test = new(logger); + + int count = 100; + int i = 0; + + long timestamp = Stopwatch.GetTimestamp(); + double[] sample = new double[count]; + + Log.Logger.Information($"running {count} samples..."); + + while (i < count) + { + if (LogOverall) + timestamp = Stopwatch.GetTimestamp(); + + test.Execute(); + + if (LogOverall) + sample[i] = Stopwatch.GetElapsedTime(timestamp).TotalMilliseconds; + + i++; + Thread.Sleep(delay); + } + + if (LogOverall) + Log.Logger.Information($"sample: {count} | avg: {sample.Average(),0:0.00} | min: {sample.Min(),0:0.00} | max: {sample.Max(),0:0.00} | total: {sample.Sum()}"); + } + } }