Что нового

[Iris Online] iWalker. Потрошим память игры. Пытаемся написать бота.

Belfigor

Модератор
Локальный модератор
Сообщения
3 591
Репутация
938
Для возможности теми кто будет изучать код, отследить его изменения поэтапно, в теме будут храниться версии от самой первой до текущей.
В разработке участвовали: Belfigor; lirikmel;
Так же в разработке косвенно поучаствовали:
Разработчики NoMadMemory.au3. Без них мы бы не смогли читать и писать данные по статичным адресам.
dwerf. Функция be_CoordsToRotation() найденная в одном из его скриптов, легла в основу функции по работе с ротацией персонажа.
Change Log:
iWalker v0.3 : Авторы: Belfigor
- Появились первые наброски будущего бота. Скрипт теперь умеет читать данные хранящиеся в памяти DMA игры.
- Написана универсальная функция извлечения данных из памяти игры.
iWalker v0.4 : Авторы: Belfigor; lirikmel
- Модифицирована функция GetData. Теперь она может работать с адресами хранящими в себе x, y, z и ротацию персонажа.
http://autoit-script.ru/index.php?topic=4334.msg31529#msg31529: : Авторы : lirikmel
- Дописан код с помощью которого бот может по прямой добраться до вейпоинта.
iWalker v0.6 : Авторы : lirikmel
- добавлено перемещение по промежуточным чекпоинтам с выбором кратчайшего пути до точки назначения
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3 591
Репутация
938
Re: Iris Online. Потрошим память игры. Пытаемся написать бота.

Для того чтобы найти статичные оффсеты в игре, нам понадобится три вещи.
1) Cheat Engine (или любая другая программа работающая с памятью процесса)
2) Атакуемая игра.
3) AutoIt, без него никуда :smile:

Итак, я скачал последнюю версию Cheat Engine 6.0 с офсайта http://www.cheatengine.org/
Игрой я выбрал одну из бесплатных ммо игр mail.ru: http://iris.mail.ru
Почему именно ее? Там можно создавать кавайных няшек, это был самый главный критерий отбора. Итак, я скачал игру, установил, зарегался. Ник в игре ChibiChi, если кому интересно, может написать. думаю ближайшие пару дней от 27.02.2011 я буду в этой игре онлайн. Сервер там вроде только один так что указывать его название не имеет смысла.

Для примера, целью нашей атаки выберем ячейку памяти хранящую в себе информацию относительно текущего значения опыта:

Какая таки няшка у меня кашерная :D

Первые несколько пунктов

6. Возвращаемся к главному окну CE, жмем New Scan, Scan type: Exact Value, Value Type: 4 Bytes. Ставим галочку HEX, в поле поиска вбиваем значение ESI которое мы только что нашли. Жмем First Scan, и получаем результатом несколько новых адресов содержащих искомое значение:


7. Жмем Add address manualy. Такем там на Add pointer. Type = float. Address of pointer пишем один из тех адресс которые мы только что нашли. Я выбрал 283E69C8. Указываем первый оффсет который мы нашли в пункте 5: A8. Жмем ОК

8. Пкм на новом добавленном адресе, жмем Find out what ACCESSES this address. Появится окно с выбором. Выбираем первый пункт. Увидим пустое окно где должны будут появиться опкоды.

9. Убиваем моба и в появившемся окне видим опкоды. Дабл клик на понравившийся. Я выбрал первый.

10. Запоминаем значение esi = 283E6888, запоминаем оффсет = 140

11. Переходим к главному окну CE. Ищим в памяти значение 283E6888, не забываем ставить галочку Hex. Получаем пачку адресов. Выбираем понравившийся, я выбрал первый, жмем Add address manualy.

12. Выбираем Pointer. Type оставляем Float. Жмем Add Pointer два раза. Указываем первый оффсет, указываем адрес который мы выбрали, указываем найденный недавно 2-й оффсет, 140. Жмем ок.

13. Пкм на новом добавленном адресе, жмем Find out what ACCESSES this address. Появится окно с выбором. Выбираем первый пункт. Увидим пустое окно где должны будут появиться опкоды.

14. Убиваем моба, получаем опкоды. Выбираем понравившийся. Я выбрал mov ecx, [esi+28]. Дабл клик, смотрим инфо. теперь нам надо искать адрес 1CA6E1B8, запоминаем его. Запоминаем оффсет = 28.

