[C#] Disc Dash Bot - Created by AceInfinity

AceInfinity

Emeritus, Contributor
Joined
Feb 21, 2012
Posts
1,728
Location
Canada
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:
  • 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.
 
Back
Top