Что нового

[Rohan] Бот для милли чаров

demonenok

Новичок
Сообщения
12
Репутация
2
Первый пост, будет постоянно изменяться по мере изменений в боте. Само обсуждение и временные коды, будут предоставляться в самом обсуждении темы.

Вот собственно последняя версия бота для мили чаров, в игре "Rohan"

Код:
Opt("PixelCoordMode", 2) ;Устанавливаем относительные координаты для определения цвета пикселя
Opt("MouseCoordMode", 2)

HotKeySet("!1", "Play")
HotKeySet("!2", "Stop")
HotKeySet("!3", "_Exit")

Global $b_run = True,$b_play = False, $i_atack
Global $i_stage,$mob_hp,$char_hp, $hWnd
Global Enum $_iStage_select = 1,$_iStage_attack = 2,$_iStage_check = 3
ConsoleWrite('> Нажмите Play для запуска' & @LF)
While $b_run
    If Not $b_play Then
        ContinueLoop
    EndIf
    Switch $i_stage
        Case $_iStage_select
            ;Проверка, выделен ли моб
			WinActivate($hWnd)
            $mob_hp = PixelGetColor(454,20)
            If $mob_hp > 10000000 Then
			    $i_atack = True
                $i_stage = $_iStage_attack
            Else
                Send("{Tab}")
            EndIf
        Case $_iStage_attack
            ;Атакуем
			If $i_atack Then
			   Send("{1}")
			   $i_atack = False			   
			   $i_stage = $_iStage_check
			Else
			   $i_stage = $_iStage_check
			EndIf
	    Case $_iStage_check			
            ;Проверим, нужно ли лечится
            $char_hp = PixelGetColor(250,25)
            If $char_hp < 5000000 Then ;Лечимся
                Send("{F1}")
                Sleep(500)
                Send("{2}")
                Sleep(3500)
                Send("{ESCAPE}")
			 EndIf
			;Проверим, нужно ли восполнять ману
	     $char_mp = PixelGetColor(250, 37) 
	     If $char_mp < 2500000 Then ; восполняем ману скллом
			    Sleep(200)
                            Send("{5}")
				$char_mp = PixelGetColor(120, 37) ;Если мана упала очень низко, то восполняем ее с помощью бутылки.
				  If $char_mp < 2500000 Then
					 Send("{8}")
				  EndIf
			EndIf
            ;Проверим, умер ли моб
            $mob_hp = PixelGetColor(453,20)
            If $mob_hp <10000000 Then
                ;Да, моб умер
                Send("{SPACE}")
                Sleep(500)
                Send("{SPACE}")
                Sleep(500)
                Send("{SPACE}")
				$i_atack = True
                $i_stage = $_iStage_select;Начинаем сначала
            Else
                ;Нет, моб не умер, продолжаем атаковать
                $i_stage = $_iStage_attack
            EndIf
    EndSwitch
WEnd
ConsoleWrite('> Скрипт завершен.' & @LF)

Func Play()
    $b_play = Not $b_play
    If $b_play Then
        $hWnd = WinGetHandle("R.O.H.A.N.")
        If IsHWnd($hWnd) Then
            WinActivate($hWnd)
			AdlibRegister("Skill_single", 10000) ;Юзаем скилл через каждые 10 сек.
			AdlibRegister("Skill_masive", 9000) ;Юзаем второй скилл через каждые 9 сек
			AdlibRegister("Buff", 3000000) ;Бафаемся через каждые пол часа
            $i_stage = $_iStage_select
        Else
            ConsoleWrite('> Игра не найдена' & @LF)
            $b_play = False
        EndIf
    EndIf
    ConsoleWrite('> Play: '& $b_play & @LF)
EndFunc

Func Skill_single()
   Send("{3}")
   $i_atack = False
   $i_stage = $_iStage_select
EndFunc

Func Skill_masive()
   Send("{4}")
   $i_atack = False
   $i_stage = $_iStage_select
EndFunc

Func Buff()
   Send("{F1}")
   Sleep(200)
   Send("{0}")
   Sleep(200)
   Send("{ESCAPE}")
   $i_atack = False
   $i_stage = $_iStage_select
EndFunc

Func Stop()
    $b_play = False
	AdlibUnRegister("Skill_single")
	AdlibUnRegister("Skill_masive")
	AdlibUnRegister("Buff")
EndFunc
 
Func _Exit()
    Exit
 EndFunc


