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.
- package/bin/cocos2d-cli.js +152 -152
- package/data/script_map.json +25 -25
- package/package.json +33 -33
- package/src/commands/add-component.js +112 -112
- package/src/commands/add.js +177 -177
- package/src/commands/build.js +78 -78
- package/src/commands/create-scene.js +181 -181
- package/src/commands/get.js +108 -108
- package/src/commands/prefab-create.js +110 -110
- package/src/commands/remove-component.js +110 -110
- package/src/commands/remove.js +99 -99
- package/src/commands/screenshot.js +108 -108
- package/src/commands/set-component.js +119 -119
- package/src/commands/set.js +107 -107
- package/src/commands/tree.js +28 -28
- package/src/lib/cc/CCButton.js +122 -122
- package/src/lib/cc/CCCamera.js +93 -93
- package/src/lib/cc/CCCanvas.js +54 -54
- package/src/lib/cc/CCColor.js +32 -32
- package/src/lib/cc/CCComponent.js +60 -60
- package/src/lib/cc/CCLabel.js +146 -146
- package/src/lib/cc/CCNode.js +255 -255
- package/src/lib/cc/CCObject.js +23 -23
- package/src/lib/cc/CCPrefab.js +242 -242
- package/src/lib/cc/CCRect.js +32 -32
- package/src/lib/cc/CCRichText.js +44 -44
- package/src/lib/cc/CCScene.js +42 -42
- package/src/lib/cc/CCSceneAsset.js +302 -302
- package/src/lib/cc/CCSize.js +26 -26
- package/src/lib/cc/CCSprite.js +94 -94
- package/src/lib/cc/CCTrs.js +74 -74
- package/src/lib/cc/CCVec2.js +26 -26
- package/src/lib/cc/CCVec3.js +29 -29
- package/src/lib/cc/CCWidget.js +98 -98
- package/src/lib/cc/index.js +42 -42
- package/src/lib/fire-utils.js +373 -373
- package/src/lib/json-parser.js +185 -185
- package/src/lib/node-utils.js +395 -395
- package/src/lib/screenshot/index.html +29 -29
- package/src/lib/screenshot-core.js +285 -286
- package/src/lib/templates.js +49 -49
- package/src/lib/utils.js +202 -202
package/src/commands/add.js
CHANGED
|
@@ -1,177 +1,177 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* add 命令 - 添加节点
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const path = require('path');
|
|
6
|
-
const fs = require('fs');
|
|
7
|
-
const { CCNode, CCSceneAsset, CCPrefab, CCCanvas, CCWidget, CCSprite, CCLabel, CCButton } = require('../lib/cc');
|
|
8
|
-
const { buildTree } = require('../lib/node-utils');
|
|
9
|
-
const { loadScriptMap, isPrefab } = require('../lib/fire-utils');
|
|
10
|
-
const { generateCompressedUUID } = require('../lib/utils');
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* 解析命令行选项
|
|
14
|
-
*/
|
|
15
|
-
function parseOptions(args, startIndex) {
|
|
16
|
-
const options = {};
|
|
17
|
-
for (let i = startIndex; i < args.length; i++) {
|
|
18
|
-
const arg = args[i];
|
|
19
|
-
if (arg.startsWith('--')) {
|
|
20
|
-
const eqIndex = arg.indexOf('=');
|
|
21
|
-
if (eqIndex > 0) {
|
|
22
|
-
const key = arg.substring(2, eqIndex);
|
|
23
|
-
let value = arg.substring(eqIndex + 1);
|
|
24
|
-
if (!isNaN(value) && value !== '') {
|
|
25
|
-
value = parseFloat(value);
|
|
26
|
-
}
|
|
27
|
-
options[key] = value;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return options;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* 创建组件
|
|
36
|
-
*/
|
|
37
|
-
function createComponent(type) {
|
|
38
|
-
switch (type.toLowerCase()) {
|
|
39
|
-
case 'canvas': return new CCCanvas();
|
|
40
|
-
case 'widget': return new CCWidget();
|
|
41
|
-
case 'sprite': return new CCSprite();
|
|
42
|
-
case 'label': return new CCLabel();
|
|
43
|
-
case 'button': return new CCButton();
|
|
44
|
-
default: return null;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* 查找节点
|
|
50
|
-
*/
|
|
51
|
-
function findNode(root, path) {
|
|
52
|
-
if (!path) return root;
|
|
53
|
-
|
|
54
|
-
const parts = path.split('/').filter(p => p);
|
|
55
|
-
if (parts.length === 0) return root;
|
|
56
|
-
|
|
57
|
-
let current = root;
|
|
58
|
-
|
|
59
|
-
// 如果路径以根节点名称开始,跳过
|
|
60
|
-
if (parts[0] === root._name) {
|
|
61
|
-
parts.shift();
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
for (const part of parts) {
|
|
65
|
-
if (!current._children || current._children.length === 0) return null;
|
|
66
|
-
const found = current._children.find(c => c._name === part);
|
|
67
|
-
if (!found) return null;
|
|
68
|
-
current = found;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return current;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function run(args) {
|
|
75
|
-
if (args.length < 3) {
|
|
76
|
-
console.log(JSON.stringify({ error: '用法: cocos2d-cli add <场景.fire|预制体.prefab> <父节点路径> <节点名称> [--type=组件类型] [--x=N] [--y=N]' }));
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const filePath = args[0];
|
|
81
|
-
const parentPath = args[1];
|
|
82
|
-
const nodeName = args[2];
|
|
83
|
-
const options = parseOptions(args, 3);
|
|
84
|
-
|
|
85
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
86
|
-
|
|
87
|
-
try {
|
|
88
|
-
let root;
|
|
89
|
-
let asset;
|
|
90
|
-
const json = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
91
|
-
|
|
92
|
-
if (ext === '.fire') {
|
|
93
|
-
asset = CCSceneAsset.fromJSON(json);
|
|
94
|
-
root = asset._scene;
|
|
95
|
-
} else if (ext === '.prefab') {
|
|
96
|
-
asset = CCPrefab.fromJSON(json);
|
|
97
|
-
root = asset._root;
|
|
98
|
-
} else {
|
|
99
|
-
console.log(JSON.stringify({ error: '不支持的文件类型,仅支持 .fire 和 .prefab' }));
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const parent = findNode(root, parentPath);
|
|
104
|
-
|
|
105
|
-
if (!parent) {
|
|
106
|
-
console.log(JSON.stringify({ error: `父节点不存在: ${parentPath}` }));
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// 创建节点
|
|
111
|
-
const node = new CCNode(nodeName);
|
|
112
|
-
|
|
113
|
-
// 应用属性
|
|
114
|
-
if (options.x !== undefined) node._trs.array[0] = parseFloat(options.x);
|
|
115
|
-
if (options.y !== undefined) node._trs.array[1] = parseFloat(options.y);
|
|
116
|
-
if (options.width !== undefined) node._contentSize.width = parseFloat(options.width);
|
|
117
|
-
if (options.height !== undefined) node._contentSize.height = parseFloat(options.height);
|
|
118
|
-
if (options.scaleX !== undefined) node._trs.array[7] = parseFloat(options.scaleX);
|
|
119
|
-
if (options.scaleY !== undefined) node._trs.array[8] = parseFloat(options.scaleY);
|
|
120
|
-
if (options.rotation !== undefined) {
|
|
121
|
-
node._trs.array[5] = parseFloat(options.rotation) * Math.PI / 180;
|
|
122
|
-
node._eulerAngles.z = parseFloat(options.rotation);
|
|
123
|
-
}
|
|
124
|
-
if (options.active !== undefined) {
|
|
125
|
-
node._active = options.active !== 'false' && options.active !== false;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// 添加组件
|
|
129
|
-
if (options.type) {
|
|
130
|
-
const comp = createComponent(options.type);
|
|
131
|
-
if (comp) {
|
|
132
|
-
comp.node = node;
|
|
133
|
-
node._components = [comp];
|
|
134
|
-
|
|
135
|
-
// 组件特殊属性
|
|
136
|
-
if (options.type.toLowerCase() === 'label') {
|
|
137
|
-
if (options.string) {
|
|
138
|
-
comp._string = options.string;
|
|
139
|
-
comp['_N$string'] = options.string;
|
|
140
|
-
}
|
|
141
|
-
if (options.fontSize) {
|
|
142
|
-
comp._fontSize = parseInt(options.fontSize);
|
|
143
|
-
comp._lineHeight = parseInt(options.fontSize);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// 添加节点到父节点
|
|
150
|
-
parent._children = parent._children || [];
|
|
151
|
-
parent._children.push(node);
|
|
152
|
-
node._parent = parent;
|
|
153
|
-
|
|
154
|
-
// 场景节点需要 _id,预制体需要 PrefabInfo
|
|
155
|
-
if (ext === '.fire') {
|
|
156
|
-
node._id = generateCompressedUUID();
|
|
157
|
-
} else if (ext === '.prefab') {
|
|
158
|
-
const { CCPrefabInfo } = require('../lib/cc');
|
|
159
|
-
node._prefab = new CCPrefabInfo();
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// 保存
|
|
163
|
-
const data = asset.toJSON();
|
|
164
|
-
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf8');
|
|
165
|
-
|
|
166
|
-
// 输出节点树
|
|
167
|
-
const scriptMap = loadScriptMap(filePath);
|
|
168
|
-
const prefab = isPrefab(data);
|
|
169
|
-
const startIndex = prefab ? 0 : 1;
|
|
170
|
-
console.log(buildTree(data, scriptMap, startIndex).trim());
|
|
171
|
-
|
|
172
|
-
} catch (err) {
|
|
173
|
-
console.log(JSON.stringify({ error: err.message }));
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
module.exports = { run };
|
|
1
|
+
/**
|
|
2
|
+
* add 命令 - 添加节点
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const { CCNode, CCSceneAsset, CCPrefab, CCCanvas, CCWidget, CCSprite, CCLabel, CCButton } = require('../lib/cc');
|
|
8
|
+
const { buildTree } = require('../lib/node-utils');
|
|
9
|
+
const { loadScriptMap, isPrefab } = require('../lib/fire-utils');
|
|
10
|
+
const { generateCompressedUUID } = require('../lib/utils');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 解析命令行选项
|
|
14
|
+
*/
|
|
15
|
+
function parseOptions(args, startIndex) {
|
|
16
|
+
const options = {};
|
|
17
|
+
for (let i = startIndex; i < args.length; i++) {
|
|
18
|
+
const arg = args[i];
|
|
19
|
+
if (arg.startsWith('--')) {
|
|
20
|
+
const eqIndex = arg.indexOf('=');
|
|
21
|
+
if (eqIndex > 0) {
|
|
22
|
+
const key = arg.substring(2, eqIndex);
|
|
23
|
+
let value = arg.substring(eqIndex + 1);
|
|
24
|
+
if (!isNaN(value) && value !== '') {
|
|
25
|
+
value = parseFloat(value);
|
|
26
|
+
}
|
|
27
|
+
options[key] = value;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return options;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 创建组件
|
|
36
|
+
*/
|
|
37
|
+
function createComponent(type) {
|
|
38
|
+
switch (type.toLowerCase()) {
|
|
39
|
+
case 'canvas': return new CCCanvas();
|
|
40
|
+
case 'widget': return new CCWidget();
|
|
41
|
+
case 'sprite': return new CCSprite();
|
|
42
|
+
case 'label': return new CCLabel();
|
|
43
|
+
case 'button': return new CCButton();
|
|
44
|
+
default: return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 查找节点
|
|
50
|
+
*/
|
|
51
|
+
function findNode(root, path) {
|
|
52
|
+
if (!path) return root;
|
|
53
|
+
|
|
54
|
+
const parts = path.split('/').filter(p => p);
|
|
55
|
+
if (parts.length === 0) return root;
|
|
56
|
+
|
|
57
|
+
let current = root;
|
|
58
|
+
|
|
59
|
+
// 如果路径以根节点名称开始,跳过
|
|
60
|
+
if (parts[0] === root._name) {
|
|
61
|
+
parts.shift();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
for (const part of parts) {
|
|
65
|
+
if (!current._children || current._children.length === 0) return null;
|
|
66
|
+
const found = current._children.find(c => c._name === part);
|
|
67
|
+
if (!found) return null;
|
|
68
|
+
current = found;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return current;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function run(args) {
|
|
75
|
+
if (args.length < 3) {
|
|
76
|
+
console.log(JSON.stringify({ error: '用法: cocos2d-cli add <场景.fire|预制体.prefab> <父节点路径> <节点名称> [--type=组件类型] [--x=N] [--y=N]' }));
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const filePath = args[0];
|
|
81
|
+
const parentPath = args[1];
|
|
82
|
+
const nodeName = args[2];
|
|
83
|
+
const options = parseOptions(args, 3);
|
|
84
|
+
|
|
85
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
let root;
|
|
89
|
+
let asset;
|
|
90
|
+
const json = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
91
|
+
|
|
92
|
+
if (ext === '.fire') {
|
|
93
|
+
asset = CCSceneAsset.fromJSON(json);
|
|
94
|
+
root = asset._scene;
|
|
95
|
+
} else if (ext === '.prefab') {
|
|
96
|
+
asset = CCPrefab.fromJSON(json);
|
|
97
|
+
root = asset._root;
|
|
98
|
+
} else {
|
|
99
|
+
console.log(JSON.stringify({ error: '不支持的文件类型,仅支持 .fire 和 .prefab' }));
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const parent = findNode(root, parentPath);
|
|
104
|
+
|
|
105
|
+
if (!parent) {
|
|
106
|
+
console.log(JSON.stringify({ error: `父节点不存在: ${parentPath}` }));
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// 创建节点
|
|
111
|
+
const node = new CCNode(nodeName);
|
|
112
|
+
|
|
113
|
+
// 应用属性
|
|
114
|
+
if (options.x !== undefined) node._trs.array[0] = parseFloat(options.x);
|
|
115
|
+
if (options.y !== undefined) node._trs.array[1] = parseFloat(options.y);
|
|
116
|
+
if (options.width !== undefined) node._contentSize.width = parseFloat(options.width);
|
|
117
|
+
if (options.height !== undefined) node._contentSize.height = parseFloat(options.height);
|
|
118
|
+
if (options.scaleX !== undefined) node._trs.array[7] = parseFloat(options.scaleX);
|
|
119
|
+
if (options.scaleY !== undefined) node._trs.array[8] = parseFloat(options.scaleY);
|
|
120
|
+
if (options.rotation !== undefined) {
|
|
121
|
+
node._trs.array[5] = parseFloat(options.rotation) * Math.PI / 180;
|
|
122
|
+
node._eulerAngles.z = parseFloat(options.rotation);
|
|
123
|
+
}
|
|
124
|
+
if (options.active !== undefined) {
|
|
125
|
+
node._active = options.active !== 'false' && options.active !== false;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 添加组件
|
|
129
|
+
if (options.type) {
|
|
130
|
+
const comp = createComponent(options.type);
|
|
131
|
+
if (comp) {
|
|
132
|
+
comp.node = node;
|
|
133
|
+
node._components = [comp];
|
|
134
|
+
|
|
135
|
+
// 组件特殊属性
|
|
136
|
+
if (options.type.toLowerCase() === 'label') {
|
|
137
|
+
if (options.string) {
|
|
138
|
+
comp._string = options.string;
|
|
139
|
+
comp['_N$string'] = options.string;
|
|
140
|
+
}
|
|
141
|
+
if (options.fontSize) {
|
|
142
|
+
comp._fontSize = parseInt(options.fontSize);
|
|
143
|
+
comp._lineHeight = parseInt(options.fontSize);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 添加节点到父节点
|
|
150
|
+
parent._children = parent._children || [];
|
|
151
|
+
parent._children.push(node);
|
|
152
|
+
node._parent = parent;
|
|
153
|
+
|
|
154
|
+
// 场景节点需要 _id,预制体需要 PrefabInfo
|
|
155
|
+
if (ext === '.fire') {
|
|
156
|
+
node._id = generateCompressedUUID();
|
|
157
|
+
} else if (ext === '.prefab') {
|
|
158
|
+
const { CCPrefabInfo } = require('../lib/cc');
|
|
159
|
+
node._prefab = new CCPrefabInfo();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// 保存
|
|
163
|
+
const data = asset.toJSON();
|
|
164
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf8');
|
|
165
|
+
|
|
166
|
+
// 输出节点树
|
|
167
|
+
const scriptMap = loadScriptMap(filePath);
|
|
168
|
+
const prefab = isPrefab(data);
|
|
169
|
+
const startIndex = prefab ? 0 : 1;
|
|
170
|
+
console.log(buildTree(data, scriptMap, startIndex).trim());
|
|
171
|
+
|
|
172
|
+
} catch (err) {
|
|
173
|
+
console.log(JSON.stringify({ error: err.message }));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
module.exports = { run };
|
package/src/commands/build.js
CHANGED
|
@@ -1,78 +1,78 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* build 命令 - 构建组件映射
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const fs = require('fs');
|
|
6
|
-
const path = require('path');
|
|
7
|
-
|
|
8
|
-
function run(args) {
|
|
9
|
-
if (args.length < 1) {
|
|
10
|
-
console.log(JSON.stringify({ error: '用法: cocos2d-cli build <项目目录>' }));
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const projectDir = args[0];
|
|
15
|
-
const importsDir = path.join(projectDir, 'library', 'imports');
|
|
16
|
-
const outputFile = path.join(__dirname, '../../data/script_map.json');
|
|
17
|
-
|
|
18
|
-
if (!fs.existsSync(importsDir)) {
|
|
19
|
-
console.log(JSON.stringify({ error: `imports 目录不存在: ${importsDir}` }));
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const scriptMap = {};
|
|
24
|
-
let processedCount = 0;
|
|
25
|
-
|
|
26
|
-
function scanDirectory(dir) {
|
|
27
|
-
const items = fs.readdirSync(dir);
|
|
28
|
-
|
|
29
|
-
for (const item of items) {
|
|
30
|
-
const fullPath = path.join(dir, item);
|
|
31
|
-
const stat = fs.statSync(fullPath);
|
|
32
|
-
|
|
33
|
-
if (stat.isDirectory()) {
|
|
34
|
-
scanDirectory(fullPath);
|
|
35
|
-
} else if (item.endsWith('.js')) {
|
|
36
|
-
try {
|
|
37
|
-
const content = fs.readFileSync(fullPath, 'utf8');
|
|
38
|
-
|
|
39
|
-
// 查找 cc._RF.push 调用
|
|
40
|
-
const match = content.match(/cc\._RF\.push\(module,\s*['"]([^'"]+)['"],\s*['"]([^'"]+)['"]\)/);
|
|
41
|
-
|
|
42
|
-
if (match) {
|
|
43
|
-
const hash = match[1];
|
|
44
|
-
const className = match[2];
|
|
45
|
-
|
|
46
|
-
// 只存储脚本相关的哈希(不以 'cc.' 开头的)
|
|
47
|
-
if (!className.startsWith('cc.')) {
|
|
48
|
-
scriptMap[hash] = className;
|
|
49
|
-
processedCount++;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
} catch (err) {
|
|
53
|
-
// 忽略读取错误
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
scanDirectory(importsDir);
|
|
60
|
-
|
|
61
|
-
// 确保输出目录存在
|
|
62
|
-
const outputDir = path.dirname(outputFile);
|
|
63
|
-
if (!fs.existsSync(outputDir)) {
|
|
64
|
-
fs.mkdirSync(outputDir, { recursive: true });
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// 写入输出文件
|
|
68
|
-
fs.writeFileSync(outputFile, JSON.stringify(scriptMap, null, 2), 'utf8');
|
|
69
|
-
|
|
70
|
-
console.log(JSON.stringify({
|
|
71
|
-
success: true,
|
|
72
|
-
count: Object.keys(scriptMap).length,
|
|
73
|
-
outputFile,
|
|
74
|
-
message: `构建完成,共 ${Object.keys(scriptMap).length} 个脚本映射`
|
|
75
|
-
}, null, 2));
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
module.exports = { run };
|
|
1
|
+
/**
|
|
2
|
+
* build 命令 - 构建组件映射
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
|
|
8
|
+
function run(args) {
|
|
9
|
+
if (args.length < 1) {
|
|
10
|
+
console.log(JSON.stringify({ error: '用法: cocos2d-cli build <项目目录>' }));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const projectDir = args[0];
|
|
15
|
+
const importsDir = path.join(projectDir, 'library', 'imports');
|
|
16
|
+
const outputFile = path.join(__dirname, '../../data/script_map.json');
|
|
17
|
+
|
|
18
|
+
if (!fs.existsSync(importsDir)) {
|
|
19
|
+
console.log(JSON.stringify({ error: `imports 目录不存在: ${importsDir}` }));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const scriptMap = {};
|
|
24
|
+
let processedCount = 0;
|
|
25
|
+
|
|
26
|
+
function scanDirectory(dir) {
|
|
27
|
+
const items = fs.readdirSync(dir);
|
|
28
|
+
|
|
29
|
+
for (const item of items) {
|
|
30
|
+
const fullPath = path.join(dir, item);
|
|
31
|
+
const stat = fs.statSync(fullPath);
|
|
32
|
+
|
|
33
|
+
if (stat.isDirectory()) {
|
|
34
|
+
scanDirectory(fullPath);
|
|
35
|
+
} else if (item.endsWith('.js')) {
|
|
36
|
+
try {
|
|
37
|
+
const content = fs.readFileSync(fullPath, 'utf8');
|
|
38
|
+
|
|
39
|
+
// 查找 cc._RF.push 调用
|
|
40
|
+
const match = content.match(/cc\._RF\.push\(module,\s*['"]([^'"]+)['"],\s*['"]([^'"]+)['"]\)/);
|
|
41
|
+
|
|
42
|
+
if (match) {
|
|
43
|
+
const hash = match[1];
|
|
44
|
+
const className = match[2];
|
|
45
|
+
|
|
46
|
+
// 只存储脚本相关的哈希(不以 'cc.' 开头的)
|
|
47
|
+
if (!className.startsWith('cc.')) {
|
|
48
|
+
scriptMap[hash] = className;
|
|
49
|
+
processedCount++;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
} catch (err) {
|
|
53
|
+
// 忽略读取错误
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
scanDirectory(importsDir);
|
|
60
|
+
|
|
61
|
+
// 确保输出目录存在
|
|
62
|
+
const outputDir = path.dirname(outputFile);
|
|
63
|
+
if (!fs.existsSync(outputDir)) {
|
|
64
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 写入输出文件
|
|
68
|
+
fs.writeFileSync(outputFile, JSON.stringify(scriptMap, null, 2), 'utf8');
|
|
69
|
+
|
|
70
|
+
console.log(JSON.stringify({
|
|
71
|
+
success: true,
|
|
72
|
+
count: Object.keys(scriptMap).length,
|
|
73
|
+
outputFile,
|
|
74
|
+
message: `构建完成,共 ${Object.keys(scriptMap).length} 个脚本映射`
|
|
75
|
+
}, null, 2));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
module.exports = { run };
|