Воскресенье, 03.02.2013, 06:13 Приветствую вас Гость | Группа "Гости" 


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Страница 1 из 1 1
Модератор форума: gravitas, C@T  
delfcode » Delphi » Процедуры и функции Delphi » Human-like движения мыши. (юнит.)
Human-like движения мыши.
CynicRus Дата: Среда, 30.01.2013, 15:42 | Сообщение # 1
Новичок
Зарегистрирован: 30.01.2013
Группа: Пользователи
Сообщений: 3
Статус: Offline
Приветствую уважаемых форумчан. Сей модуль был написан мной на Delphi XE, но должен без проблем скомпилироваться в любой другой версии дельфей , для Lazarus+FPC будет необходимо внести небольшие коррективы. Модуль реализует функциональность 'human-like mouse movements', тоесть движения мышью как человеческие. Модуль будет полезен для тех, ктора разрабатывает всяческих ботов для игр или интернет казино\покера.

Код

unit uMMovements;
  //Human-like mouse movements
  //Original idea - SRL community(http://villavu.com)
  //Ported to Delphi by CynicRus; [email protected]
interface
  uses
   Classes, SysUtils,Windows;

type
   TPointArray = array of TPoint;

   TBox = record
     x1, y1, x2, y2: Integer;
   end;

TClickType = (mouse_Left=1, mouse_Right=0, mouse_Middle=2);
     PMouseInput = ^TMouseInput;
     tagMOUSEINPUT = packed record
       dx: Longint;
       dy: Longint;
       mouseData: DWORD;
       dwFlags: DWORD;
       time: DWORD;
       dwExtraInfo: DWORD;
     end;
     TMouseInput = tagMOUSEINPUT;

     PKeybdInput = ^TKeybdInput;
     tagKEYBDINPUT = packed record
       wVk: WORD;
       wScan: WORD;
       dwFlags: DWORD;
       time: DWORD;
       dwExtraInfo: DWORD;
     end;
     TKeybdInput = tagKEYBDINPUT;

     PHardwareInput = ^THardwareInput;
     tagHARDWAREINPUT = packed record
       uMsg: DWORD;
       wParamL: WORD;
       wParamH: WORD;
     end;
     THardwareInput = tagHARDWAREINPUT;
     PInput = ^TInput;
     tagINPUT = packed record
       Itype: DWORD;
       case Integer of
         0: (mi: TMouseInput);
         1: (ki: TKeybdInput);
         2: (hi: THardwareInput);
     end;
     TInput = tagINPUT;

   const
     INPUT_MOUSE = 0;
     INPUT_KEYBOARD = 1;
     INPUT_HARDWARE = 2;
//WinApi
function SendInput(cInputs: UINT; var pInputs: TInput; cbSize: Integer): UINT; stdcall; external user32 name 'SendInput';

//Internal functions
procedure GetMousePosition(out x,y: integer);
procedure MoveMouse(x,y: integer);
procedure HoldMouse(x,y: integer; button: TClickType);
procedure ReleaseMouse(x,y: integer; button: TClickType);
function  IsMouseButtonHeld( button : TClickType) : boolean;
procedure ClickMouse(button: TClickType);
//Mouse movements implementation
procedure WindMouse(xs, ys, xe, ye, gravity, wind, minWait, maxWait, maxStep, targetArea: extended);
procedure MMouse(x, y, rx, ry: integer);
procedure Mouse(mousex, mousey, ranx, rany: Integer; button: TClickType);
procedure SleepAndMoveMouse(Time: Integer);
procedure DragMouse(StartX, StartY, SRandX, SRandY, EndX, EndY, ERandX, ERandY: Integer);

//Human-like mouse movements
procedure BrakeWindMouse(xs, ys, xe, ye, gravity, wind, minWait, maxWait, targetArea: extended);
procedure BrakeMMouse(eX, eY, ranX, ranY: Integer);
procedure ShiftWindMouse(xs, ys, xe, ye, gravity, wind, minWait, maxWait, maxStep, targetArea: extended);
procedure MissMouse(eX, eY, ranX, ranY: Integer);

var
   MouseSpeed: integer=3;

implementation

  uses math;

procedure GetMousePosition(out x,y: integer);
var
  MousePos: Windows.TPoint;
begin
   Windows.GetCursorPos(MousePos);
   x:=MousePos.X;
   y:=MousePos.Y;
end;

procedure MoveMouse(x,y: integer);
begin
   Windows.SetCursorPos(x, y);
end;

procedure HoldMouse(x,y: integer; button: TClickType);
var
   Input : TInput;
