Что нового

Бот перестаёт попадать кликами если браузер не прижат к краю монитора

Soofft91

Новичок
Сообщения
1
Репутация
0
Здравствуйте.
Прошло всего пару дней как я узнал об AutoIt, поэтому заранее извиняюсь если мой вопрос очень глупый и банальный.

Бот прекрасно работает когда окно расположено в левом углу монитора, стоит его немного сдвинуть как бот начинает кликать мимо поля. Могу предположить что проблема с точкой отсчёта координат (на 2 и/или 3 этапе работы), но самостоятельно уже 2-ое суток не могу исправить.

Демонстрация: youtube[точка]com/watch?v=AKa3YeVXm3k

Весь код бота:
Код:
#Include <WinAPIEx.au3>
#include <GUIConstantsEx.au3>
;~ #include <Array.au3> ; для _ArrayDisplay.
#Include <ImageSearch.au3>

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUIStatusBar.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>



HotKeySet("{F2}", "start")
HotKeySet("{F3}", "Pause")
HotKeySet("{F4}", "end")



;~ Local $startPole[2]
;~ Local $startPole = [85, 339]
;~ Local $endPole = [485, 700]
Global $posX = 0
Global $posY = 0
Global $status = 0
$iNumCols = 10
$iNumRows = 9
Dim $aiField[9][10]

;~ Global $wPole = $endPole[0]-$startPole[1]
;~ Global $hPole = $endPole[1]-$startPole[1]


#Region ### START Koda GUI section ### Form=
   $Form1 = GUICreate("Form1", 171, 364, -1, -1)
   $Label1 = GUICtrlCreateLabel("Позиция окна", 6, 16, 75, 17)
   $Input1 = GUICtrlCreateInput("", 96, 8, 65, 21, BitOR($GUI_SS_DEFAULT_INPUT,$ES_CENTER))
   GUICtrlSetState(-1, $GUI_DISABLE)
   $Label2 = GUICtrlCreateLabel("Клик по коорд.", 6, 46, 80, 17)
   $Input2 = GUICtrlCreateInput("", 96, 40, 65, 21, BitOR($GUI_SS_DEFAULT_INPUT,$ES_CENTER))
   GUICtrlSetState(-1, $GUI_DISABLE)
   $Button1 = GUICtrlCreateButton("Старт!", 16, 72, 131, 33)
   $Group1 = GUICtrlCreateGroup("", 8, 112, 153, 9)
   GUICtrlCreateGroup("", -99, -99, 1, 1)
   $Label3 = GUICtrlCreateLabel("1 2 3 4 5 6 7 8 9 0", 8, 128, 147, 225)
   $status = _GUICtrlStatusBar_Create($Form1)
   _GUICtrlStatusBar_SetText($status, "Ожидание запуска...")
   GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###




Func end()
   Exit 0
EndFunc




; Координаты поля
Func searchPole()
   local $search = _ImageSearch('pic.png', 0, $posX, $posY, 0x15)
   If $search = 1 Then
	  $posX += 20
	  $posY += 20
	  MouseClick("left", $posX, $posY, 1)
	Else
		MsgBox(0,"Not Found", "Corner template wasn't found")
		Return False
   EndIf
EndFunc



Func Div($iValue1, $iValue2)                                                ;there is no standard div function, so i implemented mine
	Return ($iValue1 - Mod($iValue1, $iValue2)) / $iValue2
EndFunc

Func _GetCheckColor($iPixelColor)                                           ;get cell color from color of inner pixel
	Local $Red = Div($iPixelColor, 0x10000)
	Local $Green =  Mod(Div($iPixelColor, 0x100), 0x100)
	Local $Blue = Mod($iPixelColor, 0x100)
	Local $d = 0x10                                                         ;const for imprecision
	;some magic numbers, obtained from experiments
	Select
		Case $Red > 0x90 - $d And $Green < 0x70 + $d And $Blue < 0x70 + $d
			Return 1									;red
		Case $Red < 0x50 + $d And $Green > 0x90 - $d And $Blue < 0x50 + $d
			Return 2									;green
		Case $Red < 0x50 + $d And $Green < 0x70 + $d And $Blue > 0x90 - $d
			Return 3									;blue
		Case $Red > 0xA0 - $d And $Green > 0xA0 - $d And $Blue < 0x30 + $d
			Return 4									;yellow
		Case $Red > 0x70 - $d And $Green < 0x70 + $d And $Blue > 0x90 - $d
			Return 5									;purple
		Case Else
			Return 0									;indefinite color
	EndSelect
 EndFunc




