#1 05-07-2008 07:48

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

[SA] Скрипт для редактирования сейв-файлов

Представляю вашему вниманию довольно необычный проект. Это скрипт для редактирования сейв-файлов игры San Andreas.

Для использования скрипта и, соответственно, редактирования сейвов, потребуется специальная программа: 010 Editor. Это хекс-редактор с огромным числом возможностей. Скажу честно, с недавнего времени я почти перестал пользоваться Hex Workshop'ом и перешел на 010.

Найти и скачать 010 Editor можно здесь:
http://www.sweetscape.com/

Программа платная, работает в триал-режиме 30 дней.

Одной из возможностей 010 является работа с так называемыми темплейтами (шаблонами). В шаблонах можно расписать структуру бинарного файла (выделить отдельные блоки, поля и т.д.), и после открытия такого бинарного файла в 010 в отдельном окне программы появится вся структура файла.

Пример работы шаблонов можно увидеть на этом скриншоте:

[center]savetool1wi5.th.png[/center]

Как вы можете видеть, окно разделено на 3 основные части.
1) В верхней части (savefile data) отображаются данные сейва (отдельные байты). Если в это время открыт шаблон, то при наведении на отдельные байты, можно узнать, что они означают (на скриншоте так показано поле maxWantedLevel=6)
2) В нижней части (template data) видно структуру файла. Сейв-файл разделен на блоки, в каждом из которых есть свой особый набор данных (информация о игроке, пройденных миссиях, пикапах, припаркованных машинах и т.д.). Если дважды кликнуть на любое поле шаблона, его значение можно изменить (например, увеличить число денег, стереть флаг использования читов и т.д.).
3) В правой части у меня открыты еще некоторые окна с допонительной информацией.


[center]Как пользоваться скриптом:[/center]

1. Откройте в 010 любой сейв игры (файл с расширением .b).

2. Зайдите в меню Templates-Open Template или нажмите Ctrl+F5. Выберите файл шаблона SAS.bt и откройте его. Теперь запустите шаблон нажатием F5.

3. Если все прошло успешно, появится окно со структурой файла. После этого значения сейва можно редактировать.

4. Внимание! Простого изменения файла недостаточно. В конце каждого сейва хранится число - сумма всех байтов сейва (контрольная сумма). Если вы что-то поменяете в сейве, то контрольная сумма уже не будет соответствовать файлу, и такой сейв не будет грузиться игрой. Чтобы все было ок, нужно пересчитать контрольную сумму. Для этого в комплекте идет скрипт SaveCheckSum.1sc. Его достаточно просто запустить в 010, и контрольная сумма будет пересчитана.
Для этого откройте меню Scripts-Open script (Ctrl+F7) и выберите файл SaveCheckSum.1sc. После того как скрипт будет открыт, нажмите F7 для его запуска.

5. После того как вы поменяли нужные значения в сейве и пересчитали контрольную сумму, сохраните файл и проверяйте изменения в игре.


Внимание! В шаблоне сейва вы часто можете встретить поле с названием __gap. Этим словом я обозначал промежутки в данных сейва, которые используются для выравнивания оффсетов. Если проще - то это неиспользуемые байты, их не нужно редактировать, это ни к чему не приведет.

Если вы вдруг узнали значение неизвестного ранее поля или обнаружили некорректное описание, пишите в эту тему.

[center]Несколько советов:[/center]

1. Чтобы упростить работу с шаблоном и скриптом и не открывать их каждый раз, вы можете указать 010, что эти файлы нужно открывать всякий раз, когда вы открываете файл с расширением .b
Соответствующие настройки можно найти в меню Templates-Edit Templates list и Scripts-Edit Scripts list. На скриншотах показано как нужно поставить опции:

[center]savetool2sw3.th.png savetool3gm4.th.png[/center]
2. Если у вас возникают вопросы по работе с 010 Editor, читайте справку (F1), там описано абсолютно все.

3. По вопросам, связанным со структурой сейва и отдельными значениями, обращайтесь к статье на gtamodding.com:
http://www.gtamodding.com/index.php?title=GTA_SA_Saves
или в эту тему.

