# rbxl-importer Конвертер Roblox `.rbxl` карт в проекты Rublox. Состоит из: - **Python-парсер** Roblox Binary Level формата (v0+) - **Asset downloader** с дедупликацией (Marfusha proxy + `.ROBLOSECURITY` cookie) - **Mesh→GLB конвертер** (Roblox `.mesh` v1-v5) - **Roblox-LUA runtime** (wasmoon, реализован в репо `rublox/player`) - **Flask API** + **React UI модалка** в `rublox/studio` ## Архитектура ``` [Студия] [VM 130 rbxl-importer S1] user drops .rbxl ┌─────────────────────────────┐ ↓ │ Flask (port 8690) │ POST /api-rbxl/... ─────────┤ ├ analyze: parser + report│ ↓ │ └ create: parser + конверт│ redirect /edit/ │ + asset_downloader │ │ + mesh→glb │ │ │ │ Redis (preview cache) │ │ nginx (assets.rublox.pro) │ │ /opt/roblox-assets/ │ └─────────────────────────────┘ ↓ [Marfusha proxy 85.192.61.244:39237] ↓ Roblox CDN (assetdelivery.roblox.com) ↓ Ассеты ← .ROBLOSECURITY cookie auth ``` ## Структура ``` rbxl-importer/ src/ rbxl_binreader.py — низкоуровневое чтение (deinterleave, zigzag, roblox float) rbxl_types.py — декодеры 28+ PROP типов (Vector3, CFrame, Color3, ...) rbxl_parser.py — парсер chunks → RobloxModel converter.py — RobloxModel → Rublox project_data asset_downloader.py — скачка с Roblox CDN, дедуп через roblox_assets asset_proxy.py — режимы proxy: disabled/direct/http_proxy/cloudflare_worker mesh_converter.py — Roblox .mesh v1-v5 → GLB app.py — Flask endpoints sql/ 001_roblox_assets.sql — таблицы roblox_assets, roblox_asset_usage, roblox_imports reference_files/ — тестовые .rbxl tests/ — unit-тесты ``` ## Поток импорта 1. Юзер (МИН) загружает `.rbxl` через модалку в студии. 2. POST `/import/rbxl/analyze` → парсер, отчёт, preview_hash в Redis. 3. Юзер видит: число объектов, скриптов, ассетов, классов. 4. POST `/import/rbxl/create` с title: - Парсим → конвертим RobloxModel → project_data. - Скачиваем все `rbxassetid://` ассеты (mesh/texture/sound). - Mesh → GLB через mesh_converter. - INSERT в `kubikon3d_projects` (status=draft, is_test=true). 5. Редирект на `/edit/` — открывается в студии. 6. Если есть Lua-скрипты (`kind: 'roblox-lua'`) — плеер запускает их через `RobloxLuaSandbox` (wasmoon). ## Запуск (на VM 130) ```bash systemctl start rbxl-importer systemctl status rbxl-importer # логи: journalctl -u rbxl-importer -f ``` ## ENV | Переменная | Значение | |---|---| | `PG_DSN` | DSN Postgres storys_db (через autossh туннель S1→S2) | | `REDIS_URL` | `redis://127.0.0.1:6379/0` (локальный Docker) | | `STORAGE_ROOT` | `/opt/roblox-assets` | | `PUBLIC_ASSET_BASE` | `https://assets.rublox.pro/roblox` | | `ROBLOX_PROXY_MODE` | `http_proxy` | | `ROBLOX_HTTP_PROXY` | Marfusha xray HTTP proxy | | `ROBLOX_SECURITY_COOKIE` | `.ROBLOSECURITY` от Roblox-аккаунта МИНа | ## Тестовый импорт ```bash # analyze (file=Easy Obby) curl -X POST -H "X-Auth-Override: 1" \ -F "file=@reference_files/easy_obby.rbxl" \ http://localhost:8690/import/rbxl/analyze # create curl -X POST -H "X-Auth-Override: 1" -H "Content-Type: application/json" \ -d '{"preview_hash":"", "title":"Easy Obby"}' \ http://localhost:8690/import/rbxl/create ``` ## Ограничения / TODO - **Roblox auth обязателен** для большинства ассетов (с 2024 года). Используется `.ROBLOSECURITY` cookie аккаунта МИНа. - **GUI** (ScreenGui, Frame, TextLabel) пока пропускается в конвертере (skipped). - **Animation/KeyframeSequence** требуют отдельной обработки. - **CSG**: parsing есть, но конверт в GLB не реализован — пока деградация в bbox cube. - **Terrain (voxel)** — конвертация в `robloxTerrain` поле пока заглушка. ## Авторские права Эта тест-фича для **МИНа только**. Юзер подтверждает право использовать содержимое карты при загрузке. Не открывать для публичных пользователей без юр-проверки.