К содержимому
Архивы и защита
На этой странице

Архивы и защита

Как SDK упаковывает уровень в один файл или закрывает его паролем и как распознаёт, что ему передали

Режимы экспорта

Уровень покидает устройство в одной из форм LevelExportMode:

ЗначениеРежимЧто пишетсяЗащита
0Folderобычная папка, та же форма, что на дискенет
1FolderProtectedLevelпапка, где зашифрован только level.json.gpgOpenPGP
2TarGz<имя>.tar.gzнет
3TarGzProtected<имя>.tar.gz.gpgOpenPGP
4Zip<имя>.zipнет
5ZipProtected<имя>.zip.gpgOpenPGP
6ZipEncrypted<имя>.zip с записями в AES-256собственная у zip

Число - это идентичность режима, оно никогда не меняется. Порядок в выпадающем списке редактора задан отдельно (DisplayOrder)

Каждый формат - открытый стандарт. tar -xzf, gpg -d и любой архиватор открывают их без игры:

gpg -d level.tar.gz.gpg > level.tar.gz
tar -xzf level.tar.gz

Две схемы защиты

ZipEncrypted - способ по умолчанию закрыть уровень паролем. У получателя есть архиватор, а gpg, скорее всего, нет

OpenPGP закрывает документ, папку и архив одной схемой. Только он умеет защитить папку

В FolderProtectedLevel метаданные, обложка и медиа остаются читаемыми. Поэтому браузер уровней всё ещё показывает карточку

Внутреннее расширение остаётся в имени: level.json.gpg. Ровно так файл называет gpg -c level.json, поэтому формат известен без догадок

Что попадает внутрь

LevelArchiveBuilder вычисляет содержимое по модели, а не по списку файлов в папке. Файл, на который уровень не ссылается, остаётся снаружи. Отчёт говорит, сколько таких осталось

Ссылки уровня обрабатываются так:

  • ресурс с AbsolutePath копируется в архив. Его ссылка переписывается на LevelPath, но только в экспортированной копии
  • DirectUrl остаётся как есть и попадает в отчёт: URL не может ехать внутри файла
  • отсутствующий файл попадает в отчёт с кодом archive.resource_missing

Распознавание по байтам

Имя файла может написать кто угодно. Поэтому ArchiveFormatSniffer решает по первым 8 байтам:

Первые байтыФормат
1F 8BTarGz
50 4B 03 04, 50 4B 05 06, 50 4B 07 08, 50 4B 30 30Zip
37 7A BC AF 27 1CSevenZip
тег пакета OpenPGP, проверяется последнимOpenPgp: расшифровывается и распознаётся заново
Предупреждение

.7z не читается и не пишется. Он распознаётся только затем, чтобы отказ назвал его по имени (Unsupported). Тогда человек перепакует уровень в zip, а не решит, что файл сломан

Чтение

LevelArchiveReader.ReadAsync принимает папку или Stream с поддержкой перемотки. Он возвращает LevelArchiveContent, где LevelArchiveOpenResult - одно из значений:

РезультатЗначение
Okпрочитано
PassphraseRequiredпароля нет, его нужно спросить
WrongPassphraseчеловек уже ввёл пароль, и он неверный
Damagedфайл повреждён
NotAnArchiveэто не архив
Unsupportedформат распознан, но не поддерживается

PeekMetaAsync читает только метаданные, для карточки или каталога

Сервер читает то, что кто-то решил загрузить. Поэтому читатель работает в рамках ArchiveLimits. По умолчанию это:

  • 4096 записей
  • 512 МиБ на запись
  • 1 ГиБ всего

Ничего не распаковывается за пределы хранилища, которое ему дали

Экспорт со стороны редактора - Экспорт и защита