Что нового

Работа с памятью

Rakim

Новичок
Сообщения
85
Репутация
4
Возможно ли зделать на autoit тренер для игры ? И можете ли привести пример кода ?
 

sss

Продвинутый
Сообщения
332
Репутация
96
C помощью UDF NomadMemory можно считать\записать значение в память процесса, есть даже поддержка указателей (pointer). Я с автоит-скрипта считываю статистику побед в режиме 2 игрока в игре Split Second, пример ниже. Оставил полный код, изучай.
Код:
#include <NomadMemory.au3>

$productname='Split\Second Parser v1.0'
$log_file=@ScriptDir & '\winlog.log'
$syslog_file=@ScriptDir & '\syslog.log'

_LogWrite('------------Новая сессия------------')
_SysLogWrite('------------Новая сессия------------')
_SysLogWrite('Инициализация...')

_SysLogWrite('Запуск игры...')

Run(@ScriptDir & '\SplitSecond.exe')

Sleep(1000)

_SysLogWrite('Ищу процесс...')
$pid=ProcessExists('SplitSecond.exe')

if $pid=0 Then my_Exit(-999)
_SysLogWrite('Процесс найден, PID=' & $pid)

_SysLogWrite('Пытаюсь открыть память...')
$memory_open=_MemoryOpen($pid)

_SysLogWrite('Вроде открыл...')

$p1_wins=0
$p2_wins=0

_SysLogWrite('Жду нулевых значений...')

_Memory_Wait($memory_open,'0x0853BB08','0')
_Memory_Wait($memory_open,'0x0853BB0C','0')

_SysLogWrite('Дождался. Игра началась.')
_LogWrite('Игра началась!!!')


while 1
	$memory_1_player=_MemoryRead('0x0853BB08', $memory_open)

	$memory_2_player=_MemoryRead('0x0853BB0C', $memory_open)

	If $memory_1_player>$p1_wins and $memory_1_player<>4277010157 then $p1_wins=my_P_Win(1,$memory_1_player)

	$memory_1_player_energy_1=_MemoryRead('0x19210134', $memory_open)

	_SysLogWrite('$memory_1_player_energy_1=' & $memory_1_player_energy_1)


	If $memory_2_player>$p2_wins and $memory_2_player<>4277010157 then $p2_wins=my_P_Win(2,$memory_2_player)

;~     _SysLogWrite('$memory_1_player=' & $memory_1_player)

;~ 	_SysLogWrite('$memory_2_player=' & $memory_2_player)

	if ProcessExists('SplitSecond.exe')=0 then my_Exit(0)

	Sleep(3000)

WEnd

_MemoryClose($memory_open)

Func my_P_Win($player,$count)
	Switch $player
		case 1
			Beep(500,500)
			_LogWrite('Игрок 1 (слева) выиграл! Теперь у него ' & $count & ' побед в сессии!')
		case 2
			Beep(500,500)
			Sleep(100)
			Beep(500,500)
			_LogWrite('Игрок 2 (справа) выиграл! Теперь у него ' & $count & ' побед в сессии!')
	EndSwitch
	Return $count
EndFunc

Func _LogWrite($text)
	$date=@mDAY & '.' & @MON & '.' & @YEAR & ' , ' & @HOUR & ':' & @MIN & ':' & @SEC
	FileWriteLine($log_file,$date & ' :: ' & $productname & ' :: ' & $text)
EndFunc

Func _SysLogWrite($text)
	$date=@mDAY & '.' & @MON & '.' & @YEAR & ' , ' & @HOUR & ':' & @MIN & ':' & @SEC
	FileWriteLine($syslog_file,$date & ' :: ' & $text)
EndFunc

Func my_Exit($flag)
	Switch $flag
		case 0
			If $p1_wins>$p2_wins Then
				_LogWrite('Игрок 1 (слева) победил в сессии - у него ' & $p1_wins & ' побед, а у игрока 2 - только ' & $p2_wins)
			Elseif $p1_wins=$p2_wins Then
			    _LogWrite('Честная ничья!')
			Else
				_LogWrite('Игрок 2 (справа) победил в сессии - у него ' & $p2_wins & ' побед, а у игрока 1 - только ' & $p1_wins)
			EndIf
			_LogWrite('------------Конец сессии------------')
			_SysLogWrite('Закрываюсь...')
			Exit
		case -999
			_LogWrite('------------Конец сессии------------')
			_SysLogWrite('Закрываюсь, программа передала ошибку...')
			Exit
	EndSwitch
EndFunc

Func _Memory_Wait($memoryopen,$memoryfield,$i)
	While 1
		$temp=_MemoryRead($memoryfield, $memoryopen)
		if $temp=$i then ExitLoop
	WEnd
EndFunc

