Compare commits

..

No commits in common. "cc3eb8d0beeab1aea5e480066706fd7ef768aa17" and "13fa73d77a7a5cc4d1e1df85d4d816a144b07080" have entirely different histories.

4 changed files with 10 additions and 99 deletions

View File

@ -17,7 +17,7 @@ on:
jobs: jobs:
lint: lint:
name: Lint name: Lint + Format
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -25,9 +25,7 @@ jobs:
with: with:
node-version: '18' node-version: '18'
- run: npm ci - run: npm ci
# format:check временно отключён до массового npx prettier --write - run: npm run format:check
# (см. docs/ONBOARDING.md → «Форматирование кода»). После прогона
# верни строку `- run: npm run format:check` перед npm run lint.
- run: npm run lint - run: npm run lint
build: build:
@ -52,16 +50,14 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Install trufflehog
run: |
curl -sSfL https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh \
| sh -s -- -b /usr/local/bin
- name: Run trufflehog - name: Run trufflehog
run: | run: |
trufflehog git "file://$(pwd)" \ docker run --rm -v "$(pwd):/repo" \
trufflesecurity/trufflehog:latest \
git file:///repo \
--only-verified --fail \ --only-verified --fail \
--exclude-paths .trufflehog-ignore 2>&1 | tee scan.log || EXIT=$? --exclude-paths /repo/.trufflehog-ignore 2>&1 | tee scan.log
if [ -n "$EXIT" ] && [ "$EXIT" -ne 0 ]; then if grep -q "Reason:" scan.log; then
echo "::error::Найдены секреты в коммитах! См. лог выше." echo "::error::Найдены секреты в коммитах! См. лог выше."
exit 1 exit 1
fi fi

View File

@ -36,9 +36,7 @@
"preview": "vite preview", "preview": "vite preview",
"lint": "eslint . --ext .js,.jsx --max-warnings 200", "lint": "eslint . --ext .js,.jsx --max-warnings 200",
"format": "prettier --write \"src/**/*.{js,jsx,json,md,css}\"", "format": "prettier --write \"src/**/*.{js,jsx,json,md,css}\"",
"format:check": "prettier --check \"src/**/*.{js,jsx,json,md,css}\"", "format:check": "prettier --check \"src/**/*.{js,jsx,json,md,css}\""
"fetch-assets": "node scripts/fetch-assets.js",
"postinstall": "node scripts/fetch-assets.js"
}, },
"dependencies": { "dependencies": {
"@babylonjs/core": "7.54.3", "@babylonjs/core": "7.54.3",

View File

@ -1,80 +0,0 @@
#!/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);
});

View File

@ -54,12 +54,9 @@ export function PlayerAuthProvider({ children }) {
let cancelled = false; let cancelled = false;
// STANDALONE-режим: пропускаем auth и сразу считаем юзера авторизованным // STANDALONE-режим: пропускаем auth и сразу считаем юзера авторизованным
// под dummy-id 0. Используется для разработки без бэкенда. // под dummy-id 0. Используется для разработки без бэкенда (VITE_STANDALONE=true).
// Включается через VITE_STANDALONE=true или через ?standalone=1 в URL.
const env = (typeof import.meta !== 'undefined' && import.meta.env) || {}; const env = (typeof import.meta !== 'undefined' && import.meta.env) || {};
const urlStandalone = typeof window !== 'undefined' && if (String(env.VITE_STANDALONE).toLowerCase() === 'true') {
new URLSearchParams(window.location.search).get('standalone') === '1';
if (String(env.VITE_STANDALONE).toLowerCase() === 'true' || urlStandalone) {
setState({ setState({
user: { id: 0, firstName: 'Guest', _standalone: true }, user: { id: 0, firstName: 'Guest', _standalone: true },
isAuthenticated: true, isAuthenticated: true,