;~ WinActivate("Diamond Dash на Facebook - Google Chrome")


Func click($iX, $iY)
   MouseClick("left", $iX, $iY, 1)
EndFunc


Func getColors()
;~    $Timer = TimerInit()

	Local $hWnd = WinGetHandle("[ACTIVE]")
;~ 	Local $hWnd = WinGetHandle("Diamond Dash на Facebook - Google Chrome")
	Local $Size = WinGetClientSize($hWnd)
	Local $hDC = _WinAPI_GetDC($hWnd)
	Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC)
	Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $Size[0], $Size[1])
	Local $hSv = _WinAPI_SelectObject($hMemDC, $hBitmap)
	_WinAPI_BitBlt($hMemDC, 0, 0, $Size[0], $Size[1], $hDC, 0, 0, "0x00CC0020")
	_WinAPI_SelectObject($hMemDC, $hSv)
	_WinAPI_DeleteDC($hMemDC)
	_WinAPI_ReleaseDC($hWnd, $hDC)
	Local $L = $Size[0] * $Size[1]
	Local $tBits = DllStructCreate('dword[' & $L & ']')
	_WinAPI_GetBitmapBits($hBitmap, 4 * $L, DllStructGetPtr($tBits))

	For $iCol = 0 To $iNumCols - 1
		Local $fOverExplosion = False
		For $iRow = $iNumRows - 1 to 0 Step -1
			;explosion checkout
			Local $iX = $posX + ($iCol * 40) + 14
			Local $iY = $posY + ($iRow * 40) + 4
			Local $iPixelColor = Mod(DllStructGetData($tBits, 1, $iY * $Size[0] + $iX), 0x1000000)
;~ 			If _IsWhite($iPixelColor) Then
;~ 				$fOverExplosion = True
;~ 			EndIf
			If $fOverExplosion Then
				$aiField[$iRow][$iCol] = 0
			Else
				;cell color probe
;~ 				$iX = $iCornerX + ($iCol * 40) + $iDeltaX
;~ 				$iY = $iCornerY + ($iRow * 40) + $iDeltaY
				$iX = $posX + ($iCol * 40) + 14
			    $iY = $posY + ($iRow * 40) + 4


				$iPixelColor = Mod(DllStructGetData($tBits, 1, $iY * $Size[0] + $iX), 0x1000000)
				$aiField[$iRow][$iCol] = _GetCheckColor($iPixelColor)
				If _GetCheckColor($iPixelColor) == 0 Then
;~ 				   ConsoleWrite($iX&"x"&$iY&" - алмаз"&@CR)
			   EndIf
			EndIf
		Next
	Next


	_WinAPI_DeleteObject($hBitmap)
	_WinAPI_DeleteObject($hMemDC)
	_WinAPI_DeleteObject($tBits)



;~    _ArrayDisplay($aiField, 'С указанием строки и колонки в ячейках')
;~    $iDiff = TimerDiff($Timer)
;~    ConsoleWrite($iDiff / 1000&@CR)
EndFunc





Func _DfsSearch($boxColor, $iX, $iY)
   $t1 = 1
