Что нового

Мой личный бот для Lineage2 для 2х окон и более.

skype4com

Новичок
Сообщения
11
Репутация
1
Собственно скрипт автоматизации для 2х окон lineage2. Ботом назвать пока сложно, многое при подготовке надо делать руками.

Что имеем: одно окно с бафером варком и макросом у него на бафф под клавишей F5, и какого нибудь дамагера типа тиранта или глада (лишь бы был ближнего боя) с макросом нексттаргет-атак под F6. Соответственно в пати их обьединять надо руками.

Вот так видит окно AutoIt v3 Window Info:
>>>> Window <<<<
Title:
Class: amhgfpyv
Position: 25, 25
Size: 1364, 911
Style: 0x14CF0000
ExStyle: 0x00040100
Handle: 0x000000000003032E

>>>> Control <<<<
Class:
Instance:
ClassnameNN:
Name:
Advanced (Class):
ID:
Text:
Position:
Size:
ControlClick Coords:
Style:
ExStyle:
Handle:

>>>> Mouse <<<<
Position: 537, 316
Cursor ID: 0
Color: 0x4A4C4A

>>>> StatusBar <<<<

>>>> ToolsBar <<<<

>>>> Visible Text <<<<


>>>> Hidden Text <<<<

Что отсюда примечательно:
1 Нет названия окна
2 Class: постоянно меняется при рестарте клиента. у каждого нового окна он разный.

А значит при запуске придется лично руками хватать этот класс и вставлять в код. Может быть кто знает как это дело в скрипте реализовать?

Сам скрипт:
Код:
#include <Misc.au3>

Global $sWinWARK = "[CLASS:tjysguxa]"   ;класс окна варка
Global $sWinDD = "[CLASS:tjysguxa]"     ;класс окна ДД
;Global $sWinDancer = "[CLASS:tjysguxa]" ;класс окна БД
Global $bRuning = False

HotKeySet("{NUMPAD7}", "ScriptStart")
HotKeySet("{NUMPAD8}", "ScriptStop")
HotKeySet("{NUMPAD9}", "ScriptExit")

While 1
    Sleep(100)
WEnd

Func ScriptStart()
    $bRuning = True
    $begin = TimerInit() ;записываем текущее время
   
        While $bRuning
			$dif = TimerDiff($begin) ;сравниваем время и разницу в переменную пишем
			if $dif > 900000 then ;если прошло больше 15 мин (хотя баф длится 20 мин лучше заранее)
			Baff()  ;бафаемся
			$begin = TimerInit() ;и записываем текущее время
			endif
			
			Kill()
			Sleep(5000)
			
			
        WEnd
    
EndFunc

Func Baff()
	ControlSend($sWinWARK, "", "", "{f5}") ;варк бафает
EndFunc

Func Kill()
	ControlSend($sWinDD, "", "", "{f6}") ;глад убивает
EndFunc	

;Func Dance()
;	ControlSend($sWinDancer, "", "", "{f6}") ; данс
;EndFunc

Func ScriptStop()
    $bRuning = False
EndFunc

Func ScriptExit()
    Exit
EndFunc


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

Не мешало бы:
Автоматическое распознание класса окна. Запустить скриптом одно и тоже приложение (l2.exe) в двух экземплярах и перехватить с каждого класс. Автологин прикрутить уже несложно.
Начал было прикручивать 3е окно, но уже стало сложно не путаться кто есть кто :wacko:

Кому интересно еще l2 пользуйтесь, дорабатывайте и делитесь идеями :beer:
 

ynbIpb

Скриптер
Сообщения
399
Репутация
110
Это пиратский сервер? Видимо самодельная защита, которая убирает заголовки и меняет классы.
Рекомендую ловить не класс, а хэндл окна.
Делаешь необходимое окно активным (на переднем плане), потом функцией WinList по горячей клавише собираешь все окна (вроде активное окно будет первым в массиве или проверять в цикле все окна, какое из них активно в данный момент) и функцией WinGetHandle получаешь его хэндл. Далее этим хэндлом уже манипулируешь вместо класса.

---------------- updated --------------
Вот написал пример:
Код:
; ----------------------------------------------------------------------------
; AutoIt Version: 3.3.6.1
; Author: ynbIpb
; Script Function: управление окнами в L2
; ----------------------------------------------------------------------------
Global $h1stWin = "" ; первое коно
Global $h2stWin = "" ; второе окно
HotKeySet ( "{F1}", "_GetWinHandle1")
HotKeySet ( "{F2}", "_GetWinHandle2")
HotKeySet ( "1", "_Activate1")
HotKeySet ( "2", "_Activate2")

While 1
	sleep (100)
WEnd

