Что нового

[Drakensang-Online] Бот для игры

sebun

Знающий
Сообщения
81
Репутация
5
В игре Drakensang-Online реализована почти трехмерная графика. На локации множество подвижных элементов, динамично меняющих свое положение, например огонь или бегущий моб. В написании бота для этой игры дошел до того момента, когда нужно определить объекты на карте, определить положение мобов, дроп, динамичные элементы, не имеющие отношения к игровому процессу (вода, свет, огонь). У каждого значимого элемента в игре есть особенность - при наведении на него курсора мыши он подсвечивается разными цветами, например портал - белым, враг - красным, дроп - желтозеленым. Сканирование карты попиксельно с помощью PixelSearch практически не работает из за высокой динамики, цвета быстро меняются, а задавая погрешность в параметрах функции бот находит не то, что нужно. Пробовал блоками - разделил экран на регионы и пробовал получать контрольную сумму каждого региона через PixelChecksum. Запускал два цикла. Первый сохранял контрольные суммы регионов в массив, второй повторно читал регионы и сравнивал со значениями в массиве. Не то. Даже когда карта стоит на месте, множество ложных срабатываний, к тому же сканирование занимает до нескольких секунд, за это время локация может сильно измениться. Курил форум несколько дней, просматривал темы по другим играм, смотрел про возможность сканирования памяти клиента, но пока решения не нашел, так как хочется, что бы бот работал независимо от клиента, управляя лишь клавиатурой и мышью, его не должны отловить и заблокировать персонажа, так как во многие персонажи влиты большие реальные деньги.

Прошу помощи у AutoIT-сообщества в решении вопроса по быстрому распознаванию объектов в локации, не затрагивая при этом сам клиент игры. Буду благодарен ссылкам и просто предложениям по реализации этого вопроса. :scratch:
 

lirikmel

Продвинутый
Сообщения
226
Репутация
84
курсор мыши меняется при навидении на обьект ?
 
Автор
sebun

sebun

Знающий
Сообщения
81
Репутация
5
Если бы все было так просто... Нет, курсор меняется один раз при входе в игру и остается таким на протяжении всего игрового процесса. Меняются лишь объекты игры - на тех объектах, над которыми можно произвести действие, при наведении появляется яркое обрамление разных цветов, "аура" так сказать. Вот ее я пока и беру за основу для определения "свой-чужой". Вот здесь можно посмотреть видео из игры, чтобы понять сам процесс формирования графики.

Поскольку все функции чтения с экрана отнимают время, сегодня буду пробовать такой вариант: попробую разбить экран на регионы, после чего в каждый помещать полоску толщиной в 1 пиксель, читать содержимое региона в массив, затем наводить на регион мышь и читать снова, сравнить с массивом, если изменилось - ... не уверен что прокатит, так как очень много движений на экране, мобы бегут постоянно и пачками. Да и скорость сканирования будет низкой, нужно более шустрое и оригинальное решение.
 

Dellroc

Осваивающий
Сообщения
151
Репутация
31
Я бы сделал так: за основу взял изменение курсора отслеживаемое по функции _WinAPI_GetCursorInfo, а поиск мобов по круговому движению мыши вокруг персонажа с увеличением радиуса сканирования.
Код:
Global Const $degToRad = 4 * ATan(1) / 180
$iY = @DesktopHeight / 2
$iX = @DesktopWidth / 2
$i_Step = 5
$i_Count = 0
$fPause = True

HotKeySet('{ESC}', '_Exit')
HotKeySet('{F5}', '_Pause')
MouseMove($iX, $iY, 0)
$iCursorOld = MouseGetCursor()
While 1
    If $fPause Then
        $i_Count += $i_Step
        If $i_Count / 100 >= $iY Then $i_Count = 0
        MouseMove(Int($iX + $i_Count / 100 * Cos($i_Count * $degToRad)), _
                Int($iY + $i_Count / 100 * Sin($i_Count * $degToRad)), 0)
        $iCursorNew = MouseGetCursor()
        If $iCursorOld <> $iCursorNew Then
            _MyFunc()
            Sleep(50); чтобы MsgBox успел закрыться
            MouseMove($iX, $iY, 0)
            $iCursorOld = MouseGetCursor()
            $i_Count = 0
        EndIf
    EndIf
    Sleep(5)