[center]Credits:[/center]
спасибо всем, кто принимал участие в написании статьи на gtamodding.com, особенно pdescobar и OrionSR
спасибо aru за то, что сказал про 010 Editor.

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

Offline

#2 21-07-2008 13:45

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

Re: [SA] Скрипт для редактирования сейв-файлов

Еще две программы с визуальным интерфейсом, которые могут редактировать сейвы. Сделаны они обе на основе описания формата с GTAModding.com

1. GTA SA Savegame Editor v2.8 by Paul Breeuwsma
http://www.paulinternet.nl/#sa

2. GTA:SA Save Game Editor v1.0 by Ryosuke
http://gtasamod.web.fc2.com/tool/sase/index.html

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

Offline

#3 01-08-2010 12:19

anyakog
Registered: 09-07-2010
Posts: 14

Re: [SA] Скрипт для редактирования сейв-файлов

А как подкорректировать с помощью 010 Editor % отношений с девушками? У меня снизился уровень отношений с Denise так, что повысить его нельзя ("Ну что, Казанова, она бросила тебя" - сообщение при попытке зайти в гости). В структуре сейва не удаётся ничего найти.
И вообще есть ли конкретные примеры работы с этим скриптом?
Спасибо.

Offline

#4 01-08-2010 13:08

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

Re: [SA] Скрипт для редактирования сейв-файлов

За % отношений, насколько я знаю, отвечает массив переменных $GIRL_PROGRESS. Если открыть CustomVariables.ini в SB, то можно узнать, что это переменные $359-$364 (по одной на каждую девушку). Открываем сейв-файл в редакторе, применяем шаблон и ищем нужную переменную. Она будет находиться в разделе block1, блок varSpace[10952]. Тут находятся все глобальные переменные, записанные в файле. Ищем, например, int varSpace[359] и ставим новое значение. После этого нужно изменить контрольную сумму файла путем запуска скрипта SaveCheckSum.

Все детали работы расписаны в первом сообщении.

sasave01.th.jpg

Offline

#5 02-08-2010 05:58

anyakog
Registered: 09-07-2010
Posts: 14

Re: [SA] Скрипт для редактирования сейв-файлов

Спасибо, всё получилось.
Однако, задам дилетантские вопросы:
1) как правильно было определить, что нужен блок varSpace[10952]?
2) окошко "inspector" во вкладке "Variables" дублирует данные окна "template results" и изменения можно вводить в любом из них?
3) окошко "inspector" во вкладке "Auto" отображает при значении int varSpace[359] (value= -99) самые разные значения
Signed Byte
Unsigned Byte
Signed Short
UnSigned Short
Signed Int
UnSigned Int
Signed Int64
UnSigned Int64

при значении int varSpace[359] (value= 70 (например)) выделенные жирно значения тоже становятся = 70. Почему? Можно ли редактировать только некоторые из них?
Спасибо.

Last edited by anyakog (02-08-2010 06:18)

Offline

#6 02-08-2010 06:56

anyakog
Registered: 09-07-2010
Posts: 14

Re: [SA] Скрипт для редактирования сейв-файлов

Ещё вопросы:
1) можно ли глобально охарактеризовать что записывается в save, а что нет?
Например, координаты и виды транспорта, оружия и предметов, взятые из бинарных ipl - транспорт не записывается (т.к., если отредактировать бинарник, игру заново не надо начинать, машины появляются)???
Или верно то, что записывается всё, но, если в бинарном IPL есть машина, она появится несмотря на отсутствие данных о ней в SAVE?
2) как выполнить коррекцию в SAVE в соответствии с изменениями координат и видов предметов и оружия в main.scm

Offline

#7 02-08-2010 07:29

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

Re: [SA] Скрипт для редактирования сейв-файлов

1) как правильно было определить, что нужен блок varSpace[10952]?

в этом блоке хранятся значения всех глобальных переменных из main.scm Их там как раз 10952 штуки. Раз за % отношений отвечает одна из переменных, то и искать нужно здесь.

2) окошко "inspector" во вкладке "Variables" дублирует данные окна "template results" и изменения можно вводить в любом из них?