begin
   Input.Itype:= INPUT_MOUSE;
   FillChar(Input,Sizeof(Input),0);
   Input.mi.dx:= x;
   Input.mi.dy:= y;
   case button of
     Mouse_Left: Input.mi.dwFlags:= MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTDOWN;
     Mouse_Middle: Input.mi.dwFlags:= MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MIDDLEDOWN;
     Mouse_Right: Input.mi.dwFlags:= MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_RIGHTDOWN;
   end;
   SendInput(1,Input, sizeof(Input));
end;

procedure ReleaseMouse(x,y: integer; button: TClickType);
var
   Input : TInput;
   Rect : TRect;
begin
   Input.Itype:= INPUT_MOUSE;
   FillChar(Input,Sizeof(Input),0);
   Input.mi.dx:= x + Rect.left;
   Input.mi.dy:= y + Rect.Top;
    case button of
      Mouse_Left: Input.mi.dwFlags:= MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP;
      Mouse_Middle: Input.mi.dwFlags:= MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MIDDLEUP;
      Mouse_Right: Input.mi.dwFlags:= MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_RIGHTUP;
    end;
   SendInput(1,Input, sizeof(Input));
end;

function  IsMouseButtonHeld( button : TClickType) : boolean;
begin
   case button of
      mouse_Left : Result := (GetAsyncKeyState(VK_LBUTTON) <> 0);
      mouse_Middle : Result := (GetAsyncKeyState(VK_MBUTTON) <> 0);
      mouse_Right : Result := (GetAsyncKeyState(VK_RBUTTON) <> 0);
   end;
end;

procedure ClickMouse(button: TClickType);
var
   a,b,c : integer;
begin
   { Eventually, should be made to just use Integers }
   GetMousePosition(b, c);
   HoldMouse(b, c, Button);
   repeat
     Sleep(20 + Random(30));
     a := a + 1;
   until (a > 4);
   GetMousePosition(b, c);
   ReleaseMouse(b, c, Button);
   Sleep(50+Random(50));
end;
{Moves the mouse along a spline defined by
     by Benland100
     Convert to Delphi by Cynic}
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:= min(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);
       Sleep(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;

procedure MMouse(x, y, rx, ry: integer);
var
   cx, cy: integer;
   randSpeed: Extended;
begin
   GetMousePosition(cx, cy);
   randSpeed:= (random(MouseSpeed) / 2.0 + MouseSpeed) / 10.0;
   if randSpeed = 0.0 then
     randSpeed := 0.1;
   X := x + random(rx);
   Y := y + random(ry);
   WindMouse(cx,cy,x,y,9.0,3.0,10.0/randSpeed,15.0/randSpeed,10.0*randSpeed,10.0*randSpeed);
end;

procedure Mouse(mousex, mousey, ranx, rany: Integer; button: TClickType);
begin
   MMouse(mousex, mousey, ranx, rany);
   Sleep(60 + Random(30));
   ClickMouse(button);
   Sleep(50 + Random(50));
end;

procedure SleepAndMoveMouse(Time: Integer);
var
   Moving: Boolean;
   mx, my: Integer;
   x, y, xv, yv: Extended;
   gx, gy: Extended;
   T: Integer;
begin
   GetMousePosition(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;

procedure DragMouse(StartX, StartY, SRandX, SRandY, EndX, EndY, ERandX, ERandY: Integer);
begin
   MMouse(StartX, StartY, SRandX, SRandY);
   Sleep(150 + Random(20));
   GetMousePosition(StartX, StartY);
   HoldMouse(StartX, StartY, mouse_left);
   Sleep(250 + Random(320));
   MMouse(EndX, EndY, ERandX, ERandY);
   Sleep(250 + Random(120));
   GetMousePosition(EndX, EndY);
   ReleaseMouse(EndX, EndY, mouse_left);
end;

function Distance(x1,y1,x2,y2 : integer) : integer;
begin
   Result := Round(Sqrt(Sqr(x2-x1) + Sqr(y2-y1)));
end;
{*******************************************************************************
procedure Procedure BrakeWindMouse(xs, ys, xe, ye, gravity, wind, minWait,
   maxWait, targetArea: extended);
By: Flight
Description: Mouse movement based on distance to determine speed.
              Default brake at 15%.
*******************************************************************************}
Procedure BrakeWindMouse(xs, ys, xe, ye, gravity, wind, minWait, maxWait, targetArea: extended);
var
   veloX,veloY,windX,windY,veloMag,dist,randomDist,lastDist: extended;
   lastX,lastY,MSP,W,maxStep,D,TDist: integer;
   sqrt2,sqrt3,sqrt5,PDist: 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;
   repeat

     dist:= hypot(xs - xe, ys - ye);
     wind:= min(wind, dist);
     if (dist < 1) then
       dist := 1;
     PDist := (dist/TDist);
     if (PDist < 0.01) then
       PDist := 0.01;

     {
       These constants seem smooth to me, but
       feel free to modify these settings however
       you wish.
     }

     if (PDist >= 0.15) then                    //15% (or higher) dist to destination
     begin
       D := Round(Round((Round(dist)*0.3))/5);
       if (D < 20) then
         D := 20;
         //D := RandomRange(15, 25);                        {Original}
     end else if (PDist < 0.15) then
     begin
       if ((PDist <= 0.15) and (PDist >= 0.10)) then         //10%-15%
         D := RandomRange(8, 13)
       else if (PDist < 0.10) then                           //< 10%
         D := RandomRange(4, 7);
     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;
     W := Round(W*1.2);
     Sleep(W);
     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));
     MouseSpeed :=MSP;
