Что нового

Реакция на изменение состояния курсора

MrGep

Новичок
Сообщения
74
Репутация
1
Версия AutoIt: 3.

Описание:
Доброе время суток всем))) Столкнулся с проблемой - нужно выполнять определенные действия в игре, если курсор покраснеет. Поэтому решил взять пиксель, где находится курсор. Но оказалось, что autoit смотрит "сквозь" него и такой вариант отпадает. Какие есть еще варианты?



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

данный скрипт работает, но в игре ничего не замечает.


Код:
Global $iID_Old, $iCount

HotKeySet('{Esc}', '_Exit')
$iID_Old = MouseGetCursor()
AdlibRegister('_Change_Cursor_Info', 100)
While 1
    Sleep(50)
WEnd

Func _Change_Cursor_Info()
    Local $i_X, $i_Y, $i_ID_New = MouseGetCursor()
    If $iID_Old <> $i_ID_New Then
        $iID_Old = $i_ID_New
        $iCount += 1
        Beep(300, 50)
        $i_X = MouseGetPos(0)
        $i_Y = MouseGetPos(1)
        ToolTip('Курсор изменился: ' & $iCount & @LF & 'В координатах: ' & $i_X & 'x' & $i_Y & @LF & _
                'Можно кликать мышкой.', 0, 0)
    EndIf
EndFunc   ;==>_Change_Cursor_Info

Func _Exit()
    Exit
EndFunc   ;==>_Exit

Написан madmasles
 

Zaramot

I ♥ AutoIt
Сообщения
1,160
Репутация
660
Попробуй так:
Код:
HotKeySet('{Esc}', '_Exit')