На данный момент, реализованный функции такие как:

1. Авто-выбор моба
2. Атака моба
3. Использование скиллов (по завершению их куллдауна)
4. Использование баффов (по завершению их куллдауна)
5. Поднятие лута
6. Лечение(возможно лечение скиллом и в тоже время, лечение бутылками)
7. Восполнение маны
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Что ж ты, ...(нехороший человек), с рекурсией вытворяешь, а ?!
Сначала хотел помочь, но, посмотрев код, осталось только одно желание - взять ремень и выпороть.
С массивами он не дружит... Да ты ...!!!
Мальчик, отойди от компьютера! Пойди лучше телевизор посмотри.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Зачем это вообще выкладывать. Код вообще не верно построен. Одна функция вызывает саму себя, вызывает другую функцию которая опять вызывает первую. Вы не только с массивами не умеете работать, но и не понимаете как работают функции.
 
Автор
D

demonenok

Новичок
Сообщения
12
Репутация
2
Раньше, все было написано через одну функцию и через if. После чего я все сделал как отдельные функции, что вы называете "бесполезным и глупым", когда я это сделал, бот начал работать так как надо. Раньше, с теми же настройками, бот просто выполнял if за считанные секунды и в итоге я не лечился или не поднимал шмот, что теперь выполняется как надо. То что это не грамотно, я не спорю, огромное число бесполезно повторяющихся функций.


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

так, правильно ?

Код:
#include<ButtonConstants.au3>
#include<GUIConstantsEX.au3>
#include<WindowsConstants.au3>

Global $mob_hp
Global $i = 1

Opt("MouseCoordMode", 2) ;Устанавливаем относительные координаты для клика мыши
Opt("PixelCoordMode", 2) ;Устанавливаем относительные координаты для определения цвета пикселя

HotKeySet("!1","Start") ;При нажатии на Alt + 1, запускаем скрипт
HotKeySet("!2","Pause") ;При нажатии на Alt + 2, скрипт будет ждать дальнейших действий
HotKeySet("!3","Stop") ;При нажатии на Alt + 3, скрипт закрывается

$hWnd = WinGetHandle("R.O.H.A.N.") ;Получение хендла окна

Pause() ;Сразу становимся на паузу и ждем дальнейших указаний

Func Start() ;Вот собственно сама "функция бота"

	WinActivate($hWnd) ;Активируем окно игры
	$mob_hp = PixelGetColor(454,20) ;Проверяем цвет по координатам(в моем случае, это начало ХП моба)

	If $mob_hp > 10000000 Then ;Проверяем, выделен ли у нас моб. Если да
		$i = 1 ;устанавливаем наш "Тригер" в 1

	While $mob_hp > 10000000 ; Пока у моба есть хп(т.е. пока он в таргете)

		If $i = 1 Then ;Если "Тригер" установлен в 1
			Sleep(200) ;Ожидаем 200 мл.с.
			$i = 2 ;Тригер устанавливаем в 2, чтобы еще раз не нажать на "Атаку"
			Send("{1}") ;Атакуем моба 
		EndIf

		$mob_hp = PixelGetColor(453,20) ;Пока выполняется цикл, постоянно проверяем, жив ли моб
		$char_hp = PixelGetColor(250,25) ;Так-же, проверяем свое хп
		$mob_hp_check = PixelGetColor(590,20) ;Так-же проверяем, уходил ли хп у моба

		If $char_hp < 5000000 Then ;Если хп чара, упала ниже отметины
				Send("{F1}") ;Выделяем себя
				Sleep(500) ;Ожидаем пол минуты(просто чар может не успеть "ударить последний раз" моба)
				Send("{2}") ;Используем лечение (бутылки/скилл)
				Sleep(3500) ;Ожидаем 3.5 сек. (в случае если это скилл, его нужно скастовать)
				Send("{ESCAPE}") ;Снимаем выделение с себя, чтобы можно было продолжать нормальную работу бота
				$i = 1				
		EndIf

		If $mob_hp_check > 10000000 Then ;Если хп моба в его "начале" все еще красный (а это так, мы же его только выделили и еще нечего не делали)
			Sleep(10000) ;Ожидаем 10 сек
			$mob_hp_check = PixelGetColor(590,20) ;После чего проверяем еще раз его хп

				If $mob_hp_check > 10000000 Then ;Если оно так и не изменилось
					$i = 1 ;Тригер устанавливаем в 1, чтобы чар снова начал бить моба.					
				EndIf
		
		EndIf

		If $mob_hp <10000000 Then ;Если моб умер
				Send("{SPACE}") ;Нажимаем пробел
				Sleep(500) ;ожидаем пол минуты
				Send("{SPACE}")
				Sleep(500)
				Send("{SPACE}")				
		EndIf

		Else ;Если нет
			Send("{Tab}") ;Выделяем ближайшего моба
			Sleep(100) ;Ожидаем 100мл.с.(просто чтобы игра и скрипт, смогли успеть друг за другом : ) )
			Start() ;Перезапускаем функцию заного, чтобы проверить, выделен ли моб

	WEnd

