cocos2d-cli 1.6.4 → 1.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/bin/cocos2d-cli.js +152 -152
  2. package/data/script_map.json +25 -25
  3. package/package.json +33 -33
  4. package/src/commands/add-component.js +112 -112
  5. package/src/commands/add.js +177 -177
  6. package/src/commands/build.js +78 -78
  7. package/src/commands/create-scene.js +181 -181
  8. package/src/commands/get.js +108 -108
  9. package/src/commands/prefab-create.js +110 -110
  10. package/src/commands/remove-component.js +110 -110
  11. package/src/commands/remove.js +99 -99
  12. package/src/commands/screenshot.js +108 -108
  13. package/src/commands/set-component.js +119 -119
  14. package/src/commands/set.js +107 -107
  15. package/src/commands/tree.js +28 -28
  16. package/src/lib/cc/CCButton.js +122 -122
  17. package/src/lib/cc/CCCamera.js +93 -93
  18. package/src/lib/cc/CCCanvas.js +54 -54
  19. package/src/lib/cc/CCColor.js +32 -32
  20. package/src/lib/cc/CCComponent.js +60 -60
  21. package/src/lib/cc/CCLabel.js +146 -146
  22. package/src/lib/cc/CCNode.js +255 -255
  23. package/src/lib/cc/CCObject.js +23 -23
  24. package/src/lib/cc/CCPrefab.js +242 -242
  25. package/src/lib/cc/CCRect.js +32 -32
  26. package/src/lib/cc/CCRichText.js +44 -44
  27. package/src/lib/cc/CCScene.js +42 -42
  28. package/src/lib/cc/CCSceneAsset.js +302 -302
  29. package/src/lib/cc/CCSize.js +26 -26
  30. package/src/lib/cc/CCSprite.js +94 -94
  31. package/src/lib/cc/CCTrs.js +74 -74
  32. package/src/lib/cc/CCVec2.js +26 -26
  33. package/src/lib/cc/CCVec3.js +29 -29
  34. package/src/lib/cc/CCWidget.js +98 -98
  35. package/src/lib/cc/index.js +42 -42
  36. package/src/lib/fire-utils.js +373 -373
  37. package/src/lib/json-parser.js +185 -185
  38. package/src/lib/node-utils.js +395 -395
  39. package/src/lib/screenshot/index.html +29 -29
  40. package/src/lib/screenshot-core.js +285 -286
  41. package/src/lib/templates.js +49 -49
  42. package/src/lib/utils.js +202 -202
