AceInfinity
Emeritus, Contributor
Automatic detection of game area (not much to go by here in terms of indicators, unless you were to use the title screen colors).
Preview:
Source:
Further note: I'm done with this one though, further development on my bot won't happen lol, if I wanted to I could make it meticulous enough to not miss a point, and not missclick, but it happens ever so rarely that it's decent enough the way it is.
Preview:
Source:
- Form1.cs
Code:using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; using System.Diagnostics; namespace DashBot { public partial class Form1 : Form { ThreadTimer TT; DashBot DB; public Form1() { InitializeComponent(); this.TopMost = true; DB = new DashBot(pictureBox1); TT = new ThreadTimer(DB); } private void Form1_Load(object sender, EventArgs e) { } private void button1_Click(object sender, EventArgs e) { new Thread(new ThreadStart(TT.TimerStart)).Start(); } private void button2_Click(object sender, EventArgs e) { TT.GameFinished = true; } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { Process.GetCurrentProcess().Kill(); } } }
ThreadTimer.cs
Code:using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; using System.Drawing; namespace DashBot { class ThreadTimer { DashBot dashBot; private Rectangle GameWin; public bool GameFinished; #region ThreadTimer Constructor public ThreadTimer(DashBot db) { dashBot = db; GameFinished = false; } #endregion #region //Timer Methods private class TimerStateClass { public bool CancelTimer; public System.Threading.Timer ReferenceTimer; } public void TimerStart() { TimerStateClass TimerState = new TimerStateClass(); TimerState.CancelTimer = false; TimerState.ReferenceTimer = new System.Threading.Timer(new System.Threading.TimerCallback(CheckCancelEvent), TimerState, 1, 1); GameWin = dashBot.FindRect(); while (!GameFinished) { dashBot.PlayGame(GameWin); } TimerState.CancelTimer = true; } private void CheckCancelEvent(object TimerObj) { TimerStateClass TimerClass = (TimerStateClass)TimerObj; if (TimerClass.CancelTimer) { TimerClass.ReferenceTimer.Dispose(); } } #endregion } }
DashBot.cs
Code:using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Threading; namespace DashBot { class DashBot { private PictureBox PicBoxOut; private int padX = 3; #region DashBot Constructor public DashBot(PictureBox picBox) { PicBoxOut = picBox; } #endregion #region Game Dimensions private enum GameDimensions { Width = 600, Height = 450 } #endregion #region MouseEvent API & Method [DllImport("user32.dll")] private static extern void mouse_event(uint dwFlags, int dx, int dy, int dwData, UIntPtr dwExtraInfo); private void MClick(int x, int y) { Cursor.Position = new System.Drawing.Point(x, y); mouse_event((uint)(0x00000002), 0, 0, 0, UIntPtr.Zero); mouse_event((uint)(0x00000004), 0, 0, 0, UIntPtr.Zero); } #endregion #region Main Game Method - Hit Points public void PlayGame(Rectangle GameWindow) { Bitmap GameScreen = GetGameImage(FullScreenshot(), GameWindow); PicBoxOut.BackgroundImage = Image.FromHbitmap(GameScreen.GetHbitmap()); for (int r = 0; r < GameScreen.Width; r++) { for (int c = 0; c < GameScreen.Height; c++) { Color Col = GameScreen.GetPixel(r, c); if (Col.R == 0xFF && Col.B == 0x00 && (Col.G >= 0x20 && Col.G <= 0x75)) { if (Col != Color.Black) new Thread(x => MClick(r + GameWindow.Left + padX, c + GameWindow.Top)).Start(); return; } } } } #endregion #region Convert Bitmap > Byte Array private byte[] GetIMGBytes(Bitmap BMP) { BitmapData BMPdata = BMP.LockBits(new Rectangle(0, 0, BMP.Width, BMP.Height), ImageLockMode.ReadWrite, BMP.PixelFormat); byte[] IMGdata = new byte[BMPdata.Stride * BMPdata.Height]; Marshal.Copy(BMPdata.Scan0, IMGdata, 0, IMGdata.Length); BMP.UnlockBits(BMPdata); return IMGdata; } #endregion #region GetWindowPoint private Point GetWindowPoint(int value) { int desktopW = Screen.GetBounds(Point.Empty).Width; int Scanned = value / 4; int X = Scanned % desktopW; int calcY = Scanned / desktopW; int Y = Scanned % desktopW != 0 ? ++(calcY) : calcY; return new Point(X, Y); } #endregion #region Retrieve Game Image/Bitmap private Bitmap GetGameImage(Bitmap Original, Rectangle GameRectangle) { return (Bitmap)Original.Clone(GameRectangle, Original.PixelFormat); } #endregion #region Get Full Desktop Screenshot private Bitmap FullScreenshot() { try { Rectangle scrn = Screen.GetBounds(Point.Empty); Bitmap BMP = new Bitmap(scrn.Width, scrn.Height); using (Graphics G = Graphics.FromImage(BMP)) { G.CopyFromScreen(Point.Empty, Point.Empty, scrn.Size); } return BMP; } catch (Exception) { return FullScreenshot(); } } #endregion #region Find Game Rectangle //Find Game Rectangle - 300 Black Pixels Horizontal public Rectangle FindRect() { byte[] IMGdata = GetIMGBytes(FullScreenshot()); //IMGdata == RGBA byte[] FindBytes = { 0x0, 0x0, 0x0, 0xFF }; List LB = new List(); Array.ForEach(Enumerable.Range(0, 300).ToArray(), x => LB.AddRange(FindBytes)); int[] Loc = Locate(IMGdata, LB.ToArray()); if (Loc.Count() > 0) { return new Rectangle(GetWindowPoint(Loc[0]), new Size((int)GameDimensions.Width, (int)GameDimensions.Height)); } else { return Rectangle.Empty; } } private int[] Locate(byte[] original, byte[] objarr) { if (IsEmpty(original, objarr)) return new int[0]; var list = new List(); for (int i = 0; i < original.Length; i++) { if (!IsMatch(original, i, objarr)) continue; list.Add(i); } return list.Count == 0 ? new int[0] : list.ToArray(); } private bool IsMatch(byte[] array, int pos, byte[] objarr) { if (objarr.Length > (array.Length - pos)) return false; for (int i = 0; i < objarr.Length; i++) if (array[pos + i] != objarr[i]) return false; return true; } private bool IsEmpty(byte[] arr, byte[] objarr) { return arr == null || objarr == null || arr.Length == 0 || objarr.Length == 0 || objarr.Length > arr.Length; } #endregion } }
Further note: I'm done with this one though, further development on my bot won't happen lol, if I wanted to I could make it meticulous enough to not miss a point, and not missclick, but it happens ever so rarely that it's decent enough the way it is.