# 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/<id>           │     + 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/<project_id>` — открывается в студии.
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":"<from_analyze>", "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` поле пока заглушка.

## Авторские права

Эта тест-фича для **МИНа только**. Юзер подтверждает право использовать содержимое карты при загрузке.
Не открывать для публичных пользователей без юр-проверки.
