Minecraft assets хранятся отдельно от серверной сборки и Java runtime. Один набор может использоваться несколькими профилями с одинаковым assetIndex, поэтому файлы не дублируются в S3 и на компьютере игрока.

Структура S3

В launcher/servers/{serverId}/manifest.json не должно быть путей assets/**. Assets manifest строится относительно самой папки assets, поэтому его пути начинаются с indexes/ и objects/.

Контракт API

POST /api/launcher/builds/profile возвращает четыре независимых ресурса:
Сервер читает launcher/servers/{serverId}/releases/{releaseId}/assets/{assetIndex}/manifest.json, проверяет наличие indexes/{assetIndex}.json и вычисляет revision из отсортированного списка путей, размеров и SHA-256. Для получения временных ссылок клиент вызывает:
Сервер разрешает только пути, присутствующие в подписанном manifest, и выдаёт S3 URL с коротким сроком действия.

Локальное хранение

Minecraft получает абсолютный путь {storageRoot}/assets/{assetIndex} через --assetsDir и placeholder ${assets_root}. Поле profile.assetDir сохраняется в формате профиля для совместимости, но реальное расположение задаётся отдельным assets descriptor. {storageRoot} настраивается пользователем. Поэтому assets не обязаны занимать место на системном диске и переносятся вместе с остальными игровыми данными. Подготовка выполняется последовательно:
Rust scanner проверяет весь assets manifest перед каждым запуском. Assets не включаются в периодическую Guardian-проверку во время игры: они не являются исполняемым кодом, а повторное хеширование тысяч объектов создавало бы лишнюю нагрузку. JAR, моды, native DLL и Java runtime остаются защищёнными Guardian.

Генерация manifest

Для подготовленной сборки Architechnica используется скрипт:
Перед запуском должны существовать:
Скрипт создаёт отдельно:
  • servers/4/manifest.json без assets;
  • assets/1.7.10/manifest.json только для indexes и objects.