public override void MoveTo(int x, int y, double speed = SpeedDefault) { const int MEAN = 100; const int DEV = 50; int loops_between_poll = Math.Max(1, (int)(speed * (PollingPeriod / 1000.0))); int maxrandy_x = NormalDistributor.NormalDistribution(MEAN, DEV); int maxrandy_y = NormalDistributor.NormalDistribution(MEAN, DEV); Point destination = User32.AbsoluteToRelativePoint(x, y); while (destination != Cursor.Position) { int xdif = destination.X - Cursor.Position.X; int ydif = destination.Y - Cursor.Position.Y; // +1 prevents div/0 int xdif_magnitude = Math.Abs(xdif) + 1; int ydif_magnitude = Math.Abs(ydif) + 1; int x_addition = Math.Sign(xdif); int y_addition = Math.Sign(ydif); int relative_x = 0; int relative_y = 0; for (int i = 0; i < loops_between_poll && (xdif != relative_x || ydif != relative_y); i++) { if (RandomGenerator.NextInt(0, maxrandy_x) <= (xdif_magnitude * MEAN) / ydif_magnitude) { relative_x += x_addition; } if (RandomGenerator.NextInt(0, maxrandy_y) <= (ydif_magnitude * MEAN) / xdif_magnitude) { relative_y += y_addition; } xdif_magnitude = Math.Abs(xdif + relative_x) + 1; ydif_magnitude = Math.Abs(ydif + relative_y) + 1; } WaitForNextPoll(); JumpPosition(relative_x, relative_y); } }
/// <summary> /// Moves mouse cursor in a straight line to its destination /// </summary> /// <param name="x">Absolute X coordinate to move to</param> /// <param name="y">Absolute Y coordinate to move to</param> /// <param name="speed">Speed in pixels per second</param> public override void MoveTo(int x, int y, double speed = SpeedDefault) { // cursor movement functions use relative points Point relative = User32.AbsoluteToRelativePoint(x, y); x = relative.X; y = relative.Y; // used to check if integer value of position changed since last iteration Point loc_before_sleep = Cursor.Position; double current_x = loc_before_sleep.X; double current_y = loc_before_sleep.Y; double dest_x = (double)x; double dest_y = (double)y; while (Math.Abs(current_x - dest_x) > 0.5 || Math.Abs(current_y - dest_y) > 0.5) { double displacement_x = dest_x - current_x; double displacement_y = dest_y - current_y; // pythagorean theorem to get displacement from origin to dest double distance_direct = Math.Sqrt(displacement_x * displacement_x + displacement_y * displacement_y); // hypotenuse is the portion of distance_direct that is being traversed this iteration // ({speed} pixels/sec) * (1 sec/1000 ms) * ({_PollingPeriod} ms) = double hypotenuse = Math.Min(distance_direct, speed * PollingPeriod / 1000.0); if (Math.Abs(displacement_x) < 0.1) { // no X displacement, so we're directly above or below destination // this prevents divide by 0 from calculating tan_ratio current_y += hypotenuse * (displacement_y < 0.0 ? -1.0 : 1.0); } else { // x is adjacent component // y is opposite component double tan_ratio = displacement_y / displacement_x; // the sign of tan_ratio doesn't matter to Atan double angle_to_dest = Math.Atan(tan_ratio); // Math.Cos(angle_to_dest) * hypotenuse --- gets the correct x magnitude // * (displacement_x < 0.0 ? -1.0 : 1.0) --- fixes the sign for the x component double x_add = Math.Cos(angle_to_dest) * hypotenuse * (displacement_x < 0.0 ? -1.0 : 1.0); // multiplying these always gives the correct sign for y double y_add = x_add * tan_ratio; current_x += x_add; current_y += y_add; } int new_x = (int)Math.Round(current_x); int new_y = (int)Math.Round(current_y); loc_before_sleep = new Point(new_x, new_y); if (Cursor.Position != loc_before_sleep) { //Cursor.Position = loc_before_sleep; Point absolute = User32.RelativeToAbsolutePoint(loc_before_sleep); SetPosition(absolute.X, absolute.Y); } WaitForNextPoll(); // in case human user moved mouse cursor during the WaitForNextPoll(): // if the cursor is not where it is expected to be, // reset current_x and current_y back to the actual position if (Cursor.Position != loc_before_sleep) { // TODO: just use JumpPosition instead and just keep track of relative changes? current_x = Cursor.Position.X; current_y = Cursor.Position.Y; } } }
public void SetPosition(int x, int y) { Cursor.Position = User32.AbsoluteToRelativePoint(x, y); }
public void SetPosition(int x, int y) { Point relative = User32.AbsoluteToRelativePoint(x, y); User32.SetCursorPos(relative.X, relative.Y); }