Code:
{
// ----------[ Mouse Handler ] ---------- //
[Version]: 1.00
[Description]: A set of custom mouse routines intended to simulate
human-realistic movements
}
Procedure AL_SetMouseSpeed(Speed: Integer);
{var
RanVal: Integer;
TempSpeed: Extended;
ExVals1,ExVals2: Array of Extended;
}
begin
MouseSpeed := Speed;
{
if (Speed < 2) then
Speed := 2;
ExVals1 := [1.1,1.2,1.3];
ExVals2 := [0.7,0.8,0.9];
RanVal := RandomRange(0,2);
Case AL_Mood of
'Normal': TempSpeed := (Speed*1.0);
'Goofy' : TempSpeed := (Speed*(ExVals1[RanVal]));
'Bored' : TempSpeed := (Speed*(ExVals2[RanVal]));
end;
if (Round(TempSpeed) < 2) then
TempSpeed := 2;
MouseSpeed := Round(TempSpeed);
}
end;
{*******************************************************************************
Type MEvent
By: Flight
Description: Mouse event combining movement & click type with end point
and random X/Y additions
*******************************************************************************}
Type
MEvent = record
MType: string;
EPoint: TPoint;
CType,RX,RY: integer;
End;
{*******************************************************************************
procedure Procedure AL_BrakeWindMouse(xs, ys, xe, ye, gravity, wind, minWait,
maxWait, targetArea: extended; reverse: boolean);
By: Flight
Description: Mouse movement based on distance to determine speed. Default slowed
speed at 20% from destination, if Double is set to true then slowed
speed also starts at origin and ends 80% to destination.
*******************************************************************************}
Procedure AL_BrakeWindMouse(xs, ys, xe, ye, gravity, wind, minWait, maxWait,
targetArea: extended; double: boolean);
var
veloX,veloY,windX,windY,veloMag,dist,randomDist,lastDist,D: extended;
lastX,lastY,MSP,W,TDist,T: integer;
sqrt2,sqrt3,sqrt5,PDist,maxStep,dModA,dModB,nModA,nModB: extended;
begin
MSP := MouseSpeed;
sqrt2:= sqrt(2);
sqrt3:= sqrt(3);
sqrt5:= sqrt(5);
TDist := Distance(Round(xs), Round(ys), Round(xe), Round(ye));
if (TDist < 1) then
TDist := 1;
dModA := 0.88; //.80
dModB := 0.95; //.90
if (TDist > 220) then
begin
nModA := 0.08;
nModB := 0.04;
end else if (TDist <= 220) then
begin
nModA := 0.20;
nModB := 0.10;
end;
MarkTime(T);
repeat
if (TimeFromMark(T)>5000) then
break;
dist:= hypot(xs - xe, ys - ye);
wind:= minE(wind, dist);
if (dist < 1) then
dist := 1;
PDist := (dist/TDist);
if (PDist < 0.01) then
PDist := 0.01;
if Double then
begin
if (PDist <= dModA) then
begin
D := (Round((Round(dist)*0.3))/5);
if (D < 20) then
D := 20;
end else if (PDist > dModA) then
begin
if (PDist < dModB) then
D := RandomRange(5, 8)
else if (PDist >= dModB) then
D := RandomRange(3, 4);
end;
end;
if (PDist >= nModA) then
begin
D := (Round((Round(dist)*0.3))/5);
if (D < 20) then
D := 20;
end else if (PDist < nModA) then
begin
if (PDist >= nModB) then
D := RandomRange(5, 8)
else if (PDist < nModB) then
D := RandomRange(3, 4);
end;
if (D <= Round(dist)) then
maxStep := D
else
maxStep := Round(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;
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));
W := (Random((Round(100/MSP)))*6);
if (W < 5) then
W := 5;
if Double then
if (PDist > dModA) then
W := Round(W*2.5)
else
W := Round(W*1.2);
wait(W);
lastdist:= dist;
until(hypot(xs - xe, ys - ye) < 1)
if (Round(xe) <> Round(xs)) or (Round(ye) <> Round(ys)) then
MMouse(Round(xe), Round(ye), 0, 0);
AL_SetMouseSpeed(MSP);
end;
{*******************************************************************************
Procedure AL_HumanWindMouse(xs, ys, xe, ye, gravity, wind, minWait,
maxWait, targetArea: extended);
By: Flight
Description: ....
*******************************************************************************}
Procedure AL_HumanWindMouse(xs, ys, xe, ye, gravity, wind, minWait, maxWait, targetArea: extended);
var
veloX,veloY,windX,windY,veloMag,dist,randomDist,lastDist,D: extended;
lastX,lastY,MSP,W,T,TDist: integer;
sqrt2,sqrt3,sqrt5,maxStep,rCnc: extended;
begin
MSP := MouseSpeed;
sqrt2:= sqrt(2);
sqrt3:= sqrt(3);
sqrt5:= sqrt(5);
TDist := Distance(Round(xs), Round(ys), Round(xe), Round(ye));
MarkTime(T);
repeat
if (TimeFromMark(T)>10000) then
break;
dist:= hypot(xs - xe, ys - ye);
wind:= minE(wind, dist);
if (dist < 1) then
dist := 1;
D := (Round((Round(TDist)*0.3))/7);
if (D > 25) then
D := 25;
if (D < 5) then
D := 5;
rCnc := Random(6);
if (rCnc = 1) then
D := RandomRange(2,3);
if (D <= Round(dist)) then
maxStep := D
else
maxStep := Round(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;
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));
W := (Random((Round(100/MSP)))*6);
if (W < 5) then
W := 5;
W := Round(W*0.9);
wait(W);
lastdist:= dist;
until(hypot(xs - xe, ys - ye) < 1)
if (Round(xe) <> Round(xs)) or (Round(ye) <> Round(ys)) then
MMouse(Round(xe), Round(ye), 0, 0);
AL_SetMouseSpeed(MSP);
end;
{*******************************************************************************
Procedure AL_WindMouseDTM(xs, ys, xe, ye, gravity, wind, minWait, maxWait,
targetArea: extended; DTM: Integer)
By: Flight
Description: "Slowly" moves the mouse while searching for a DTM
on the main-screen.
*******************************************************************************}
Function AL_WindMouseDTM(xs, ys, xe, ye, gravity, wind, minWait, maxWait, targetArea: extended; DTM: Integer): Boolean;
var
veloX,veloY,windX,windY,veloMag,dist,randomDist,lastDist,step: extended;
lastX,lastY,MSP,W,maxStep,X,Y: integer;
sqrt2,sqrt3,sqrt5: extended;
fX,fY,mX,mY: Integer;
B: TBox;
begin
Result := False;
MSP := MouseSpeed;
sqrt2 := sqrt(2);
sqrt3 := sqrt(3);
sqrt5 := sqrt(5);
repeat
dist:= hypot(xs - xe, ys - ye);
wind:= minE(wind, dist);
maxStep := (RandomRange(2, 4));
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;
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));
GetMousePos(mX, mY);
B := IntToBox(mX-5, mY-5, mX+5, mY+5);
//Search for the scroll bar near the mouse
if (not FindColorTolerance(fX, fY, 4807781, B.x1, B.y1, B.x2, B.y2, 25)) then
Exit;
if FindDTM(DTM, X, Y, MSX1, MSY1, MSX2, MSY2) then
begin
Result := True;
Exit;
end;
case Random(50) of
1..25: W := (MSP + (Random((MSP/4))));
26..50: W := (MSP - (RandomRange((MSP/2), MSP-1)));
end;
if (W < 1) then
W := 1;
wait(W);
step:= hypot(xs - lastX, ys - lastY);
lastdist:= dist;
until(hypot(xs - xe, ys - ye) < 1)
if (Round(xe) <> Round(xs)) or (Round(ye) <> Round(ys)) then
MoveMouse(Round(xe), Round(ye));
AL_SetMouseSpeed(MSP);
end;
{*******************************************************************************
procedure BrakeMMouse(Pnt: TPoint; ranX, ranY: Integer; double: Boolean);
By: Flight
Description: Makes use of BrakeWindMouse; mouse speed decreases at 15% to
destination point. If Double is set to true then speed starts
slow and increases through the first 15% of the path.
*******************************************************************************}
Procedure AL_BrakeMMouse(Pnt: TPoint; ranX, ranY: Integer; double: Boolean);
var
randSpeed: extended;
X,Y,MS: integer;
begin
MS := MouseSpeed;
randSpeed := (random(MouseSpeed) / 2.0 + MouseSpeed) / 10.0;
GetMousePos(X, Y);
AL_BrakeWindMouse(X, Y, RandomRange(Pnt.X-ranX, Pnt.X+ranX), RandomRange(Pnt.Y-ranY,Pnt.Y+ranY),
8, 3, 10.0/randSpeed, 15.0/randSpeed, 10.0*randSpeed, double);
AL_SetMouseSpeed(MS);
end;
{*******************************************************************************
procedure AL_AccurateMMouse(Pnt: TPoint; ranX, ranY: Integer);
By: Flight
Description: Same as BrakeMMouse but uses a much straighter path; required
for choosing tabbed options.
*******************************************************************************}
Procedure AL_AccurateMMouse(Pnt: TPoint; ranX, ranY: Integer);
var
randSpeed: extended;
X,Y,MS: integer;
begin
MS := MouseSpeed;
randSpeed := (random(MouseSpeed) / 2.0 + MouseSpeed) / 10.0;
GetMousePos(X, Y);
AL_BrakeWindMouse(X, Y, RandomRange(Pnt.X-ranX, Pnt.X+ranX), RandomRange(Pnt.Y-ranY,Pnt.Y+ranY), 14, 3, 10.0/randSpeed, 15.0/randSpeed, 10.0*randSpeed, False);
AL_SetMouseSpeed(MS);
end;
{*******************************************************************************
procedure AL_HumanMMouse(Pnt: TPoint; ranX, ranY: Integer);
By: Flight
Description:...
*******************************************************************************}
Procedure AL_HumanMMouse(Pnt: TPoint; ranX, ranY: Integer);
var
randSpeed: extended;
X,Y,MS: integer;
begin
MS := MouseSpeed;
randSpeed := (random(MouseSpeed) / 2.0 + MouseSpeed) / 10.0;
GetMousePos(X, Y);
AL_HumanWindMouse(X, Y, RandomRange(Pnt.X-ranX, Pnt.X+ranX), RandomRange(Pnt.Y-ranY,Pnt.Y+ranY), 7, 5, 10.0 / randSpeed, 15.0 / randSpeed, 10.0 * randSpeed);
AL_SetMouseSpeed(MS);
end;
{*******************************************************************************
procedure AL_ShiftWindMouse(xs, ys, xe, ye, gravity, wind, minWait, maxWait, maxStep,
targetArea: extended);
By: Flight
Description: Mouse movement that shifts speed after every mouse 'step'
*******************************************************************************}
procedure AL_ShiftWindMouse(xs, ys, xe, ye, gravity, wind, minWait, maxWait, maxStep, targetArea: extended);
var
veloX,veloY,windX,windY,veloMag,dist,randomDist,lastDist,step: extended;
lastX,lastY,MS: integer;
sqrt2,sqrt3,sqrt5: extended;
begin
MS := MouseSpeed;
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;
case Random(2) of
1: MouseSpeed := (MS+(RandomRange(2,5)));
2: MouseSpeed := (MS-(RandomRange(2,5)));
end;
if (MouseSpeed < 4) then
MouseSpeed := 4;
AL_SetMouseSpeed(MouseSpeed);
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;
AL_SetMouseSpeed(MS);
end;
case Random(2) of
1: MouseSpeed := (MS+(RandomRange(2,5)));
2: MouseSpeed := (MS-(RandomRange(2,5)));
end;
if (MouseSpeed < 4) then
MouseSpeed := 4;
AL_SetMouseSpeed(MouseSpeed);
if (Round(xe) <> Round(xs)) or (Round(ye) <> Round(ys)) then
MoveMouse(Round(xe), Round(ye));
AL_SetMouseSpeed(MS);
end;
{*******************************************************************************
procedure AL_MissMouse(Pnt: TPoint; ranX, ranY: Integer);
By: Flight
Description: Makes use of ShiftWindMouse; it also initially misses the target
point (miss area determined by dist & speed) then corrects itself.
*******************************************************************************}
Procedure AL_MissMouse(Pnt: TPoint; ranX, ranY: Integer);
var
randSpeed: extended;
X,Y,X2,Y2,A,Dist,MP: integer;
begin
A := MouseSpeed;
GetMousePos(X, Y);
Dist := Distance(X, Y, Pnt.X, Pnt.Y);
MP := Round(Dist/150);
if MP < 0 then
MP := 1;
randSpeed := (random(MouseSpeed) / 2.0 + MouseSpeed) / 10.0;
X2 := RandomRange(Pnt.X-(A*MP), Pnt.X+(A*MP));
Y2 := RandomRange(Pnt.Y-(A*MP), Pnt.Y+(A*MP));
AL_ShiftWindMouse(X, Y, X2, Y2, 11, 8, 10.0 / randSpeed, 12.0 / randSpeed, 10.0 * randSpeed, 10.0 * randSpeed);
GetMousePos(X, Y);
AL_BrakeMMouse(Pnt, ranX, ranY, True);
AL_SetMouseSpeed(A);
end;
{*******************************************************************************
procedure AL_HumanRandomMouse;
By: Flight
Description: Slowly moves the mouse a short distance in a random direction.
*******************************************************************************}
Procedure AL_HumanRandomMouse;
var
randSpeed: extended;
x, y, firstSpeed: integer;
begin
firstSpeed := mouseSpeed;
AL_SetMouseSpeed(RandomRange(5, 10));
randSpeed := (random(MouseSpeed) / 2.0 + MouseSpeed) / 10.0;
GetMousePos(x, y);
AL_HumanWindMouse(x, y, RandomRange(x-75,x+75), RandomRange(y-75,y+75),
30, 55, 10.0 / randSpeed, 12.0 / randSpeed, 10.0 * randSpeed);
AL_SetMouseSpeed(firstSpeed);
end;
{*******************************************************************************
procedure AL_FastClick(button: Integer);
By: Flight
Description: Quickly click or right-click the mouse.
*******************************************************************************}
procedure AL_FastClick(button: Integer);
var
x, y: integer;
begin
if (button = mouse_move) then Exit;
GetMousePos(x, y);
HoldMouse(x, y, button);
Wait(RandomRange(60, 150));
GetMousePos(x, y);
ReleaseMouse(x, y, button);
end;
{*******************************************************************************
procedure AL_MouseBoxEx(x1, y1, x2, y2, Dist, ClickType: Integer);
By: Raymond (modded by Flight)
Description: Does mouse stuff (ClickType), and uses a point that is within Dist from
the closest point between mouse and the box.
*******************************************************************************}
procedure AL_MouseBoxEx(x1, y1, x2, y2, Dist, ClickType: Integer);
var
PT : TPoint;
begin
GetMousePos(pt.x,pt.y);
PT := RandomPointBoxEx(pt,inttobox(x1,y1,x2,y2),Dist);
AL_BrakeMMouse(pt, 0, 0, False);
AL_FastClick(ClickType);
end;
function AL_ConMEvent(MType: String; Pnt: TPoint; rX, rY, CType: Integer): MEvent;
begin
if ((not(Lowercase(MType) = 'normal')) and
(not(Lowercase(MType) = 'miss')) and
(not(Lowercase(MType) = 'human')) and
(not(Lowercase(MType) = 'brake'))) then
begin
srl_Warn('ConMEvent', 'Invalid MType; please use normal, miss, or brake', warn_AllVersions);
exit;
end;
if not InRange(CType, 0, 3) then
begin
srl_Warn('ConMEvent', 'Invalid CType; please use mouse_left, mouse_right, or mouse_move', warn_AllVersions);
exit;
end;
Result.MType := MType;
Result.CType := CType;
Result.EPoint := Pnt;
Result.RX := rX;
Result.RY := rY;
end;
function AL_IsMEventValid(MouseIn: MEvent): Boolean;
begin
Result := False;
if (MouseIn.MType <> '') then
if InRange(MouseIn.CType, 0, 3) then
if (MouseIn.EPoint.X > 0) then
Result := ((MouseIn.RX >= 0) and (MouseIn.RY >= 0));
end;
function AL_StreamMouse(MouseIn: MEvent; UpTextArr, RClickOptions: TStringArray;
UpTextWait, OptionsWait: Integer): Boolean;
begin
Result := False;
if not AL_IsMEventValid(MouseIn) then
begin
srl_Warn('AL_StreamMouse', 'Invalid MEvent', warn_AllVersions);
exit;
end;
case lowercase(MouseIn.MType) of
'normal': MMouse(MouseIn.EPoint.X, MouseIn.EPoint.Y, MouseIn.RX, MouseIn.RY);
'miss' : AL_MissMouse(MouseIn.EPoint, MouseIn.RX, MouseIn.RY);
'human' : AL_HumanMMouse(MouseIn.EPoint, MouseIn.RX, MouseIn.RY);
'brake' : AL_BrakeMMouse(MouseIn.EPoint, MouseIn.RX, MouseIn.RY, True)
end;
if ((Length(UpTextArr) = 0) and (Length(RClickOptions) = 0)) then
begin
AL_FastClick(MouseIn.CType);
result := True;
exit;
end;
if (Length(UpTextArr) > 0) then
begin
if WaitUpTextMulti(UpTextArr, UpTextWait) then
begin
AL_FastClick(MouseIn.CType);
if (Length(RClickOptions) > 0) then
result := WaitOptionMulti(RClickOptions, OptionsWait)
else
result := True;
exit;
end else
exit;
end;
if ((Length(UpTextArr) = 0) and (Length(RClickOptions) > 0)) then
begin
AL_FastClick(mouse_right);
result := WaitOptionMulti(RClickOptions, OptionsWait);
end;
end;