Что нового

[Мышь, клавиатура] [World of Tanks] Функция MouseMove() некорректно двигает прицел

RavdonikaS

Новичок
Сообщения
68
Репутация
4
Друзья помогите пытаюсь в бою сделать наведение на танк по цвету пикселя иконки через MouseMove() но получается указатель мыши как будто резко дергается на нужные координаты и сразу так же резко возвращается назад с небольшим сдвигом
Пробовал и скорости движения мыши менять и вычислять расстояние до нужного пикселя и делить его на /2 /3 /4 но дергания мыши с небольшим смещением повторяются
Замерял через MouseGetPos() координаты движения мыши получается при движении позиция мыши отклоняется от центральной позиции на 1-5 пикселей в зависимости от скорости движения мыши
Пробовал через MouseMove() добавлять эти 1-5 пикселей к центральной позиции но все равно происходит рывок как бы в нужное место и резко возвращается назад
Что это защита игры или в WoT это реализуется другими средствами и какие есть подводные камни в наведении прицелов в подобных играх?
В ангаре или на миникарте при зажатом ctrl все MouseMove() обрабатываются корректно ставят курсор в нужное место
Код:
#include <GuiConstants.au3> 
#include <ComboConstants.au3>
#include <TabConstants.au3>
#include <StaticConstants.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstants.au3> 
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Opt("MouseClickDownDelay", 400)
Opt("SendKeyDelay", 400)

HotKeySet("{numpad0}","pausa")
HotKeySet("{end}","eksit")
HotKeySet("{numpad5}","srzuboi")


GUICreate("Form1", 142, 105, 1762, 496, $WS_POPUP ,$WS_EX_TOPMOST)
$_Vboi = GUICtrlCreateLabel("Состояние датчиков", 16, 8, 142, 17)
$_s4etboi = GUICtrlCreateLabel("Счётчик боёв ", 16, 32, 142, 17)
$_HP = GUICtrlCreateLabel("ХП танка ", 16, 56, 142, 17)
$pausa = GUICtrlCreateLabel("Запуск скрипта", 16, 80, 142, 17)
GUISetState(@SW_SHOW)
   Beep(500,200)
   Global $ps, $s4etboi, $svet, $navodka, $kart, $Dist, $DistX, $DistY, $TposX,$TposY
   Global $HP, $BOI

WinActivate("WoT Client")
While 1
   If $ps=1 Then
		 dat4ik()
		 If $HP=1 Then
			   If $svet=1  Then
					 If $kart=1 Then
						   $coord=PixelSearch(571, 170, 1340, 913, 0x7E75E2,5);Поиск танка на карте
						   If not @error Then
							  MouseClick("right",$coord[0],$coord[1])
							  cttrl("up")
							  MouseWheel("down",10)
							  $navodka=TimerInit()
						   EndIf
					 ElseIf $kart=0 Then
							  $Mpos=MouseGetPos()
							  $coord=PixelSearch(571, 170, 1340, 913, 0x7E75E2,10) ;Поиск танка 
							  If not @error Then
									If $coord[0]>$Mpos[0] Then
									   $DistX=$coord[0]-$Mpos[0]
									   Dist()
									   $TmovX=($Mpos[0]-4)
									ElseIf $coord[0]<$Mpos[0] Then
									   $DistX=$Mpos[0]-$coord[0]
									   Dist()
									   $TmovX=($Mpos[0]+4)
									EndIf
									
									If $coord[1]<$Mpos[1] Then
									   $DistY=$Mpos[1]-$coord[1]
									   Dist()
									   $TmovY=($Mpos[1]+4)
									ElseIf $coord[1]>$Mpos[1] Then
									   $DistY=$coord[1]-$Mpos[1]	
									   Dist()
									   $TmovY=($Mpos[1]-4)
									EndIf
									If $Dist > 10 Then
									   MouseMove($TmovX,$TmovY,5)
									EndIf
																	 
							  EndIf
							  
							  If TimerDiff($navodka)>10000 Then
									MouseClick("left")
									$svet=0
							  EndIf 
					 EndIf
						   
						   
			   Else
					 $svet=1
					 cttrl("dn")
			   EndIf	
			   	
		 ElseIf $BOI=1 Then
			   cttrl("up")
			   Send("{PRINTSCREEN}")
			   MouseClick("",1456,173)
			   Sleep(2500)
			   MouseClick("",951,31)
			   Sleep(2500)
			   MouseMove(@DesktopWidth/2,@DesktopHeight/2)
			   $s4etboi+=1
			   GUICtrlSetData($_s4etboi,"Счётчик боёв "&$s4etboi)
		 EndIf	  
   EndIf   
