@ives_xxz/packages 1.0.1 → 1.0.3

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.
@@ -0,0 +1,320 @@
1
+ const FS = require('fire-fs');
2
+ const Path = require('path');
3
+
4
+ module.exports = {
5
+ backupMap: new Map(),
6
+ isProcessing: false,
7
+
8
+ load() {
9
+ Editor.log('[皮肤管理器] 插件加载');
10
+ Editor.Builder.on('build-start', this.onBuildStart.bind(this));
11
+ Editor.Builder.on('build-finished', this.onBuildFinished.bind(this));
12
+ },
13
+
14
+ unload() {
15
+ Editor.log('[皮肤管理器] 插件卸载');
16
+ Editor.Builder.removeListener('build-start', this.onBuildStart);
17
+ Editor.Builder.removeListener('build-finished', this.onBuildFinished);
18
+ },
19
+
20
+ messages: {
21
+ open() {
22
+ Editor.Panel.open('multi-skin');
23
+ },
24
+
25
+ 'get-config'(event) {
26
+ try {
27
+ const config = this.loadConfig();
28
+ Editor.log('[皮肤管理器] 返回配置给面板:', config);
29
+ if (event.reply) {
30
+ event.reply(null, config);
31
+ }
32
+ return config;
33
+ } catch (error) {
34
+ Editor.error('[皮肤管理器] 获取配置失败:', error);
35
+ if (event.reply) {
36
+ event.reply(error, null);
37
+ }
38
+ return null;
39
+ }
40
+ },
41
+
42
+ 'save-config'(event, config) {
43
+ try {
44
+ const configPath = Path.join(__dirname, '../../../../', 'skin-config.json');
45
+ FS.writeFileSync(configPath, JSON.stringify(config, null, 2));
46
+ Editor.log('[皮肤管理器] 保存配置成功:', config);
47
+
48
+ if (event.reply) {
49
+ event.reply(null, { success: true });
50
+ }
51
+ return { success: true };
52
+ } catch (error) {
53
+ Editor.error('[皮肤管理器] 保存配置失败:', error);
54
+ if (event.reply) {
55
+ event.reply(null, { success: false, error: error.message });
56
+ }
57
+ return { success: false, error: error.message };
58
+ }
59
+ },
60
+ },
61
+
62
+ loadConfig() {
63
+ try {
64
+ const configPath = Path.join(__dirname, '../../../../', 'skin-config.json');
65
+
66
+ if (FS.existsSync(configPath)) {
67
+ const content = FS.readFileSync(configPath, 'utf8');
68
+ return JSON.parse(content);
69
+ } else {
70
+ const defaultConfig = { enabled: false, currentSkin: '' };
71
+ FS.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2));
72
+ return defaultConfig;
73
+ }
74
+ } catch (error) {
75
+ Editor.warn('[皮肤管理器] 加载配置失败:', error);
76
+ return { enabled: false, currentSkin: '' };
77
+ }
78
+ },
79
+
80
+ findAllSkinDirectories() {
81
+ const projectPath = Editor.Project.path;
82
+ const assetsPath = Path.join(projectPath, 'assets');
83
+ const skinDirectories = [];
84
+
85
+ const findSkinDirs = (dirPath) => {
86
+ try {
87
+ const items = FS.readdirSync(dirPath);
88
+
89
+ for (const item of items) {
90
+ const fullPath = Path.join(dirPath, item);
91
+
92
+ try {
93
+ const stat = FS.statSync(fullPath);
94
+
95
+ if (stat.isDirectory()) {
96
+ if (item.toLowerCase() === 'skin') {
97
+ const skinItems = FS.readdirSync(fullPath);
98
+ for (const skinItem of skinItems) {
99
+ const skinItemPath = Path.join(fullPath, skinItem);
100
+ try {
101
+ const skinStat = FS.statSync(skinItemPath);
102
+ if (skinStat.isDirectory()) {
103
+ const metaPath = skinItemPath + '.meta';
104
+ const hasMeta = FS.existsSync(metaPath);
105
+
106
+ skinDirectories.push({
107
+ skinName: skinItem,
108
+ skinPath: skinItemPath,
109
+ metaPath: hasMeta ? metaPath : null,
110
+ parentPath: fullPath,
111
+ relativePath: Path.relative(assetsPath, skinItemPath),
112
+ });
113
+ }
114
+ } catch (e) {}
115
+ }
116
+ }
117
+
118
+ findSkinDirs(fullPath);
119
+ }
120
+ } catch (e) {}
121
+ }
122
+ } catch (error) {}
123
+ };
124
+
125
+ if (FS.existsSync(assetsPath)) {
126
+ findSkinDirs(assetsPath);
127
+ }
128
+
129
+ return skinDirectories;
130
+ },
131
+
132
+ onBuildStart(options, callback) {
133
+ if (this.isProcessing) {
134
+ Editor.log('[皮肤管理器] 正在处理,跳过');
135
+ callback();
136
+ return;
137
+ }
138
+
139
+ this.isProcessing = true;
140
+
141
+ try {
142
+ const config = this.loadConfig();
143
+
144
+ if (!config.enabled) {
145
+ Editor.log('[皮肤管理器] 功能未启用,跳过处理');
146
+ this.isProcessing = false;
147
+ callback();
148
+ return;
149
+ }
150
+
151
+ const currentSkin = config.currentSkin;
152
+ if (!currentSkin) {
153
+ Editor.warn('[皮肤管理器] 未指定当前皮肤,跳过处理');
154
+ this.isProcessing = false;
155
+ callback();
156
+ return;
157
+ }
158
+
159
+ Editor.log(`[皮肤管理器] 构建开始,处理皮肤资源,保留: ${currentSkin}`);
160
+
161
+ this.backupMap.clear();
162
+
163
+ const projectPath = Editor.Project.path;
164
+ const backupRoot = Path.join(projectPath, 'backups');
165
+ if (!FS.existsSync(backupRoot)) {
166
+ FS.mkdirSync(backupRoot);
167
+ }
168
+
169
+ const skinDirectories = this.findAllSkinDirectories();
170
+ Editor.log(`[皮肤管理器] 找到 ${skinDirectories.length} 个皮肤目录`);
171
+
172
+ let movedCount = 0;
173
+
174
+ for (const directory of skinDirectories) {
175
+ if (directory.skinName === currentSkin) {
176
+ Editor.log(`[皮肤管理器] 保留: ${directory.relativePath}`);
177
+ continue;
178
+ }
179
+
180
+ const relativeToAssets = Path.relative(
181
+ Path.join(projectPath, 'assets'),
182
+ directory.skinPath
183
+ );
184
+ const backupPath = Path.join(backupRoot, relativeToAssets);
185
+ const backupMetaPath = backupPath + '.meta';
186
+
187
+ const backupDir = Path.dirname(backupPath);
188
+ if (!FS.existsSync(backupDir)) {
189
+ FS.mkdirsSync(backupDir);
190
+ }
191
+
192
+ try {
193
+ FS.renameSync(directory.skinPath, backupPath);
194
+
195
+ if (directory.metaPath && FS.existsSync(directory.metaPath)) {
196
+ FS.renameSync(directory.metaPath, backupMetaPath);
197
+ Editor.log(`[皮肤管理器] 已移动.meta文件: ${directory.metaPath}`);
198
+ }
199
+
200
+ this.backupMap.set(directory.skinPath, {
201
+ backupPath: backupPath,
202
+ backupMetaPath: directory.metaPath ? backupMetaPath : null,
203
+ originalMetaPath: directory.metaPath,
204
+ skinName: directory.skinName,
205
+ parentPath: directory.parentPath,
206
+ });
207
+
208
+ movedCount++;
209
+
210
+ Editor.log(`[皮肤管理器] 已移动: ${directory.relativePath}`);
211
+ } catch (error) {
212
+ Editor.error(`[皮肤管理器] 移动失败: ${directory.skinPath}`, error);
213
+ if (FS.existsSync(backupPath)) {
214
+ try {
215
+ FS.renameSync(backupPath, directory.skinPath);
216
+ if (FS.existsSync(backupMetaPath) && directory.metaPath) {
217
+ FS.renameSync(backupMetaPath, directory.metaPath);
218
+ }
219
+ } catch (recoveryError) {
220
+ Editor.error(`[皮肤管理器] 恢复失败: ${directory.skinPath}`, recoveryError);
221
+ }
222
+ }
223
+ }
224
+ }
225
+
226
+ Editor.log(`[皮肤管理器] 已移动 ${movedCount} 个非当前皮肤目录到备份文件夹`);
227
+
228
+ setTimeout(() => {
229
+ this.isProcessing = false;
230
+ callback?.();
231
+ }, 500);
232
+ } catch (error) {
233
+ Editor.error('[皮肤管理器] 处理皮肤文件夹失败:', error);
234
+
235
+ this.restoreSkinFolders().finally(() => {
236
+ this.isProcessing = false;
237
+ callback?.(error);
238
+ });
239
+ }
240
+ },
241
+
242
+ onBuildFinished(options, result, callback) {
243
+ Editor.log('[皮肤管理器] 构建完成,开始恢复皮肤文件夹');
244
+
245
+ this.restoreSkinFolders()
246
+ .then(() => {
247
+ callback?.();
248
+ })
249
+ .catch((error) => {
250
+ Editor.error('[皮肤管理器] 恢复皮肤文件夹失败:', error);
251
+ callback?.(error);
252
+ });
253
+ },
254
+
255
+ restoreSkinFolders() {
256
+ return new Promise((resolve, reject) => {
257
+ if (this.backupMap.size === 0) {
258
+ resolve();
259
+ return;
260
+ }
261
+
262
+ Editor.log('[皮肤管理器] 开始恢复皮肤文件夹...');
263
+ let restoredCount = 0;
264
+
265
+ for (const [originalPath, backupInfo] of this.backupMap) {
266
+ const { backupPath, backupMetaPath, originalMetaPath } = backupInfo;
267
+
268
+ try {
269
+ if (FS.existsSync(backupPath)) {
270
+ if (FS.existsSync(originalPath)) {
271
+ FS.removeSync(originalPath);
272
+ }
273
+
274
+ if (originalMetaPath && FS.existsSync(originalMetaPath)) {
275
+ FS.removeSync(originalMetaPath);
276
+ }
277
+
278
+ const originalDir = Path.dirname(originalPath);
279
+ if (!FS.existsSync(originalDir)) {
280
+ FS.mkdirsSync(originalDir);
281
+ }
282
+
283
+ FS.renameSync(backupPath, originalPath);
284
+
285
+ if (backupMetaPath && FS.existsSync(backupMetaPath) && originalMetaPath) {
286
+ FS.renameSync(backupMetaPath, originalMetaPath);
287
+ Editor.log(`[皮肤管理器] 已恢复.meta文件: ${originalMetaPath}`);
288
+ }
289
+
290
+ restoredCount++;
291
+
292
+ Editor.log(`[皮肤管理器] 已恢复: ${originalPath}`);
293
+ } else {
294
+ Editor.warn(`[皮肤管理器] 备份文件不存在: ${backupPath}`);
295
+ }
296
+ } catch (error) {
297
+ Editor.error(`[皮肤管理器] 恢复失败: ${originalPath}`, error);
298
+ }
299
+ }
300
+
301
+ try {
302
+ const projectPath = Editor.Project.path;
303
+ const backupRoot = Path.join(projectPath, 'backups');
304
+ if (FS.existsSync(backupRoot)) {
305
+ FS.removeSync(backupRoot);
306
+ Editor.log(`[皮肤管理器] 已删除备份文件夹: ${backupRoot}`);
307
+ }
308
+ } catch (error) {
309
+ Editor.error('[皮肤管理器] 删除备份文件夹失败:', error);
310
+ }
311
+
312
+ this.backupMap.clear();
313
+ Editor.log(`[皮肤管理器] 恢复完成,共恢复 ${restoredCount} 个文件夹`);
314
+
315
+ setTimeout(() => {
316
+ resolve();
317
+ }, 500);
318
+ });
319
+ },
320
+ };
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "multi-skin",
3
+ "version": "1.0.0",
4
+ "description": "皮肤构建管理插件",
5
+ "author": "ives",
6
+ "main": "main.js",
7
+ "main-menu": {
8
+ "i18n:MAIN_MENU.package.title/皮肤管理器": {
9
+ "message": "multi-skin:open"
10
+ }
11
+ },
12
+ "panel": {
13
+ "main": "panel/index.js",
14
+ "type": "dockable",
15
+ "title": "皮肤管理器",
16
+ "width": 1334,
17
+ "height": 600
18
+ },
19
+ "contributions": {
20
+ "builder": {
21
+ "hooks": "./main.js"
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,306 @@
1
+ Editor.Panel.extend({
2
+ style: `
3
+ .container {
4
+ padding: 20px;
5
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
6
+ }
7
+
8
+ .header {
9
+ margin-bottom: 30px;
10
+ padding-bottom: 15px;
11
+ border-bottom: 2px solid #1890ff;
12
+ }
13
+
14
+ .config-section {
15
+ margin-bottom: 30px;
16
+ padding: 20px;
17
+ background: #f6f8fa;
18
+ border-radius: 6px;
19
+ border: 1px solid #e1e4e8;
20
+ }
21
+
22
+ .config-row {
23
+ display: flex;
24
+ align-items: center;
25
+ margin-bottom: 15px;
26
+ }
27
+
28
+ .config-label {
29
+ width: 120px;
30
+ font-weight: 500;
31
+ font-size: 14px;
32
+ }
33
+
34
+ .skin-input {
35
+ flex: 1;
36
+ padding: 8px 12px;
37
+ border: 1px solid #d9d9d9;
38
+ border-radius: 4px;
39
+ font-size: 14px;
40
+ }
41
+
42
+ .tip {
43
+ font-size: 12px;
44
+ color: #666;
45
+ margin-top: 8px;
46
+ }
47
+
48
+ .tip code {
49
+ background: #f0f0f0;
50
+ padding: 2px 6px;
51
+ border-radius: 3px;
52
+ font-family: monospace;
53
+ }
54
+
55
+ .footer {
56
+ display: flex;
57
+ justify-content: space-between;
58
+ align-items: center;
59
+ margin-top: 20px;
60
+ }
61
+
62
+ .message {
63
+ padding: 10px 15px;
64
+ border-radius: 4px;
65
+ margin-bottom: 15px;
66
+ font-size: 13px;
67
+ display: none;
68
+ }
69
+
70
+ .message.success {
71
+ background: #f6ffed;
72
+ border: 1px solid #b7eb8f;
73
+ color: #52c41a;
74
+ display: block;
75
+ }
76
+
77
+ .message.error {
78
+ background: #fff2f0;
79
+ border: 1px solid #ffccc7;
80
+ color: #f5222d;
81
+ display: block;
82
+ }
83
+
84
+ .message.info {
85
+ background: #e6f7ff;
86
+ border: 1px solid #91d5ff;
87
+ color: #1890ff;
88
+ display: block;
89
+ }
90
+
91
+ .status {
92
+ font-size: 14px;
93
+ font-weight: 500;
94
+ min-height: 24px;
95
+ display: flex;
96
+ align-items: center;
97
+ }
98
+
99
+ .status-icon {
100
+ display: inline-block;
101
+ margin-right: 6px;
102
+ font-size: 16px;
103
+ }
104
+
105
+ .loading {
106
+ opacity: 0.6;
107
+ pointer-events: none;
108
+ }
109
+ `,
110
+
111
+ template: `
112
+ <div class="container" id="container">
113
+ <div class="header">
114
+ <h2>🎨 皮肤管理器</h2>
115
+ <p>构建时只保留指定皮肤,自动剔除其他skin文件夹</p>
116
+ </div>
117
+
118
+ <div class="config-section">
119
+ <div class="config-row">
120
+ <div class="config-label">当前皮肤:</div>
121
+ <input
122
+ type="text"
123
+ class="skin-input"
124
+ id="skinInput"
125
+ placeholder="请输入皮肤名称"
126
+ disabled
127
+ >
128
+ </div>
129
+
130
+ <div class="config-row">
131
+ <div class="config-label">启用功能:</div>
132
+ <ui-checkbox id="enableCheckbox" disabled></ui-checkbox>
133
+ </div>
134
+ </div>
135
+
136
+ <div class="message" id="message"></div>
137
+
138
+ <div class="footer">
139
+ <div class="status" id="status">
140
+ <span class="status-icon">⏳</span>
141
+ <span>正在加载配置...</span>
142
+ </div>
143
+ <div>
144
+ <ui-button id="saveBtn" class="green" disabled>💾 保存配置</ui-button>
145
+ </div>
146
+ </div>
147
+ </div>
148
+ `,
149
+
150
+ $: {
151
+ container: '#container',
152
+ skinInput: '#skinInput',
153
+ enableCheckbox: '#enableCheckbox',
154
+ saveBtn: '#saveBtn',
155
+ message: '#message',
156
+ status: '#status',
157
+ },
158
+
159
+ ready() {
160
+ Editor.log('皮肤管理器面板已加载');
161
+
162
+ this.$saveBtn.addEventListener('confirm', () => {
163
+ this.saveConfig();
164
+ });
165
+
166
+ this.$skinInput.addEventListener('input', () => {
167
+ this.updateStatus();
168
+ });
169
+
170
+ this.$skinInput.addEventListener('change', () => {
171
+ this.updateStatus();
172
+ });
173
+
174
+ this.$enableCheckbox.addEventListener('change', () => {
175
+ this.updateStatus();
176
+ });
177
+
178
+ this.loadConfig();
179
+ },
180
+
181
+ async loadConfig() {
182
+ try {
183
+ this.showMessage('正在加载配置...', 'info');
184
+
185
+ const config = await new Promise((resolve, reject) => {
186
+ Editor.Ipc.sendToMain('multi-skin:get-config', (error, result) => {
187
+ if (error) reject(error);
188
+ else resolve(result);
189
+ });
190
+ });
191
+
192
+ Editor.log('从IPC加载到的配置:', config);
193
+
194
+ if (!config) {
195
+ throw new Error('配置加载为空');
196
+ }
197
+
198
+ this.$skinInput.value = config.currentSkin || '';
199
+ this.$enableCheckbox.checked = config.enabled || false;
200
+
201
+ this.$skinInput.disabled = false;
202
+ this.$enableCheckbox.disabled = false;
203
+ this.$saveBtn.disabled = false;
204
+ this.$container.classList.remove('loading');
205
+
206
+ this.updateStatus(true);
207
+
208
+ if (config.currentSkin) {
209
+ this.showMessage(
210
+ `配置已加载: ${config.enabled ? '启用' : '禁用'} - 皮肤: ${config.currentSkin}`,
211
+ 'success'
212
+ );
213
+ } else {
214
+ this.showMessage('配置已加载,未设置皮肤', 'info');
215
+ }
216
+ } catch (error) {
217
+ Editor.error('加载配置失败:', error);
218
+ this.showMessage(`加载配置失败: ${error.message},使用默认配置`, 'error');
219
+
220
+ this.$skinInput.value = '';
221
+ this.$enableCheckbox.checked = false;
222
+ this.$skinInput.disabled = false;
223
+ this.$enableCheckbox.disabled = false;
224
+ this.$saveBtn.disabled = false;
225
+ this.$container.classList.remove('loading');
226
+ this.updateStatus(true);
227
+ }
228
+ },
229
+
230
+ updateStatus(isInitialLoad = false) {
231
+ const enabled = this.$enableCheckbox.checked;
232
+ const skin = this.$skinInput.value.trim();
233
+
234
+ let icon = '';
235
+ let text = '';
236
+ let color = '';
237
+
238
+ if (!enabled) {
239
+ icon = '⭕';
240
+ text = skin ? `功能已禁用 (配置皮肤: ${skin})` : '功能已禁用,未设置皮肤';
241
+ color = '#999';
242
+ } else if (!skin) {
243
+ icon = '⚠️';
244
+ text = '请填写皮肤名称';
245
+ color = '#faad14';
246
+ } else {
247
+ icon = '✅';
248
+ text = `已启用,将保留皮肤: ${skin}`;
249
+ color = '#52c41a';
250
+ }
251
+
252
+ this.$status.innerHTML = `<span class="status-icon">${icon}</span><span>${text}</span>`;
253
+ this.$status.style.color = color;
254
+ },
255
+
256
+ async saveConfig() {
257
+ const enabled = this.$enableCheckbox.checked;
258
+ const skin = this.$skinInput.value.trim();
259
+
260
+ if (enabled && !skin) {
261
+ this.showMessage('启用功能时必须填写皮肤名称', 'error');
262
+ return;
263
+ }
264
+
265
+ try {
266
+ const config = {
267
+ enabled: enabled,
268
+ currentSkin: skin,
269
+ };
270
+
271
+ const result = await new Promise((resolve, reject) => {
272
+ Editor.Ipc.sendToMain('multi-skin:save-config', config, (error, result) => {
273
+ if (error) reject(error);
274
+ else resolve(result);
275
+ });
276
+ });
277
+
278
+ if (result.success) {
279
+ let message = '配置已保存';
280
+ if (enabled) {
281
+ message += `,构建时将保留皮肤: ${skin}`;
282
+ } else {
283
+ message += ',功能已禁用';
284
+ }
285
+ this.showMessage(message, 'success');
286
+ this.updateStatus();
287
+ } else {
288
+ this.showMessage('保存失败: ' + (result.error || '未知错误'), 'error');
289
+ }
290
+ } catch (error) {
291
+ Editor.error('保存配置失败:', error);
292
+ this.showMessage(`保存失败: ${error.message}`, 'error');
293
+ }
294
+ },
295
+
296
+ showMessage(text, type = 'info') {
297
+ const msg = this.$message;
298
+ msg.textContent = text;
299
+ msg.className = 'message ' + type;
300
+
301
+ setTimeout(() => {
302
+ msg.className = 'message';
303
+ msg.textContent = '';
304
+ }, 3000);
305
+ },
306
+ });
@@ -9,7 +9,7 @@ const configFileName = 'ccc-png-auto-compress.json';
9
9
 
10
10
  /** 默认配置 */
11
11
  const defaultConfig = {
12
- enabled: true,
12
+ enabled: false,
13
13
  minQuality: 40,
14
14
  maxQuality: 80,
15
15
  colors: 256,
package/package.json CHANGED
@@ -1,12 +1,10 @@
1
1
  {
2
2
  "name": "@ives_xxz/packages",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "cocoscreator 2.x plugins",
5
5
  "main": "index.js",
6
- "scripts": {
7
- },
6
+ "scripts": {},
8
7
  "keywords": ["123456"],
9
8
  "author": "ives",
10
9
  "license": "ISC"
11
-
12
10
  }