EndFunc

Func Pause() ;Функция паузы
	While 1
		Sleep(1)
	WEnd
EndFunc

Func Stop() ;Закрыть скрипт
	Exit
EndFunc
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Удалите и никому не показывайте
 
Автор
D

demonenok

Новичок
Сообщения
12
Репутация
2
Если постоянно повторять одно и тоже, то я сомневаюсь, что научусь грамотно писать скрипт. По этому заместо того, чтобы постоянно говорить "удали" и т.д., подскажите, что не так и что нужно исправить. По крайней мере, что вам не нравится, может смогу объяснить почему оно так написано или пойму как грамотней написать.


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

Что ж ты, ...(нехороший человек), с рекурсией вытворяешь, а ?!
Сначала хотел помочь, но, посмотрев код, осталось только одно желание - взять ремень и выпороть.
С массивами он не дружит... Да ты ...!!!
Мальчик, отойди от компьютера! Пойди лучше телевизор посмотри.

Подскажите пожалуйста, что я не так написал и как возможно это исправить ?!
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Код:
Opt("PixelCoordMode", 2) ;Устанавливаем относительные координаты для определения цвета пикселя

If Not HotKeySet("!1", "Play") Then Exit ConsoleWrite('! Комбинация Alt + 1 занята' & @LF)
If Not HotKeySet("!2", "Stop") Then Exit ConsoleWrite('! Комбинация Alt + 2 занята' & @LF)

Global $hWnd,$b_run = True,$b_play = False
Global $i_stage,$mob_hp,$char_hp
Global Enum $_iStage_select = 1,$_iStage_attack = 2,$_iStage_check = 3
ConsoleWrite('> Нажмите Play для запуска' & @LF)
While $b_run
	Sleep(250)
	If Not $b_play Then
		ContinueLoop
	EndIf
	Switch $i_stage
		Case $_iStage_select
			;Проверка, выделен ли моб
			$mob_hp = PixelGetColor(454,20)
			If $mob_hp > 10000000 Then
				$i_stage = $_iStage_attack
			Else
				Send("{Tab}")
			EndIf
		Case $_iStage_attack
			;Атакуем
			Send("{1}")
			$i_stage = $_iStage_check
		Case $_iStage_check
			;Проверим, нужно ли лечится
			$char_hp = PixelGetColor(250,25)
			If $char_hp < 5000000 Then ;Лечимся
				Send("{F1}")
				Sleep(500)
				Send("{2}")
				Sleep(3500)
				Send("{ESCAPE}")
			EndIf
			;Проверим, умер ли моб
			$mob_hp = PixelGetColor(453,20)
			If $mob_hp <10000000 Then
				;Да, моб умер
				Send("{SPACE}")
				Sleep(500)
				Send("{SPACE}")
				Sleep(500)
				Send("{SPACE}")
				$i_stage = $_iStage_select;Начинаем сначала
			Else
				;Нет, моб не умер, продолжаем атаковать
				$i_stage = $_iStage_attack
			EndIf
	EndSwitch
WEnd
ConsoleWrite('> Скрипт завершен.' & @LF)

Func Play()
	$b_play = Not $b_play
	If $b_play Then
		$hWnd = WinGetHandle("R.O.H.A.N.")
		If IsHWnd($hWnd) Then
			WinActivate($hWnd)
			$i_stage = $_iStage_select
		Else
			ConsoleWrite('> Игра не найдена' & @LF)
			$b_play = False
		EndIf
	EndIf
	ConsoleWrite('> Play: '& $b_play & @LF)
EndFunc

Func Stop()
	$b_run = False
EndFunc
 
Автор
D

demonenok

