#RequireAdmin
#include <WinAPI.au3>
OnAutoItExitRegister("Cleanup")
Opt("TrayAutoPause", 0) ; скрипт не останавливает работу при наведении и кликах мышью на значок скрипта в системном трее
Opt("WinWaitDelay", 100) ; продолжительность паузы успешного ожидания в оконных функциях
Opt("MouseCoordMode", 0) ; относительные координаты активного окна для указателя мыши для большей совместимости кликов через Windows Messages
Opt("PixelCoordMode", 2) ; относительные координаты клиентской области активного окна для пиксельных функций
Global $Paused = False
Global Const $kgranic[6] = [0x55,0x48,0x46,0x59,0x42,0x57] ; массив ASCII кодов символов "границ"
Global Const $meshochek[5] = [0x0F124A,0x150A0F,0x453709,0x231B01,0x48340D] ; массив пяти пикселей части изображения мешочка, идущих один за одним по оси Х
; будем искать третий пиксел, затем сравнивать соседние слева направо
Global $key_ret, $key_lParam, $key_lUpParam, $user32, $coord
Global Const $WM_KEYDOWN = 0x0100, $WM_KEYUP = 0x0101, $WM_ACTIVATE = 0x0006, $WM_SETFOCUS = 0x0007
;;; вешаем хук на обработку нажатий клавиш Pause и Control+Pause
Global $hMod = _WinAPI_GetModuleHandle(0)
Global $hStub_KeyProc = DllCallbackRegister("KeyProc", "long", "int;wparam;lparam")
Global $hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($hStub_KeyProc), $hMod, 0)
;;;
Global $handle = WinGetHandle("[CLASS:Turbine Device Class]") ; получаем хэндл окна с игрой по его классу
Global $hWidth = _WinAPI_GetClientWidth($handle)
Global $hHeight = _WinAPI_GetClientHeight($handle)
If _WinAPI_GetKeyboardLayout($handle) <> 0x0419 Then _WinAPI_SetKeyboardLayout($handle, 0x0419) ; меняем раскладку клавиатуры на русскую в окне игры, если стоит другая
WinSetState($handle, "", @SW_DISABLE) ; отключаем возможность пользовательского взаимодействия с окном
DllCall("user32.dll", "int", "SendMessage", "hwnd", $handle, "uint", $WM_ACTIVATE, "int", 1, "int", 0) ; делаем вид что активируем окно с игрой
DllCall("user32.dll", "int", "SendMessage", "hwnd", $handle, "uint", $WM_SETFOCUS, "int", 1, "int", 0) ; делаем вид что передаем окну фокус для пользовательского ввода
While 1
LClick(111, 53) ; клик в начало области ввода Поиска Невостребованных трофеев
$user32 = DllOpen("user32.dll")
If @error Then ExitLoop
; вводим слово "границ" посимвольно из массива ASCII кодов для поиска Мешочков стражей границ в окне Невостребованных трофеев
For $i = 0 To UBound($kgranic)-1
$key_ret = DllCall($user32, 'int', "MapVirtualKey", 'int', $kgranic[$i], 'int', 0)
$key_lParam = BitOR(BitShift($key_ret[0], -16), 1)
$key_lUpParam = BitOR($key_lParam, 0xC0000000)
DllCall($user32, "int", "PostMessage", "hwnd", $handle, "int", $WM_KEYDOWN, "int", $kgranic[$i], "long", $key_lParam)
Sleep(Random(10, 150, 1))
DllCall($user32, "int", "PostMessage", "hwnd", $handle, "int", $WM_KEYUP, "int", $kgranic[$i], "long", $key_lUpParam)
Sleep(Random(15, 250, 1))
Next
DllClose($user32)
RClick(43, 128) ; клик ПКМ по местоположению первого найденного трофея в списке трофеев (его там может и не быть, но это проверять дольше и вовсе необязательно)
LClick(260, 53) ; клик в конец области ввода, чтобы далее воспользоваться Backspace и стереть написанное
; это необходимо когда надо искать названия нескольких трофеев по очереди - данный пример упрощенный вариант для одного трофея
$user32 = DllOpen("user32.dll")
If @error Then ExitLoop
$key_ret = DllCall($user32, 'int', "MapVirtualKey", 'int', 0x08, 'int', 0) ; клавиша Backspace (далее жмем 10 раз (для подстраховки) чтобы стереть написанное)
$key_lParam = BitOR(BitShift($key_ret[0], -16), 1)
$key_lUpParam = BitOR($key_lParam, 0xC0000000)
For $i = 1 To 10
DllCall($user32, "int", "PostMessage", "hwnd", $handle, "int", $WM_KEYDOWN, "int", $key_ret[1], "long", $key_lParam)
Sleep(Random(10, 150, 1))
DllCall($user32, "int", "PostMessage", "hwnd", $handle, "int", $WM_KEYUP, "int", $key_ret[1], "long", $key_lUpParam)
Sleep(Random(15, 250, 1))
Next
DllClose($user32)
LClick(1166, 650) ; клик по выбранному ассисту, чтобы убрать фокус из области ввода текста, но чтобы при этом не сбросился выбранный ассист
$user32 = DllOpen("user32.dll")
If @error Then ExitLoop
$key_ret = DllCall($user32, 'int', "MapVirtualKey", 'int', 0x78, 'int', 0) ; клавиша F9 для выбора в ассист следующего игрока
$key_lParam = BitOR(BitShift($key_ret[0], -16), 1)
$key_lUpParam = BitOR($key_lParam, 0xC0000000)
DllCall($user32, "int", "PostMessage", "hwnd", $handle, "int", $WM_KEYDOWN, "int", $key_ret[1], "long", $key_lParam)
Sleep(Random(10, 150, 1))
DllCall($user32, "int", "PostMessage", "hwnd", $handle, "int", $WM_KEYUP, "int", $key_ret[1], "long", $key_lUpParam)
Sleep(Random(15, 250, 1))
$key_ret = DllCall($user32, 'int', "MapVirtualKey", 'int', 0x31, 'int', 0) ; клавиша 1 для использования скилла (хотка на хил) на игрока в ассисте, для получения общего с ним лута
$key_lParam = BitOR(BitShift($key_ret[0], -16), 1)
$key_lUpParam = BitOR($key_lParam, 0xC0000000)
DllCall($user32, "int", "PostMessage", "hwnd", $handle, "int", $WM_KEYDOWN, "int", 0x31, "long", $key_lParam)
Sleep(Random(10, 150, 1))
DllCall($user32, "int", "PostMessage", "hwnd", $handle, "int", $WM_KEYUP, "int", 0x31, "long", $key_lUpParam)
Sleep(Random(15, 250, 1))
DllClose($user32)
Sleep(Random(2000, 3000, 1))
$coord = _SearchPix($hWidth - 434, $hHeight - 412, $hWidth, $hHeight, $meshochek)
If Not @error Then RClick($coord[0], $coord[1]) ; кликаем ПКМ по изображению Мешочка стражей границ, в случае если он был найден, чтобы извлечь из него Медальены стражей границ
Sleep(Random(4000, 6000, 1))
WEnd
; снятие скриншота неактивного окна и обрезание области по указанным координатам
; последовательное заполнение созданной в памяти структуры данных $tBits пикселями (их цветами) из полученной области
; поиск пикселя заданного цвета в структуре данных $tBits
Func _SearchPix(Const $x1, Const $y1, Const $x2, Const $y2, ByRef Const $i_Color, $shvar = 0)
Local $i_R, $i_G, $i_B, $cur_Color, $cur_R, $cur_G, $cur_B, $pix_Color, $pix_R, $pix_G, $pix_B, $a_Pixels[2]
Local $iWidth = $x2-$x1
Local $iHeight = $y2-$y1
Local $iSize = $iWidth * $iHeight
Local $tBits = DllStructCreate('dword[' & $iSize & ']')
Local $hDDC = _WinAPI_GetDC($handle)
Local $hSrcDC = _WinAPI_CreateCompatibleDC($hDDC)
Local $hSrcBitmap = _WinAPI_CreateCompatibleBitmap($hDDC, $hWidth, $hHeight)
Local $hSrcObj = _WinAPI_SelectObject($hSrcDC, $hSrcBitmap)
DllCall("user32.dll", "int", "PrintWindow", "hwnd", $handle, "hwnd", $hSrcDC, "int", 1)
Local $hDestDC = _WinAPI_CreateCompatibleDC($hDDC)
Local $hDestBitmap = _WinAPI_CreateCompatibleBitmap($hDDC, $iWidth, $iHeight)
Local $hDestObj = _WinAPI_SelectObject($hDestDC, $hDestBitmap)
_WinAPI_BitBlt($hDestDC, 0, 0, $iWidth, $iHeight, $hSrcDC, $x1, $y1, 0x00CC0020) ; $SRCCOPY
_WinAPI_GetBitmapBits($hDestBitmap, 4 * $iSize, DllStructGetPtr($tBits))
_WinAPI_SelectObject($hSrcDC, $hSrcObj)
_WinAPI_SelectObject($hDestDC, $hDestObj)
_WinAPI_DeleteDC($hSrcDC)
_WinAPI_DeleteDC($hDestDC)
_WinAPI_DeleteObject($hSrcBitmap)
_WinAPI_DeleteObject($hDestBitmap)
_WinAPI_ReleaseDC($handle, $hDDC)
If $shvar <= 0 Then
For $i = 1 To $iSize
$cur_Color = BitAND(DllStructGetData($tBits, 1, $i), 0x00FFFFFF)
If BitXOR($cur_Color, $i_Color[2]) == 0 Then
For $k = 0 to 4
If $k <> 2 Then
$pix_Color = $i_Color[$k]
$cur_Color = BitAND(DllStructGetData($tBits, 1, $i+$k-2), 0x00FFFFFF)
If BitXOR($cur_Color, $pix_Color) <> 0 Then ExitLoop
If $k = 4 Then
$a_Pixels[0] = Mod($i, $iWidth) - 1 + $x1
$a_Pixels[1] = Ceiling($i / $iWidth) - 1 + $y1
Return $a_Pixels
EndIf
EndIf
Next
EndIf
Next
Else
$i_R = BitAND(BitShift($i_Color[2], 16), 0xFF)
$i_G = BitAND(BitShift($i_Color[2], 8), 0xFF)
$i_B = BitAND($i_Color[2], 0xFF)
For $i = 1 To $iSize
$cur_Color = BitAND(DllStructGetData($tBits, 1, $i), 0x00FFFFFF)
$cur_R = BitAND(BitShift($cur_Color, 16), 0xFF)
$cur_G = BitAND(BitShift($cur_Color, 8), 0xFF)
$cur_B = BitAND($cur_Color, 0xFF)
If Abs($cur_R-$i_R)<=$shvar And Abs($cur_G-$i_G)<=$shvar And Abs($cur_B-$i_B)<=$shvar Then
For $k = 0 to 4
If $k <> 2 Then
$pix_Color = $i_Color[$k]
$pix_R = BitAND(BitShift($pix_Color, 16), 0xFF)
$pix_G = BitAND(BitShift($pix_Color, 8), 0xFF)
$pix_B = BitAND($pix_Color, 0xFF)
$cur_Color = BitAND(DllStructGetData($tBits, 1, $i+$k-2), 0x00FFFFFF)
$cur_R = BitAND(BitShift($cur_Color, 16), 0xFF)
$cur_G = BitAND(BitShift($cur_Color, 8), 0xFF)
$cur_B = BitAND($cur_Color, 0xFF)
If Not (Abs($cur_R-$pix_R)<=$shvar And Abs($cur_G-$pix_G)<=$shvar And Abs($cur_B-$pix_B)<=$shvar) Then ExitLoop
If $k = 4 Then
$a_Pixels[0] = Mod($i, $iWidth) - 1 + $x1
$a_Pixels[1] = Ceiling($i / $iWidth) - 1 + $y1
Return $a_Pixels
EndIf
EndIf
Next
EndIf
Next
EndIf
Return SetError(1)
EndFunc
Func LClick($X = "", $Y = "") ; функция клика левой кнопкой мыши
Local Const $WM_MOUSEMOVE = 0x0200, $WM_LBUTTONDOWN = 0x0201, $WM_LBUTTONUP = 0x0202
Local $long = BitOR($Y * 0x10000, BitAND($X, 0xFFFF))
DllCall("user32.dll", "int", "SendMessage", "hwnd", $handle, "uint", $WM_ACTIVATE, "int", 1, "int", 0) ; делаем вид что активируем окно с игрой
DllCall("user32.dll", "int", "SendMessage", "hwnd", $handle, "uint", $WM_SETFOCUS, "int", 1, "int", 0) ; делаем вид что передаем окну фокус для пользовательского ввода
Local $mouse_pos = MouseGetPos() ; запоминаем текущее положение указателя мыши
$user32 = DllOpen("user32.dll")
If @error Then Exit
DllCall($user32, "int", "PostMessage", "hwnd", $handle, "int", $WM_MOUSEMOVE, "int", 0, "long", $long) ; перемещаем указатель мыши в окне игры по указанным функции координатам
Sleep(Random(15, 25, 1))
DllCall($user32, "int", "PostMessage", "hwnd", $handle, "int", $WM_LBUTTONDOWN, "int", 0x0001, "long", 0) ; производим клик в окне игры
DllCall($user32, "int", "PostMessage", "hwnd", $handle, "int", $WM_LBUTTONUP, "int", 0x0001, "long", 0)
Sleep(Random(15, 25, 1))
DllClose($user32)
MouseMove($mouse_pos[0], $mouse_pos[1], 0) ; перемещаем указатель мыши в предварительно записанные координаты
Sleep(Random(25, 250, 1))
EndFunc
Func RClick($X = "", $Y = "") ; функция клика правой кнопкой мыши
Local Const $WM_MOUSEMOVE = 0x0200, $WM_RBUTTONDOWN = 0x0204, $WM_RBUTTONUP = 0x0205
Local $long = BitOR($Y * 0x10000, BitAND($X, 0xFFFF))
DllCall("user32.dll", "int", "SendMessage", "hwnd", $handle, "uint", $WM_ACTIVATE, "int", 1, "int", 0) ; делаем вид что активируем окно с игрой
DllCall("user32.dll", "int", "SendMessage", "hwnd", $handle, "uint", $WM_SETFOCUS, "int", 1, "int", 0) ; делаем вид что передаем окну фокус для пользовательского ввода
Local $mouse_pos = MouseGetPos() ; запоминаем текущее положение указателя мыши
$user32 = DllOpen("user32.dll")
If @error Then Exit
DllCall($user32, "int", "PostMessage", "hwnd", $handle, "int", $WM_MOUSEMOVE, "int", 0, "long", $long) ; перемещаем указатель мыши в окне игры по указанным функции координатам
Sleep(Random(15, 25, 1))
DllCall($user32, "int", "PostMessage", "hwnd", $handle, "int", $WM_RBUTTONDOWN, "int", 0x0001, "long", 0) ; производим клик в окне игры
DllCall($user32, "int", "PostMessage", "hwnd", $handle, "int", $WM_RBUTTONUP, "int", 0x0001, "long", 0)
Sleep(Random(15, 25, 1))
DllClose($user32)
MouseMove($mouse_pos[0], $mouse_pos[1], 0) ; перемещаем указатель мыши в предварительно записанные координаты
Sleep(Random(25, 250, 1))
EndFunc
; функция постановки на паузу по горячей клавише Pause Break
Func TogglePause()
AdlibUnRegister("TogglePause")
While $Paused
Sleep(1000)
WEnd
If _WinAPI_GetKeyboardLayout($handle) <> 0x0419 Then _WinAPI_SetKeyboardLayout($handle, 0x0419) ; меняем раскладку клавиатуры на русскую в окне игры, если стоит другая
WinSetState($handle, "", @SW_DISABLE) ; отключаем возможность пользовательского взаимодействия с окном
DllCall("user32.dll", "int", "SendMessage", "hwnd", $handle, "uint", $WM_ACTIVATE, "int", 1, "int", 0) ; делаем вид что активируем окно с игрой
DllCall("user32.dll", "int", "SendMessage", "hwnd", $handle, "uint", $WM_SETFOCUS, "int", 1, "int", 0) ; делаем вид что передаем окну фокус для пользовательского ввода
EndFunc
; DLL Callback function
Func KeyProc($nCode, $wParam, $lParam)
If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
Local $tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
Local $tKeyCode = DllStructGetData($tKEYHOOKS, "vkCode")
If $wParam = $WM_KEYDOWN Then
If $tKeyCode = 0x03 Then ; код клавиш "CTRL+PAUSE"
Exit
ElseIf $tKeyCode = 0x13 Then ; код клавиши "PAUSE"
$Paused = Not $Paused
If $Paused Then
WinSetState($handle, "", @SW_ENABLE) ; включаем возможность пользовательского взаимодействия с окном
AdlibRegister("TogglePause", 100)
EndIf
EndIf
EndIf
Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc
Func Cleanup() ; функция срабатывающая при завершении скрипта
_WinAPI_UnhookWindowsHookEx($hHook)
DllCallbackFree($hStub_KeyProc)
WinSetState($handle, "", @SW_ENABLE) ; включаем возможность пользовательского взаимодействия с окном
EndFunc
Func _WinAPI_LoadKeyboardLayout($iLanguage, $iFlag = 0)
Local $Ret = DllCall('user32.dll', 'uint_ptr', 'LoadKeyboardLayoutW', 'wstr', Hex($iLanguage, 8), 'uint', $iFlag)
If (@error) Or (Not $Ret[0]) Then
Return SetError(1, 0, 0)
EndIf
Return $Ret[0]
EndFunc
Func _WinAPI_SetKeyboardLayout($hWnd, $iLanguage, $iFlags = 0)
Local $hLocale = 0
If $iLanguage Then
$hLocale = _WinAPI_LoadKeyboardLayout($iLanguage)
If @error Then
Return SetError(1, 0, 0)
EndIf
EndIf
DllCall('user32.dll', 'none', 'SendMessage', 'hwnd', $hWnd, 'uint', 0x0050, 'uint', $iFlags, 'uint_ptr', $hLocale)
Return 1
EndFunc
Func _WinAPI_GetKeyboardLayout($hWnd)
Local $Ret
$Ret = DllCall('user32.dll', 'dword', 'GetWindowThreadProcessId', 'hwnd', $hWnd, 'ptr', 0)
If (@error) Or (Not $Ret[0]) Then
Return SetError(1, 0, 0)
EndIf
$Ret = DllCall('user32.dll', 'uint_ptr', 'GetKeyboardLayout', 'dword', $Ret[0])
If (@error) Or (Not $Ret[0]) Then
Return SetError(1, 0, 0)
EndIf
Return $Ret[0]
EndFunc
Func _WinAPI_GetBitmapBits($hBitmap, $iSize, $pBits)
Local $Ret = DllCall('gdi32.dll', 'dword', 'GetBitmapBits', 'ptr', $hBitmap, 'dword', $iSize, 'ptr', $pBits)
If (@error) Or (Not $Ret[0]) Then
Return SetError(1, 0, 0)
EndIf
Return $Ret[0]
EndFunc