да. более того значения можно изменять прямо в центральном окне с 16-ричными цифрами smile

3) окошко "inspector" во вкладке "Auto" отображает при значении int varSpace[359] (value= -99) самые разные значения

Byte Short Int In64 - это, грубо говоря, размеры чисел (как размер обуви). Byte занимает только 1 байт, Short - 2, Int - 4, Int64 - 8 байтов. Соответственно у них различается и минимальное и максимальное значение. Например в 1 Byte больше 255 записать нельзя. Когда вы выделяете какое-то место в файле (ставите курсор в центральном поле), редактор не знает, число какого размера тут записано. Это знает только игра: прочитать 1 байт или 4. Поэтому он предлагает все возможные варианты. В шаблонах (вкладка Variables) указаны размеры каждого поля. Например, одна глобальная переменная занимает 4 байта (Int), поэтому когда вы редактируете ее значение, изменяются сразу 4 байта сейв-файла.

Signed/unsigned - число со знаком или без. Более подробно лучше почитать в википедии и на специализированных сайтах.

1) можно ли глобально охарактеризовать что записывается в save, а что нет?

в сейв-файл записываются только конкретные данные. Файл разбит на несколько блоков, каждый хранит определенные данные:
Блок 1: Разное
Блок 2: Данные скриптов (глобальные переменные, данные о потоках)
Блок 3: Данные об игроке (здоровье, броня, деньги)
Блок 4: Данные о гаражах
Блок 5: Данные, используемые при смерти игрока или поимке его копами (например, флаг из опкода 08DD)
... и так далее

подробнейшее описание формата сейв-файла со всеми блоками есть на gtamodding.com
http://www.gtamodding.com/index.php?title=GTA_SA_Saves

Переписывать его тут не вижу смысла.

2) как выполнить коррекцию в SAVE в соответствии с изменениями координат и видов предметов и оружия в main.scm

Если нужно изменить пикапы предметов или оружия, то открой block 6 Pickups, найди нужные пикапы и измени координаты или другие данные.

Offline

#8 02-08-2010 08:29

anyakog
Registered: 09-07-2010
Posts: 14

Re: [SA] Скрипт для редактирования сейв-файлов

подробнейшее описание формата сейв-файла со всеми блоками есть на gtamodding.com
http://www.gtamodding.com/index.php?title=GTA_SA_Saves

