Что нового

[World Of Warplanets] Написание достойного бота

firex

AutoIT Гуру
Сообщения
943
Репутация
208
ivanius
Это вы все не верно поняли. Пересматривайте логику работы своих функций в соответствии с моим шаблоном (он включает возможность приостановки, продолжения, полной остановки и смены цикла/ов). Вам придется подумать, не все же на блюдце подносить.
 
Автор
I

ivanius

Знающий
Сообщения
74
Репутация
5
Логику я понял в зависимости от $CurrentFuncState, который я глобально могу поменять, функция выполняет определенные действия (остановка, выход, работа).
Хорошо подумаю, спасибо.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
ivanius сказал(а):
Мне нужно принудительно Выйти из функции или ее завершить или передать управление другой или хотя бы выйти из цикла и это нужно сделать из другой функции, которая сидит на кнопке.
Т.е. я не хочу прописывать в каждой функции и в каждом цикле условия типа "_IsKeyDown() - exit loop"
но сейчас почти так и сделано, добавил в While (and _ExitLoop) еще одно условие и меняю его по общей кнопке.

ivanius, Вам нужен этот механизм для отладки бота или вы хотите использовать его в готовом боте?
Я бы предложил использовать разбиение на два отдельных модуля - один реализует функции бота, другой отвечает за GUI.
Но для готового бота это означает наличие двух exe-шников. Вряд ли Вам подойдёт такой вариант, если вы делаете бота для кого-то.
 
Автор
I

ivanius

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

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Ну тогда я бы делал примерно так
Код:
Func Start_Battle();Bot_()
 Run("WoW_fight.exe")
EndFunc


А в самом уже WoW_fight.exe находилось бы
Код:
HotKeySet("{PAUSE}", "_Exit")
Func _Exit()
 Exit
EndFunc
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
Не особо раскрыл перспективы такого подхода к организации циклов, однако:
Код:
; ======== Before
Global $iState
; ---
AdlibRegister( "__Check", 50 )

While 1 ;Loop1
	Local $hTimer
	; -
	If Not $hTimer Or TimerDiff( $hTimer ) > 1000 Then
		$hTimer = TimerInit()
		$iState = ( Random( 1, 5, 1 ) = 4 )
	EndIf

	Sleep( 10 )
WEnd

Func __Check()
	If $iState Then
		If $iState = 2 Then _
			; < Остановить Loop1

		; -
		$iState = 0
	EndIf
EndFunc


Код:
; ======== After
Global $_Loop1_hTimer, $iState
Global $a_MyLoops[3][3] = [ [ 2 ], _
	[ "Loop1", 0, 1 ], _
	[ "Loop_Check", 0, 1 ] ]

While 1 ;Управляющий цикл
	For $Loop = 1 To $a_MyLoops[0][0] Step 1
		If $a_MyLoops[$Loop][2] Then ;State=Resume
			Switch Call( $a_MyLoops[$Loop][0], $a_MyLoops[$Loop][1] )
				Case -1 ;Internal stop
					$a_MyLoops[$Loop][1] = 0
					ContinueCase
				Case -2 ;Internal pause
					$a_MyLoops[$Loop][2] = 0

				Case N ;<Any special internal code

			EndSwitch
		EndIf
	Next
WEnd