While 1
    if '0x' & Hex(PixelGetColor(MouseGetPos(0) + 5, MouseGetPos(1) + 5, 6) = '0xFF0000' then ToolTip('Курсор изменился') ;Имени цвет на нужный
WEnd

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

MrGep

Новичок
Сообщения
74
Репутация
1
К сожалению, не находит(


6a12f8bf6d0b.jpg



Вот скрин курсора, в спокойном состоянии он синий(Да и цвет не проблема, поменять можно) Вопрос в том, что autoit не видит его никакими методами(
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
MrGep сказал(а):
К сожалению, не находит(
Попробуй максимально снизить качество графики. В том же самом WoW при высоком качестве настроек скрипт смотрел сквозь курсор. Когда же настройки понижались до минимума, скрипт начинал распознавать пиксели на курсоре.
 

lirikmel

Продвинутый
Сообщения
226
Репутация
84
оО может легче следить за изменением id курсора ? а не цвета
 

Belfigor

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

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
MrGep

Попробуй этот код. Наведи на врага, дождись когда курсор будет красный, нажми F2. Если в окошке курсор нарисовался - то половина дела решена :smile:

Код:
#include <WinAPIEx.au3>
Global Const $STM_SETIMAGE = 0x0172
GUICreate('', 128, 128)
Global $idIcon=GUICtrlCreateIcon('', 0, 48, 48, 32, 32)
GUISetState()
HotKeySet("{F2}", "_SetIcon")
Do
Until GUIGetMsg() = -3
Func _SetIcon()
	$aCursor = _WinAPI_GetCursorInfo()
	$hCursor = $aCursor[2]
	$aCursorInfo = _WinAPI_GetIconInfo($hCursor)
	$hbmMask = $aCursorInfo[4]
	$hColor = $aCursorInfo[5]
	$hIcon = _WinAPI_CreateIconIndirect($hColor, $hbmMask)
	GUICtrlSendMsg($idIcon, $STM_SETIMAGE, 1, $hIcon)
EndFunc   ;==>_SetIcon


WinApiEx.au3 скачаешь тут http://autoit-script.ru/index.php/topic,47.0.html
 
Автор
M

MrGep

Новичок
Сообщения
74
Репутация
1
Получилось немного иначе)) При зажатом ф2 он рисовал курсор в окошке(Добавил слип на пять секунд) Вот только не могу понять, как можно теперь сделать так, чтобы он выдавал действие(msgbox) при появлении этого курсора( Как я понял, создается окошко, в которое кидается текущий курсор) Или как?
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
MrGep
Т.е он нарисовал нужный курсор? Красного цвета такой как в игре?
 
Автор
M

MrGep

Новичок
Сообщения
74
Репутация
1
inververs, я немного не разобрался в скрипте. Он выводит как изображение или сохраняет вид текущего курсора? Просто пытался записать скрипт, чтобы он искал этот курсор на экране. Но не получилось, программа в упор его не видит. Можно ли сделать так, что как только идет несовпадение курсоров(Неактивного с активным), то выдавалось msgbox?
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
По сути, этот скрипт получает информацию о текущем курсоре, далее получает его bitmap и bitmask и уже потом рисует его в GUI.

И bitmap и bitmask это хэндлы в памяти ссылающиеся на некую структуру.

Можно ли эту информацию использовать для идентификации разных курсоров? Видимо да, но тут нужно понимание работы с bitmaps. Я не знаю, как можно получить некую "контрольную сумму" (может есть какой нибудь способ) этого битмапа, что бы потом ее сравнивать.

Когда я писал скрипт, то дописал - что он поможет решить только первую половину проблемы :smile:. Со второй тебе поможет кто нибудь другой.


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

Ну или как вариант - делай PixelChecksum для окна в котом рисуется курсор.

И еще один момент. Т.к функции сами создают структуры для bitmap и bitmask в памяти, то тебе необходимо позаботиться об их удалении после завершения функции _SetIcon()

Добавив в конец:
Код:
_WinAPI_DeleteObject($hbmMask)
_WinAPI_DeleteObject($hColor)
 

running-frag

why me?
Сообщения
441
Репутация
60
Если есть хэнд картинки попробуйте поковырятся в ней через PixelSearch () и хэнд (к картинке курсора). Так же можно и простым PixelGetColor () и хэндлом.

Самый худший вариант "разобрать картинку на массив пикселей" и поискать в нём нужный.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Попробуй этот код. Понажимай F2 и посмотри, что будет меняться при разных курсорах

Код:
Global Const $STM_SETIMAGE = 0x0172
GUICreate("", 463, 83, 334, 398)
$idIcon = GUICtrlCreateIcon("", -1, 8, 8, 32, 32)
GUICtrlCreateLabel("ResID", 64, 8, 34, 17)
$Label2 = GUICtrlCreateLabel("Нажмите F2", 136, 8, 316, 17)
GUICtrlCreateLabel("ModName", 64, 32, 53, 17)
$Label4 = GUICtrlCreateLabel("Нажмите F2", 136, 32, 316, 17)
GUICtrlCreateLabel("ResName", 64, 56, 51, 17)
$Label6 = GUICtrlCreateLabel("Нажмите F2", 136, 56, 316, 17)
GUISetState()
HotKeySet("{F2}", "_SetIcon")
Do
Until GUIGetMsg() = -3
Func _SetIcon()
    $aCursor = _WinAPI_GetCursorInfo()
    $hCursor = $aCursor[2]
	$aCursorInfo=_WinAPI_GetIconInfoEx($hCursor)
	$hIcon = _WinAPI_CreateIconIndirect($aCursorInfo[4], $aCursorInfo[3])
	GUICtrlSetData($Label2,$aCursorInfo[5])
	GUICtrlSetData($Label4,$aCursorInfo[6])
	GUICtrlSetData($Label6,$aCursorInfo[7])
	GUICtrlSendMsg($idIcon, $STM_SETIMAGE, 1, $hIcon)
	_WinAPI_DeleteObject($aCursorInfo[3])
	_WinAPI_DeleteObject($aCursorInfo[4])
EndFunc   ;==>_SetIcon
 

rusreg79

Продвинутый
Сообщения
159
Репутация
57
Код:
#include <WinAPIEx.au3>

Global $Cursor_id_1, $Cursor_id_2

;==============================
HotKeySet("{Enter}", "_Enter")
$i=False
Do
	ToolTip ( " Наведите курсор на цель (на моба) и нажмите клавишу Enter " )
	Sleep(20)
Until $i
Func _Enter()
	$Cursor_id_1 = _WinAPI_GetCursorInfo()
	$i = True
	HotKeySet("{Enter}");Удалить HotKey
EndFunc
;==============================


While 1
	 $Cursor_id_2 = _WinAPI_GetCursorInfo()
	If $Cursor_id_1[2] = $Cursor_id_2[2] Then
		ToolTip ( " Цель найдена " )
	Else
		ToolTip ( " Идет поиск цели... " )
	EndIf
	Sleep(20)
WEnd
 
Автор
M

MrGep

Новичок
Сообщения
74
Репутация
1
rusreg79, огромное спасибо, то, что нужно)))
Всем спасибо, тема решена))
 