;~    ConsoleWrite($iX&"x"&$iY&" ")
;~    ConsoleWrite($aiField[$iX][$iY]&" ")


   If $iX <> 0 And $boxColor == $aiField[$iX-1][$iY] Then ; Проверка от текущей точки (ВВЕРХ -1)
	  $t1 = $t1 + 1
	  If $iY <> 0 And $boxColor == $aiField[$iX-1][$iY-1] Then ; (ВВЕРХ -1, ВЛЕВО -1)
		 $t1 = $t1 + 1
	  EndIf
	  If $iX >= 2 And $boxColor == $aiField[$iX-2][$iY] Then ; (ВВЕРХ -2)
		 $t1 = $t1 + 1
	  EndIf
	  If $iY <= 8 And $iX <> 0 And $boxColor == $aiField[$iX-1][$iY+1] Then ; (ВВЕРХ -1, ВПРАВО +1)
		 $t1 = $t1 + 1
	  EndIf
   EndIf


   If $iY <= 8 And $boxColor == $aiField[$iX][$iY+1] Then ; Проверка от текущей точки (ВПРАВО +1)
	  $t1 = $t1 + 1
	  If $iX <> 0 And $boxColor == $aiField[$iX-1][$iY+1] Then ; ( ВПРАВО +1, ВВЕРХ -1)
		 $t1 = $t1 + 1
	  EndIf
	  If $iY <= 7 And $boxColor == $aiField[$iX][$iY+2] Then ; ( ВПРАВО +2)
		 $t1 = $t1 + 1
	  EndIf
	  If $iX <> 8 And $boxColor == $aiField[$iX+1][$iY+1] Then ; ( ВПРАВО +1, ВНИЗ -1)
		 $t1 = $t1 + 1
	  EndIf
   EndIf

   Return $t1
EndFunc



; Поиск в глубину
Func startSearch()
   getColors()
;~    _ArrayDisplay($aiField, 'С указанием строки и колонки в ячейках')
;~    $Timer2 = TimerInit()

   For $i = 0 to Ubound($aiField) - 1
	  $numArray = 8 - $i

	  For $iv = 0 to 9
		 $sovpad = 0 ; Сбрасывание счётчика совпадений
		 $boxColor = $aiField[$numArray][$iv] ; Переменная с текущим цветом

		 If $boxColor <> 0 Then
			$sovpad = _DfsSearch($boxColor, $numArray, $iv)
		 EndIf

		 ; Действие если найдено больше 3-х совпадений
		 If $sovpad >= 3 Then
			$iX = $posX + ($iv * 40) + 20
			$iY = $posY + ($numArray * 40) + 20
			MouseClick("left", $iX, $iY, 1)
			ConsoleWrite($iX&"x"&$iY&@CR)
;~ 			MouseMove($iX, $iY, 1)
;~ 			ConsoleWrite($numArray&"x"&$iv&":"&$sovpad&" ") ; Вывод позиции для клика и кол-во совпадений

;~ 			$iDiff2 = TimerDiff($Timer2)
;~ 			ConsoleWrite($iDiff2 / 1000&@CR)

;~ 			Sleep(2000)
;~ 			startSearch()
			Return False
		 EndIf
	  Next
   Next
EndFunc










Func Pause()
   $status = 0
   _GUICtrlStatusBar_SetText($status, "Пауза")
EndFunc
;~ startSearch()


While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $Button1
			_GUICtrlStatusBar_SetText($status, "Работает")
			start()
	EndSwitch


   if $status = 1 Then
	  Sleep(100)
	  startSearch()
   EndIf
WEnd





Func start()
   searchPole()
   $status = 1
   GUICtrlSetData($Input1, $posX&" x "&$posY)


#CS
   While 2
	  Sleep(1000)


	  GUICtrlSetData($label3, $text)
   WEnd
#CE

EndFunc


1 этап работы: С помощью функции _ImageSearch() нахожу край игрового поля и для проверки верного нахождения отправляю туда курсор, на видео видно что положение поля всегда определяется верно. Также позиция поля попадает в окно программы.

2 этап работы: делаю снимок экрана и проверяю цвета каждого квадрата. Заношу цвета в массив.

3 этап работы: поиск 3-х идущих подряд квадрата с одинаковым цветом и клик по первому из них.
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Посмотри опции
Код:
Opt("MouseCoordMode", ..)
Opt("PixelCoordMode", ..)

Они левым верхним углом отсчета для стандартных команд
Если команды нестандартные то придется в ручную расчитывать отступы через
Код:
WinGetPos()
 
Верх