15. Переходим к главному окну CE. Ищим в памяти значение 1CA6E1B8, не забываем ставить галочку Hex. Получаем адреса. Алилуя, мы видим зелененький адрес. Он то нам и нужен. Мы нашли базовый адрес. Жмум Add adress manually.

16. Стандартные действия мы уже запомнили. Жмем на Add Pointer 3 раза, вбиваем 1-й оффсет = A8, вбиваем 2-й оффсет - 140, вбиваем найденный только что адресс 00955E8С, вбиваем его оффсет = 28, жмем ок.


Теперь мы перезапускаем клиент игры, аттачим CEк новому процессу и видим что у нас в последнем добавленном нами адресом отображается текущее значение EXP

Чтож, найдя что-то думаю первым делом вы захотите найти статический адрес ХП вашего чара. Итак, нашли вы базовый адрес, дальше вам захочется макс хп, мп и тд. Логично предположить что подобные данные должны храниться в одной структуре и недалеко друг от друга. ПКМ на свой базовый адрес ХП, тыкаем Browse this memory region

И видим:

СurHP, CurMP, MaxHP, MaxMP лежат в одной структуре каждая на 4 байта дальше базового адреса который мы нашли.

Так выглядит адрес CurHP, его оффсет = C5 от базового.
CurMP находится на 8 байт дальше чем наш базовый адрес и его офсет будет = С5+4 = С9
MaxHP лежит на 12 байт дальше нашего оффсета и его офсет будет = С5+4+4 = CD
MaxMP лежит на 16 байт дальше нашего базового адреса и его офсет будет = С5+4+4+4 = D1
Ник чара кстати лежит там же, чуть выше.
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3 591
Репутация
938
Re: Iris Online. Потрошим память игры. Пытаемся написать бота.

Собственно в процессе написания возникла пара проблем, например игра после закрытия не хотела запускаться, этот вопрос мне помог решить lirikmel, так же он дал мне пример кода для использования поинтеров на примере хп моба:
Код:
#include <GUIConstants.au3>
#include <nomadmemory.au3>
Global $ProcessName = "IRIS ONLINE v1.18.22996"
Global $ProcessID = WinGetProcess($ProcessName,"")
SetPrivilege("SeDebugPrivilege", 1)
Global $HP = 0x00955e8c ; Указатель (см.картинку выше)
Global $DllInformation = _MemoryOpen($ProcessID)
Global $hWnd = WinGetHandle("IRIS ONLINE v1.18.22996", "")
$CurrentHP = (_MemoryRead($HP, $DllInformation, 'ptr'))
        ;MsgBox (1,"проверь",$CurrentHP ,"")
		$Cur = $CurrentHP + 32
       ; MsgBox (1,"проверь",$Cur,"")
		$CurrentHP = (_MemoryRead($Cur, $DllInformation, 'ptr'))
        ; MsgBox (1,"проверь",$CurrentHP,"")
		$Cur = $CurrentHP + 256
		;MsgBox (1,"проверь",$Cur,"")
		$CurrentHP = (_MemoryRead($Cur, $DllInformation, 'ptr'))
        ; MsgBox (1,"проверь",$CurrentHP,"")
		$Cur = $CurrentHP + 168
		;MsgBox (1,"проверь",$Cur,"")
	     $Curr =  (_MemoryRead($Cur, $DllInformation, 'float'))
MsgBox (1,"проверь",$Curr,"")


