Формат Соранения Файла (ASE)

Материал из ARK Wiki
Перейти к навигации Перейти к поиску

На этой странице описан пользовательский формат файла сохранения, используемый ARK: Survival Evolved в файлах .ark, и она предназначена для всех, кто хочет изучить или прочитать файлы сохранения напрямую. Файлы .ark содержат текущее состояние мира, включая существ, инвентарь, предметы, построенные конструкции и состояние листвы. Это двоичный файл с несколькими сегментами, и в настоящее время существует одиннадцать версий формата с номерами от 1 до 11. На этой странице основное внимание уделяется версии 9.

Чтобы понять все это, вам нужны базовые знания о Двоичных файлах и базовое понимание представления чисел в памяти (числа с плавающей запятой, целые числа, и т.д.).

Основной процесс чтения данных файла сохранения Ark выглядит следующим образом:

Сегменты

Заголовок Файла

Заголовок расположен в самом начале файла и содержит такую информацию, как адреса сегментов, количество сохранений и общее время воспроизведения.

Как заголовок файла выглядит в файле версии 9

Имя Тип Длина Описание
Версия файла int16 2 байта Номер версии файла сохранения.
Смещение Двоичных Данных int32 4 байта Это смещение файла, с которого начинаются встроенные двоичные данные.
Неизвестно int32 4 байта Кажется, это неиспользуемые данные (все тесты считываются 0)
Смещение Таблицы Имен int32 4 байта Это смещение, с которого начинается таблица имен.
Смещение сегмента данных объекта int32 4 байта Это смещение, с которого начинаются сериализованные данные объекта (свойства).
Время игры float 4 байта В этом разделе хранится внутриигровое время.
Счетчик сохранений int32 4 байта В этом разделе хранится количество сохранений файла.

Объект Имен Двоичных Данных

Чтобы прочитать эту таблицу, вам нужно прочитать данные Строк в объект столько раз, сколько было указано в длине массива.

Имя Тип Длина Описание
Длина массива Int32 2 байта Это говорит нам, сколько Строк содержится в этом массиве.
Строковые данные Строка Неизвестные байты Размер этих объектов неизвестен, поскольку данные считываются на лету.

Таблица Имен

Концепция

"Имена" - это концепция Unreal Engine, которая (в рамках движка) позволяет эффективно сравнивать строки (нужно сравнивать только индексы или хэши (вычисляемые внутри), а не всю строку целиком) и сокращать использование памяти для часто повторяющегося текста. Имена состоят из двух частей:

  • Центральная строковая таблица (которой является этот сегмент), которая в двоичном файле специфична для файла и объединена в глобальную, общую для всех объектов в движке во время выполнения;
  • И ссылки на эту таблицу, состоящие из индекса таблицы int32 и номера экземпляра int32.

Ненулевой номер экземпляра добавляется (уменьшается на единицу) к строке, которой предшествует одиночное подчеркивание.

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

Сериализованный формат

Этот сегмент начинается со смещения, найденного в заголовке.

Имя Тип Длина Описание
Длина массива int32 4 байта Это говорит нам, сколько строк содержится в таблице.
Записи string[] Последовательность строк, завершающаяся нулем, количество которых определяется вышеупомянутым полем длины массива.

Встроенный Объект Двоичных Данных

Использование этих данных неизвестно, мы будем читать массив массивов, содержащих числа Int32. Сначала мы прочитаем длину массива и выполним цикл столько раз, в каждом из этих циклов мы будем:

Считайте следующие 4 байта как Int32 и выполните цикл много раз, считывая каждый раз другое значение Int32 в SubArray.

Имя Тип Длина Описание
Длина массива Int32 4 байта Это говорит нам о том, сколько массивов содержится в этом массиве
SubArray Length Int32 4 байта Это говорит нам, сколько Строк содержится в этом массиве.
Данные Int32 Int32 Длина подмассива * 4 байта Числа Int32 в массиве

Неизвестный Объект Данных

Это какой-то неизвестный объект данных, нам нужно правильно его прочитать на случай, если Ark в какой-то момент его использует.

Имя Тип Длина Описание
Длина массива Int32 4 байта Это говорит нам, сколько массивов содержится в этом массиве.
Неизвестный номер Int32 4 байта Это неизвестный номер, который выглядит как какой-то флаг.
Неизвестное количество объектов Int32 4 байта Это неизвестное число, которое, похоже, сообщает нам количество объектов.
Строковые данные String Неизвестные байты Некоторые неизвестные строковые данные

Таблица Метаданных Объекта

Это основной сегмент, который действует как индекс всех объектов игрового мира, содержащихся в файле.

Имя Тип Длина Описание
Длина массива Int32 4 байта Это говорит нам, сколько записей находится в этой таблице.
Записи
Имя Тип Длина Описание
GUID uint8[16] 16 байт GUID (глобальный уникальный идентификатор) объекта. Однако его уникальность не гарантируется.
Имя класса Name 8 байт Имя класса, экземпляром которого является этот объект.