Func _GetWinHandle1 () ; функция определения хэндла первого окна
	$aAllWindows = WinList (); собираем все окна в массив
	For $i = 1 to $aAllWindows[0][0]; перебираем все окна в цикле и проверяем активно ли оно
		If _IsActive($aAllWindows[$i][1]) Then ; если окно активно, то это наше окно
			$h1stWin = $aAllWindows[$i][1] ; помещаем его хэндл в заранее приготовленную переменную
			TrayTip ( "Опознание окон", "1 Окно опознано!", 3)
		EndIf
	Next
EndFunc

Func _GetWinHandle2 () ; функция определения хэндла втогого окна
	$aAllWindows = WinList (); собираем все окна в массив
	For $i = 1 to $aAllWindows[0][0]; перебираем все окна в цикле и проверяем активно ли оно
		If _IsActive($aAllWindows[$i][1]) Then ; если окно активно, то это наше окно
			$h2stWin = $aAllWindows[$i][1] ; помещаем его хэндл в заранее приготовленную переменную
			TrayTip ( "Опознание окон", "2 Окно опознано!", 3)
		EndIf
	Next
EndFunc

Func _IsActive($handle); функция проверки активно ли окно
  If BitAnd( WinGetState($handle), 8 ) Then 
    Return 1
  Else
    Return 0
  EndIf
EndFunc

Func _Activate1(); функция активации первого окна
	WinActivate ($h1stWin)
EndFunc

Func _Activate2(); функция активации второго окна
	WinActivate ($h2stWin)
EndFunc

Запусти 2 окна, сделай активным первое и нажми F1, потом сделай активным второе и нажми F2, Всё теперь понажимай 1 и 2 и будет активироваться то первое то второе окно.
 
Автор
S

skype4com

Новичок
Сообщения
11
Репутация
1
Да сервак фришный пвп. Выбрал рандомно, просто хотелось ботоводить).

Поиграл с кодом ynbIpb, нормально, работает. Еще вопрос: а есть возможность "disable" хоткея как только функция отработает? Получается что один запуск скрипта = одно нажатие хоткея. Хотелось бы его вырубить.
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Код:
HotKeySet ( "1", "1")
 
Автор
S

skype4com

Новичок
Сообщения
11
Репутация
1
Belfigor сказал(а):
Код:
HotKeySet ( "1", "1")
Клавиша забинденная на хоткей в скрипте перестает работать в системе. Она управляет только скриптом. А вот так я так понял возвращается функционал:
Код:
HotKeySet("{NUMPAD7}", "{NUMPAD7}")

или:
Код:
HotKeySet ( "1", "1")

я все правильно понял?
 

ynbIpb

Скриптер
Сообщения
399
Репутация
110
Судя по справке:
Код:
HotKeySet ( "{F1}", "_GetWinHandle1") ; это устанавливает хоткей
HotKeySet ( "{F1}") ; это снимает хоткей

тоесть таже команда без указания функции.
 
Автор
S

skype4com

Новичок
Сообщения
11
Репутация
1
Вообщем допиленный бот выглядит так:
Код:
#include <Misc.au3>

Global $sWinWARK = ""   ;класс окна варка
Global $sWinDD = ""     ;класс окна ДД
Global $sWinDancer = "" ;класс окна БД
Global $bRuning = False

HotKeySet ( "{F1}", "_GetWinHandle1")
HotKeySet ( "{F2}", "_GetWinHandle2")
HotKeySet ( "{F3}", "_GetWinHandle3")
HotKeySet("{NUMPAD7}", "Baff")
HotKeySet("{NUMPAD8}", "ScriptStop")
HotKeySet("{NUMPAD9}", "ScriptExit")

While 1
    Sleep(100)
WEnd

Func _GetWinHandle1 () ; функция определения хэндла первого окна
    $aAllWindows = WinList (); собираем все окна в массив
    For $i = 1 to $aAllWindows[0][0]; перебираем все окна в цикле и проверяем активно ли оно
        If _IsActive($aAllWindows[$i][1]) Then ; если окно активно, то это наше окно
            $sWinWARK = $aAllWindows[$i][1] ; помещаем его хэндл в заранее приготовленную переменную
            TrayTip ( "Опознание окон", "1 Окно Wark опознано!", 3)
			HotKeySet ( "{F1}")
        EndIf
    Next
EndFunc
Func _GetWinHandle2 () ; функция определения хэндла втогого окна
    $aAllWindows = WinList (); собираем все окна в массив
    For $i = 1 to $aAllWindows[0][0]; перебираем все окна в цикле и проверяем активно ли оно
        If _IsActive($aAllWindows[$i][1]) Then ; если окно активно, то это наше окно
            $sWinDD = $aAllWindows[$i][1] ; помещаем его хэндл в заранее приготовленную переменную
            TrayTip ( "Опознание окон", "2 Окно DD опознано!", 3)
			HotKeySet ( "{F2}")
        EndIf
    Next