Я слегка переработал этот код и у меня получилась вот такая функция:
Код:
Func GetData($Param1, $Param2="no param", $Param3="no param")
	Local $Base, $MemTemp, $DataType, $Offset[5] = ["nop", "nop", "nop", "nop", "nop"] ;Определяем массив в который можно записать до 4 массивов. Сразу же присваиваем всем ячейкам какое-нибудь значение отличное от офсета.
	;$Base - сюда скрипт записывает необходимый базовый адрес для текущего запроса
	;$MemTemp - тут скрипт обрабатывает данные получаемые из памяти необходимые для текущего запроса
	;$DataType - сюда скрипт записывает тип данных необходимый для текущего запроса
	;При обращении в эту функцию, она сперва переопределяет все значения на необходимые скрипту в данный момент и далее отправляет эти данные на обработку
	Select
		Case $Param1 = "Char" ;наша структура работы с персонажем
			Select
				Case $Param2 = "Cur HP" ;жизни персонажа. Обращение: GetData("Char", "Cur HP")
					$Base = 0x00955890 ;база ХП
					$Offset[1] = "C5" ;Оффсет на ХП
					$DataType = "dword" ;тип данных
				Case $Param2 = "Cur MP" ;мана персонажа. Обращение: GetData("Char", "Cur HP")
					$Base = 0x00955890 ;база МП
					$Offset[1] = "C9" ;Оффсет на МП
					$DataType = "dword" ;тип данных
				Case $Param2 = "SXP" ;SXP персонажа. Обращение: GetData("Char", "SXP")
					$Base = 0x00955e8c ;база SXP
					$Offset[1] = "28" ;1-й Оффсет на SXP
					$Offset[2] = "140" ;2-й Оффсет на SXP
					$Offset[3] = "A8" ;3-й Оффсет на SXP
					$DataType = "float" ;тип данных
				Case Else
					SetError(1)
					;Сообщение об ошибке может быть закомменчено или наоборот, в зависимости от того чего мы хотим от скрипта.
					ErrorMsg('GetData("'&$Param1&'", WTF?...', 'Ошибка вызова: команды GetData("'&$Param1&'", "'&$Param2&'") не существует.')
			EndSelect
		Case $Param1 = "Target"
			Select
				Case $Param2 = "Cur HP" ;жизни цели. Обращение: GetData("Target", "Cur HP")
					$Base = 0x00955e8c ;база tHP
					$Offset[1] = "20" ;1-й Оффсет на tHP
					$Offset[2] = "100" ;2-й Оффсет на tHP
					$Offset[3] = "A8" ;3-й Оффсет на tHP
					$DataType = "float" ;тип данных
				Case Else
					;Сообщение об ошибке может быть закомменчено или наоборот, в зависимости от того чего мы хотим от скрипта.
					ErrorMsg('GetData("'&$Param1&'", WTF?...', 'Ошибка вызова: команды GetData("'&$Param1&'", "'&$Param2&'") не существует.')
			EndSelect
		Case Else
			;Сообщение об ошибке может быть закомменчено или наоборот, в зависимости от того чего мы хотим от скрипта.
			ErrorMsg('GetData(WTF?...', 'Ошибка вызова: команды GetData("'&$Param1&'") не существует.')
	EndSelect
	;Тут происходит обработка данных пришедших сверхку
	$MemTemp = (_MemoryRead($Base, $DllInformation)) ;первый запрос в память, полученный результат уже будет обрабатываться в цикле
	For $i = 2 To UBound($Offset, 1)-1 Step 1 ;i начинается с двух потому что было решено оставить [0] ячейку пустой, мб в будущем пригодится. В обращениях же к памяти обращения идут в ячейку [$i-1]
		If String($Offset[$i]) = "nop" Then ;Смотрим значение текущей ячейки. Если оно не содержит в себе оффсет
			$MemTemp =  (_MemoryRead($MemTemp+Dec($Offset[$i-1]), $DllInformation, $DataType)) ;Значит нам пора формировать последний запрос используя данные хранящиеся в пред идущей ячейке [$i-1], в котором необходимо указать тип данных которые мы желаем получить.
			ExitLoop ;Отправив последний запрос, выходим из цикла. Нам больше нечего искать.
		Else ;Если значение в текущей ячейке содержит в себе оффсет, значит и пред идущая ячейка содержит в себе оффсет. 
			$MemTemp =  (_MemoryRead($MemTemp+Dec($Offset[$i-1]), $DllInformation)) ;Формируем запрос используя оффсет хранящийся в пред идущей от текущей ячейке [$i-1]
		EndIf
	Next
	Return $MemTemp ;Возвращаем полученные данные.
EndFunc

Суть функции в том что она уже сама по себе универсальна и может работать с поинтерами от 1 до 4 уровня. Думаю для Iris Online этого вполне хватит. Ну а чтобы добавить новые адреса для обработки, достаточно создать новое условие и вбить в него желаемые параметры.
Спасибо так же xamd, за пояснения относительно использования офсетов в автоите :smile:
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3 591
Репутация
938
Re: Iris Online. Потрошим память игры. Пытаемся написать бота.

