93 lines
3.4 KiB
JavaScript
93 lines
3.4 KiB
JavaScript
#!/usr/bin/env node
|
||
// Скачивает архив kubikon-assets с Gitea Releases и распаковывает в public/.
|
||
// Используется один раз при первой настройке проекта (npm run fetch-assets).
|
||
//
|
||
// Архив весит ~43МБ, содержит модели (.glb), текстуры (.png) и скины.
|
||
// В Git они НЕ лежат — занимают много места и редко меняются.
|
||
//
|
||
// ES-модуль (в package.json "type": "module").
|
||
|
||
import fs from 'node:fs';
|
||
import path from 'node:path';
|
||
import https from 'node:https';
|
||
import { execSync } from 'node:child_process';
|
||
import { fileURLToPath } from 'node:url';
|
||
|
||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||
|
||
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('Распаковка...');
|
||
// На Windows используем native tar.exe из System32 — Git Bash-овский
|
||
// BSD-tar ломается на путях с двоеточием (`C:` интерпретируется как
|
||
// ssh-хост). На *nix просто `tar` в $PATH.
|
||
const tarBin =
|
||
process.platform === 'win32' && fs.existsSync('C:\\Windows\\System32\\tar.exe')
|
||
? 'C:\\Windows\\System32\\tar.exe'
|
||
: 'tar';
|
||
execSync(`"${tarBin}" -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);
|
||
});
|