Артефакти
Артефакт це один файл встановлення: куди він іде, звідки береться, як перевіряється.
{
"path": "${library_directory}/org/lwjgl/lwjgl/3.3.3/lwjgl-3.3.3-natives-linux.jar",
"source": {
"url": "https://libraries.minecraft.net/…/lwjgl-3.3.3-natives-linux.jar"
},
"size": 110704,
"integrity": { "sha1": "149070a5480900347071b7074779531f25a6e3dc" },
"rules": "allow.os.linux",
"extract": { "into": "${natives_directory}", "clean": true }
}| Поле | Обов'язкове | Що це |
|---|---|---|
path | так | Куди записується файл. |
source | так | Звідки беруться байти. |
integrity | ні | Хеш, який він має мати. |
size | ні | Розмір у байтах. |
rules | ні | Які комп'ютери його отримують. |
extract | ні | Як його розпакувати. |
overwrite | ні | Що стає з файлом, який уже є. |
metadata | ні | Будь-що. Встановлювач його ігнорує. |
Невідоме поле це помилка. Поле, якого читач не розуміє, могло б змінити те, що встановлюється.
У конфігурації
Більшість артефактів надходить від плагінів. Можна також написати один власноруч. Звичайний Minecraft з двома доданими файлами:
// opys.config.mjs
export default defineConfig({
plugins: [
minecraft({ version: '1.21.1' }),
java({ version: '21' }),
],
manifest: {
command: '@minecraft.command',
args: ['@minecraft.jvmArgs', '@minecraft.mainClass', '@minecraft.gameArgs'],
workdir: '${game_directory}',
artifacts: [
// найменший артефакт: куди, звідки, його хеш
{
path: '${game_directory}/resourcepacks/pack.zip',
source: { url: 'https://example.com/pack.zip' },
integrity: { sha256: 'ce79869e…' },
},
// лише для Windows, розпаковується після завантаження
{
path: '${game_directory}/tools/overlay.zip',
source: { url: 'https://example.com/overlay.zip' },
integrity: { sha256: '4b1c07aa…' },
rules: 'allow.os.windows',
extract: { into: '${game_directory}/tools/overlay' },
},
],
},
});Звідки береться решта:
| У конфігурації | Стає |
|---|---|
Завантажувач, java | Тисячі завантажень, закріплені. |
links, modrinth | Одне завантаження на посилання, закріплене. |
files | Один перенесений файл (блоб) на файл. |
manifest.artifacts | Саме те, що ви написали. |
path
Куди записується файл. Майже завжди починається зі змінної:
"path": "${game_directory}/mods/jei.jar"Він має бути всередині root. Шлях будь-де в іншому місці зупиняє встановлення.
Два артефакти, один шлях: під час збирання конфігурації пізніший перемагає, а раніший відкидається. Маніфест ніколи не має тримати два.
source
Звідки беруться байти. Рівно одна з двох форм.
Завантаження
"source": { "url": "https://example.com/a-1.0.jar" }URL може містити змінні. Встановлювач завантажує у <path>.partial і перейменовує після завершення, тож обірване завантаження ніколи не виглядає завершеним.
Невдале завантаження повторюється ще тричі, через 0.5, 2 і 8 секунд.
Перенесений файл
"source": { "blob": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" }Файл подорожує всередині бандла, у blobs/<id>. Id це sha256 його вмісту, малими шістнадцятковими літерами.
integrity не потрібна. Ім'я це хеш, тож блоб завжди перевіряється за власним ім'ям.
Коли що використовувати: URL для всього опублікованого. Блоб для файла без публічної адреси. У конфігурації ви рідко вибираєте власноруч: files робить блоби, а links робить завантаження.
integrity
Хеш, який файл має мати. Один хеш або список.
"integrity": { "sha256": "ce79869e1307ed8ee1e2baa86a412b1eb5b75d10a01006d788a6f968bcfaee94" }"integrity": [
{ "sha1": "149070a5480900347071b7074779531f25a6e3dc" },
{ "md5": "d41d8cd98f00b204e9800998ecf8427e" }
]Кожен запис має один ключ: sha1, sha256 або md5. Зі списком достатньо збігу з будь-яким.
Він використовується двічі:
- Перед завантаженням. Файл, що вже на диску і збігається, зберігається. Той, що не збігається, завантажується знову.
- Після завантаження. Файл, що не збігається, провалює встановлення.
Без хеша немає оновлень
Артефакт без integrity ніколи не перевіряється. Раз його файл існує, він зберігається як є, навіть якщо джерело змінилося. Завжди давайте хеш. Файл, який має лишатися, щойно з'явився, каже це через overwrite.
size
Розмір у байтах. Він рухає смугу поступу і порядок завантаження. З файлом він не звіряється. Для цього є integrity.
rules
Які комп'ютери отримають цей файл. Без нього всі.
"rules": "allow.os.windows"Для нативних бібліотек, JDK під кожну платформу і модів, що працюють лише на деяких системах. Усе про синтаксис на сторінці Правила.
extract
Що розпакувати, коли файл уже на місці. Один крок або список кроків, що виконуються по черзі.
Тип архіву береться з імені файла: .tar, .tar.gz і .tgz це tar. Усе інше читається як zip (.jar це zip).
Є три види кроків. Який ви отримаєте, залежить від наявних полів.
Дамп: увесь архів
{ "into": "${natives_directory}", "clean": true, "excludes": ["META-INF/"] }| Поле | Що робить |
|---|---|
into | Тека, куди розпакувати. Обов'язкове. |
clean | true спочатку спорожняє into. |
includes | Лише ці записи. |
excludes | Пропустити ці. Типово: ["META-INF/"]. |
Застосування: нативні бібліотеки, перевизначення файлів модпака.
Сканування: записи, що збігаються
{ "matches": "*", "into": "${java_runtime_dir}/jdk-21", "strip": ["*/"] }| Поле | Що робить |
|---|---|
matches | Які записи брати. Обов'язкове. |
into | Тека, куди розпакувати. Обов'язкове. |
includes | Додаткові шаблони. Запис береться, якщо збігається будь-який. |
excludes | Пропустити ці. |
strip | Прибрати початкову частину імені кожного запису. |
strip: ["*/"] відкидає верхню теку архіву, як би вона не звалася. Верхня тека архіву JDK несе номер збирання, тож саме так плагін java розпаковує його.
Застосування: архів з текою-обгорткою, яка вам не потрібна.
Вибір: один файл
{ "file": "LICENSE", "into": "${game_directory}/LICENSE.txt" }Бере запис із точним ім'ям file і записує його у файл into. Відсутній запис провалює встановлення.
Застосування: один виконуваний файл з архіву випуску.
Шаблони записів
matches, includes і excludes використовують навмисно малий синтаксис:
| Шаблон | Збігається |
|---|---|
lib/ або lib/* | Імена, що починаються з lib/ |
lib* | Імена, що починаються з lib |
*.so | Імена, що закінчуються на .so |
* | Усе |
| будь-що інше | Саме це ім'я |
Це не синтаксис глобів очищення. Шаблони тут не підставляються зі змінними. into підставляється.
Варто знати
- Розпакування виконується на кожному встановленні, тож розпаковані файли завжди відповідають маніфесту.
- Символічні посилання і біти виконуваності зберігаються з tar, на Unix. Режим запису zip ігнорується.
- Запис, що ліг би поза
into(абсолютне ім'я,..), зупиняє встановлення. Архів це чужий файл. - Так само символічне посилання в tar, що вказує поза
into. intoмає бути всерединіroot.- З
clean: trueтримайте сам архів позаinto.
overwrite
Що стає з файлом, який уже є. Відсутній файл встановлюється завжди, і все встановлене перевіряється.
| Значення | Файл, що вже лежить за path |
|---|---|
"always" (за умовчанням) | Встановлюється знову, якщо його байти не збігаються з integrity. |
"never" | Належить гравцю і зберігається, хоч би що в ньому було. |
"never" для файла, який змінює гравець: options.txt, конфіг, який він редагує, список серверів, який він доповнює.
{
"path": "${game_directory}/options.txt",
"source": { "blob": "3d862eef…" },
"overwrite": "never"
}- Те, що встановлюється, усе одно перевіряється.
overwriteнічого не каже про байти: завантаження звіряється зintegrity, а блоб зі своїм ім'ям, як і будь-який інший. - Будь-яке джерело. І файл у бандлі, і завантаження. Файл у бандлі завжди має хеш свого блоба, тож
"never"це єдиний спосіб його зберегти. - Не разом з
extract. Архів розпаковується при кожному встановленні, тож його файли не можна лишити гравцю."never"зextractвідхиляється. - Невідоме значення відхиляється.
cleanupцей файл ніколи не видаляє: це власний файл маніфесту.
metadata
Будь-яке значення JSON. Встановлювач його ніколи не читає. Плагіни використовують його для власних нотаток.