WEnd
		 
Func Dist()
	  $Dist = sqrt($DistX^2+$DistY^2) 
	  GUICtrlSetData($_Vboi, "Расстояние="&Round($Dist))			
   EndFunc


Func Dat4ik()
			PixelSearch(731, 1022,731, 1022,0x006F00);Поиск зеленой полоски ХП
			If Not @error  Then
			   GUICtrlSetData($_HP,"[||||||||||||||||||||||||||||||||||||||||||||]")
			   $HP=1
			Else
			   GUICtrlSetData($_HP,"[                         ]")
			   $HP=0
			EndIf
			PixelSearch(951, 33,951, 33,0xFF7818);В оконном режиме кнопка "В бой"
			If Not @error Then
			   GUICtrlSetData($_Vboi, "ДА В БОЙ") 
			   $BOI=1
			Else
			   GUICtrlSetData($_Vboi, "НЕТ В БОЙ") 
			   $BOI=0
			EndIf
EndFunc
Func cttrl($updn)
   Switch $updn
	   Case "dn"
			Send("{CTRLDOWN}")
			$kart=1
			GUICtrlSetData($_Vboi, "Карта зажата")
	   Case "up"
			$kart=0
			Opt("MouseClickDownDelay", 400)
			Send("{CTRLUP}")
			GUICtrlSetData($_Vboi, "Карта отжата")
   EndSwitch
EndFunc

Func pausa()
   Beep(500,200)
   cttrl("up")
   $ps+=1
   If $ps=1 Then
	  GUICtrlSetData($pausa, ">>>>>>>>>>>>>>>>>>")
   ElseIf $ps<>1 Then
	  GUICtrlSetData($pausa, "                 ||  ||")
	  $ps=0
   EndIf
EndFunc
Func eksit()
   cttrl("up")
   Beep(500,200)
   Exit
EndFunc
 

firex

AutoIT Гуру
Сообщения
943
Репутация
206
RavdonikaS
Ну во-первых вы некорректно работаете с координатами - их получаете в 2d мире, а камерой управляете в 3d.
Была тут одна тема где я более-менее описал топорный механизм преобразования, но искать ее долго.

Во-вторых поведение с отскоком назад само по себе странное, дело тут явно в особенностях игры.
http://autoit-script.ru/index.php?topic=22079.msg129419#msg129419


P.S. В WoT не играл, так что ориентируюсь по предоставленной вами информации.
 
Автор
RavdonikaS

RavdonikaS

Новичок
Сообщения
68
Репутация
4
Буду дальше копать
С памятью WoT если кто-то возился напишите поделитесь опытом в каком виде там хранится поворот башни или направление дула?
 

firex

AutoIT Гуру
Сообщения
943
Репутация
206
RavdonikaS [?]
С памятью WoT если кто-то возился напишите поделитесь опытом в каком виде там хранится поворот башни или направление дула?
Зачем? Исходя из вашей спецификации и кода ясно, что вы пишите "пиксельный аимбот", который подразумевает автонаведение на цели находящиеся в пределах видимой области, для этого в дебри игры за положением пушки лезть совсем не обязательно. Если уж собрались работать с памятью, то с пикселями как таковой работы не должно быть.

Буду дальше копать
Копайте ту ссылку, что я скинул, для мыши все практически идентично.
 

SNAK

SNAK
Сообщения
59
Репутация
0
Вот так попробуй
Код:
#include <WinAPI.au3>
_WinAPI_Mouse_Event($MOUSEEVENTF_MOVE,10,0)
 

_serfer_78_

Новичок
Сообщения
16
Репутация
0
RavdonikaS сказал(а):
Друзья помогите пытаюсь в бою сделать наведение на танк по цвету пикселя иконки через MouseMove() но получается указатель мыши как будто резко дергается на нужные координаты и сразу так же резко возвращается назад с небольшим сдвигом
Пробовал и скорости движения мыши менять и вычислять расстояние до нужного пикселя и делить его на /2 /3 /4 но дергания мыши с небольшим смещением повторяются
Замерял через MouseGetPos() координаты движения мыши получается при движении позиция мыши отклоняется от центральной позиции на 1-5 пикселей в зависимости от скорости движения мыши
Пробовал через MouseMove() добавлять эти 1-5 пикселей к центральной позиции но все равно происходит рывок как бы в нужное место и резко возвращается назад
Что это защита игры или в WoT это реализуется другими средствами и какие есть подводные камни в наведении прицелов в подобных играх?
В ангаре или на миникарте при зажатом ctrl все MouseMove() обрабатываются корректно ставят курсор в нужное место
Код:
#include <GuiConstants.au3> 
#include <ComboConstants.au3>
#include <TabConstants.au3>
#include <StaticConstants.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstants.au3> 
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Opt("MouseClickDownDelay", 400)
Opt("SendKeyDelay", 400)

