From 16223e06ef94b0ca2d33083b207c10d9a3f05653 Mon Sep 17 00:00:00 2001 From: min Date: Mon, 8 Jun 2026 21:20:01 +0300 Subject: [PATCH] =?UTF-8?q?feat(rbxl):=20=D0=B2=D1=8B=D0=B1=D0=BE=D1=80=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B6=D0=B8=D0=BC=D0=B0=20=D1=81=D0=BA=D1=80=D0=B8?= =?UTF-8?q?=D0=BF=D1=82=D0=BE=D0=B2=20=D0=B2=20=D0=BC=D0=BE=D0=B4=D0=B0?= =?UTF-8?q?=D0=BB=D0=BA=D0=B5=20=D0=B8=D0=BC=D0=BF=D0=BE=D1=80=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 3 опции в модалке (только если в карте есть скрипты): - 'disabled' (default) — скрипты импортируются с enabled=false в метадате → GameRuntime их не запускает, но видны в иерархии для чтения как референс при написании своих Lua-скриптов. - 'enabled' — скрипты активны (старое поведение). Может вешать игру на старых Roblox 2007-2010 паттернах. - 'skip' — scripts[] обнуляется, чистый импорт только геометрии. Реализация: - RbxlImportModal.jsx: state scriptsMode + radio-блок над названием игры, показывается только если report.scripts_total > 0. - rbxlImporterApi.js: передача scripts_mode в /import/rbxl/create. - app.py: _apply_scripts_mode() патчит JSON-метадату на 2-й строке packed-кода скрипта (или удаляет scripts[] для 'skip'). GameRuntime уже умеет уважать meta.enabled === false — пропускает скрипт. Deploy app.py на VM 130. --- .../src/__pycache__/app.cpython-314.pyc | Bin 0 -> 20714 bytes rbxl-importer/src/app.py | 51 +++++++++++++++ src/api/rbxlImporterApi.js | 11 +++- src/components/RbxlImportModal.jsx | 58 +++++++++++++++++- 4 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 rbxl-importer/src/__pycache__/app.cpython-314.pyc diff --git a/rbxl-importer/src/__pycache__/app.cpython-314.pyc b/rbxl-importer/src/__pycache__/app.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2b0e39132649d95abbdf2652cd99cd3e0d88217c GIT binary patch literal 20714 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 Ud0)QxR&zmLuK2&_O2Pks0f0WFPyhe` literal 0 HcmV?d00001 diff --git a/rbxl-importer/src/app.py b/rbxl-importer/src/app.py index b9788db..4e31893 100644 --- a/rbxl-importer/src/app.py +++ b/rbxl-importer/src/app.py @@ -210,6 +210,12 @@ def create(): data = request.get_json(silent=True) or {} preview_hash = data.get('preview_hash') title = (data.get('title') or '').strip() or 'Импортировано из Roblox' + # scripts_mode: 'disabled' (default) — оставить в проекте, но enabled=False + # 'enabled' — попытаться запустить, может вешать + # 'skip' — не импортировать совсем + scripts_mode = data.get('scripts_mode', 'disabled') + if scripts_mode not in ('disabled', 'enabled', 'skip'): + scripts_mode = 'disabled' if not preview_hash: return jsonify({'error': 'preview_hash required'}), 400 @@ -274,6 +280,10 @@ def create(): # Подставляем URLs в project_data _resolve_asset_urls(project_data, asset_url_map) + # Применяем scripts_mode: меняем поле enabled в метадате каждого скрипта + # либо удаляем все скрипты полностью. + _apply_scripts_mode(project_data, scripts_mode) + # Создаём проект в kubikon3d_projects # Используем bridge на user-service / storys API, ИЛИ напрямую в storys_db. # Прямой INSERT — проще для MVP. id автогенерируется. @@ -335,5 +345,46 @@ def _resolve_asset_urls(project_data: dict, asset_map: dict) -> None: snd['url'] = asset_map[rid] +def _apply_scripts_mode(project_data: dict, mode: str) -> None: + """Применяет режим scripts_mode к проекту. + + mode='disabled' (default): для каждого скрипта меняем JSON-метадату + на 2-й строке packed-кода — выставляем enabled=False. GameRuntime + уже умеет уважать этот флаг и не запускает. + mode='enabled': оставляем как было (как пришло из конвертера). + mode='skip': удаляем все scripts из scene.scripts полностью. + """ + scene = project_data.get('scene', {}) + scripts = scene.get('scripts', []) + if not scripts: + return + + if mode == 'skip': + scene['scripts'] = [] + return + + if mode == 'enabled': + return # ничего не делаем + + # mode == 'disabled' — патчим метадату каждого скрипта. + # Формат packed-кода (см. converter._convert_script): + # "// @roblox-lua\n// {JSON}\n/* lua_source:\n...source...\n*/\n" + for s in scripts: + code = s.get('code', '') + lines = code.split('\n', 2) + if len(lines) < 2 or not lines[0].startswith('// @roblox-lua'): + continue + meta_line = lines[1] + if not meta_line.startswith('// '): + continue + try: + meta = json.loads(meta_line[3:]) + meta['enabled'] = False + new_meta_line = '// ' + json.dumps(meta, ensure_ascii=False) + s['code'] = lines[0] + '\n' + new_meta_line + '\n' + (lines[2] if len(lines) > 2 else '') + except (json.JSONDecodeError, ValueError): + continue + + if __name__ == '__main__': app.run(host='0.0.0.0', port=8690, debug=False) diff --git a/src/api/rbxlImporterApi.js b/src/api/rbxlImporterApi.js index 68675f2..fa7b762 100644 --- a/src/api/rbxlImporterApi.js +++ b/src/api/rbxlImporterApi.js @@ -52,11 +52,18 @@ export async function analyzeRbxl(file) { /** * Создаёт проект из preview_hash. Возвращает { project_id, redirect, assets_downloaded, assets_failed }. */ -export async function createRbxlProject(previewHash, title) { +export async function createRbxlProject(previewHash, title, opts = {}) { const resp = await fetch(`${RBXL_addres}/import/rbxl/create`, { method: 'POST', headers: { ...authHeaders(), 'Content-Type': 'application/json' }, - body: JSON.stringify({ preview_hash: previewHash, title: title || '' }), + body: JSON.stringify({ + preview_hash: previewHash, + title: title || '', + // 'disabled' (default) — импортнуть выключенными, читать можно + // 'enabled' — попытаться запустить (может вешать карту) + // 'skip' — не импортировать совсем + scripts_mode: opts.scriptsMode || 'disabled', + }), }); if (!resp.ok) { const text = await resp.text(); diff --git a/src/components/RbxlImportModal.jsx b/src/components/RbxlImportModal.jsx index 8d137ec..9c3e5cd 100644 --- a/src/components/RbxlImportModal.jsx +++ b/src/components/RbxlImportModal.jsx @@ -26,6 +26,9 @@ export default function RbxlImportModal({ open, onClose, currentUserId, onCreate const [previewHash, setPreviewHash] = useState(null); const [title, setTitle] = useState(''); const [error, setError] = useState(null); + // Режим скриптов: 'disabled' (импортнуть выключенными — для чтения), + // 'enabled' (попытаться запустить — может вешать карту), 'skip' (удалить). + const [scriptsMode, setScriptsMode] = useState('disabled'); const fileInputRef = useRef(null); if (!open) return null; @@ -45,6 +48,7 @@ export default function RbxlImportModal({ open, onClose, currentUserId, onCreate const reset = () => { setFile(null); setReport(null); setPreviewHash(null); setTitle(''); setError(null); setAnalyzing(false); setCreating(false); + setScriptsMode('disabled'); }; const handleClose = () => { reset(); onClose?.(); }; @@ -88,7 +92,7 @@ export default function RbxlImportModal({ open, onClose, currentUserId, onCreate setCreating(true); setError(null); try { - const result = await createRbxlProject(previewHash, title); + const result = await createRbxlProject(previewHash, title, { scriptsMode }); onCreated?.(result); handleClose(); // редирект на редактор @@ -206,6 +210,58 @@ export default function RbxlImportModal({ open, onClose, currentUserId, onCreate + {report.scripts_total > 0 && ( +
+
+ Что делать со скриптами ({report.scripts_total} шт.)? +
+ + + +
+ )} +