Новичок
Сообщения
12
Репутация
2
Спасибо большое очень интересный способ и сам бы я до него точно не додумался. Достаточно сложно для меня написано, но вроде разобрался что к чему. Теперь буду пытаться писать по вашему примеру, огромное спасибо, так как это решило много моих проблем. Думаю теперь можно приступать к моим вопросам, особенно к первому, по привязке координат к окну на любом компьютере где разрешение окна игры такое-же, как у меня, при написании скрипта (т.е. чтобы цвет брало по нужным мне координатам).
 

Whited

Знающий
Сообщения
79
Репутация
10
demonenok [?]
к моим вопросам, особенно к первому, по привязке координат к окну на любом компьютере где разрешение окна игры такое-же, как у меня, при написании скрипта (т.е. чтобы цвет брало по нужным мне координатам).


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

Если же ты имел ввиду что у других будет другое разрешение экрана, то тут только разрабатывание собственных алгоритмов нахождения уникальных координат, например определенные пиксели по порядку.
 
Автор
D

demonenok

Новичок
Сообщения
12
Репутация
2
Whited,

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

Whited

Знающий
Сообщения
79
Репутация
10
demonenok [?]
Whited,Я тоже так думал, но дав другу свой скрипт, он сказал, что у него не те координаты клацает (хотя разрешение одинаковое), значит всеже проблема у него какая-то или он не туда смотрит, тут уже без понятия. Спасибо за информацию. Тогда перейдем ко второму вопросу, который для меня самый важный, как во время выполнения цикла, выполнять действие один раз в 3 минуты ? Т.е. есть ли такая возможность вообще ? Проверять цвет скилла, откотился он или нет, это не вриант, так как с цветами в игре туго.

AdlibRegister
 
Автор
D

demonenok

Новичок
Сообщения
12
Репутация
2
Огромное спасибо, это то, что надо.


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

Adlib-функция должна оставаться предельно простой, поскольку вызывается часто (а работа основного скрипта приостанавливается)

Это противоречит тому, что мне необходимо, так как бот перестает работать и начинает ожидать выполнения функции. Т.е. он просто весит, пока меня не выделит моб, чтобы пнуть его скиллом : (
 

Whited

Знающий
Сообщения
79
Репутация
10
demonenok [?]
выполнять действие один раз в 3 минуты


[?]
Adlib-функция должна оставаться предельно простой, поскольку вызывается часто


ну а что тогда? Так и должно быть. Сформируй свои мысли правильно, еще раз обрисуй алгоритм бота своего....
 
Автор
D

demonenok

Новичок
Сообщения
12
Репутация
2
Моя ошибка, исправил, работает как надо, приношу извинения


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

ну а что тогда? Так и должно быть. Сформируй свои мысли правильно, еще раз обрисуй алгоритм бота своего....

Мне надо, чтобы во время выполнения моего скрипта (т.е. атак бота и т.д.), раз в 10 секунд, использовался скилл (в моем случае, скилл откатывается раз в 10 сек), т.е. бот должен выполнять свои действия, а не простаивать 10 сек, а потом использовать скилл : ) Но вроде у меня всеже это получилось, просто не туда его "пихал", так что вопрос снят : )


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

Бот работает, реализовано вроде все, что необходимо было от него. Осталось придумать что-то с лутом, ибо нажимать пробел 3 раза, с ожиданием какого-то времени, не очень прикольно : ) Сейчас он стоит на пробном тестировании, вечером, если он нормально сдаст тест, выложу тут исходник всего бота с подробными комментариями (может кому-то пригодится). Всем спасибо большое за помощь.

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

Спасибо большое. Тему просьба еще не закрывать, так как создание бота только в разгаре : )
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
OffTopic:
Не стоит называть нечто подобное ботом, это вводит людей в заблуждение. Бот наделен хотя бы зачаточным но интеллектом, он принимает решения вразумительно, исходя из сложившийся ситуации а не последовательно как у тебя. Это можно назвать макросом, вермишелью, скриптом, но не ботом.
 
Автор
D

demonenok

Новичок
Сообщения
12
Репутация
2
Да, ты прав. Сейчас это лишь "кликер" хотя и умеет лечить и восполнять во время боя, т.е. выполняет это не "по расписанию", а лишь когда надо. Так-же и скиллы использует лишь по окончанию их куллдауна. Но как и было сказано "это лишь начало", я сейчас пытаюсь научиться вычислять оффсеты и хотел узнать, мне обсуждать их в моей же теме ? (так как я хочу дописать этот кликер, хотябы до "полууровня" бота : ) ) Или в какой-то теме, в которой обсуждаются оффсеты ?


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

