@opys/runtime
Частина opys, потрібна лаунчеру. Вона бере бандл, встановлює те, що бандл перелічує, і запускає гру. Вона нічого не збирає: ні конфігурації, ні плагінів.
npm install @opys/runtimeПотрібен Node.js 20 або новіший.
Приклад
import { launch, RuntimeError } from '@opys/runtime';
try {
const child = await launch(
{ url: 'https://example.com/packs/game.opys' },
{
vars: {
root: '/home/player/.local/share/my-pack',
username: 'Player',
uuid: '00000000-0000-0000-0000-000000000001',
token: '0',
},
install: {
onProgress(p) {
if (p.phase === 'download')
console.log(`${p.fetched}/${p.total} files`);
},
},
},
);
child.on('exit', (code) => console.log('the game exited with', code));
} catch (err) {
if (err instanceof RuntimeError) console.error(`${err.code}: ${err.message}`);
else throw err;
}Функції
| Функція | Встановлює | Запускає гру | Повертає |
|---|---|---|---|
install(source, options?) | так | ні | нічого |
launch(source, options?) | так | так | ChildProcess |
prepare(source, options?) | так | ні | LaunchSpec |
buildLaunch(source, options?) | ні | ні | LaunchSpec |
spawnLaunch(spec) | ні | так | ChildProcess |
readHead(source) | ні | ні | Head |
currentPlatform() | OsOptions |
launch це prepare, а потім spawnLaunch. Використовуйте ці дві самі, щоб змінити те, що запускається, або запустити по-своєму.
readHead потрібна для екрана налаштувань. Вона повертає те, що бандл каже про себе, { format, options }, а options це те, що може обрати гравець. Читається лише заголовок: бандл за URL не завантажується, тільки його перші байти.
Звідки береться збірка
Перший аргумент кожної функції.
| Джерело | Що це |
|---|---|
{ url } | Бандл на сервері, читається частинами. |
{ bundle } | Шлях бандла на диску. |
{ manifest } | Маніфест у пам'яті. Він не везе файлів, лише завантажує їх. |
{ url } не завантажується цілком. Читаються його каталог і маніфест, кілька сотень кілобайтів, а далі лише ті перевезені файли, яких бракує встановленню, тож запуск без нового коштує не більше. Кожен запит після першого прив'язано до тієї самої версії файла через If-Range: бандл, замінений посеред встановлення, завершується NetworkError, а не встановлює половину кожного. Від сервера, що не віддає діапазонів або не називає версії файла, бандл завантажується цілком.
Параметри
| Параметр | Де | Що робить |
|---|---|---|
vars | усюди | Значення для змінних бандла. |
features | усюди | Перемикачі на кшталт java_console. |
platform | усюди | Встановити для іншої ОС чи ЦП. Типово: цієї. |
cwd | launch, prepare | Перекриває робочу теку. |
install | launch, prepare | Параметри встановлення або false, щоб пропустити встановлення. |
onProgress | install | Колбек прогресу. |
concurrency | install | Паралельні завантаження. Типово 8. |
verifyIntegrity | install | false пропускає перевірки хешів. Лишіть увімкненим. |
Усе, що належить комп'ютеру гравця, таке як root, передається як vars. Бандл не тримає нічого з цього.
Завжди передавайте root. Нічого не записується і не видаляється поза ним, і ваше значення перемагає значення бандла. Бандл, який називає шлях деінде, відхиляється до будь-чого завантаженого, з кодом manifest.
Що повертається
LaunchSpec
Що запустити, з усіма заповненими змінними.
| Поле | Тип | Що це |
|---|---|---|
command | string | Програма. |
args | string[] | Її аргументи, для цього комп'ютера. |
workdir | string | Тека, у якій її запустити. |
envs | Record<string, string> | Змінні середовища для додання. |
Прогрес
onProgress викликається з одним із цих. Розрізняйте їх за phase.
phase | Також має | Коли |
|---|---|---|
resolve | Бандл читається. | |
download | fetched, total, skipped, bytes, totalBytes | Після кожного файла. Підсумки. |
download:start | path, totalBytes | Один файл починається. |
download:bytes | path, bytes | Один файл отримав ще. |
download:done | path | Один файл завершився. |
verify | Хеші перевіряються. | |
extract | count | Архіви розпаковуються. |
cleanup | removed, directories | Застарілі файли видалено. |
totalBytes це сума розмірів, які оголошує бандл. Він дорівнює 0 для файла, переліченого без розміру.
Помилки
Кожна невдача це RuntimeError з code. Вирішуйте за кодом, ніколи за повідомленням.
code | Клас | Також має | Що сталося |
|---|---|---|---|
network | NetworkError | url, status, body | Не вдалося завантаження. |
integrity | IntegrityError | paths | Файл не збігся зі своїм хешем. |
extraction | ExtractionError | artifactPath, cause | Не вдалося розпакувати архів. |
manifest | RuntimeError | Бандл неправильний або нечитабельний. | |
io | RuntimeError | Не вдалося записати файл. | |
cancelled | RuntimeError | Встановлення зупинено. | |
other | RuntimeError | Усе інше. |
Кожна функція
Кожна функція, у кожному способі використання.
const source = { bundle: './game.opys' };
const vars = { root: '/games/pack', username: 'Player', uuid: '0000…', token: '0' };
// лише встановлення
await install(source, { vars });
await install(source, { vars, features: ['java_console'], concurrency: 16 });
await install(source, { vars, platform: { name: 'windows', version: '10.0', arch: 'x86_64' } });
await install({ url: 'https://example.com/game.opys' }, { vars, onProgress: (p) => console.log(p.phase) });
// встановити і запустити
const child = await launch(source, { vars });
await launch(source, { vars, install: false }); // уже встановлено
await launch(source, { vars, cwd: '/games/pack/saves' }); // інша робоча тека
await launch(source, { vars, install: { concurrency: 4 } });
// встановити, а потім запустити самим
const spec = await prepare(source, { vars });
// { command: '/games/pack/runtimes/jdk-21/bin/java', args: [...], workdir: '/games/pack/', envs: { JAVA_HOME: '…' } }
spawnLaunch({ ...spec, args: ['-Xmx8G', ...spec.args] });
// що було б запущено, без нічого встановленого
await buildLaunch(source, { vars });
// що може обрати гравець, до будь-якого встановлення
const head = await readHead({ url: 'https://example.com/game.opys' });
// { format: 1, options: [{ slider: 'xmx', title: 'RAM', min: 2048, max: 16384, step: 512, default: 4096 }] }
await readHead({ manifest }); // undefined: маніфест у пам'яті не лежить у бандлі
// маніфест у пам'яті: добре, доки він не везе файлів
await install({ manifest: { vars: {}, artifacts: [] } });
currentPlatform(); // { name: 'linux', version: '', arch: 'x86_64' }Документація
- Інтеграція лаунчера: лаунчер крок за кроком
@opys/bundle: файл, з якого він встановлює
Частина opys.