3 блокера перед запуском opensource-контрибьюторов: 1. CI Lint+Format убран format:check (отдельная формат-неделя). Secret-scan переехал с docker run на нативный trufflehog install. 2. Ассеты (106 МБ kubikon-assets/) в Gitea Releases: https://git.rublox.pro/rublox/player/releases/tag/assets-v1 npm run fetch-assets + postinstall. 3. PlayerAuth поддерживает ?standalone=1 URL-параметр (раньше только через VITE_STANDALONE в .env).
81 lines
2.8 KiB
JavaScript
81 lines
2.8 KiB
JavaScript
#!/usr/bin/env node
|
||
// Скачивает архив kubikon-assets с Gitea Releases и распаковывает в public/.
|
||
// Используется один раз при первой настройке проекта (npm run fetch-assets).
|
||
//
|
||
// Архив весит ~43МБ, содержит модели (.glb), текстуры (.png) и скины.
|
||
// В Git они НЕ лежат — занимают много места и редко меняются.
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
const https = require('https');
|
||
const { execSync } = require('child_process');
|
||
|
||
const RELEASE_URL =
|
||
'https://git.rublox.pro/rublox/player/releases/download/assets-v1/kubikon-assets.tar.gz';
|
||
const PUBLIC_DIR = path.join(__dirname, '..', 'public');
|
||
const TARGET_DIR = path.join(PUBLIC_DIR, 'kubikon-assets');
|
||
const TMP_TAR = path.join(PUBLIC_DIR, '_assets-tmp.tar.gz');
|
||
|
||
function download(url, dest) {
|
||
return new Promise((resolve, reject) => {
|
||
const file = fs.createWriteStream(dest);
|
||
https
|
||
.get(url, (res) => {
|
||
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
||
file.close();
|
||
fs.unlinkSync(dest);
|
||
return download(res.headers.location, dest).then(resolve, reject);
|
||
}
|
||
if (res.statusCode !== 200) {
|
||
file.close();
|
||
fs.unlinkSync(dest);
|
||
return reject(new Error(`HTTP ${res.statusCode} от ${url}`));
|
||
}
|
||
const total = parseInt(res.headers['content-length'] || '0', 10);
|
||
let received = 0;
|
||
let lastPct = -1;
|
||
res.on('data', (chunk) => {
|
||
received += chunk.length;
|
||
if (total) {
|
||
const pct = Math.floor((received / total) * 100);
|
||
if (pct !== lastPct && pct % 5 === 0) {
|
||
process.stdout.write(`\rСкачивание: ${pct}% (${(received / 1024 / 1024).toFixed(1)} МБ)`);
|
||
lastPct = pct;
|
||
}
|
||
}
|
||
});
|
||
res.pipe(file);
|
||
file.on('finish', () => {
|
||
process.stdout.write('\n');
|
||
file.close(resolve);
|
||
});
|
||
})
|
||
.on('error', (err) => {
|
||
file.close();
|
||
fs.unlinkSync(dest);
|
||
reject(err);
|
||
});
|
||
});
|
||
}
|
||
|
||
async function main() {
|
||
if (fs.existsSync(TARGET_DIR) && fs.readdirSync(TARGET_DIR).length > 0) {
|
||
console.log('kubikon-assets/ уже существует. Удали папку чтобы перекачать.');
|
||
process.exit(0);
|
||
}
|
||
|
||
console.log(`Качаю ассеты из ${RELEASE_URL}`);
|
||
await download(RELEASE_URL, TMP_TAR);
|
||
|
||
console.log('Распаковка...');
|
||
execSync(`tar -xzf "${TMP_TAR}" -C "${PUBLIC_DIR}"`, { stdio: 'inherit' });
|
||
fs.unlinkSync(TMP_TAR);
|
||
|
||
console.log('Готово! Ассеты в public/kubikon-assets/');
|
||
}
|
||
|
||
main().catch((err) => {
|
||
console.error('Ошибка:', err.message);
|
||
process.exit(1);
|
||
});
|