sapdon 3.1.0 → 3.2.0
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/README.md +8 -1
- package/doc/api.md +2 -2
- package/package.json +18 -19
- package/{dist → prod}/cli/index.d.ts +1 -1
- package/prod/cli/index.js +1 -0
- package/{dist → prod}/cli/start.js +997 -967
- package/{dist → prod}/core/index.d.ts +2155 -1652
- package/prod/core/index.js +59017 -0
- package/prod/utils/index.d.ts +41 -0
- package/prod/utils/index.js +1 -0
- package/dist/cli/build.d.ts +0 -7
- package/dist/cli/build.js +0 -236
- package/dist/cli/dev-server/client.d.ts +0 -2
- package/dist/cli/dev-server/client.js +0 -21
- package/dist/cli/dev-server/config.d.ts +0 -3
- package/dist/cli/dev-server/config.js +0 -3
- package/dist/cli/dev-server/handles.d.ts +0 -4
- package/dist/cli/dev-server/handles.js +0 -5
- package/dist/cli/dev-server/hmr.d.ts +0 -1
- package/dist/cli/dev-server/hmr.js +0 -13
- package/dist/cli/dev-server/index.d.ts +0 -4
- package/dist/cli/dev-server/index.js +0 -17
- package/dist/cli/dev-server/server.d.ts +0 -14
- package/dist/cli/dev-server/server.js +0 -59
- package/dist/cli/dev-server/syncFiles.d.ts +0 -3
- package/dist/cli/dev-server/syncFiles.js +0 -45
- package/dist/cli/index.js +0 -90
- package/dist/cli/init.d.ts +0 -9
- package/dist/cli/init.js +0 -80
- package/dist/cli/load.d.ts +0 -3
- package/dist/cli/load.js +0 -94
- package/dist/cli/start.d.ts +0 -2
- package/dist/cli/tools/textureSet.d.ts +0 -13
- package/dist/cli/tools/textureSet.js +0 -103
- package/dist/cli/utils.d.ts +0 -13
- package/dist/cli/utils.js +0 -89
- package/dist/core/addon/biome.d.ts +0 -22
- package/dist/core/addon/biome.js +0 -27
- package/dist/core/addon/block/block.d.ts +0 -41
- package/dist/core/addon/block/block.js +0 -46
- package/dist/core/addon/controllers/animationController.d.ts +0 -43
- package/dist/core/addon/controllers/animationController.js +0 -73
- package/dist/core/addon/controllers/render_controllers.js +0 -162
- package/dist/core/addon/entity/clientEntity.d.ts +0 -107
- package/dist/core/addon/entity/clientEntity.js +0 -149
- package/dist/core/addon/entity/entity.d.ts +0 -42
- package/dist/core/addon/entity/entity.js +0 -50
- package/dist/core/addon/feature/oreFeature.d.ts +0 -19
- package/dist/core/addon/feature/oreFeature.js +0 -24
- package/dist/core/addon/featureRule.d.ts +0 -20
- package/dist/core/addon/featureRule.js +0 -25
- package/dist/core/addon/item/attachable.d.ts +0 -94
- package/dist/core/addon/item/attachable.js +0 -134
- package/dist/core/addon/item/item.d.ts +0 -19
- package/dist/core/addon/item/item.js +0 -26
- package/dist/core/addon/manifest.d.ts +0 -49
- package/dist/core/addon/manifest.js +0 -65
- package/dist/core/addon/menuCategory.d.ts +0 -6
- package/dist/core/addon/menuCategory.js +0 -7
- package/dist/core/addon/recipe/baseRecipe.d.ts +0 -12
- package/dist/core/addon/recipe/baseRecipe.js +0 -23
- package/dist/core/addon/recipe/data.d.ts +0 -66
- package/dist/core/addon/recipe/data.js +0 -74
- package/dist/core/addon/recipe/furnace.d.ts +0 -17
- package/dist/core/addon/recipe/furnace.js +0 -43
- package/dist/core/addon/recipe/shaped.d.ts +0 -26
- package/dist/core/addon/recipe/shaped.js +0 -53
- package/dist/core/addon/recipe/shapeless.d.ts +0 -18
- package/dist/core/addon/recipe/shapeless.js +0 -36
- package/dist/core/biome/biome.d.ts +0 -14
- package/dist/core/biome/biome.js +0 -23
- package/dist/core/biome/biomeComponent.d.ts +0 -46
- package/dist/core/biome/biomeComponent.js +0 -77
- package/dist/core/block/basicBlock.d.ts +0 -48
- package/dist/core/block/basicBlock.js +0 -105
- package/dist/core/block/block.d.ts +0 -32
- package/dist/core/block/block.js +0 -92
- package/dist/core/block/blockComponent.d.ts +0 -187
- package/dist/core/block/blockComponent.js +0 -500
- package/dist/core/block/cropBlock.d.ts +0 -4
- package/dist/core/block/cropBlock.js +0 -27
- package/dist/core/block/geometryBlock.d.ts +0 -12
- package/dist/core/block/geometryBlock.js +0 -16
- package/dist/core/block/oreBlock.d.ts +0 -9
- package/dist/core/block/oreBlock.js +0 -25
- package/dist/core/block/rotatableBlock.d.ts +0 -27
- package/dist/core/block/rotatableBlock.js +0 -107
- package/dist/core/block/tileBlock.d.ts +0 -17
- package/dist/core/block/tileBlock.js +0 -125
- package/dist/core/entity/basicEntity.d.ts +0 -111
- package/dist/core/entity/basicEntity.js +0 -170
- package/dist/core/entity/behavior/followMob.d.ts +0 -12
- package/dist/core/entity/behavior/followMob.js +0 -35
- package/dist/core/entity/behavior/followParent.d.ts +0 -7
- package/dist/core/entity/behavior/followParent.js +0 -15
- package/dist/core/entity/behavior/randomStroll.d.ts +0 -31
- package/dist/core/entity/behavior/randomStroll.js +0 -63
- package/dist/core/entity/behavior/tempt.d.ts +0 -73
- package/dist/core/entity/behavior/tempt.js +0 -134
- package/dist/core/entity/bundles/BasicMoveBundle.js +0 -8
- package/dist/core/entity/bundles/basicBundle.d.ts +0 -13
- package/dist/core/entity/bundles/basicBundle.js +0 -38
- package/dist/core/entity/clientEntity.d.ts +0 -20
- package/dist/core/entity/clientEntity.js +0 -37
- package/dist/core/entity/componets/entityComponet.d.ts +0 -202
- package/dist/core/entity/componets/entityComponet.js +0 -354
- package/dist/core/entity/data/nativeEntityData.d.ts +0 -9
- package/dist/core/entity/data/nativeEntityData.js +0 -38
- package/dist/core/entity/dummyEntity.js +0 -14
- package/dist/core/entity/entity.d.ts +0 -15
- package/dist/core/entity/entity.js +0 -11
- package/dist/core/entity/nativeEntity.d.ts +0 -8
- package/dist/core/entity/nativeEntity.js +0 -28
- package/dist/core/entity/navigation/walk.d.ts +0 -23
- package/dist/core/entity/navigation/walk.js +0 -56
- package/dist/core/entity/projectile.d.ts +0 -3
- package/dist/core/entity/projectile.js +0 -7
- package/dist/core/factory/biomeFactory.d.ts +0 -4
- package/dist/core/factory/biomeFactory.js +0 -13
- package/dist/core/factory/blockFactory.d.ts +0 -34
- package/dist/core/factory/blockFactory.js +0 -143
- package/dist/core/factory/entityFactory.d.ts +0 -17
- package/dist/core/factory/entityFactory.js +0 -75
- package/dist/core/factory/featureFactory.d.ts +0 -6
- package/dist/core/factory/featureFactory.js +0 -23
- package/dist/core/factory/itemExtra.d.ts +0 -8
- package/dist/core/factory/itemExtra.js +0 -9
- package/dist/core/factory/itemFactory.d.ts +0 -27
- package/dist/core/factory/itemFactory.js +0 -112
- package/dist/core/factory/recipeFactory.d.ts +0 -18
- package/dist/core/factory/recipeFactory.js +0 -39
- package/dist/core/factory/uiFactory.d.ts +0 -12
- package/dist/core/factory/uiFactory.js +0 -32
- package/dist/core/feature/oreFeature.d.ts +0 -10
- package/dist/core/feature/oreFeature.js +0 -11
- package/dist/core/feature-rule/condition/biomeFilter.d.ts +0 -26
- package/dist/core/feature-rule/condition/biomeFilter.js +0 -36
- package/dist/core/feature-rule/condition/featureConditions.d.ts +0 -27
- package/dist/core/feature-rule/condition/featureConditions.js +0 -37
- package/dist/core/feature-rule/distribution/coordinateDistribution.d.ts +0 -17
- package/dist/core/feature-rule/distribution/coordinateDistribution.js +0 -23
- package/dist/core/feature-rule/distribution/featureDistribution.d.ts +0 -31
- package/dist/core/feature-rule/distribution/featureDistribution.js +0 -41
- package/dist/core/feature-rule/featureRule.d.ts +0 -17
- package/dist/core/feature-rule/featureRule.js +0 -26
- package/dist/core/index.js +0 -1
- package/dist/core/item/armor.d.ts +0 -21
- package/dist/core/item/armor.js +0 -90
- package/dist/core/item/attachable.d.ts +0 -6
- package/dist/core/item/attachable.js +0 -26
- package/dist/core/item/food.d.ts +0 -24
- package/dist/core/item/food.js +0 -38
- package/dist/core/item/item.d.ts +0 -36
- package/dist/core/item/item.js +0 -69
- package/dist/core/item/itemComponents.d.ts +0 -113
- package/dist/core/item/itemComponents.js +0 -225
- package/dist/core/registry.d.ts +0 -12
- package/dist/core/registry.js +0 -17
- package/dist/core/texture.d.ts +0 -18
- package/dist/core/texture.js +0 -38
- package/dist/core/ui/buttonMapping.d.ts +0 -97
- package/dist/core/ui/buttonMapping.js +0 -132
- package/dist/core/ui/dataBindingObject.d.ts +0 -97
- package/dist/core/ui/dataBindingObject.js +0 -134
- package/dist/core/ui/elements/button.d.ts +0 -21
- package/dist/core/ui/elements/button.js +0 -101
- package/dist/core/ui/elements/collectionPanel.d.ts +0 -12
- package/dist/core/ui/elements/collectionPanel.js +0 -53
- package/dist/core/ui/elements/grid.d.ts +0 -8
- package/dist/core/ui/elements/grid.js +0 -33
- package/dist/core/ui/elements/image.d.ts +0 -13
- package/dist/core/ui/elements/image.js +0 -55
- package/dist/core/ui/elements/label.d.ts +0 -14
- package/dist/core/ui/elements/label.js +0 -61
- package/dist/core/ui/elements/panel.d.ts +0 -11
- package/dist/core/ui/elements/panel.js +0 -49
- package/dist/core/ui/elements/scrollingPanel.d.ts +0 -14
- package/dist/core/ui/elements/scrollingPanel.js +0 -59
- package/dist/core/ui/elements/stackPanel.d.ts +0 -14
- package/dist/core/ui/elements/stackPanel.js +0 -37
- package/dist/core/ui/elements/uiElement.d.ts +0 -53
- package/dist/core/ui/elements/uiElement.js +0 -129
- package/dist/core/ui/properties/control.d.ts +0 -214
- package/dist/core/ui/properties/control.js +0 -286
- package/dist/core/ui/properties/dataBinding.d.ts +0 -6
- package/dist/core/ui/properties/dataBinding.js +0 -16
- package/dist/core/ui/properties/factory.d.ts +0 -37
- package/dist/core/ui/properties/factory.js +0 -62
- package/dist/core/ui/properties/gridProp.d.ts +0 -65
- package/dist/core/ui/properties/gridProp.js +0 -90
- package/dist/core/ui/properties/input.d.ts +0 -97
- package/dist/core/ui/properties/input.js +0 -134
- package/dist/core/ui/properties/layout.d.ts +0 -105
- package/dist/core/ui/properties/layout.js +0 -145
- package/dist/core/ui/properties/scrollView.d.ts +0 -105
- package/dist/core/ui/properties/scrollView.js +0 -145
- package/dist/core/ui/properties/sound.d.ts +0 -47
- package/dist/core/ui/properties/sound.js +0 -66
- package/dist/core/ui/properties/sprite.d.ts +0 -161
- package/dist/core/ui/properties/sprite.js +0 -222
- package/dist/core/ui/properties/text.d.ts +0 -135
- package/dist/core/ui/properties/text.js +0 -187
- package/dist/core/ui/registry/uiSystemRegistry.d.ts +0 -8
- package/dist/core/ui/registry/uiSystemRegistry.js +0 -26
- package/dist/core/ui/systems/chest.d.ts +0 -5
- package/dist/core/ui/systems/chest.js +0 -21
- package/dist/core/ui/systems/containerUISystem.d.ts +0 -67
- package/dist/core/ui/systems/containerUISystem.js +0 -214
- package/dist/core/ui/systems/guidebook.d.ts +0 -9
- package/dist/core/ui/systems/guidebook.js +0 -206
- package/dist/core/ui/systems/serverForm.d.ts +0 -13
- package/dist/core/ui/systems/serverForm.js +0 -116
- package/dist/core/ui/systems/system.d.ts +0 -16
- package/dist/core/ui/systems/system.js +0 -37
- package/dist/oc/actor.js +0 -44
- package/dist/oc/core.js +0 -201
- package/dist/oc/input.js +0 -67
- package/dist/oc/optional.js +0 -31
- /package/{dist → prod}/oc/index.d.ts +0 -0
- /package/{dist → prod}/oc/index.js +0 -0
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
import { program } from 'commander';
|
|
3
3
|
import inquirer from 'inquirer';
|
|
4
4
|
import path from 'path';
|
|
5
|
-
import os from 'os';
|
|
6
5
|
import { fileURLToPath as fileURLToPath$1 } from 'url';
|
|
7
6
|
import fs, { readFileSync } from 'fs';
|
|
8
7
|
import { randomUUID } from 'crypto';
|
|
9
8
|
import { fileURLToPath } from 'node:url';
|
|
10
9
|
import cp from 'child_process';
|
|
10
|
+
import { cacheSync } from '@sapdon/utils/cache.js';
|
|
11
11
|
import fs$1 from 'fs/promises';
|
|
12
|
+
import { serialize } from '@sapdon/utils/index.js';
|
|
12
13
|
import http from 'http';
|
|
14
|
+
import { handleRemoteLogger } from '@sapdon/cli/remoteLogger/server.js';
|
|
13
15
|
import { rollup } from 'rollup';
|
|
14
16
|
import commonjs from '@rollup/plugin-commonjs';
|
|
15
17
|
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
|
@@ -17,6 +19,8 @@ import ts from '@rollup/plugin-typescript';
|
|
|
17
19
|
import { typescriptPaths } from 'rollup-plugin-typescript-paths';
|
|
18
20
|
import json from '@rollup/plugin-json';
|
|
19
21
|
import 'rollup-plugin-visualizer';
|
|
22
|
+
import terser from '@rollup/plugin-terser';
|
|
23
|
+
import os from 'os';
|
|
20
24
|
import lodash from 'lodash';
|
|
21
25
|
|
|
22
26
|
const generateUUID = () => {
|
|
@@ -104,272 +108,348 @@ function dirname(importMeta) {
|
|
|
104
108
|
const __dirname = path.dirname(__filename);
|
|
105
109
|
return __dirname;
|
|
106
110
|
}
|
|
111
|
+
function parseJsonWithComments(jsonStr) {
|
|
112
|
+
return JSON.parse(String(jsonStr).replace(/\/\/.*|\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, "$1"));
|
|
113
|
+
}
|
|
114
|
+
|
|
107
115
|
function getBuildConfig() {
|
|
108
|
-
const pwd =
|
|
116
|
+
const pwd = getProjectPath();
|
|
109
117
|
const configFile = path.join(pwd, 'build.config');
|
|
110
118
|
if (!fs.existsSync(configFile)) {
|
|
111
119
|
throw new Error('未找到项目配置文件,请先初始化项目');
|
|
112
120
|
}
|
|
113
|
-
return
|
|
121
|
+
return cacheSync(configFile, file => parseBuildConfig(file));
|
|
122
|
+
}
|
|
123
|
+
function transferV1ToV2({ defaultConfig, resources, scripts }) {
|
|
124
|
+
const buildConfig = {
|
|
125
|
+
formatVersion: 2,
|
|
126
|
+
buildOptions: {
|
|
127
|
+
useHMR: true,
|
|
128
|
+
buildMode: 'development',
|
|
129
|
+
buildEntry: defaultConfig.buildEntry,
|
|
130
|
+
scriptEntry: defaultConfig.scriptEntry,
|
|
131
|
+
scriptOutput: defaultConfig.scriptEntry.replace('.ts', '.js'),
|
|
132
|
+
useJs: scripts[0].type === 'ts' ? false : true,
|
|
133
|
+
buildDir: defaultConfig.buildDir,
|
|
134
|
+
dependencies: defaultConfig.dependencies,
|
|
135
|
+
resource: {
|
|
136
|
+
path: resources[0].path,
|
|
137
|
+
resourceHints: true
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
versionType: 'release'
|
|
141
|
+
};
|
|
142
|
+
return buildConfig;
|
|
143
|
+
}
|
|
144
|
+
function parseBuildConfig(file) {
|
|
145
|
+
const obj = parseJsonWithComments(fs.readFileSync(file));
|
|
146
|
+
if (obj.formatVersion === 2) {
|
|
147
|
+
return obj;
|
|
148
|
+
}
|
|
149
|
+
const upgratedConfig = transferV1ToV2(obj);
|
|
150
|
+
fs.writeFileSync(file, JSON.stringify(upgratedConfig, null, 2));
|
|
151
|
+
return upgratedConfig;
|
|
114
152
|
}
|
|
115
153
|
|
|
116
|
-
// 获取当前文件的路径
|
|
117
|
-
const __filename$2 = fileURLToPath$1(import.meta.url);
|
|
118
|
-
// 获取当前文件的目录
|
|
119
|
-
const __dirname$
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
182
|
-
return {
|
|
183
|
-
name: path.basename(dir),
|
|
184
|
-
description: packageJson.description || "A new sapdon project",
|
|
185
|
-
author: packageJson.author || "Sapdon",
|
|
186
|
-
version: packageJson.version || "1.0.0"
|
|
187
|
-
}
|
|
188
|
-
} catch (error) {
|
|
189
|
-
console.error("读取package.json文件时出错:", error);
|
|
190
|
-
return null
|
|
191
|
-
}
|
|
192
|
-
} else {
|
|
193
|
-
return null
|
|
194
|
-
}
|
|
195
|
-
};
|
|
196
|
-
|
|
154
|
+
// 获取当前文件的路径
|
|
155
|
+
const __filename$2 = fileURLToPath$1(import.meta.url);
|
|
156
|
+
// 获取当前文件的目录
|
|
157
|
+
const __dirname$1 = path.dirname(__filename$2);
|
|
158
|
+
const templateMapping = {
|
|
159
|
+
js: 'js_sapdon',
|
|
160
|
+
ts: 'ts_sapdon'
|
|
161
|
+
};
|
|
162
|
+
const initProject = (projectPath, data) => {
|
|
163
|
+
console.log(1, data);
|
|
164
|
+
//检查项目目录是否存在
|
|
165
|
+
//如果不存在则创建项目目录
|
|
166
|
+
//从模板下载项目文件
|
|
167
|
+
//根据用户输入的项目信息生成项目配置文件
|
|
168
|
+
//根据用户选择是否生成脚本文件,生成脚本文件
|
|
169
|
+
if (!pathNotExist(projectPath)) {
|
|
170
|
+
console.log("项目名称已存在,创建项目目录失败");
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
//模版目录
|
|
174
|
+
const templateDir = path.join(__dirname$1, `../../src/templates/${templateMapping[data.language || 'js']}`);
|
|
175
|
+
copyFolder(templateDir, projectPath);
|
|
176
|
+
//生成模组介绍文件
|
|
177
|
+
saveFile(path.join(projectPath, "mod.info"), JSON.stringify(data, null, 2));
|
|
178
|
+
//执行npm i
|
|
179
|
+
cp.execSync('npm i', { cwd: projectPath, stdio: 'inherit' });
|
|
180
|
+
};
|
|
181
|
+
const initNPMProject = (projectPath, data) => {
|
|
182
|
+
//检查项目文件是否存在
|
|
183
|
+
//如果不存在则创建项目
|
|
184
|
+
//从模板下载项目文件
|
|
185
|
+
//根据用户输入的项目信息生成项目配置文件
|
|
186
|
+
//根据用户选择是否生成脚本文件,生成脚本文件
|
|
187
|
+
if (!pathNotExist(path.join(projectPath, "mod.info")) || !pathNotExist(path.join(projectPath, "main.mjs")) || !pathNotExist(path.join(projectPath, "scripts")) || !pathNotExist(path.join(projectPath, "build.config"))) {
|
|
188
|
+
console.log("项目已存在...");
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
//模版目录
|
|
192
|
+
const templateDir = path.join(__dirname$1, "../templates/js_sapdon");
|
|
193
|
+
copyFolder(templateDir, projectPath);
|
|
194
|
+
//生成模组介绍文件
|
|
195
|
+
saveFile(path.join(projectPath, "mod.info"), JSON.stringify(data, null, 2));
|
|
196
|
+
};
|
|
197
|
+
// 读取package.json文件并提取信息
|
|
198
|
+
const readPackageJson = (dir) => {
|
|
199
|
+
const packageJsonPath = path.join(dir, 'package.json');
|
|
200
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
201
|
+
try {
|
|
202
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
203
|
+
return {
|
|
204
|
+
name: path.basename(dir),
|
|
205
|
+
description: packageJson.description || "A new sapdon project",
|
|
206
|
+
author: packageJson.author || "Sapdon",
|
|
207
|
+
version: packageJson.version || "1.0.0"
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
console.error("读取package.json文件时出错:", error);
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
};
|
|
197
219
|
const globalObject = {};
|
|
220
|
+
function getProjectPath() {
|
|
221
|
+
const projectPath = globalObject.projectPath ?? process.cwd();
|
|
222
|
+
if (!fs.existsSync(path.join(projectPath, "build.config"))) {
|
|
223
|
+
throw new Error("无效的项目路径");
|
|
224
|
+
}
|
|
225
|
+
return projectPath;
|
|
226
|
+
}
|
|
227
|
+
function getProjectName() {
|
|
228
|
+
return cacheSync('projectName', () => path.basename(getProjectPath()));
|
|
229
|
+
}
|
|
230
|
+
function getBuildDirBp() {
|
|
231
|
+
const { buildDir } = getBuildConfig().buildOptions;
|
|
232
|
+
const name = getProjectName();
|
|
233
|
+
return path.join(getProjectPath(), buildDir, name + '_bp');
|
|
234
|
+
}
|
|
198
235
|
|
|
199
|
-
/**
|
|
200
|
-
* 递归遍历目录,收集所有 PNG 文件的路径
|
|
201
|
-
* @param {string} directory - 要遍历的目录
|
|
202
|
-
* @param {string} basePath - 基础路径(用于计算相对路径)
|
|
203
|
-
* @param {string} prefix - 路径前缀(如 "textures/items/")
|
|
204
|
-
* @returns {Promise<Object>} - 返回一个对象,键为文件名,值为相对路径(不带 .png 后缀)
|
|
205
|
-
*/
|
|
206
|
-
const traverseDirectory = async (directory, basePath, prefix = "") => {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
resource_pack_name: projectName,
|
|
300
|
-
texture_name: "atlas.items",
|
|
301
|
-
texture_data: itemTexturesSet,
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
// 写入文件
|
|
305
|
-
await generateJsonFile(outputPath, jsonData, "Item texture JSON file generated successfully.");
|
|
306
|
-
} catch (err) {
|
|
307
|
-
console.error("Error generating item texture JSON:", err);
|
|
308
|
-
}
|
|
236
|
+
/**
|
|
237
|
+
* 递归遍历目录,收集所有 PNG 文件的路径
|
|
238
|
+
* @param {string} directory - 要遍历的目录
|
|
239
|
+
* @param {string} basePath - 基础路径(用于计算相对路径)
|
|
240
|
+
* @param {string} prefix - 路径前缀(如 "textures/items/")
|
|
241
|
+
* @returns {Promise<Object>} - 返回一个对象,键为文件名,值为相对路径(不带 .png 后缀)
|
|
242
|
+
*/
|
|
243
|
+
const traverseDirectory = async (directory, basePath, prefix = "") => {
|
|
244
|
+
const texturesSet = {};
|
|
245
|
+
const files = await fs$1.readdir(directory);
|
|
246
|
+
for (const file of files) {
|
|
247
|
+
const filePath = path.join(directory, file);
|
|
248
|
+
const fileStats = await fs$1.stat(filePath);
|
|
249
|
+
if (fileStats.isDirectory()) {
|
|
250
|
+
// 如果是目录,递归遍历
|
|
251
|
+
const subDirectoryTextures = await traverseDirectory(filePath, basePath, prefix);
|
|
252
|
+
Object.assign(texturesSet, subDirectoryTextures);
|
|
253
|
+
}
|
|
254
|
+
else if (file.endsWith(".png")) {
|
|
255
|
+
// 如果是 PNG 文件,提取文件名并生成 texture_data
|
|
256
|
+
const fileName = path.basename(file, ".png"); // 去掉 .png 后缀
|
|
257
|
+
const relativePath = path.relative(basePath, filePath).replace(/\.png$/, ""); // 去掉 .png 后缀
|
|
258
|
+
const normalizedPath = `${prefix}${relativePath.replace(/\\/g, "/")}`; // 确保路径使用正斜杠
|
|
259
|
+
texturesSet[fileName] = {
|
|
260
|
+
textures: normalizedPath,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return texturesSet;
|
|
265
|
+
};
|
|
266
|
+
/**
|
|
267
|
+
* 生成 JSON 文件
|
|
268
|
+
* @param {string} outputPath - 输出的 JSON 文件路径
|
|
269
|
+
* @param {Object} jsonData - 要写入的 JSON 数据
|
|
270
|
+
* @param {string} successMessage - 成功时的日志消息
|
|
271
|
+
*/
|
|
272
|
+
const generateJsonFile = async (outputPath, jsonData, successMessage) => {
|
|
273
|
+
try {
|
|
274
|
+
const jsonString = JSON.stringify(jsonData, null, 2);
|
|
275
|
+
await fs$1.writeFile(outputPath, jsonString);
|
|
276
|
+
console.log(successMessage);
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
console.error("Error writing JSON file:", err);
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
/**
|
|
283
|
+
* 生成 block_texture.json 文件
|
|
284
|
+
* @param {string} itemTexturesPath - 包含 PNG 文件的根目录
|
|
285
|
+
* @param {string} outputPath - 输出的 JSON 文件路径
|
|
286
|
+
* @param {string} projectName - 项目名称
|
|
287
|
+
*/
|
|
288
|
+
async function generateBlockTextureJson(itemTexturesPath, outputPath, projectName, userTerrainTextures) {
|
|
289
|
+
try {
|
|
290
|
+
// 递归遍历目录,获取所有 PNG 文件的路径
|
|
291
|
+
const itemTexturesSet = await traverseDirectory(itemTexturesPath, itemTexturesPath, "textures/blocks/");
|
|
292
|
+
// 合并用户自定义的texture_data
|
|
293
|
+
if (userTerrainTextures) {
|
|
294
|
+
Object.assign(itemTexturesSet, userTerrainTextures);
|
|
295
|
+
}
|
|
296
|
+
// 生成 JSON 数据
|
|
297
|
+
const jsonData = {
|
|
298
|
+
texture_name: "atlas.terrain",
|
|
299
|
+
resource_pack_name: projectName,
|
|
300
|
+
padding: 8,
|
|
301
|
+
num_mip_levels: 4,
|
|
302
|
+
texture_data: itemTexturesSet,
|
|
303
|
+
};
|
|
304
|
+
// 写入文件
|
|
305
|
+
await generateJsonFile(outputPath, jsonData, "Block texture JSON file generated successfully.");
|
|
306
|
+
}
|
|
307
|
+
catch (err) {
|
|
308
|
+
console.error("Error generating block texture JSON:", err);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* 生成 item_texture.json 文件
|
|
313
|
+
* @param {string} itemTexturesPath - 包含 PNG 文件的根目录
|
|
314
|
+
* @param {string} outputPath - 输出的 JSON 文件路径
|
|
315
|
+
*/
|
|
316
|
+
async function generateItemTextureJson(itemTexturesPath, outputPath, projectName, userItemTextures) {
|
|
317
|
+
try {
|
|
318
|
+
// 递归遍历目录,获取所有 PNG 文件的路径
|
|
319
|
+
const itemTexturesSet = await traverseDirectory(itemTexturesPath, itemTexturesPath, "textures/items/");
|
|
320
|
+
// 合并用户自定义的texture_data
|
|
321
|
+
if (userItemTextures) {
|
|
322
|
+
Object.assign(itemTexturesSet, userItemTextures);
|
|
323
|
+
}
|
|
324
|
+
// 生成 JSON 数据
|
|
325
|
+
const jsonData = {
|
|
326
|
+
resource_pack_name: projectName,
|
|
327
|
+
texture_name: "atlas.items",
|
|
328
|
+
texture_data: itemTexturesSet,
|
|
329
|
+
};
|
|
330
|
+
// 写入文件
|
|
331
|
+
await generateJsonFile(outputPath, jsonData, "Item texture JSON file generated successfully.");
|
|
332
|
+
}
|
|
333
|
+
catch (err) {
|
|
334
|
+
console.error("Error generating item texture JSON:", err);
|
|
335
|
+
}
|
|
309
336
|
}
|
|
310
337
|
|
|
311
|
-
class ItemTextureManager {
|
|
312
|
-
static item_texture_sets = new Map();
|
|
313
|
-
static getItemTextureSet(){
|
|
314
|
-
return this.item_texture_sets;
|
|
315
|
-
}
|
|
316
|
-
static getItemTextures(){
|
|
317
|
-
return Object.fromEntries(this.item_texture_sets);
|
|
318
|
-
}
|
|
319
|
-
static registerTextureData(texture_name,texture_data){
|
|
320
|
-
this.item_texture_sets.set(texture_name,texture_data);
|
|
321
|
-
}
|
|
322
|
-
static registerTexture(texture_name,texture_path){
|
|
323
|
-
this.registerTextureData(texture_name,{textures:texture_path});
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
static
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
this.flipbook_textures.push(flipbook_texture);
|
|
349
|
-
}
|
|
338
|
+
class ItemTextureManager {
|
|
339
|
+
static item_texture_sets = new Map();
|
|
340
|
+
static getItemTextureSet() {
|
|
341
|
+
return this.item_texture_sets;
|
|
342
|
+
}
|
|
343
|
+
static getItemTextures() {
|
|
344
|
+
return Object.fromEntries(this.item_texture_sets);
|
|
345
|
+
}
|
|
346
|
+
static registerTextureData(texture_name, texture_data) {
|
|
347
|
+
this.item_texture_sets.set(texture_name, texture_data);
|
|
348
|
+
}
|
|
349
|
+
static registerTexture(texture_name, texture_path) {
|
|
350
|
+
this.registerTextureData(texture_name, { textures: texture_path });
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
class terrainTextureManager {
|
|
354
|
+
static terrain_texture_sets = new Map();
|
|
355
|
+
static getTerrainTextureSet() {
|
|
356
|
+
return this.terrain_texture_sets;
|
|
357
|
+
}
|
|
358
|
+
static getTerrainTextures() {
|
|
359
|
+
return Object.fromEntries(this.terrain_texture_sets);
|
|
360
|
+
}
|
|
361
|
+
static registerTextureData(texture_name, texture_data) {
|
|
362
|
+
this.terrain_texture_sets.set(texture_name, texture_data);
|
|
363
|
+
}
|
|
364
|
+
static registerTexture(texture_name, texture_path) {
|
|
365
|
+
this.registerTextureData(texture_name, { textures: texture_path });
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
const FlipbookTextures = {
|
|
369
|
+
flipbook_textures: [],
|
|
370
|
+
registerFlipbookTexture(atlas_tile, texture, ticks_per_frame, options = {}) {
|
|
371
|
+
const flipbook_texture = { "atlas_tile": atlas_tile, "flipbook_texture": texture, ticks_per_frame };
|
|
372
|
+
Object.assign(flipbook_texture, options);
|
|
373
|
+
this.flipbook_textures.push(flipbook_texture);
|
|
374
|
+
}
|
|
350
375
|
};
|
|
351
376
|
|
|
352
|
-
|
|
353
|
-
|
|
377
|
+
if (!Symbol.metadata) {
|
|
378
|
+
//@ts-ignore
|
|
379
|
+
Symbol.metadata = Symbol('[[metadata]]');
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// 因为无法判断其他代码实现的接口是否真的是RawType,所以用Symbol来标记
|
|
383
|
+
// 只要不export,其他代码就无法访问这个Symbol, 确保了唯一性
|
|
384
|
+
const IS_RAW_SYMBOL = Symbol('isRawJSON');
|
|
385
|
+
function isRawJSON(v) {
|
|
386
|
+
return v?.[IS_RAW_SYMBOL] === true;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const rawTypes = [
|
|
390
|
+
'boolean', 'number'
|
|
391
|
+
];
|
|
392
|
+
const transferableTypes = [
|
|
393
|
+
'string', 'undefined'
|
|
394
|
+
];
|
|
395
|
+
function jsonEncoderReplacer(_, v) {
|
|
396
|
+
const typeOf = typeof v;
|
|
397
|
+
if (typeOf === null) {
|
|
398
|
+
return null;
|
|
399
|
+
}
|
|
400
|
+
if (transferableTypes.includes(typeOf)) {
|
|
401
|
+
return v;
|
|
402
|
+
}
|
|
403
|
+
if (rawTypes.includes(typeOf)) {
|
|
404
|
+
return JSON.rawJSON(v);
|
|
405
|
+
}
|
|
406
|
+
if (typeOf === 'object') {
|
|
407
|
+
if (JSON.isRawJSON(v)) {
|
|
408
|
+
return v;
|
|
409
|
+
}
|
|
410
|
+
if (isRawJSON(v)) {
|
|
411
|
+
// 字符串再包装一遍
|
|
412
|
+
return JSON.rawJSON(v.rawJSON);
|
|
413
|
+
}
|
|
414
|
+
return v;
|
|
415
|
+
}
|
|
416
|
+
if (typeOf === 'bigint') {
|
|
417
|
+
return JSON.rawJSON(v.toString());
|
|
418
|
+
}
|
|
419
|
+
throw new Error('Unexpected value');
|
|
420
|
+
}
|
|
421
|
+
const jsonEncodeDecoder = {
|
|
422
|
+
encode(value) {
|
|
423
|
+
return JSON.stringify(value, jsonEncoderReplacer);
|
|
424
|
+
},
|
|
425
|
+
decode: JSON.parse
|
|
354
426
|
};
|
|
427
|
+
function encode(value, encodeDecoder = jsonEncodeDecoder) {
|
|
428
|
+
return encodeDecoder.encode(value);
|
|
429
|
+
}
|
|
430
|
+
function decode(value, encodeDecoder = jsonEncodeDecoder) {
|
|
431
|
+
return encodeDecoder.decode(value);
|
|
432
|
+
}
|
|
355
433
|
|
|
356
|
-
const {
|
|
357
|
-
port:
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
434
|
+
const devServerConfig = {
|
|
435
|
+
port: 49037,
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
const { port: port$1 } = devServerConfig;
|
|
439
|
+
async function cliRequest(path, ...params) {
|
|
440
|
+
try {
|
|
441
|
+
await fetch(`http://localhost:${port$1}/${path}`, {
|
|
442
|
+
method: 'POST',
|
|
443
|
+
headers: {
|
|
444
|
+
'Content-Type': 'application/json'
|
|
445
|
+
},
|
|
446
|
+
body: encode(params)
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
catch (error) {
|
|
450
|
+
console.error(error);
|
|
451
|
+
console.error('尝试在构建脚本中使用 server.startDevServer() 启动开发服务器');
|
|
452
|
+
}
|
|
373
453
|
}
|
|
374
454
|
|
|
375
455
|
const { port } = devServerConfig;
|
|
@@ -390,7 +470,7 @@ class DevelopmentServer {
|
|
|
390
470
|
req.on('data', chunk => buf = Buffer.concat([buf, chunk]));
|
|
391
471
|
req.on('end', () => {
|
|
392
472
|
try {
|
|
393
|
-
resolve(
|
|
473
|
+
resolve(decode(buf));
|
|
394
474
|
}
|
|
395
475
|
catch (error) {
|
|
396
476
|
reject(error);
|
|
@@ -430,54 +510,47 @@ class DevelopmentServer {
|
|
|
430
510
|
}
|
|
431
511
|
const server = new DevelopmentServer();
|
|
432
512
|
|
|
433
|
-
class UISystemRegistry {
|
|
434
|
-
static #ui_system_map = {}
|
|
435
|
-
static #ui_def_list = []
|
|
436
|
-
// 注册 UISystem
|
|
437
|
-
static registerUISystem(ui_system) {
|
|
438
|
-
const ui_system_path = ui_system.path + ui_system.name + ".json";
|
|
439
|
-
this.#ui_system_map[ui_system_path] = ui_system;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
//
|
|
458
|
-
static
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
//
|
|
462
|
-
static
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
this.#ui_system_map = systems;
|
|
475
|
-
});
|
|
476
|
-
|
|
477
|
-
server.handle('register-ui/def', defs => {
|
|
478
|
-
this.#ui_def_list = defs;
|
|
479
|
-
});
|
|
480
|
-
}
|
|
513
|
+
class UISystemRegistry {
|
|
514
|
+
static #ui_system_map = {};
|
|
515
|
+
static #ui_def_list = [];
|
|
516
|
+
// 注册 UISystem
|
|
517
|
+
static registerUISystem(ui_system) {
|
|
518
|
+
const ui_system_path = ui_system.path + ui_system.name + ".json";
|
|
519
|
+
this.#ui_system_map[ui_system_path] = ui_system;
|
|
520
|
+
}
|
|
521
|
+
// 添加外部 UI 定义
|
|
522
|
+
static addOuterUIdefs(ui_defs) {
|
|
523
|
+
if (!Array.isArray(ui_defs)) {
|
|
524
|
+
throw new Error("参数必须是一个数组");
|
|
525
|
+
}
|
|
526
|
+
this.#ui_def_list.concat(ui_defs);
|
|
527
|
+
}
|
|
528
|
+
static submit() {
|
|
529
|
+
cliRequest("register-ui/def", this.#ui_def_list);
|
|
530
|
+
cliRequest("register-ui/system", this.#ui_system_map);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
class UISystemRegistryServer {
|
|
534
|
+
// 私有静态字段
|
|
535
|
+
static #ui_system_map = {};
|
|
536
|
+
static #ui_def_list = [];
|
|
537
|
+
// 获取所有注册的 UISystem
|
|
538
|
+
static getUISystemList() {
|
|
539
|
+
return Object.values(this.#ui_system_map);
|
|
540
|
+
}
|
|
541
|
+
// 获取 UI 定义列表(剔除 "ui/server_form")
|
|
542
|
+
static getUIdefList() {
|
|
543
|
+
const combinedList = this.#ui_def_list.concat(Object.keys(this.#ui_system_map));
|
|
544
|
+
return combinedList.filter(item => item !== "ui/server_form");
|
|
545
|
+
}
|
|
546
|
+
static startServer() {
|
|
547
|
+
server.handle('register-ui/system', systems => {
|
|
548
|
+
this.#ui_system_map = systems;
|
|
549
|
+
});
|
|
550
|
+
server.handle('register-ui/def', defs => {
|
|
551
|
+
this.#ui_def_list = defs;
|
|
552
|
+
});
|
|
553
|
+
}
|
|
481
554
|
}
|
|
482
555
|
|
|
483
556
|
const clientRegistryData = [];
|
|
@@ -490,11 +563,12 @@ class GRegistry {
|
|
|
490
563
|
* @param {string} name 文件名字
|
|
491
564
|
* @param {string} root 根目录,如 "behavior"、"resource" 等
|
|
492
565
|
* @param {string} path 数据的路径,如 "blocks/"、"items/"、"recipes/" 等
|
|
493
|
-
* @param {string} data 实例 必须包含 toJson 方法
|
|
566
|
+
* @param {string | object} data 实例 必须包含 toJson 方法
|
|
494
567
|
*/
|
|
495
568
|
static register(name, root, path, data) {
|
|
496
|
-
data = data === 'string'
|
|
497
|
-
|
|
569
|
+
data = data === 'string'
|
|
570
|
+
? JSON.parse(data)
|
|
571
|
+
: serialize(data);
|
|
498
572
|
clientRegistryData.push({ name, root, path, data });
|
|
499
573
|
}
|
|
500
574
|
static submit() {
|
|
@@ -515,129 +589,109 @@ class GRegistryServer {
|
|
|
515
589
|
// console.log(data.map(item => item.data.description))
|
|
516
590
|
this.dataList = data;
|
|
517
591
|
});
|
|
518
|
-
server.handle('
|
|
519
|
-
console.log.apply(console, info);
|
|
520
|
-
});
|
|
592
|
+
server.handle('remote-logger', handleRemoteLogger);
|
|
521
593
|
}
|
|
522
594
|
}
|
|
523
595
|
var registry;
|
|
524
596
|
(function (registry) {
|
|
525
|
-
function
|
|
597
|
+
function submit() {
|
|
526
598
|
GRegistry.submit();
|
|
527
599
|
UISystemRegistry.submit();
|
|
528
600
|
cliRequest('submit', {});
|
|
529
601
|
}
|
|
530
|
-
registry.
|
|
531
|
-
function log(...info) {
|
|
532
|
-
cliRequest('log', ...info);
|
|
533
|
-
}
|
|
534
|
-
registry.log = log;
|
|
602
|
+
registry.submit = submit;
|
|
535
603
|
})(registry || (registry = {}));
|
|
536
604
|
|
|
537
|
-
/**
|
|
538
|
-
* 处理 blocks.json 数据
|
|
539
|
-
* @param {Object} data blocks.json 数据
|
|
540
|
-
* @returns {Object} 处理后的 blocks 数据
|
|
541
|
-
*/
|
|
542
|
-
const processBlocksData = (data) => {
|
|
543
|
-
const textures_arr = data.textures;
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
*
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
const
|
|
575
|
-
|
|
576
|
-
const
|
|
577
|
-
const
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
const
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
if (
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
const filePath = path.join(buildRootPath, dataPath, `${name}.json`);
|
|
625
|
-
|
|
626
|
-
// 保存文件
|
|
627
|
-
saveFile(filePath, JSON.stringify(data, null, 2));
|
|
628
|
-
});
|
|
629
|
-
|
|
630
|
-
// 保存 blocks.json
|
|
631
|
-
console.log("保存 blocks.json 文件:", blocksJsonPath);
|
|
632
|
-
saveFile(blocksJsonPath, JSON.stringify(blocks, null, 2));
|
|
633
|
-
|
|
634
|
-
console.log(`已加载并执行 ${modPath} 文件!`);
|
|
635
|
-
} catch (err) {
|
|
636
|
-
console.error(`加载或执行 ${modPath} 失败:${err.message}`);
|
|
637
|
-
console.error(err.stack); // 打印堆栈跟踪以便调试
|
|
638
|
-
}
|
|
605
|
+
/**
|
|
606
|
+
* 处理 blocks.json 数据
|
|
607
|
+
* @param {Object} data blocks.json 数据
|
|
608
|
+
* @returns {Object} 处理后的 blocks 数据
|
|
609
|
+
*/
|
|
610
|
+
const processBlocksData = (data) => {
|
|
611
|
+
const textures_arr = data.textures;
|
|
612
|
+
// 检查 textures 数组长度
|
|
613
|
+
if (textures_arr.length !== 6) {
|
|
614
|
+
console.warn(`blocks.json 的 textures 数组长度不为 6,实际长度: ${textures_arr.length}`);
|
|
615
|
+
return {};
|
|
616
|
+
}
|
|
617
|
+
// 构建 blocks 数据
|
|
618
|
+
const blocks = {};
|
|
619
|
+
blocks[data.identifier] = {
|
|
620
|
+
textures: {
|
|
621
|
+
up: textures_arr[0],
|
|
622
|
+
down: textures_arr[1],
|
|
623
|
+
east: textures_arr[2],
|
|
624
|
+
west: textures_arr[3],
|
|
625
|
+
south: textures_arr[4],
|
|
626
|
+
north: textures_arr[5]
|
|
627
|
+
}
|
|
628
|
+
};
|
|
629
|
+
return blocks;
|
|
630
|
+
};
|
|
631
|
+
/**
|
|
632
|
+
* Server
|
|
633
|
+
* 加载并执行模组文件
|
|
634
|
+
* @param {string} modPath 模组文件路径
|
|
635
|
+
* @param {string} buildPath 构建目录路径
|
|
636
|
+
* @param {string} projectName 项目名
|
|
637
|
+
*/
|
|
638
|
+
const generateAddon = async (modPath, buildPath, projectName) => {
|
|
639
|
+
try {
|
|
640
|
+
const buildBehDirPath = path.join(buildPath, `${projectName}_BP`);
|
|
641
|
+
const buildResDirPath = path.join(buildPath, `${projectName}_RP`);
|
|
642
|
+
const resDir = (...name) => path.join(buildResDirPath, ...name);
|
|
643
|
+
// 初始化 blocks.json 数据
|
|
644
|
+
const blocksJsonPath = path.join(buildBehDirPath, "blocks.json");
|
|
645
|
+
const blocks = { "format_version": "1.20.20" };
|
|
646
|
+
//生成item_texture.json
|
|
647
|
+
const item_texture_dir = resDir("textures/items");
|
|
648
|
+
const item_texture_json_path = resDir("textures/item_texture.json");
|
|
649
|
+
generateItemTextureJson(item_texture_dir, item_texture_json_path, projectName, ItemTextureManager.getItemTextures());
|
|
650
|
+
//生成terrain_texture.json
|
|
651
|
+
const terrain_texture_dir = resDir("textures/blocks");
|
|
652
|
+
const terrain_texture_json_path = resDir("textures/terrain_texture.json");
|
|
653
|
+
generateBlockTextureJson(terrain_texture_dir, terrain_texture_json_path, projectName, terrainTextureManager.getTerrainTextures());
|
|
654
|
+
//生成flipbook_textures.json
|
|
655
|
+
const flipbook_textures_path = resDir("textures/flipbook_textures.json");
|
|
656
|
+
saveFile(flipbook_textures_path, JSON.stringify(FlipbookTextures.flipbook_textures, null, 2));
|
|
657
|
+
//_ui_defs.json
|
|
658
|
+
const ui_def = UISystemRegistryServer.getUIdefList();
|
|
659
|
+
saveFile(resDir("ui/_ui_defs.json"), JSON.stringify({ "ui_defs": ui_def }, null, 2));
|
|
660
|
+
UISystemRegistryServer.getUISystemList().forEach((ui_system) => {
|
|
661
|
+
if (ui_system.path) {
|
|
662
|
+
saveFile(resDir(ui_system.path, `${ui_system.name}.json`), JSON.stringify(ui_system, null, 2));
|
|
663
|
+
}
|
|
664
|
+
});
|
|
665
|
+
// 从全局注册表中获取数据
|
|
666
|
+
const dataList = GRegistryServer.getDataList();
|
|
667
|
+
// console.log("dataList:", dataList)
|
|
668
|
+
// 遍历数据并保存到相应的目录
|
|
669
|
+
dataList.forEach(({ name, root, path: dataPath, data }) => {
|
|
670
|
+
// 处理 blocks.json 数据
|
|
671
|
+
if (dataPath === "blocks/") {
|
|
672
|
+
const processedBlocks = processBlocksData(data);
|
|
673
|
+
Object.assign(blocks, processedBlocks);
|
|
674
|
+
}
|
|
675
|
+
// 根据数据类型确定根目录
|
|
676
|
+
const rootPath = root === "behavior" ? `${projectName}_BP` : `${projectName}_RP`;
|
|
677
|
+
const buildRootPath = path.join(buildPath, rootPath);
|
|
678
|
+
// 拼接文件路径
|
|
679
|
+
const filePath = path.join(buildRootPath, dataPath, `${name}.json`);
|
|
680
|
+
// 保存文件
|
|
681
|
+
saveFile(filePath, JSON.stringify(data, null, 2));
|
|
682
|
+
});
|
|
683
|
+
// 保存 blocks.json
|
|
684
|
+
console.log("保存 blocks.json 文件:", blocksJsonPath);
|
|
685
|
+
saveFile(blocksJsonPath, JSON.stringify(blocks, null, 2));
|
|
686
|
+
console.log(`已加载并执行 ${modPath} 文件!`);
|
|
687
|
+
}
|
|
688
|
+
catch (err) {
|
|
689
|
+
console.error(`加载或执行 ${modPath} 失败:${err.message}`);
|
|
690
|
+
console.error(err.stack); // 打印堆栈跟踪以便调试
|
|
691
|
+
}
|
|
639
692
|
};
|
|
640
693
|
|
|
694
|
+
// 定义语义化版本号类
|
|
641
695
|
// 定义头部信息类
|
|
642
696
|
class AddonManifestHeader {
|
|
643
697
|
constructor(name, description, version, uuid, options = {}) {
|
|
@@ -652,7 +706,6 @@ class AddonManifestHeader {
|
|
|
652
706
|
this.min_engine_version = options.min_engine_version;
|
|
653
707
|
}
|
|
654
708
|
}
|
|
655
|
-
|
|
656
709
|
// 定义模块信息类
|
|
657
710
|
class AddonManifestModule {
|
|
658
711
|
constructor(description, moduleType, uuid, version) {
|
|
@@ -662,7 +715,6 @@ class AddonManifestModule {
|
|
|
662
715
|
this.version = version;
|
|
663
716
|
}
|
|
664
717
|
}
|
|
665
|
-
|
|
666
718
|
// 定义元数据信息类
|
|
667
719
|
class AddonManifestMetadata {
|
|
668
720
|
constructor(authors, license, generatedWith, productType, url) {
|
|
@@ -673,59 +725,388 @@ class AddonManifestMetadata {
|
|
|
673
725
|
this.url = url;
|
|
674
726
|
}
|
|
675
727
|
}
|
|
676
|
-
|
|
677
728
|
// 定义清单文件类
|
|
678
729
|
class AddonManifest {
|
|
679
|
-
constructor(formatVersion, header, modules, dependencies, capabilities=null, metadata=null) {
|
|
730
|
+
constructor(formatVersion, header, modules, dependencies, capabilities = null, metadata = null) {
|
|
680
731
|
this.format_version = formatVersion;
|
|
681
732
|
this.header = header;
|
|
682
733
|
this.modules = modules;
|
|
683
734
|
this.dependencies = dependencies;
|
|
684
|
-
if(capabilities != null)
|
|
685
|
-
|
|
735
|
+
if (capabilities != null)
|
|
736
|
+
this.capabilities = capabilities;
|
|
737
|
+
if (metadata != null)
|
|
738
|
+
this.metadata = metadata;
|
|
686
739
|
}
|
|
687
740
|
}
|
|
688
741
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
const corePath = path.join(rootDir, 'core');
|
|
702
|
-
const cliPath = path.join(rootDir, 'cli');
|
|
703
|
-
const ocPath = path.join(rootDir, 'oc');
|
|
704
|
-
const targetCorePath = path.join(projectModules, '@sapdon/core');
|
|
705
|
-
const targetCliPath = path.join(projectModules, '@sapdon/cli');
|
|
706
|
-
const targetOcPath = path.join(projectModules, '@sapdon/oc');
|
|
707
|
-
|
|
708
|
-
fs.cpSync(corePath, targetCorePath, { recursive: true, force: true });
|
|
709
|
-
fs.cpSync(cliPath, targetCliPath, { recursive: true, force: true });
|
|
710
|
-
fs.cpSync(ocPath, targetOcPath, { recursive: true, force: true });
|
|
711
|
-
|
|
712
|
-
fs.writeFileSync(path.join(targetCorePath, 'package.json'), JSON.stringify({
|
|
713
|
-
name: '@sapdon/core',
|
|
714
|
-
main: 'index.js',
|
|
715
|
-
version: '1.0.0',
|
|
716
|
-
}));
|
|
717
|
-
fs.writeFileSync(path.join(targetCliPath, 'package.json'), JSON.stringify({
|
|
718
|
-
name: '@sapdon/cli',
|
|
719
|
-
main: 'index.js',
|
|
720
|
-
version: '1.0.0',
|
|
721
|
-
}));
|
|
722
|
-
fs.writeFileSync(path.join(targetOcPath, 'package.json'), JSON.stringify({
|
|
723
|
-
name: '@sapdon/oc',
|
|
724
|
-
main: 'index.js',
|
|
725
|
-
version: '1.0.0',
|
|
726
|
-
}));
|
|
742
|
+
const MC_INSTALL_PATH = {
|
|
743
|
+
MAIN: 'AppData/Local/Packages/Microsoft.MinecraftUWP_8wekyb3d8bbwe/LocalState/games/com.mojang/',
|
|
744
|
+
BETA: 'AppData/Local/Packages/Microsoft.MinecraftWindowsBeta_8wekyb3d8bbwe/LocalState/games/com.mojang/'
|
|
745
|
+
};
|
|
746
|
+
function mojangPath() {
|
|
747
|
+
return cacheSync('McInstallPath.Main', () => path.join(os.homedir(), MC_INSTALL_PATH.MAIN));
|
|
748
|
+
}
|
|
749
|
+
function betaPath() {
|
|
750
|
+
return cacheSync('McInstallPath.Beta', () => path.join(os.homedir(), MC_INSTALL_PATH.BETA));
|
|
751
|
+
}
|
|
752
|
+
function getGamePath() {
|
|
753
|
+
return getBuildConfig().versionType === 'beta' ? betaPath() : mojangPath();
|
|
727
754
|
}
|
|
728
755
|
|
|
756
|
+
var name = "sapdon";
|
|
757
|
+
var version = "3.2.0";
|
|
758
|
+
var scripts = {
|
|
759
|
+
build: "node scripts/build.cjs",
|
|
760
|
+
pub: "npm run build && npm publish"
|
|
761
|
+
};
|
|
762
|
+
var keywords = [
|
|
763
|
+
"bedrock",
|
|
764
|
+
"tools",
|
|
765
|
+
"addon"
|
|
766
|
+
];
|
|
767
|
+
var author = "Meteage";
|
|
768
|
+
var license = "ISC";
|
|
769
|
+
var type = "module";
|
|
770
|
+
var bin = {
|
|
771
|
+
sapdon: "prod/cli/start.js"
|
|
772
|
+
};
|
|
773
|
+
var description = "Sapdon is a Node.js toolkit designed for building Bedrock Edition Minecraft addon packs.";
|
|
774
|
+
var devDependencies = {
|
|
775
|
+
"@minecraft/server": "^2.0.0-beta.1.21.80-preview.20",
|
|
776
|
+
"@minecraft/server-ui": "^1.3.0",
|
|
777
|
+
"@types/lodash": "^4.17.16",
|
|
778
|
+
"@types/node": "^22.14.0",
|
|
779
|
+
"tsc-alias": "^1.8.13"
|
|
780
|
+
};
|
|
781
|
+
var dependencies = {
|
|
782
|
+
"@rollup/plugin-commonjs": "^28.0.2",
|
|
783
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
784
|
+
"@rollup/plugin-node-resolve": "^16.0.0",
|
|
785
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
786
|
+
"@rollup/plugin-typescript": "^12.1.2",
|
|
787
|
+
chalk: "^5.4.1",
|
|
788
|
+
commander: "^13.0.0",
|
|
789
|
+
"download-git-repo": "^3.0.2",
|
|
790
|
+
inquirer: "^12.3.1",
|
|
791
|
+
lodash: "^4.17.21",
|
|
792
|
+
ora: "^8.1.1",
|
|
793
|
+
rollup: "^4.39.0",
|
|
794
|
+
"rollup-plugin-dts": "^6.2.1",
|
|
795
|
+
"rollup-plugin-typescript-paths": "^1.5.0",
|
|
796
|
+
"rollup-plugin-visualizer": "^5.14.0",
|
|
797
|
+
"tsconfig-paths": "^4.2.0",
|
|
798
|
+
tslib: "^2.8.1",
|
|
799
|
+
typescript: "^5.8.2"
|
|
800
|
+
};
|
|
801
|
+
var files = [
|
|
802
|
+
"prod/**/*",
|
|
803
|
+
"doc/**/*"
|
|
804
|
+
];
|
|
805
|
+
var packageJson = {
|
|
806
|
+
name: name,
|
|
807
|
+
version: version,
|
|
808
|
+
scripts: scripts,
|
|
809
|
+
keywords: keywords,
|
|
810
|
+
author: author,
|
|
811
|
+
license: license,
|
|
812
|
+
type: type,
|
|
813
|
+
bin: bin,
|
|
814
|
+
description: description,
|
|
815
|
+
devDependencies: devDependencies,
|
|
816
|
+
dependencies: dependencies,
|
|
817
|
+
files: files
|
|
818
|
+
};
|
|
819
|
+
|
|
820
|
+
function getPackageJson() {
|
|
821
|
+
return cacheSync(path.join(dirname(import.meta), '../../../package.json'), () => packageJson);
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
async function syncDevFilesServer(projectPath, projectName) {
|
|
825
|
+
const buildConfig = JSON.parse(readFileSync(path.join(projectPath, "build.config")));
|
|
826
|
+
const buildDir = path.join(projectPath, buildConfig.buildOptions.buildDir);
|
|
827
|
+
const buildBehDirPath = path.join(buildDir, `${projectName}_BP`);
|
|
828
|
+
const buildResDirPath = path.join(buildDir, `${projectName}_RP`);
|
|
829
|
+
fs.cpSync(buildBehDirPath, path.join(getGamePath(), "development_behavior_packs/", `${projectName}_BP/`), { recursive: true, force: true });
|
|
830
|
+
fs.cpSync(buildResDirPath, path.join(getGamePath(), "development_resource_packs/", `${projectName}_RP/`), { recursive: true, force: true });
|
|
831
|
+
}
|
|
832
|
+
async function writeLib(projectPath) {
|
|
833
|
+
const projectModules = path.join(projectPath, "node_modules");
|
|
834
|
+
const rootDir = path.join(dirname(import.meta), '../');
|
|
835
|
+
const corePath = path.join(rootDir, 'core');
|
|
836
|
+
const cliPath = path.join(rootDir, 'cli');
|
|
837
|
+
const ocPath = path.join(rootDir, 'oc');
|
|
838
|
+
const targetCorePath = path.join(projectModules, '@sapdon/core');
|
|
839
|
+
const targetCliPath = path.join(projectModules, '@sapdon/cli');
|
|
840
|
+
const targetOcPath = path.join(projectModules, '@sapdon/oc');
|
|
841
|
+
const packageJson = getPackageJson();
|
|
842
|
+
fs.cpSync(corePath, targetCorePath, { recursive: true, force: true });
|
|
843
|
+
fs.cpSync(cliPath, targetCliPath, { recursive: true, force: true });
|
|
844
|
+
fs.cpSync(ocPath, targetOcPath, { recursive: true, force: true });
|
|
845
|
+
fs.writeFileSync(path.join(targetCorePath, 'package.json'), JSON.stringify({
|
|
846
|
+
name: '@sapdon/core',
|
|
847
|
+
main: 'index.js',
|
|
848
|
+
version: packageJson.version,
|
|
849
|
+
}));
|
|
850
|
+
fs.writeFileSync(path.join(targetCliPath, 'package.json'), JSON.stringify({
|
|
851
|
+
name: '@sapdon/cli',
|
|
852
|
+
main: 'index.js',
|
|
853
|
+
version: packageJson.version,
|
|
854
|
+
}));
|
|
855
|
+
fs.writeFileSync(path.join(targetOcPath, 'package.json'), JSON.stringify({
|
|
856
|
+
name: '@sapdon/oc',
|
|
857
|
+
main: 'index.js',
|
|
858
|
+
version: packageJson.version,
|
|
859
|
+
}));
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
function startDevServer() {
|
|
863
|
+
if (server.isListening()) {
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
866
|
+
server.bootstrap();
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
// 获取当前文件的目录路径
|
|
870
|
+
const __filename$1 = fileURLToPath$1(import.meta.url);
|
|
871
|
+
path.dirname(__filename$1);
|
|
872
|
+
//读取配置文件
|
|
873
|
+
// const pathConfig = JSON.parse(readFile(path.join(__dirname, "./build.config")))
|
|
874
|
+
const rollupIgnores = [
|
|
875
|
+
'rollup',
|
|
876
|
+
'typescript',
|
|
877
|
+
'@sapdon/core',
|
|
878
|
+
'@sapdon/cli',
|
|
879
|
+
'@minecraft',
|
|
880
|
+
];
|
|
881
|
+
//脚本打包器
|
|
882
|
+
const scriptBundler = {
|
|
883
|
+
js: async (source, target, sourcemap) => {
|
|
884
|
+
const buildConfig = getBuildConfig();
|
|
885
|
+
try {
|
|
886
|
+
const bundle = await rollup({
|
|
887
|
+
input: source,
|
|
888
|
+
plugins: [
|
|
889
|
+
nodeResolve({
|
|
890
|
+
preferBuiltins: true
|
|
891
|
+
}),
|
|
892
|
+
//@ts-ignore
|
|
893
|
+
commonjs(),
|
|
894
|
+
//@ts-ignore
|
|
895
|
+
json(),
|
|
896
|
+
// visualizer({ open: true }), //可视化分析, 打包出问题取消注释这一行
|
|
897
|
+
...(buildConfig.buildOptions.buildMode === 'development' ? [] : [
|
|
898
|
+
terser(),
|
|
899
|
+
]),
|
|
900
|
+
],
|
|
901
|
+
external(name) {
|
|
902
|
+
for (const candidate of rollupIgnores) {
|
|
903
|
+
if (name.includes(candidate)) {
|
|
904
|
+
return true;
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
return false;
|
|
908
|
+
}
|
|
909
|
+
});
|
|
910
|
+
await bundle.write({
|
|
911
|
+
file: target,
|
|
912
|
+
format: 'esm',
|
|
913
|
+
sourcemap,
|
|
914
|
+
});
|
|
915
|
+
bundle.close();
|
|
916
|
+
}
|
|
917
|
+
catch (e) {
|
|
918
|
+
console.error(e);
|
|
919
|
+
}
|
|
920
|
+
},
|
|
921
|
+
//ts先通过rollup处理后再复制
|
|
922
|
+
ts: async (source, target, sourcemap) => {
|
|
923
|
+
const projectPath = getProjectPath();
|
|
924
|
+
const buildConfig = getBuildConfig();
|
|
925
|
+
try {
|
|
926
|
+
const bundle = await rollup({
|
|
927
|
+
input: source,
|
|
928
|
+
plugins: [
|
|
929
|
+
typescriptPaths(),
|
|
930
|
+
nodeResolve({
|
|
931
|
+
preferBuiltins: true
|
|
932
|
+
}),
|
|
933
|
+
//@ts-ignore
|
|
934
|
+
ts({
|
|
935
|
+
tsconfig: path.join(projectPath, 'tsconfig.json'),
|
|
936
|
+
}),
|
|
937
|
+
//@ts-ignore
|
|
938
|
+
commonjs(),
|
|
939
|
+
//@ts-ignore
|
|
940
|
+
json(),
|
|
941
|
+
// visualizer({ open: true }), //可视化分析, 打包出问题取消注释这一行
|
|
942
|
+
...(buildConfig.buildOptions.buildMode === 'development' ? [] : [
|
|
943
|
+
terser(),
|
|
944
|
+
]),
|
|
945
|
+
],
|
|
946
|
+
external(name) {
|
|
947
|
+
for (const candidate of rollupIgnores) {
|
|
948
|
+
if (name.includes(candidate)) {
|
|
949
|
+
return true;
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
return false;
|
|
953
|
+
}
|
|
954
|
+
});
|
|
955
|
+
await bundle.write({
|
|
956
|
+
file: target,
|
|
957
|
+
format: 'esm',
|
|
958
|
+
sourcemap,
|
|
959
|
+
});
|
|
960
|
+
bundle.close();
|
|
961
|
+
}
|
|
962
|
+
catch (e) {
|
|
963
|
+
console.error(e);
|
|
964
|
+
}
|
|
965
|
+
},
|
|
966
|
+
any: async (a, b) => {
|
|
967
|
+
const buildConfig = getBuildConfig();
|
|
968
|
+
buildConfig.buildOptions.useJs
|
|
969
|
+
? await scriptBundler.js(a, b)
|
|
970
|
+
: await scriptBundler.ts(a, b);
|
|
971
|
+
},
|
|
972
|
+
};
|
|
973
|
+
async function bundleScripts(useJs = false) {
|
|
974
|
+
const elementType = useJs ? 'js' : 'ts';
|
|
975
|
+
const projectPath = getProjectPath();
|
|
976
|
+
const buildConfig = getBuildConfig();
|
|
977
|
+
const { scriptEntry, scriptOutput, buildMode } = buildConfig.buildOptions;
|
|
978
|
+
scriptBundler[elementType](path.join(projectPath, scriptEntry), path.join(getBuildDirBp(), scriptOutput), buildMode === 'development' ? true : false);
|
|
979
|
+
}
|
|
980
|
+
async function runOnChild(targetFilePath) {
|
|
981
|
+
const { promise, resolve } = Promise.withResolvers();
|
|
982
|
+
cp.fork(targetFilePath, { stdio: 'inherit' }).on('exit', resolve);
|
|
983
|
+
return promise;
|
|
984
|
+
}
|
|
985
|
+
async function runScript(src) {
|
|
986
|
+
const randomName = '.' + crypto.randomUUID() + '.js';
|
|
987
|
+
const targetFilePath = path.join(path.dirname(src), '.tmp', randomName);
|
|
988
|
+
await scriptBundler.any(src, targetFilePath);
|
|
989
|
+
try {
|
|
990
|
+
await runOnChild(targetFilePath);
|
|
991
|
+
}
|
|
992
|
+
catch (e) {
|
|
993
|
+
console.error(e);
|
|
994
|
+
}
|
|
995
|
+
finally {
|
|
996
|
+
fs.rmSync(targetFilePath, { force: true });
|
|
997
|
+
}
|
|
998
|
+
return;
|
|
999
|
+
}
|
|
1000
|
+
function projectCanBuild(projectPath) {
|
|
1001
|
+
console.log("开始构建项目");
|
|
1002
|
+
console.log("项目路径:" + projectPath);
|
|
1003
|
+
//检查项目是否存在
|
|
1004
|
+
if (pathNotExist(projectPath)) {
|
|
1005
|
+
console.log("项目不存在");
|
|
1006
|
+
return false;
|
|
1007
|
+
}
|
|
1008
|
+
//检查项目是否有build.config文件
|
|
1009
|
+
if (pathNotExist(path.join(projectPath, "build.config"))) {
|
|
1010
|
+
console.log("项目没有build.config文件");
|
|
1011
|
+
return false;
|
|
1012
|
+
}
|
|
1013
|
+
return true;
|
|
1014
|
+
}
|
|
1015
|
+
//构建项目
|
|
1016
|
+
/**
|
|
1017
|
+
* `server`
|
|
1018
|
+
*
|
|
1019
|
+
* 在使用前使用 `projectCanBuild` 确保项目可以构建
|
|
1020
|
+
* @param {string} projectPath
|
|
1021
|
+
* @param {string} projectName
|
|
1022
|
+
*/
|
|
1023
|
+
const buildProject = async (projectPath, projectName) => {
|
|
1024
|
+
//读取build.config文件
|
|
1025
|
+
const buildConfig = getBuildConfig();
|
|
1026
|
+
//读取mod.info文件
|
|
1027
|
+
const modInfoPath = path.join(projectPath, "mod.info");
|
|
1028
|
+
const modInfo = JSON.parse(readFile(modInfoPath));
|
|
1029
|
+
const min_engine_version = versionStringToArray(modInfo.min_engine_version);
|
|
1030
|
+
const buildDirPath = path.join(projectPath, buildConfig.buildOptions.buildDir);
|
|
1031
|
+
const buildBehDirPath = path.join(buildDirPath, `${projectName}_BP/`);
|
|
1032
|
+
const buildResDirPath = path.join(buildDirPath, `${projectName}_RP/`);
|
|
1033
|
+
const absoluteModPath = path.join(projectPath, buildConfig.buildOptions.buildEntry);
|
|
1034
|
+
if (!server.isListening()) {
|
|
1035
|
+
//生成manifest.json文件
|
|
1036
|
+
//判断manifest.json是否已经生成过了,生成过了就不用生成
|
|
1037
|
+
const manifestPath = path.join(buildBehDirPath, "manifest.json");
|
|
1038
|
+
if (pathNotExist(manifestPath)) {
|
|
1039
|
+
const behManifest = generateBehManifest(modInfo.name, modInfo.description, modInfo.version, {
|
|
1040
|
+
min_engine_version: min_engine_version,
|
|
1041
|
+
}, buildConfig.buildOptions.dependencies, buildConfig.buildOptions.scriptEntry);
|
|
1042
|
+
const resManifest = generateResManifest(modInfo.name, modInfo.description, modInfo.version, {
|
|
1043
|
+
min_engine_version: min_engine_version,
|
|
1044
|
+
}, []);
|
|
1045
|
+
//BP
|
|
1046
|
+
saveFile(path.join(buildBehDirPath, "manifest.json"), behManifest);
|
|
1047
|
+
//RP
|
|
1048
|
+
saveFile(path.join(buildResDirPath, "manifest.json"), resManifest);
|
|
1049
|
+
}
|
|
1050
|
+
//复制pack_icon.png
|
|
1051
|
+
const packIconPath = path.join(projectPath, "pack_icon.png");
|
|
1052
|
+
copyFileSync(packIconPath, path.join(buildBehDirPath, "pack_icon.png"));
|
|
1053
|
+
copyFileSync(packIconPath, path.join(buildResDirPath, "pack_icon.png"));
|
|
1054
|
+
// 现在只有一个resource
|
|
1055
|
+
const resource = buildConfig.buildOptions.resource;
|
|
1056
|
+
const sourcePath = path.join(projectPath, resource.path);
|
|
1057
|
+
copyFolder(sourcePath, buildResDirPath);
|
|
1058
|
+
// 在客户端启动前启动服务器
|
|
1059
|
+
startDevServer();
|
|
1060
|
+
GRegistryServer.startServer();
|
|
1061
|
+
UISystemRegistryServer.startServer();
|
|
1062
|
+
server.handle('submit', () => {
|
|
1063
|
+
//只有当buildMode为development时才加载用户modjs文件
|
|
1064
|
+
if (buildConfig.buildOptions.buildMode === "development") {
|
|
1065
|
+
//动态加载用户modjs文件
|
|
1066
|
+
generateAddon(absoluteModPath, buildDirPath, projectName);
|
|
1067
|
+
}
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1070
|
+
// buildEntry (有可能生成ts或js文件, 所以需要先编译)
|
|
1071
|
+
await runScript(absoluteModPath);
|
|
1072
|
+
// scriptEntry
|
|
1073
|
+
await bundleScripts(buildConfig.buildOptions.useJs);
|
|
1074
|
+
await syncDevFilesServer(projectPath, projectName);
|
|
1075
|
+
};
|
|
1076
|
+
function versionStringToArray(versionString) {
|
|
1077
|
+
// 使用 split 方法将字符串按 '.' 分割成数组
|
|
1078
|
+
const parts = versionString.split('.');
|
|
1079
|
+
// 使用 map 方法将每个部分转换为数字
|
|
1080
|
+
const versionArray = parts.map(part => Number(part));
|
|
1081
|
+
return versionArray;
|
|
1082
|
+
}
|
|
1083
|
+
const generateBehManifest = (name, description, version, options = {}, dependencies = [], entry) => {
|
|
1084
|
+
console.log("开始生成behavior_packs/manifest.json");
|
|
1085
|
+
console.log("Entry:", entry);
|
|
1086
|
+
const header = new AddonManifestHeader((name + "_BP"), description, versionStringToArray(version), generateUUID(), options);
|
|
1087
|
+
const module = new AddonManifestModule("行为模块", "data", generateUUID(), versionStringToArray(version));
|
|
1088
|
+
const script_module = new AddonManifestModule("脚本模块", "script", generateUUID(), versionStringToArray(version));
|
|
1089
|
+
if (entry) {
|
|
1090
|
+
script_module.entry = entry;
|
|
1091
|
+
}
|
|
1092
|
+
const metadata = new AddonManifestMetadata(["@sapdon"], "MIT", {
|
|
1093
|
+
"sapdon": ["1.0.0"]
|
|
1094
|
+
}, "addon", "https://github.com/junjun260/sapdon");
|
|
1095
|
+
const manifest = new AddonManifest(2, //格式版本
|
|
1096
|
+
header, [module, script_module], dependencies, null, metadata);
|
|
1097
|
+
return JSON.stringify(manifest, null, 2);
|
|
1098
|
+
};
|
|
1099
|
+
const generateResManifest = (name, description, version, options = {}, dependencies = []) => {
|
|
1100
|
+
const header = new AddonManifestHeader((name + "_RP"), description, versionStringToArray(version), generateUUID(), options);
|
|
1101
|
+
const module = new AddonManifestModule("资源模块", "resources", generateUUID(), versionStringToArray(version));
|
|
1102
|
+
const metadata = new AddonManifestMetadata(["@sapdon"], "MIT", {
|
|
1103
|
+
"sapdon": ["1.0.0"]
|
|
1104
|
+
}, "addon", "https://github.com/junjun260/sapdon");
|
|
1105
|
+
const manifest = new AddonManifest(2, //格式版本
|
|
1106
|
+
header, [module], [], null, metadata);
|
|
1107
|
+
return JSON.stringify(manifest, null, 2);
|
|
1108
|
+
};
|
|
1109
|
+
|
|
729
1110
|
const classStr = `import fs from 'fs'
|
|
730
1111
|
export class FileResource {
|
|
731
1112
|
static cache: Record<string, FileResource> = {}
|
|
@@ -872,8 +1253,8 @@ function watchResourceDir() {
|
|
|
872
1253
|
}
|
|
873
1254
|
function initResourceDir() {
|
|
874
1255
|
// js 项目无法使用资源目录短链接
|
|
875
|
-
const {
|
|
876
|
-
if (
|
|
1256
|
+
const { buildOptions } = getBuildConfig();
|
|
1257
|
+
if (buildOptions.buildEntry.endsWith('js')) {
|
|
877
1258
|
return;
|
|
878
1259
|
}
|
|
879
1260
|
const cwd = process.cwd();
|
|
@@ -885,514 +1266,163 @@ function initResourceDir() {
|
|
|
885
1266
|
fs.mkdirSync(resDir);
|
|
886
1267
|
}
|
|
887
1268
|
const resourceHint = generateResourceHint(resDir);
|
|
888
|
-
generateHintFile(resourceHint, path.join(cwd, 'res.ts'));
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
const debounce = lodash.debounce;
|
|
892
|
-
|
|
893
|
-
function hmr(projectPath, projectName) {
|
|
894
|
-
const { buildDir, useHMR } = getBuildConfig().defaultConfig;
|
|
895
|
-
watchResourceDir();
|
|
896
|
-
if (useHMR) {
|
|
897
|
-
fs.watch(projectPath, { recursive: true }, debounce(async (eventType, filename) => {
|
|
898
|
-
if (!eventType || !filename) {
|
|
899
|
-
return
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
if (filename.startsWith('.') || filename.startsWith(buildDir)) {
|
|
903
|
-
return
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
if (filename.endsWith('.js') || filename.endsWith('.ts')) {
|
|
907
|
-
process.stdout.write(`File ${filename} changed, reloading...\r`);
|
|
908
|
-
await buildProject(projectPath, projectName);
|
|
909
|
-
console.log(`Reloaded ${filename}`);
|
|
910
|
-
}
|
|
911
|
-
}), 1000);
|
|
912
|
-
}
|
|
1269
|
+
generateHintFile(resourceHint, path.join(cwd, 'res.hint.ts'));
|
|
913
1270
|
}
|
|
914
1271
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
1272
|
+
const debounce = lodash.debounce;
|
|
1273
|
+
function hmr(projectPath, projectName) {
|
|
1274
|
+
const { buildDir, useHMR } = getBuildConfig().buildOptions;
|
|
1275
|
+
watchResourceDir();
|
|
1276
|
+
if (useHMR) {
|
|
1277
|
+
fs.watch(projectPath, { recursive: true }, debounce(async (eventType, filename) => {
|
|
1278
|
+
if (!eventType || !filename) {
|
|
1279
|
+
return;
|
|
1280
|
+
}
|
|
1281
|
+
if (filename.startsWith('.') ||
|
|
1282
|
+
filename.startsWith(buildDir)) {
|
|
1283
|
+
return;
|
|
1284
|
+
}
|
|
1285
|
+
if (filename.endsWith('.js') ||
|
|
1286
|
+
filename.endsWith('.ts') ||
|
|
1287
|
+
filename === 'build.config' ||
|
|
1288
|
+
filename === 'mod.info') {
|
|
1289
|
+
process.stdout.write(`File ${filename} changed, reloading...\r`);
|
|
1290
|
+
await buildProject(projectPath, projectName);
|
|
1291
|
+
console.log(`Reloaded ${filename}`);
|
|
1292
|
+
}
|
|
1293
|
+
}), 1000);
|
|
918
1294
|
}
|
|
919
|
-
server.bootstrap();
|
|
920
1295
|
}
|
|
921
1296
|
|
|
922
|
-
|
|
923
|
-
const
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
const
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
* @param {string} projectName
|
|
1054
|
-
*/
|
|
1055
|
-
const buildProject = async (projectPath, projectName) => {
|
|
1056
|
-
//读取build.config文件
|
|
1057
|
-
const buildConfigPath = path.join(projectPath, "build.config");
|
|
1058
|
-
const buildConfig = JSON.parse(readFile(buildConfigPath));
|
|
1059
|
-
//读取mod.info文件
|
|
1060
|
-
const modInfoPath = path.join(projectPath, "mod.info");
|
|
1061
|
-
const modInfo = JSON.parse(readFile(modInfoPath));
|
|
1062
|
-
const min_engine_version = versionStringToArray(modInfo.min_engine_version);
|
|
1063
|
-
|
|
1064
|
-
const buildDirPath = path.join(projectPath, buildConfig.defaultConfig.buildDir);
|
|
1065
|
-
const buildBehDirPath = path.join(buildDirPath, `${projectName}_BP/`);
|
|
1066
|
-
const buildResDirPath = path.join(buildDirPath, `${projectName}_RP/`);
|
|
1067
|
-
|
|
1068
|
-
const absoluteModPath = path.join(projectPath, buildConfig.defaultConfig.buildEntry);
|
|
1069
|
-
|
|
1070
|
-
if (!server.isListening()) {
|
|
1071
|
-
//生成manifest.json文件
|
|
1072
|
-
//判断manifest.json是否已经生成过了,生成过了就不用生成
|
|
1073
|
-
const manifestPath = path.join(buildBehDirPath, "manifest.json");
|
|
1074
|
-
if (pathNotExist(manifestPath)) {
|
|
1075
|
-
const behManifest = generateBehManifest(
|
|
1076
|
-
modInfo.name,
|
|
1077
|
-
modInfo.description,
|
|
1078
|
-
modInfo.version,
|
|
1079
|
-
{
|
|
1080
|
-
min_engine_version: min_engine_version,
|
|
1081
|
-
},
|
|
1082
|
-
buildConfig.defaultConfig.dependencies,
|
|
1083
|
-
buildConfig.defaultConfig.scriptEntry
|
|
1084
|
-
);
|
|
1085
|
-
|
|
1086
|
-
const resManifest = generateResManifest(
|
|
1087
|
-
modInfo.name,
|
|
1088
|
-
modInfo.description,
|
|
1089
|
-
modInfo.version,
|
|
1090
|
-
{
|
|
1091
|
-
min_engine_version: min_engine_version,
|
|
1092
|
-
},
|
|
1093
|
-
[]
|
|
1094
|
-
);
|
|
1095
|
-
|
|
1096
|
-
//BP
|
|
1097
|
-
saveFile(path.join(buildBehDirPath, "manifest.json"), behManifest);
|
|
1098
|
-
//RP
|
|
1099
|
-
saveFile(path.join(buildResDirPath, "manifest.json"), resManifest);
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
//复制pack_icon.png
|
|
1103
|
-
const packIconPath = path.join(projectPath, "pack_icon.png");
|
|
1104
|
-
|
|
1105
|
-
copyFileSync(packIconPath, path.join(buildBehDirPath, "pack_icon.png"));
|
|
1106
|
-
copyFileSync(packIconPath, path.join(buildResDirPath, "pack_icon.png"));
|
|
1107
|
-
|
|
1108
|
-
const resources = buildConfig.resources;
|
|
1109
|
-
resources.forEach(element => {
|
|
1110
|
-
const sourcePath = path.join(projectPath, element.path);
|
|
1111
|
-
copyFolder(sourcePath, buildResDirPath);
|
|
1112
|
-
});
|
|
1113
|
-
|
|
1114
|
-
// 在客户端启动前启动服务器
|
|
1115
|
-
startDevServer();
|
|
1116
|
-
GRegistryServer.startServer();
|
|
1117
|
-
UISystemRegistryServer.startServer();
|
|
1118
|
-
server.handle('submit', () => {
|
|
1119
|
-
//只有当buildMode为development时才加载用户modjs文件
|
|
1120
|
-
if (buildConfig.defaultConfig.buildMode === "development") {
|
|
1121
|
-
//动态加载用户modjs文件
|
|
1122
|
-
generateAddon(absoluteModPath, buildDirPath, projectName);
|
|
1123
|
-
}
|
|
1124
|
-
});
|
|
1125
|
-
|
|
1126
|
-
hmr(projectPath, projectName);
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
const scripts = buildConfig.scripts;
|
|
1130
|
-
const scriptPath = path.join(buildBehDirPath, "scripts/");
|
|
1131
|
-
|
|
1132
|
-
for (const element of scripts) {
|
|
1133
|
-
await bundleScripts(projectPath, scriptPath, element);
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1136
|
-
await runScript(absoluteModPath);
|
|
1137
|
-
await syncDevFilesServer(projectPath, projectName);
|
|
1138
|
-
};
|
|
1139
|
-
|
|
1140
|
-
function versionStringToArray(versionString) {
|
|
1141
|
-
// 使用 split 方法将字符串按 '.' 分割成数组
|
|
1142
|
-
const parts = versionString.split('.');
|
|
1143
|
-
|
|
1144
|
-
// 使用 map 方法将每个部分转换为数字
|
|
1145
|
-
const versionArray = parts.map(part => Number(part));
|
|
1146
|
-
|
|
1147
|
-
return versionArray
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
const generateBehManifest = (name, description, version, options = {}, dependencies = [], entry) => {
|
|
1151
|
-
console.log("开始生成behavior_packs/manifest.json");
|
|
1152
|
-
console.log("Entry:", entry);
|
|
1153
|
-
const header = new AddonManifestHeader(
|
|
1154
|
-
(name + "_BP"),
|
|
1155
|
-
description,
|
|
1156
|
-
versionStringToArray(version),
|
|
1157
|
-
generateUUID(),
|
|
1158
|
-
options
|
|
1159
|
-
);
|
|
1160
|
-
const module = new AddonManifestModule(
|
|
1161
|
-
"行为模块",
|
|
1162
|
-
"data",
|
|
1163
|
-
generateUUID(),
|
|
1164
|
-
versionStringToArray(version)
|
|
1165
|
-
);
|
|
1166
|
-
const script_module = new AddonManifestModule(
|
|
1167
|
-
"脚本模块",
|
|
1168
|
-
"script",
|
|
1169
|
-
generateUUID(),
|
|
1170
|
-
versionStringToArray(version)
|
|
1171
|
-
);
|
|
1172
|
-
if (entry) { script_module.entry = entry; }
|
|
1173
|
-
|
|
1174
|
-
const metadata = new AddonManifestMetadata(
|
|
1175
|
-
["@sapdon"],
|
|
1176
|
-
"MIT",
|
|
1177
|
-
{
|
|
1178
|
-
"sapdon": ["1.0.0"]
|
|
1179
|
-
},
|
|
1180
|
-
"addon",
|
|
1181
|
-
"https://github.com/junjun260/sapdon"
|
|
1182
|
-
);
|
|
1183
|
-
|
|
1184
|
-
const manifest = new AddonManifest(
|
|
1185
|
-
2,//格式版本
|
|
1186
|
-
header,
|
|
1187
|
-
[module, script_module],
|
|
1188
|
-
dependencies,
|
|
1189
|
-
null,
|
|
1190
|
-
metadata
|
|
1191
|
-
);
|
|
1192
|
-
|
|
1193
|
-
return JSON.stringify(manifest, null, 2)
|
|
1194
|
-
};
|
|
1195
|
-
|
|
1196
|
-
const generateResManifest = (name, description, version, options = {}, dependencies = []) => {
|
|
1197
|
-
const header = new AddonManifestHeader(
|
|
1198
|
-
(name + "_RP"),
|
|
1199
|
-
description,
|
|
1200
|
-
versionStringToArray(version),
|
|
1201
|
-
generateUUID(),
|
|
1202
|
-
options
|
|
1203
|
-
);
|
|
1204
|
-
const module = new AddonManifestModule(
|
|
1205
|
-
"资源模块",
|
|
1206
|
-
"resources",
|
|
1207
|
-
generateUUID(),
|
|
1208
|
-
versionStringToArray(version)
|
|
1209
|
-
);
|
|
1210
|
-
|
|
1211
|
-
const metadata = new AddonManifestMetadata(
|
|
1212
|
-
["@sapdon"],
|
|
1213
|
-
"MIT",
|
|
1214
|
-
{
|
|
1215
|
-
"sapdon": ["1.0.0"]
|
|
1216
|
-
},
|
|
1217
|
-
"addon",
|
|
1218
|
-
"https://github.com/junjun260/sapdon"
|
|
1219
|
-
);
|
|
1220
|
-
|
|
1221
|
-
const manifest = new AddonManifest(
|
|
1222
|
-
2,//格式版本
|
|
1223
|
-
header,
|
|
1224
|
-
[module],
|
|
1225
|
-
[],
|
|
1226
|
-
null,
|
|
1227
|
-
metadata
|
|
1228
|
-
);
|
|
1229
|
-
|
|
1230
|
-
return JSON.stringify(manifest, null, 2)
|
|
1231
|
-
};
|
|
1232
|
-
|
|
1233
|
-
const __filename = fileURLToPath$1(import.meta.url);
|
|
1234
|
-
const __dirname = path.dirname(__filename);
|
|
1235
|
-
|
|
1236
|
-
process.removeAllListeners('warning');
|
|
1237
|
-
|
|
1238
|
-
async function start() {
|
|
1239
|
-
// 额外添加的init方法
|
|
1240
|
-
program.command("init").description("初始化一个基于NodeJS的项目").action(() => {
|
|
1241
|
-
const currentDir = process.cwd();
|
|
1242
|
-
const packageJsonPath = path.join(currentDir, 'package.json');
|
|
1243
|
-
let packageJsonData;
|
|
1244
|
-
if (!fs.existsSync(packageJsonPath)) {
|
|
1245
|
-
console.error("没有找到package.json文件,请使改用create命令进行创建。");
|
|
1246
|
-
return
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
|
-
try {
|
|
1250
|
-
packageJsonData = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
1251
|
-
} catch (error) {
|
|
1252
|
-
console.error("读取package.json文件时出错:", error);
|
|
1253
|
-
console.log("请使改用create命令进行创建。");
|
|
1254
|
-
return
|
|
1255
|
-
}
|
|
1256
|
-
|
|
1257
|
-
// 添加或更新scripts字段
|
|
1258
|
-
packageJsonData.scripts = {
|
|
1259
|
-
...packageJsonData.scripts,
|
|
1260
|
-
init: "sapdon init",
|
|
1261
|
-
pack: "sapdon pack",
|
|
1262
|
-
config: "sapdon config"
|
|
1263
|
-
};
|
|
1264
|
-
|
|
1265
|
-
try {
|
|
1266
|
-
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJsonData, null, 2), 'utf-8');
|
|
1267
|
-
} catch (error) {
|
|
1268
|
-
console.error("写入package.json文件时出错:", error);
|
|
1269
|
-
return
|
|
1270
|
-
}
|
|
1271
|
-
|
|
1272
|
-
inquirer.prompt([
|
|
1273
|
-
{
|
|
1274
|
-
type: "input",
|
|
1275
|
-
name: "min_engine_version",
|
|
1276
|
-
message: "最低引擎版本:",
|
|
1277
|
-
default: "1.19.50"
|
|
1278
|
-
}
|
|
1279
|
-
]).then((answers) => {
|
|
1280
|
-
initNPMProject(currentDir, { ...readPackageJson(currentDir), ...answers });
|
|
1281
|
-
console.log("请使用命令sapdon config配置框架的build.config文件。");
|
|
1282
|
-
});
|
|
1283
|
-
});
|
|
1284
|
-
|
|
1285
|
-
program.command("create <project-name>").description("Create a new project").action((projectName) => {
|
|
1286
|
-
inquirer.prompt([
|
|
1287
|
-
{
|
|
1288
|
-
type: "input",
|
|
1289
|
-
name: "name",
|
|
1290
|
-
message: "Project Name:",
|
|
1291
|
-
default: path.basename(projectName)
|
|
1292
|
-
},
|
|
1293
|
-
{
|
|
1294
|
-
type: "input",
|
|
1295
|
-
name: "description",
|
|
1296
|
-
message: "Project Description:",
|
|
1297
|
-
default: "A new sapdon project"
|
|
1298
|
-
},
|
|
1299
|
-
{
|
|
1300
|
-
type: "input",
|
|
1301
|
-
name: "author",
|
|
1302
|
-
message: "Author Name:",
|
|
1303
|
-
default: "Sapdon"
|
|
1304
|
-
},
|
|
1305
|
-
{
|
|
1306
|
-
type: "input",
|
|
1307
|
-
name: "version",
|
|
1308
|
-
message: "Project Version:",
|
|
1309
|
-
default: "1.0.0"
|
|
1310
|
-
},
|
|
1311
|
-
{
|
|
1312
|
-
type: "input",
|
|
1313
|
-
name: "min_engine_version",
|
|
1314
|
-
message: "Minimum Engine Version:",
|
|
1315
|
-
default: "1.19.50",
|
|
1316
|
-
},
|
|
1317
|
-
{
|
|
1318
|
-
type: "input",
|
|
1319
|
-
name: "language",
|
|
1320
|
-
message: "Language:(js/ts)",
|
|
1321
|
-
default: "ts",
|
|
1322
|
-
},
|
|
1323
|
-
]).then((answers) => {
|
|
1324
|
-
const projectPath = path.join(process.cwd(), projectName);
|
|
1325
|
-
console.log('项目路径:', projectPath);
|
|
1326
|
-
initProject(projectPath, answers);
|
|
1327
|
-
initMojangPath(projectPath);
|
|
1328
|
-
writeLib(projectPath);
|
|
1329
|
-
});
|
|
1330
|
-
});
|
|
1331
|
-
|
|
1332
|
-
program.command("build <project-name>").description("Build the project").action((projectName) => {
|
|
1333
|
-
console.log("Building the project...");
|
|
1334
|
-
const projectPath = path.join(process.cwd(), projectName);
|
|
1335
|
-
globalObject.projectPath = projectPath;
|
|
1336
|
-
initResourceDir();
|
|
1337
|
-
if (projectCanBuild(projectPath)) {
|
|
1338
|
-
buildProject(projectPath, path.basename(projectPath));
|
|
1339
|
-
}
|
|
1340
|
-
});
|
|
1341
|
-
|
|
1342
|
-
// pack 命令
|
|
1343
|
-
program.command("pack").description("Pack the current project").action(() => {
|
|
1344
|
-
console.log("Packing the current project...");
|
|
1345
|
-
const projectPath = process.cwd();
|
|
1346
|
-
if (projectCanBuild(projectPath)) {
|
|
1347
|
-
buildProject(projectPath, path.basename(projectPath));
|
|
1348
|
-
}
|
|
1349
|
-
});
|
|
1350
|
-
|
|
1351
|
-
program.command('lib').description('Generate lib files for development server.').action(() => {
|
|
1352
|
-
const projectPath = process.cwd();
|
|
1353
|
-
writeLib(projectPath);
|
|
1354
|
-
});
|
|
1355
|
-
|
|
1356
|
-
program.command('res').description('Generate resource hints.').action(() => {
|
|
1357
|
-
initResourceDir();
|
|
1358
|
-
});
|
|
1359
|
-
|
|
1360
|
-
// 配置build.config文件的命令
|
|
1361
|
-
program.command("config").description("Configure build.config file").action(() => {
|
|
1362
|
-
const buildConfigPath = path.join(__dirname, "./build.config");
|
|
1363
|
-
let buildConfigData;
|
|
1364
|
-
|
|
1365
|
-
try {
|
|
1366
|
-
buildConfigData = JSON.parse(readFile(buildConfigPath));
|
|
1367
|
-
} catch (error) {
|
|
1368
|
-
console.error("读取build.config文件时出错:", error);
|
|
1369
|
-
return
|
|
1370
|
-
}
|
|
1371
|
-
|
|
1372
|
-
inquirer.prompt([
|
|
1373
|
-
{
|
|
1374
|
-
type: "input",
|
|
1375
|
-
name: "mojangPath",
|
|
1376
|
-
message: "Mojang Path (must end with LocalState/games/com.mojang/):",
|
|
1377
|
-
default: path.join(os.homedir(), "AppData/Local/Packages/Microsoft.MinecraftUWP_8wekyb3d8bbwe/LocalState/games/com.mojang/")
|
|
1378
|
-
},
|
|
1379
|
-
{
|
|
1380
|
-
type: "input",
|
|
1381
|
-
name: "mojangBetaPath",
|
|
1382
|
-
message: "Mojang Beta Path (must end with LocalState/games/com.mojang/):",
|
|
1383
|
-
default: path.join(os.homedir(), "AppData/Local/Packages/Microsoft.MinecraftUWP_8wekyb3d8bbwe/LocalState/games/com.mojang/")
|
|
1384
|
-
}
|
|
1385
|
-
]).then((answers) => {
|
|
1386
|
-
try {
|
|
1387
|
-
fs.writeFileSync(buildConfigPath, JSON.stringify({ ...buildConfigData, ...answers }, null, 2), 'utf-8');
|
|
1388
|
-
console.log("build.config文件已更新。");
|
|
1389
|
-
} catch (error) {
|
|
1390
|
-
console.error("写入build.config文件时出错:", error);
|
|
1391
|
-
}
|
|
1392
|
-
});
|
|
1393
|
-
});
|
|
1394
|
-
|
|
1395
|
-
program.parse(program.argv);
|
|
1396
|
-
}
|
|
1397
|
-
|
|
1297
|
+
const __filename = fileURLToPath$1(import.meta.url);
|
|
1298
|
+
const __dirname = path.dirname(__filename);
|
|
1299
|
+
process.removeAllListeners('warning');
|
|
1300
|
+
async function start() {
|
|
1301
|
+
// 额外添加的init方法
|
|
1302
|
+
program.command("init").description("初始化一个基于NodeJS的项目").action(() => {
|
|
1303
|
+
const currentDir = process.cwd();
|
|
1304
|
+
const packageJsonPath = path.join(currentDir, 'package.json');
|
|
1305
|
+
let packageJsonData;
|
|
1306
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
1307
|
+
console.error("没有找到package.json文件,请使改用create命令进行创建。");
|
|
1308
|
+
return;
|
|
1309
|
+
}
|
|
1310
|
+
try {
|
|
1311
|
+
packageJsonData = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
1312
|
+
}
|
|
1313
|
+
catch (error) {
|
|
1314
|
+
console.error("读取package.json文件时出错:", error);
|
|
1315
|
+
console.log("请使改用create命令进行创建。");
|
|
1316
|
+
return;
|
|
1317
|
+
}
|
|
1318
|
+
// 添加或更新scripts字段
|
|
1319
|
+
packageJsonData.scripts = {
|
|
1320
|
+
...packageJsonData.scripts,
|
|
1321
|
+
init: "sapdon init",
|
|
1322
|
+
pack: "sapdon pack",
|
|
1323
|
+
config: "sapdon config"
|
|
1324
|
+
};
|
|
1325
|
+
try {
|
|
1326
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJsonData, null, 2), 'utf-8');
|
|
1327
|
+
}
|
|
1328
|
+
catch (error) {
|
|
1329
|
+
console.error("写入package.json文件时出错:", error);
|
|
1330
|
+
return;
|
|
1331
|
+
}
|
|
1332
|
+
inquirer.prompt([
|
|
1333
|
+
{
|
|
1334
|
+
type: "input",
|
|
1335
|
+
name: "min_engine_version",
|
|
1336
|
+
message: "最低引擎版本:",
|
|
1337
|
+
default: "1.19.50"
|
|
1338
|
+
}
|
|
1339
|
+
]).then((answers) => {
|
|
1340
|
+
initNPMProject(currentDir, { ...readPackageJson(currentDir), ...answers });
|
|
1341
|
+
console.log("请使用命令sapdon config配置框架的build.config文件。");
|
|
1342
|
+
});
|
|
1343
|
+
});
|
|
1344
|
+
program.command("create <project-name>").description("Create a new project").action((projectName) => {
|
|
1345
|
+
inquirer.prompt([
|
|
1346
|
+
{
|
|
1347
|
+
type: "input",
|
|
1348
|
+
name: "name",
|
|
1349
|
+
message: "Project Name:",
|
|
1350
|
+
default: path.basename(projectName)
|
|
1351
|
+
},
|
|
1352
|
+
{
|
|
1353
|
+
type: "input",
|
|
1354
|
+
name: "description",
|
|
1355
|
+
message: "Project Description:",
|
|
1356
|
+
default: "A new sapdon project"
|
|
1357
|
+
},
|
|
1358
|
+
{
|
|
1359
|
+
type: "input",
|
|
1360
|
+
name: "author",
|
|
1361
|
+
message: "Author Name:",
|
|
1362
|
+
default: "Sapdon"
|
|
1363
|
+
},
|
|
1364
|
+
{
|
|
1365
|
+
type: "input",
|
|
1366
|
+
name: "version",
|
|
1367
|
+
message: "Project Version:",
|
|
1368
|
+
default: "1.0.0"
|
|
1369
|
+
},
|
|
1370
|
+
{
|
|
1371
|
+
type: "input",
|
|
1372
|
+
name: "min_engine_version",
|
|
1373
|
+
message: "Minimum Engine Version:",
|
|
1374
|
+
default: "1.19.50",
|
|
1375
|
+
},
|
|
1376
|
+
{
|
|
1377
|
+
type: "input",
|
|
1378
|
+
name: "language",
|
|
1379
|
+
message: "Language:(js/ts)",
|
|
1380
|
+
default: "ts",
|
|
1381
|
+
},
|
|
1382
|
+
]).then((answers) => {
|
|
1383
|
+
const projectPath = path.join(process.cwd(), projectName);
|
|
1384
|
+
console.log('项目路径:', projectPath);
|
|
1385
|
+
initProject(projectPath, answers);
|
|
1386
|
+
writeLib(projectPath);
|
|
1387
|
+
});
|
|
1388
|
+
});
|
|
1389
|
+
program.command("build <project-name>").description("Build the project").action((projectName) => {
|
|
1390
|
+
console.log("Building the project...");
|
|
1391
|
+
const projectPath = path.join(process.cwd(), projectName);
|
|
1392
|
+
globalObject.projectPath = projectPath;
|
|
1393
|
+
initResourceDir();
|
|
1394
|
+
if (projectCanBuild(projectPath)) {
|
|
1395
|
+
buildProject(projectPath, path.basename(projectPath));
|
|
1396
|
+
hmr(projectPath, projectName);
|
|
1397
|
+
}
|
|
1398
|
+
});
|
|
1399
|
+
// pack 命令
|
|
1400
|
+
program.command("pack").description("Pack the current project").action(() => {
|
|
1401
|
+
console.log("Packing the current project...");
|
|
1402
|
+
const projectPath = process.cwd();
|
|
1403
|
+
if (projectCanBuild(projectPath)) {
|
|
1404
|
+
buildProject(projectPath, path.basename(projectPath));
|
|
1405
|
+
}
|
|
1406
|
+
});
|
|
1407
|
+
program.command('lib').description('Generate lib files for development server.').action(() => {
|
|
1408
|
+
const projectPath = process.cwd();
|
|
1409
|
+
writeLib(projectPath);
|
|
1410
|
+
});
|
|
1411
|
+
program.command('res').description('Generate resource hints.').action(() => {
|
|
1412
|
+
initResourceDir();
|
|
1413
|
+
});
|
|
1414
|
+
// 配置build.config文件的命令
|
|
1415
|
+
program.command("config").description("Configure build.config file").action(() => {
|
|
1416
|
+
const buildConfigPath = path.join(__dirname, "./build.config");
|
|
1417
|
+
let buildConfigData;
|
|
1418
|
+
try {
|
|
1419
|
+
buildConfigData = JSON.parse(readFile(buildConfigPath));
|
|
1420
|
+
}
|
|
1421
|
+
catch (error) {
|
|
1422
|
+
console.error("读取build.config文件时出错:", error);
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1425
|
+
});
|
|
1426
|
+
program.parse(program.argv);
|
|
1427
|
+
}
|
|
1398
1428
|
start();
|