EndFunc
Func _GetWinHandle3 () ; функция определения хэндла 3го окна
    $aAllWindows = WinList (); собираем все окна в массив
    For $i = 1 to $aAllWindows[0][0]; перебираем все окна в цикле и проверяем активно ли оно
        If _IsActive($aAllWindows[$i][1]) Then ; если окно активно, то это наше окно
            $sWinDancer = $aAllWindows[$i][1] ; помещаем его хэндл в заранее приготовленную переменную
            TrayTip ( "Опознание окон", "3 Окно Dancer опознано!", 3)
			HotKeySet ( "{F3}")
        EndIf
    Next
EndFunc
Func _IsActive($handle); функция проверки активно ли окно
  If BitAnd( WinGetState($handle), 8 ) Then 
    Return 1
  Else
    Return 0
  EndIf
EndFunc

Func ScriptStart()
    $bRuning = True
    $begin = TimerInit() ;записываем текущее время
	$BaffRabit = TimerInit()
	$Dancer = TimerInit()
   
        While $bRuning
			$DifDANCE = TimerDiff($Dancer)
			$dif = TimerDiff($begin) ;сравниваем время и разницу в переменную пишем
			$difrabit = TimerDiff($BaffRabit)
			if $dif > 1200000 then ;если прошло больше 15 мин (хотя баф длится 20 мин лучше заранее)
			Baff()  ;бафаемся
			Sleep(1000)
			$begin = TimerInit() ;и записываем текущее время
			endif
			if $difrabit > 90000 Then
				ControlSend($sWinDD, "", "", "{f7}")
				$BaffRabit = TimerInit()
				Sleep(2000)
			endif
			if $DifDANCE > 100000 Then ;если дансу больше 100 сек
				Dance()
				$Dancer = TimerInit()
			EndIf
			
			Kill()
			Sleep(10000)
			

        WEnd
    
EndFunc

Func Baff()
	ControlSend($sWinWARK, "", "", "{f5}") ;варк бафает
	Sleep(10000)
	ControlSend($sWinDD, "", "", "{f12}") ;распаковываем соски
	ControlSend($sWinWARK, "", "", "{f6}") ;варк берет таргет
	Sleep(1000)
	ControlSend($sWinDD, "", "", "{f8}")	;ДД берет таргет варка и начинает мочить
	ScriptStart()
EndFunc

Func Kill()
	ControlSend($sWinDD, "", "", "{f6}") ;nexttarget
	Sleep(500)
	ControlSend($sWinDD, "", "", "{f5}") ;attack
	Sleep(100)
	ControlSend($sWinDancer, "", "", "{f3}")
EndFunc	

Func Dance()
	ControlSend($sWinDancer, "", "", "{f4}") ; данс
	Sleep(12000)
	ControlSend($sWinDancer, "", "", "{f1}") ;атакуем что в таргете
EndFunc

Func ScriptStop()
    $bRuning = False
EndFunc

Func ScriptExit()
    Exit
EndFunc


Задействовано 3 перса: Тирант(Главный ДД), БД, и варк. Начинается все с варка, он бафает пати и берет ближайшего моба в таргет (если он есть), тир подхватывает таргет с варка и если есть там кто то идет мочить, БД подхватывает ассист с тиранта и бежит помогать. Тирант по таймеру бафает на себя тотем зайца. БД по таймеру выдает денсы. Все бы хорошо), но на этой фришке глючит все что только может глючить). Макросы работают с вероятностью 30%, т.е. тирант стоит в толпе мобов, не может взять цель, ну и мобы его в конце концов ковыряют пока не ляжет). На каком нибуть офф серве проверить нет возможности. Но там то работать должно точно как часы.
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
skype4com [?]
А значит при запуске придется лично руками хватать этот класс и вставлять в код. Может быть кто знает как это дело в скрипте реализовать?
Немного поникрофилю, ботами не занимаюсь, но стало интересно по классу окна - что если получить хэндл окна через процесс запуска самой игры(через Run)? Вот пример для блокнота:
Код:
$runNp_1 = Run('notepad.exe')
$hNp_1 = WinGetHandle($runNp_1)
WinWaitActive($hNp_1)
ControlSetText($hNp_1, '', 'Edit1', 'FIRST WINDOW' & @CRLF & '11111111111111')
Sleep(1000)
WinMove($hNp_1, '', 0, 0)
$runNp_2 = Run('notepad.exe')
$hNp_2 = WinGetHandle($runNp_2)
WinWaitActive($hNp_2)
ControlSetText($hNp_2, '', 'Edit1', 'SECOND WINDOW' & @CRLF & '222222222222')
Sleep(1000)
WinMove($hNp_2, '', 400, 600)

Но будет ли он работать для клиента линейки не знаю, ибо его нету :D
Просьба проверить.
 

ynbIpb

Скриптер
Сообщения
399
Репутация
110
Redline
Бывает, что клиент запускается через авто апдейтер и в обход апдейтера защита не даёт запустить.
з.ы.
Кстати сейчас Автоит работает на Руофе, так как там отключили корейскую защиту GG и полностью работают на своей.
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
ynbIpb
Понял, вопросов больше не имею :whistle:
 
Верх