Что нового

[Автоматизация] Бот для BlueStacks, считывание с экрана

Matuin

Новичок
Сообщения
10
Репутация
0
Доброго времени суток. Описание ситуации: написан бот, играющий в одну игрушку до бесконечности.

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

Используется:
Отсчет координат пикселей и координат мыши от левого верхнего окна эмулятора:

Код:
Opt("PixelCoordMode", 2) ;Отсчет координат пикселей от левого верхнего угла клиентской части окна
Opt("MouseCoordMode", 2) ;Отсчет координат мыши от левого верхнего угла клиентской части окна


Горячие клавиши остановки и вызова некоторых функций:
Код:
HotKeySet("{Pause}", "Kill")
HotKeySet("{F1}", "Zam")


Конструкции считывания картинки из эмулятора по типу:
Код:
$u2=PixelGetColor(255, 802)
$u3=PixelGetColor(207, 420)
if $u2=2369580 And $u3=2369580 Then
	MouseClick("left", 106, 77, 1, 5)
EndIf


Код:
$k1=PixelChecksum(613, 309, 645, 341)
if $k1=2157676909 Then
	MouseClick("left", 700, 484, 1, 5)
	sleep(500)
	MouseClick("left", 912, 159, 1, 5)
	sleep(5000)
EndIf


Код:
Func Zam()
	$aPos = MouseGetPos()
$mPos=PixelChecksum(779, 148, 1052, 179)
$Hcs=PixelChecksum(511,117, 876, 149)
$nPos=PixelChecksum(516, 317, 911, 360)
$xPos=PixelChecksum(210, 144, 269, 199)
$epos=PixelChecksum(40,734,243,775)
$kpos=PixelChecksum(312, 229, 325, 379)
	$j1=PixelChecksum(592,154, 833, 187)
	$j2=PixelChecksum(627, 276, 780, 313)
$j3=PixelChecksum(530, 186, 889, 222)
$k1=PixelChecksum(613, 309, 645, 341)
$k2=PixelChecksum(602, 81, 654, 90)
	$d1=PixelChecksum(808, 753, 1024, 785)
$d2=PixelChecksum(519,71,890,105)
$d3=PixelChecksum(517,210,891,242)
$d4=PixelChecksum(176,154,235,211)
	$j4= PixelChecksum(74, 57, 146, 113)
$j5= PixelChecksum(911, 281, 927,309)
$j6=PixelChecksum(91,241,126,261)
$s1=PixelChecksum(260,62 ,311,84)
MsgBox(4096, "Координаты курсора мыши:", 'X= ' & $aPos[0] & ", Y= " & $aPos[1])
MsgBox(4096, "чексуммы", '$m=' & $mPos & @LF & _
	'$Hcs=' & $Hcs & @LF & _
	'$nPos=' & $nPos & @LF & _
	'$xpos=' & $xPos & @LF & _
	'$kpos=' & $kpos & @LF & _
	'$epos=' & $epos & @LF & _
	'$j1=' & $j1 & @LF & _
	'$j2=' & $j2 & @LF & _
	'$j3=' & $j3 & @LF & _
	'$k1=' & $k1 & @LF & _
	'$k2=' & $k2 & @LF & _
	'$j4=' & $j4 & @LF & _
	'$c7=' & $c7 & @LF & _
	'$j5=' & $j5 & @LF & _
	'$d1=' & $d1 & @LF & _
	'$d2=' & $d2 & @LF & _
	'$d3=' & $d3 & @LF & _
	'$d4=' & $d4 & @LF & _
	'$j6=' & $j6 & @LF & _
	'$s1=' & $s1)
WinActivate($WinName)
EndFunc
 
Автор
M

Matuin

Новичок
Сообщения
10
Репутация
0
Поработал над вопросом:
вариант 1 - считать с памяти содержимое адресов, для определения текущего экрана, сложность: не известны адреса и их содержимое
вариант 2 - использовать библиотеку GDIPlus.au3, для создания битмапов. описание функций библиотеки пока не нашел, самому разбирать 5к строк кода не элементарно.
 

