#1 15-12-2006 09:00

Seemann
Registered: 07-08-2006
Posts: 2,155

[SA] Примеры работы с игровой памятью

Если вам потребуется в скрипте использовать глобальный ID модели из списка импортирумых моделей (DEFINE OBJECTS), вы можете прочитать его из адреса памяти игры, используя следующую формулу:

 MA = -4982 + (ModelID * -7)

Например, чтобы прочитать глобальный ID модели INFO используйте следующий код:

 0@ = #INFO
 0@ *= -7
 0@ += -4982
 0084: $modelID = &0(0@,1i)

в modelID будет записано 1239.

вот пример цикла, который выводит по очереди все ID моделей из стандартного майна

03C4: set_status_text_to $modelID 0 'FEC_NMN'

 // -4982 + (ModelID * -7)
for 1@ = -1 downto -388 // #INFO downto #SFCOPDR
 0085: 0@ = 1@ 
 0@ *= -7
 0@ += -4982
 0084: $modelID = &0(0@,1i) 
 wait 1000
end // for

Я правда не знаю, насколько это полезно, но вдруг пригодится.

Offline

#2 10-01-2007 10:39

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: [SA] Примеры работы с игровой памятью

Изменение ключей GXT, использование собственных текстов без редактирования american.gxt

// ----------------------------------------------------------------------
//          change GXT Entries
// ----------------------------------------------------------------------  
:ChangeGXTEntries  
  alloc($_param1, 76) 
  alloc($_asmproc, 77)
  alloc($_param2, 78)
  1@ = @_GXTNewString_1  
  2@ = @_GXTNewString_2
  3@ = @_GXTNewString_3
  4@ = @_GXTNewString_4     
  5@ = @_GXTNewString_5     
  6@ = @_GXTNewString_6     
  7@ = @_GXTNewString_7     
  8@ = @_GXTNewString_8  
  9@ = @_GXTNewString_9  
  10@ = @_GXTNewString_10  
  11@ = @_GXTNewString_11  
  12@ = @_GXTNewString_12  
  0@ = -429863
  31@ = 1
  while 31@ < 24  // strings*2
      // -------------------------------
      // FIND GXT ENTRY
      // -------------------------------         
      &0(0@,1i) = 0xA49960
      &0(0@,1i) += @_GetGxtStringPointer
      $_asmproc = 0x6A0050               // char* GetGxtString
      $_param1 = 0xA49958
      005E: $_param1 += 1@(31@,33i)      // char* GXTEntry      
      0572: run_asm_inject true
      // -------------------------------
      // CHANGE GXT STRING
      // -------------------------------
      dec(31@)
      $_param1 = 0xA49964
      005E: $_param1 += 1@(31@,33i)     // char* Source, new string
      &0(0@,1i) = 0xA49960
      &0(0@,1i) += @_CopyString
      $_asmproc = 0x718660              // int CopyString
      0572: run_asm_inject true
      inc(31@,2)      
  end   
return
  // ASM injectors
  // -------------------------------  
  // .text:006A0050 ; char *__cdecl GetGxtString(char *GXT_Entry)
  :_GetGxtStringPointer
  hex 
   FF 35 909AA400      // push dword ptr [0xA49960+$_param1*4]
   B9    40B3C100      // mov ecx, @aAmericanGxt
   FF 15 949AA400      // call dword ptr [0xA49960+$_asmproc*4]
   A3    989AA400      // mov [$_param2], eax
   C3                  // return  
  end
  // .text:00718660 ; int __cdecl CopyString(char *Destination,char *Source)
  :_CopyString
  hex 
   FF 35 909AA400      // push dword ptr [0xA49960+$_param1*4]
   FF 35 989AA400      // push dword ptr [0xA49960+$_param2*4] 
   FF 15 949AA400      // call dword ptr [0xA49960+$_asmproc*4]
   83 C4 08            // add esp, 8
   C3                  // return  
  end                                                           
  // Compiled Strings Pool (null-terminated)
  // -------------------------------  
  :_GXTNewString_1
  0900: "Player position:"
  0900: 'FED_DFL'
  
  :_GXTNewString_2
  0900: "X: ~1~.~1~"
  0900: 'FED_DLS'

  :_GXTNewString_3  
  0900: "Y: ~1~.~1~"
  0900: 'FED_DSR'

  :_GXTNewString_4
  0900: "Z: ~1~.~1~"
  0900: 'FEC_TGD'
    
  :_GXTNewString_5
  0900: "Last eventID: ~1~"
  0900: 'FED_RID'

  :_GXTNewString_6
  0900: "Targeted ped:"
  0900: 'FED_SCP'

  :_GXTNewString_7
  0900: "<no target>"
  0900: 'FED_SPR'

  :_GXTNewString_8
  0900: "Health: ~1~"
  0900: 'DEBUGT1'

  :_GXTNewString_9
  0900: "Model: ~1~"
  0900: 'DEBW0'
   
  :_GXTNewString_10
  0900: "Traffic cars: ~1~"
  0900: 'DEBW1'

  :_GXTNewString_11
  0900: "Car model: ~1~"
  0900: 'DEBW3'

  :_GXTNewString_12
  // last entry
    