Если бы (или я туплю):
Block 6: Pickups на сайте ничего не сказано о координатах в этом блоке.
Конкретно я хочу передвинуть веник от бензоколонки к дому Denise, в SB нахожу:
$3257 = Pickup.Create(#FLOWERA, 15, 1928.68, -1774.21, 13.54)
Ищу в struct tpickup [**] и не нахожу координат ни в 1 из 620, ввожу поиск 1928.68 в 010 Editor - безрезультатно
И какой идентификатор pickup нужно брать из SB?
Спасибо

Offline

#9 02-08-2010 11:25

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

Re: [SA] Скрипт для редактирования сейв-файлов

А если немного подумать? В структуре пикапов есть поле с говорящим названием pos. Читаем описание:

0x10    word[3]        x,y,z, all multiplied by 8

Соответственно, в pos записаны координаты пикапов. Но не в виде обычных float, а в более компактном виде. Если float занимает 4 байта, то тут используется только 2. Чтобы получить нормальную координату надо записанное там число разделить на 8. Например, 15429 / 8 = 1928,625. Знакомое число? Чтобы записать новую координату в сейв, надо ее сначала умножить на 8. Например, 2562.22 * 8 = 20497 (дробная часть отбрасывается).

Нужный тебе пикап - это struct tPickup pickups[412]. Я нашел его по номеру модели (#FLOWERA=325).

Попутно нашел недостаток в своем шаблоне. Для полей pos в данном случае надо использовать тип числа не WORD, а SHORT. WORD - это беззнаковое представление числа, вмещает числа от 0 до 65535. А координаты могут быть и отрицательными. Поэтому должен использоваться тип SHORT, который вмещает числа от -32768..32767.

В общем я перезалил шаблон в первом сообщении.

Offline

#10 18-09-2011 15:25

MenderBolin
Registered: 17-09-2011
Posts: 1

Re: [SA] Скрипт для редактирования сейв-файлов

А что если там форматом значений в типе данных в int и float в разделе статистики "value" должно быть время (часы и минуты), то как менять эту величину?
Хочу изменить "Время в игре" из 11:26 в 11:00. Вроде мелочь, но всё же как?

Там в "value" стоит лишь цифра 1, но это совсем не похоже на 11:26

Last edited by MenderBolin (18-09-2011 16:37)

Offline

#11 23-09-2011 11:42

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

Re: [SA] Скрипт для редактирования сейв-файлов

MenderBolin wrote:

А что если там форматом значений в типе данных в int и float в разделе статистики "value" должно быть время (часы и минуты), то как менять эту величину?
Хочу изменить "Время в игре" из 11:26 в 11:00. Вроде мелочь, но всё же как?

Там в "value" стоит лишь цифра 1, но это совсем не похоже на 11:26

я подозреваю, что там записывается кол-во миллисекунд (или других единиц измерения, например, секунд или минут), прошедших с момента начала игры. Функция отображения меню статистики потом это число "разбивает" на часы и минуты.

Насчет 1, возможно ты смотришь не в то поле.

Offline

#12 23-09-2011 12:45

VintProg_Pro
Registered: 17-06-2010
Posts: 153

Re: [SA] Скрипт для редактирования сейв-файлов

Были времена, а теперь не чего нового на GTA не выходит!

Offline

#13 27-08-2013 18:00

2257733
Registered: 27-08-2013
Posts: 2

Re: [SA] Скрипт для редактирования сейв-файлов

А как изменить пройденные миссии? Например, не могу пройти "не по ту сторону рельс", как сделать её пройденной?

Offline

#14 27-08-2013 20:14

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

Re: [SA] Скрипт для редактирования сейв-файлов

1. вариант простой: выложить свой сейв и попросить на каком-либо форуме, чтобы помогли пройти нужную миссию. например, на gtaforums.com для этого есть целый раздел Mission Help и специальный сайт для закачки сейв-файлов.

2. вариант сложный: изменить сейв игры таким образом, чтобы она думала, что миссия пройдена (не всегда рекомендуется, поскольку некоторые миссии вводят в игру изменения, такие как открытие барьеров, доп. парковки и т.п., чего простым изменением пары байтов сложно сделать).

Прохождение миссий контролируется в скриптах глобальными переменными. Нужно узнать какая переменная отвечает за прохождение требуемой миссии (Wrong Side of the Tracks).

а) открываем main.scm в Sanny Builder. Ищем строку Wrong Side of the Tracks

DEFINE MISSION 29 AT @SMOKE3           // Wrong Side of the Tracks

Итак нужная миссия имеет номер 29

б) Ищем строку start_mission 29 или start_mission SMOKE3

:SMOKE_232
00D6: if 
0038:   $SMOKE_TOTAL_PASSED_MISSIONS == 2 
004D: jump_if_false @SMOKE_284 
0004: $ONMISSION = 1 
00BA: show_text_styled GXT 'SMOKE_3' time 1000 style 2  // Wrong Side of the Tracks
0050: gosub @SUB_CJ_GOTO_SMOKE_HOUSE 
0417: start_mission SMOKE3 // Wrong Side of the Tracks

Ага, вот и требуемая переменная ($SMOKE_TOTAL_PASSED_MISSIONS). Если она равна 2, то при определенных условиях (игрок в маркере), запускается миссия Wrong Side of the Tracks. Чуть ниже идет проверка на другую миссию

:SMOKE_284
00D6: if 
0038:   $SMOKE_TOTAL_PASSED_MISSIONS == 3 
004D: jump_if_false @SMOKE_336 
0004: $ONMISSION = 1 
00BA: show_text_styled GXT 'SMOKE_4' time 1000 style 2  // Just Business
0050: gosub @SUB_CJ_GOTO_SMOKE_HOUSE 
0417: start_mission DRUGS1 // Just Business

Т.е. если $SMOKE_TOTAL_PASSED_MISSIONS равно 3, то запустится уже миссия Just Business, когда CJ придет в гости к смоуку.