P.S: Основная работа с памятью начинается в районе 40-50 строки, + я добавил свою функцию для работы с памятью - _MemoryWait(массив_от_MemoryOpen,ячейка,значение) - пауза, пока в ячейке не будет указанное значение.
 
Автор
R

Rakim

Новичок
Сообщения
85
Репутация
4
Спс *) Но не мог бы ты его переделать ? Например что бы он по клику менял значение ? А то эт сложновато прост *)
И скажи как тут те + поставить ?
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Предупреждение За нарушение правил форума (пункт Б.5):
Имя темы должно нести смысловую нагрузку (отражать суть вопроса/проблемы)
Правильно сформулированное название темы привлекает больше внимания, и шансы получить конкретный ответ увеличиваются.


Как правильно называть темы

"Работа с памятью" - это неприемлемое название темы, переименуйте тему иначе она будет закрыта, а вам возможно будет выдан бан на несколько дней.

С уважением, Модератор раздела.










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

Rakim
тебе сюда http://autoit-script.ru/index.php?board=8.0
но сначала прочти это http://autoit-script.ru/index.php?topic=124.0
 

sss

Продвинутый
Сообщения
332
Репутация
96
Плюс - нажми полезное сообщение или под аватаркой нажми +1.Скрипт - прилагаю. $var1 и $var2 - это адреса ячеек.
Код:
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <NomadMemory.au3>

$var1='0x0853BB08'
$var2='0x0853BB0C'

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("MyGUI", 368, 137)
$Label1 = GUICtrlCreateLabel("Шаг 1: Введи имя процесса (например, SplitSecond.exe)", 8, 8, 286, 17)
$input_process_name = GUICtrlCreateInput("", 8, 30, 185, 21)
$Label2 = GUICtrlCreateLabel("Шаг 2: Ожидание запуска игры. Запустите приложение.", 8, 56, 289, 17)
GuictrlSetState($Label2,$GUI_HIDE)
$Button_pname_ok = GUICtrlCreateButton("Принять", 200, 30, 75, 21, $WS_GROUP)
$Label3 = GUICtrlCreateLabel("Шаг 3: Получение pid и открытие памяти процесса...", 8, 80, 270, 17)
GuictrlSetState($Label3,$GUI_HIDE)
$Label4 = GUICtrlCreateLabel("Память открыта. Перехожу в режим управления через 3 секунды...", 8, 104, 348, 17)
GuictrlSetState($Label4,$GUI_HIDE)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		case $Button_pname_ok
			$pname=GUICtrlRead($input_process_name)
			GuictrlSetState($Label2,$GUI_SHOW)
			GuictrlSetState($Button_pname_ok,$GUI_DISABLE)
			ExitLoop

	EndSwitch
WEnd

While 1
	$pid=ProcessExists($pname)
	if $pid<>0 then ExitLoop
	$Msg = GUIGetMsg()
	Switch $Msg
	    Case $GUI_EVENT_CLOSE
	   		Exit
	EndSwitch
WEnd

GuictrlSetState($Label3,$GUI_SHOW)

$memory_open=_MemoryOpen($pid)

GuictrlSetState($Label4,$GUI_SHOW)
Sleep(3000)

GUIDelete($Form1)

$Form2 = GUICreate("Form1", 305, 161)
$Label1 = GUICtrlCreateLabel("Ячейка " & $var1, 8, 8, 150, 17)
$input_1 = GUICtrlCreateInput("", 8, 28, 137, 21)
$input_2 = GUICtrlCreateInput("", 176, 28, 121, 21)
$Label2 = GUICtrlCreateLabel("Ячейка " & $var2, 176, 8, 150, 17)
$button_getdata = GUICtrlCreateButton("Получить данные из игры", 8, 64, 291, 25, $WS_GROUP)
$button_setdata = GUICtrlCreateButton("Записать свои данные в игру", 8, 96, 291, 25, $WS_GROUP)
$Button_exit = GUICtrlCreateButton("Выход", 8, 128, 291, 25, $WS_GROUP)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		case $button_getdata
			$memory_1=_MemoryRead($var1, $memory_open)
			$memory_2=_MemoryRead($var2, $memory_open)
			GUICtrlSetData($input_1,$memory_1)
			GUICtrlSetData($input_2,$memory_2)

		case $button_setdata
			$input_1_data=GUICtrlRead($input_1)
			$input_2_data=GUICtrlRead($input_2)
			if $input_1_data='' or $input_2_data='' then
				MsgBox(0,'','Введите оба значения!')
				ContinueLoop
			EndIf
			_MemoryWrite($var1, $memory_open, $input_1_data)
			_MemoryWrite($var2, $memory_open, $input_2_data)
		case $Button_exit
			Exit

	EndSwitch
WEnd
 
Верх