diff --git a/src/editor/engine/StudioCollab.js b/src/editor/engine/StudioCollab.js index 68ee0d4..ccb4c74 100644 --- a/src/editor/engine/StudioCollab.js +++ b/src/editor/engine/StudioCollab.js @@ -161,6 +161,48 @@ export class StudioCollab { return r; }; } + + // Скрипты — синхрон создания/редактирования (upsertScript) и удаления + // (removeScript). Скрипты живут в scene._scripts[] ({id, code, target, + // name}); UI зовёт scene.upsertScript / scene.removeScript. + const sc = this.scene; + if (sc && !sc.__collabScriptsPatched) { + sc.__collabScriptsPatched = true; + if (typeof sc.upsertScript === 'function') { + const origUpsert = sc.upsertScript.bind(sc); + sc.upsertScript = function (id, code, target, name) { + const r = origUpsert(id, code, target, name); + if (!self._applyingRemote) { + // id может быть сгенерён внутри upsertScript, если был null — + // достаём фактический из _scripts (последний с этим code). + let realId = id; + if (realId == null) { + const arr = sc._scripts || []; + realId = arr.length ? arr[arr.length - 1].id : null; + } + const rec = (sc._scripts || []).find((s) => s.id === realId); + if (rec) { + self.sendOp({ + op: 'scriptUpsert', + id: rec.id, + code: rec.code, + target: rec.target ?? null, + name: rec.name ?? null, + }); + } + } + return r; + }; + } + if (typeof sc.removeScript === 'function') { + const origRemoveScript = sc.removeScript.bind(sc); + sc.removeScript = function (id) { + const r = origRemoveScript(id); + if (!self._applyingRemote) self.sendOp({ op: 'scriptRemove', id }); + return r; + }; + } + } } /** Снять обёртки (при выходе из коллаба восстановить оригиналы — простой флаг). */ @@ -387,6 +429,17 @@ export function applyRemoteOp(scene, op) { case 'blockRemove': bm?.removeBlock?.(op.x, op.y, op.z); return; + case 'scriptUpsert': + // Создание/редактирование скрипта у соавтора. _applyingRemote уже + // выставлен (см. _applyRemoteOp) → обёртка upsertScript не зашлёт + // эхо обратно. _onSceneChange внутри обновит React-панели. + scene.upsertScript?.(op.id, op.code, op.target ?? null, op.name ?? null); + scene._onCollabScriptsChange?.(); + return; + case 'scriptRemove': + scene.removeScript?.(op.id); + scene._onCollabScriptsChange?.(); + return; } switch (t) { case 'add': {