Skip to content

@opys/runtime ​

npm

Частина opys, потрібна лаунчеру. Вона бере бандл, встановлює те, що бандл перелічує, і запускає гру. Вона нічого не збирає: ні конфігурації, ні плагінів.

sh
npm install @opys/runtime

Потрібен Node.js 20 або новіший.

Приклад ​

js
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усюдиВстановити для іншої ОС чи ЦП. Типово: цієї.
cwdlaunch, prepareПерекриває робочу теку.
installlaunch, prepareПараметри встановлення або false, щоб пропустити встановлення.
onProgressinstallКолбек прогресу.
concurrencyinstallПаралельні завантаження. Типово 8.
verifyIntegrityinstallfalse пропускає перевірки хешів. Лишіть увімкненим.

Усе, що належить комп'ютеру гравця, таке як root, передається як vars. Бандл не тримає нічого з цього.

Завжди передавайте root. Нічого не записується і не видаляється поза ним, і ваше значення перемагає значення бандла. Бандл, який називає шлях деінде, відхиляється до будь-чого завантаженого, з кодом manifest.

Що повертається ​

LaunchSpec ​

Що запустити, з усіма заповненими змінними.

ПолеТипЩо це
commandstringПрограма.
argsstring[]Її аргументи, для цього комп'ютера.
workdirstringТека, у якій її запустити.
envsRecord<string, string>Змінні середовища для додання.

Прогрес ​

onProgress викликається з одним із цих. Розрізняйте їх за phase.

phaseТакож маєКоли
resolveБандл читається.
downloadfetched, total, skipped, bytes, totalBytesПісля кожного файла. Підсумки.
download:startpath, totalBytesОдин файл починається.
download:bytespath, bytesОдин файл отримав ще.
download:donepathОдин файл завершився.
verifyХеші перевіряються.
extractcountАрхіви розпаковуються.
cleanupremoved, directoriesЗастарілі файли видалено.

totalBytes це сума розмірів, які оголошує бандл. Він дорівнює 0 для файла, переліченого без розміру.

Помилки ​

Кожна невдача це RuntimeError з code. Вирішуйте за кодом, ніколи за повідомленням.

codeКласТакож маєЩо сталося
networkNetworkErrorurl, status, bodyНе вдалося завантаження.
integrityIntegrityErrorpathsФайл не збігся зі своїм хешем.
extractionExtractionErrorartifactPath, causeНе вдалося розпакувати архів.
manifestRuntimeErrorБандл неправильний або нечитабельний.
ioRuntimeErrorНе вдалося записати файл.
cancelledRuntimeErrorВстановлення зупинено.
otherRuntimeErrorУсе інше.

Кожна функція ​

Кожна функція, у кожному способі використання.

js
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.