WEnd

Func _Pause()
    $fPause = Not $fPause
EndFunc   ;==>_Pause
Func _MyFunc()
    MsgBox(64, 'Info', 'Курсор изменился в координатах:' & @LF & _
            Int($iX + $i_Count / 100 * Cos($i_Count * $degToRad)) & 'x' & _
            Int($iY + $i_Count / 100 * Sin($i_Count * $degToRad)))
EndFunc   ;==>_MyFunc

Func _Exit()
    Exit
EndFunc   ;==>_Exit
 

lirikmel

Продвинутый
Сообщения
226
Репутация
84
Я бы сделал так: за основу взял изменение курсора отслеживаемое по функции _WinAPI_GetCursorInfo, а поиск мобов по круговому движению мыши вокруг персонажа с увеличением радиуса сканирования.
ну я поэтому и спрашивал про изменение курсора, похоже не вариант..
Вопрос второй клик левой клавиши передвижение ?
Можно выделить цель правой клавишей мыши ?
 
Автор
sebun

sebun

Знающий
Сообщения
81
Репутация
5
Я бы сделал так: за основу взял изменение курсора...
Ты бы так не сделал, курсор всегда статичен.

Вопрос второй клик левой клавиши передвижение ?
Можно выделить цель правой клавишей мыши ?
Кнопки мыши настраиваются, но! Левая кнопка - если моба нет, то движение, если моб - используется скилл (атака). Правая - скилл2 (атака). Постоянное нажатие на левую или правую кнопки - то же самое - движение в точку положения курсора или атака этой точки. Объекты логически распознаются только по двум признакам:
Код:
   if [объект движется или шевелится] then
        if [при наведении курсора мыши вокруг объекта появляется красный ореол] then
            [Враг! Атака!]
        elseif [при наведении курсора мыши вокруг объекта появляется зеленый ореол] then
            [свояк, пусть идет своей дорогой]
        elseif [при наведении курсора мыши вокруг объекта появляется желтый ореол] then
            [дроп, плохо лежит, перепрятать!]
        else
            [хрен пойми что, возможно бабочка, игнорировать]
        endif
    endif

По поводу кругового движения мыши - делал, но с PixelSearch (повторюсь, курсор в игре не меняется), скорость работы не устраивает - пока курсор очертит круг, моб проскакивает насквозь. Делал две вертикальные линии (перс всегда стоит в центре), которые идут от центра в стороны, невозможно вообще что то получить - динамика освещения, дым, туман - все это мешает определить изменения пикселя.

Пока одна мысль - каким то образом научить бота понимать карту, причем не по цветам, а по расположению каких то статичных объектов, при этом используя только два цвета, черный (1) и белый (0). Однобитная матрица строится гораздо быстрее, чем, скажем, hex-число. Но все упирается в поиск пикселя, это слишком медленно, поэтому нужно как то работать с памятью напрямую, минуя массивы. Возмжно, через WinAPI сделать какое то наложение на картинку, либо как то подключиться к драйверу видеокарты и работать с картинкой на аппаратном уровне (память процесса не трогать!)? Это я уже в дебри полез, кажется, что я изобретаю велосипед, а решение где то на поверхности плавает... :scratch:
 

lirikmel

Продвинутый
Сообщения
226
Репутация
84
я даже скачал посмотрел , почему просто не водить мышкой по экрану клиента ? оО ..при наведении на объект появляется подпись по середине и не меняет свое положение , мобов легко определить при появлении красной полоски ,с объектами я думаю тоже можно к чему то привязаться . самое интересное как реализовать передвижение передвижение персонажа , поидее без этой функции бот будет бесполезен /

Мобы в игре довольно большие так что движение мышью не могут занимать много времени, вот полезная темка , ускорит работу скроипта такого вида http://autoit-script.ru/index.php?topic=8824.0
то есть двигаем мышью,ждем появление красной полоски
 
Автор
sebun

sebun