// -------------------------------

вот код изменения GXT в runtime. Откомментирую позже.
Пара замечаний: массив строк (0900) должен оканчиваться на метку (даже пустую), максимум изменяемых строк таким способом равно 31 (по числу локальных переменных). После запуска этой подпрограммы, ключи из GXT используются как обычно; текст не должен оканчиваться на пробел (не знаю почему).

Процедура полностью автономная, все что нужно менять это 1) сами строки, 2) массив меток 3) в цикле while число (31@ < 24), оно равно числу элементов массива * 2

Чтобы строки отображались не в верхнем регистре, а как написаны, переключите форматирование в опциях санника на Как есть.

Last edited by Seemann (10-01-2007 11:00)

Offline

#3 10-01-2007 10:42

Alexander
Registered: 19-08-2006
Posts: 184
Website

Re: [SA] Примеры работы с игровой памятью

Очень хороший код ... Надо применить .

Offline

#4 14-01-2007 16:14

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: [SA] Примеры работы с игровой памятью

Открываем всю карту

for 0@ = 354164 to 354188
&0(0@,1i) = 16843009
end

Этот код откроет всю карту (уберет "туман" с непосещенных зон), как будто вы проехали по всему штату.

Offline

#5 18-01-2007 17:50

svetka
Registered: 29-12-2006
Posts: 222

Re: [SA] Примеры работы с игровой памятью

Открываем всю карту

А как правильно установить этот код?

Last edited by svetka (18-01-2007 17:51)

Offline

#6 19-01-2007 04:55

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: [SA] Примеры работы с игровой памятью

2svetka:
просто вставь это в любое место в начала игры, например сразу после команды 03a4: name_thread 'MAIN' или в нулевую миссию.

Offline

#7 15-02-2007 12:38

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: [SA] Примеры работы с игровой памятью

Двигаем игрока по карте

Смысл таков: по нажатию кнопки F4, игрок перемещается в координаты, записанные во внешнем файле.

:MovePlayer
0@ = -429863
1@ = 304497
while true
    wait 250
    &0(1@,1i) == 0xFF0000
    jf continue
    &0(0@,1i) = 0xA49960
    &0(0@,1i) += @_SetNewCoords
    0572: run_asm_inject true
end // while
:_SetNewCoords
hex
 B8 B0 D7 5B 00 FF D0 C3
end

Теперь создавайте файл playercoords.txt в корневой директории игры (там, где exe), в нем пишите строчку, содержащую три координаты XYZ (можно разделять запятыми или пробелом). После нажатия F4 игра переместит CJ'я в указанные координаты.

Файл можно менять во время игры.

Offline

#8 15-02-2007 15:24

Alexander
Registered: 19-08-2006
Posts: 184
Website

Re: [SA] Примеры работы с игровой памятью

Можешь расписать , как ты к файлу обратился ?

Offline

#9 15-02-2007 16:15

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: [SA] Примеры работы с игровой памятью

я только вызвал готовую процедуру в ехе, которая открывает этот файл, читает, ставит координаты, закрывает файл. Видимо, это была часть дебаггера, больше она не используется.

Offline

#10 10-03-2007 00:43

yelmi
Registered: 10-12-2006
Posts: 134
Website

Re: [SA] Примеры работы с игровой памятью

Изменение ключей GXT, использование собственных текстов без редактирования american.gxt – шикарная вещь, работает как часы, но вот столкнулся с проблемой русификации. У меня имеется три, а быть может и больше вариантов перевода и каждый использует разные символы для русских букв. Каким то образом можно решить эту проблему? Не хочется, к примеру, для отдельной миссии в нагрузку кидать файлы fonts.dat и fonts.txd.

Offline

#11 10-03-2007 14:15

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: [SA] Примеры работы с игровой памятью

Хмм, а как это связано с модом? Представь, что ты использовал бы обычный метод через american.gxt, ты бы тоже мог иметь только один вариант перевода и вынужден был бы включить еще свой fonts.

Вывод: юзайте английский язык

Offline

#12 02-05-2007 09:03

Sanchez
Registered: 18-08-2006
Posts: 280

Re: [SA] Примеры работы с игровой памятью

Может и так уже все знают, но решил написать smile

Команда, отвечающая за уменьшение здоровья при падении с байка:

004B3296   D865 04          FSUB DWORD PTR SS:[EBP+4]

Команда, отвечающая за уменьшение здоровья:

004B3314   D865 04          FSUB DWORD PTR SS:[EBP+4]