Пропатчена функция GetData.
Код:
Case $Param2 = "Pos" ;Обращение: GetData("Char", "Pos", ...
					$Base = 0x0094a154 ;Выносим сюда потому что $Base у всех адресов ниже идущей структуры одинаковый.
					$DataType = "float"
					$Offset[1] = "C"
					Select
						Case $Param3 = "X" ;Обращение: GetData("Char", "Pos", "X")
							$Offset[2] = "24"
						Case $Param3 = "Y" ;Обращение: GetData("Char", "Pos", "Y")
							$Offset[2] = "28"
						Case $Param3 = "Z" ;Обращение: GetData("Char", "Pos", "Z")
							$Offset[2] = "38"
						Case $Param3 = "R Base" ;Обращение: GetData("Char", "Pos", "R Base") Работаем с ячейкой отвечающей за ротацию чара
							$Offset[2] = "48"
						Case $Param3 = "R" ;Обращение: GetData("Char", "Pos", "R") ;Вычисляем ротацию.
							$Temp = GetData("Char", "Pos", "R Base")
							$Temp = $Temp - (360*Floor($Temp/360))
							Return $Temp
						Case $Param3 = "All" ;Обращение: GetData("Char", "Pos", "All")
							Local $rScan[4] = ["X", "Y", "Z", "R"] ;Создаем временный массив в который заносим то что будет сканироваться и в каком порядке оно будет сканироваться
							Local $rTemp[4] ;Создаем временный массив в который будем записывать результаты сканов
							For $i = 0 To UBound($rTemp, 1)-1 Step 1
								$rTemp[$i] = GetData("Char", "Pos", $rScan[$i]) ;Сканируем
							Next
							Return $rTemp ;Возвращаем массив
						Case Else
							SetError(3)
							;Сообщение об ошибке может быть закомменчено или наоборот, в зависимости от того чего мы хотим от скрипта.
							ErrorMsg('GetData("'&$Param1&'", "'&$Param2&'", WTF?...', 'Ошибка вызова: команды GetData("'&$Param1&'", "'&$Param2&'", "'&$Param3&'") не существует.')
					EndSelect

Добавлена работа с координатами чара и ротацией камеры.
 

lirikmel

Продвинутый
Сообщения
225
Репутация
84
Re: Iris Online. Потрошим память игры. Пытаемся написать бота.

иииии??? базовый адрес то нашли ?..а то я скока не сканил хп моба так и не нашел -) пришлось пиксельным ботом остановиться..
http://www.progamercity.net/other-mmo/release-iris-online-mini-bot-iris-mail-ru-1151/
:smile:

думаю ты сразу узнаешь свой пример скелета бота ...обросший "мясом" :-[
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3 591
Репутация
938
Re: Iris Online. Потрошим память игры. Пытаемся написать бота.

Адрес то нашел. Пишу гайд в данный момент, но форум лаганул когда я накатал почти весь гайд и я потерял редактированное сообщение. Пишу заново >.<
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3 591
Репутация
938
Re: Iris Online. Потрошим память игры. Пытаемся написать бота.

Мда, на каждом шагу меня подстерегают неудачи. Почему когда я закрыл игру, я не могу ее запустить по новой? Мне пишет Error update file >.<
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3 591
Репутация
938
Re: Iris Online. Потрошим память игры. Пытаемся написать бота.

выложил скрипт iWalker v0.3. Пока это не бот но основа положена :smile:
Теперь попробуем научить нашего бота осмысленно передвигаться
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3 591
Репутация
938
Re: Iris Online vs iWalker. Потрошим память игры. Пытаемся написать бота.

А, действительно. Вечером подправлю
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3 591
Репутация
938
iWalker v0.5

iWalker v0.5: Авторы: lirikmel
- Дописан код с помощью которого бот может по прямой добраться до вейпоинта.
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3 591
Репутация
938
iWalker v0.5.1

iWalker v0.5.1 - Авторы: Belfigor
- Отличается от http://autoit-script.ru/index.php?topic=4334.msg31529#msg31529 написанной lirikmel только тем, что теперь в коде отсутствует функции _RotationWtite() и GetData(). Две эти функции объединила в себя универсальная функция DataOp которая теперь может использоваться как для чтения так и для записи данных по указанному статичному адресу.
Плюсы: мы экономим на строках кода, у нас нету лишнего кода который в разных местах скрипта делает одни и те же действия.
Минусы: не нашел :smile:.
Изменения синтаксиса:
если раньше мы могли только читать из памяти и для чтения пользовались командой:
Код:
GetData("Target", "Cur HP")

то теперь синтаксис изменился на:
Код:
DataOp("Target", "Cur HP")

На первый взгляд вы скажете что изменилось только название функции, нет. Там так же добавился ряд параметров.
Было:
Код:
GetData($Param1, $Param2="no param", $Param3="no param")

Стало:
Код:
DataOp($Param1, $Param2="no param", $Param3="no param", $ToDo="Read", $Data="no data")

$Param1, $Param2, $Param3 - все так же определяют куда в памяти мы хотим попасть.
$ToDo - теперь определяет что мы хотим с этой областью памяти сделать, прочитать или записать. По дефолту стоит значение Read, поэтому если вы хотите просто прочитать память, вам достаточно использовать лишь 1-е 3 параметра. Если же вы хотите записать в этот участок памяти что-либо, вам надо указать "Warite".
$Data - То значение которое мы хотим записать. Если пред идущим параметром вы указываете "Write", то вам надо указать так же и параметр $Data. В противном случае в память будет записан 0.


Как мы превратили просто читающую функцию в пишущую?
Было:
Код:
$MemTemp = (_MemoryRead($Base, $DllInformation))
For $i = 2 To UBound($Offset, 1)-1 Step 1
	If String($Offset[$i]) = "nop" Then
		$MemTemp =  _MemoryRead($MemTemp+Dec($Offset[$i-1]), $DllInformation, $DataType)
		ExitLoop
	Else
		$MemTemp =  (_MemoryRead($MemTemp+Dec($Offset[$i-1]), $DllInformation))
	EndIf
Next
Return $MemTemp


Стало:
Код:
$MemTemp = (_MemoryRead($Base, $DllInformation))
For $i = 2 To UBound($Offset, 1)-1 Step 1
	If String($Offset[$i]) = "nop" Then
		If $ToDo = "Read" Then $MemTemp =  _MemoryRead($MemTemp+Dec($Offset[$i-1]), $DllInformation, $DataType)
		If $ToDo = "Write" Then $MemTemp =  _MemoryWrite($MemTemp+Dec($Offset[$i-1]), $DllInformation, $Data, $DataType)
		ExitLoop
	Else
		$MemTemp =  (_MemoryRead($MemTemp+Dec($Offset[$i-1]), $DllInformation))
	EndIf
Next
Return $MemTemp


Различия:
Код:
If $ToDo = "Read" Then $MemTemp =  _MemoryRead($MemTemp+Dec($Offset[$i-1]), $DllInformation, $DataType)
If $ToDo = "Write" Then $MemTemp =  _MemoryWrite($MemTemp+Dec($Offset[$i-1]), $DllInformation, $Data, $DataType)

К финальному обращению в NomadMemory мы просто добавили явное указание что она вызывается только тогда когда мы хотим прочитать память. Так же мы добавили строку которая пишет в память и назначили ей явное указание когда быть вызванной.

В целом же вся функция DataOp работает по той же схеме по которой работала GetData. Первыми тремя параметрами вы показываете скрипту где брать статичный адрес, оффсеты и тип данных в котором хранится значение, далее эти параметры применяются для чтения или записи по нужному нам адресу.
 

Insari

Осваивающий
Сообщения
34
Репутация
35
Re: Iris Online vs iWalker. Потрошим память игры. Пытаемся написать бота.

Очень большая просьба!
Belfigor добавь, пожалуйста, первые 5-ть пунктов во второй пост.
 

Bloodrinker

<Блуждающий...>
Сообщения
228
Репутация
19
Re: Iris Online vs iWalker. Потрошим память игры. Пытаемся написать бота.

жаль, что так браузерки не расковыряешь, если только она не с клиентом...
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3 591
Репутация
938
Re: Iris Online vs iWalker. Потрошим память игры. Пытаемся написать бота.

Insari сказал(а):
Очень большая просьба! Belfigor добавь, пожалуйста, первые 5-ть пунктов во второй пост.
Балин! Да я же его патчил уже, первый пост, точно помню там были первые 5 пунктов >.<
 

Bloodrinker

<Блуждающий...>
Сообщения
228
Репутация
19
Re: Iris Online vs iWalker. Потрошим память игры. Пытаемся написать бота.

Belfigor сказал(а):
Балин! Да я же его патчил уже, первый пост, точно помню там были первые 5 пунктов >.<
я тоже 5-й пункт не нашел... ну вроде понял.. а через артмани тоже можно наверно... поучительный пост однако, побольше таких, жги исче ;)
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3 591
Репутация
938
Re: Iris Online vs iWalker. Потрошим память игры. Пытаемся написать бота.

Процесс обучения бота осмысленному передвижению довольно таки затянулся уже как 7 дней коддинга по 6-12 часов в день. Сейчас он стоит на стадии:
Pathing Bot. Волновой алгоритм перемещения в ммо играх.
Опытным путем было выяснено что волновой алгоритм плохо масштабируется и без ректальных оптимизаций непригоден для больших площадей
.
На подходе Астар и алгоритм Дийкстры
, очень сильно замедляет процесс - полное отсутствие познаний в математике