Знающий
Сообщения
81
Репутация
5
Благодарю, почитаю тему. Но сразу вопрос - как читать эту полоску? Свои решения я приводил в двух постах выше. А вот как раз с передвижением все проще - я перевел трехмерную графику в одномерную и получил лабиринт, в котором собирался опробовать волновой механизм передвижения, где то тут он публиковался, сейчас лень искать. Пока главная задача - распознавание.

P.S. Тему почитал. Математически расчитать движения курсора по экрану - это я делал, но по другому, поскольку масштаб объектов большой, я просто делил рабочую область на регионы и в шахматном порядке их "прозванивал". И снова PixelSearch... Мой камень преткновения. Про свои попытки я писал в посте #2, а в #5 написал, что из за высокой динамики работа с пикселями затруднена, например смена освещения. Кроме того, ты посмотрел первую карту, там да, простенько. А на дальних картах, куда попасть может лишь 40 лвл, освещенность меняется кардинально. Например локация "Костяная пустыня", там вокруг все однотонно, просто песок, но на подходе к некоторым участкам наступает ночь, причем не сразу, а плавно, некоторые участки инвертируют цвета, скажем, все становится либо очень темным, либо все цвета становятся синими... Остаются лишь очертания объектов и их обрамление. На счет объектов как раз все еще проще - нажал Ctrl и на экране появляются названия всех объектов, но это мобов не касается, а мне именно они нужны.
 

Dellroc

Осваивающий
Сообщения
151
Репутация
31
На счёт статичности курсора вы сильно ошибаетесь... он непрерывно выдаёт разные хэндлы... скорее всего это его координаты относительно всей карты, но с этим предположением нужно ещё разобраться.
Как вы собираетесь определять координаты персонажа на карте для перемещения?
 
Автор
sebun

sebun

Знающий
Сообщения
81
Репутация
5
На счёт статичности курсора вы сильно ошибаетесь... он непрерывно выдаёт разные хэндлы..
Прошу прощения! Когда речь зашла про изменения курсора, я имел ввиду его визуальные изменения, например при наведении на моба перчатка сменяется на меч, и не подумал про хэндлы. Прежде, чем давать ответ, хотел лично проверить, что выдает _WinAPI_GetCursorInfo, но увы, функция выдает координаты курсора, его дескриптор, видимость и...и все. Быть может вы имели ввиду что то другое?


Код:
#include <WinAPI.au3>
 While 1
	 ToolTip("data = " & MouseGetCursor ())
 WEnd


Вот этот код (лишнее убрал для наглядности) показывает, что в окне игры, сколько мышкой не крутил, значение MouseGetCursor всегда 0 (UNKNOWN), то есть курсор скрыт, а вместо него выдается уже курсор игры.

Как вы собираетесь определять координаты персонажа на карте для перемещения?
Это отдельная тема, касаться которой сейчас не хотелось бы, так как я стараюсь быть последовательным и сейчас задача стоит другая - в определении мобов. На счет координат уже есть наработки, но давайте об этом потом, так как важно сейчас решить вопрос с распознаванием.

Сейчас ковыряю картинку в Photoshop, хочу по совету lirikmel попробовать читать полоску, которая появляется при наведении курсора на моба. Она появляется всегда в одном и том же месте и имеет фиксированную ширину, но ее положение зависит от масштаба окна, который сейчас пытаюсь вычислить в процентах, а так же текст на этой полоске порой выходит за границы. Буду искать два цвета - чистый красный (фон полоски) и чистый белый (цвет текста) по центру этой полоски. А мышь двигать по регионам, что быстрее, чем по кругу. О результатах отпишусь позже.
 

Dellroc

Осваивающий
Сообщения
151
Репутация
31
OffTopic:
Код:
#include <WinAPI.au3>

$fPause = True

HotKeySet('{ESC}', '_Exit')
HotKeySet('{F5}', '_Pause')
ConsoleWrite(@CRLF)

While 1
    If $fPause Then
		$iCursorOld = _WinAPI_GetCursorInfo()
		ToolTip($iCursorOld[2],10,10)
		ConsoleWrite($iCursorOld[2]&@CRLF)
    EndIf
    Sleep(100)
WEnd

