All checks were successful
ITERATION 6 (single-VM rewrite):
- RobloxLuaSharedWorker: один wasmoon-state на 742 скрипта (не 742 VM)
- Pre-populated Workspace + Player.PlayerGui перед addScripts
- На каждом Part — Touched/TouchEnded сигналы; на каждом TextButton —
MouseButton1Click/Activated/MouseEnter/Leave; Humanoid с Died/Health
- Двухфазный init: addScriptsBatch ВСЕ скрипты → kickoff() с PlayerAdded
- wait()/task.wait/task.spawn/task.delay через scheduler+coroutines
- guiClick от Rublox-GUI → fireEvent → инстанс.MouseButton1Click.Fire()
- playerTouch → part.Touched.Fire(HumanoidRootPart) + humanoid.Touched
ITERATION 7 (nullStub compatibility):
- debug.setmetatable(nil, ...) + debug.setmetatable(function() end, ...)
с полным набором __index/__newindex/__call/__add/__sub/.../__len/__concat
- Возврат undefined из FindFirstChild/WaitForChild (вместо JS proxy)
- Lua-side __null_stub_singleton с Connect/connect/Wait/Fire (lowercase aliases)
- __rbxl_lookup_part через __rbxl_parts_by_id table (не ipairs на JS array)
- script.Parent гарантированно не nil (либо реальный Part либо null stub)
- RbxSignal: Connect+connect, Wait+wait, Fire+fire, Disconnect+disconnect
- SIGNAL_NAMES whitelist расширен: Tool (Selected/Equipped), Remote (OnInvoke),
ChatMakeSystemMessage, etc.
Converter:
- GUI: UDim2 dataclass правильно резолвится (scale*100 + offset/viewport*100)
- размеры в процентах (как Rublox-GuiOverlay ожидает)
- ScreenGui.Enabled → пропагируется в детей
- Эвристика скрыть HD Admin/Chat/CommandBar/TeleportTo модалки
- rbxasset:// rbxassetid:// фильтруются на пустой URL
Hierarchy:
- scroll-to-selected раскрывает workspace+rootPrims+folders перед scroll
- data-sel-id на всех ItemRow с rAF×2 timing
Известные ограничения:
- Synapse X obfuscated скрипты часто всё равно падают (требуют конкретный Roblox-VM)
- но debug.setmetatable перехват не даёт скриптам валиться на indexing/arithmetic
- реальные пользовательские KillBrick (Touched) теперь работают
- GUI кнопки → MouseButton1Click работают
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
rbxl-importer
Конвертер Roblox .rbxl карт в проекты Rublox. Состоит из:
- Python-парсер Roblox Binary Level формата (v0+)
- Asset downloader с дедупликацией (Marfusha proxy +
.ROBLOSECURITYcookie) - Mesh→GLB конвертер (Roblox
.meshv1-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-тесты
Поток импорта
- Юзер (МИН) загружает
.rbxlчерез модалку в студии. - POST
/import/rbxl/analyze→ парсер, отчёт, preview_hash в Redis. - Юзер видит: число объектов, скриптов, ассетов, классов.
- POST
/import/rbxl/createс title:- Парсим → конвертим RobloxModel → project_data.
- Скачиваем все
rbxassetid://ассеты (mesh/texture/sound). - Mesh → GLB через mesh_converter.
- INSERT в
kubikon3d_projects(status=draft, is_test=true).
- Редирект на
/edit/<project_id>— открывается в студии. - Если есть Lua-скрипты (
kind: 'roblox-lua') — плеер запускает их черезRobloxLuaSandbox(wasmoon).
Запуск (на VM 130)
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-аккаунта МИНа |
Тестовый импорт
# 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 года). Используется
.ROBLOSECURITYcookie аккаунта МИНа. - GUI (ScreenGui, Frame, TextLabel) пока пропускается в конвертере (skipped).
- Animation/KeyframeSequence требуют отдельной обработки.
- CSG: parsing есть, но конверт в GLB не реализован — пока деградация в bbox cube.
- Terrain (voxel) — конвертация в
robloxTerrainполе пока заглушка.
Авторские права
Эта тест-фича для МИНа только. Юзер подтверждает право использовать содержимое карты при загрузке. Не открывать для публичных пользователей без юр-проверки.