mirror of
https://github.com/HappyLifeOk/cc-3-8-x-mcp.git
synced 2026-08-21 05:57:14 +00:00
226 lines
6.5 KiB
JavaScript
226 lines
6.5 KiB
JavaScript
'use strict';
|
|||
|
|
|
||
|
|
const fs = require('node:fs');
|
||
|
|
const path = require('node:path');
|
||
|
|
const {
|
||
|
|
makePrefabRoot,
|
||
|
|
makeNode,
|
||
|
|
makePrefabInfo,
|
||
|
|
makeCompPrefabInfo,
|
||
|
|
makeUITransform,
|
||
|
|
makeSprite,
|
||
|
|
makeLabel,
|
||
|
|
} = require('../src/primitives.js');
|
||
|
|
|
||
|
|
const FIXTURE_DIR = path.join(__dirname, 'fixtures');
|
||
|
|
const FIXTURE_PROJECT_ROOT = path.join(FIXTURE_DIR, 'project');
|
||
|
|
const FIXTURE_ASSETS_DIR = path.join(FIXTURE_PROJECT_ROOT, 'assets');
|
||
|
|
const FIXTURE_TEMP_DIR = path.join(FIXTURE_ASSETS_DIR, '.tmp');
|
||
|
|
const HOME_UI_FIXTURE = path.join(FIXTURE_ASSETS_DIR, 'HomeUI.prefab');
|
||
|
|
const NESTED_PREFAB_FIXTURE = path.join(FIXTURE_ASSETS_DIR, 'TaskEntry.prefab');
|
||
|
|
const TASK_BTN_UUID = '5f4d2de3-a7dc-4d47-a41f-f27a12549b20';
|
||
|
|
const NESTED_PREFAB_UUID = 'addbe9a2-fd7e-5f3b-9164-ee44de8b1045';
|
||
|
|
const NESTED_ROOT_FILE_ID = 'as0LdMaKxSWSLxrZB9u9KA';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 生成一个只覆盖 CLI/override 测试契约的最小 Cocos 3 Prefab。
|
||
|
|
* stub 固定放在 id=10,保留旧测试对 mountedChildren/propertyOverrides 的覆盖。
|
||
|
|
*/
|
||
|
|
function buildHomeUiFixture() {
|
||
|
|
const elements = new Array(28);
|
||
|
|
|
||
|
|
elements[0] = makePrefabRoot({ name: 'HomeUI', rootId: 1 });
|
||
|
|
elements[1] = makeNode({
|
||
|
|
name: 'HomeUI',
|
||
|
|
childIds: [2, 4, 6, 8, 10, 24],
|
||
|
|
prefabId: 19,
|
||
|
|
});
|
||
|
|
elements[2] = makeNode({
|
||
|
|
name: 'touchArea',
|
||
|
|
pos: [0, 0, 0],
|
||
|
|
parentId: 1,
|
||
|
|
prefabId: 3,
|
||
|
|
});
|
||
|
|
elements[3] = makePrefabInfo({ rootId: 1, fileId: 'fixtureTouchAreaFileId' });
|
||
|
|
elements[4] = makeNode({
|
||
|
|
name: 'left',
|
||
|
|
pos: [-243, 12, 0],
|
||
|
|
parentId: 1,
|
||
|
|
prefabId: 5,
|
||
|
|
});
|
||
|
|
elements[5] = makePrefabInfo({ rootId: 1, fileId: 'fixtureLeftNodeFileId' });
|
||
|
|
elements[6] = makeNode({
|
||
|
|
name: 'n5',
|
||
|
|
parentId: 1,
|
||
|
|
componentIds: [7],
|
||
|
|
prefabId: 20,
|
||
|
|
});
|
||
|
|
elements[7] = makeSprite({
|
||
|
|
nodeId: 6,
|
||
|
|
spriteFrameUuid: '00000000-0000-0000-0000-000000000005@f9941',
|
||
|
|
prefabInfoId: 22,
|
||
|
|
});
|
||
|
|
elements[8] = makeNode({
|
||
|
|
name: 'n7',
|
||
|
|
parentId: 1,
|
||
|
|
componentIds: [9],
|
||
|
|
prefabId: 21,
|
||
|
|
});
|
||
|
|
elements[9] = makeLabel({
|
||
|
|
nodeId: 8,
|
||
|
|
string: '开始',
|
||
|
|
prefabInfoId: 23,
|
||
|
|
});
|
||
|
|
|
||
|
|
// nested prefab stub:结构与 Creator 3.8 序列化格式一致。
|
||
|
|
elements[10] = {
|
||
|
|
__type__: 'cc.Node',
|
||
|
|
_objFlags: 0,
|
||
|
|
_parent: { __id__: 1 },
|
||
|
|
_prefab: { __id__: 11 },
|
||
|
|
__editorExtras__: {},
|
||
|
|
};
|
||
|
|
elements[11] = {
|
||
|
|
__type__: 'cc.PrefabInfo',
|
||
|
|
root: { __id__: 10 },
|
||
|
|
asset: {
|
||
|
|
__uuid__: NESTED_PREFAB_UUID,
|
||
|
|
__expectedType__: 'cc.Prefab',
|
||
|
|
},
|
||
|
|
fileId: NESTED_ROOT_FILE_ID,
|
||
|
|
instance: { __id__: 12 },
|
||
|
|
targetOverrides: null,
|
||
|
|
};
|
||
|
|
elements[12] = {
|
||
|
|
__type__: 'cc.PrefabInstance',
|
||
|
|
fileId: 'fixtureNestedInstanceId',
|
||
|
|
prefabRootNode: { __id__: 1 },
|
||
|
|
mountedChildren: [],
|
||
|
|
mountedComponents: [],
|
||
|
|
propertyOverrides: [13, 15, 16, 17, 18].map((id) => ({ __id__: id })),
|
||
|
|
removedComponents: [],
|
||
|
|
};
|
||
|
|
elements[13] = {
|
||
|
|
__type__: 'CCPropertyOverrideInfo',
|
||
|
|
targetInfo: { __id__: 14 },
|
||
|
|
propertyPath: ['_name'],
|
||
|
|
value: 'taskEntry',
|
||
|
|
};
|
||
|
|
elements[14] = {
|
||
|
|
__type__: 'cc.TargetInfo',
|
||
|
|
localID: [NESTED_ROOT_FILE_ID],
|
||
|
|
};
|
||
|
|
elements[15] = {
|
||
|
|
__type__: 'CCPropertyOverrideInfo',
|
||
|
|
targetInfo: { __id__: 14 },
|
||
|
|
propertyPath: ['_lpos'],
|
||
|
|
value: { __type__: 'cc.Vec3', x: -272, y: 53, z: 0 },
|
||
|
|
};
|
||
|
|
elements[16] = {
|
||
|
|
__type__: 'CCPropertyOverrideInfo',
|
||
|
|
targetInfo: { __id__: 14 },
|
||
|
|
propertyPath: ['_lrot'],
|
||
|
|
value: { __type__: 'cc.Quat', x: 0, y: 0, z: 0, w: 1 },
|
||
|
|
};
|
||
|
|
elements[17] = {
|
||
|
|
__type__: 'CCPropertyOverrideInfo',
|
||
|
|
targetInfo: { __id__: 14 },
|
||
|
|
propertyPath: ['_euler'],
|
||
|
|
value: { __type__: 'cc.Vec3', x: 0, y: 0, z: 0 },
|
||
|
|
};
|
||
|
|
elements[18] = {
|
||
|
|
__type__: 'CCPropertyOverrideInfo',
|
||
|
|
targetInfo: { __id__: 14 },
|
||
|
|
propertyPath: ['_lscale'],
|
||
|
|
value: { __type__: 'cc.Vec3', x: 1, y: 1, z: 1 },
|
||
|
|
};
|
||
|
|
|
||
|
|
elements[19] = makePrefabInfo({
|
||
|
|
rootId: 1,
|
||
|
|
fileId: 'fixtureHomeRootFileId',
|
||
|
|
nestedPrefabInstanceRoots: [10],
|
||
|
|
});
|
||
|
|
elements[20] = makePrefabInfo({ rootId: 1, fileId: 'fixtureSpriteNodeFileId' });
|
||
|
|
elements[21] = makePrefabInfo({ rootId: 1, fileId: 'fixtureLabelNodeFileId' });
|
||
|
|
elements[22] = makeCompPrefabInfo('fixtureSpriteCompId');
|
||
|
|
elements[23] = makeCompPrefabInfo('fixtureLabelCompId');
|
||
|
|
elements[24] = makeNode({
|
||
|
|
name: 'btnMerge',
|
||
|
|
parentId: 1,
|
||
|
|
componentIds: [26],
|
||
|
|
prefabId: 25,
|
||
|
|
});
|
||
|
|
elements[25] = makePrefabInfo({ rootId: 1, fileId: 'fixtureBtnMergeNodeFileId' });
|
||
|
|
elements[26] = makeUITransform({
|
||
|
|
nodeId: 24,
|
||
|
|
width: 120,
|
||
|
|
height: 60,
|
||
|
|
prefabInfoId: 27,
|
||
|
|
});
|
||
|
|
elements[27] = makeCompPrefabInfo('fixtureBtnMergeUiTransformId');
|
||
|
|
|
||
|
|
return elements;
|
||
|
|
}
|
||
|
|
|
||
|
|
function buildNestedPrefabFixture() {
|
||
|
|
return [
|
||
|
|
makePrefabRoot({ name: 'TaskEntry', rootId: 1 }),
|
||
|
|
makeNode({ name: 'TaskEntry', prefabId: 2 }),
|
||
|
|
makePrefabInfo({ rootId: 1, fileId: NESTED_ROOT_FILE_ID }),
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
function writeGeneratedFile(filePath, content) {
|
||
|
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||
|
|
if (fs.existsSync(filePath) && fs.readFileSync(filePath, 'utf8') === content) return;
|
||
|
|
|
||
|
|
const tempPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
||
|
|
fs.writeFileSync(tempPath, content, 'utf8');
|
||
|
|
try {
|
||
|
|
fs.renameSync(tempPath, filePath);
|
||
|
|
} catch (error) {
|
||
|
|
if (fs.existsSync(filePath)) fs.unlinkSync(tempPath);
|
||
|
|
else throw error;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function ensureHomeUiFixture() {
|
||
|
|
fs.mkdirSync(FIXTURE_TEMP_DIR, { recursive: true });
|
||
|
|
writeGeneratedFile(
|
||
|
|
path.join(FIXTURE_PROJECT_ROOT, 'package.json'),
|
||
|
|
JSON.stringify({ name: 'cc-mcp-test-project', private: true }, null, 2) + '\n'
|
||
|
|
);
|
||
|
|
writeGeneratedFile(
|
||
|
|
NESTED_PREFAB_FIXTURE,
|
||
|
|
JSON.stringify(buildNestedPrefabFixture(), null, 2) + '\n'
|
||
|
|
);
|
||
|
|
writeGeneratedFile(
|
||
|
|
`${NESTED_PREFAB_FIXTURE}.meta`,
|
||
|
|
JSON.stringify({ ver: '1.1.50', importer: 'prefab', imported: true, uuid: NESTED_PREFAB_UUID }, null, 2) + '\n'
|
||
|
|
);
|
||
|
|
const taskBtnPath = path.join(FIXTURE_ASSETS_DIR, 'scripts', 'TaskBtn.ts');
|
||
|
|
writeGeneratedFile(
|
||
|
|
taskBtnPath,
|
||
|
|
"import { _decorator, Component } from 'cc';\nconst { ccclass } = _decorator;\n@ccclass('TaskBtn')\nexport class TaskBtn extends Component {}\n"
|
||
|
|
);
|
||
|
|
writeGeneratedFile(
|
||
|
|
`${taskBtnPath}.meta`,
|
||
|
|
JSON.stringify({ ver: '4.0.24', importer: 'typescript', imported: true, uuid: TASK_BTN_UUID }, null, 2) + '\n'
|
||
|
|
);
|
||
|
|
writeGeneratedFile(
|
||
|
|
HOME_UI_FIXTURE,
|
||
|
|
JSON.stringify(buildHomeUiFixture(), null, 2) + '\n'
|
||
|
|
);
|
||
|
|
return HOME_UI_FIXTURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
module.exports = {
|
||
|
|
HOME_UI_FIXTURE,
|
||
|
|
FIXTURE_PROJECT_ROOT,
|
||
|
|
FIXTURE_TEMP_DIR,
|
||
|
|
TASK_BTN_UUID,
|
||
|
|
buildHomeUiFixture,
|
||
|
|
buildNestedPrefabFixture,
|
||
|
|
ensureHomeUiFixture,
|
||
|
|
};
|