Sergio

Новичок
Сообщения
41
Репутация
3
https://autoit-script.ru/index.php?topic=3026.0
посмотри в этой теме. Может подойдет
 

DStalker

Ботоводство+Мультибоксинг = время выспаться ;)
Сообщения
39
Репутация
2
Matuin сказал(а):
Конструкции считывания картинки из эмулятора по типу:
Код:
$u2=PixelGetColor(255, 802)
$u3=PixelGetColor(207, 420)
if $u2=2369580 And $u3=2369580 Then
	MouseClick("left", 106, 77, 1, 5)
EndIf

Аможет так:
Код:
$pxlcolor1=PixelSearch(587, 101, 827, 326, 0x5EF0A0, 50);поиск пикселя1 с цветом1 и глубиной оттенков в 50.
							If Not @error Then
                                                        $pxlcolor2=PixelSearch(587, 101, 827, 326, 0x9EE022, 50);поиск пикселя2 с цветом2 и глубиной оттенков в 50.
							              If Not @error Then

								       sleep(100)
								       MouseClick ("left", $pxlcolor2[0],$pxlcolor2[1], 1, 10)
								       sleep(700)
							              EndIf
					                EndIf

и тогда от координат окна зависеть не будешь;)
 

Dellroc

Осваивающий
Сообщения
151
Репутация
31
Я решал данную проблему через поиск картинок с помощью библиотеки ImageSearchDLL, т.к. работа с пикселями часто подводит.
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Вместо PixelSearch можно адаптировать библиотеку FastFind, к ней может оказаться нелегко привыкнуть, но скорость обработки и точность возрастает в тысячи раз.
 
Автор
M

Matuin

Новичок
Сообщения
10
Репутация
0
Поиск пикселя работает в очень частном случае, поскольку возможна ситуация множества пикселей на экране одного цвета/оттенка. Для однозначной идентификации помогает только PixelCheckSum.
Однако стала известна причина, почему на другом ПК все изменилось, оказалось что у него другой размер окна эмулятора из за меньшего монитора, и эмулятор на пару пикселей не влезает в ширину. Пересмотрев все размеры зон чексумм, все заработало. Даже намного более стабильно, чем на первом ПК. Возможно на это изменение влияют различные обновления системы отвечающие за графику.

Прорабатывал вопрос по сканированию памяти, вполне реально считать содержимое каждой ячейке в диапазоне адресов от 0х10000 до 0х7EFE4FFC(сам размер диапазона был взят из редактора памяти ArtMoney). Идея была вычислить ячейки занимаемые именно приложением в эмуляторе через разницу содержимого памяти эмулятора с открытым приложением и без него. Были вычислены адреса, занимаемые приложением. Вот тут и был первый промах. Одно и тоже состояние приложения(главный экран) словно занимало совсем разные ячейки или имело совсем разные значения каждый раз при загрузке именно этого экрана. Я рассчитывал, что хотя бы часть из них будет совпадать; впрочем возможно так и есть, но я не доработал до окончания. Все затевалось для идентификации текущего экрана в приложении. Вероятно еще поработаю над этим вопросом.
 
Автор
M

Matuin

Новичок
Сообщения
10
Репутация
0
Вопрос решился путем развертки эмулятора на весь экран. Значительная часть чексумм остается прежней даже после обновлений клиента игры. Очевидно, будут изменяться при смене монитора(и разрешения экрана) и при переустановке операционной системы.
 

Ganibal95

GreenBytes
Сообщения
877
Репутация
240
Matuin сказал(а):
Вопрос решился путем развертки эмулятора на весь экран. Значительная часть чексумм остается прежней даже после обновлений клиента игры. Очевидно, будут изменяться при смене монитора(и разрешения экрана) и при переустановке операционной системы.
Не плохо было бы увидеть скриншот игры которую вы пытаетесь автоматизировать. Желательно в bmp или png формате без потери качества.
- м.б. в Эмуляторе присутствует настройки контрастности, яркости и прочее ?
- Возможно добавить к вашему сущ. боту отличие цветов на маску. т.е допустим у вас изначально был цвет 0xFF0000 при установке на другой ПК, цвет будет отличатся 0xFE0101 , ну как вариант, то можно добавить маску ( условие ).
Для начало каждый цвет разбить в структуру:

Код:
Structure RGB {
byte R;
byte G;
byte B;
}

Создаем константу для маски:

Код:
Const Mask  0x10

Далее разбиваем все в структуру и выполняем условия, я приведу пример для одного цвета, но для остальных условие не отличается.

Код:
if ( R < (R+Mask) & R > (R-Mask) ) {
// Ваше действие
}
 
Автор
M

Matuin

Новичок
Сообщения
10
Репутация
0
Игра Marvel:Битва чемпионов.
Сейчас вопрос стабильности отошел на задний план.
Намного важнее теперь преуспевание. На данном этапе ведение боя выглядит достаточно хаотично, поскольку быстро добывать информацию о себе и противнике я не нашел способа. Всякие захваты экрана и чексуммы не будут работать, слишком много переменного на экране: персонажи и фон, все постоянно в движении.
Для написания эффективного алгоритма обучения нужно знать расстояние между противниками и действия противника чуть ли не в каждый момент времени.
Копание в памяти не дало эффекта, не известно что и где искать.
Сейчас бой удачен, если попадает в правильный момент времени, если нет то проигрывает в ноль.
Код:
Func Fight()
	$ii=0
	While 1
		M($z1,$t1,$z2,$t2,$z3,$t3,$z4,$t4,$z5,$t5,$z6,$t6,$z7,$t7,$z8,$t8,$z9,$t9,$z10,$t10)
		$dArray[8]=PixelGetColor(937, 93)
		If $dArray[8]<>478726 Then ExitLoop
		$ii=$ii+1
		if $ii=7 then
			Send("{UP}")
			$ii=0
		EndIf
	WEnd
EndFunc

Пояснения:
$ii нужен для прожима спец атак, не прерывая основных клавиш.
$dArray[8] выход из цикла, после окончания боя.
Функция М используется для преобразования числовой комбинации в задержки между нажатиями клавиш и сами клавиши.
Были испробованы несколько алгоритмов обучения, а именно генетический и подкрепления-наказания. Подобрать комбинацию проще, чем сами клавиши.
Выглядит она по дилетантски, но минимальный удачный круг содержит именно столько клавиш.
Отрывок функции М
Код:
Func M($i1,$j1,$i2,$j2,$i3,$j3,$i4,$j4,$i5,$j5,$i6,$j6,$i7,$j7,$i8,$j8,$i9,$j9,$i10,$j10)
 	Select
		Case $i1=1
			Send("{UP}")
		Case $i1=2
			Send("{DOWN}")
		Case $i1=3
			Send("{RIGHT}")
		Case $i1=4
			Send("{LEFT}")
		Case $i1=5
			Send("{SPACE}")
		Case $i1=6
			Send("{RIGHT down}")
			sleep(250)
			Send("{RIGHT up}")
	EndSelect
	Select
		Case $j1=1
			Sleep(150)
		Case $j1=2
			Sleep(250)
		Case $j1=3
			Sleep(350)
		Case $j1=4
			Sleep(450)
		Case $j1=5
			Sleep(0)
		Case $j1=6
			Sleep(550)
		Case $j1=7
			Sleep(650)
		Case $j1=8
			Sleep(750)
	EndSelect

и так далее.
Была пара вариантов оптимизации до размера 100 знаков в комбинации, 50 клавиш и 50 задержек, но это эффекта не возымело. Каждый бой уникален и реагировать определенно нужно на определенные действия противника. Для этого требуется добыть информацию из оперативной памяти приложения, как выше говорилось, не известно что и где именно искать.
 

Вложения

  • BlueStacks_ScreenShot.jpg
    BlueStacks_ScreenShot.jpg
    178.7 КБ · Просмотры: 32
Верх