This is a game macro I created for the first time using C# WinForms. All actions were performed as intended, but the following error message is displayed in the UseImageSearch() function:
Error occurred during image search: Failed to allocate 3582272 bytes
Error occurred during image search: Failed to allocate 3582272 bytes
Error occurred during image search: Failed to allocate 3582272 bytes
Since this is the first code I’ve written, I’m not sure where it went wrong. I’m looking for a prince who can improve the code.
Below is the entire code.
using System;
using System.Linq;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using OpenCvSharp;
using System.Drawing;
namespace CookieRunMacro
{
public partial class Form1 : Form
{
Random rand = new Random();
IntPtr bsW;
IntPtr bstW;
private CancellationTokenSource cancellationTokenSource;
private bool isRunning = false;
private const int MaxLines = 20;
int count = 0;
[DllImport("user32.dll")] // Find window
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")] // Find child window
public static extern IntPtr FindWindowEx(IntPtr hWnd1, IntPtr hWnd2, string lpsz1, string lpsz2);
[DllImport("user32.dll")] // Show window
public static extern void SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")] // Restore window
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")] // Change window position
public static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags);
[DllImport("user32.dll")]
internal static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcblt, int nFlags);
[DllImport("user32.dll", CharSet = CharSet.Auto)] // Send message to window
public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
private const uint WM_LBUTTONDOWN = 0x0201;
private const uint WM_LBUTTONUP = 0x0202;
public static IntPtr BlueStackFind(string window)
{
IntPtr hw1 = FindWindow("Qt5154QWindowOwnDCIcon", "BlueStacks App Player");
IntPtr hw2 = FindWindowEx(hw1, IntPtr.Zero, null, "HD-Player");
return hw2;
}
private void AddText(string text)
{
// Add line to text box
logTextBox.AppendText(text + Environment.NewLine);
// If lines in text box exceed maximum lines
if (logTextBox.Lines.Length > MaxLines)
{
// Remove old lines
logTextBox.Text = string.Join(Environment.NewLine, logTextBox.Lines.Skip(logTextBox.Lines.Length - MaxLines));
}
}
public async Task RangeClick(int startX, int startY, int endX, int endY)
{
if (!isRunning)
return;
int x = rand.Next(startX, endX + 1);
int y = rand.Next(startY, endY + 1);
IntPtr lParam = (IntPtr)((y << 16) | (x & 0xFFFF));
PostMessage(bstW, 0x0006, (IntPtr)1, lParam);
PostMessage(bstW, WM_LBUTTONDOWN, (IntPtr)0x0001, lParam);
await Task.Delay(rand.Next(30, 80));
PostMessage(bstW, WM_LBUTTONUP, IntPtr.Zero, lParam);
AddText("Click(x, y): " + x + ", " + y);
}
public string[] ResourcesLoad(string folderPath)
{
string[] imgPaths = Directory.GetFiles(folderPath, "*.png");
return imgPaths;
}
public string[] UseImageSearch(string imgPath, double threshold = 0.98f)
{
if (!isRunning)
return null;
Graphics gdata = Graphics.FromHwnd(bstW);
Rectangle rect = Rectangle.Round(gdata.VisibleClipBounds);
Bitmap screenBitmap = new Bitmap(rect.Width, rect.Height);
try
{
using (Graphics g = Graphics.FromImage(screenBitmap))
{
IntPtr hdc = g.GetHdc();
PrintWindow(bstW, hdc, 0x2);
g.ReleaseHdc(hdc);
}
using (Mat screenMat = OpenCvSharp.Extensions.BitmapConverter.ToMat(screenBitmap).CvtColor(ColorConversionCodes.BGRA2GRAY))
using (Mat findMat = Cv2.ImRead(imgPath, ImreadModes.Grayscale))
using (Mat result = new Mat())
{
// Perform template matching
Cv2.MatchTemplate(screenMat, findMat, result, TemplateMatchModes.CCoeffNormed);
// Find max value in result matrix
Cv2.MinMaxLoc(result, out _, out double maxVal, out _, out OpenCvSharp.Point maxLoc);
// return
// 0: image similarity
// 1,2: image coordinates (x, y)
// 3,4: image dimensions (width, height)
if (maxVal >= threshold)
{
return new string[] { maxVal.ToString(), maxLoc.X.ToString(), maxLoc.Y.ToString(), findMat.Width.ToString(), findMat.Height.ToString() };
}
}
}
catch (Exception ex)
{
AddText("Error occurred during image search: " + ex.Message);
}
finally
{
screenBitmap.Dispose();
}
return null;
}
public async Task MacroLogicAsync(CancellationToken cancellationToken)
{
try
{
while (!cancellationToken.IsCancellationRequested)
{
bool isDead = false;
do
{
await Task.Delay(1000);
string[] imgPaths = ResourcesLoad("./Resources/");
foreach (string imgPath in imgPaths)
{
if (cancellationToken.IsCancellationRequested || !isRunning)
return;
String[] data = UseImageSearch(imgPath);
if (data != null)
{
AddText(""" + imgPath + "" Image recognition successful");
AddText("Found image similarity: " + data[0]);
int x, y, w, h;
int.TryParse(data[1], out x); // x-coordinate
int.TryParse(data[2], out y); // y-coordinate
int.TryParse(data[3], out w); // width
int.TryParse(data[4], out h); // height
await RangeClick(x, y, x + w, y + h);
if (imgPath == "./Resources/DeathConfirmation.PNG")
{
isDead = true;
break;
}
}
}
} while (!isDead);
count += 1;
countText.Text = "Repetitions: " + count.ToString() + " times";
}
}
catch (Exception ex)
{
AddText("Error occurred during macro execution: " + ex.Message);
isRunning = false;
startButton.Invoke(new Action(() => startButton.Enabled = true));
stopButton.Invoke(new Action(() => stopButton.Enabled = false));
}
}
public Form1()
{
InitializeComponent();
}
private async void startButton_Click(object sender, EventArgs e)
{
startButton.Enabled = false;
stopButton.Enabled = true;
AddText("Starting macro.");
if ((IntPtr)BlueStackFind("BlueStacks App Player") == (IntPtr)0)
{
startButton.Enabled = true;
stopButton.Enabled = false;
AddText("Cannot find handle.");
AddText("Stopping macro.");
return;
}
else
{
AddText("BlueStack handle detected.");
}
bsW = FindWindow(null, "BlueStacks App Player");
bstW = BlueStackFind("BlueStacks App Player");
SetForegroundWindow(bsW);
ShowWindow(bsW, 5);
SetWindowPos(bsW, 0, 0, 0, 925, 535, 0x0040 | 0x0010);
SetWindowPos(bsW, 0, 0, 0, 925, 535, 0x0040 | 0x0001);
if (!isRunning)
{
isRunning = true;
cancellationTokenSource = new CancellationTokenSource();
await Task.Run(() => MacroLogicAsync(cancellationTokenSource.Token));
// await MacroLogicAsync(cancellationTokenSource.Token));
}
}
private void stopButton_Click(object sender, EventArgs e)
{
if (cancellationTokenSource != null)
{
cancellationTokenSource.Cancel();
cancellationTokenSource = null;
}
isRunning = false;
startButton.Enabled = true;
stopButton.Enabled = false;
AddText("Stopping macro.");
}
private void clearLog_Click(object sender, EventArgs e)
{
logTextBox.Text = "";
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (cancellationTokenSource != null)
{
cancellationTokenSource.Cancel();
cancellationTokenSource = null;
}
isRunning = false;
}
}
}
I created a program to find an image, compare it with the game window, and click on a random position of the image found in the window. It works fine up to this point, but there are too many error messages being displayed. I didn’t encounter any errors on my computer, but my friend’s computer showed error messages. I want to fix this issue.
Also, I would appreciate it if you could let me know if there are any strange contents in the code.
stttupiiid developer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.