All checks were successful
Тест-фича для МИНа. Полное описание в rbxl-importer/INFO_PROCESS.md. Backend (rbxl-importer/ на VM 130 S1): - Python-парсер Roblox Binary (28+ типов значений) - Asset downloader через Marfusha proxy + .ROBLOSECURITY cookie - Mesh→GLB конвертер (v1-v5) - Converter Roblox-классов → project_data - Flask API: /analyze + /create Frontend: - API.js + components/RbxlImportModal.jsx (drag-n-drop) Тестовый импорт Easy Obby: project_id 2697, 2244 primitives + 742 lua-scripts + 5 ассетов. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
8.2 KiB
8.2 KiB
rbxl-importer: лог разработки
2026-06-07
Фаза 0. Подготовка (✓)
- Освобождено место на S1: удалён
pve/dataLV (+133 GB), VM 111/112/114/116 (+285 GB). Свободно стало 419 GB в VGpve. - Создана VM 130 rbxl-importer (IP 192.168.1.130, Ubuntu 22.04, 4 vCPU, 4 GB RAM, 200 GB).
- Установлены: Docker, Python 3.11+venv, nginx, postgresql-client.
- Клонированы studio-rbxl-import и player-rbxl-import worktree, ветка
feat/rbxl-import. - Smoke-test парсера на
Escape Easy Obby Parkour Uncopylocked.rbxl(8205 instances, 120 классов).
Фаза 1. Парсер .rbxl (✓)
- Реализованы файлы:
rbxl_binreader.py,rbxl_types.py,rbxl_parser.py. - Декодирование 28+ Roblox PROP типов: String, Bool, Int32, Float, Double, UDim, UDim2, Ray, Faces, Axes, BrickColor, Color3, Vector2, Vector3, CFrame, Quaternion, Enum, Referent, Vector3int16, NumberSequence, ColorSequence, NumberRange, Rect, PhysicalProperties, Color3uint8, Int64, SharedString, Bytecode, OptionalCFrame, UniqueId, Font.
- Особенности формата покрыты: interleaved-transformed массивы, zigzag для signed int, Roblox float encoding, LZ4 chunks.
- Протестировано на 6 файлах: 0 warnings:
easy_obby.rbxl(Easy Obby Parkour, 437 KB, 8205 instances)miners-haven.rbxl(Miners Haven, 8 MB, 60950 instances)- 4 synthetic из
rojo-rbx/rbx-dom/benches/files/
Фаза 2. Asset pipeline (✓)
- БД: миграция
001_roblox_assets.sql(3 таблицы) применена вstorys_db(S2 primary через autossh туннель S1 PVE 192.168.1.152:25435). asset_downloader.py: дедупликация поrbx_asset_id+ sha256, retry с backoff, классификация по content-type/magic bytes.asset_proxy.py: режимыdisabled/direct/http_proxy/cloudflare_worker. Используетсяhttp_proxyчерез Marfusha xray (85.192.61.244:39237).- Cookie auth:
.ROBLOSECURITYот аккаунтаminkorenovsk2сохранён в/home/min/.roblosecurityна VM 130, EnvironmentFile подключен в systemd unit. mesh_converter.py: парсер Roblox.meshv1-v5 + GLB writer (glTF 2.0 binary).- v1.00 ASCII протестирован: 500 facets, 1500 vertices → 54900 байт GLB.
- v2-v5 binary — написаны, проверим на реальных файлах.
nginxна VM 130:/opt/roblox-assets/отдаётся какhttps://assets.rublox.pro/roblox/...с CORS.
Фаза 3. Конвертер геометрии (✓)
converter.py: маппинг 30+ Roblox-классов → Rubloxproject_data.Part,WedgePart,CornerWedgePart,TrussPart→ primitives (cube/wedge/cornerwedge).MeshPart,UnionOperation→ glbModels (с fallback на bbox cube).SpawnLocation→ scene.spawnPoint.Lighting→ scene.environment.Sound→ scene.sounds.Script/LocalScript/ModuleScript→ scene.scripts с kind='roblox-lua' и raw lua_source.
- Material enum (Plastic→glossy, Neon→neon, Metal→metal, Glass→glass, ...).
- CFrame → position + Euler XYZ (system axes Roblox = Babylon: right-handed Y-up).
- Scale: 1 Roblox stud = 0.28 м (настраиваемо).
- Easy Obby результат: 2244 primitives + 742 lua-scripts + 5 ассетов (sounds) для скачки.
Фаза 4. Lua-runtime + Roblox API shim (✓)
- wasmoon (Lua 5.4 WASM) интегрирован в
player/studio(npm install). RobloxLuaWorker.js— Worker-хост с инициализацией wasmoon, IPC с main thread.RobloxLuaSandbox.js— main-side обёртка.roblox-shim.js— math классы (Vector3, Color3, CFrame, UDim2), Instance прокси (game, workspace, script, GetService, GetChildren, FindFirstChild, IsA с иерархией классов), Part свойства (Position/CFrame/Size/Color/Material/Anchored/CanCollide/Transparency), RBXScriptSignal (Touched, Heartbeat, Stepped, RenderStepped, Connect, Wait, Disconnect).roblox-scheduler.js— корутины черезcoroutine.create/resume/yield, шедулер для wait/task.wait/task.delay/task.spawn, автоматический fire Heartbeat/Stepped/RenderStepped на каждом tick.roblox-tween.js— TweenService с 10 easing-функциями (Linear, Quad, Cubic, Quart, Quint, Sine, Bounce, Elastic, Back, Exponential) для Vector3/Color3/CFrame/number.roblox-services.js— Players, LocalPlayer, Character, Humanoid (Health, WalkSpeed, JumpPower, TakeDamage, Died), UserInputService, RemoteEvent (FireServer/FireClient/OnServerEvent), RemoteFunction, DataStoreService (GetAsync/SetAsync/IncrementAsync), HttpService (JSONEncode/Decode), ContextActionService stub.roblox-physics.js— BodyVelocity, BodyGyro, BodyPosition, BodyForce, BodyAngularVelocity, AlignPosition, LinearVelocity.
Тесты Lua-runtime: 36/36 ✓
tests/rbxl-lua-mvp.test.js— math + Instance + Part + IsA (9/9)tests/rbxl-lua-wait.test.js— корутины + wait/task.wait/task.delay (5/5)tests/rbxl-lua-tween.test.js— TweenService + Linear easing (2/2)tests/rbxl-lua-services.test.js— Humanoid + DataStore + HttpService + RemoteEvent (8/8)tests/rbxl-lua-integration.test.js— реалистичные obby/simulator снейппеты (12/12): KillBrick, WalkSpeed boost, Tween door, BodyVelocity конвейер, leaderstats, DataStore checkpoint, циклы с wait, task.spawn параллель, Color3 + Material смена, RemoteEvent client→server, Heartbeat счётчик, Vector3 arithmetic.
Фаза 5. Flask API + UI (✓)
src/app.pyFlask:GET /health→ okPOST /import/rbxl/analyze→ парсер + report + preview_hash (Redis 20 мин TTL)POST /import/rbxl/create→ скачка ассетов + конверт mesh→GLB + INSERT в kubikon3d_projects
- Запущен через systemd unit
rbxl-importer.service(Restart=on-failure, EnvironmentFile с cookie). - Redis (Docker
redis-rbxl) для preview cache. studio/src/components/RbxlImportModal.jsx— React компонент с drag-n-drop, отчётом, формой создания. Доступен только МИНу.studio/src/api/rbxlImporterApi.js— клиент.- Тест-результат: Easy Obby импортирован как project_id 2697 (2244 primitives, 742 lua-scripts, 5 ассетов скачано без ошибок).
Фаза 6. Совместимость с плеером + DNS (✓)
GameRuntime.js: добавлен_startRobloxLuaScript()метод и веткаif (s.kind === 'roblox-lua')вstart()._handleRobloxLuaCommand(): маппит IPC команды от Lua-sandbox (partSet, partVel, playerCmd) на PrimitiveManager и game.player API._buildRobloxLuaSceneSnap(): преобразует projectData.scene.primitives → формат для Lua (workspace:GetChildren).- NPM proxy_host на S1 NPM (VM 101 192.168.1.43):
assets.rublox.proиapi-rbxl.rublox.pro→ VM 130:80. - DNS Cloudflare: 2 A-записи (proxied=false) → 85.175.7.40 (S1 публичный IP).
- End-to-end протестировано:
https://api-rbxl.rublox.pro/health→ 200 OK.
Фаза 7. Документация (в работе)
- README.md в rbxl-importer/
- INFO_PROCESS.md (этот файл)
- TODO: commit + PR в Gitea для studio и player worktree.
Известные ограничения
- Lua-runtime пока MVP: нет GUI (ScreenGui/Frame/TextLabel), нет
:Wait()на сигналах через корутины (толькоConnect), нет Animation/KeyframeSequence. - CSG meshes (UnionOperation) парсятся, но конверт в GLB не реализован — bbox cube fallback.
- Terrain voxel grid конвертится в заглушку (плоский ландшафт).
- TouchEvent в плеере не fire'ится автоматически из физики Babylon — нужно добавить collision broadcaster.