HotKeySet("{numpad0}","pausa")
HotKeySet("{end}","eksit")
HotKeySet("{numpad5}","srzuboi")


GUICreate("Form1", 142, 105, 1762, 496, $WS_POPUP ,$WS_EX_TOPMOST)
$_Vboi = GUICtrlCreateLabel("Состояние датчиков", 16, 8, 142, 17)
$_s4etboi = GUICtrlCreateLabel("Счётчик боёв ", 16, 32, 142, 17)
$_HP = GUICtrlCreateLabel("ХП танка ", 16, 56, 142, 17)
$pausa = GUICtrlCreateLabel("Запуск скрипта", 16, 80, 142, 17)
GUISetState(@SW_SHOW)
   Beep(500,200)
   Global $ps, $s4etboi, $svet, $navodka, $kart, $Dist, $DistX, $DistY, $TposX,$TposY
   Global $HP, $BOI

WinActivate("WoT Client")
While 1
   If $ps=1 Then
		 dat4ik()
		 If $HP=1 Then
			   If $svet=1  Then
					 If $kart=1 Then
						   $coord=PixelSearch(571, 170, 1340, 913, 0x7E75E2,5);Поиск танка на карте
						   If not @error Then
							  MouseClick("right",$coord[0],$coord[1])
							  cttrl("up")
							  MouseWheel("down",10)
							  $navodka=TimerInit()
						   EndIf
					 ElseIf $kart=0 Then
							  $Mpos=MouseGetPos()
							  $coord=PixelSearch(571, 170, 1340, 913, 0x7E75E2,10) ;Поиск танка 
							  If not @error Then
									If $coord[0]>$Mpos[0] Then
									   $DistX=$coord[0]-$Mpos[0]
									   Dist()
									   $TmovX=($Mpos[0]-4)
									ElseIf $coord[0]<$Mpos[0] Then
									   $DistX=$Mpos[0]-$coord[0]
									   Dist()
									   $TmovX=($Mpos[0]+4)
									EndIf
									
									If $coord[1]<$Mpos[1] Then
									   $DistY=$Mpos[1]-$coord[1]
									   Dist()
									   $TmovY=($Mpos[1]+4)
									ElseIf $coord[1]>$Mpos[1] Then
									   $DistY=$coord[1]-$Mpos[1]	
									   Dist()
									   $TmovY=($Mpos[1]-4)
									EndIf
									If $Dist > 10 Then
									   MouseMove($TmovX,$TmovY,5)
									EndIf
																	 
							  EndIf
							  
							  If TimerDiff($navodka)>10000 Then
									MouseClick("left")
									$svet=0
							  EndIf 
					 EndIf
						   
						   
			   Else
					 $svet=1
					 cttrl("dn")
			   EndIf	
			   	
		 ElseIf $BOI=1 Then
			   cttrl("up")
			   Send("{PRINTSCREEN}")
			   MouseClick("",1456,173)
			   Sleep(2500)
			   MouseClick("",951,31)
			   Sleep(2500)
			   MouseMove(@DesktopWidth/2,@DesktopHeight/2)
			   $s4etboi+=1
			   GUICtrlSetData($_s4etboi,"Счётчик боёв "&$s4etboi)
		 EndIf	  
   EndIf   
WEnd
		 
Func Dist()
	  $Dist = sqrt($DistX^2+$DistY^2) 
	  GUICtrlSetData($_Vboi, "Расстояние="&Round($Dist))			
   EndFunc


Func Dat4ik()
			PixelSearch(731, 1022,731, 1022,0x006F00);Поиск зеленой полоски ХП
			If Not @error  Then
			   GUICtrlSetData($_HP,"[||||||||||||||||||||||||||||||||||||||||||||]")
			   $HP=1
			Else
			   GUICtrlSetData($_HP,"[                         ]")
			   $HP=0
			EndIf
			PixelSearch(951, 33,951, 33,0xFF7818);В оконном режиме кнопка "В бой"
			If Not @error Then
			   GUICtrlSetData($_Vboi, "ДА В БОЙ") 
			   $BOI=1
			Else
			   GUICtrlSetData($_Vboi, "НЕТ В БОЙ") 
			   $BOI=0
			EndIf