Belfigor

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


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

Вот собственно скриншот самой игры. Прилаживаю скриншот для того, чтобы если в дальнейшем будут вопросы по боту, вы примерно ориентировались что и где в игре(т.е. может оно пригодится : ) ). Оффсет удалось найти с первого раза, без особых проблем (Lucky!). если кому интересно, то у меня получились, такие оффсеты:

Max HP - 00CBDF20 + 16c
Cur HP - 00CBDF20 + 16c + 4(170)
Max MP - 00CBDF20 + 16c + 4 + 4(174)
CurMP - 00CBDF20 + 16c + 4 + 4 + 4(178)

Теперь займусь поиском оффсетов Exp, Mob. HP и еще сделаю попытки поиска оффсетов лута, так как надо научить бота, поднимать только то, что мне необходимо : )


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

Подскажите пожалуйста, как получить данные из этих адрессов что я нашел ?! В коде профан, пытаюсь использовать такой скрипт:

Код:
#include <nomadmemory.au3>
Global $ProcessName = "R.O.H.A.N."
Global $ProcessID = WinGetProcess($ProcessName, "")
SetPrivilege("SeDebugPrivilege", 1)
Global $HP = 0x00CBDF20 ; Указатель (см.картинку выше)
Global $DllInformation = _MemoryOpen($ProcessID)
Global $hWnd = WinGetHandle("R.O.H.A.N.", "")
$CurrentHP = (_MemoryRead($HP, $DllInformation, 'ptr'))
MsgBox(1, "проверь", $CurrentHP, "")
$Cur = $CurrentHP + 356
MsgBox(1, "проверь", $Cur, "")


но нечего не получается .. : ( В итоге выдает одни 0
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Смотри тему про iris online
 
Автор
D

demonenok

Новичок
Сообщения
12
Репутация
2
Подскажите пожалуйста, как узнать, нужно ли подключать "*.dll" файл, для получения BaseAdress с помощью Autoit ? Возможно из-за этого у меня постоянно выдаются 0-ли


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

Как я понял, ответ на мой вопрос примерно таков: " В роли BaseAdress оно бы нашло длл, а не сам адрес ".


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

Ответ нашел, данные выдает как надо. Печально признаваться но вся проблема был в том, что работал GG, который я не знаю, как отключать (сейчас я делаю это, с помощью корейского бота, который предоставляется бесплатно, но чтобы он работал, нужно покупать аккаунт на месяц). Проблема в том, что из-за отключения GG с помощью бота, постоянно дисконектит из игры, примерно через 3 - 5 мин. Так что пока не имею понятия, как побороть GG для дальнейшего написания своего "бота" или "более умного кликера" : ) Кстати, игра использует nProtect GameMon Rev 1692 - может кто-то знает, как такую заразу побороть (хотя и сомневаюсь, что кто-то даст, если даже знает). В общем, продвижение останавливается, пока не найду ответы, как отключать GG


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

Кстати, было интересно, почему CE видет нормально данные, даже когда запущен GG, а Autoit, нет ?
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
У CE всякие undetect вероятно есть от рождения. Теоретически оснастив ими своего бота, ты защитишь клиент от дисконнектов. Отключение же GG можно осуществить с помощью переписывания целевого кода CE на нужный тебе, но тут как бы надо знать ассемблер, и достаточно хорошо. Да из знать мало, надо еще готовую программу уметь реверсинженирить.
 
Автор
D

demonenok

Новичок
Сообщения
12
Репутация
2
Спасибо за информацию. Попробую поискать, как можно скрыть бота, чтобы не дисконектило, хоть таким образом ГГ будет убит.

Подскажите, а как найти BaseAdrr and Offset присущие нику и координатам, а так-же ХП мобам ? Пытался найти свой ник, много-много адресов нахожу, а как найти те, в которых хранятся мои ники, но главный где хранится мой ник всегда, не смог найти. А на счет координат и хп моба, то там нету цифер. Т.е. я не могу знать точно свои координаты, та как на "мини карте" координаты в виде полигонов сделаны(сетки), т.е. допустим C3, H2 и т.п. Хп моба, это как обычная полоска, без каких либо циферок и даже примерно сколько у него хп, мне не известно ...
 
Верх