Обратите внимание, что это только имя класса, а не полный путь. ARK больше не хранит никакой информации о типе объекта.

Является предметом? bool 4 байта Это определяет, является ли объект предметом
Длина массива имен классов Int32 4 байта Количество Объектов класса Ark, содержащихся в этом массиве.
Имя класса Объект класса Ark 8 байт Эти данные повторяют количество, указанное в параметре Длина массива имен классов
Из файла данных Логический объект 4 байта Логическое значение, указывающее, взято ли оно из файла данных (значение неизвестно).
Индекс файла данных Int32 4 байта Индекс файла данных (неизвестное значение)
Доступны данные о местоположении Логический объект 4 байта Это указывает, доступны ли данные о местоположении, только если это правда, существуют следующие 24 байта, в противном случае информация не существует и ее следует пропустить.
Данные о местоположении Объект данных местоположения 24 Bytes Эти данные доступны только в том случае, если предыдущее сообщение Доступные данные о местоположении было true, в противном случае нам следует пропустить чтение этих 24 байтов.
Смещение данных Int32 4 байта Это сообщает нам смещение свойств, с которого следует начать чтение свойств объекта.
Неизвестное целое число Int32 4 байта Неизвестное целое число, которое всегда равно 0 (это может быть просто NUL длиной 4 байта)

Свойства Объекта

Это одна из самых "забавных" частей для чтения данных. Чтобы создать этот объект, мы заполним его массивом объектов, которые мы прочитали из файла. Сначала нам нужно просуммировать смещение блока свойств объекта заголовка файла Ark со смещением свойств игрового объекта и начнем чтение оттуда, пока не достигнем имени класса с именем "None"

Имя Тип Длина Описание
Имя класса Объект класса Ark 8 байт Имя класса свойства, если результат равен "None", нам нужно прекратить чтение в конце этого свойства.
Свойства Содержание Свойства Объекта Неизвестные байты Если предыдущее имя класса не было "None", то мы начинаем считывать содержимое свойства соответствующим образом
Неизвестное целое число Int32 4 байта Неизвестное целое число, которое всегда равно 0 (это может быть просто NUL длиной 4 байта)
Дополнительные данные Дополнительный объект данных Неизвестные байты Иногда в конце свойств содержатся дополнительные данные. Вам следует сохранить эти данные, поскольку они могут содержать важную информацию.

Свойства Объекта

После прочтения имени класса свойства вам необходимо прочитать данные в соответствии с его классификацией:

Объект BoolProperty

Имя Тип Длина Описание
Длина Int32 4 байта Длина в байтах данных для чтения
Индекс Int32 4 байта Индекс прочитанных данных (используется для некоторых свойств, которые повторяются несколько раз)
Ценность PropertyBoolean 1 байтs Логическое значение

Объект ByteProperty

Имя Тип Длина Описание
Длина Int32 4 байта Длина данных для чтения в байтах. Забавно, что иногда это не говорит нам точный размер читаемых байтов.
Индекс Int32 4 байта Индекс прочитанных данных (используется для некоторых свойств, которые повторяются несколько раз)
Значение UInt8 или Объект класса Ark или необработанные байты 1, 8 или неизвестные байты Если длина равна 1, читайте как UInt8, если длина равна 8, тогда читайте как Объект класса Ark, за которым следует значение другого Объект класса Ark, если длина отличается, читайте как необработанные байты.

Объект FloatProperty

Имя Тип Длина Описание
Длина Int32 4 байта Длина в байтах данных для чтения
Индекс Int32 4 байта Индекс прочитанных данных (используется для некоторых свойств, которые повторяются несколько раз)
Значение Float 4 байта Плавающее значение

DoubleProperty Object

Имя Тип Длина Описание
Длина Int32 4 байта Длина в байтах данных для чтения
Индекс Int32 4 байта Индекс прочитанных данных (используется для некоторых свойств, которые повторяются несколько раз)
Значение Double 8 байт The Double Value

Объект IntProperty

Это читается так же, как Int32Property Object

Объект Int8Property

Имя Тип Длина Описание
Длина Int32 4 байта Длина в байтах данных для чтения
Индекс Int32 4 байта Индекс прочитанных данных (используется для некоторых свойств, которые повторяются несколько раз)
Значение Int8 1 байт Подписанное значение Int8

UInt8Property Object

Имя Тип Длина Описание
Длина Int32 4 байта Длина в байтах данных для чтения
Индекс Int32 4 байта Индекс прочитанных данных (используется для некоторых свойств, которые повторяются несколько раз)
Значение UInt8 1 байт Беззнаковое значение UInt8

Int16Property Object