end;

Procedure BrakeMMouse(eX, eY, ranX, ranY: Integer);
var
   randSpeed: extended;
   X,Y,MS: integer;
begin
   MS := MouseSpeed;
   randSpeed := (random(MouseSpeed) / 2.0 + MouseSpeed) / 10.0;
   GetMousePosition(X, Y);
   BrakeWindMouse(X, Y, eX, eY, 9, 5, 10.0 / randSpeed, 15.0 / randSpeed, 10.0 * randSpeed);
   MouseSpeed := MS;
end;

{*******************************************************************************
procedure 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 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:= min(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;

     if (lastX <> Round(xs)) or (lastY <> Round(ys)) then
       MoveMouse(Round(xs), Round(ys));

     step:= hypot(xs - lastX, ys - lastY);
     sleep(round((maxWait - minWait) * (step / maxStep) + minWait));
     lastdist:= dist;
     MouseSpeed := 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;

   if (Round(xe) <> Round(xs)) or (Round(ye) <> Round(ys)) then
     MoveMouse(Round(xe), Round(ye));
    MouseSpeed := MS;
end;

{*******************************************************************************
procedure MissMouse(eX, eY, 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 MissMouse(eX, eY, ranX, ranY: Integer);
var
   randSpeed: extended;
   X,Y,X2,Y2,A,Dist,MP: integer;
begin
   A := MouseSpeed;
   GetMousePosition(X, Y);
   Dist := Distance(X, Y, eX, eY);
   MP := Round(Dist/150);
   if MP < 0 then
     MP := 1;
   randSpeed := (random(MouseSpeed) / 2.0 + MouseSpeed) / 10.0;
   X2 := RandomRange(eX-(A*MP), eX+(A*MP));
   Y2 := RandomRange(eY-(A*MP), eY+(A*MP));
   ShiftWindMouse(X, Y, X2, Y2, 11, 8, 10.0 / randSpeed, 12.0 / randSpeed, 10.0 * randSpeed, 10.0 * randSpeed);
   GetMousePosition(X, Y);
   MMouse(eX, eY, ranX, ranY);
   MouseSpeed := A;
end;

procedure FastClick(button: TClickType);
var
   x, y: integer;
begin
   GetMousePosition(x, y);
   HoldMouse(x, y, button);
   Sleep(RandomRange(60, 150));
   GetMousePosition(x, y);
   ReleaseMouse(x, y, button);
end;

end.



Cheers,
Cynic.
 
Волк-1024 Дата: Среда, 30.01.2013, 18:04 | Сообщение # 2
Продвинутый
Зарегистрирован: 24.07.2011
Группа: Проверенные
Сообщений: 281
Статус: Offline
Избавься от модулей Classes, SysUtils и будет вообще отлично.





Delphi+Assembler=Сила
 
CynicRus Дата: Четверг, 31.01.2013, 13:18 | Сообщение # 3
Новичок
Зарегистрирован: 30.01.2013
Группа: Пользователи
Сообщений: 3
Статус: Offline
Я первоначально писал код под Lazarus+FPC так как мне нужно было кросплатформенное решение, потому и присутствую эти 2 стандартных модуля для него. И впринципе достаточно заменить Windows на LCLType,LCLIntf и данный код без проблем будет работать на всех поддерживаемых Lazarus платформах. Код проверен и работоспособен, а наличие этих модулей в данной версии юнита - если хотите небольшая система AntiLeech. Кому потребуется то сам без труда их уберёт, ну а если постребовалось а убрать такие юниты реципиент не в состоянии - значит и не надо оно ему-)
 
delfcode » Delphi » Процедуры и функции Delphi » Human-like движения мыши. (юнит.)
Страница 1 из 1 1
Поиск:

delfcode.ru © 2008 - 2013 Хостинг от uCoz