в) Проверим это в самой миссии
Ищем метку :SMOKE3

//-------------Mission 29---------------
// Originally: Wrong Side of the Tracks

:SMOKE3

Это начало миссии. Теперь отсюда ищем блок успешного прохождения миссии (обычно там показывается текст Mission Passed)

:SMOKE3_20115
0008: $SMOKE_TOTAL_PASSED_MISSIONS += 1 
0318: set_latest_mission_passed 'SMOKE_3'  // Wrong Side of the Tracks
030C: progress_made = 1 
01E3: show_text_1number_styled GXT 'M_PASSR' number 5 time 5000 style 1  // MISSION PASSED!~n~~w~RESPECT +
0394: play_music 1 
0998: add_respect 5 
0110: clear_player $PLAYER_CHAR wanted_level 
0051: return

Точно, при успешном прохождении переменная $SMOKE_TOTAL_PASSED_MISSIONS увеличивается на 1. В следующий раз запустится уже другая миссия.

г) Осталось изменить переменную в памяти игры.

Можно пойти 2-мя путями. Простой - это создать CLEO-скрипт, который сам установит переменную в нужное значение.

{$CLEO}
$SMOKE_TOTAL_PASSED_MISSIONS = 3
0A93: end_custom_thread

Компилируем (F7), запускаем игру (переменная меняется и скрипт завершает работу), после чего .cs-файл лучше удалить, чтобы он не менял переменную каждый раз.

Примечание. Тут есть одно но. Миссия при успешном прохождении не только меняет величину глобальной переменной, но и накидывает респекта CJ-ю, что влияет на 100% прохождение (строка 0998: add_respect 5 ). Поэтому во избежание проблем, эту строку тоже надо добавить в CLEO-скрипт

{$CLEO}
$SMOKE_TOTAL_PASSED_MISSIONS = 3
0998: add_respect 5
0A93: end_custom_thread

Миссия "пройдена".

Сложный путь изменения переменной - это редактирование сейв-файла (.b). Его можно редактировать разными способами (используя скрипт в этой теме или специальную программу).
Для этого нужно найти, где хранится переменная в сейве. Обращаю внимание, что в сейвах глобальные переменные хранятся не под именами ($SMOKE_TOTAL_PASSED_MISSIONS), а под своими индексами. Узнать индекс переменной можно в файле Sanny Builder\data\sa\CustomVariables.ini

454=Smoke_Total_Passed_Missions

Итак, нужная нам переменная - 454-я в массиве глобальных переменных.
Открываем сейв в редакторе 010 editor. Открываем SaveTool template (тот скрипт, что описан в первом посте темы). Ищем массив глобальных переменных.

struct tBlock01_Script block1		13Dh	CFD1h	Fg: Bg:
...
int varSpace[10952]		146h	AB20h	Fg: Bg:

В сейве хранится 10952 глобальные переменные. наша переменная 452.

int varSpace[452]	0	856h	4h	Fg: Bg:

записываем туда 3, меняем контрольную сумму сейва и проверяем в игре изменения.

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

P.S. Для изменения глобальных переменных "на лету" прямо в игре, можно использовать мой Memory Hacker.

Offline

#15 28-08-2013 15:13

2257733
Registered: 27-08-2013
Posts: 2

Re: [SA] Скрипт для редактирования сейв-файлов

Спасибо!:D;-):clap: Нигде не мог найти=(
Раньше просто скачивал сейвы, и из-за другого порядка прохождений даже не подозревал о такой классной миссии как "just business"

Offline

#16 28-08-2013 20:35

Den_spb
From: Ленинград
Registered: 23-11-2008
Posts: 941
Website

Re: [SA] Скрипт для редактирования сейв-файлов

2257733 wrote:

А как изменить пройденные миссии? Например, не могу пройти "не по ту сторону рельс", как сделать её пройденной?

Эту миссию легко пройти, но при одном условии - мотоцикл всё время должен находиться в пределах первого вагона (не локомотива!). Если опережать первый вагон или наоборот, ехать позади него - миссию будет не пройти.

Offline

Board footer

Powered by FluxBB