Func Loop1( ByRef $__idx )
	Switch $__idx
		Case 0
			ConsoleWrite( "С вероятностью 0.2 цикл прекратит работу" & @CRLF)
			If Not $_Loop1_hTimer Or TimerDiff( $_Loop1_hTimer ) > 1000 Then
				$_Loop1_hTimer = TimerInit()
				$iState = ( Random( 1, 5, 1 ) = 4
			EndIf

		Case 1
			ConsoleWrite( "Цикл будет остановлен ДО выполнения этой части" & @CRLF)
			Sleep( 10 )

		Case Else
			$__idx = -1 ;Restart Loop1
	EndSwitch
	; ---
	$__idx += 1
	Return 0
EndFunc

Func Loop_Check( ByRef $__idx )
	Switch $__idx
		Case 0
			If $iState Then
				If $iState = 2 Then
					$a_MyLoops[1][2] = 0 ;External Loop1 stop!
				EndFunc
				; -
				$iState = 0
			EndIf

		Case Else
			$__idx = -1 ;Restart Loop_Check
	EndSwitch
	; ---
	$__idx += 1
	Return 0
EndFunc


Более практично будет организовать по этому принципу мини-UDF aka Регистрирование и управление подобными цикличными функциями. На мой взгляд, это вполне нормальный ответ отсутствию потоков в AutoIt.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
firex
Это еще более странный и не понятный код.
Имхо, у ivanius явно работа с интерфейсом на втором месте, поэтому ему нужно учить GUICtrlSetOnEvent и в каждом цикле делать что то такое:
Код:
While 1
If canceled() Then exitloop
остальной код.
Wend
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
inververs
Подобный цикл можно прервать только в его начале и невозможно установить в состояние паузы на динамическую позицию. Более того, подобный цикл блокирует работу всего скрипта, однако мы можем использовать AdlibRegister для выполнения некой части кода. Но, что делать в случае, если эта "некая" часть достаточно ресурсоемка?

Можно решать эти проблемы тысячей условий, AdlibRegister-функций и вы все равно будете наступать себе на пятки. На счет GUICtrlSetOnEvent:
Код:
While 1
If canceled() Then exitloop
1) десятки строк кода, которые вызывают в общей сложности задержку >2000ms @ После срабатывания триггера ждать придется до 2 секунд
2) а если имеется цикл в цикле?
Wend


И это еще ерунда. С такими подходами из скрипта выйдет полноценный костыль, и на исправление багов уйдет времени больше, чем на разработку.
 
Автор
I

ivanius

Знающий
Сообщения
74
Репутация
5
inververs сказал(а):
firex
Это еще более странный и не понятный код.
Имхо, у ivanius явно работа с интерфейсом на втором месте, поэтому ему нужно учить GUICtrlSetOnEvent и в каждом цикле делать что то такое:
Код:
While 1
If canceled() Then exitloop
остальной код.
Wend
У меня сейчас так и построен сейчас код, в каждом цикле стоит
Код:
while not @error and _NeedExit
wend
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
firex А чем Контрол Эвент то не понравился? :о. Вставляешь внутри каждой функции одну типовую функцию работающую с глобальными переменными и вперед :о. Использовать GuiGetMsg в программе где основным является цикл контроля игры - не слишком удобно. Помню я тоже бадался и не хотел использовать OnEvent, в итоге все сошлось к тому, что у меня был маленький пультик с десятком кнопок, каждая из колторых должна была выполниться моментально, но пока я не перешел на OnEvent я должен был в лучшем случае ждать по пол секунды - секунде с момента нажатия, до того как команда исполнится. + Еще и согласовывать везде логику.
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
Belfigor
Как раз используя OnEvent придется больше времени потратить на согласование. На счет ожидания пол секунды-секунду - это скорее опять же про OnEvent:
#msg112137
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
firex Таки тебе как разработчику виднее. Я теперь от силы пишу скрипты для МЧС Грожданской Обороны, там ГУЙ куда важнее самого скрипта. Но таки сложно поверить что GUIGetMsg удобнее чем OnEventMode
 
Автор
I

ivanius

Знающий
Сообщения
74
Репутация
5
В общем у меня все получилось и с гуи вроде-бы разобрался, последняя проблема - переодически залипает стрельба как будто зажата клавиша стрельбы , но при этом
if _IsPressed(01) Then - не срабатывает, и просто MouseUp("left") не помогает... только остановка


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

http://autoit-script.ru/index.php?topic=12055.0 - тут прочитал но не понял в чем смысл


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

написал вот так:
Код:
_WinAPI_Keybd_Event(0x01, $KEYEVENTF_KEYUP)

Не помогло :(
 

Belfigor

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

ivanius

Знающий
Сообщения
74
Репутация
5
спасибо сейчас проверю, пока занимаюсь другой проблемой http://autoit-script.ru/index.php?topic=18770.new#new - этой, тоже связано с ботом (косвенно).
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Это типа для чтобы организовать серверную часть дабы контролировать распространение бота или продавать по подписке?
 
Автор
I

ivanius

Знающий
Сообщения
74
Репутация
5
Да хочу оповещение об обновлениях сделать и смотерть сколько пользователей, бота распространяю по очень разным ценам, кто в бете был - тому бесплатно.
 
Верх