#1 24-12-2009 21:03

BritishColonist
Registered: 30-09-2009
Posts: 72

[Delphi] Чтение координат игрока

Alien, а если я хочу найти координаты игрока, мне надо пользоваться такой же формулой?
Получается результат 0.
Delphi:

X:=$B6F5F0+($30)*$7C4+$14;
ReadProcessMemory(ProcHandle,ptr(X),@value,4,rw);
Edit1.Text := FloatToStr(value);

$7С4 - размер педа (в смысле ячейки с педом).
$30 - Х-координата (смещение или как там?).
$14 - ещё какое-то там смещение (не разбираюсь пока в них).
Чувствую, формула неверна. Представил ещё две строки из дельфи на всякий случай (а вдруг в них накосячил, не зная каких-нибудь там правил преобразования данных?).

Last edited by dragonforce (24-12-2009 21:04)

Offline

#2 24-12-2009 21:35

Sanchez
Registered: 18-08-2006
Posts: 280

Re: [Delphi] Чтение координат игрока

Должно быть как-то так:

PlPtr, PlPosPtr, BytesRead: LongWord;
PlPos: record
	X, Y, Z: Single;
end;

ReadProcessMemory(hProcess, Ptr($B6F5F0), @PlPtr, 4, BytesRead);
ReadProcessMemory(hProcess, Ptr(PlPtr + $14), @PlPosPtr, 4, BytesRead);
ReadProcessMemory(hProcess, Ptr(PlPosPtr + $30), @PlPos, 12, BytesRead);

---

В строку преобразовывать лучше через Format, чтобы не было длинных 'хвостов':

Edit1.Text := Format('%.4f %.4f %.4f', [PlPos.X, plPos.Y, PlPos.Z]);

---

Исправленный вариант:

procedure TForm1.Button1Click(Sender: TObject);
var
	hWindow: HWND;
	dwProcessId, hProcess, BytesRead: Cardinal;
	PlPtr, MatrixPtr: Cardinal;
	PlPos: record
		X, Y, Z: Single;
	end;

begin
	hWindow := FindWindow('Grand theft auto: San Andreas', 'GTA: San Andreas');
	if hWindow = 0 then Exit;
	GetWindowThreadProcessId(hWindow, dwProcessId);
	hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, dwProcessId);
	if hProcess = 0 then Exit;
	ReadProcessMemory(hProcess, Ptr($00B7CD98), @PlPtr, 4, BytesRead);
	if PlPtr = 0 then Exit;
	ReadProcessMemory(hProcess, Ptr(PlPtr + $14), @MatrixPtr, 4, BytesRead);
	if MatrixPtr <> 0 then
		ReadProcessMemory(hProcess, Ptr(MatrixPtr + $30), @PlPos, 12, BytesRead)
	else
		ReadProcessMemory(hProcess, Ptr(PlPtr + $4), @PlPos, 12, BytesRead);
	Edit1.Text := Format('%.4f %.4f %.4f', [PlPos.X, PlPos.Y, PlPos.Z]);
end;

Last edited by Sanchez (24-12-2009 23:19)

Offline

#3 24-12-2009 21:43

BritishColonist
Registered: 30-09-2009
Posts: 72

Re: [Delphi] Чтение координат игрока

Так я и не понял, что мы делаем, чтобы находить значения правильно.
Мы складываем адрес из смещений и сразу из него читаем?
Или читаем один адрес, складываем смещение со значением из этого адреса, читаем получившийся адрес (адрес-сумма предыдущего адреса и смещения)?
Почему, кстати надо использовать Single? Простенький Real разве не подходит под максимальные значения координат на карте? Я пробовал уже и так, и так, но дельного ничего не вышло.

Offline

#4 24-12-2009 21:47

Alien
Registered: 12-10-2008
Posts: 564

Re: [Delphi] Чтение координат игрока

Этот код получает координаты камеры, а не игрока.
Если нужны координаты игрока:
[c]var
    pPlayerPed, pMatrix: DWORD;
    PlayerPos: record
        x, y, z: Single;
    end;

