fix(scene-script): 拦截对组件核心属性(node等)的修改,防止编辑器卡死崩溃

This commit is contained in:
火焰库拉
2026-02-26 10:26:17 +08:00
parent 9268340af3
commit 7ab8bac506
2 changed files with 18 additions and 0 deletions

View File

@@ -193,3 +193,12 @@
1. **直接拦截节点**: 当检测到传入 `cc.Node``Node` 作为组件类型时直接驳回,并返回富含指导意义的中文提示词(如“请使用 create-node 创建节点”)。 1. **直接拦截节点**: 当检测到传入 `cc.Node``Node` 作为组件类型时直接驳回,并返回富含指导意义的中文提示词(如“请使用 create-node 创建节点”)。
2. **继承链校验**: 提取引擎类定义后,强制要求通过 `cc.js.isChildClassOf` 判断该类必须继承自 `cc.Component`。若不合法则即时截断并提示。 2. **继承链校验**: 提取引擎类定义后,强制要求通过 `cc.js.isChildClassOf` 判断该类必须继承自 `cc.Component`。若不合法则即时截断并提示。
- **价值**: 通过将冰冷的底层异常翻译为“手把手教 AI 怎么重试”的指导性异常,彻底根治了 AI 在操作组件时乱认对象、反复撞墙的通病。 - **价值**: 通过将冰冷的底层异常翻译为“手把手教 AI 怎么重试”的指导性异常,彻底根治了 AI 在操作组件时乱认对象、反复撞墙的通病。
---
## 防止核心属性被篡改崩溃 (2026-02-26)
### 1. `manage_components` 核心属性保护
- **问题**: AI 助手在使用 `manage_components` 尝试修改 `Label` 位置时,错误地对组件传参 `{ node: { position: ... } }`,导致 Label 的 `this.node` 强引用被覆写为普通对象。引发渲染报错 (`Cannot read property 'a' of undefined`) 和删除卡死 (`this.node._removeComponent is not a function`)。
- **修复**: 在 `scene-script.js``applyProperties` 中增加了核心属性黑名单机制。强制拦截对 `node`, `uuid`, `_id` 的直接写入并给出警告。彻底杜绝由于组件的节点引用被破坏所引发的场景崩溃和编辑器卡死问题。

View File

@@ -341,6 +341,15 @@ module.exports = {
const compClass = component.constructor; const compClass = component.constructor;
for (const [key, value] of Object.entries(props)) { for (const [key, value] of Object.entries(props)) {
// 【防呆设计】拦截对核心只读属性的非法重写
// 如果直接修改组件的 node 属性,会导致该引用丢失变成普通对象,进而引发编辑器卡死
if (key === "node" || key === "uuid" || key === "_id") {
Editor.warn(
`[scene-script] 拒绝覆盖组件的只读/核心属性: ${key}。请勿对组件执行此操作,修改位置/激活状态等请操作 Node 节点!`,
);
continue;
}
// 【核心修复】专门处理各类事件属性 (ClickEvents, ScrollEvents 等) // 【核心修复】专门处理各类事件属性 (ClickEvents, ScrollEvents 等)
const isEventProp = const isEventProp =
Array.isArray(value) && (key.toLowerCase().endsWith("events") || key === "clickEvents"); Array.isArray(value) && (key.toLowerCase().endsWith("events") || key === "clickEvents");