Func _Pause()
    $fPause = Not $fPause
EndFunc   ;==>_Pause

Func _Exit()
    Exit
EndFunc   ;==>_Exit
 
Автор
sebun

sebun

Знающий
Сообщения
81
Репутация
5
На ровном месте скачет как бешеный :blink:
Прекрасно работает, скажем, в окне браузера, но только не в окне игры.
Dellroc, спасибо за помощь, я ценю, но может качнешь клиент? Я читал твои посты в других темам, человек ты грамотный, может придумаешь что нибудь, имея перед собой эту игрушку? Я пока учу скрипт читать полоску жизни, может хоть этот вариант прокатит, там всего 200 пикселей прочитать, и выход из условия если найден нужный цвет.
 

Dellroc

Осваивающий
Сообщения
151
Репутация
31
Качнул, поставил, нашёл хп, силу (вроде), координаты персонажа в памяти. Выложу позже адреса. Защиты нет на игре, так-что смело можно читать память.
Меня не столько интересует сам бой, т.к. там можно в мобов даже не тыкать и шмалять по радиусу без прицела. Главное бегать и мобов собирать, которые между прочим не отстают совсем. Вообще игра по своему типу копия дяблы.
А про то, что хэндл курсора скачет - это явно вывод какой-то информации, но какой надо ещё допедрить.
 
Автор
sebun

sebun

Знающий
Сообщения
81
Репутация
5
Спасибо тебе, добрый человек! Но вот два вопроса. 1 - где гарантия, что у игры не появится защита и потом с моим ботом не начнут банить персов пачками, если бот будет использовать память? 2 - адреса статичные? Если есть желание, попробуй перезапустить и проверить старые адреса.

Вообще если удасться перевести объекты из памяти в координаты, я напишу бота для поднятия тебе репы ))) Благо защита на форуме примитивная...


Добавлено:
Сообщение автоматически объединено:

Вообщем сделал распознавание по полоске жизни, шустренько реагирует:
Код:
; расчитываем положение полоски жизни
$posLineX = $Win[0]+357  ; Win - это у меня массив координат рабочей области игры
$posLineY = $Win[1]+75
$posLineL = 175           ; длина полоски
$posLineColor = 0xFF4040 ; и ее цвет

HotKeySet('{ESC}', '_Exit')

While 1
   
   $coord = PixelSearch ( $posLineX, $posLineY, $posLineX+$posLineL, $posLineY, $posLineColor, 0, 2 )
   If Not @error Then
	  MsgBox(0, "Моб! Мочи его!")
   EndIf

WEnd

Func _Exit()
    Exit
EndFunc


Теперь все это дело запихиваем в цикл расчета регионов и, как я писал, наводим мышь на регион и смотрим полоску жизни. Пробую реализовать и буду тестить. И без внедрения в память!
 

Belfigor

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


Добавлено:
Сообщение автоматически объединено:

sebun [?]
Благо защита на форуме примитивная...
И получишь пермобан.
 
Автор
sebun

sebun

Знающий
Сообщения
81
Репутация
5
И получишь пермобан.
Ну, во первых это шутка была. Во вторых я хорошо знаком с движком форума и хаком репы, так что написать на том же AutiIt ботика, который будет регаться, обходить защиту и постить, а так же нажимать репу - не проблема (капча ломается как два пальца..., остальное - один вечер работы). Если я тебя, Belfigor, задел этим, извини. Я тебе, кстати, спасибо хотел сказать за то, что отредактировал заголовок моей темы, а не предупреждение вынес, как раньше. :angel:

Конкретно по поводу бота - в настоящий момент сделал открытие карты и ее чтение, функция возвращает название региона, в котором находится персонаж. Сейчас работаю над передвижением по локациям.

Собственно, назрел еще один вопрос. Не нравится мне PixelSearch, вернее ее параметр shade-variation. Задача - найти пиксель, который окрашен, скажем, больше в сторону голубого, или почти красный. То есть задать цвет, который максимально похож на искомый. В этой функции мало настроек, нужный пиксель порой не находит, а если в shade-variation выставить большое число, она ошибается. Теперь началось мучение с цветами - одного моба видит, другого нет. Вернее цвет полоски зависит от двух причин:

