BotLib Wiki
A botting library written in C#, and using the .NET framework.
Status: Beta
Brought to you by:
botlib
/* BOTTING LIBRARY NAMESPACES */ #region NAMESPACES using System; using System.Drawing; using System.Threading; using System.Diagnostics; using System.Windows.Forms; using System.Collections.Generic; using System.Runtime.InteropServices; #endregion //#######################################################################\\ //! @>>>>! BOTLIB v1.0 !<<<<@ !\\ //!! C#.NET library for game bots and macros -- Handles all program I/O !!\\ //!!! @>>>>! FREE AND OPEN SOURCE !<<<<@ !!!\\ //###############################################################################\\ //############## IMPORTANT NOTICE - There is NO error handling in this class. You will have to do that yourself ##############\\ // Download Visual C# Express here => www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-csharp-express \\ namespace BOTLIB { public class robot { #region DLLIMPORTS [DllImport("user32.dll")] static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo); public enum MouseEventFlags : uint { LEFTDOWN = 0x00000002, LEFTUP = 0x00000004, MIDDLEDOWN = 0x00000020, MIDDLEUP = 0x00000040, MOVE = 0x00000001, ABSOLUTE = 0x00008000, RIGHTDOWN = 0x00000008, RIGHTUP = 0x00000010, WHEEL = 0x00000800, XDOWN = 0x00000080, XUP = 0x00000100 } [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetFrontWindow(IntPtr hWnd); //www.pinvoke.net/default.aspx/user32.getwindowrect [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); //www.pinvoke.net/default.aspx/Structures/RECT.html [StructLayout(LayoutKind.Sequential)] public struct RECT { //This will contain the location of the 4 corners of our window public int Left; public int Top; public int Right; public int Bottom; } [DllImport("user32.dll")] static extern short GetAsyncKeyState(System.Windows.Forms.Keys vKey); [DllImport("User32.dll")] public static extern int ShowWindow(IntPtr hwnd, int nCmdShow); #endregion /* x5 DLL Imports x1 struct & x1 enum*/ #region SCREENSHOTS /// <summary> /// Takes a screenshot of the whole screen /// </summary> /// <returns>Returns a bitmap image of the screen</returns> public static Bitmap getScreenshot() { // Create new bitmap object the size of screen Bitmap screenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); // Creates a new graphic object Graphics graphic = Graphics.FromImage(screenshot); //Takes the screenshot graphic.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size); //Dispose the graphics object graphic.Dispose(); // Return the bitmap to the user return screenshot; } /// <summary> /// Takes a bitmap screenshot of a particular window /// </summary> /// <param name="processName">The process/window's title</param> /// <returns>Bitmap of the window</returns> public static Bitmap getScreenshotOfWindow(string windowTitle) { //This will hold our window's information RECT WINDOW = new RECT(); //Get the window information IntPtr window = getWindowHandle(windowTitle); //Get window details GetWindowRect(window, out WINDOW); //Width and height of window int winWidth = WINDOW.Right - WINDOW.Left; int winHeight = WINDOW.Bottom - WINDOW.Top; //Window size Size winSize = new Size(winWidth, winHeight); //Our graphics variables Bitmap screenshot = new Bitmap(winWidth, winHeight); Graphics graphic = Graphics.FromImage(screenshot); //Takes the screenshot, starting where the top left corner of the window is, and takes only the size of the window graphic.CopyFromScreen(WINDOW.Left, WINDOW.Top, 0, 0, winSize, CopyPixelOperation.SourceCopy); //Clean up a bit graphic.Dispose(); //Return the screenshot return screenshot; } #endregion /* x2 Methods getScreenshot() & getScreenshotOfWindow() */ #region WINDOW HANDLING /// <summary> /// Returns the main window handle for the given process /// </summary> /// <param name="windowName">String with window title</param> /// <param name="contains">True/False does the window title have to match exactly. False means it will check if the title /// contains the string passed to it /// </param> /// <returns>A window handle</returns> public static IntPtr getWindowHandle(string windowTitle) { //Will hold window handle IntPtr hWnd = (IntPtr)0; //Get list of all running processes Process[] processes = Process.GetProcesses(); //Return if couldm't find any if (processes.Length <= 0) { return hWnd; } //Wait Thread.Sleep(3000); //Loop through foreach (Process process in processes) { //If window title mathc if (process.MainWindowTitle == windowTitle) { //Set hwnd to window handle hWnd = process.MainWindowHandle; break; } } return hWnd; } /// <summary> /// Sets aparticular window to the front /// </summary> /// <param name="windowName"></param> public Boolean setFrontWindow(string windowName) { //Get the main window handle and set it to the foreground return SetFrontWindow(getWindowHandle(windowName)); } /// <summary> /// Sets a windo to the front /// </summary> /// <param name="windowHandle">Window handle to set</param> /// <returns>True/False</returns> public Boolean setFrontWindow(IntPtr windowHandle) { return SetFrontWindow(windowHandle); } /// <summary> /// Shows a window /// </summary> /// <param name="windowHandle">The window's handle</param> public static void showWindow(IntPtr windowHandle) { ShowWindow(windowHandle, 9); return; } #endregion /* x3 Methods getWindowHandle(), setFrontWindow(), [OVERLOADED - setFrontWindow() ] & showWindow() */ #region IMAGE RECOGNITON /// <summary> /// Searches for a bitmap inside a larger one /// </summary> /// <param name="small">Image (Bitmap) to look for </param> /// <param name="large">Image (Bitmap) to look in</param> /// <returns>True if image was found, and changes the Point value passed to it to the top left co-ordinates of where the image was found</returns> public bool findImage(Bitmap small, Bitmap large, out Point location) { //Loop through large images width for (int largeX = 0; largeX < large.Width; largeX++) { //And height for (int largeY = 0; largeY < large.Height; largeY++) { //Loop through the small width for (int smallX = 0; smallX < small.Width; smallX++) { //And height for (int smallY = 0; smallY < small.Height; smallY++) { //Get current pixels for both image Color currentSmall = small.GetPixel(smallX, smallY); Color currentLarge = large.GetPixel(largeX + smallX, largeY + smallY); //If they dont match (i.e. the image is not there) if (!colorsMatch(currentSmall, currentLarge)) //Goto the next pixel in the large image goto nextLoop; } } //If all the pixels match up, then return true and change Point location to the top left co-ordinates where it was found location = new Point(largeX, largeY); return true; //Go to next pixel on large image nextLoop: continue; } } //Return false if image is not found, and set an empty point location = Point.Empty; return false; } /// <summary> /// Finds ALL occurences of a smaller image inside a bigger one /// </summary> /// <param name="small">Image (24 bit Bitmap) to find </param> /// <param name="large">Image (Bitmap) to look in</param> /// <returns>A list containing Points of the top left of where the image occured</returns> public List<Point> findImages(Bitmap small, Bitmap large) { /* !!! WARNING !!! This can be very slow but can save time in the long term. For instance, you can take a picture of the screen, * find and store all "items" (thing you can do stuff to) then get the person/avatar to walk round and handle each money individualy, * and you just acount for the changes in position he has made. 1 big screenshot is better than 20 small ones, * (creates the impression of faster run speed) */ //A new list of image locations List<Point> imageLocations = new List<Point>(); //Loop through large images width for (int largeX = 0; largeX < large.Width; largeX++) { //And height for (int largeY = 0; largeY < large.Height; largeY++) { //Loop through the small width for (int smallX = 0; smallX < small.Width; smallX++) { //And height for (int smallY = 0; smallY < small.Height; smallY++) { //Get current pixels for both image Color currentSmall = small.GetPixel(smallX, smallY); Color currentLarge = large.GetPixel(largeX + smallX, largeY + smallY); //If they dont match (i.e. the image is not there) if (!colorsMatch(currentSmall, currentLarge)) //Goto the next pixel in the large image goto nextLoop; } } //If all the pixels match up, add point to list imageLocations.Add(new Point(largeX, largeY)); //Go to next pixel on large image nextLoop: continue; } } return imageLocations; } /// <summary> /// Finds the first occurence of a color. Starts from top left corner /// </summary> /// <param name="image">Image to look in</param> /// <param name="color">Color to look for</param> /// <param name="absolute">If the colors have to be an exact match or not</param> /// <param name="tolerance">How close the colors have to be. Read more in the colorsSimilar() method</param> /// <returns>True if color found, and changes value of the Point passed to it</returns> public bool findColor(Bitmap image, Color color, out Point location, bool absolute = false, int tolerance = 5) { //Loop through image width for (int i = 0; i <= image.Width; i++) { //And height for (int j = 0; j <= image.Height; j++) { // If absolute match wanted and their is an absolute match between color and current pixel, return true and change Point location if (absolute && colorsMatch(color, image.GetPixel(i, j))) { location = new Point(i, j); return true; } // If colors similar otherwise, change locatio and return true else if (colorsSimilar(color, image.GetPixel(i, j), tolerance)) { location = new Point(i, j); return true; } } } //Return false if color not found location = Point.Empty; return false; } /// <summary> /// Searches through an image for a particular color and adds all occurences to a Point List /// </summary> /// <param name="image">Image (Bitmap) to look in</param> /// <param name="color">Color to search for</param> /// <param name="absolute">If the colors have to be an exact match or not</param> /// <param name="tolerance">How close the colors have to be. Read more in the colorsSimilar() method</param> /// <returns>A list of point where the color has occured</returns> public List<Point> findColors(Bitmap image, Color color, bool absolute = false, int tolerance = 5) { //Create a new list List<Point> colorLocations = new List<Point>(); //Loop through image width for (int i = 0; i <= image.Width; i++) { // And height for (int j = 0; j <= image.Height; j++) { //If absolute match wanted and their is an absolute match, add point onto lis if (absolute && colorsMatch(color, image.GetPixel(i, j))) colorLocations.Add(new Point(i, j)); else { //If colors are similar otherwise, add Point onto list if (colorsSimilar(color, image.GetPixel(i, j), tolerance)) colorLocations.Add(new Point(i, j)); } } } //Return list of color locations return colorLocations; } /// <summary> /// Sees if 2 colors are an EXACT match /// </summary> /// <param name="one">First color to compare</param> /// <param name="two">Second color to compare</param> /// <returns>True or false depending on if there the same</returns>pect of the color public static bool colorsMatch(Color one, Color two) { //Compares the R,G & B as if (one.B == two.B && one.G == two.G && one.R == two.R) return true; return false; } /// <summary> /// Compares 2 colors and sees if they are SIMILAR /// </summary> /// <param name="one">First color to compare</param> /// <param name="two">Second color to compare</param> /// <param name="tolerance">Differance allowed. Higher equals more different colors and vice versa</param> /// <returns>True or false on colors being similar</returns> public static bool colorsSimilar(Color one, Color two, int tolerance) { //If any colors aspects difference if bigger than the tolerance, return false if (Math.Abs(one.B - two.B) >= tolerance || Math.Abs(one.G - two.G) >= tolerance || Math.Abs(one.R - two.R) >= tolerance) return false; return true; } #endregion /* x6 Methods findImage(), findImages(), findColor(), findColors(), colorsMatch() & colorsSimilar() */ #region AUTOMATION CONTROL /// <summary> /// Simulates key preses. Read about how to use here => www.msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.send.aspx /// </summary> /// <param name="key">String of keys to be presses</param> public void sendKeys(String key) { //Send keys to the system SendKeys.Send(key.Trim()); return; } /// <summary> /// Checks if the key given is currently down /// </summary> /// <param name="key">The key to check READ => msdn.microsoft.com/en-us/library/system.windows.forms.keys.aspx</param> /// <returns>Tru/False</returns> public bool isKeyDown(Keys key) { //Returns if the key is down return GetAsyncKeyState(key) == -32767; } /// <summary> /// Causes the mouse to left click at its current position /// </summary> public void leftClick() { // Mouse down mouse_event((int)(MouseEventFlags.LEFTDOWN), 0, 0, 0, 0); //Wait delay(10, 30); //Mouse up mouse_event((int)(MouseEventFlags.LEFTUP), 0, 0, 0, 0); return; } /// <summary> /// Causes the mouse to right click at its current position /// </summary> public void rightClick() { //Mouse down mouse_event((int)(MouseEventFlags.RIGHTDOWN), 0, 0, 0, 0); //Wait a bit delay(10, 30); //Mouse up mouse_event((int)(MouseEventFlags.RIGHTUP), 0, 0, 0, 0); return; } /// <summary> /// Moves the mouse in a linear straight line to the target position /// </summary> /// <param name="targetX">X co-ordinate of target</param> /// <param name="targetY">Y co-ordinate of target</param> /// <param name="human">Human mouse movement or just assign position</param> /// <param name="steps">Number of steps to take. More means a slower but smoother move, less means a faster but more jerky movement</param> public bool moveMouse(int targetX, int targetY, bool human = true, int steps = 100) { /* If the mouse moves to slowly when traveling over buttons/boxes/dropdowns (anything to click) it can stop, and will then jump to the target due to the fail safe. You can change the delay time, but the best thing to do is to try out different numbers of steps and get the right balance */ //If mouse movement is not human if (!human) { // Set mouse to target position Cursor.Position = new Point(targetX, targetY); return true; } // Word out how far the cursor must move for each step. It will then change by this much each step int xStep = (targetX - Cursor.Position.X) / steps; int yStep = (targetY - Cursor.Position.Y) / steps; // Loop through the steps for (int i = 0; i <= steps; i++) { // Work out the new mouse postion int xPosition = Cursor.Position.X + xStep; int yPosition = Cursor.Position.Y + yStep; //Move the mouse to its new position Cursor.Position = new Point(xPosition, yPosition); //Delay a few milliseconds Thread.Sleep(5); } // As a fail safe assigns the mouse the target position Cursor.Position = new Point(targetX, targetY); //If position is right if (Cursor.Position.X == targetX && Cursor.Position.Y == targetY) //return true return true; else return false; } /// <summary> /// Moves the mouse relative to the window. eg if you specified for it to move to 10,10 over the window "Notepad" /// it would move 10,10 into the top left of Notepad. A bit like local scope where 0,0 is the top left corner of the window given. /// </summary> /// <param name="windowHandle">Window handle</param> /// <param name="targetX">Trget X position</param> /// <param name="targetY">Target Y position</param> /// <param name="human">Human or not mouse movement</param> /// <param name="steps">Number of steps to take</param> /// <returns>True or false depending on outcome</returns> public bool moveMouseWindow(IntPtr windowHandle, int targetX, int targetY, bool human = true, int steps = 100) { //Will sore window details RECT WINDOW = new RECT(); //Get window details if (!GetWindowRect(windowHandle, out WINDOW)) return false; //Move the mouse if (!moveMouse(WINDOW.Left + targetX, WINDOW.Top + targetY, human, steps)) return false; return true; } /// <summary> /// Gets the mouse position /// </summary> /// <returns>Returns Point with mouse position</returns> public Point getMouse() { return Cursor.Position; } /// <summary> /// Gets the mouse position relative to the upper left corner of a window /// </summary> /// <param name="window">Window name</param> /// <returns>Mouse position</returns> public Point getMouseWindow(IntPtr window) { //Store cursor position Point position = Cursor.Position; //Will store window details RECT WINDOW = new RECT(); //Get window details GetWindowRect(window, out WINDOW); //Return new point relative to window return new Point(position.X - WINDOW.Left, position.Y - WINDOW.Top); } #endregion /*x8 Methods sendKeys(), isKeyDown(), leftClick(), rightClick() moveMouse(), moveMouseWindow(), getMouse() & getMouseWindow()*/ #region ANTI-BANS // Note that human mouse movement is in the OS CONTROL region /// <summary> /// New little thing that simulates a slight "jiggle" of the mouse, like a humans unsteady hands. Be aware this has had little testing /// </summary> public void mouseJiggle() { //Work out a slight change in mouse position int xChange = random(-10, 10); int yChange = random(-10, 10); //Move mouse a few pixels moveMouse(Cursor.Position.X + xChange, Cursor.Position.Y + yChange, true, 5); //Wait a bit delay(20, 60); // Move mouse back to original point moveMouse(Cursor.Position.X - xChange, Cursor.Position.Y - yChange, true, 5); return; } /// <summary> /// Pauses the thread for a random number of milliseconds in range. Randomly delays create a human like pause, /// but you can also use the fact that some method like findImage and findColor can take several seconds so that counts as a pause /// </summary> /// <param name="lower">Minimum delay time</param> /// <param name="upper">Maximum delay time</param> public void delay(int lower = 10, int upper = 30) { Thread.Sleep(random(lower, upper)); return; } /// <summary> /// Pauses the thread for the given time /// </summary> /// <param name="time">No of milliseconds to delay for.</param> public void delay(int time = 10000) { Thread.Sleep(time); return; } /// <summary> /// Generates a random number between the ranges given. Doing stuff randomly makes the program different everytime (more human like) /// </summary> /// <param name="lower">Minimum number possible</param> /// <param name="upper">Maxium number possible</param> /// <returns>A random number</returns> public static int random(int lower, int upper) { return new Random().Next(lower, upper); } #endregion /* x4 Methods mouseJiggle(), delay(), [OVERLOADED - delay()] & random() */ }