ReadProcessMemory(ProcHandle,Pointer($B7CD98),@pPlayerPed,4,NULL);
if (pPlayerPed <> 0) then
begin
    ReadProcessMemory(ProcHandle,Pointer(pPlayerPed + $14),@pMatrix,4,NULL);
    if (pMatrix <> 0) then
        ReadProcessMemory(ProcHandle,Pointer(pMatrix + $30),@PlayerPos,12,NULL);
    else
        ReadProcessMemory(ProcHandle,Pointer(pPlayerPed + 4),@PlayerPos,12,NULL);
    Edit1.Text := Format('%.4f %.4f %.4f', [PlayerPos.x, PlayerPos.y, PlayerPos.z]);
end
else
    Edit1.Text := 'Player ped not defined yet';[/c]
плохо помню дельфи, поэтому просто внес поправки в код Sanchez'а...=)

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

Single - 4 байта, Real - 6 байт.

Last edited by Alien (24-12-2009 21:49)

Offline

#5 25-12-2009 11:22

BritishColonist
Registered: 30-09-2009
Posts: 72

Re: [Delphi] Чтение координат игрока

Оу! Результаты есть. Спасибо)

Alien wrote:
    ReadProcessMemory(ProcHandle,Pointer(pPlayerPed + $14),@pMatrix,4,NULL);
    if (pMatrix <> 0) then
        ReadProcessMemory(ProcHandle,Pointer(pMatrix + $30),@PlayerPos,12,NULL);
    else
        ReadProcessMemory(ProcHandle,Pointer(pPlayerPed + 4),@PlayerPos,12,NULL);

Можно тут поподробнее? Почему сначала читается адрес со смещением +$30, а потом другой адрес со смещением +4?
Ещё вопрос: как получить угол игрока? Меня интересует значение направления лица игрока (Z). На gtamodding.ru написано "матрица вращения", то есть, надо создать ещё одну запись (pAng : record ax,ay,az:single end;). Так я сделал. А вот считать как?
Я не понял (выше), почему смещения в этих двух случаях (pMatrix=0 или pMatrix<>0) разные, но принцип вроде должен быть таким же и для координат?

ReadProcessMemory(ProcHandle,ptr(pPlayerPed + $14),@pMatrix,4,rw);
      if (pMatrix <> 0) then
       begin
        ReadProcessMemory(ProcHandle,ptr(pMatrix + $30),@pPos,12,rw);
        ReadProcessMemory(ProcHandle,ptr(pMatrix),@pAng,12,rw)
       end
      else
       begin
        ReadProcessMemory(ProcHandle,ptr(pPlayerPed + 4),@pPos,12,rw);
        ReadProcessMemory(ProcHandle,ptr(pMatrix),@pAng,12,rw) //вот тут другое смещение?
       end;

Я читаю из pMatrix, ибо в базе адресов стоит непонятное 0x0 to 0x2C... (а откуда надо читать? x_X)

Last edited by dragonforce (25-12-2009 11:24)

Offline

#6 25-12-2009 14:34

DimP
Registered: 23-03-2009
Posts: 51

Re: [Delphi] Чтение координат игрока

dragonforce, если надо сделать айр брейк с вращением относительно Z ,то может поможет вот этот код, на delphi думаю не сложно перенести будет.

0000: NOP    
:NONAME_2
wait 1
if and
      Player.Defined($PLAYER_CHAR) //found
      not actor.dead($PLAYER_ACTOR) //notdead
     004D: jump_if_false @NONAME_2
if
0AB0:  key_pressed 16//activation/deactivation
then
 if 
 22@ > 0 
 then 
   if 
   26@ > 0 
   then
   0A8D: 10@ = read_memory 1@ size 4 virtual_protect 0
   10@ += 66
   0A8D: 25@ = read_memory 10@ size 1 virtual_protect 0
   25@ -= 3
   0A8C: write_memory 10@ size 1 value 25@ virtual_protect 0
   26@ = 0
   end
 22@ = 0
 wait 700
 else
 22@ = 1
 wait 700
 end
end