[list type=decimal]
[*]написанного на ней названия моба
[*]заднего фона (полоска полупрозрачная)
[/list]

Сам текст на этой полоске обрамлен функцией, которая в Photoshop называется "внешним свечением", то есть все пиксели рядом с надписью становятся светлее. Второе - на заднем фоне может быть как почти черная картинка, так и почти белая. Соответственно полоска будет либо темнее, либо светлее, в силу своей прозрачности.

Есть ли более гибкий аналог PixelSearch? Или все же пытаться получить с картинки цвет, разложить его на RGB и смотреть какой составляющей в цвете больше?
 

bugaj

Знающий
Сообщения
140
Репутация
11
работа с цветами пикселей на автоите занятие для мазахистов.

Есть ли более гибкий аналог PixelSearch? Или все же пытаться получить с картинки цвет, разложить его на RGB и смотреть какой составляющей в цвете больше?

или уменьшить битность картинки или разбить ее на меньшее количество цветов (первое проще, второе надежней), что приведет к тому, что "разные" цвета в игре, станут одинаковыми на обработанной картинке.
 
Автор
sebun

sebun

Знающий
Сообщения
81
Репутация
5
bugaj сказал(а):
уменьшить битность картинки или разбить ее на меньшее количество цветов
Ну, как это сделать, не нагружая лишними вычислениями бота, я пока не знаю. Все, что сделал - это выставил в настройках клиента минимальные значения графики. Выглядит жутковато, но пока для моих целей сойдет.

Возник вопрос по поводу чтения полоски жизни. Слишком медленно выполняется скрипт:

Код:
Func SearchMob()
   
   Local $WinGame[4] = [460, 175, 1350, 647] ; координаты рабочей области (временно поставил статические значения, положение окна мне известно)
   
   ; делим область на части (сетка) - тут настройка чисто для экспериментов
   $Rx = 10 ; размерность сетки по оси X
   $Ry = 5 ; размерность сетки по оси Y
  
   $blockX = Floor(($WinGame[2] - $WinGame[0])/$Rx) ; ширина блока (по оси Х)
   $blockY = Floor(($WinGame[3] - $WinGame[1])/$Ry) ; высота блока (по оси У)
   
   ; расчитываем положение полоски жизни (тоже временно забил статичные данные)
   $posLineX = 815
   $posLineY = 220
   $posLineL = 184
   
   ; Расчет блоков на экране и поиск пикселей заданного цвета
   Local $blockXY[2] ; координаты текущего блока
   
   For $iXbloc = 0 To $Rx-1 Step 1
	  For $iYbloc = 0 To $Ry-1 Step 1
		 
		 $iX = $WinGame[0] + ($blockX * $iXbloc) ; положение блока по оси Х
		 $iY = $WinGame[1] + ($blockY * $iYbloc) ; положение блока по оси Y
		 
		 $blockXY[0] = $iX+($Rx/2)
		 $blockXY[1] = $iY+($Ry/2)
		 
		 MouseMove ( $blockXY[0], $blockXY[1], 0 ) ; навести мышь на центр региона
		 
		 $coord_1 = PixelSearch ( $posLineX, $posLineY, $posLineX+$posLineL, $posLineY, 0xff4040, 1, 1 )
		 $coord_2 = PixelSearch ( $posLineX, $posLineY, $posLineX+$posLineL, $posLineY, 0xff1f1f, 1, 1 )
		 Sleep(100)
		 		
		 If $coord_1 <> 0 OR $coord_2 <> 0 Then
			Return $blockXY ; моб обнаружен!
		 EndIf
		 
	  Next
   Next
   
   Return 0
EndFunc


Тормозит скрипт именно PixelSearch, которая запускается на одном и том же отрезке дважды для поиска разных цветов (в таком варианте почти всех мобов определяет). Пробовал предложенные варианты, в том числе PixelSearchEx, но слишком медленно выполняется. Пока из вариантов - не сканировать все 180 пикселей на полоске, а определить, на каком участке этой полоски находится пиксель и его сканить. Но тогда придется писать под каждого моба условие.

