Note
No poker players where harmed during the making of my poker bot.
Origin and idea
One of my pet projects was a poker bot. This poker bot worked on Pokerstars. It was able to play poker without human intervention. Unfortunately it lost most of the time. The mouse movement was a issue with this bot. To avoid detection i wanted the mouse to move as humanly as possible. So no straight line and at normal speed.
After searching on Google and grabing some ideas i have made some code to round the gathered information. The base idea is to record your own movement and use this to get from any point a to any point b.
Now the source part
Pinvoke Methods
To determine the mouse position, set the mouse position and trigger the click event you need some pinvoke methods.
//Triggers mouse click event
[DllImport(
"user32.dll",
CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(
uint dwFlags,
uint dx,
uint dy,
uint cButtons,
uint dwExtraInfo);
//Get current mouse position
[DllImport(
"user32.dll",
EntryPoint = "GetCursorPos")]
public extern static bool GetCursorPosition(
out System.Drawing.Point lpPoint);
//Set current mouse position
[DllImport(
"user32.dll",
EntryPoint = "SetCursorPos")]
public extern static Int32 SetCursorPosition(
Int32 x,
Int32 y);
Data Container
We also need a data container to store al recorded mouse movements. This recording is later used als template.
//Data container to store recorded mouse movements
//This data is a template for the actual mouse move
public class MouseMovement
{ #region Propertie(s)
public Point Point { get; private set; } public Int32 ElapsedMilliseconds { get; private set; } public Double R { set; get; } public Double PHI { set; get; } #endregion
#region Constructor(s)
public MouseMovement(
Point point,
Int32 elapsedMilliseconds)
{ this.ElapsedMilliseconds = elapsedMilliseconds;
this.Point = point;
}
#endregion
}
The actual recording
The actual recording is needed to create a template. This template is used move the mouse as humanly possible from any poin a to any point b.
//The actual recording of the template
//After recoding the polar coordinates wil be set
public List<MouseMovement> Record(Int64 forMilliseconds)
{ List<MouseMovement> recording = new List<MouseMovement>();
Stopwatch sw = new Stopwatch();
sw.Start();
Point currentPosition;
while ((sw.Elapsed.Milliseconds + (sw.Elapsed.Seconds * 1000))
<= forMilliseconds)
{ GetCursorPosition(out currentPosition);
recording.Add(
new MouseMovement(
new Point(
currentPosition.X,
currentPosition.Y),
sw.ElapsedMilliseconds));
}
MouseMovement.SetPolarCoordinates(recording);
return recording;
}
Polar Coordinates
Convert mouse movement to polar coordinates.
public void SetPolarCoordinates()
{ if (this.Count == 0)
return;
MouseMovement baseMouseMovement = this.First();
MouseMovement lastMouseMovement = this.Last();
foreach (MouseMovement mouseMovement in this)
{ Double current_r = Kart2Polar_R
(
(mouseMovement.Point.X - baseMouseMovement.Point.X),
(mouseMovement.Point.Y - baseMouseMovement.Point.Y)
);
Double current_phi = Kart2Polar_Phi
(
(mouseMovement.Point.X - baseMouseMovement.Point.X),
(mouseMovement.Point.Y - baseMouseMovement.Point.Y),
current_r
);
mouseMovement.PHI = current_phi;
mouseMovement.R = current_r;
}
Double target_r = Kart2Polar_R
(
(lastMouseMovement.Point.X - baseMouseMovement.Point.X),
(lastMouseMovement.Point.Y - baseMouseMovement.Point.Y)
);
Double target_phi = Kart2Polar_Phi
(
(lastMouseMovement.Point.X - baseMouseMovement.Point.X),
(lastMouseMovement.Point.Y - baseMouseMovement.Point.Y),
target_r
);
foreach (MouseMovement mouseMovement in this)
{ mouseMovement.PHI = (mouseMovement.PHI - target_phi);
mouseMovement.R = (mouseMovement.R / target_r);
}
}
private Double Polar2Kart_X(Double r, Double phi)
{ return (r * Math.Cos(phi));
}
private Double Polar2Kart_Y(Double r, Double phi)
{ return (r * Math.Sin(phi));
}
private Double Kart2Polar_R(Int32 x, Int32 y)
{ return Math.Sqrt((x * x) + (y * y));
}
private Double Kart2Polar_Phi(Int32 x, Int32 y, Double r)
{ Double phi;
if (y < 0)
phi = -1 * Math.Acos(x / r);
else
phi = Math.Acos(x / r);
return phi;
}
Move based on recorded template
For the best and natural result you should record multiple templates. I serialize the object and randomly pick a template.
public void Move(Point toPoint)
{ Point basePoint;
GetCursorPosition(out basePoint);
Double target_r = Recording.Kart2Polar_R
(
(toPoint.X - basePoint.X),
(toPoint.Y - basePoint.Y)
);
Double target_phi = Recording.Kart2Polar_Phi
(
(toPoint.X - basePoint.X),
(toPoint.Y - basePoint.Y),
target_r
);
Int32 x = 0;
Int32 y = 0;
foreach (MouseMovement mouseMovement in this)
{ x = (Int32)Math.Round(
Polar2Kart_X((mouseMovement.R * target_r),
(mouseMovement.PHI + target_phi)) + basePoint.X);
y = (Int32)Math.Round(Polar2Kart_Y(
(mouseMovement.R * target_r),
(mouseMovement.PHI + target_phi)) + basePoint.Y);
if (this.IndexOf(mouseMovement) > 0)
Thread.Sleep(
mouseMovement.ElapsedMilliseconds -
this[(this.IndexOf(mouseMovement) - 1)].ElapsedMilliseconds);
SetCursorPosition(x, y);
}
}
!! Have fun and use it wisely !!