@@ -1,374 +1,374 @@
1
- /**
2
- * Fire/Prefab 文件工具模块
3
- * 提供场景/预制体文件的读写和编辑器交互功能
4
- */
5
-
6
- const fs = require('fs');
7
- const path = require('path');
8
- const crypto = require('crypto');
9
-
10
- /**
11
- * 检测是否为预制体文件
12
- */
13
- function isPrefab(data) {
14
- return data[0]?.__type__ === 'cc.Prefab';
15
- }
16
-
17
- /**
18
- * 加载场景/预制体文件
19
- */
20
- function loadScene(scenePath) {
21
- if (!fs.existsSync(scenePath)) {
22
- throw new Error(`文件不存在: ${scenePath}`);
23
- }
24
-
25
- const content = fs.readFileSync(scenePath, 'utf8');
26
- return JSON.parse(content);
27
- }
28
-
29
- /**
30
- * 保存场景/预制体文件
31
- */
32
- function saveScene(scenePath, data) {
33
- fs.writeFileSync(scenePath, JSON.stringify(data, null, 2), 'utf8');
34
- }
35
-
36
- /**
37
- * 构建 ID 和索引映射
38
- */
39
- function buildMaps(data) {
40
- const idMap = {};
41
- const indexMap = {};
42
- const prefab = isPrefab(data);
43
-
44
- function traverse(nodeIndex, parentPath = '') {
45
- const node = data[nodeIndex];
46
- if (!node) return;
47
-
48
- if (!node.__type__?.startsWith('cc.Node') && node.__type__ !== 'cc.Scene') {
49
- return;
50
- }
51
-
52
- const nodeId = node._id;
53
- if (nodeId) {
54
- idMap[nodeId] = nodeIndex;
55
- }
56
-
57
- const nodeName = node._name || '(unnamed)';
58
- const nodePath = parentPath ? `${parentPath}/${nodeName}` : nodeName;
59
-
60
- indexMap[nodeIndex] = {
61
- _id: nodeId,
62
- name: nodeName,
63
- path: nodePath,
64
- type: node.__type__
65
- };
66
-
67
- if (node._children) {
68
- node._children.forEach(childRef => {
69
- traverse(childRef.__id__, nodePath);
70
- });
71
- }
72
- }
73
-
74
- traverse(1);
75
-
76
- return { idMap, indexMap, prefab };
77
- }
78
-
79
- /**
80
- * 查找节点索引
81
- */
82
- function findNodeIndex(data, indexMap, nodeRef) {
83
- if (/^\d+$/.test(nodeRef)) {
84
- return parseInt(nodeRef);
85
- }
86
-
87
- for (const [idx, info] of Object.entries(indexMap)) {
88
- if (info.name === nodeRef || info.path === nodeRef || info.path.endsWith('/' + nodeRef)) {
89
- return parseInt(idx);
90
- }
91
- }
92
-
93
- return null;
94
- }
95
-
96
- /**
97
- * 重建所有 __id__ 引用
98
- */
99
- function rebuildReferences(data, deletedIndices) {
100
- const indexMap = {};
101
- let newIndex = 0;
102
- for (let oldIndex = 0; oldIndex < data.length; oldIndex++) {
103
- if (!deletedIndices.has(oldIndex)) {
104
- indexMap[oldIndex] = newIndex;
105
- newIndex++;
106
- }
107
- }
108
-
109
- function updateRef(obj) {
110
- if (!obj || typeof obj !== 'object') return;
111
-
112
- if (obj.__id__ !== undefined) {
113
- const oldId = obj.__id__;
114
- if (indexMap[oldId] !== undefined) {
115
- obj.__id__ = indexMap[oldId];
116
- }
117
- } else {
118
- for (const key of Object.keys(obj)) {
119
- updateRef(obj[key]);
120
- }
121
- }
122
- }
123
-
124
- for (const item of data) {
125
- updateRef(item);
126
- }
127
-
128
- return indexMap;
129
- }
130
-
131
- /**
132
- * 检查 CLI Helper 插件状态
133
- */
134
- function checkPluginStatus() {
135
- const http = require('http');
136
-
137
- return new Promise((resolve) => {
138
- const req = http.request({
139
- hostname: 'localhost',
140
- port: 7455,
141
- path: '/status',
142
- method: 'GET'
143
- }, (res) => {
144
- let data = '';
145
- res.on('data', chunk => data += chunk);
146
- res.on('end', () => {
147
- try {
148
- resolve(JSON.parse(data));
149
- } catch (e) {
150
- resolve(null);
151
- }
152
- });
153
- });
154
-
155
- req.on('error', () => resolve(null));
156
- req.setTimeout(3000, () => { req.destroy(); resolve(null); });
157
- req.end();
158
- });
159
- }
160
-
161
- /**
162
- * 触发编辑器刷新
163
- */
164
- function refreshEditor(scenePath) {
165
- if (!scenePath) return;
166
-
167
- const http = require('http');
168
-
169
- const assetsPath = path.dirname(scenePath);
170
- const projectPath = path.dirname(assetsPath);
171
- const relativePath = path.relative(projectPath, scenePath).replace(/\\/g, '/');
172
- const targetSceneUrl = 'db://' + relativePath.replace(/^assets\//, 'assets/');
173
-
174
- const getCurrentScene = () => {
175
- return new Promise((resolve) => {
176
- const req = http.request({
177
- hostname: 'localhost',
178
- port: 7455,
179
- path: '/current-scene',
180
- method: 'GET'
181
- }, (res) => {
182
- let data = '';
183
- res.on('data', chunk => data += chunk);
184
- res.on('end', () => {
185
- try {
186
- resolve(JSON.parse(data).sceneUrl || null);
187
- } catch (e) {
188
- resolve(null);
189
- }
190
- });
191
- });
192
- req.on('error', () => resolve(null));
193
- req.setTimeout(3000, () => { req.destroy(); resolve(null); });
194
- req.end();
195
- });
196
- };
197
-
198
- const sendRefreshRequest = (sceneUrl) => {
199
- const postData = sceneUrl ? JSON.stringify({ sceneUrl }) : '';
200
- const req = http.request({
201
- hostname: 'localhost',
202
- port: 7455,
203
- path: '/refresh',
204
- method: 'POST',
205
- headers: {
206
- 'Content-Type': 'application/json',
207
- 'Content-Length': Buffer.byteLength(postData)
208
- }
209
- }, () => {});
210
- req.on('error', () => {});
211
- if (postData) req.write(postData);
212
- req.end();
213
- };
214
-
215
- getCurrentScene().then(currentSceneUrl => {
216
- sendRefreshRequest(currentSceneUrl === targetSceneUrl ? targetSceneUrl : null);
217
- });
218
- }
219
-
220
- /**
221
- * 安装 CLI Helper 插件
222
- */
223
- function installPlugin(scenePath) {
224
- try {
225
- const assetsPath = path.dirname(scenePath);
226
- const projectPath = path.dirname(assetsPath);
227
- const packagesPath = path.join(projectPath, 'packages');
228
- const pluginPath = path.join(packagesPath, 'cocos2d-cli-helper');
229
-
230
- if (fs.existsSync(pluginPath)) return true;
231
-
232
- if (!fs.existsSync(packagesPath)) {
233
- fs.mkdirSync(packagesPath, { recursive: true });
234
- }
235
-
236
- const cliPluginPath = path.join(__dirname, '..', '..', 'editor-plugin');
237
-
238
- if (!fs.existsSync(cliPluginPath)) return false;
239
-
240
- fs.cpSync(cliPluginPath, pluginPath, { recursive: true });
241
- return true;
242
- } catch (e) {
243
- return false;
244
- }
245
- }
246
-
247
- /**
248
- * 加载脚本映射
249
- */
250
- function loadScriptMap(scenePath) {
251
- const projectPath = path.dirname(path.dirname(scenePath));
252
- const mapPath = path.join(projectPath, 'data', 'script_map.json');
253
- try {
254
- if (fs.existsSync(mapPath)) {
255
- return JSON.parse(fs.readFileSync(mapPath, 'utf-8'));
256
- }
257
- } catch (e) {}
258
- return {};
259
- }
260
-
261
- /**
262
- * 生成 fileId(用于 PrefabInfo)
263
- */
264
- function generateFileId() {
265
- const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
266
- let result = '';
267
- for (let i = 0; i < 22; i++) {
268
- result += chars.charAt(Math.floor(Math.random() * chars.length));
269
- }
270
- return result;
271
- }
272
-
273
- /**
274
- * 获取预制体根节点索引
275
- */
276
- function getPrefabRootIndex(data) {
277
- if (!isPrefab(data)) return null;
278
- return 1;
279
- }
280
-
281
- /**
282
- * 生成 UUID
283
- */
284
- function generateUUID() {
285
- return crypto.randomUUID();
286
- }
287
-
288
- /**
289
- * 生成预制体的 meta 对象
290
- * @param {string} uuid - 可选的 UUID,不传则自动生成
291
- * @returns {object}
292
- */
293
- function createPrefabMeta(uuid) {
294
- return {
295
- ver: '1.3.2',
296
- uuid: uuid || generateUUID(),
297
- importer: 'prefab',
298
- optimizationPolicy: 'AUTO',
299
- asyncLoadAssets: false,
300
- readonly: false,
301
- subMetas: {}
302
- };
303
- }
304
-
305
- /**
306
- * 生成场景的 meta 对象
307
- * @param {string} uuid - 可选的 UUID,不传则自动生成
308
- * @returns {object}
309
- */
310
- function createSceneMeta(uuid) {
311
- return {
312
- ver: '1.3.2',
313
- uuid: uuid || generateUUID(),
314
- importer: 'scene',
315
- asyncLoadAssets: false,
316
- autoReleaseAssets: false,
317
- subMetas: {}
318
- };
319
- }
320
-
321
- /**
322
- * 保存 meta 文件
323
- * @param {string} filePath - 资源文件路径(.prefab 或 .fire)
324
- * @param {object} meta - meta 对象
325
- */
326
- function saveMetaFile(filePath, meta) {
327
- const metaPath = filePath + '.meta';
328
- fs.writeFileSync(metaPath, JSON.stringify(meta, null, 2), 'utf8');
329
- return metaPath;
330
- }
331
-
332
- /**
333
- * 加载 meta 文件
334
- * @param {string} filePath - 资源文件路径
335
- * @returns {object|null}
336
- */
337
- function loadMetaFile(filePath) {
338
- const metaPath = filePath + '.meta';
339
- try {
340
- if (fs.existsSync(metaPath)) {
341
- return JSON.parse(fs.readFileSync(metaPath, 'utf8'));
342
- }
343
- } catch (e) {}
344
- return null;
345
- }
346
-
347
- module.exports = {
348
- // 文件操作
349
- loadScene,
350
- saveScene,
351
- isPrefab,
352
-
353
- // 索引映射
354
- buildMaps,
355
- findNodeIndex,
356
- rebuildReferences,
357
-
358
- // 编辑器交互
359
- refreshEditor,
360
- installPlugin,
361
- checkPluginStatus,
362
-
363
- // Meta 文件管理
364
- generateUUID,
365
- createPrefabMeta,
366
- createSceneMeta,
367
- saveMetaFile,
368
- loadMetaFile,
369
-
370
- // 工具函数
371
- loadScriptMap,
372
- generateFileId,
373
- getPrefabRootIndex
1
+ /**
2
+ * Fire/Prefab 文件工具模块
3
+ * 提供场景/预制体文件的读写和编辑器交互功能
4
+ */
5
+
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+ const crypto = require('crypto');
9
+
10
+ /**
11
+ * 检测是否为预制体文件
12
+ */
13
+ function isPrefab(data) {
14
+ return data[0]?.__type__ === 'cc.Prefab';
15
+ }
16
+
17
+ /**
18
+ * 加载场景/预制体文件
19
+ */
20
+ function loadScene(scenePath) {
21
+ if (!fs.existsSync(scenePath)) {
22
+ throw new Error(`文件不存在: ${scenePath}`);
23
+ }
24
+
25
+ const content = fs.readFileSync(scenePath, 'utf8');
26
+ return JSON.parse(content);
27
+ }
28
+
29
+ /**
30
+ * 保存场景/预制体文件
31
+ */
32
+ function saveScene(scenePath, data) {
33
+ fs.writeFileSync(scenePath, JSON.stringify(data, null, 2), 'utf8');
34
+ }
35
+
36
+ /**
37
+ * 构建 ID 和索引映射
38
+ */
39
+ function buildMaps(data) {
40
+ const idMap = {};
41
+ const indexMap = {};
42
+ const prefab = isPrefab(data);
43
+
44
+ function traverse(nodeIndex, parentPath = '') {
45
+ const node = data[nodeIndex];
46
+ if (!node) return;
47
+
48
+ if (!node.__type__?.startsWith('cc.Node') && node.__type__ !== 'cc.Scene') {
49
+ return;
50
+ }
51
+
52
+ const nodeId = node._id;
53
+ if (nodeId) {
54
+ idMap[nodeId] = nodeIndex;
55
+ }
56
+
57
+ const nodeName = node._name || '(unnamed)';
58
+ const nodePath = parentPath ? `${parentPath}/${nodeName}` : nodeName;
59
+
60
+ indexMap[nodeIndex] = {
61
+ _id: nodeId,
62
+ name: nodeName,
63
+ path: nodePath,
64
+ type: node.__type__
65
+ };
66
+
67
+ if (node._children) {
68
+ node._children.forEach(childRef => {
69
+ traverse(childRef.__id__, nodePath);
70
+ });
71
+ }
72
+ }
73
+
74
+ traverse(1);
75
+
76
+ return { idMap, indexMap, prefab };
77
+ }
78
+
79
+ /**
80
+ * 查找节点索引
81
+ */
82
+ function findNodeIndex(data, indexMap, nodeRef) {
83
+ if (/^\d+$/.test(nodeRef)) {
84
+ return parseInt(nodeRef);
85
+ }
86
+
87
+ for (const [idx, info] of Object.entries(indexMap)) {
88
+ if (info.name === nodeRef || info.path === nodeRef || info.path.endsWith('/' + nodeRef)) {
89
+ return parseInt(idx);
90
+ }
91
+ }
92
+
93
+ return null;
94
+ }
95
+
96
+ /**
97
+ * 重建所有 __id__ 引用
98
+ */
99
+ function rebuildReferences(data, deletedIndices) {
100
+ const indexMap = {};
101
+ let newIndex = 0;
102
+ for (let oldIndex = 0; oldIndex < data.length; oldIndex++) {
103
+ if (!deletedIndices.has(oldIndex)) {
104
+ indexMap[oldIndex] = newIndex;
105
+ newIndex++;
106
+ }
107
+ }
108
+
109
+ function updateRef(obj) {
110
+ if (!obj || typeof obj !== 'object') return;
111
+
112
+ if (obj.__id__ !== undefined) {
113
+ const oldId = obj.__id__;
114
+ if (indexMap[oldId] !== undefined) {
115
+ obj.__id__ = indexMap[oldId];
116
+ }
117
+ } else {
118
+ for (const key of Object.keys(obj)) {
119
+ updateRef(obj[key]);
120
+ }
121
+ }
122
+ }
123
+
124
+ for (const item of data) {
125
+ updateRef(item);
126
+ }
127
+
128
+ return indexMap;
129
+ }
130
+
131
+ /**
132
+ * 检查 CLI Helper 插件状态
133
+ */
134
+ function checkPluginStatus() {
135
+ const http = require('http');
136
+
137
+ return new Promise((resolve) => {
138
+ const req = http.request({
139
+ hostname: 'localhost',
140
+ port: 7455,
141
+ path: '/status',
142
+ method: 'GET'
143
+ }, (res) => {
144
+ let data = '';
145
+ res.on('data', chunk => data += chunk);
146
+ res.on('end', () => {
147
+ try {
148
+ resolve(JSON.parse(data));
149
+ } catch (e) {
150
+ resolve(null);
151
+ }
152
+ });
153
+ });
154
+
155
+ req.on('error', () => resolve(null));
156
+ req.setTimeout(3000, () => { req.destroy(); resolve(null); });
157
+ req.end();
158
+ });
159
+ }
160
+
161
+ /**
162
+ * 触发编辑器刷新
163
+ */
164
+ function refreshEditor(scenePath) {
165
+ if (!scenePath) return;
166
+
167
+ const http = require('http');
168
+
169
+ const assetsPath = path.dirname(scenePath);
170
+ const projectPath = path.dirname(assetsPath);
171
+ const relativePath = path.relative(projectPath, scenePath).replace(/\\/g, '/');
172
+ const targetSceneUrl = 'db://' + relativePath.replace(/^assets\//, 'assets/');
173
+
174
+ const getCurrentScene = () => {
175
+ return new Promise((resolve) => {
176
+ const req = http.request({
177
+ hostname: 'localhost',
178
+ port: 7455,
179
+ path: '/current-scene',
180
+ method: 'GET'
181
+ }, (res) => {
182
+ let data = '';
183
+ res.on('data', chunk => data += chunk);
184
+ res.on('end', () => {
185
+ try {
186
+ resolve(JSON.parse(data).sceneUrl || null);
187
+ } catch (e) {
188
+ resolve(null);
189
+ }
190
+ });
191
+ });
192
+ req.on('error', () => resolve(null));
193
+ req.setTimeout(3000, () => { req.destroy(); resolve(null); });
194
+ req.end();
195
+ });
196
+ };
197
+
198
+ const sendRefreshRequest = (sceneUrl) => {
199
+ const postData = sceneUrl ? JSON.stringify({ sceneUrl }) : '';
200
+ const req = http.request({
201
+ hostname: 'localhost',
202
+ port: 7455,
203
+ path: '/refresh',
204
+ method: 'POST',
205
+ headers: {
206
+ 'Content-Type': 'application/json',
207
+ 'Content-Length': Buffer.byteLength(postData)
208
+ }
209
+ }, () => {});
210
+ req.on('error', () => {});
211
+ if (postData) req.write(postData);
212
+ req.end();
213
+ };
214
+
215
+ getCurrentScene().then(currentSceneUrl => {
216
+ sendRefreshRequest(currentSceneUrl === targetSceneUrl ? targetSceneUrl : null);
217
+ });
218
+ }
219
+
220
+ /**
221
+ * 安装 CLI Helper 插件
222
+ */
223
+ function installPlugin(scenePath) {
224
+ try {
225
+ const assetsPath = path.dirname(scenePath);
226
+ const projectPath = path.dirname(assetsPath);
227
+ const packagesPath = path.join(projectPath, 'packages');
228
+ const pluginPath = path.join(packagesPath, 'cocos2d-cli-helper');
229
+
230
+ if (fs.existsSync(pluginPath)) return true;
231
+
232
+ if (!fs.existsSync(packagesPath)) {
233
+ fs.mkdirSync(packagesPath, { recursive: true });
234
+ }
235
+
236
+ const cliPluginPath = path.join(__dirname, '..', '..', 'editor-plugin');
237
+
238
+ if (!fs.existsSync(cliPluginPath)) return false;
239
+
240
+ fs.cpSync(cliPluginPath, pluginPath, { recursive: true });
241
+ return true;
242
+ } catch (e) {
243
+ return false;
244
+ }
245
+ }
246
+
247
+ /**
248
+ * 加载脚本映射
249
+ */
250
+ function loadScriptMap(scenePath) {
251
+ const projectPath = path.dirname(path.dirname(scenePath));
252
+ const mapPath = path.join(projectPath, 'data', 'script_map.json');
253
+ try {
254
+ if (fs.existsSync(mapPath)) {
255
+ return JSON.parse(fs.readFileSync(mapPath, 'utf-8'));
256
+ }
257
+ } catch (e) {}
258
+ return {};
259
+ }
260
+
261
+ /**
262
+ * 生成 fileId(用于 PrefabInfo)
263
+ */
264
+ function generateFileId() {
265
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
266
+ let result = '';
267
+ for (let i = 0; i < 22; i++) {
268
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
269
+ }
270
+ return result;
271
+ }
272
+
273
+ /**
274
+ * 获取预制体根节点索引
275
+ */
276
+ function getPrefabRootIndex(data) {
277
+ if (!isPrefab(data)) return null;
278
+ return 1;
279
+ }
280
+
281
+ /**
282
+ * 生成 UUID
283
+ */
284
+ function generateUUID() {
285
+ return crypto.randomUUID();
286
+ }
287
+
288
+ /**
289
+ * 生成预制体的 meta 对象
290
+ * @param {string} uuid - 可选的 UUID,不传则自动生成
291
+ * @returns {object}
292
+ */
293
+ function createPrefabMeta(uuid) {
294
+ return {
295
+ ver: '1.3.2',
296
+ uuid: uuid || generateUUID(),
297
+ importer: 'prefab',
298
+ optimizationPolicy: 'AUTO',
299
+ asyncLoadAssets: false,
300
+ readonly: false,
301
+ subMetas: {}
302
+ };
303
+ }
304
+
305
+ /**
306
+ * 生成场景的 meta 对象
307
+ * @param {string} uuid - 可选的 UUID,不传则自动生成
308
+ * @returns {object}
309
+ */
310
+ function createSceneMeta(uuid) {
311
+ return {
312
+ ver: '1.3.2',
313
+ uuid: uuid || generateUUID(),
314
+ importer: 'scene',
315
+ asyncLoadAssets: false,
316
+ autoReleaseAssets: false,
317
+ subMetas: {}
318
+ };
319
+ }
320
+
321
+ /**
322
+ * 保存 meta 文件
323
+ * @param {string} filePath - 资源文件路径(.prefab 或 .fire)
324
+ * @param {object} meta - meta 对象
325
+ */
326
+ function saveMetaFile(filePath, meta) {
327
+ const metaPath = filePath + '.meta';
328
+ fs.writeFileSync(metaPath, JSON.stringify(meta, null, 2), 'utf8');
329
+ return metaPath;
330
+ }
331
+
332
+ /**
333
+ * 加载 meta 文件
334
+ * @param {string} filePath - 资源文件路径
335
+ * @returns {object|null}
336
+ */
337
+ function loadMetaFile(filePath) {
338
+ const metaPath = filePath + '.meta';
339
+ try {
340
+ if (fs.existsSync(metaPath)) {
341
+ return JSON.parse(fs.readFileSync(metaPath, 'utf8'));
342
+ }
343
+ } catch (e) {}
344
+ return null;
345
+ }
346
+
347
+ module.exports = {
348
+ // 文件操作
349
+ loadScene,
350
+ saveScene,
351
+ isPrefab,
352
+
353
+ // 索引映射
354
+ buildMaps,
355
+ findNodeIndex,
356
+ rebuildReferences,
357
+
358
+ // 编辑器交互
359
+ refreshEditor,
360
+ installPlugin,
361
+ checkPluginStatus,
362
+
363
+ // Meta 文件管理
364
+ generateUUID,
365
+ createPrefabMeta,
366
+ createSceneMeta,
367
+ saveMetaFile,
368
+ loadMetaFile,
369
+
370
+ // 工具函数
371
+ loadScriptMap,
372
+ generateFileId,
373
+ getPrefabRootIndex
374
374
  };