Belfigor, вот ты написал шикарный пост про работу с памятью. Я не знаком с Cheat Engine, ну просто не любитель взломов, а если очень приспичит, пользовался ArtMoney. Собственно вопрос - хотел проверить, динамические адреса в игре или статичные, хотел найти адрес, по которому появляется эта полоска жизни. Но проблема в том, что появляется она только когда курсор стоит на мобе. Убрал курсор с моба - полоска исчезла. Какой дашь совет?
 

Dellroc

Осваивающий
Сообщения
151
Репутация
31
Вот попробуй этим поискать пиксели http://autoit-script.ru/index.php/topic,10393.0.html
Добавляю обещанные адреса. Их нужно скопировать и вставить в CE
<?xml version="1.0"?>
<CheatTable>
<CheatEntries>
<CheatEntry>
<ID>2</ID>
<Description>"Name"</Description>
<Color>80000008</Color>
<VariableType>String</VariableType>
<Length>10</Length>
<Unicode>0</Unicode>
<ZeroTerminate>1</ZeroTerminate>
<Address>drakensangonline.exe+a26c04</Address>
<Offsets>
<Offset>3C</Offset>
<Offset>70</Offset>
<Offset>40</Offset>
<Offset>C8</Offset>
<Offset>574</Offset>
</Offsets>
</CheatEntry>
<CheatEntry>
<ID>9</ID>
<Description>"LVL"</Description>
<Color>80000008</Color>
<VariableType>4 Bytes</VariableType>
<Address>drakensangonline.exe+a26c04</Address>
<Offsets>
<Offset>44</Offset>
<Offset>68</Offset>
<Offset>28</Offset>
<Offset>80</Offset>
<Offset>574</Offset>
</Offsets>
</CheatEntry>
<CheatEntry>
<ID>0</ID>
<Description>"HP"</Description>
<Color>80000008</Color>
<VariableType>4 Bytes</VariableType>
<Address>drakensangonline.exe+a26c04</Address>
<Offsets>
<Offset>20</Offset>
<Offset>68</Offset>
<Offset>28</Offset>
<Offset>80</Offset>
<Offset>574</Offset>
</Offsets>
</CheatEntry>
<CheatEntry>
<ID>7</ID>
<Description>"Yarost"</Description>
<Color>80000008</Color>
<VariableType>4 Bytes</VariableType>
<Address>drakensangonline.exe+a26c04</Address>
<Offsets>
<Offset>2C</Offset>
<Offset>68</Offset>
<Offset>28</Offset>
<Offset>80</Offset>
<Offset>574</Offset>
</Offsets>
</CheatEntry>
<CheatEntry>
<ID>8</ID>
<Description>"OP"</Description>
<Color>80000008</Color>
<VariableType>4 Bytes</VariableType>
<Address>drakensangonline.exe+a26c04</Address>
<Offsets>
<Offset>40</Offset>
<Offset>68</Offset>
<Offset>28</Offset>
<Offset>80</Offset>
<Offset>574</Offset>
</Offsets>
</CheatEntry>
<CheatEntry>
<ID>19</ID>
<Description>"X"</Description>
<Color>80000008</Color>
<VariableType>Float</VariableType>
<Address>"drakensangonline.exe"+009F92B4</Address>
<Offsets>
<Offset>48</Offset>
<Offset>0</Offset>
<Offset>18</Offset>
<Offset>60</Offset>
<Offset>2C</Offset>
</Offsets>
</CheatEntry>
<CheatEntry>
<ID>20</ID>
<Description>"Y"</Description>
<Color>80000008</Color>
<VariableType>Float</VariableType>
<Address>"drakensangonline.exe"+009F92B4</Address>
<Offsets>
<Offset>40</Offset>
<Offset>0</Offset>
<Offset>18</Offset>
<Offset>60</Offset>
<Offset>2C</Offset>
</Offsets>
</CheatEntry>
</CheatEntries>
</CheatTable>
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
sebun
найди хоть какой-то показатель, даже самый простой и там уже тебе будет видно что там с адресами, хп, ману чара например, или еще какой у него там параметр. Но если это флешь результатов это никаких не даст.
 
Верх