文档: 更新所有文档与代码注释为中文
This commit is contained in:
36
main.js
36
main.js
@@ -1409,11 +1409,11 @@ export default class NewScript extends cc.Component {
|
||||
// 3. 应用编辑
|
||||
// 必须按倒序应用编辑,否则后续编辑的位置会偏移 (假设edits未排序,这里简单处理,实际上LSP通常建议客户端倒序应用或计算偏移)
|
||||
// 这里假设edits已经按照位置排序或者用户负责,如果需要严谨,应先按 start/position 倒序排序
|
||||
// 简单做个排序保险:
|
||||
// 简单排序保险:
|
||||
const sortedEdits = [...edits].sort((a, b) => {
|
||||
const posA = a.position !== undefined ? a.position : a.start;
|
||||
const posB = b.position !== undefined ? b.position : b.start;
|
||||
return posB - posA; // big to small
|
||||
return posB - posA; // 从大到小
|
||||
});
|
||||
|
||||
sortedEdits.forEach((edit) => {
|
||||
@@ -1479,10 +1479,25 @@ export default class NewScript extends cc.Component {
|
||||
'File/Save': 'scene:stash-and-save', // 别名
|
||||
'Edit/Undo': 'scene:undo',
|
||||
'Edit/Redo': 'scene:redo',
|
||||
'Edit/Delete': 'scene:delete-selected',
|
||||
'Delete': 'scene:delete-selected',
|
||||
'delete': 'scene:delete-selected',
|
||||
'Node/Create Empty Node': 'scene:create-node-by-classid', // 简化的映射,通常需要参数
|
||||
'Project/Build': 'app:build-project',
|
||||
};
|
||||
|
||||
// 特殊处理 delete-node:UUID 格式
|
||||
if (menuPath.startsWith("delete-node:")) {
|
||||
const uuid = menuPath.split(":")[1];
|
||||
if (uuid) {
|
||||
Editor.Scene.callSceneScript('mcp-bridge', 'delete-node', { uuid }, (err, result) => {
|
||||
if (err) callback(err);
|
||||
else callback(null, result || `Node ${uuid} deleted via scene script`);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (menuMap[menuPath]) {
|
||||
const ipcMsg = menuMap[menuPath];
|
||||
try {
|
||||
@@ -1508,7 +1523,6 @@ export default class NewScript extends cc.Component {
|
||||
}
|
||||
},
|
||||
|
||||
// 验证脚本
|
||||
// 验证脚本
|
||||
validateScript(args, callback) {
|
||||
const { filePath } = args;
|
||||
@@ -1550,7 +1564,7 @@ export default class NewScript extends cc.Component {
|
||||
// 简单的正则表达式检查:是否有非法字符或明显错误结构 (示例)
|
||||
// 这里暂时只做简单的括号匹配检查或直接通过,但给出一个 Warning
|
||||
|
||||
// 检查是否有 class 定义 (简单的heuristic)
|
||||
// 检查是否有 class 定义 (简单的启发式检查)
|
||||
if (!content.includes('class ') && !content.includes('interface ') && !content.includes('enum ') && !content.includes('export ')) {
|
||||
return callback(null, { valid: true, message: "Warning: TypeScript file seems to lack standard definitions (class/interface), but basic syntax check is skipped due to missing compiler." });
|
||||
}
|
||||
@@ -1631,7 +1645,7 @@ export default class NewScript extends cc.Component {
|
||||
"inspect-apis"() {
|
||||
addLog("info", "[API Inspector] Starting DEEP inspection...");
|
||||
|
||||
// Helper to get function arguments
|
||||
// 获取函数参数的辅助函数
|
||||
const getArgs = (func) => {
|
||||
try {
|
||||
const str = func.toString();
|
||||
@@ -1645,7 +1659,7 @@ export default class NewScript extends cc.Component {
|
||||
}
|
||||
};
|
||||
|
||||
// Helper to inspect an object
|
||||
// 检查对象的辅助函数
|
||||
const inspectObj = (name, obj) => {
|
||||
if (!obj) return { name, exists: false };
|
||||
const props = {};
|
||||
@@ -1655,7 +1669,7 @@ export default class NewScript extends cc.Component {
|
||||
const allKeys = new Set([...Object.getOwnPropertyNames(obj), ...Object.getOwnPropertyNames(proto || {})]);
|
||||
|
||||
allKeys.forEach(key => {
|
||||
if (key.startsWith("_")) return; // Skip private
|
||||
if (key.startsWith("_")) return; // 跳过私有属性
|
||||
try {
|
||||
const val = obj[key];
|
||||
if (typeof val === 'function') {
|
||||
@@ -1668,7 +1682,7 @@ export default class NewScript extends cc.Component {
|
||||
return { name, exists: true, props };
|
||||
};
|
||||
|
||||
// 1. Inspect Standard Objects
|
||||
// 1. 检查标准对象
|
||||
const standardObjects = {
|
||||
"Editor.assetdb": Editor.assetdb,
|
||||
"Editor.Selection": Editor.Selection,
|
||||
@@ -1684,7 +1698,7 @@ export default class NewScript extends cc.Component {
|
||||
report[key] = inspectObj(key, standardObjects[key]);
|
||||
});
|
||||
|
||||
// 2. Check Specific Forum APIs
|
||||
// 2. 检查特定论坛提到的 API
|
||||
const forumChecklist = [
|
||||
"Editor.assetdb.queryInfoByUuid",
|
||||
"Editor.assetdb.assetInfoByUuid",
|
||||
@@ -1705,7 +1719,7 @@ export default class NewScript extends cc.Component {
|
||||
const checklistResults = {};
|
||||
forumChecklist.forEach(path => {
|
||||
const parts = path.split(".");
|
||||
let curr = global; // In main process, Editor is global
|
||||
let curr = global; // 在主进程中,Editor 是全局的
|
||||
let exists = true;
|
||||
for (const part of parts) {
|
||||
if (curr && curr[part]) {
|
||||
@@ -1721,7 +1735,7 @@ export default class NewScript extends cc.Component {
|
||||
addLog("info", `[API Inspector] Standard Objects:\n${JSON.stringify(report, null, 2)}`);
|
||||
addLog("info", `[API Inspector] Forum Checklist:\n${JSON.stringify(checklistResults, null, 2)}`);
|
||||
|
||||
// 3. Inspect Built-in Package IPCs
|
||||
// 3. 检查内置包 IPC 消息
|
||||
const ipcReport = {};
|
||||
const builtinPackages = ["scene", "builder", "assets"]; // 核心内置包
|
||||
const fs = require("fs");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "mcp-bridge",
|
||||
"version": "1.0.0",
|
||||
"description": "Cocos Creator MCP Bridge",
|
||||
"description": "Cocos Creator MCP 桥接插件",
|
||||
"author": "Firekula",
|
||||
"main": "main.js",
|
||||
"scene-script": "scene-script.js",
|
||||
|
||||
@@ -184,7 +184,7 @@ module.exports = {
|
||||
if (typeof value === 'string') {
|
||||
targetNode = cc.engine.getInstanceById(value);
|
||||
|
||||
// Fallback for compressed UUIDs
|
||||
// 针对压缩 UUID 的回退处理
|
||||
if (!targetNode && Editor.Utils && Editor.Utils.UuidUtils) {
|
||||
try {
|
||||
const decompressed = Editor.Utils.UuidUtils.decompressUuid(value);
|
||||
@@ -252,7 +252,7 @@ module.exports = {
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Ignore type check errors
|
||||
// 忽略类型检查错误
|
||||
}
|
||||
|
||||
component[key] = finalValue;
|
||||
@@ -399,20 +399,20 @@ module.exports = {
|
||||
for (const key in c) {
|
||||
if (typeof c[key] !== "function" && !key.startsWith("_") && c[key] !== undefined) {
|
||||
try {
|
||||
// Safe serialization check
|
||||
// 安全序列化检查
|
||||
const val = c[key];
|
||||
if (val === null || val === undefined) {
|
||||
properties[key] = val;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Primitives are safe
|
||||
// 基础类型是安全的
|
||||
if (typeof val !== 'object') {
|
||||
properties[key] = val;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Special Cocos Types
|
||||
// 特殊 Cocos 类型
|
||||
if (val instanceof cc.ValueType) {
|
||||
properties[key] = val.toString();
|
||||
} else if (val instanceof cc.Asset) {
|
||||
@@ -422,14 +422,14 @@ module.exports = {
|
||||
} else if (val instanceof cc.Component) {
|
||||
properties[key] = `Component(${val.name}<${val.__typename}>)`;
|
||||
} else {
|
||||
// Arrays and Plain Objects
|
||||
// Attempt to strip to pure JSON data to avoid IPC errors with Native/Circular objects
|
||||
// 数组和普通对象
|
||||
// 尝试转换为纯 JSON 数据以避免 IPC 错误(如包含原生对象/循环引用)
|
||||
try {
|
||||
const jsonStr = JSON.stringify(val);
|
||||
// Ensure we don't pass the original object reference
|
||||
// 确保不传递原始对象引用
|
||||
properties[key] = JSON.parse(jsonStr);
|
||||
} catch (e) {
|
||||
// If JSON fails (e.g. circular), format as string
|
||||
// 如果 JSON 失败(例如循环引用),格式化为字符串
|
||||
properties[key] = `[Complex Object: ${val.constructor ? val.constructor.name : typeof val}]`;
|
||||
}
|
||||
}
|
||||
@@ -594,6 +594,28 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
|
||||
"delete-node": function (event, args) {
|
||||
const { uuid } = args;
|
||||
const node = cc.engine.getInstanceById(uuid);
|
||||
if (node) {
|
||||
const parent = node.parent;
|
||||
node.destroy();
|
||||
Editor.Ipc.sendToMain("scene:dirty");
|
||||
// 延迟通知以确保节点已被移除
|
||||
setTimeout(() => {
|
||||
if (parent) {
|
||||
Editor.Ipc.sendToAll("scene:node-changed", { uuid: parent.uuid });
|
||||
}
|
||||
// 广播节点删除事件
|
||||
Editor.Ipc.sendToAll("scene:node-deleted", { uuid: uuid });
|
||||
}, 10);
|
||||
|
||||
if (event.reply) event.reply(null, `Node ${uuid} deleted`);
|
||||
} else {
|
||||
if (event.reply) event.reply(new Error(`Node not found: ${uuid}`));
|
||||
}
|
||||
},
|
||||
|
||||
"manage-vfx": function (event, args) {
|
||||
const { action, nodeId, properties, name, parentId } = args;
|
||||
const scene = cc.director.getScene();
|
||||
|
||||
Reference in New Issue
Block a user