Simba Code:
(*
Mouse
=====
Mouse routines.
.. contents::
*)
// TODO: Constant/Var docs
var
MouseSpeed: Integer;
{$IFDEF UseLaptopMouse}
LMouse_MissChance: Integer;
{$ENDIF}
const
mouse_move = 3;
(*
WindMouse
~~~~~~~~~
.. code-block:: pascal
procedure WindMouse(xs, ys, xe, ye, gravity, wind, minWait, maxWait, maxStep, targetArea: extended);
Moves the mouse along a spline defined by
.. note::
by Benland100
Example:
.. code-block:: pascal
*)
procedure WindMouse(xs, ys, xe, ye, gravity, wind, minWait, maxWait, maxStep, targetArea: extended);
var
veloX, veloY, windX, windY, veloMag, dist, randomDist, lastDist, step: extended;
lastX, lastY: integer;
sqrt2, sqrt3, sqrt5: extended;
begin
try
sqrt2:= sqrt(2);
sqrt3:= sqrt(3);
sqrt5:= sqrt(5);
while hypot(xs - xe, ys - ye) > 1 do
begin
dist:= hypot(xs - xe, ys - ye);
wind:= minE(wind, dist);
if dist >= targetArea then
begin
windX:= windX / sqrt3 + (random(round(wind) * 2 + 1) - wind) / sqrt5;
windY:= windY / sqrt3 + (random(round(wind) * 2 + 1) - wind) / sqrt5;
end else
begin
windX:= windX / sqrt2;
windY:= windY / sqrt2;
if (maxStep < 3) then
begin
maxStep:= random(3) + 3.0;
end else
begin
maxStep:= maxStep / sqrt5;
end;
end;
veloX:= veloX + windX;
veloY:= veloY + windY;
veloX:= veloX + gravity * (xe - xs) / dist;
veloY:= veloY + gravity * (ye - ys) / dist;
if hypot(veloX, veloY) > maxStep then
begin
randomDist:= maxStep / 2.0 + random(round(maxStep) div 2);
veloMag:= sqrt(veloX * veloX + veloY * veloY);
veloX:= (veloX / veloMag) * randomDist;
veloY:= (veloY / veloMag) * randomDist;
end;
lastX:= Round(xs);
lastY:= Round(ys);
xs:= xs + veloX;
ys:= ys + veloY;
if (lastX <> Round(xs)) or (lastY <> Round(ys)) then
MoveMouse(Round(xs), Round(ys));
step:= hypot(xs - lastX, ys - lastY);
wait(round((maxWait - minWait) * (step / maxStep) + minWait));
lastdist:= dist;
end;
if (Round(xe) <> Round(xs)) or (Round(ye) <> Round(ys)) then
MoveMouse(Round(xe), Round(ye));
except
end;
end;
(*
MMouse
~~~~~~
.. code-block:: pascal
procedure MMouse(x, y, rx, ry: integer);
Moves the mouse. rx and ry are total range of the randomness for the mouse. i.e. if rx:=6 then the randomness of the mouse will be from x-3 to x+3.
.. note::
by Benland100, laptop mouse by Hobbit (and nielsie95)
Example:
.. code-block:: pascal
*)
procedure MMouse(x, y, rx, ry: integer);
var
cx, cy, halfRx, halfRy : integer;
randSpeed: Extended;
{$IFDEF UseLaptopMouse}
seg, e, f, g, nx, ny, hypo: Integer;
a, b, c: Extended;
Miss: Boolean;
{$ENDIF}
begin
GetMousePos(cx, cy);
halfRx := rx / 2;
halfRy := ry / 2;
{$IFDEF UseLaptopMouse}
miss := (Random(LMouse_MissChance) = 0);
e:= 0;
a:= x - cx;
b:= y - cy;
c:= Pow(a,2) + Pow(b,2)
hypo:= Round(Sqrt(c));
case hypo of
0: Exit;
1..225: seg:=1;
226..600: seg:= Random(2) + 1;
601..1800: seg:= random(3) + 2;
else seg := 5;
end;
f := Round( a / seg);
g := Round( b / seg);
repeat
Wait(30 + random(50));
{Begin: Modified from MMouse by Benland100}
randSpeed := (random(MouseSpeed) / 2.0 + MouseSpeed) / 10.0;
if randSpeed = 0.0 then
randSpeed := 0.1;
getMousePos(cx,cy);
nx:= (cx + (f * e)) + randomrange(-halfRx,halfRx);
ny:= (cy + (g * e)) + randomrange(-halfRy,halfRy);
{End: Modified from MMouse by Benland100}
if Miss then
begin
nx:= nx + RandomRange(rx, rx * 2);
ny:= ny + RandomRange(ry, ry * 2);
end;
WindMouse(cx,cy,nx,ny,11.0,8.0,10.0/randSpeed,12.0/randSpeed,10.0*randSpeed,10.0*randSpeed);
e:= e + 1;
until(e = seg);
GetMousePos(cx, cy);
if not PointInBox(Point(cx, cy), IntToBox(x, y, x + rx, y + ry)) then
begin
Wait(30 + random(30));
WindMouse(cx,cy,(x + random(rx)),(y + random(ry)),11.0,6.0,10.0/randSpeed,15.0/randSpeed,10.0*randSpeed,10.0*randSpeed);
end;
{$ELSE}
randSpeed:= (random(MouseSpeed) / 2.0 + MouseSpeed) / 10.0;
if randSpeed = 0.0 then
randSpeed := 0.1;
X := x + random(-halfRx,halfRx);
Y := y + random(-halfRy,halfRy);
WindMouse(cx,cy,x,y,9.0,3.0,10.0/randSpeed,15.0/randSpeed,10.0*randSpeed,10.0*randSpeed);
{$ENDIF}
end;
(*
ClickMouse2
~~~~~~~~~~~
.. code-block:: pascal
procedure ClickMouse2(button: variant);
Clicks the mouse in a human way on the current mouse spot.
.. note::
by SRL Community
Example:
.. code-block:: pascal
*)
procedure ClickMouse2(button: variant);
var
a,b,c : integer;
iButton: Integer;
begin
{ Eventually, should be made to just use Integers }
if VariantIsBoolean(button) then
begin
if (button) then
iButton := mouse_left
else
iButton := mouse_right;
end else
iButton := button;
if (iButton = mouse_move) then Exit; { we aren't actually clicking! }
GetMousePos(b, c);
HoldMouse(b, c, iButton);
repeat
Wait(20 + Random(30));
a := a + 1;
until (a > 4);
GetMousePos(b, c);
ReleaseMouse(b, c, iButton);
Wait(50+Random(50));
end;
(*
Mouse
~~~~~
.. code-block:: pascal
procedure Mouse(mousex, mousey, ranx, rany: Integer; button: variant);
Moves then clicks mouse (will only move if 'mouse_move' passed).
.. note::
by Mutant Squirrle, Harry
Example:
.. code-block:: pascal
*)
procedure Mouse(mousex, mousey, ranx, rany: Integer; button: variant);
begin
MMouse(mousex, mousey, ranx, rany);
Wait(60 + Random(30));
ClickMouse2(button);
Wait(50 + Random(50));
end;
(*
MouseBox
~~~~~~~~
.. code-block:: pascal
procedure MouseBox(x1, y1, x2, y2: Integer; ClickType: Integer);
Moves mouse into a random position in the box. Clicks if told to.
.. note::
by Nava2
Example:
.. code-block:: pascal
*)
procedure MouseBox(x1, y1, x2, y2: Integer; ClickType: Integer);
var
fx, fy: Integer;
begin
GaussBox(fx, fy, x1, y1, x2, y2);
if InRange(ClickType, mouse_Right, mouse_move) then
Mouse(fx, fy, 0, 0, clickType)
else
srl_Warn('MouseBox', 'ClickType is NOT a valid number!', warn_AllVersions);
end;
(*
MouseTBox
~~~~~~~~~
.. code-block:: pascal
procedure MouseTBox(Box: TBox; ClickType: variant);
Moves the mouse to the Indicated Box, and performs the ClickType
.. note::
by PhaseCode
Example:
Mouse(InvBox(1),1);
.. code-block:: pascal
*)
procedure MouseTBox(Box: TBox; ClickType: variant);
begin
MouseBox(Box.X1, Box.Y1, Box.X2, Box.Y2, ClickType)
end;
procedure MouseAction(mx, my, rx, ry: Integer; a: fnct_ActionOptions);
begin
case (a) of
Move: MMouse(mx, my, rx, ry);
ClickLeft: Mouse(mx, my, rx, ry, mouse_left);
ClickRight: Mouse(mx, my, rx, ry, mouse_right);
ClickMiddle: Mouse(mx, my, rx, ry, mouse_middle);
end;
end;
(*
SleepAndMoveMouse
~~~~~~~~~~~~~~~~~
.. code-block:: pascal
procedure SleepAndMoveMouse(Time: Integer);
Waits for specified time and moves mouse around like bored human would.
.. note::
by RsN
Example:
.. code-block:: pascal
*)
procedure SleepAndMoveMouse(Time: Integer);
var
Moving: Boolean;
mx, my: Integer;
x, y, xv, yv: Extended;
gx, gy: Extended;
T: Integer;
begin
GetMousePos(mx, my);
x := mx;
y := my;
if (Random(2) = 0) then
Moving := False
else
Moving := True;
gx := 130 + Random(500);
gy := 130 + Random(300);
T := GetTickCount;
repeat
Sleep(10);
if (Moving) then
begin
if (gx > x) then
xv := xv + 0.1
else
xv := xv - 0.1;
if (gy > y) then
yv := yv + 0.1
else
yv := yv - 0.1;
x := x + xv;
y := y + yv;
MoveMouse(Round(x), Round(y));
end;
if (Random(100) = 0) then
Moving := not Moving;
if (Random(30) = 0) then
begin
gx := 130 + Random(500);
gy := 130 + Random(300);
end;
until (Abs(GetTickCount - T) >= Time);
end;
(*
IdleTime
~~~~~~~~
.. code-block:: pascal
procedure IdleTime(Time, Rand: integer; Gravity: extended);
Randomly moves the mouse (Rand, and Gravity) for Time milliseconds
.. note::
by BenLand100
Example:
.. code-block:: pascal
*)
procedure IdleTime(Time, Rand: Integer; Gravity: Extended);
var
H, W, Cx, Cy, i, n, St: Integer;
Controls, Path: TPointArray;
LastC, LastP: TPoint;
begin
St := GetSystemTime;
GetClientDimensions(W, H);
SetArrayLength(Controls, 4);
GetMousePos(Cx, Cy);
LastP.x := Cx;
LastP.y := Cy;
LastC.x := LastP.x + (Random(Rand * 2) - Rand);
LastC.y := LastP.y + (Random(Rand * 2) - Rand);
repeat
Controls[0].x := LastP.x;
Controls[0].y := LastP.y;
Controls[1].x := LastP.x + -(LastC.x - LastP.x);
Controls[1].y := LastP.y + -(LastC.y - lastP.y);
Controls[2].x := Controls[1].x + (Random(Rand * 2) - Rand);
Controls[2].y := Controls[1].y + (Random(Rand * 2) - Rand);
Controls[3].x := Controls[2].x + (Random(Rand * 2) - Rand);
Controls[3].x := Controls[3].x + Round(-(Controls[3].x - (W / 2)) *
(Gravity));
Controls[3].y := Controls[2].y + (Random(Rand * 2) - Rand);
Controls[3].y := Controls[3].y + Round(-(Controls[3].y - (H / 2)) *
(Gravity));
LastC.x := Controls[2].x;
LastC.y := Controls[2].y;
LastP.x := Controls[3].x;
LastP.y := Controls[3].y;
Path := MakeSplinePath(Controls, 0.01);
Path := MidPoints(Path, 5);
n := GetArrayLength(Path);
for i := 0 to n - 1 do
begin
MoveMouse(Path[i].x, Path[i].y);
Wait(Random(2) + 2);
if (GetSystemTime - St >= Time) then Break
end;
until (GetSystemTime - St >= Time)
end;
function WaitUpTextMulti(S: TStringArray; Time: Integer): Boolean; Forward;
(*
SpiralMouseMulti
~~~~~~~~~~~~~~~~
.. code-block:: pascal
function SpiralMouseMulti(var fx, fy: Integer; x1, y1, x2, y2: Integer; UpText: TStringArray; PpC, aInc: Integer): Boolean;
Spirals the mouse in a circle from the center of the defined box.
It will continue to spiral until it finds a spiral completely outside
the box, always skipping points outside.
Returns the occurance of the first occurance of UpText into fx, fy.
Takes multiple UpTexts as a TStringArray.
PpC: The number of pixels to increase per spiral.
aInc: The number of stops to make around each spiral.
Takes some testing to get the right combination of PpC and aInc.
.. note::
by Nava2
Example:
.. code-block:: pascal
*)
function SpiralMouseMulti(var fx, fy: Integer; x1, y1, x2, y2: Integer; UpText: TStringArray; PpC, aInc: Integer): Boolean;
var
aStep, a, rStep, rV, oB: Extended;
pX, pY, ms: Integer;
sP: TPoint;
L2R: Boolean;
begin
Result := False;
ms := MouseSpeed;
MouseSpeed := 25 + RandomRange(-3, 3);
sP := MiddleTPA([Point(x1, y1), Point(x2, y2)]);
aStep := Pi / (aInc / 2);
a := 0;
rStep := (PpC / aInc);
L2R := Random(2) = 0;
//Writeln('aStep: ' + FloatToStr(aStep) + ' rStep ' + FloatToStr(rStep));
repeat
rV := rV + rStep;
pX := Round(rV * cos(a)) + sP.x;
pY := Round(rV * sin(a)) + sP.y;
if L2R then
a := a + aStep
else
a := a - aStep;
if InRange(pX, x1, x2) and InRange(pY, y1, y2) then
begin
oB := 0;
MMouse(pX - 2, pY - 2, 5, 5);
if WaitUpTextMulti(UpText, 300) then
begin
GetMousePos(fx, fy);
Result := True;
end;
end else
oB := oB + aStep;
until Result or (oB > (2 * Pi));
MouseSpeed := ms;
end;
(*
SpiralMouse
~~~~~~~~~~~
.. code-block:: pascal
function SpiralMouse(var fx, fy: Integer; x1, y1, x2, y2: Integer; UpText: String; PpC, aInc: Integer): Boolean;
Spirals the mouse in a circle from the center of the defined box.
It will continue to spiral until it finds a spiral completely outside
the box, always skipping points outside.
Returns the occurance of the UpText into fx, fy.
See `SpiralMouseMulti` for more information
.. note::
by Nava2
Example:
.. code-block:: pascal
*)
function SpiralMouse(var fx, fy: Integer; x1, y1, x2, y2: Integer; UpText: String; PpC, aInc: Integer): Boolean;
begin
Result := SpiralMouseMulti(fx, fy, x1, y1, x2, y2, [UpText], PpC, aInc);
end;
(*
DidClick
~~~~~~~~
.. code-block:: pascal
function DidClick(Red: Boolean; Time: integer): boolean;
Checks for the X after a click, Times Out after Time.
DidClick Time must be at LEAST 200 now.
.. note::
by Rasta Magician
Modded by Narcle on Feb. 4th, 2012
Example:
.. code-block:: pascal
*)
function DidClick(Red: Boolean; Time: integer): boolean;
var
TimeOut, x, y, w, h, R, G: integer;
B: TBox;
begin
GetMousePos(x, y);
GetClientDimensions(w, h);
B := IntToBox(x - 15, y - 15, x + 15, y + 15);
if B.x1 < 0 then B.x1 := 0;
if B.y1 < 0 then B.y1 := 0;
if B.x2 > w then B.x2 := w;
if B.y2 > h then B.y2 := h;
TimeOut := GetSystemTime + Time;
while (GetSystemTime < TimeOut) do
begin
R := CountColorTolerance(395675, B.x1, B.y1, B.x2, B.y2, 15);
G := CountColorTolerance(1695663, B.x1, B.y1, B.x2, B.y2, 15);
if Red then
begin
if (G > 8) then
Exit;
Result := (R > 20);
end else
begin
if (R > 5) then
Exit;
Result := (G > 35);
end;
if Result then
Exit;
end;
end;
(*
DidRedClick
~~~~~~~~~~~
.. code-block:: pascal
function DidRedClick: Boolean;
Checks for the Red X after a Click, Times out after 500 ms
.. note::
by Rasta Magician
Example:
.. code-block:: pascal
*)
function DidRedClick: Boolean;
begin
Result := DidClick(true, 1000);
end;
(*
DidYellowClick
~~~~~~~~~~~~~~
.. code-block:: pascal
function DidYellowClick: Boolean;
Checks for the Yellow X after a Click, Times out after 500 ms
.. note::
by Rasta Magician
Example:
.. code-block:: pascal
*)
function DidYellowClick: Boolean;
begin
Result := DidClick(false, 1000);
end;
(*
MouseOval
~~~~~~~~~
.. code-block:: pascal
procedure MouseOval(cx, cy, mx, my, clickType: Integer);
Clicks a random point within an oval shape.
* cx, cy: The center point of the oval.
* rx, ry: X and Y radius of the oval.
* clickType: mouse_Move, mouse_Left, mouse_Right, or mouse_Middle.
.. note::
by mixster
Last Updated: Unknown.
Example:
.. code-block:: pascal
*)
procedure MouseOval(cx, cy, rx, ry, clickType: Integer);
var
o: TPoint;
begin
if not InRange(clickType, 0, 3) then
begin
srl_Warn('MouseOval', 'ClickType is NOT a valid number!', warn_AllVersions);
exit;
end;
o.y := Random(ry) * ((Random(2) * 2) - 1);
o.x := Random(Round(Sqrt(Sqr(ry) - Sqr(o.y)) * rx / ry)) * ((Random(2) * 2) - 1);
case clickType of
mouse_right..mouse_middle: Mouse(cx + o.x, cy + o.y, 0, 0, clickType);
mouse_move: MMouse(cx + o.x, cy + o.y, 0, 0);
end;
end;
(*
MouseCircle
~~~~~~~~~~~
.. code-block:: pascal
procedure MouseCircle(MidX, MidY, Radius, clickType: Integer);
Same as MouseOval, but clicks within a circle instead.
.. note::
by mixster
Last Updated: Mar. 21st, 2012 by Coh3n
Example:
.. code-block:: pascal
*)
procedure MouseCircle(MidX, MidY, Radius, clickType: Integer);
begin
MouseOval(MidX, MidY, Radius, Radius, clickType);
end;
(*
MouseBoxEx
~~~~~~~~~~
.. code-block:: pascal
procedure MouseBoxEx(x1, y1, x2, y2: Integer; Dist,ClickType: Integer);
Does mouse stuff (ClickType), and uses a point that is within Dist from
the closest point between mouse and the box.
.. note::
by Raymond
Example:
.. code-block:: pascal
*)
procedure MouseBoxEx(x1, y1, x2, y2: Integer; Dist,ClickType: Integer);
var
PT : TPoint;
begin
GetMousePos(pt.x,pt.y);
PT := RandomPointBoxEx(pt,inttobox(x1,y1,x2,y2),Dist);
case ClickType of
mouse_right..mouse_middle : Mouse(pt.x, pt.y, 0, 0, clickType);
mouse_move : MMouse(pt.x, pt.y, 0, 0);
else
srl_Warn('MouseBox', 'ClickType is NOT a valid number!', warn_AllVersions);
end;
end;
(*
DragMouse
~~~~~~~~~
.. code-block:: pascal
procedure DragMouse(StartX, StartY, SRandX, SRandY, EndX, EndY, ERandX, ERandY: Integer);
Leftclicks StartX, StartY and drags mouse to EndX, EndY.
.. note::
by NaumanAkhlaQ
Example:
.. code-block:: pascal
*)
procedure DragMouse(StartX, StartY, SRandX, SRandY, EndX, EndY, ERandX, ERandY: Integer);
begin
MMouse(StartX, StartY, SRandX, SRandY);
Wait(150 + Random(20));
GetMousePos(StartX, StartY);
HoldMouse(StartX, StartY, mouse_left);
Wait(250 + Random(320));
MMouse(EndX, EndY, ERandX, ERandY);
Wait(250 + Random(120));
GetMousePos(EndX, EndY);
ReleaseMouse(EndX, EndY, mouse_left);
end;
(*
DragMouseTBox
~~~~~~~~~~~~~
.. code-block:: pascal
procedure DragMouseTBox(StartBox, EndBox: TBox);
Left clicks a point within StartBox and drags mouse to a point within EndBox,
of which the points selected follows a normal distribution from the centre of the box.
.. note::
by riwu, modelled after DragMouse by NaumanAkhlaQ
Example:
.. code-block:: pascal
*)
procedure DragMouseTBox(StartBox, EndBox: TBox);
var
StartX, StartY, EndX, EndY: Integer;
begin
MouseTBox(StartBox, mouse_move);
Wait(150 + Random(20));
GetMousePos(StartX, StartY);
HoldMouse(StartX, StartY, mouse_left);
Wait(250 + Random(320));
MouseTBox(EndBox, mouse_move);
Wait(250 + Random(120));
GetMousePos(EndX, EndY);
ReleaseMouse(EndX, EndY, mouse_left);
end;