Полученный в процессе реализации системы передвижения опыт, бесценен
 

lirikmel

Продвинутый
Сообщения
225
Репутация
84
iWalker v0.6

- добавлено перемещение по промежуточным чекпоинтам с выбором кратчайшего пути
до точки назначения
код сортировки координат
Код:
Dim $avArray [10][3]=[["195","391"],["181","391"],["164","384"],["141","381"],["126","390"], _;заполняем массив переменными (координатами)
                     ["103","400"],["82","411"],["25","369"],["100","78"],["15","89"]]
_ArrayDisplay($avArray);смотрим


For $i=0 to UBound($avArray)-1 ;преводим все переменные массива в числовой вид ..оО кто его знает зачем но без этого почему то незаработало
$avArray[$i][$ii] = Number($avArray[$i][$ii])
Next

select
case  $x1 < $Lx2  ; если координата x начала меньше х конечной
  For $i=0 to UBound($avArray)-1
  if UBound($avArray)-1< $I Then
	 ExitLoop
   elseif $avArray[$i][$ii] < $Lx2 and $avArray[$i][$ii] > $x1 then ; сортируем в диапазан значения из массива
  Else
	_ArrayDelete ( $avArray, $i ) ;удаляем лишнее
$i=$i-1
EndIf
Next
case $x1 > $Lx2 ; если координата x начала больше х конечной
For $i=0 to UBound($avArray)-1
  if UBound($avArray)-1< $I Then
	 ExitLoop
   elseif $avArray[$i][$ii] > $Lx2 and $avArray[$i][$ii] < $x1 then
  Else
	_ArrayDelete ( $avArray, $i )
$i=$i-1
EndIf
Next

EndSelect


_ArraySort( $avArray,1) ; сортируем по убыванию
_ArrayDisplay( $avArray, "Sort Decending" )


 For $i=0 to UBound($avArray)-1
 $Ax1 = $avArray[$i][$ii]
 $Ay1 = $avArray[$i][1]
 ;MsgBox (1,"проверь",$Ax1&$Ay1,"")
 $avArray[$i][2] = Number(Sqrt(($Ax1 - $x1) ^ 2 + ($Ay1 - $y1) ^ 2)) ;вычисляем расстояния между кооринатами текущего положения и чекпоинтов
_ArraySwap( $avArray[$i][0], $avArray[$i][2] ); переносим расстояния в первый столбец (ненашел просто как сортировать по другимстолбцам)
;_ArrayDisplay($avArray)

Next
_ArraySort( $avArray) ;сортируем по возрастанию для определения ближайшего чекпоинта
_ArrayDisplay( $avArray, "Sort Decending" )
 $chkX = $avArray[0][2] ;отправляем координаты ближайшей точки
 $chkY = $avArray[0][1]
Local $Return[2] = [$chkX, $chkY]
Return $Return
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3 591
Репутация
938
Re: Iris Online vs iWalker. Потрошим память игры. Пытаемся написать бота.

К функции передвижения и нахождения пути был успешно прикручен алгоритм Ли. Осталось только научить бота автоматически генерировать геодату и можно выкладывать новый релиз исходников :smile:.
Позже отдельно алгоритм с ГУИ для тестов будет так же выложен в этой ветке.
 

Hracid

Новичок
Сообщения
8
Репутация
2
Re: Iris Online vs iWalker. Потрошим память игры. Пытаемся написать бота.

если я все правильно понял то со структурами хранящими данные об окружающем мире вы разобрались?
если не сложно, не могли бы вы поделиться с форумчанами этой информацией?
лично меня интересует, как определить размер структуры, и начало структуры?
в моем понимании есть статический адрес хранящий в себе адрес начала структуры, а зная её размер можно будет двигаться по структурам. т.к. в памяти они как правильно идут последовательно. т.е. представлены в виде массива.
 
Автор
B

Belfigor

Модератор
Локальный модератор
Сообщения
3 591
Репутация
938
Re: Iris Online vs iWalker. Потрошим память игры. Пытаемся написать бота.

Нет, понял ты неправильно. Основательная работа с памятью остановилась тогда когда было решено написать сперва вразумительный механизм передвижения. Со структурами пока никто не ковырялся. Мне если честно и самому было бы интересно узнать что-нибудь о работе со структурами памяти.
Собсно бот уже умеет двигаться: http://www.youtube.com/watch?v=-dEvxa2MGR4
Правда это пока только альфа версия, в ближайшее время ее исходник появится на форуме.
 
Верх