studio/src/App.jsx
МИН 31adbf151b Initial public release: Студия Рублокса v1.0
Open-source веб-студия для создания игр Рублокса, двойная лицензия
AGPL-3.0 + Коммерческая.

Главное:
- Vite 5 + React 18 + Babylon 7.54.3 + Monaco Editor + Colyseus 0.16
- Самодостаточный движок ~28к строк (66 файлов): BlockManager,
  TerrainVoxelBuilder, ModelManager, DecoManager, PlayerController,
  ScriptSandboxWorker, MultiplayerSync, 30+ GD-гейммодов
- Главный редактор KubikonEditor (~37к строк) + панели, ScriptEditor (Monaco)
- Витрина игр (KubikonFeed, KubikonStudio, KubikonDocs, KubikonLearn)
- Geometry Dash sub-app (GdMenu, GdShop, GdRules, GdCoverArt)
- 10 admin-preview каталогов для дизайнеров (скины, музыка, порталы и т.д.)
- Конфигурируемый бэкенд через VITE_API_BASE — работает со staging
  (dev-api.rublox.pro) без настройки
- Standalone-режим (VITE_STANDALONE=true) — открыть пустой редактор без бэка
- Полная документация (на русском): README, ARCHITECTURE, CONTRIBUTING,
  SECURITY, CHANGELOG
- ESLint + Prettier + EditorConfig
- Legal: LICENSE (AGPL-3.0), LICENSE-COMMERCIAL.md, CLA.md, COPYRIGHT.md
- Issue templates: bug_report, feature_request, security_disclosure

Перед публикацией:
- Все импорты из minecraftia заменены на локальные
- Все хардкоды URL (minecraftia-school.ru) и внутренних IP убраны → env
- Admin-эндпоинты Kubikon3DService вырезаны (остаются в приватном репо)
- AdminKubikonModeration не публикуется (модерация — в team.rublox.pro)
- 93 МБ ассетов public/kubikon-assets вынесены в .gitignore
  (раздаются через release artifact)
2026-05-27 23:41:10 +03:00

95 lines
5.3 KiB
JavaScript

import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { lazy, Suspense } from 'react';
import { AuthProvider } from './auth/AuthContext.jsx';
import { SanctionsProvider } from './auth/SanctionsContext.jsx';
import LoadingScreen from './LoadingScreen.jsx';
// Code-splitting: каждая большая страница в своём чанке.
const KubikonEditor = lazy(() => import('./editor/KubikonEditor.jsx'));
const KubikonPlayer = lazy(() => import('./preview-player/KubikonPlayer.jsx'));
const KubikonFeed = lazy(() => import('./community/KubikonFeed.jsx'));
const KubikonStudio = lazy(() => import('./community/KubikonStudio.jsx'));
const KubikonDocs = lazy(() => import('./community/KubikonDocs.jsx'));
const KubikonRules = lazy(() => import('./community/KubikonRules.jsx'));
const KubikonHeroKit = lazy(() => import('./community/KubikonHeroKit.jsx'));
const KubikonLearn = lazy(() => import('./community/KubikonLearn.jsx'));
const KubikonGamePage = lazy(() => import('./community/KubikonGamePage.jsx'));
const KubikonUserGames = lazy(() => import('./community/KubikonUserGames.jsx'));
const RealtimeTest = lazy(() => import('./community/RealtimeTest.jsx'));
// Geometry Dash sub-app
const GdShop = lazy(() => import('./gd-shop/GdShop.jsx'));
const GdMenu = lazy(() => import('./gd-shop/GdMenu.jsx'));
const GdRules = lazy(() => import('./gd-shop/GdRules.jsx'));
const GdCoverArt = lazy(() => import('./gd-shop/GdCoverArt.jsx'));
const GdPlayWrapper = lazy(() => import('./gd-shop/GdPlayWrapper.jsx'));
// Превью-роуты для команды дизайнеров (закрытые в проде по роли,
// в opensource доступны всем — это просто галереи ассетов).
const GdBossesPreview = lazy(() => import('./admin-preview/GdBossesPreview.jsx'));
const GdSkinsPreview = lazy(() => import('./admin-preview/GdSkinsPreview.jsx'));
const GdSpikesPreview = lazy(() => import('./admin-preview/GdSpikesPreview.jsx'));
const GdArchesPreview = lazy(() => import('./admin-preview/GdArchesPreview.jsx'));
const GdFinishesPreview = lazy(() => import('./admin-preview/GdFinishesPreview.jsx'));
const GdPortalsPreview = lazy(() => import('./admin-preview/GdPortalsPreview.jsx'));
const GdMusicPreview = lazy(() => import('./admin-preview/GdMusicPreview.jsx'));
const GdSfxPreview = lazy(() => import('./admin-preview/GdSfxPreview.jsx'));
const GdShipSkinsPreview = lazy(() => import('./admin-preview/GdShipSkinsPreview.jsx'));
const GdDecoPreview = lazy(() => import('./admin-preview/GdDecoPreview.jsx'));
function FallbackLoader() {
return <LoadingScreen text="Загружаю модуль студии..." />;
}
export default function App() {
return (
<BrowserRouter>
<AuthProvider>
<SanctionsProvider>
<Suspense fallback={<FallbackLoader />}>
<Routes>
{/* Редактор и плеер (fullscreen) */}
<Route path="/edit/:id" element={<KubikonEditor />} />
<Route path="/play/:id" element={<KubikonPlayer />} />
<Route path="/game/:id" element={<KubikonGamePage />} />
{/* Лента, профиль, доки */}
<Route path="/" element={<KubikonStudio />} />
<Route path="/feed" element={<KubikonFeed />} />
<Route path="/docs" element={<KubikonDocs />} />
<Route path="/rules" element={<KubikonRules />} />
<Route path="/hero-kit" element={<KubikonHeroKit />} />
<Route path="/learn" element={<KubikonLearn />} />
<Route path="/learn/:articleId" element={<KubikonLearn />} />
<Route path="/user/:userId" element={<KubikonUserGames />} />
<Route path="/realtime-test" element={<RealtimeTest />} />
{/* Geometry Dash */}
<Route path="/gd" element={<GdMenu />} />
<Route path="/gd/shop" element={<GdShop />} />
<Route path="/gd/rules" element={<GdRules />} />
<Route path="/gd/cover-art" element={<GdCoverArt />} />
<Route path="/gd/play/:id" element={<GdPlayWrapper />} />
{/* Каталоги ассетов (для дизайнеров) */}
<Route path="/preview/gd/bosses" element={<GdBossesPreview />} />
<Route path="/preview/gd/skins" element={<GdSkinsPreview />} />
<Route path="/preview/gd/spikes" element={<GdSpikesPreview />} />
<Route path="/preview/gd/arches" element={<GdArchesPreview />} />
<Route path="/preview/gd/finishes" element={<GdFinishesPreview />} />
<Route path="/preview/gd/portals" element={<GdPortalsPreview />} />
<Route path="/preview/gd/music" element={<GdMusicPreview />} />
<Route path="/preview/gd/sfx" element={<GdSfxPreview />} />
<Route path="/preview/gd/ship-skins" element={<GdShipSkinsPreview />} />
<Route path="/preview/gd/deco" element={<GdDecoPreview />} />
{/* 404 → главная */}
<Route path="*" element={<KubikonStudio />} />
</Routes>
</Suspense>
</SanctionsProvider>
</AuthProvider>
</BrowserRouter>
);
}