Команда, отвечающая за уменьшение текущего количества патрон в машине:

0073FA85   48               DEC EAX

Команда, отвечающая за уменьшения общего количества патрон в машине:

0073FAAF   FF4E 0C          DEC DWORD PTR DS:[ESI+C]

Команда, отвечающая за уменьшение текущего количества патрон пешком:

007428AF   48               DEC EAX

Команда, отвечающая за уменьшения общего количества патрон пешком:

007428E6   FF4E 0C          DEC DWORD PTR DS:[ESI+C]

Можно все команды занопить (90h), тогда патроны и здоровье заканчиваться не будут, или DEC заменить на INC, а FSUB заменить на FADD – патроны и здоровье будет прибавлятся.

Можно пропатчить как сам экзешник, так и процесс. Все адреса для версии gta_sa.exe v1.0

Скачать патч (патчится сам процесс, только для v1.0):
1) для заморозки жизней;
2) для заморозки патронов.

Last edited by Sanchez (02-05-2007 10:17)

Offline

#13 02-05-2007 09:12

Alexander
Registered: 19-08-2006
Posts: 184
Website

Re: [SA] Примеры работы с игровой памятью

хорошо smile надо будет сделать общий патч для всех стандартных ехе .

Offline

#14 02-05-2007 09:14

Sanchez
Registered: 18-08-2006
Posts: 280

Re: [SA] Примеры работы с игровой памятью

Alexander wrote:

хорошо  надо будет сделать общий патч для всех стандартных ехе .

У меня кроме 1.0 больше нет wink

Offline

#15 03-05-2007 14:16

Alexander
Registered: 19-08-2006
Posts: 184
Website

Re: [SA] Примеры работы с игровой памятью

я про себя говрил smile оффсеты мне найти будет не сложно ... Только вот времени бы побольше .

Offline

#16 04-05-2007 09:19

Sanchez
Registered: 18-08-2006
Posts: 280

Re: [SA] Примеры работы с игровой памятью

Только вот времени бы побольше .

Да там недолго wink Вот мои исходники если нужно http://foolroot.nm.ru/source/

Last edited by Sanchez (04-05-2007 09:20)

Offline

#17 05-05-2007 16:10

Alexander
Registered: 19-08-2006
Posts: 184
Website

Re: [SA] Примеры работы с игровой памятью

Спасибо , буду использовать .

Offline

#18 13-06-2008 06:17

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: [SA] Примеры работы с игровой памятью

[center][large]Управление фарами[/large][/center]

Вчера мною и listener'ом был разобран весьма интересный класс в движке игры, который в частности позволяет получить полный контроль над фарами машины. Сразу оговорюсь, поворотниками управлять нельзя smile

Через этот класс можно чинить фары машины, если они разбиты.

Передние фары (левая и правая) чинятся по отдельности, задние - только обе сразу.

Итак, как это делается.

1. Сначала получаем адрес машины в памяти

03C0: 0@ = actor $PLAYER_ACTOR car
0A97: 1@ = car 0@ struct

2. Теперь получаем адрес нужного класса, путем прибавления смещения к начальному адресу машины

1@ += 0x5A0

3. Теперь можно чинить фары. Делается это строкой

0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 1 0

Последние 2 цифры - параметры. Предпоследняя цифра (1) означает состояние фары (1 - разбита, 0 - не разбита smile). Последняя цифра - номер фары (0 - передняя левая, 1 - передняя правая, 3 - задние фары). Другие цифры не работают.
Число 1@ - это адрес класса, который мы получили выше.

Варьируя номера фар и их состояние можно получить эффект стробоскопов (выключаем левую/правую переднюю фару по очереди) (проверять нужно ночью, когда фары включены):

 while true
    wait 250
    if
        Player.Defined($PLAYER_CHAR)
    then
        if 
            Actor.Driving($PLAYER_ACTOR)           
        then
            03C0: 0@ = actor $PLAYER_ACTOR car
            0A97: 1@ = car 0@ struct
            1@ += 0x5A0
            0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 1 0 // выключили переднюю левую
            0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 0 1 // включили переднюю правую         
            wait 300
            0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 0 0 // включили переднюю левую
            0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 1 1 // выключили переднюю правую         
            wait 300           
        end
    end
 end

<hr>

Аналогичным способом можно проверить - разбита фара или нет. Для этого используется такая строка:

0AA8: call_function_method 0x6C2130 struct 1@ num_params 1 pop 0 1 0@