Dellroc

Осваивающий
Сообщения
151
Репутация
31
Я даже подскажу как у меня сделан финт в плане курсора для этой игры:
Код:
#include <nomadmemory.au3>

Func _target($PID,$DllInformation)
If $PID = -1 Then
	SetError(1)
    Return 0
EndIf
Local $sModule = "RF_Online.bin"
Local $baseADDR = _MemoryModuleGetBaseAddress($PID, $sModule)
Local $offset_target = 0x2008448
Local $mem = "0x"&hex($baseADDR+$offset_target)
Local $target = _MemoryRead($mem, $DllInformation,"char[31]") ; читаем адрес из памяти
If $target = '' Then Return '#'
Return $target
EndFunc

Func _MFree($PID,$DllInformation)
Local $MFreeBase = 0x00c0d380
If $PID = -1 Then
	SetError(1)
    Return 0
EndIf
Local $MFreeCur = (_MemoryRead($MFreeBase, $DllInformation, 'ptr'))
$MFreeCur = _MemoryRead($MFreeCur + 404, $DllInformation, 'ptr')
If $MFreeCur = '' Then Return '#'
Return $MFreeCur
EndFunc

Func _MAttack($PID,$DllInformation)
Local $MAttackBase = 0x00c0d380
If $PID = -1 Then
	SetError(1)
    Return 0
EndIf
Local $MAttackCur = (_MemoryRead($MAttackBase, $DllInformation, 'ptr'))
$MAttackCur = _MemoryRead($MAttackCur + 412, $DllInformation, 'ptr')
If $MAttackCur = '' Then
	MsgBox(0,'Ошибка','Не удалось получить хэндл мышки в атаке')
	Exit
EndIf
Return $MAttackCur
EndFunc

Func _MNPC($PID,$DllInformation)
Local $MNPCBase = 0x00c0d380
If $PID = -1 Then
	SetError(1)
    Return 0
EndIf
Local $MNPCCur = (_MemoryRead($MNPCBase, $DllInformation, 'ptr'))
$MNPCCur = _MemoryRead($MNPCCur + 444, $DllInformation, 'ptr')
If $MNPCCur = '' Then Return '#'
Return $MNPCCur
EndFunc

Эти функции вытаскивают из памяти игры ID курсора в состоянии "на цели", "свободное" и на "НПС".
В кратце пример:
Код:
$tMNPC=_MNPC($PID,$DllInformation)
$cursor1 = _WinAPI_GetCursorInfo()
If $cursor1[2] = $tMNPC And $cursor1[2]<>0 Then
	MouseClick('left',$nR[0],$tnR,1,3)
	If _target($PID,$DllInformation) = 'Торговец' Then
		TrayTip('','Торговец найден ',0,2)
		MouseMove(10,90,3)
		ExitLoop
	Else
		Send('{ESC 2}')
		TrayTip('','Попали не в торговца',0,2)
	EndIf
EndIf
 

teges

Знающий
Сообщения
18
Репутация
16
А как был найден адрес курсора в памяти? точнее офсет от базового
 

Dellroc

Осваивающий
Сообщения
151
Репутация
31
Это было одноразовое просветление... К сожалению повторить не получится.
 

lirikmel

Продвинутый
Сообщения
226
Репутация
84
А как был найден адрес курсора в памяти? точнее офсет от базового
поиск неизвестного значения в CE - навел на чтото-курсор изменился -отсеиваем значение изменилось - переводим опять в другое положение - значение изменилось (либо наоборотв зависимости олт ситуации)...и отсеиваем ..отсеиваем..отсеиваем
 
Верх