if
22@ == 1
then
1@ = 0xB6F5F0
0A8D: 2@ = read_memory 1@ size 4 virtual_protect 0
2@ += 0x14
0A8D: 3@ = read_memory 2@ size 4 virtual_protect 0
0A8E: 4@ = 3@ + 0x30
0A8E: 5@ = 3@ + 0x34
0A8E: 6@ = 3@ + 0x38
0A8D: 7@ = read_memory 4@ size 4 virtual_protect 0
0A8D: 8@ = read_memory 5@ size 4 virtual_protect 0
0A8D: 9@ = read_memory 6@ size 4 virtual_protect 0
//---------------------------------------------------------
0A8D: 10@ = read_memory 1@ size 4 virtual_protect 0
10@ += 1132
0A8C: write_memory 10@ size 1 value 3 virtual_protect 0
10@ -= 1132
10@ += 66
  if 
  26@ < 1 
  then
  0A8D: 25@ = read_memory 10@ size 1 virtual_protect 0
  25@ += 3
  0A8C: write_memory 10@ size 1 value 25@ virtual_protect 0
  26@ = 1
  end
10@ -= 66
10@ += 348
0A8C: write_memory 10@ size 1 value 205 virtual_protect 0
//---------------------------------------------------------
0A8D: 11@ = read_memory 2@ size 4 virtual_protect 0
0A8D: 12@ = read_memory 2@ size 4 virtual_protect 0
11@ += 0x10
12@ += 0x14
0A8D: 13@ = read_memory 11@ size 4 virtual_protect 0
0A8D: 14@ = read_memory 12@ size 4 virtual_protect 0

006B: 13@ *= 21@
006B: 14@ *= 21@

if or
0AB0:  key_pressed 87//W
0AB0:  key_pressed 65//A
0AB0:  key_pressed 83//S
0AB0:  key_pressed 68//D
then
005B: 7@ += 13@ 
005B: 8@ += 14@ 
  if 
  21@ <= 12.0
  then
  21@ += 0.12
  end
else
  21@ = 0.0
end

if 
0AB0:  key_pressed 90//down
then
0063: 9@ -= 23@
  if 
  23@ <= 12.0
  then
  23@ += 0.12
  end
else
  23@ = 0.0
end

if 
0AB0:  key_pressed 88//up
then
005B: 9@ += 24@
  if 
  24@ <= 12.0
  then
  24@ += 0.12
  end
else
  24@ = 0.0
end
//---------------------------------------------------------
0A8C: write_memory 4@ size 4 value 7@ virtual_protect 0 
0A8C: write_memory 5@ size 4 value 8@ virtual_protect 0 
0A8C: write_memory 6@ size 4 value 9@ virtual_protect 0 
end
jump @NONAME_2

Просто получаем cos и sin из матрицы вращения, умножаем на какое нибудь число n(чем больше тем скорость выше) и прибавляем  cos*n + x , sin*n+y. Для лица игрока читать вроде нужно из
0x10 и 0x14 ,хотя может это не так,но все работает.

И у меня вопрос, где находится матрица вращения камеры ?, что бы сделать движение по всем осям

Last edited by DimP (25-12-2009 15:19)

Offline

#7 25-12-2009 16:48

listener
From: Vice City
Registered: 09-11-2006
Posts: 615
Website

Re: [Delphi] Чтение координат игрока

dragonforce wrote:

Можно тут поподробнее? Почему сначала читается адрес со смещением +$30, а потом другой адрес со смещением +4?
Ещё вопрос: как получить угол игрока? Меня интересует значение направления лица игрока (Z). На gtamodding.ru написано "матрица вращения", то есть, надо создать ещё одну запись (pAng : record ax,ay,az:single end;). Так я сделал. А вот считать как?
Я не понял (выше), почему смещения в этих двух случаях (pMatrix=0 или pMatrix<>0) разные, но принцип вроде должен быть таким же и для координат?

Координаты Entity могут храниться либо в CPlaceable, либо в матрице трансформации.
Соответственно, рекомендованный метод - сначала попробовать получить матрицу трансформации (+0x14), а, если это не удалось, получить точку по слещению +4.
Если удалось - из матрицы берется вектор pos (+0x30).

http://sannybuilder.com/forums/viewtopi … 6385#p6385


C5 - GTA IV/RDR/GTA V script compiler.
~ 60% done.

Offline

Board footer

Powered by FluxBB