Здесь последние 2 параметра означают: номер фары (1 - это передняя правая) и переменную, в которую будет записан результат (0@). Значение 0@ равное 0 означает, что фара не разбита, 1 - разбита.
struct 1@ означает все тот же адрес класса, как и в примере выше.

 while true
    wait 250
    if
        Player.Defined($PLAYER_CHAR)
    then
        if 
            Actor.Driving($PLAYER_ACTOR)           
        then
            03C0: 0@ = actor $PLAYER_ACTOR car
            0A97: 1@ = car 0@ struct
            1@ += 0x5A0
            0AA8: call_function_method 0x6C2130 struct 1@ num_params 1 pop 0 1 0@ // записываем в 0@ состояние передней правой фары
            if
                0@ == 1
            then
                03E5: show_text_box 'HELP101'  // вы разбили правую фару. сейчас починим
                0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 0 1 // включили переднюю правую                            
            end            
        end
    end
 end

Last edited by Seemann (13-06-2008 07:35)

Offline

#19 13-06-2008 13:57

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: [SA] Примеры работы с игровой памятью

[center][large]Самый быстрый способ создать перед игроком машину[/large][/center]

0AA5: call 0x0043A0B6 num_params 1 pop 1 #INFERNUS

#INFERNUS - это желаемая модель машины. Все остальное (загрузку модели, расчет координат) сделает игра.

(подробнее здесь и ниже по тексту).

Offline

#20 22-09-2008 11:06

Basco
Registered: 22-09-2008
Posts: 1

Re: [SA] Примеры работы с игровой памятью

Seemann wrote:

[center][large]Управление фарами[/large][/center]

Вчера мною и listener'ом был разобран весьма интересный класс в движке игры, который в частности позволяет получить полный контроль над фарами машины. Сразу оговорюсь, поворотниками управлять нельзя smile

Через этот класс можно чинить фары машины, если они разбиты.

Передние фары (левая и правая) чинятся по отдельности, задние - только обе сразу.

Итак, как это делается.

1. Сначала получаем адрес машины в памяти

03C0: 0@ = actor $PLAYER_ACTOR car
0A97: 1@ = car 0@ struct

2. Теперь получаем адрес нужного класса, путем прибавления смещения к начальному адресу машины

1@ += 0x5A0

3. Теперь можно чинить фары. Делается это строкой

0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 1 0

Последние 2 цифры - параметры. Предпоследняя цифра (1) означает состояние фары (1 - разбита, 0 - не разбита smile). Последняя цифра - номер фары (0 - передняя левая, 1 - передняя правая, 3 - задние фары). Другие цифры не работают.
Число 1@ - это адрес класса, который мы получили выше.

Варьируя номера фар и их состояние можно получить эффект стробоскопов (выключаем левую/правую переднюю фару по очереди) (проверять нужно ночью, когда фары включены):

 while true
    wait 250
    if
        Player.Defined($PLAYER_CHAR)
    then
        if 
            Actor.Driving($PLAYER_ACTOR)           
        then
            03C0: 0@ = actor $PLAYER_ACTOR car
            0A97: 1@ = car 0@ struct
            1@ += 0x5A0
            0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 1 0 // выключили переднюю левую
            0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 0 1 // включили переднюю правую         
            wait 300
            0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 0 0 // включили переднюю левую
            0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 1 1 // выключили переднюю правую         
            wait 300           
        end
    end
 end

а можно чтобы  эффект стробоскопов  включался/отключался например при нажатии кнопки U
а то у меня стоит скрипт включения/отключения фар
Охото чтобы можно было ездить и просто с горяшими фарами и со страбаскопами

Last edited by Basco (22-09-2008 11:10)

Offline

#21 13-08-2009 17:00

CraZZZy-GameRRR
From: Москва
Registered: 11-08-2009
Posts: 97
Website

Re: [SA] Примеры работы с игровой памятью

А как включить/выключить правую/левую заднюю фару?

Offline

#22 13-08-2009 21:17

Sw[ee]t
From: Нижний Новгород
Registered: 16-02-2009
Posts: 686
Website

Re: [SA] Примеры работы с игровой памятью

Basco wrote:

а можно чтобы  эффект стробоскопов  включался/отключался например при нажатии кнопки U
а то у меня стоит скрипт включения/отключения фар
Охото чтобы можно было ездить и просто с горяшими фарами и со страбаскопами

Можно.

while true
    wait 250
    if and
        Player.Defined($PLAYER_CHAR)
        0AB0: key_pressed 0x55
        Actor.Driving($PLAYER_ACTOR)           
        then
            03C0: 0@ = actor $PLAYER_ACTOR car
            0A97: 1@ = car 0@ struct
            1@ += 0x5A0
            0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 1 0
            0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 0 1         
            wait 300
            0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 0 0
            0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 1 1
            wait 300           
        end
end

Вроде так...

Last edited by Sw[ee]t (13-08-2009 21:18)

Offline

#23 01-08-2013 10:48

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: [SA] Примеры работы с игровой памятью

Как узнать имя машины, в которую целится игрок

код показался очень занятным, поэтому для истории запомним ссылочку

Offline

Board footer

Powered by FluxBB