EndFunc
Func cttrl($updn)
   Switch $updn
	   Case "dn"
			Send("{CTRLDOWN}")
			$kart=1
			GUICtrlSetData($_Vboi, "Карта зажата")
	   Case "up"
			$kart=0
			Opt("MouseClickDownDelay", 400)
			Send("{CTRLUP}")
			GUICtrlSetData($_Vboi, "Карта отжата")
   EndSwitch
EndFunc

Func pausa()
   Beep(500,200)
   cttrl("up")
   $ps+=1
   If $ps=1 Then
	  GUICtrlSetData($pausa, ">>>>>>>>>>>>>>>>>>")
   ElseIf $ps<>1 Then
	  GUICtrlSetData($pausa, "                 ||  ||")
	  $ps=0
   EndIf
EndFunc
Func eksit()
   cttrl("up")
   Beep(500,200)
   Exit
EndFunc

Если наводиться в аркадном режиме то вот кусок функции для примера

Код:
;=== Ищем цель на экране
				$coord = PixelSearch(0, 30, 1024, 530, $color, $shade-variation, 1)
				If Not @error Then
					$x = $coord[0]
					$y = $coord[1]

						While WinActive("[TITLE:WoT Client]") And (($x < 500 - $margin) Or ($x > 500 + $margin) Or ($y < 300 - $margin) Or ($y > 300 + $margin)) And (($x <> -1) And ($y <> -1)) And PixelGetColor(290, 723) <> 0xAE3F28
							If ($x > 500) Then
								Send("{RIGHT}")
							Else
								Send("{LEFT}")
							EndIf

							If ($y > 300) Then
								Send("{DOWN}")
							Else
								Send("{UP}")
							EndIf

							$coord = PixelSearch(0, 30, 1024, 530, $color, $shade-variation, 1)
							If Not @error Then
								$x = $coord[0]
								$y = $coord[1]
							Else
								$x = -1
								$y = -1
							EndIf
						WEnd

						While WinActive("[TITLE:WoT Client]") And (($x < 500 - $margin2) Or ($x > 500 + $margin2) Or ($y < 370 - $margin2) Or ($y > 370 + $margin2)) And (($x <> -1) And ($y <> -1)) And PixelGetColor(290, 723) <> 0xAE3F28
							If ($x > 512) Then
								Send("{RIGHT}")
							Else
								Send("{LEFT}")
							EndIf

							If ($y > 370) Then
								Send("{DOWN}")
							Else
								Send("{UP}")
							EndIf
							$coord = PixelSearch(0, 30, 1024, 530, $color, $shade-variation)
							If Not @error Then
								$x = $coord[0]
								$y = $coord[1]
							Else
								$x = -1
								$y = -1
							EndIf
						WEnd
					EndIf	
	;=== Дальше стреляем если навелись



А если в арт режиме то нужно через dll двигать мышь по одному пикселю с помощью цикла For ...

Код:
Do
		For $i = 3 To 1 Step -1
			If $hwnd <> "" Then $var1 = PixelSearch(330, 200, 690, 660, $color, $shade-variation, 2)
			If Not @Error Then
				$x1 = $var1[0] - 512
				$y1 = $var1[1] - 386
				$v1 = 1
				_mousemove_($x1, $y1)
			Else
				$v1 = 0
			EndIf
		Next
	Until ВАШЕ УСЛОВИЕ ; пока False например $v1 = 0


Самописанная функция _mousemove_ работает через dll, смотрите хелп как работать с библиотеками...

Вместо $shade-variation вписываем допустимое отклонение искомого цвета.
Все очень просто, арт прицел прилипает к танку и не на секунду не отстает, причем движется очень плавно.


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

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

def get_Gun():
player = BigWorld.player()
x, y, z = player.gunRotator.markerInfo[0]
return '%s %-10d, %s %-10d, %s %-10d' % ('GunX:', x, 'GunY:', y, 'GunZ:', z)
Аналогично со всеми остальными параметрами. Как вывести данные из игры и передать их в бот можно найти тут https://autoit-script.ru/index.php?topic=24328.msg139077#msg139077
 
Верх