Skip to content

Артефакти ​

Артефакт це один файл встановлення: куди він іде, звідки береться, як перевіряється.

json
{
  "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 з двома доданими файлами:

js
// 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 ​

Куди записується файл. Майже завжди починається зі змінної:

json
"path": "${game_directory}/mods/jei.jar"

Він має бути всередині root. Шлях будь-де в іншому місці зупиняє встановлення.

Два артефакти, один шлях: під час збирання конфігурації пізніший перемагає, а раніший відкидається. Маніфест ніколи не має тримати два.

source ​

Звідки беруться байти. Рівно одна з двох форм.

Завантаження ​

json
"source": { "url": "https://example.com/a-1.0.jar" }

URL може містити змінні. Встановлювач завантажує у <path>.partial і перейменовує після завершення, тож обірване завантаження ніколи не виглядає завершеним.

Невдале завантаження повторюється ще тричі, через 0.5, 2 і 8 секунд.

Перенесений файл ​

json
"source": { "blob": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" }

Файл подорожує всередині бандла, у blobs/<id>. Id це sha256 його вмісту, малими шістнадцятковими літерами.

integrity не потрібна. Ім'я це хеш, тож блоб завжди перевіряється за власним ім'ям.

Коли що використовувати: URL для всього опублікованого. Блоб для файла без публічної адреси. У конфігурації ви рідко вибираєте власноруч: files робить блоби, а links робить завантаження.

integrity ​

Хеш, який файл має мати. Один хеш або список.

json
"integrity": { "sha256": "ce79869e1307ed8ee1e2baa86a412b1eb5b75d10a01006d788a6f968bcfaee94" }
json
"integrity": [
  { "sha1": "149070a5480900347071b7074779531f25a6e3dc" },
  { "md5": "d41d8cd98f00b204e9800998ecf8427e" }
]

Кожен запис має один ключ: sha1, sha256 або md5. Зі списком достатньо збігу з будь-яким.

Він використовується двічі:

  • Перед завантаженням. Файл, що вже на диску і збігається, зберігається. Той, що не збігається, завантажується знову.
  • Після завантаження. Файл, що не збігається, провалює встановлення.

Без хеша немає оновлень

Артефакт без integrity ніколи не перевіряється. Раз його файл існує, він зберігається як є, навіть якщо джерело змінилося. Завжди давайте хеш. Файл, який має лишатися, щойно з'явився, каже це через overwrite.

size ​

Розмір у байтах. Він рухає смугу поступу і порядок завантаження. З файлом він не звіряється. Для цього є integrity.

rules ​

Які комп'ютери отримають цей файл. Без нього всі.

json
"rules": "allow.os.windows"

Для нативних бібліотек, JDK під кожну платформу і модів, що працюють лише на деяких системах. Усе про синтаксис на сторінці Правила.

extract ​

Що розпакувати, коли файл уже на місці. Один крок або список кроків, що виконуються по черзі.

Тип архіву береться з імені файла: .tar, .tar.gz і .tgz це tar. Усе інше читається як zip (.jar це zip).

Є три види кроків. Який ви отримаєте, залежить від наявних полів.

Дамп: увесь архів ​

json
{ "into": "${natives_directory}", "clean": true, "excludes": ["META-INF/"] }
ПолеЩо робить
intoТека, куди розпакувати. Обов'язкове.
cleantrue спочатку спорожняє into.
includesЛише ці записи.
excludesПропустити ці. Типово: ["META-INF/"].

Застосування: нативні бібліотеки, перевизначення файлів модпака.

Сканування: записи, що збігаються ​

json
{ "matches": "*", "into": "${java_runtime_dir}/jdk-21", "strip": ["*/"] }
ПолеЩо робить
matchesЯкі записи брати. Обов'язкове.
intoТека, куди розпакувати. Обов'язкове.
includesДодаткові шаблони. Запис береться, якщо збігається будь-який.
excludesПропустити ці.
stripПрибрати початкову частину імені кожного запису.

strip: ["*/"] відкидає верхню теку архіву, як би вона не звалася. Верхня тека архіву JDK несе номер збирання, тож саме так плагін java розпаковує його.

Застосування: архів з текою-обгорткою, яка вам не потрібна.

Вибір: один файл ​

json
{ "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, конфіг, який він редагує, список серверів, який він доповнює.

json
{
  "path": "${game_directory}/options.txt",
  "source": { "blob": "3d862eef…" },
  "overwrite": "never"
}
  • Те, що встановлюється, усе одно перевіряється. overwrite нічого не каже про байти: завантаження звіряється з integrity, а блоб зі своїм ім'ям, як і будь-який інший.
  • Будь-яке джерело. І файл у бандлі, і завантаження. Файл у бандлі завжди має хеш свого блоба, тож "never" це єдиний спосіб його зберегти.
  • Не разом з extract. Архів розпаковується при кожному встановленні, тож його файли не можна лишити гравцю. "never" з extract відхиляється.
  • Невідоме значення відхиляється.
  • cleanup цей файл ніколи не видаляє: це власний файл маніфесту.

metadata ​

Будь-яке значення JSON. Встановлювач його ніколи не читає. Плагіни використовують його для власних нотаток.