Имя Тип Длина Описание
Длина Int32 4 байта Длина в байтах данных для чтения
Индекс Int32 4 байта Индекс прочитанных данных (используется для некоторых свойств, которые повторяются несколько раз)
Значение Int16 2 байта Подписанное значение Int16

Объект UInt16Property

Имя Тип Длина Описание
Длина Int32 4 байта Длина в байтах данных для чтения
Индекс Int32 4 байта Индекс прочитанных данных (используется для некоторых свойств, которые повторяются несколько раз)
Значение UInt16 2 байта Беззнаковое значение UInt16

Объект Int32Property

Имя Тип Длина Описание
Длина Int32 4 байта Длина в байтах данных для чтения
Индекс Int32 4 байта Индекс прочитанных данных (используется для некоторых свойств, которые повторяются несколько раз)
Значение Int32 4 байта Подписанное значение Int32

Объект UInt32Property

Имя Тип Длина Описание
Длина Int32 4 байта Длина в байтах данных для чтения
Индекс Int32 4 байта Индекс прочитанных данных (используется для некоторых свойств, которые повторяются несколько раз)
Значение UInt32 4 байта Беззнаковое значение UInt32

Объект Int64Property

Имя Тип Длина Описание
Длина Int32 4 байта Длина в байтах данных для чтения
Индекс Int32 4 байта Индекс прочитанных данных (используется для некоторых свойств, которые повторяются несколько раз)
Значение Int64 8 байт Подписанное значение Int64

Объект UInt64Property

Имя Тип Длина Описание
Длина Int32 4 байта Длина в байтах данных для чтения
Индекс Int32 4 байта Индекс прочитанных данных (используется для некоторых свойств, которые повторяются несколько раз)
Значение UInt64 8 байт Беззнаковое значение UInt64

Объект NameProperty

Имя Тип Длина Описание
Длина Int32 4 байта Длина в байтах данных для чтения
Индекс Int32 4 байта Индекс прочитанных данных (используется для некоторых свойств, которые повторяются несколько раз)
Значение Объект класса Ark 8 байт Объект имени класса Ark

Объект ObjectProperty

Имя Тип Длина Описание
Длина Int32 4 байта Длина в байтах данных для чтения
Индекс Int32 4 байта Индекс прочитанных данных (используется для некоторых свойств, которые повторяются несколько раз)
ID Int32 4 байта Это какой-то ID (неизвестное использование)
Значение Int32 Или Объект класса Ark 4 или 8 байт Если длина равна 8, прочитайте значение Int32, если она равна 12, прочитайте Int32 как значение.

Объект StructProperty

Объект ArrayProperty

Объект PropertyText

Объект StrProperty

Объект Класса Ark

При чтении объекта класса Ark вам всегда нужно читать 8 байтов, а когда определен индекс (более 0), вам нужно добавить этот индекс к имени класса, поэтому, если у вас есть объект таблицы Объект таблицы имен и в позиции #72 у вас есть PrimalItem_WeaponEmptyCryopod_C (Примечание: в Объект таблицы имен) это означает, что если ваш индекс = 1, вам нужно добавить _0 в конце создайте PrimalItem_WeaponEmptyCryopod_C_0, и если ваш индекс = 135, вам нужно добавить _134.

Имя Тип Длина Описание
ID Int32 4 байта Соответствующий ID в Объекте таблицы имен
Индекс Int32 4 байта Индекс этого имени, игра принимает имена и представляет их с _INDEX в конце. Если это число равно 0, мы не добавляем _0 к имени, мы оставляем исходное имя как есть, если мы находим 1 или больше в этом значении нам нужно начать отсчет с 0, что означает, что Index=1 — это Append=_0

Типы Данных

Ниже приведены типы данных и способы их соответствующего чтения.

Строка

Имя Тип Длина Описание
Длина строки Int32 4 байта Это говорит нам, сколько байтов нужно прочитать.
Данные строк Строка Длина строки bytes Считайте эти данные как строку, имейте в виду, что последний символ будет NUL-символом 0x00.

Логическое значение

Чтение 32 бит (4 байта), в котором младший бит указывает на истинность

Двойной

Чтение 64-битного (8-байтового) двойного числа

Плавающий

Чтение 32-битного (4-байтового) числа с плавающей запятой

Int8

Чтение 8-битного (1 байта) целого числа со знаком

UInt8

Чтение 8-битного (1 байта) целого числа без знака

Int16

Чтение 16-битного (2-байтового) целого числа со знаком

UInt16

Чтение 16-битного (2-байтового) целого числа без знака

Int32

Чтение 32-битного (4-байтового) целого числа со знаком

UInt32

Чтение 32-битного (4-байтового) целого числа без знака

Int64

Чтение 64-битного (8-байтового) целого числа со знаком

UInt64

Чтение 64-битного (8-байтового) целого числа без знака

PropertyBoolean

Чтение 8 бит (1 байт), в котором младший бит указывает на истинность.