@sfmc-bds/bds-tools 0.2.0-beta.11 → 0.2.0-beta.13
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/dist/bds-manager.d.ts.map +1 -1
- package/dist/bds-manager.js +12 -1
- package/dist/bds-manager.js.map +2 -2
- package/dist/check-update.d.ts.map +1 -1
- package/dist/check-update.js +3 -2
- package/dist/check-update.js.map +2 -2
- package/dist/cli-pack-manager.js +11 -1
- package/dist/cli-pack-manager.js.map +2 -2
- package/dist/dependency-negotiator.d.ts +73 -0
- package/dist/dependency-negotiator.d.ts.map +1 -0
- package/dist/dependency-negotiator.js +151 -0
- package/dist/dependency-negotiator.js.map +7 -0
- package/dist/dependency-negotiator.test.js +120 -0
- package/dist/dependency-negotiator.test.js.map +7 -0
- package/dist/level-dat.d.ts +87 -0
- package/dist/level-dat.d.ts.map +1 -0
- package/dist/level-dat.js +326 -0
- package/dist/level-dat.js.map +7 -0
- package/dist/level-dat.test.js +125 -0
- package/dist/level-dat.test.js.map +7 -0
- package/dist/pack-manager.d.ts +18 -6
- package/dist/pack-manager.d.ts.map +1 -1
- package/dist/pack-manager.js +73 -24
- package/dist/pack-manager.js.map +2 -2
- package/dist/server-properties-i18n.d.ts +17 -0
- package/dist/server-properties-i18n.d.ts.map +1 -0
- package/dist/server-properties-i18n.js +197 -0
- package/dist/server-properties-i18n.js.map +7 -0
- package/dist/server-properties.d.ts +22 -0
- package/dist/server-properties.d.ts.map +1 -1
- package/dist/server-properties.js +126 -1
- package/dist/server-properties.js.map +2 -2
- package/dist/server-properties.test.js +127 -0
- package/dist/server-properties.test.js.map +7 -0
- package/dist/world-packs.d.ts +57 -1
- package/dist/world-packs.d.ts.map +1 -1
- package/dist/world-packs.js +159 -1
- package/dist/world-packs.js.map +2 -2
- package/package.json +6 -3
package/dist/pack-manager.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { copyDirAsync, copyFileAsync, readJsonFile } from "./fsx.js";
|
|
4
|
+
import {
|
|
5
|
+
BASELINE_BEDROCK_DEPENDENCIES
|
|
6
|
+
} from "./dependency-negotiator.js";
|
|
7
|
+
export * from "./dependency-negotiator.js";
|
|
4
8
|
const SFMC_PERMISSIONS = [
|
|
5
9
|
"@minecraft/server",
|
|
6
10
|
"@minecraft/server-ui",
|
|
@@ -19,6 +23,9 @@ function bdsWorldsDir(bdsRoot) {
|
|
|
19
23
|
function bdsWorldLevelDir(bdsRoot, levelName) {
|
|
20
24
|
return path.join(bdsWorldsDir(bdsRoot), levelName);
|
|
21
25
|
}
|
|
26
|
+
function levelDatPath(bdsRoot, levelName) {
|
|
27
|
+
return path.join(bdsWorldLevelDir(bdsRoot, levelName), "level.dat");
|
|
28
|
+
}
|
|
22
29
|
function worldPackListFile(worldsDir, levelName, kind) {
|
|
23
30
|
const name = kind === "behavior" ? "world_behavior_packs.json" : "world_resource_packs.json";
|
|
24
31
|
return path.join(worldsDir, levelName, name);
|
|
@@ -26,8 +33,11 @@ function worldPackListFile(worldsDir, levelName, kind) {
|
|
|
26
33
|
function configPermissionPath(bdsRoot, bpUuid) {
|
|
27
34
|
return path.join(bdsRoot, "config", bpUuid, "permission.json");
|
|
28
35
|
}
|
|
36
|
+
function configPermissionsPath(bdsRoot, bpUuid) {
|
|
37
|
+
return path.join(bdsRoot, "config", bpUuid, "permissions.json");
|
|
38
|
+
}
|
|
29
39
|
function hasConfigPermission(bdsRoot, bpUuid) {
|
|
30
|
-
return fs.existsSync(configPermissionPath(bdsRoot, bpUuid));
|
|
40
|
+
return fs.existsSync(configPermissionsPath(bdsRoot, bpUuid)) || fs.existsSync(configPermissionPath(bdsRoot, bpUuid));
|
|
31
41
|
}
|
|
32
42
|
function randomUuid() {
|
|
33
43
|
return crypto.randomUUID();
|
|
@@ -43,13 +53,17 @@ async function assembleBehaviorPack(opts) {
|
|
|
43
53
|
await fs.promises.mkdir(path.join(opts.outDir, "scripts"), { recursive: true });
|
|
44
54
|
await fs.promises.writeFile(path.join(opts.outDir, "scripts", "main.js"), "/* no scripts */\n", "utf8");
|
|
45
55
|
}
|
|
46
|
-
await writeBehaviorPackManifest(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
56
|
+
await writeBehaviorPackManifest(
|
|
57
|
+
opts.outDir,
|
|
58
|
+
{
|
|
59
|
+
name: opts.projectName,
|
|
60
|
+
uuid: bpUuid,
|
|
61
|
+
version,
|
|
62
|
+
description: opts.description,
|
|
63
|
+
moduleUuid: opts.moduleUuid
|
|
64
|
+
},
|
|
65
|
+
opts.dependencies
|
|
66
|
+
);
|
|
53
67
|
if (opts.iconSrc && fs.existsSync(opts.iconSrc)) {
|
|
54
68
|
await copyFileAsync(opts.iconSrc, path.join(opts.outDir, "pack_icon.png"));
|
|
55
69
|
}
|
|
@@ -109,16 +123,42 @@ async function deployToBDS(opts) {
|
|
|
109
123
|
}
|
|
110
124
|
return { bpDir: bpDst, rpDir };
|
|
111
125
|
}
|
|
112
|
-
async function ensureConfigPermission(bdsRoot, bpUuid) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
126
|
+
async function ensureConfigPermission(bdsRoot, bpUuid, moduleUuid) {
|
|
127
|
+
let changed = false;
|
|
128
|
+
const updateFile = async (filePath) => {
|
|
129
|
+
let currentModules = [];
|
|
130
|
+
let restConfig = {};
|
|
131
|
+
if (fs.existsSync(filePath)) {
|
|
132
|
+
try {
|
|
133
|
+
const raw = readJsonFile(filePath);
|
|
134
|
+
if (Array.isArray(raw.allowed_modules)) {
|
|
135
|
+
currentModules = raw.allowed_modules;
|
|
136
|
+
}
|
|
137
|
+
const { allowed_modules: _, ...rest } = raw;
|
|
138
|
+
restConfig = rest;
|
|
139
|
+
} catch {
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const merged = Array.from(/* @__PURE__ */ new Set([...currentModules, ...SFMC_PERMISSIONS]));
|
|
143
|
+
if (merged.length === currentModules.length && fs.existsSync(filePath)) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
const dir = path.dirname(filePath);
|
|
147
|
+
await fs.promises.mkdir(dir, { recursive: true });
|
|
148
|
+
const payload = { allowed_modules: merged, ...restConfig };
|
|
149
|
+
const tmp = path.join(dir, `.permission.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`);
|
|
150
|
+
await fs.promises.writeFile(tmp, JSON.stringify(payload, null, 2) + "\n", "utf8");
|
|
151
|
+
await fs.promises.rename(tmp, filePath);
|
|
152
|
+
return true;
|
|
153
|
+
};
|
|
154
|
+
const uuids = Array.from(/* @__PURE__ */ new Set([bpUuid, ...moduleUuid ? [moduleUuid] : []]));
|
|
155
|
+
for (const u of uuids) {
|
|
156
|
+
if (await updateFile(configPermissionsPath(bdsRoot, u))) changed = true;
|
|
157
|
+
if (await updateFile(configPermissionPath(bdsRoot, u))) changed = true;
|
|
158
|
+
}
|
|
159
|
+
const defaultFile = path.join(bdsRoot, "config", "default", "permissions.json");
|
|
160
|
+
if (await updateFile(defaultFile)) changed = true;
|
|
161
|
+
return changed;
|
|
122
162
|
}
|
|
123
163
|
function readPackManifestHeader(packDir) {
|
|
124
164
|
const file = path.join(packDir, "manifest.json");
|
|
@@ -135,6 +175,16 @@ function readPackManifestHeader(packDir) {
|
|
|
135
175
|
return null;
|
|
136
176
|
}
|
|
137
177
|
}
|
|
178
|
+
function readPackManifestDependencies(packDir) {
|
|
179
|
+
const file = path.join(packDir, "manifest.json");
|
|
180
|
+
if (!fs.existsSync(file)) return [];
|
|
181
|
+
try {
|
|
182
|
+
const raw = readJsonFile(file);
|
|
183
|
+
return Array.isArray(raw.dependencies) ? raw.dependencies : [];
|
|
184
|
+
} catch {
|
|
185
|
+
return [];
|
|
186
|
+
}
|
|
187
|
+
}
|
|
138
188
|
async function writePermissionsJson(bpDir) {
|
|
139
189
|
const payload = { allowed_modules: [...SFMC_PERMISSIONS] };
|
|
140
190
|
await fs.promises.mkdir(bpDir, { recursive: true });
|
|
@@ -164,7 +214,7 @@ async function editWorldPackList(opts, mode) {
|
|
|
164
214
|
await fs.promises.writeFile(tmp, JSON.stringify(entries, null, 2) + "\n", "utf8");
|
|
165
215
|
await fs.promises.rename(tmp, file);
|
|
166
216
|
}
|
|
167
|
-
async function writeBehaviorPackManifest(outDir, header) {
|
|
217
|
+
async function writeBehaviorPackManifest(outDir, header, dependencies) {
|
|
168
218
|
const manifest = {
|
|
169
219
|
format_version: 2,
|
|
170
220
|
header: {
|
|
@@ -183,11 +233,7 @@ async function writeBehaviorPackManifest(outDir, header) {
|
|
|
183
233
|
version: header.version
|
|
184
234
|
}
|
|
185
235
|
],
|
|
186
|
-
dependencies:
|
|
187
|
-
{ module_name: "@minecraft/server", version: "1.18.0" },
|
|
188
|
-
{ module_name: "@minecraft/server-admin", version: "1.0.0-beta" },
|
|
189
|
-
{ module_name: "@minecraft/diagnostics", version: "1.0.0-beta" }
|
|
190
|
-
]
|
|
236
|
+
dependencies: dependencies && dependencies.length > 0 ? dependencies : BASELINE_BEDROCK_DEPENDENCIES
|
|
191
237
|
};
|
|
192
238
|
const file = path.join(outDir, "manifest.json");
|
|
193
239
|
await fs.promises.mkdir(outDir, { recursive: true });
|
|
@@ -281,6 +327,7 @@ export {
|
|
|
281
327
|
bdsWorldLevelDir,
|
|
282
328
|
bdsWorldsDir,
|
|
283
329
|
configPermissionPath,
|
|
330
|
+
configPermissionsPath,
|
|
284
331
|
copyDirAsync,
|
|
285
332
|
copyFileAsync,
|
|
286
333
|
deployToBDS,
|
|
@@ -288,10 +335,12 @@ export {
|
|
|
288
335
|
enablePackInWorld,
|
|
289
336
|
ensureConfigPermission,
|
|
290
337
|
hasConfigPermission,
|
|
338
|
+
levelDatPath,
|
|
291
339
|
loadModuleResourcePackMap,
|
|
292
340
|
randomUuid,
|
|
293
341
|
readLevelName,
|
|
294
342
|
readLevelNameSync,
|
|
343
|
+
readPackManifestDependencies,
|
|
295
344
|
readPackManifestHeader,
|
|
296
345
|
readWorldPackList,
|
|
297
346
|
readWorldPackListResult,
|
package/dist/pack-manager.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/pack-manager.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * pack-manager.ts \u2014 Bedrock \u884C\u4E3A\u5305\uFF08BP\uFF09\u4E0E\u8D44\u6E90\u5305\uFF08RP\uFF09\u7EC4\u88C5\u53CA\u90E8\u7F72\u5F15\u64CE\n *\n * \u6838\u5FC3\u8BBE\u8BA1\u4E0E\u8C03\u7528\u8DEF\u5F84\uFF1A\n * - \u8FDB\u7A0B\u5185\u76F4\u8FDE\uFF08\u63A8\u8350\uFF09\uFF1A`@sfmc-bds/bds-tools/pack-manager-lib` \u4F9B CLI \u7F16\u6392\u4E0E\u751F\u547D\u5468\u671F\u7BA1\u7406\u76F4\u63A5\u8C03\u7528\uFF08\u9075\u5FAA\u4F9D\u8D56\u5012\u7F6E\u539F\u5219\uFF09\n * - \u72EC\u7ACB CLI\uFF1A\u7531 `cli-pack-manager.ts` \u66B4\u9732\u547D\u4EE4\u884C\u5B50\u547D\u4EE4\u4F9B\u811A\u672C\u4E0E\u624B\u5DE5\u8C03\u8BD5\u4F7F\u7528\n *\n * \u6838\u5FC3\u80FD\u529B\uFF1A\n * - \u884C\u4E3A\u5305\u7EC4\u88C5\uFF1A\u5C06 esbuild \u6253\u5305\u540E\u7684 `scripts/main.js`\u3001\u5143\u6570\u636E manifest \u4E0E\u56FE\u6807\u5C01\u88C5\u4E3A BDS \u884C\u4E3A\u5305\u7ED3\u6784\n * - \u8D44\u6E90\u5305\u805A\u5408\uFF1A\u5C06\u5404\u6A21\u5757\u79C1\u6709\u7684 `resource_pack` \u76EE\u5F55\u65E0\u51B2\u7A81\u9012\u5F52\u5408\u5E76\u4E3A\u805A\u5408\u8D44\u6E90\u5305\n * - \u4E16\u754C\u90E8\u7F72\u4E0E\u6E05\u5355\u6FC0\u6D3B\uFF1A\u5C06\u5305\u90E8\u7F72\u81F3 BDS `<level>/behavior_packs` \u4E0E `resource_packs`\uFF0C\u5E76\u540C\u6B65\u7EF4\u62A4 `world_behavior_packs.json`\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { copyDirAsync, copyFileAsync, readJsonFile } from \"./fsx.js\";\n\n/* \u2500\u2500 \u7C7B\u578B\u5B9A\u4E49 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\nexport interface AssembleBehaviorPackOpts {\n /** \u5DF2\u5B8C\u6210\u6253\u5305\u7684 `scripts/main.js` \u6240\u5728\u6E90\u7801\u76EE\u5F55\uFF08\u5373 esbuild \u8F93\u51FA\u76EE\u5F55\uFF09\u3002 */\n srcDir: string;\n /** \u884C\u4E3A\u5305\u76EE\u6807\u8F93\u51FA\u76EE\u5F55\uFF08\u82E5\u4E0D\u5B58\u5728\u5219\u81EA\u52A8\u521B\u5EFA\uFF09\u3002 */\n outDir: string;\n /** BP \u9879\u76EE/\u76EE\u5F55\u540D\uFF08\u9ED8\u8BA4\u4E3A `'sfmc-modules'`\uFF09\u3002 */\n projectName: string;\n /** `manifest.json` \u4E2D\u7684 `header.version` `[major, minor, patch]`\uFF08\u9ED8\u8BA4\u4E3A `[1, 0, 0]`\uFF09\u3002 */\n version?: [number, number, number] | undefined;\n /** `manifest.json` \u4E2D\u7684\u5305\u63CF\u8FF0\u4FE1\u606F\u3002 */\n description?: string | undefined;\n /** `pack_icon.png` \u56FE\u6807\u6E90\u6587\u4EF6\u8DEF\u5F84\uFF08\u53EF\u9009\uFF0C\u672A\u63D0\u4F9B\u5219\u8DF3\u8FC7\uFF09\u3002 */\n iconSrc?: string | undefined;\n /** \u7A33\u5B9A\u7684 `header.uuid`\uFF08\u7F3A\u7701\u65F6\u5C06\u5728\u9996\u6B21\u88C5\u914D\u65F6\u968F\u673A\u751F\u6210\uFF09\u3002 */\n uuid?: string | undefined;\n /** \u7A33\u5B9A\u7684 `script module uuid`\uFF08\u7F3A\u7701\u65F6\u968F\u673A\u751F\u6210\uFF09\u3002 */\n moduleUuid?: string | undefined;\n}\n\nexport interface AssembleResourcePackOpts {\n /** \u9700\u5408\u5E76\u8D44\u6E90\u5305\u76EE\u5F55\u7684\u6A21\u5757\u6620\u5C04\u5B57\u5178\uFF08`Record<moduleId, resourcePackDir>`\uFF09\u3002 */\n moduleResourceDirs: Record<string, string>;\n /** \u8D44\u6E90\u5305\u76EE\u6807\u8F93\u51FA\u76EE\u5F55\uFF08\u82E5\u4E0D\u5B58\u5728\u5219\u81EA\u52A8\u521B\u5EFA\uFF09\u3002 */\n outDir: string;\n /** RP \u9879\u76EE/\u76EE\u5F55\u540D\u3002 */\n projectName: string;\n /** `manifest.json` \u4E2D\u7684 `header.version` `[major, minor, patch]`\uFF08\u9ED8\u8BA4\u4E3A `[1, 0, 0]`\uFF09\u3002 */\n version?: [number, number, number] | undefined;\n /** `manifest.json` \u4E2D\u7684\u5305\u63CF\u8FF0\u4FE1\u606F\u3002 */\n description?: string | undefined;\n /** \u7A33\u5B9A\u7684 `header.uuid`\uFF08\u7F3A\u7701\u65F6\u968F\u673A\u751F\u6210\uFF09\u3002 */\n uuid?: string | undefined;\n /** \u7A33\u5B9A\u7684 `resources module uuid`\uFF08\u7F3A\u7701\u65F6\u968F\u673A\u751F\u6210\uFF09\u3002 */\n moduleUuid?: string | undefined;\n}\n\n\nexport interface AssembleResult {\n uuid: string;\n version: [number, number, number];\n}\n\nexport interface DeployOpts {\n bdsRoot: string;\n levelName: string;\n /** \u5DF2\u7EC4\u88C5\u597D\u7684 BP \u6E90\u76EE\u5F55 */\n behaviorPackSrc: string;\n /** \u5DF2\u7EC4\u88C5\u597D\u7684 RP \u6E90\u76EE\u5F55 (\u53EF\u7701\u7565,\u53EA\u7528 BP \u4E5F\u5408\u6CD5) */\n resourcePackSrc?: string;\n /** BP \u76EE\u6807\u76EE\u5F55\u540D (worlds/<level>/behavior_packs/<bpName>) */\n bpName: string;\n /** RP \u76EE\u6807\u76EE\u5F55\u540D (worlds/<level>/resource_packs/<rpName>);\u7701\u7565\u65F6\u590D\u7528 bpName + '-rp' */\n rpName?: string;\n /**\n * \u65E0 resourcePackSrc \u65F6\u662F\u5426\u5220\u9664\u4E16\u754C\u5185\u5DF2\u6709 RP \u76EE\u5F55\u3002\n * \u7528\u4E8E\u6A21\u5757\u4E0D\u518D\u63D0\u4F9B RP \u65F6\u6E05\u7406\u805A\u5408\u5305\u6B8B\u7559(\u9ED8\u8BA4 false,\u907F\u514D\u8BEF\u5220\u672A\u58F0\u660E\u7684 RP)\u3002\n */\n clearResourcePack?: boolean;\n}\n\nexport interface DeployResult {\n bpDir: string;\n rpDir: string | null;\n}\n\nexport interface EnablePackOpts {\n worldsDir: string;\n levelName: string;\n kind: \"behavior\" | \"resource\";\n packUuid: string;\n version: [number, number, number];\n}\n\n/* \u2500\u2500 \u8DEF\u5F84\u5E38\u91CF \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/** SFMC \u5408\u6210 BP \u7684\u56FA\u5B9A @minecraft/* permissions,\u6240\u6709\u7528\u5230\u7684\u547D\u540D\u7A7A\u95F4\u90FD\u6253\u5F00\u3002 */\nexport const SFMC_PERMISSIONS = [\n \"@minecraft/server\",\n \"@minecraft/server-ui\",\n \"@minecraft/server-admin\",\n \"@minecraft/server-gametest\",\n \"@minecraft/server-net\",\n \"@minecraft/server-editor\",\n \"@minecraft/diagnostics\",\n] as const;\n\n/** `<bdsRoot>/server.properties` \u2014 level-name / telemetry \u7B49\u5171\u7528\uFF08DRY\uFF09 */\nexport function serverPropertiesPath(bdsRoot: string): string {\n return path.join(bdsRoot, \"server.properties\");\n}\n\n/** `<bdsRoot>/worlds` \u2014 enable-list / \u90E8\u7F72\u8C03\u7528\u65B9\u52FF\u518D\u786C\u62FC\uFF08Demeter\uFF09 */\nexport function bdsWorldsDir(bdsRoot: string): string {\n return path.join(bdsRoot, \"worlds\");\n}\n\n/** `<bdsRoot>/worlds/<level>` */\nexport function bdsWorldLevelDir(bdsRoot: string, levelName: string): string {\n return path.join(bdsWorldsDir(bdsRoot), levelName);\n}\n\n/** \u4E16\u754C enable-list JSON \u7EDD\u5BF9\u8DEF\u5F84\uFF08\u5355\u4E00\u6743\u5A01\uFF0C\u4F9B\u8BFB\u5199\u4E24\u4FA7\uFF09 */\nexport function worldPackListFile(\n worldsDir: string,\n levelName: string,\n kind: \"behavior\" | \"resource\"\n): string {\n const name = kind === \"behavior\" ? \"world_behavior_packs.json\" : \"world_resource_packs.json\";\n return path.join(worldsDir, levelName, name);\n}\n\n/** `<bdsRoot>/config/<bpUuid>/permission.json` \u2014 Script API \u6743\u9650\u6587\u4EF6\u6743\u5A01\u8DEF\u5F84 */\nexport function configPermissionPath(bdsRoot: string, bpUuid: string): string {\n return path.join(bdsRoot, \"config\", bpUuid, \"permission.json\");\n}\n\n/** \u662F\u5426\u5DF2\u6709 Script API permission.json\uFF08\u53EA\u8BFB\uFF0C\u4F9B preflight/status\uFF09 */\nexport function hasConfigPermission(bdsRoot: string, bpUuid: string): boolean {\n return fs.existsSync(configPermissionPath(bdsRoot, bpUuid));\n}\n\n/** \u968F\u673A\u751F\u6210 BP/RP manifest.json header.uuid (RFC 4122 v4) */\nexport function randomUuid(): string {\n /* crypto.randomUUID \u662F Node 19+ \u5185\u7F6E,\u8FD9\u91CC\u76F4\u63A5\u7528 */\n return crypto.randomUUID();\n}\n\n/* \u2500\u2500 \u9AA8\u67B6\u51FD\u6570 (Commit 5 \u5B9E\u73B0) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/**\n * Assemble a Bedrock behavior pack directory at `outDir` from a prebuilt\n * `srcDir` (which must already contain `scripts/main.js` plus whatever else\n * was bundled by esbuild) and write a fresh `manifest.json` + `permissions.json`.\n *\n * The caller is responsible for running esbuild first; pack-manager does not\n * bundle scripts. That decoupling keeps pack assembly independent of the bundler.\n */\nexport async function assembleBehaviorPack(opts: AssembleBehaviorPackOpts): Promise<AssembleResult> {\n const version = opts.version ?? [1, 0, 0];\n const bpUuid = opts.uuid ?? randomUuid();\n await fs.promises.rm(opts.outDir, { recursive: true, force: true });\n await fs.promises.mkdir(opts.outDir, { recursive: true });\n if (fs.existsSync(opts.srcDir)) {\n await copyDirAsync(opts.srcDir, opts.outDir);\n } else {\n await fs.promises.mkdir(path.join(opts.outDir, \"scripts\"), { recursive: true });\n await fs.promises.writeFile(path.join(opts.outDir, \"scripts\", \"main.js\"), \"/* no scripts */\\n\", \"utf8\");\n }\n await writeBehaviorPackManifest(opts.outDir, {\n name: opts.projectName,\n uuid: bpUuid,\n version,\n description: opts.description,\n moduleUuid: opts.moduleUuid,\n });\n if (opts.iconSrc && fs.existsSync(opts.iconSrc)) {\n await copyFileAsync(opts.iconSrc, path.join(opts.outDir, \"pack_icon.png\"));\n }\n await writePermissionsJson(opts.outDir);\n return { uuid: bpUuid, version };\n}\n\n/**\n * Merge every enabled module's `resource_pack/**` tree into one RP directory\n * at `outDir`, with a single fresh `manifest.json`. Per-module subfolders are\n * preserved so resource pack authors can disambiguate (e.g. `peace/textures/...`).\n */\nexport async function assembleResourcePack(opts: AssembleResourcePackOpts): Promise<AssembleResult> {\n const version = opts.version ?? [1, 0, 0];\n const rpUuid = opts.uuid ?? randomUuid();\n await fs.promises.rm(opts.outDir, { recursive: true, force: true });\n await fs.promises.mkdir(opts.outDir, { recursive: true });\n for (const [moduleId, rpDir] of Object.entries(opts.moduleResourceDirs)) {\n if (!fs.existsSync(rpDir)) continue;\n const dst = path.join(opts.outDir, moduleId);\n await fs.promises.mkdir(dst, { recursive: true });\n await copyDirAsync(rpDir, dst);\n }\n await writeResourcePackManifest(opts.outDir, {\n name: opts.projectName,\n uuid: rpUuid,\n version,\n description: opts.description,\n moduleUuid: opts.moduleUuid,\n });\n return { uuid: rpUuid, version };\n}\n\n/**\n * Read the `level-name=` value from `<bdsRoot>/server.properties`.\n * Falls back to \"Bedrock level\" (BDS default) when the file is missing or\n * the key is absent.\n */\nfunction parseLevelNameFromProperties(text: string): string {\n for (const line of text.split(/\\r?\\n/)) {\n const m = /^\\s*level-name\\s*=\\s*(.+?)\\s*$/.exec(line);\n if (m && m[1]) return m[1];\n }\n return \"Bedrock level\";\n}\n\n/** \u540C\u6B65\u8BFB level-name\uFF08\u4F9B sfmc resolveBdsContext \u7B49\u540C\u8FDB\u7A0B\u8C03\u7528\u65B9\uFF0CDRY\uFF09\u3002 */\nexport function readLevelNameSync(bdsRoot: string): string {\n const file = serverPropertiesPath(bdsRoot);\n if (!fs.existsSync(file)) return \"Bedrock level\";\n return parseLevelNameFromProperties(fs.readFileSync(file, \"utf8\"));\n}\n\n/** \u4E0E sync \u540C\u5951\u7EA6\uFF1BCLI / async \u8C03\u7528\u65B9\u8D70\u6B64\u5165\u53E3\uFF08LSP\uFF09 */\nexport async function readLevelName(bdsRoot: string): Promise<string> {\n return readLevelNameSync(bdsRoot);\n}\n\n/**\n * Copy BP/RP source dirs into the world's behavior_packs/ + resource_packs/\n * folders, and write a fresh `permissions.json` into the BP target.\n *\n * Does NOT edit world_behavior_packs.json \u2014 that's a separate step the caller\n * must invoke after restart, because BDS only reads that file at startup.\n */\nexport async function deployToBDS(opts: DeployOpts): Promise<DeployResult> {\n /* levelDir = worlds/<level>\uFF1B\u4E0E EnablePackOpts.worldsDir(=worlds/) \u8BED\u4E49\u4E0D\u540C \u2014 \u52FF\u6DF7\u7528\uFF08LSP\uFF09 */\n const levelDir = bdsWorldLevelDir(opts.bdsRoot, opts.levelName);\n const bpDst = path.join(levelDir, \"behavior_packs\", opts.bpName);\n const rpDst = path.join(levelDir, \"resource_packs\", opts.rpName ?? `${opts.bpName}-rp`);\n await fs.promises.mkdir(levelDir, { recursive: true });\n await fs.promises.rm(bpDst, { recursive: true, force: true });\n await copyDirAsync(opts.behaviorPackSrc, bpDst);\n await writePermissionsJson(bpDst);\n let rpDir: string | null = null;\n if (opts.resourcePackSrc && fs.existsSync(opts.resourcePackSrc)) {\n await fs.promises.rm(rpDst, { recursive: true, force: true });\n await copyDirAsync(opts.resourcePackSrc, rpDst);\n rpDir = rpDst;\n } else if (opts.clearResourcePack) {\n /* \u8C03\u7528\u65B9\u663E\u5F0F\u58F0\u660E\u4E0D\u518D\u90E8\u7F72 RP \u2014 \u6E05\u6389\u805A\u5408 RP \u76EE\u5F55\u6B8B\u7559 */\n await fs.promises.rm(rpDst, { recursive: true, force: true });\n }\n return { bpDir: bpDst, rpDir };\n}\n\n/**\n * \u786E\u4FDD BDS Script API \u4FA7 `<bdsRoot>/config/<bpUuid>/permission.json` \u5B58\u5728\u3002\n * \u5DF2\u5B58\u5728\u5219\u8DF3\u8FC7(\u4E0D\u8986\u76D6\u7528\u6237\u624B\u5DE5\u6539\u52A8)\u3002\n * @returns true = \u65B0\u5199\u5165; false = \u5DF2\u5B58\u5728\u8DF3\u8FC7\n */\nexport async function ensureConfigPermission(bdsRoot: string, bpUuid: string): Promise<boolean> {\n const file = configPermissionPath(bdsRoot, bpUuid);\n if (fs.existsSync(file)) return false;\n const dir = path.dirname(file);\n await fs.promises.mkdir(dir, { recursive: true });\n const payload = { allowed_modules: [...SFMC_PERMISSIONS] };\n const tmp = path.join(dir, `.permission.${process.pid}.tmp`);\n await fs.promises.writeFile(tmp, JSON.stringify(payload, null, 2) + \"\\n\", \"utf8\");\n await fs.promises.rename(tmp, file);\n return true;\n}\n\n/** \u4ECE\u5DF2\u88C5\u914D BP/RP \u76EE\u5F55\u8BFB\u53D6 header.uuid + version;\u5931\u8D25\u8FD4\u56DE null\u3002 */\nexport function readPackManifestHeader(\n packDir: string\n): { uuid: string; version: [number, number, number]; moduleUuid?: string } | null {\n const file = path.join(packDir, \"manifest.json\");\n if (!fs.existsSync(file)) return null;\n try {\n const raw = readJsonFile<{\n header?: { uuid?: string; version?: number[] };\n modules?: Array<{ uuid?: string }>;\n }>(file);\n const uuid = raw.header?.uuid;\n const ver = raw.header?.version;\n if (typeof uuid !== \"string\" || !Array.isArray(ver) || ver.length < 3) return null;\n const version: [number, number, number] = [Number(ver[0]), Number(ver[1]), Number(ver[2])];\n const moduleUuid = raw.modules?.[0]?.uuid;\n return { uuid, version, ...(typeof moduleUuid === \"string\" ? { moduleUuid } : {}) };\n } catch {\n return null;\n }\n}\n\n/**\n * Write `@minecraft/*` allowed_modules into a behavior pack's\n * `permissions.json`. Idempotent: rewrites any pre-existing file.\n */\nexport async function writePermissionsJson(bpDir: string): Promise<void> {\n const payload = { allowed_modules: [...SFMC_PERMISSIONS] };\n await fs.promises.mkdir(bpDir, { recursive: true });\n const tmp = path.join(bpDir, `.permissions.${process.pid}.tmp`);\n await fs.promises.writeFile(tmp, JSON.stringify(payload, null, 2) + \"\\n\", \"utf8\");\n await fs.promises.rename(tmp, path.join(bpDir, \"permissions.json\"));\n}\n\n/**\n * Add `{ pack_id, version }` to `worlds/<level>/world_behavior_packs.json`\n * (or `world_resource_packs.json`). If the pack_id already exists, replace its\n * version. File missing \u2192 initialize as `[]`.\n */\nexport async function enablePackInWorld(opts: EnablePackOpts): Promise<void> {\n await editWorldPackList(opts, \"enable\");\n}\n\n/** Remove a pack_id from the world's enable-list JSON. */\nexport async function disablePackInWorld(opts: EnablePackOpts): Promise<void> {\n await editWorldPackList(opts, \"disable\");\n}\n\ninterface WorldPackEntry {\n pack_id: string;\n version: [number, number, number];\n}\n\nasync function editWorldPackList(\n opts: EnablePackOpts,\n mode: \"enable\" | \"disable\"\n): Promise<void> {\n const file = worldPackListFile(opts.worldsDir, opts.levelName, opts.kind);\n /* \u4E0E readWorldPackList \u540C\u6E90\u89E3\u6790,\u518D\u5199\u56DE(DRY);\u5F02\u6B65\u5199\u8DEF\u5F84\u4FDD\u7559\u539F\u8BED\u4E49 */\n let entries: WorldPackEntry[] = readWorldPackList(opts.worldsDir, opts.levelName, opts.kind);\n const idx = entries.findIndex((e) => e.pack_id === opts.packUuid);\n if (mode === \"enable\") {\n const next: WorldPackEntry = { pack_id: opts.packUuid, version: opts.version };\n if (idx >= 0) entries[idx] = next;\n else entries.push(next);\n } else {\n if (idx >= 0) entries.splice(idx, 1);\n }\n await fs.promises.mkdir(path.dirname(file), { recursive: true });\n const tmp = `${file}.${process.pid}.tmp`;\n await fs.promises.writeFile(tmp, JSON.stringify(entries, null, 2) + \"\\n\", \"utf8\");\n await fs.promises.rename(tmp, file);\n}\n\n/* \u2500\u2500 \u4F4E\u5C42 helpers (Commit 5 \u5B9E\u73B0) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\nexport async function writeBehaviorPackManifest(\n outDir: string,\n header: {\n name: string;\n uuid: string;\n version: [number, number, number];\n description?: string | undefined;\n moduleUuid?: string | undefined;\n }\n): Promise<void> {\n const manifest = {\n format_version: 2,\n header: {\n name: header.name,\n uuid: header.uuid,\n version: header.version,\n description: header.description ? `${header.description} (behavior pack)` : \"SFMC behavior pack\",\n min_engine_version: [1, 21, 0],\n },\n modules: [\n {\n type: \"script\",\n language: \"javascript\",\n entry: \"scripts/main.js\",\n uuid: header.moduleUuid ?? crypto.randomUUID(),\n version: header.version,\n },\n ],\n dependencies: [\n { module_name: \"@minecraft/server\", version: \"1.18.0\" },\n { module_name: \"@minecraft/server-admin\", version: \"1.0.0-beta\" },\n { module_name: \"@minecraft/diagnostics\", version: \"1.0.0-beta\" },\n ],\n };\n const file = path.join(outDir, \"manifest.json\");\n await fs.promises.mkdir(outDir, { recursive: true });\n await fs.promises.writeFile(file, JSON.stringify(manifest, null, 2) + \"\\n\", \"utf8\");\n}\n\nexport async function writeResourcePackManifest(\n outDir: string,\n header: {\n name: string;\n uuid: string;\n version: [number, number, number];\n description?: string | undefined;\n moduleUuid?: string | undefined;\n }\n): Promise<void> {\n const manifest = {\n format_version: 2,\n header: {\n name: header.name,\n uuid: header.uuid,\n version: header.version,\n description: header.description ? `${header.description} (resource pack)` : \"SFMC resource pack\",\n min_engine_version: [1, 21, 0],\n },\n modules: [\n {\n type: \"resources\",\n uuid: header.moduleUuid ?? crypto.randomUUID(),\n version: header.version,\n },\n ],\n };\n const file = path.join(outDir, \"manifest.json\");\n await fs.promises.mkdir(outDir, { recursive: true });\n await fs.promises.writeFile(file, JSON.stringify(manifest, null, 2) + \"\\n\", \"utf8\");\n}\n\n/* Re-export copyFileAsync so callers can copy icon without\n * pulling in the full fsx surface area. */\nexport { copyFileAsync, copyDirAsync };\n\n/* \u2500\u2500 Discovery \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/**\n * Walk `<modulesDir>/<id>/resource_pack/` for every installed module and\n * return a map { id: absoluteDir }. Modules without a resource_pack folder\n * are silently skipped. Used by `assemble-rp` and the sfmc CLI to know which\n * modules to merge into the resource pack output.\n */\nexport function scanModuleResourcePacks(modulesDir: string): Record<string, string> {\n const out: Record<string, string> = {};\n if (!fs.existsSync(modulesDir)) return out;\n for (const entry of fs.readdirSync(modulesDir, { withFileTypes: true })) {\n if (entry.name.startsWith(\".\")) continue;\n // \u8DDF\u968F symlink\uFF08--link \u5B89\u88C5\uFF09\uFF1BDirent.isDirectory() \u5BF9\u94FE\u63A5\u76EE\u5F55\u4E3A false\n try {\n if (!fs.statSync(path.join(modulesDir, entry.name)).isDirectory()) continue;\n } catch {\n continue;\n }\n const rpDir = path.join(modulesDir, entry.name, \"resource_pack\");\n if (fs.existsSync(rpDir)) {\n out[entry.name] = rpDir;\n }\n }\n return out;\n}\n\n/**\n * \u4ECE JSON \u6587\u4EF6\u52A0\u8F7D\u663E\u5F0F moduleId \u2192 resource_pack \u76EE\u5F55\u6620\u5C04\u3002\n * \u4F9B assemble-rp --modules-json \u4F7F\u7528,\u907F\u514D\u8C03\u7528\u65B9\u518D\u505A\u4E34\u65F6\u76EE\u5F55\u955C\u50CF(OCP/DRY)\u3002\n */\nexport function loadModuleResourcePackMap(jsonPath: string): Record<string, string> {\n const raw = JSON.parse(fs.readFileSync(jsonPath, \"utf8\")) as unknown;\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) {\n throw new Error(`modules-json must be an object: ${jsonPath}`);\n }\n const out: Record<string, string> = {};\n for (const [id, dir] of Object.entries(raw as Record<string, unknown>)) {\n if (typeof id !== \"string\" || !id || typeof dir !== \"string\" || !dir) continue;\n const abs = path.resolve(dir);\n if (!fs.existsSync(abs)) {\n throw new Error(`modules-json entry missing: ${id} \u2192 ${abs}`);\n }\n out[id] = abs;\n }\n return out;\n}\n\n/**\n * \u8BFB\u53D6\u4E16\u754C enable-list(\u5355\u4E00\u6743\u5A01,\u4F9B has-pack / list-packs / \u8C03\u7528\u65B9\u590D\u7528 \u2014 DRY)\u3002\n * \u6587\u4EF6\u7F3A\u5931 \u2192 entries=[]\uFF1BJSON \u635F\u574F \u2192 entries=[] \u4E14 parseFailedFile \u6709\u503C\uFF08\u4F9B doctor \u533A\u5206\uFF09\u3002\n */\nexport type WorldPackListReadResult = {\n entries: Array<{ pack_id: string; version: [number, number, number] }>;\n /** \u6587\u4EF6\u5B58\u5728\u4F46\u89E3\u6790\u5931\u8D25\u65F6\u4E3A\u8BE5 JSON \u7EDD\u5BF9\u8DEF\u5F84 */\n parseFailedFile?: string;\n};\n\nexport function readWorldPackListResult(\n worldsDir: string,\n levelName: string,\n kind: \"behavior\" | \"resource\"\n): WorldPackListReadResult {\n const file = worldPackListFile(worldsDir, levelName, kind);\n if (!fs.existsSync(file)) return { entries: [] };\n try {\n const arr = JSON.parse(fs.readFileSync(file, \"utf8\")) as unknown;\n if (!Array.isArray(arr)) return { entries: [], parseFailedFile: file };\n const out: Array<{ pack_id: string; version: [number, number, number] }> = [];\n for (const e of arr) {\n if (!e || typeof e !== \"object\") continue;\n const packId = (e as { pack_id?: unknown }).pack_id;\n const ver = (e as { version?: unknown }).version;\n if (typeof packId !== \"string\" || !packId) continue;\n const version: [number, number, number] =\n Array.isArray(ver) && ver.length >= 3\n ? [Number(ver[0]), Number(ver[1]), Number(ver[2])]\n : [1, 0, 0];\n out.push({ pack_id: packId, version });\n }\n return { entries: out };\n } catch {\n return { entries: [], parseFailedFile: file };\n }\n}\n\n/** \u517C\u5BB9\u8BFB\u4FA7\uFF1A\u53EA\u8981 entries\uFF08\u635F\u574F\u65F6\u4E0E\u7F3A\u5931\u540C\u4E3A []\uFF09\u3002\u8BE6\u7EC6\u7ED3\u679C\u89C1 readWorldPackListResult\u3002 */\nexport function readWorldPackList(\n worldsDir: string,\n levelName: string,\n kind: \"behavior\" | \"resource\"\n): Array<{ pack_id: string; version: [number, number, number] }> {\n return readWorldPackListResult(worldsDir, levelName, kind).entries;\n}\n\n/** \u4E16\u754C enable-list \u662F\u5426\u5DF2\u542B\u6307\u5B9A pack_id(\u53EA\u8BFB,\u4F9B preflight \u590D\u7528)\u3002 */\nexport function worldPackListHas(\n worldsDir: string,\n levelName: string,\n kind: \"behavior\" | \"resource\",\n packUuid: string\n): boolean {\n return readWorldPackList(worldsDir, levelName, kind).some((e) => e.pack_id === packUuid);\n}"],
|
|
5
|
-
"mappings": "AAaA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,cAAc,eAAe,oBAAoB;
|
|
4
|
+
"sourcesContent": ["/**\n * pack-manager.ts \u2014 Bedrock \u884C\u4E3A\u5305\uFF08BP\uFF09\u4E0E\u8D44\u6E90\u5305\uFF08RP\uFF09\u7EC4\u88C5\u53CA\u90E8\u7F72\u5F15\u64CE\n *\n * \u6838\u5FC3\u8BBE\u8BA1\u4E0E\u8C03\u7528\u8DEF\u5F84\uFF1A\n * - \u8FDB\u7A0B\u5185\u76F4\u8FDE\uFF08\u63A8\u8350\uFF09\uFF1A`@sfmc-bds/bds-tools/pack-manager-lib` \u4F9B CLI \u7F16\u6392\u4E0E\u751F\u547D\u5468\u671F\u7BA1\u7406\u76F4\u63A5\u8C03\u7528\uFF08\u9075\u5FAA\u4F9D\u8D56\u5012\u7F6E\u539F\u5219\uFF09\n * - \u72EC\u7ACB CLI\uFF1A\u7531 `cli-pack-manager.ts` \u66B4\u9732\u547D\u4EE4\u884C\u5B50\u547D\u4EE4\u4F9B\u811A\u672C\u4E0E\u624B\u5DE5\u8C03\u8BD5\u4F7F\u7528\n *\n * \u6838\u5FC3\u80FD\u529B\uFF1A\n * - \u884C\u4E3A\u5305\u7EC4\u88C5\uFF1A\u5C06 esbuild \u6253\u5305\u540E\u7684 `scripts/main.js`\u3001\u5143\u6570\u636E manifest \u4E0E\u56FE\u6807\u5C01\u88C5\u4E3A BDS \u884C\u4E3A\u5305\u7ED3\u6784\n * - \u8D44\u6E90\u5305\u805A\u5408\uFF1A\u5C06\u5404\u6A21\u5757\u79C1\u6709\u7684 `resource_pack` \u76EE\u5F55\u65E0\u51B2\u7A81\u9012\u5F52\u5408\u5E76\u4E3A\u805A\u5408\u8D44\u6E90\u5305\n * - \u4E16\u754C\u90E8\u7F72\u4E0E\u6E05\u5355\u6FC0\u6D3B\uFF1A\u5C06\u5305\u90E8\u7F72\u81F3 BDS `<level>/behavior_packs` \u4E0E `resource_packs`\uFF0C\u5E76\u540C\u6B65\u7EF4\u62A4 `world_behavior_packs.json`\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { copyDirAsync, copyFileAsync, readJsonFile } from \"./fsx.js\";\nimport {\n BASELINE_BEDROCK_DEPENDENCIES,\n type PackManifestDependency,\n} from \"./dependency-negotiator.js\";\nexport * from \"./dependency-negotiator.js\";\n\n/* \u2500\u2500 \u7C7B\u578B\u5B9A\u4E49 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\nexport interface AssembleBehaviorPackOpts {\n /** \u5DF2\u5B8C\u6210\u6253\u5305\u7684 `scripts/main.js` \u6240\u5728\u6E90\u7801\u76EE\u5F55\uFF08\u5373 esbuild \u8F93\u51FA\u76EE\u5F55\uFF09\u3002 */\n srcDir: string;\n /** \u884C\u4E3A\u5305\u76EE\u6807\u8F93\u51FA\u76EE\u5F55\uFF08\u82E5\u4E0D\u5B58\u5728\u5219\u81EA\u52A8\u521B\u5EFA\uFF09\u3002 */\n outDir: string;\n /** BP \u9879\u76EE/\u76EE\u5F55\u540D\uFF08\u9ED8\u8BA4\u4E3A `'sfmc-modules'`\uFF09\u3002 */\n projectName: string;\n /** `manifest.json` \u4E2D\u7684 `header.version` `[major, minor, patch]`\uFF08\u9ED8\u8BA4\u4E3A `[1, 0, 0]`\uFF09\u3002 */\n version?: [number, number, number] | undefined;\n /** `manifest.json` \u4E2D\u7684\u5305\u63CF\u8FF0\u4FE1\u606F\u3002 */\n description?: string | undefined;\n /** `pack_icon.png` \u56FE\u6807\u6E90\u6587\u4EF6\u8DEF\u5F84\uFF08\u53EF\u9009\uFF0C\u672A\u63D0\u4F9B\u5219\u8DF3\u8FC7\uFF09\u3002 */\n iconSrc?: string | undefined;\n /** \u7A33\u5B9A\u7684 `header.uuid`\uFF08\u7F3A\u7701\u65F6\u5C06\u5728\u9996\u6B21\u88C5\u914D\u65F6\u968F\u673A\u751F\u6210\uFF09\u3002 */\n uuid?: string | undefined;\n /** \u7A33\u5B9A\u7684 `script module uuid`\uFF08\u7F3A\u7701\u65F6\u968F\u673A\u751F\u6210\uFF09\u3002 */\n moduleUuid?: string | undefined;\n /** \u81EA\u5B9A\u4E49/\u52A8\u6001\u534F\u5546\u540E\u7684 dependencies\uFF08\u7F3A\u7701\u4F7F\u7528 BASELINE_BEDROCK_DEPENDENCIES\uFF09\u3002 */\n dependencies?: PackManifestDependency[] | undefined;\n}\n\nexport interface AssembleResourcePackOpts {\n /** \u9700\u5408\u5E76\u8D44\u6E90\u5305\u76EE\u5F55\u7684\u6A21\u5757\u6620\u5C04\u5B57\u5178\uFF08`Record<moduleId, resourcePackDir>`\uFF09\u3002 */\n moduleResourceDirs: Record<string, string>;\n /** \u8D44\u6E90\u5305\u76EE\u6807\u8F93\u51FA\u76EE\u5F55\uFF08\u82E5\u4E0D\u5B58\u5728\u5219\u81EA\u52A8\u521B\u5EFA\uFF09\u3002 */\n outDir: string;\n /** RP \u9879\u76EE/\u76EE\u5F55\u540D\u3002 */\n projectName: string;\n /** `manifest.json` \u4E2D\u7684 `header.version` `[major, minor, patch]`\uFF08\u9ED8\u8BA4\u4E3A `[1, 0, 0]`\uFF09\u3002 */\n version?: [number, number, number] | undefined;\n /** `manifest.json` \u4E2D\u7684\u5305\u63CF\u8FF0\u4FE1\u606F\u3002 */\n description?: string | undefined;\n /** \u7A33\u5B9A\u7684 `header.uuid`\uFF08\u7F3A\u7701\u65F6\u968F\u673A\u751F\u6210\uFF09\u3002 */\n uuid?: string | undefined;\n /** \u7A33\u5B9A\u7684 `resources module uuid`\uFF08\u7F3A\u7701\u65F6\u968F\u673A\u751F\u6210\uFF09\u3002 */\n moduleUuid?: string | undefined;\n}\n\n\nexport interface AssembleResult {\n uuid: string;\n version: [number, number, number];\n}\n\nexport interface DeployOpts {\n bdsRoot: string;\n levelName: string;\n /** \u5DF2\u7EC4\u88C5\u597D\u7684 BP \u6E90\u76EE\u5F55 */\n behaviorPackSrc: string;\n /** \u5DF2\u7EC4\u88C5\u597D\u7684 RP \u6E90\u76EE\u5F55 (\u53EF\u7701\u7565,\u53EA\u7528 BP \u4E5F\u5408\u6CD5) */\n resourcePackSrc?: string;\n /** BP \u76EE\u6807\u76EE\u5F55\u540D (worlds/<level>/behavior_packs/<bpName>) */\n bpName: string;\n /** RP \u76EE\u6807\u76EE\u5F55\u540D (worlds/<level>/resource_packs/<rpName>);\u7701\u7565\u65F6\u590D\u7528 bpName + '-rp' */\n rpName?: string;\n /**\n * \u65E0 resourcePackSrc \u65F6\u662F\u5426\u5220\u9664\u4E16\u754C\u5185\u5DF2\u6709 RP \u76EE\u5F55\u3002\n * \u7528\u4E8E\u6A21\u5757\u4E0D\u518D\u63D0\u4F9B RP \u65F6\u6E05\u7406\u805A\u5408\u5305\u6B8B\u7559(\u9ED8\u8BA4 false,\u907F\u514D\u8BEF\u5220\u672A\u58F0\u660E\u7684 RP)\u3002\n */\n clearResourcePack?: boolean;\n}\n\nexport interface DeployResult {\n bpDir: string;\n rpDir: string | null;\n}\n\nexport interface EnablePackOpts {\n worldsDir: string;\n levelName: string;\n kind: \"behavior\" | \"resource\";\n packUuid: string;\n version: [number, number, number];\n}\n\n/* \u2500\u2500 \u8DEF\u5F84\u5E38\u91CF \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/** SFMC \u5408\u6210 BP \u7684\u56FA\u5B9A @minecraft/* permissions,\u6240\u6709\u7528\u5230\u7684\u547D\u540D\u7A7A\u95F4\u90FD\u6253\u5F00\u3002 */\nexport const SFMC_PERMISSIONS = [\n \"@minecraft/server\",\n \"@minecraft/server-ui\",\n \"@minecraft/server-admin\",\n \"@minecraft/server-gametest\",\n \"@minecraft/server-net\",\n \"@minecraft/server-editor\",\n \"@minecraft/diagnostics\",\n] as const;\n\n/** `<bdsRoot>/server.properties` \u2014 level-name / telemetry \u7B49\u5171\u7528\uFF08DRY\uFF09 */\nexport function serverPropertiesPath(bdsRoot: string): string {\n return path.join(bdsRoot, \"server.properties\");\n}\n\n/** `<bdsRoot>/worlds` \u2014 enable-list / \u90E8\u7F72\u8C03\u7528\u65B9\u52FF\u518D\u786C\u62FC\uFF08Demeter\uFF09 */\nexport function bdsWorldsDir(bdsRoot: string): string {\n return path.join(bdsRoot, \"worlds\");\n}\n\n/** `<bdsRoot>/worlds/<level>` */\nexport function bdsWorldLevelDir(bdsRoot: string, levelName: string): string {\n return path.join(bdsWorldsDir(bdsRoot), levelName);\n}\n\n/** `<bdsRoot>/worlds/<level>/level.dat` \u2014 \u4E16\u754C\u5B58\u6863\u6743\u5A01\u8DEF\u5F84 */\nexport function levelDatPath(bdsRoot: string, levelName: string): string {\n return path.join(bdsWorldLevelDir(bdsRoot, levelName), \"level.dat\");\n}\n\n/** \u4E16\u754C enable-list JSON \u7EDD\u5BF9\u8DEF\u5F84\uFF08\u5355\u4E00\u6743\u5A01\uFF0C\u4F9B\u8BFB\u5199\u4E24\u4FA7\uFF09 */\nexport function worldPackListFile(\n worldsDir: string,\n levelName: string,\n kind: \"behavior\" | \"resource\"\n): string {\n const name = kind === \"behavior\" ? \"world_behavior_packs.json\" : \"world_resource_packs.json\";\n return path.join(worldsDir, levelName, name);\n}\n\n/** `<bdsRoot>/config/<bpUuid>/permission.json` \u2014 Script API \u6743\u9650\u6587\u4EF6\u6743\u5A01\u8DEF\u5F84 */\nexport function configPermissionPath(bdsRoot: string, bpUuid: string): string {\n return path.join(bdsRoot, \"config\", bpUuid, \"permission.json\");\n}\n\n/** `<bdsRoot>/config/<bpUuid>/permissions.json` \u2014 BDS \u5B98\u65B9\u89C4\u8303\u590D\u6570\u6743\u9650\u6587\u4EF6\u8DEF\u5F84 */\nexport function configPermissionsPath(bdsRoot: string, bpUuid: string): string {\n return path.join(bdsRoot, \"config\", bpUuid, \"permissions.json\");\n}\n\n/** \u662F\u5426\u5DF2\u6709 Script API permission.json \u6216 permissions.json\uFF08\u53EA\u8BFB\uFF0C\u4F9B preflight/status\uFF09 */\nexport function hasConfigPermission(bdsRoot: string, bpUuid: string): boolean {\n return fs.existsSync(configPermissionsPath(bdsRoot, bpUuid)) || fs.existsSync(configPermissionPath(bdsRoot, bpUuid));\n}\n\n/** \u968F\u673A\u751F\u6210 BP/RP manifest.json header.uuid (RFC 4122 v4) */\nexport function randomUuid(): string {\n /* crypto.randomUUID \u662F Node 19+ \u5185\u7F6E,\u8FD9\u91CC\u76F4\u63A5\u7528 */\n return crypto.randomUUID();\n}\n\n/* \u2500\u2500 \u9AA8\u67B6\u51FD\u6570 (Commit 5 \u5B9E\u73B0) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/**\n * Assemble a Bedrock behavior pack directory at `outDir` from a prebuilt\n * `srcDir` (which must already contain `scripts/main.js` plus whatever else\n * was bundled by esbuild) and write a fresh `manifest.json` + `permissions.json`.\n *\n * The caller is responsible for running esbuild first; pack-manager does not\n * bundle scripts. That decoupling keeps pack assembly independent of the bundler.\n */\nexport async function assembleBehaviorPack(opts: AssembleBehaviorPackOpts): Promise<AssembleResult> {\n const version = opts.version ?? [1, 0, 0];\n const bpUuid = opts.uuid ?? randomUuid();\n await fs.promises.rm(opts.outDir, { recursive: true, force: true });\n await fs.promises.mkdir(opts.outDir, { recursive: true });\n if (fs.existsSync(opts.srcDir)) {\n await copyDirAsync(opts.srcDir, opts.outDir);\n } else {\n await fs.promises.mkdir(path.join(opts.outDir, \"scripts\"), { recursive: true });\n await fs.promises.writeFile(path.join(opts.outDir, \"scripts\", \"main.js\"), \"/* no scripts */\\n\", \"utf8\");\n }\n await writeBehaviorPackManifest(\n opts.outDir,\n {\n name: opts.projectName,\n uuid: bpUuid,\n version,\n description: opts.description,\n moduleUuid: opts.moduleUuid,\n },\n opts.dependencies\n );\n if (opts.iconSrc && fs.existsSync(opts.iconSrc)) {\n await copyFileAsync(opts.iconSrc, path.join(opts.outDir, \"pack_icon.png\"));\n }\n await writePermissionsJson(opts.outDir);\n return { uuid: bpUuid, version };\n}\n\n/**\n * Merge every enabled module's `resource_pack/**` tree into one RP directory\n * at `outDir`, with a single fresh `manifest.json`. Per-module subfolders are\n * preserved so resource pack authors can disambiguate (e.g. `peace/textures/...`).\n */\nexport async function assembleResourcePack(opts: AssembleResourcePackOpts): Promise<AssembleResult> {\n const version = opts.version ?? [1, 0, 0];\n const rpUuid = opts.uuid ?? randomUuid();\n await fs.promises.rm(opts.outDir, { recursive: true, force: true });\n await fs.promises.mkdir(opts.outDir, { recursive: true });\n for (const [moduleId, rpDir] of Object.entries(opts.moduleResourceDirs)) {\n if (!fs.existsSync(rpDir)) continue;\n const dst = path.join(opts.outDir, moduleId);\n await fs.promises.mkdir(dst, { recursive: true });\n await copyDirAsync(rpDir, dst);\n }\n await writeResourcePackManifest(opts.outDir, {\n name: opts.projectName,\n uuid: rpUuid,\n version,\n description: opts.description,\n moduleUuid: opts.moduleUuid,\n });\n return { uuid: rpUuid, version };\n}\n\n/**\n * Read the `level-name=` value from `<bdsRoot>/server.properties`.\n * Falls back to \"Bedrock level\" (BDS default) when the file is missing or\n * the key is absent.\n */\nfunction parseLevelNameFromProperties(text: string): string {\n for (const line of text.split(/\\r?\\n/)) {\n const m = /^\\s*level-name\\s*=\\s*(.+?)\\s*$/.exec(line);\n if (m && m[1]) return m[1];\n }\n return \"Bedrock level\";\n}\n\n/** \u540C\u6B65\u8BFB level-name\uFF08\u4F9B sfmc resolveBdsContext \u7B49\u540C\u8FDB\u7A0B\u8C03\u7528\u65B9\uFF0CDRY\uFF09\u3002 */\nexport function readLevelNameSync(bdsRoot: string): string {\n const file = serverPropertiesPath(bdsRoot);\n if (!fs.existsSync(file)) return \"Bedrock level\";\n return parseLevelNameFromProperties(fs.readFileSync(file, \"utf8\"));\n}\n\n/** \u4E0E sync \u540C\u5951\u7EA6\uFF1BCLI / async \u8C03\u7528\u65B9\u8D70\u6B64\u5165\u53E3\uFF08LSP\uFF09 */\nexport async function readLevelName(bdsRoot: string): Promise<string> {\n return readLevelNameSync(bdsRoot);\n}\n\n/**\n * Copy BP/RP source dirs into the world's behavior_packs/ + resource_packs/\n * folders, and write a fresh `permissions.json` into the BP target.\n *\n * Does NOT edit world_behavior_packs.json \u2014 that's a separate step the caller\n * must invoke after restart, because BDS only reads that file at startup.\n */\nexport async function deployToBDS(opts: DeployOpts): Promise<DeployResult> {\n /* levelDir = worlds/<level>\uFF1B\u4E0E EnablePackOpts.worldsDir(=worlds/) \u8BED\u4E49\u4E0D\u540C \u2014 \u52FF\u6DF7\u7528\uFF08LSP\uFF09 */\n const levelDir = bdsWorldLevelDir(opts.bdsRoot, opts.levelName);\n const bpDst = path.join(levelDir, \"behavior_packs\", opts.bpName);\n const rpDst = path.join(levelDir, \"resource_packs\", opts.rpName ?? `${opts.bpName}-rp`);\n await fs.promises.mkdir(levelDir, { recursive: true });\n await fs.promises.rm(bpDst, { recursive: true, force: true });\n await copyDirAsync(opts.behaviorPackSrc, bpDst);\n await writePermissionsJson(bpDst);\n let rpDir: string | null = null;\n if (opts.resourcePackSrc && fs.existsSync(opts.resourcePackSrc)) {\n await fs.promises.rm(rpDst, { recursive: true, force: true });\n await copyDirAsync(opts.resourcePackSrc, rpDst);\n rpDir = rpDst;\n } else if (opts.clearResourcePack) {\n /* \u8C03\u7528\u65B9\u663E\u5F0F\u58F0\u660E\u4E0D\u518D\u90E8\u7F72 RP \u2014 \u6E05\u6389\u805A\u5408 RP \u76EE\u5F55\u6B8B\u7559 */\n await fs.promises.rm(rpDst, { recursive: true, force: true });\n }\n return { bpDir: bpDst, rpDir };\n}\n\n/**\n * \u786E\u4FDD BDS Script API \u4FA7\u6743\u9650\u6587\u4EF6\u5B58\u5728\u5E76\u5305\u542B\u5B8C\u6574\u7684 SFMC \u6240\u9700\u6A21\u5757\u6743\u9650\u3002\n * - \u81EA\u52A8\u589E\u91CF\u5408\u5E76\u73B0\u6709 allowed_modules\uFF0C\u81EA\u52A8\u8865\u9F50\u65B0\u589E\u6743\u9650\uFF08\u5982 @minecraft/diagnostics\uFF09\n * - \u540C\u65F6\u7EF4\u62A4 BDS \u5B98\u65B9\u89C4\u8303\u7684 permissions.json \u4E0E\u5386\u53F2\u517C\u5BB9\u7684 permission.json\n * - \u540C\u65F6\u66F4\u65B0 moduleUuid\uFF08\u82E5\u63D0\u4F9B\uFF09\u4E0E config/default/permissions.json \u515C\u5E95\u6743\u9650\n * @returns true = \u6709\u65B0\u589E/\u66F4\u65B0; false = \u5DF2\u662F\u6700\u65B0\u65E0\u9700\u4FEE\u6539\n */\nexport async function ensureConfigPermission(\n bdsRoot: string,\n bpUuid: string,\n moduleUuid?: string\n): Promise<boolean> {\n let changed = false;\n\n const updateFile = async (filePath: string): Promise<boolean> => {\n let currentModules: string[] = [];\n let restConfig: Record<string, unknown> = {};\n if (fs.existsSync(filePath)) {\n try {\n const raw = readJsonFile<{ allowed_modules?: string[]; [k: string]: unknown }>(filePath);\n if (Array.isArray(raw.allowed_modules)) {\n currentModules = raw.allowed_modules;\n }\n const { allowed_modules: _, ...rest } = raw;\n restConfig = rest;\n } catch {\n // \u6587\u4EF6\u635F\u574F\u5219\u6309\u5168\u65B0\u5199\u5165\n }\n }\n const merged = Array.from(new Set([...currentModules, ...SFMC_PERMISSIONS]));\n if (merged.length === currentModules.length && fs.existsSync(filePath)) {\n return false;\n }\n const dir = path.dirname(filePath);\n await fs.promises.mkdir(dir, { recursive: true });\n const payload = { allowed_modules: merged, ...restConfig };\n const tmp = path.join(dir, `.permission.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`);\n await fs.promises.writeFile(tmp, JSON.stringify(payload, null, 2) + \"\\n\", \"utf8\");\n await fs.promises.rename(tmp, filePath);\n return true;\n };\n\n const uuids = Array.from(new Set([bpUuid, ...(moduleUuid ? [moduleUuid] : [])]));\n for (const u of uuids) {\n if (await updateFile(configPermissionsPath(bdsRoot, u))) changed = true;\n if (await updateFile(configPermissionPath(bdsRoot, u))) changed = true;\n }\n\n const defaultFile = path.join(bdsRoot, \"config\", \"default\", \"permissions.json\");\n if (await updateFile(defaultFile)) changed = true;\n\n return changed;\n}\n\n/** \u4ECE\u5DF2\u88C5\u914D BP/RP \u76EE\u5F55\u8BFB\u53D6 header.uuid + version;\u5931\u8D25\u8FD4\u56DE null\u3002 */\nexport function readPackManifestHeader(\n packDir: string\n): { uuid: string; version: [number, number, number]; moduleUuid?: string } | null {\n const file = path.join(packDir, \"manifest.json\");\n if (!fs.existsSync(file)) return null;\n try {\n const raw = readJsonFile<{\n header?: { uuid?: string; version?: number[] };\n modules?: Array<{ uuid?: string }>;\n }>(file);\n const uuid = raw.header?.uuid;\n const ver = raw.header?.version;\n if (typeof uuid !== \"string\" || !Array.isArray(ver) || ver.length < 3) return null;\n const version: [number, number, number] = [Number(ver[0]), Number(ver[1]), Number(ver[2])];\n const moduleUuid = raw.modules?.[0]?.uuid;\n return { uuid, version, ...(typeof moduleUuid === \"string\" ? { moduleUuid } : {}) };\n } catch {\n return null;\n }\n}\n\n\n/** \u4ECE\u5DF2\u88C5\u914D BP/RP \u76EE\u5F55\u8BFB\u53D6 dependencies \u5217\u8868\uFF1B\u82E5\u65E0\u6216\u5931\u8D25\u8FD4\u56DE []\u3002 */\nexport function readPackManifestDependencies(packDir: string): PackManifestDependency[] {\n const file = path.join(packDir, \"manifest.json\");\n if (!fs.existsSync(file)) return [];\n try {\n const raw = readJsonFile<{ dependencies?: PackManifestDependency[] }>(file);\n return Array.isArray(raw.dependencies) ? raw.dependencies : [];\n } catch {\n return [];\n }\n}\n\n/**\n * Write `@minecraft/*` allowed_modules into a behavior pack's\n * `permissions.json`. Idempotent: rewrites any pre-existing file.\n */\nexport async function writePermissionsJson(bpDir: string): Promise<void> {\n const payload = { allowed_modules: [...SFMC_PERMISSIONS] };\n await fs.promises.mkdir(bpDir, { recursive: true });\n const tmp = path.join(bpDir, `.permissions.${process.pid}.tmp`);\n await fs.promises.writeFile(tmp, JSON.stringify(payload, null, 2) + \"\\n\", \"utf8\");\n await fs.promises.rename(tmp, path.join(bpDir, \"permissions.json\"));\n}\n\n/**\n * Add `{ pack_id, version }` to `worlds/<level>/world_behavior_packs.json`\n * (or `world_resource_packs.json`). If the pack_id already exists, replace its\n * version. File missing \u2192 initialize as `[]`.\n */\nexport async function enablePackInWorld(opts: EnablePackOpts): Promise<void> {\n await editWorldPackList(opts, \"enable\");\n}\n\n/** Remove a pack_id from the world's enable-list JSON. */\nexport async function disablePackInWorld(opts: EnablePackOpts): Promise<void> {\n await editWorldPackList(opts, \"disable\");\n}\n\ninterface WorldPackEntry {\n pack_id: string;\n version: [number, number, number];\n}\n\nasync function editWorldPackList(\n opts: EnablePackOpts,\n mode: \"enable\" | \"disable\"\n): Promise<void> {\n const file = worldPackListFile(opts.worldsDir, opts.levelName, opts.kind);\n /* \u4E0E readWorldPackList \u540C\u6E90\u89E3\u6790,\u518D\u5199\u56DE(DRY);\u5F02\u6B65\u5199\u8DEF\u5F84\u4FDD\u7559\u539F\u8BED\u4E49 */\n let entries: WorldPackEntry[] = readWorldPackList(opts.worldsDir, opts.levelName, opts.kind);\n const idx = entries.findIndex((e) => e.pack_id === opts.packUuid);\n if (mode === \"enable\") {\n const next: WorldPackEntry = { pack_id: opts.packUuid, version: opts.version };\n if (idx >= 0) entries[idx] = next;\n else entries.push(next);\n } else {\n if (idx >= 0) entries.splice(idx, 1);\n }\n await fs.promises.mkdir(path.dirname(file), { recursive: true });\n const tmp = `${file}.${process.pid}.tmp`;\n await fs.promises.writeFile(tmp, JSON.stringify(entries, null, 2) + \"\\n\", \"utf8\");\n await fs.promises.rename(tmp, file);\n}\n\n/* \u2500\u2500 \u4F4E\u5C42 helpers (Commit 5 \u5B9E\u73B0) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\nexport async function writeBehaviorPackManifest(\n outDir: string,\n header: {\n name: string;\n uuid: string;\n version: [number, number, number];\n description?: string | undefined;\n moduleUuid?: string | undefined;\n },\n dependencies?: PackManifestDependency[] | undefined\n): Promise<void> {\n const manifest = {\n format_version: 2,\n header: {\n name: header.name,\n uuid: header.uuid,\n version: header.version,\n description: header.description ? `${header.description} (behavior pack)` : \"SFMC behavior pack\",\n min_engine_version: [1, 21, 0],\n },\n modules: [\n {\n type: \"script\",\n language: \"javascript\",\n entry: \"scripts/main.js\",\n uuid: header.moduleUuid ?? crypto.randomUUID(),\n version: header.version,\n },\n ],\n dependencies:\n dependencies && dependencies.length > 0 ? dependencies : BASELINE_BEDROCK_DEPENDENCIES,\n };\n const file = path.join(outDir, \"manifest.json\");\n await fs.promises.mkdir(outDir, { recursive: true });\n await fs.promises.writeFile(file, JSON.stringify(manifest, null, 2) + \"\\n\", \"utf8\");\n}\n\nexport async function writeResourcePackManifest(\n outDir: string,\n header: {\n name: string;\n uuid: string;\n version: [number, number, number];\n description?: string | undefined;\n moduleUuid?: string | undefined;\n }\n): Promise<void> {\n const manifest = {\n format_version: 2,\n header: {\n name: header.name,\n uuid: header.uuid,\n version: header.version,\n description: header.description ? `${header.description} (resource pack)` : \"SFMC resource pack\",\n min_engine_version: [1, 21, 0],\n },\n modules: [\n {\n type: \"resources\",\n uuid: header.moduleUuid ?? crypto.randomUUID(),\n version: header.version,\n },\n ],\n };\n const file = path.join(outDir, \"manifest.json\");\n await fs.promises.mkdir(outDir, { recursive: true });\n await fs.promises.writeFile(file, JSON.stringify(manifest, null, 2) + \"\\n\", \"utf8\");\n}\n\n/* Re-export copyFileAsync so callers can copy icon without\n * pulling in the full fsx surface area. */\nexport { copyFileAsync, copyDirAsync };\n\n/* \u2500\u2500 Discovery \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/**\n * Walk `<modulesDir>/<id>/resource_pack/` for every installed module and\n * return a map { id: absoluteDir }. Modules without a resource_pack folder\n * are silently skipped. Used by `assemble-rp` and the sfmc CLI to know which\n * modules to merge into the resource pack output.\n */\nexport function scanModuleResourcePacks(modulesDir: string): Record<string, string> {\n const out: Record<string, string> = {};\n if (!fs.existsSync(modulesDir)) return out;\n for (const entry of fs.readdirSync(modulesDir, { withFileTypes: true })) {\n if (entry.name.startsWith(\".\")) continue;\n // \u8DDF\u968F symlink\uFF08--link \u5B89\u88C5\uFF09\uFF1BDirent.isDirectory() \u5BF9\u94FE\u63A5\u76EE\u5F55\u4E3A false\n try {\n if (!fs.statSync(path.join(modulesDir, entry.name)).isDirectory()) continue;\n } catch {\n continue;\n }\n const rpDir = path.join(modulesDir, entry.name, \"resource_pack\");\n if (fs.existsSync(rpDir)) {\n out[entry.name] = rpDir;\n }\n }\n return out;\n}\n\n/**\n * \u4ECE JSON \u6587\u4EF6\u52A0\u8F7D\u663E\u5F0F moduleId \u2192 resource_pack \u76EE\u5F55\u6620\u5C04\u3002\n * \u4F9B assemble-rp --modules-json \u4F7F\u7528,\u907F\u514D\u8C03\u7528\u65B9\u518D\u505A\u4E34\u65F6\u76EE\u5F55\u955C\u50CF(OCP/DRY)\u3002\n */\nexport function loadModuleResourcePackMap(jsonPath: string): Record<string, string> {\n const raw = JSON.parse(fs.readFileSync(jsonPath, \"utf8\")) as unknown;\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) {\n throw new Error(`modules-json must be an object: ${jsonPath}`);\n }\n const out: Record<string, string> = {};\n for (const [id, dir] of Object.entries(raw as Record<string, unknown>)) {\n if (typeof id !== \"string\" || !id || typeof dir !== \"string\" || !dir) continue;\n const abs = path.resolve(dir);\n if (!fs.existsSync(abs)) {\n throw new Error(`modules-json entry missing: ${id} \u2192 ${abs}`);\n }\n out[id] = abs;\n }\n return out;\n}\n\n/**\n * \u8BFB\u53D6\u4E16\u754C enable-list(\u5355\u4E00\u6743\u5A01,\u4F9B has-pack / list-packs / \u8C03\u7528\u65B9\u590D\u7528 \u2014 DRY)\u3002\n * \u6587\u4EF6\u7F3A\u5931 \u2192 entries=[]\uFF1BJSON \u635F\u574F \u2192 entries=[] \u4E14 parseFailedFile \u6709\u503C\uFF08\u4F9B doctor \u533A\u5206\uFF09\u3002\n */\nexport type WorldPackListReadResult = {\n entries: Array<{ pack_id: string; version: [number, number, number] }>;\n /** \u6587\u4EF6\u5B58\u5728\u4F46\u89E3\u6790\u5931\u8D25\u65F6\u4E3A\u8BE5 JSON \u7EDD\u5BF9\u8DEF\u5F84 */\n parseFailedFile?: string;\n};\n\nexport function readWorldPackListResult(\n worldsDir: string,\n levelName: string,\n kind: \"behavior\" | \"resource\"\n): WorldPackListReadResult {\n const file = worldPackListFile(worldsDir, levelName, kind);\n if (!fs.existsSync(file)) return { entries: [] };\n try {\n const arr = JSON.parse(fs.readFileSync(file, \"utf8\")) as unknown;\n if (!Array.isArray(arr)) return { entries: [], parseFailedFile: file };\n const out: Array<{ pack_id: string; version: [number, number, number] }> = [];\n for (const e of arr) {\n if (!e || typeof e !== \"object\") continue;\n const packId = (e as { pack_id?: unknown }).pack_id;\n const ver = (e as { version?: unknown }).version;\n if (typeof packId !== \"string\" || !packId) continue;\n const version: [number, number, number] =\n Array.isArray(ver) && ver.length >= 3\n ? [Number(ver[0]), Number(ver[1]), Number(ver[2])]\n : [1, 0, 0];\n out.push({ pack_id: packId, version });\n }\n return { entries: out };\n } catch {\n return { entries: [], parseFailedFile: file };\n }\n}\n\n/** \u517C\u5BB9\u8BFB\u4FA7\uFF1A\u53EA\u8981 entries\uFF08\u635F\u574F\u65F6\u4E0E\u7F3A\u5931\u540C\u4E3A []\uFF09\u3002\u8BE6\u7EC6\u7ED3\u679C\u89C1 readWorldPackListResult\u3002 */\nexport function readWorldPackList(\n worldsDir: string,\n levelName: string,\n kind: \"behavior\" | \"resource\"\n): Array<{ pack_id: string; version: [number, number, number] }> {\n return readWorldPackListResult(worldsDir, levelName, kind).entries;\n}\n\n/** \u4E16\u754C enable-list \u662F\u5426\u5DF2\u542B\u6307\u5B9A pack_id(\u53EA\u8BFB,\u4F9B preflight \u590D\u7528)\u3002 */\nexport function worldPackListHas(\n worldsDir: string,\n levelName: string,\n kind: \"behavior\" | \"resource\",\n packUuid: string\n): boolean {\n return readWorldPackList(worldsDir, levelName, kind).some((e) => e.pack_id === packUuid);\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* server-properties-i18n.ts — BDS server.properties 多语言注释字典
|
|
3
|
+
*/
|
|
4
|
+
export interface ServerPropertyDoc {
|
|
5
|
+
/** 中文功能概述 */
|
|
6
|
+
desc: string;
|
|
7
|
+
/** 合法取值与枚举说明 */
|
|
8
|
+
values?: string;
|
|
9
|
+
/** 避坑、性能或安全性提示 */
|
|
10
|
+
tip?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const SERVER_PROPERTIES_DOCS_ZH_CN: Record<string, ServerPropertyDoc>;
|
|
13
|
+
/**
|
|
14
|
+
* 根据属性 key 和目标语言获取说明文档
|
|
15
|
+
*/
|
|
16
|
+
export declare function getServerPropertyDoc(key: string, locale?: string): ServerPropertyDoc | undefined;
|
|
17
|
+
//# sourceMappingURL=server-properties-i18n.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-properties-i18n.d.ts","sourceRoot":"","sources":["../src/server-properties-i18n.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,iBAAiB;IAChC,aAAa;IACb,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,4BAA4B,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAuL1E,CAAC;AAEF;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAgB,GAAG,iBAAiB,GAAG,SAAS,CAQzG"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
const SERVER_PROPERTIES_DOCS_ZH_CN = {
|
|
2
|
+
"server-name": {
|
|
3
|
+
desc: "\u670D\u52A1\u5668\u540D\u79F0\uFF08\u663E\u793A\u5728\u5BA2\u6237\u7AEF\u5C40\u57DF\u7F51/\u597D\u53CB\u5217\u8868\u4E2D\uFF09",
|
|
4
|
+
values: "\u4EFB\u610F\u5B57\u7B26\u4E32\uFF08\u8BF7\u52FF\u5305\u542B\u5206\u53F7 ;\uFF09"
|
|
5
|
+
},
|
|
6
|
+
"gamemode": {
|
|
7
|
+
desc: "\u65B0\u73A9\u5BB6\u9996\u6B21\u52A0\u5165\u4E16\u754C\u65F6\u7684\u9ED8\u8BA4\u6E38\u620F\u6A21\u5F0F",
|
|
8
|
+
values: "survival (\u751F\u5B58) | creative (\u521B\u9020) | adventure (\u5192\u9669)"
|
|
9
|
+
},
|
|
10
|
+
"force-gamemode": {
|
|
11
|
+
desc: "\u662F\u5426\u5F3A\u5236\u73A9\u5BB6\u6BCF\u6B21\u91CD\u65B0\u8FDE\u63A5\u65F6\u90FD\u91CD\u7F6E\u4E3A\u9ED8\u8BA4\u6E38\u620F\u6A21\u5F0F",
|
|
12
|
+
values: "true (\u6BCF\u6B21\u8FDB\u670D\u5F3A\u5236\u8F6C\u4E3A\u9ED8\u8BA4\u6A21\u5F0F) | false (\u4FDD\u7559\u73A9\u5BB6\u4E0A\u6B21\u79BB\u7EBF\u65F6\u7684\u6A21\u5F0F)"
|
|
13
|
+
},
|
|
14
|
+
"difficulty": {
|
|
15
|
+
desc: "\u6E38\u620F\u4E16\u754C\u7684\u9ED8\u8BA4\u96BE\u5EA6",
|
|
16
|
+
values: "peaceful (\u548C\u5E73) | easy (\u7B80\u5355) | normal (\u666E\u901A) | hard (\u56F0\u96BE)"
|
|
17
|
+
},
|
|
18
|
+
"allow-cheats": {
|
|
19
|
+
desc: "\u662F\u5426\u5141\u8BB8\u5728\u63A7\u5236\u53F0\u6216\u6E38\u620F\u5185\u4F7F\u7528\u7BA1\u7406\u5458\u6307\u4EE4\uFF08\u4F5C\u5F0A\u6A21\u5F0F\uFF09",
|
|
20
|
+
values: "true | false",
|
|
21
|
+
tip: "\u82E5\u5F00\u542F\u6B64\u9879\uFF0C\u52A0\u5165\u8BE5\u4E16\u754C\u7684\u73A9\u5BB6\u5C06\u65E0\u6CD5\u83B7\u5F97 Xbox \u6210\u5C31"
|
|
22
|
+
},
|
|
23
|
+
"max-players": {
|
|
24
|
+
desc: "\u5141\u8BB8\u540C\u65F6\u5728\u7EBF\u7684\u6700\u5927\u73A9\u5BB6\u6570\u91CF\u9650\u5236",
|
|
25
|
+
values: "\u6B63\u6574\u6570\uFF08\u5982 10\u300120\uFF09"
|
|
26
|
+
},
|
|
27
|
+
"online-mode": {
|
|
28
|
+
desc: "\u662F\u5426\u5F00\u542F\u5FAE\u8F6F Xbox Live \u6B63\u7248\u8EAB\u4EFD\u9A8C\u8BC1",
|
|
29
|
+
values: "true (\u4EC5\u5141\u8BB8\u6B63\u7248\u5FAE\u8F6F\u8D26\u53F7\u767B\u5F55) | false (\u5141\u8BB8\u79BB\u7EBF\u514D\u767B\u5F55\u8FDE\u63A5\uFF0C\u4F46\u6613\u53D7\u5047\u4EBA\u653B\u51FB)",
|
|
30
|
+
tip: "\u516C\u7F51\u670D\u52A1\u5668\u5F3A\u70C8\u5EFA\u8BAE\u8BBE\u4E3A true \u4EE5\u9632\u6B62\u6076\u610F\u4F2A\u9020\u8EAB\u4EFD"
|
|
31
|
+
},
|
|
32
|
+
"white-list": {
|
|
33
|
+
desc: "\u662F\u5426\u5F00\u542F\u51C6\u5165\u767D\u540D\u5355\u9A8C\u8BC1\uFF08\u90E8\u5206\u7248\u672C\u5BF9\u5E94 allow-list\uFF09",
|
|
34
|
+
values: "true (\u4EC5\u5141\u8BB8\u767D\u540D\u5355\u4E2D\u7684\u73A9\u5BB6\u8FDB\u5165) | false (\u6240\u6709\u73A9\u5BB6\u5747\u53EF\u8FDB\u5165)"
|
|
35
|
+
},
|
|
36
|
+
"allow-list": {
|
|
37
|
+
desc: "\u662F\u5426\u5F00\u542F\u51C6\u5165\u767D\u540D\u5355\u9A8C\u8BC1\uFF08\u9700\u914D\u5408 allowlist.json \u4F7F\u7528\uFF09",
|
|
38
|
+
values: "true (\u4EC5\u5141\u8BB8\u767D\u540D\u5355\u4E2D\u7684\u73A9\u5BB6\u8FDB\u5165) | false (\u6240\u6709\u73A9\u5BB6\u5747\u53EF\u8FDB\u5165)"
|
|
39
|
+
},
|
|
40
|
+
"server-port": {
|
|
41
|
+
desc: "\u670D\u52A1\u7AEF\u76D1\u542C\u7684 IPv4 UDP \u7F51\u7EDC\u901A\u4FE1\u7AEF\u53E3",
|
|
42
|
+
values: "1 ~ 65535\uFF08\u9ED8\u8BA4\uFF1A19132\uFF09"
|
|
43
|
+
},
|
|
44
|
+
"server-portv6": {
|
|
45
|
+
desc: "\u670D\u52A1\u7AEF\u76D1\u542C\u7684 IPv6 UDP \u7F51\u7EDC\u901A\u4FE1\u7AEF\u53E3",
|
|
46
|
+
values: "1 ~ 65535\uFF08\u9ED8\u8BA4\uFF1A19133\uFF09"
|
|
47
|
+
},
|
|
48
|
+
"enable-lan-visibility": {
|
|
49
|
+
desc: "\u662F\u5426\u5411\u5C40\u57DF\u7F51\u5E7F\u64AD\u672C\u670D\u52A1\u5668\uFF08\u4F7F\u540C\u5C40\u57DF\u7F51\u73A9\u5BB6\u80FD\u5728\u5BA2\u6237\u7AEF\u300C\u597D\u53CB\u300D\u5217\u8868\u4E2D\u76F4\u63A5\u53D1\u73B0\uFF09",
|
|
50
|
+
values: "true | false"
|
|
51
|
+
},
|
|
52
|
+
"view-distance": {
|
|
53
|
+
desc: "\u670D\u52A1\u7AEF\u5411\u5BA2\u6237\u7AEF\u53D1\u9001\u5730\u56FE\u533A\u5757\u7684\u6700\u5927\u89C6\u8DDD\uFF08\u5355\u4F4D\uFF1A\u533A\u5757\uFF09",
|
|
54
|
+
values: "\u6B63\u6574\u6570\uFF08\u5EFA\u8BAE 12 ~ 32\uFF0C\u6570\u503C\u8D8A\u5927\u7F51\u7EDC\u4E0E\u5185\u5B58\u6D88\u8017\u8D8A\u9AD8\uFF09"
|
|
55
|
+
},
|
|
56
|
+
"tick-distance": {
|
|
57
|
+
desc: "\u4E16\u754C\u5B9E\u4F53\u903B\u8F91\u4E0E\u65B9\u5757\u66F4\u65B0\u7684\u6A21\u62DF\u8BA1\u7B97\u8DDD\u79BB\uFF08\u5355\u4F4D\uFF1A\u533A\u5757\uFF09",
|
|
58
|
+
values: "4 ~ 12\uFF08\u6570\u503C\u8D8A\u5C0F\u670D\u52A1\u5668\u6027\u80FD\u8D8A\u597D\uFF0C\u4F4E\u914D\u673A\u578B\u63A8\u8350 4\uFF09"
|
|
59
|
+
},
|
|
60
|
+
"player-idle-timeout": {
|
|
61
|
+
desc: "\u73A9\u5BB6\u6302\u673A\u65E0\u64CD\u4F5C\u81EA\u52A8\u8E22\u51FA\u8D85\u65F6\u65F6\u95F4\uFF08\u5355\u4F4D\uFF1A\u5206\u949F\uFF09",
|
|
62
|
+
values: "0 (\u6C38\u4E0D\u8E22\u51FA) \u6216\u5927\u4E8E 0 \u7684\u6574\u6570"
|
|
63
|
+
},
|
|
64
|
+
"max-threads": {
|
|
65
|
+
desc: "BDS \u8FD0\u884C\u53EF\u4F7F\u7528\u7684\u6700\u5927\u5DE5\u4F5C\u7EBF\u7A0B\u6570",
|
|
66
|
+
values: "0 (\u7531\u670D\u52A1\u7AEF\u6839\u636E CPU \u6838\u5FC3\u6570\u81EA\u52A8\u5206\u914D) \u6216\u6307\u5B9A\u7EBF\u7A0B\u6570"
|
|
67
|
+
},
|
|
68
|
+
"level-name": {
|
|
69
|
+
desc: "\u8981\u52A0\u8F7D\u7684\u4E16\u754C\u5B58\u6863\u6587\u4EF6\u5939\u540D\u79F0\uFF08\u5BF9\u5E94 worlds/ \u76EE\u5F55\u4E0B\u7684\u5B50\u6587\u4EF6\u5939\uFF09",
|
|
70
|
+
values: "\u6587\u4EF6\u5939\u540D\u79F0\uFF08\u9ED8\u8BA4\uFF1ABedrock level\uFF09"
|
|
71
|
+
},
|
|
72
|
+
"level-seed": {
|
|
73
|
+
desc: "\u5168\u65B0\u4E16\u754C\u751F\u6210\u65F6\u7684\u968F\u673A\u79CD\u5B50",
|
|
74
|
+
values: "\u4EFB\u610F\u6570\u5B57\u6216\u6587\u672C\uFF08\u7559\u7A7A\u5219\u6BCF\u6B21\u65B0\u5EFA\u4E16\u754C\u968F\u673A\u751F\u6210\uFF09"
|
|
75
|
+
},
|
|
76
|
+
"default-player-permission-level": {
|
|
77
|
+
desc: "\u65B0\u73A9\u5BB6\u9996\u6B21\u52A0\u5165\u65F6\u7684\u9ED8\u8BA4\u6743\u9650\u7EA7\u522B",
|
|
78
|
+
values: "visitor (\u8BBF\u5BA2\uFF0C\u4E0D\u53EF\u7834\u574F\u6216\u4EA4\u4E92) | member (\u666E\u901A\u6210\u5458) | operator (\u64CD\u4F5C\u5458)"
|
|
79
|
+
},
|
|
80
|
+
"texturepack-required": {
|
|
81
|
+
desc: "\u662F\u5426\u5F3A\u5236\u73A9\u5BB6\u4E0B\u8F7D\u670D\u52A1\u5668\u6307\u5B9A\u7684\u6750\u8D28\u8D44\u6E90\u5305\u540E\u624D\u80FD\u52A0\u5165",
|
|
82
|
+
values: "true (\u5FC5\u987B\u4E0B\u8F7D) | false (\u53EF\u9009\u4E0B\u8F7D)"
|
|
83
|
+
},
|
|
84
|
+
"content-log-console-output-enabled": {
|
|
85
|
+
desc: "\u662F\u5426\u5C06\u5185\u5BB9\u65E5\u5FD7\uFF08\u6A21\u7EC4/\u884C\u4E3A\u5305\u89E3\u6790\u8B66\u544A\u3001SAPI \u811A\u672C\u62A5\u9519\u4E0E console.log\uFF09\u5B9E\u65F6\u8F93\u51FA\u5230\u63A7\u5236\u53F0",
|
|
86
|
+
values: "true | false",
|
|
87
|
+
tip: "\u5F00\u53D1\u6216\u8C03\u8BD5\u6A21\u7EC4\u65F6\u5F3A\u70C8\u5EFA\u8BAE\u8BBE\u4E3A true\uFF0C\u4EE5\u4FBF\u5373\u65F6\u67E5\u770B\u9519\u8BEF"
|
|
88
|
+
},
|
|
89
|
+
"compression-threshold": {
|
|
90
|
+
desc: "\u7F51\u7EDC\u6570\u636E\u5305\u542F\u7528\u538B\u7F29\u7684\u6700\u5C0F\u5B57\u8282\u9608\u503C",
|
|
91
|
+
values: "0 (\u5168\u90E8\u538B\u7F29) ~ 65535 \u5B57\u8282\uFF081.20+ \u9ED8\u8BA4\u901A\u5E38\u4E3A 1\uFF09"
|
|
92
|
+
},
|
|
93
|
+
"compression-algorithm": {
|
|
94
|
+
desc: "\u7F51\u7EDC\u4F20\u8F93\u6570\u636E\u5305\u7684\u538B\u7F29\u7B97\u6CD5",
|
|
95
|
+
values: "zlib (\u6807\u51C6\u9AD8\u538B\u7F29\u6BD4) | snappy (\u9AD8\u6027\u80FD\u4F4E\u5EF6\u8FDF\uFF0CCPU \u5F00\u9500\u5C0F)"
|
|
96
|
+
},
|
|
97
|
+
"server-authoritative-movement": {
|
|
98
|
+
desc: "\u73A9\u5BB6\u79FB\u52A8\u9A8C\u8BC1\u6743\u5A01\u6A21\u5F0F",
|
|
99
|
+
values: "server-auth (\u670D\u52A1\u7AEF\u6743\u5A01\u5224\u5B9A) | client-auth (\u5BA2\u6237\u7AEF\u6743\u5A01)"
|
|
100
|
+
},
|
|
101
|
+
"player-movement-score-threshold": {
|
|
102
|
+
desc: "\u73A9\u5BB6\u79FB\u52A8\u5F02\u5E38\u88AB\u5224\u5B9A\u4E3A\u4F5C\u5F0A\u7684\u7D2F\u8BA1\u5F02\u5E38\u5206\u9608\u503C",
|
|
103
|
+
values: "\u6574\u6570\uFF08\u9ED8\u8BA4 20\uFF09"
|
|
104
|
+
},
|
|
105
|
+
"player-movement-action-direction-threshold": {
|
|
106
|
+
desc: "\u73A9\u5BB6\u653B\u51FB\u6216\u7834\u574F\u52A8\u4F5C\u4E0E\u89C6\u7EBF\u671D\u5411\u5939\u89D2\u504F\u5DEE\u7684\u5224\u5B9A\u9608\u503C",
|
|
107
|
+
values: "\u6D6E\u70B9\u6570\uFF08\u9ED8\u8BA4 0.85\uFF09"
|
|
108
|
+
},
|
|
109
|
+
"player-movement-distance-threshold": {
|
|
110
|
+
desc: "\u73A9\u5BB6\u5355\u6B21\u4F4D\u79FB\u8D85\u51FA\u6B63\u5E38\u8303\u56F4\u7684\u5224\u5B9A\u9608\u503C",
|
|
111
|
+
values: "\u6D6E\u70B9\u6570\uFF08\u9ED8\u8BA4 0.3\uFF09"
|
|
112
|
+
},
|
|
113
|
+
"player-movement-duration-threshold-in-ms": {
|
|
114
|
+
desc: "\u79FB\u52A8\u5F02\u5E38\u5224\u5B9A\u91C7\u6837\u7684\u6ED1\u52A8\u65F6\u95F4\u7A97\u53E3\uFF08\u5355\u4F4D\uFF1A\u6BEB\u79D2\uFF09",
|
|
115
|
+
values: "\u6574\u6570\uFF08\u9ED8\u8BA4 500\uFF09"
|
|
116
|
+
},
|
|
117
|
+
"correct-player-movement": {
|
|
118
|
+
desc: "\u5F53\u68C0\u6D4B\u5230\u73A9\u5BB6\u79FB\u52A8\u4F5C\u5F0A\u6216\u8D85\u6807\u65F6\uFF0C\u662F\u5426\u5F3A\u5236\u5C06\u5176\u62C9\u56DE\u5408\u6CD5\u4F4D\u7F6E\uFF08\u9632\u98DE\u5929/\u52A0\u901F\uFF09",
|
|
119
|
+
values: "true (\u5F3A\u5236\u56DE\u62C9\u7EA0\u6B63) | false (\u4EC5\u5728\u540E\u53F0\u8BB0\u5F55\u8B66\u544A)"
|
|
120
|
+
},
|
|
121
|
+
"server-authoritative-block-breaking": {
|
|
122
|
+
desc: "\u65B9\u5757\u7834\u574F\u52A8\u4F5C\u662F\u5426\u7531\u670D\u52A1\u7AEF\u6743\u5A01\u5224\u5B9A\uFF08\u9632\u6B62\u53D8\u901F\u5237\u65B9\u5757\u7B49\u4F5C\u5F0A\u884C\u4E3A\uFF09",
|
|
123
|
+
values: "client-auth | server-auth"
|
|
124
|
+
},
|
|
125
|
+
"chat-restriction": {
|
|
126
|
+
desc: "\u804A\u5929\u8FC7\u6EE4\u9650\u5236\u7B56\u7565",
|
|
127
|
+
values: "None (\u65E0\u9650\u5236) | Dropped (\u9759\u9ED8\u4E22\u5F03\u8FDD\u89C4\u5185\u5BB9) | Disabled (\u5B8C\u5168\u7981\u7528\u804A\u5929)"
|
|
128
|
+
},
|
|
129
|
+
"disable-player-interaction": {
|
|
130
|
+
desc: "\u662F\u5426\u7981\u7528\u9759\u9ED8\u4EA4\u4E92\u68C0\u6D4B\uFF08\u7528\u4E8E\u6392\u67E5\u7F51\u7EDC\u5EF6\u8FDF\u6216\u9632\u5FEB\u901F\u4EA4\u4E92\uFF09",
|
|
131
|
+
values: "true | false"
|
|
132
|
+
},
|
|
133
|
+
"client-side-chunk-generation-enabled": {
|
|
134
|
+
desc: "\u662F\u5426\u5141\u8BB8\u5BA2\u6237\u7AEF\u5728\u672C\u5730\u751F\u6210\u5C1A\u672A\u52A0\u8F7D\u7684\u5730\u5F62\u533A\u5757\uFF08\u52A0\u5FEB\u957F\u8DDD\u79BB\u63A2\u7D22\u65F6\u7684\u89C6\u89C9\u52A0\u8F7D\u901F\u5EA6\uFF09",
|
|
135
|
+
values: "true (\u5141\u8BB8\u5BA2\u6237\u7AEF\u672C\u5730\u9884\u751F\u6210) | false (\u5168\u90E8\u7531\u670D\u52A1\u7AEF\u751F\u6210\u5E76\u4F20\u8F93)"
|
|
136
|
+
},
|
|
137
|
+
"block-network-ids-are-hashes": {
|
|
138
|
+
desc: "\u65B9\u5757\u5728\u7F51\u7EDC\u4F20\u8F93\u4E2D\u7684\u552F\u4E00\u6807\u8BC6\u662F\u5426\u91C7\u7528\u54C8\u5E0C\u503C",
|
|
139
|
+
values: "true | false"
|
|
140
|
+
},
|
|
141
|
+
"disable-persona": {
|
|
142
|
+
desc: "\u662F\u5426\u7981\u7528\u4E2A\u6027\u5316\u88C5\u626E/\u89D2\u8272\u521B\u5EFA\u5668\uFF08Persona \u76AE\u80A4\uFF09",
|
|
143
|
+
values: "true (\u5F3A\u5236\u4F7F\u7528\u7ECF\u5178\u76AE\u80A4) | false (\u5141\u8BB8\u4F7F\u7528\u5B98\u65B9\u634F\u8138\u89D2\u8272)"
|
|
144
|
+
},
|
|
145
|
+
"disable-custom-skins": {
|
|
146
|
+
desc: "\u662F\u5426\u7981\u7528\u73A9\u5BB6\u4E0A\u4F20\u7684\u81EA\u5B9A\u4E49\u7ECF\u5178\u76AE\u80A4\uFF08\u9632\u6B62\u6076\u610F\u6216\u900F\u660E\u76AE\u80A4\uFF09",
|
|
147
|
+
values: "true (\u7981\u7528\u81EA\u5B9A\u4E49\u76AE\u80A4) | false (\u5141\u8BB8\u81EA\u5B9A\u4E49\u76AE\u80A4)"
|
|
148
|
+
},
|
|
149
|
+
"emit-server-telemetry": {
|
|
150
|
+
desc: "\u662F\u5426\u5411 Mojang \u53D1\u9001\u670D\u52A1\u5668\u9065\u6D4B\u4E0E\u8FD0\u884C\u5065\u5EB7\u8BCA\u65AD\u6570\u636E",
|
|
151
|
+
values: "true | false",
|
|
152
|
+
tip: "\u4F7F\u7528\u672C\u5E73\u53F0\u65F6\u56E0\u60A8\u5DF2\u540C\u610F Mojang EULA \u534F\u8BAE\uFF0C\u6309\u534F\u8BAE\u4FDD\u6301\u542F\u7528"
|
|
153
|
+
},
|
|
154
|
+
"server-build-radius-ratio": {
|
|
155
|
+
desc: "\u5141\u8BB8\u73A9\u5BB6\u5EFA\u9020\u548C\u4EA4\u4E92\u7684\u4E16\u754C\u533A\u57DF\u534A\u5F84\u6BD4\u4F8B",
|
|
156
|
+
values: "Disabled (\u65E0\u9650\u5236) \u6216 0.0 ~ 1.0 \u7684\u6D6E\u70B9\u6570"
|
|
157
|
+
},
|
|
158
|
+
"allow-outbound-script-debugging": {
|
|
159
|
+
desc: "\u662F\u5426\u5141\u8BB8\u670D\u52A1\u7AEF\u811A\u672C\u4E3B\u52A8\u8FDE\u63A5\u5916\u90E8\u8C03\u8BD5\u5668\uFF08\u5141\u8BB8 /script debugger connect \u6307\u4EE4\uFF09",
|
|
160
|
+
values: "true | false",
|
|
161
|
+
tip: "\u4EC5\u5728\u901A\u8FC7 VS Code \u8C03\u8BD5 SAPI \u6A21\u7EC4\u65F6\u5F00\u542F\uFF0C\u751F\u4EA7\u73AF\u5883\u5EFA\u8BAE\u5173\u95ED"
|
|
162
|
+
},
|
|
163
|
+
"allow-inbound-script-debugging": {
|
|
164
|
+
desc: "\u662F\u5426\u5141\u8BB8\u5916\u90E8\u811A\u672C\u8C03\u8BD5\u5668\u4E3B\u52A8\u8FDE\u63A5\u670D\u52A1\u7AEF\uFF08\u5141\u8BB8 /script debugger listen \u6307\u4EE4\uFF09",
|
|
165
|
+
values: "true | false",
|
|
166
|
+
tip: "\u4EC5\u5728\u901A\u8FC7 VS Code \u8C03\u8BD5 SAPI \u6A21\u7EC4\u65F6\u5F00\u542F\uFF0C\u751F\u4EA7\u73AF\u5883\u5EFA\u8BAE\u5173\u95ED"
|
|
167
|
+
},
|
|
168
|
+
"force-inbound-debug-port": {
|
|
169
|
+
desc: "\u811A\u672C\u8C03\u8BD5\u5668\u76D1\u542C\u7684\u4E13\u5C5E\u7F51\u7EDC\u7AEF\u53E3",
|
|
170
|
+
values: "1 ~ 65535\uFF08\u9ED8\u8BA4\uFF1A19144\uFF09"
|
|
171
|
+
},
|
|
172
|
+
"script-debugger-auto-attach": {
|
|
173
|
+
desc: "\u4E16\u754C\u52A0\u8F7D\u65F6\uFF0C\u662F\u5426\u81EA\u52A8\u8FDE\u63A5\u6216\u76D1\u542C\u5916\u90E8\u811A\u672C\u8C03\u8BD5\u5668",
|
|
174
|
+
values: "disabled (\u4E0D\u81EA\u52A8\u9644\u52A0) | connect (\u81EA\u52A8\u5411\u5916\u8FDE\u63A5) | listen (\u81EA\u52A8\u5F00\u542F\u7AEF\u53E3\u76D1\u542C)"
|
|
175
|
+
},
|
|
176
|
+
"script-debugger-auto-attach-connect-address": {
|
|
177
|
+
desc: "\u5F53 auto-attach \u8BBE\u4E3A connect \u65F6\uFF0C\u5C1D\u8BD5\u8FDE\u63A5\u7684\u76EE\u6807\u8C03\u8BD5\u5668\u4E3B\u673A\u4E0E\u7AEF\u53E3",
|
|
178
|
+
values: "ip:port\uFF08\u4F8B\u5982 localhost:19144\uFF09"
|
|
179
|
+
},
|
|
180
|
+
"websocket-retry-time": {
|
|
181
|
+
desc: "\u8FDE\u63A5\u5916\u90E8 WebSocket \u670D\u52A1\u5668\u65AD\u5F00\u540E\u7684\u81EA\u52A8\u91CD\u8BD5\u95F4\u9694\uFF08\u5355\u4F4D\uFF1A\u79D2\uFF09",
|
|
182
|
+
values: "\u6B63\u6574\u6570\uFF08\u9ED8\u8BA4 20\uFF09"
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
function getServerPropertyDoc(key, locale = "zh-CN") {
|
|
186
|
+
const normalizedKey = key.trim().toLowerCase();
|
|
187
|
+
const normalizedLocale = locale.toLowerCase();
|
|
188
|
+
if (normalizedLocale === "zh" || normalizedLocale.startsWith("zh-")) {
|
|
189
|
+
return SERVER_PROPERTIES_DOCS_ZH_CN[normalizedKey];
|
|
190
|
+
}
|
|
191
|
+
return void 0;
|
|
192
|
+
}
|
|
193
|
+
export {
|
|
194
|
+
SERVER_PROPERTIES_DOCS_ZH_CN,
|
|
195
|
+
getServerPropertyDoc
|
|
196
|
+
};
|
|
197
|
+
//# sourceMappingURL=server-properties-i18n.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/server-properties-i18n.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * server-properties-i18n.ts \u2014 BDS server.properties \u591A\u8BED\u8A00\u6CE8\u91CA\u5B57\u5178\n */\n\nexport interface ServerPropertyDoc {\n /** \u4E2D\u6587\u529F\u80FD\u6982\u8FF0 */\n desc: string;\n /** \u5408\u6CD5\u53D6\u503C\u4E0E\u679A\u4E3E\u8BF4\u660E */\n values?: string;\n /** \u907F\u5751\u3001\u6027\u80FD\u6216\u5B89\u5168\u6027\u63D0\u793A */\n tip?: string;\n}\n\nexport const SERVER_PROPERTIES_DOCS_ZH_CN: Record<string, ServerPropertyDoc> = {\n \"server-name\": {\n desc: \"\u670D\u52A1\u5668\u540D\u79F0\uFF08\u663E\u793A\u5728\u5BA2\u6237\u7AEF\u5C40\u57DF\u7F51/\u597D\u53CB\u5217\u8868\u4E2D\uFF09\",\n values: \"\u4EFB\u610F\u5B57\u7B26\u4E32\uFF08\u8BF7\u52FF\u5305\u542B\u5206\u53F7 ;\uFF09\",\n },\n \"gamemode\": {\n desc: \"\u65B0\u73A9\u5BB6\u9996\u6B21\u52A0\u5165\u4E16\u754C\u65F6\u7684\u9ED8\u8BA4\u6E38\u620F\u6A21\u5F0F\",\n values: \"survival (\u751F\u5B58) | creative (\u521B\u9020) | adventure (\u5192\u9669)\",\n },\n \"force-gamemode\": {\n desc: \"\u662F\u5426\u5F3A\u5236\u73A9\u5BB6\u6BCF\u6B21\u91CD\u65B0\u8FDE\u63A5\u65F6\u90FD\u91CD\u7F6E\u4E3A\u9ED8\u8BA4\u6E38\u620F\u6A21\u5F0F\",\n values: \"true (\u6BCF\u6B21\u8FDB\u670D\u5F3A\u5236\u8F6C\u4E3A\u9ED8\u8BA4\u6A21\u5F0F) | false (\u4FDD\u7559\u73A9\u5BB6\u4E0A\u6B21\u79BB\u7EBF\u65F6\u7684\u6A21\u5F0F)\",\n },\n \"difficulty\": {\n desc: \"\u6E38\u620F\u4E16\u754C\u7684\u9ED8\u8BA4\u96BE\u5EA6\",\n values: \"peaceful (\u548C\u5E73) | easy (\u7B80\u5355) | normal (\u666E\u901A) | hard (\u56F0\u96BE)\",\n },\n \"allow-cheats\": {\n desc: \"\u662F\u5426\u5141\u8BB8\u5728\u63A7\u5236\u53F0\u6216\u6E38\u620F\u5185\u4F7F\u7528\u7BA1\u7406\u5458\u6307\u4EE4\uFF08\u4F5C\u5F0A\u6A21\u5F0F\uFF09\",\n values: \"true | false\",\n tip: \"\u82E5\u5F00\u542F\u6B64\u9879\uFF0C\u52A0\u5165\u8BE5\u4E16\u754C\u7684\u73A9\u5BB6\u5C06\u65E0\u6CD5\u83B7\u5F97 Xbox \u6210\u5C31\",\n },\n \"max-players\": {\n desc: \"\u5141\u8BB8\u540C\u65F6\u5728\u7EBF\u7684\u6700\u5927\u73A9\u5BB6\u6570\u91CF\u9650\u5236\",\n values: \"\u6B63\u6574\u6570\uFF08\u5982 10\u300120\uFF09\",\n },\n \"online-mode\": {\n desc: \"\u662F\u5426\u5F00\u542F\u5FAE\u8F6F Xbox Live \u6B63\u7248\u8EAB\u4EFD\u9A8C\u8BC1\",\n values: \"true (\u4EC5\u5141\u8BB8\u6B63\u7248\u5FAE\u8F6F\u8D26\u53F7\u767B\u5F55) | false (\u5141\u8BB8\u79BB\u7EBF\u514D\u767B\u5F55\u8FDE\u63A5\uFF0C\u4F46\u6613\u53D7\u5047\u4EBA\u653B\u51FB)\",\n tip: \"\u516C\u7F51\u670D\u52A1\u5668\u5F3A\u70C8\u5EFA\u8BAE\u8BBE\u4E3A true \u4EE5\u9632\u6B62\u6076\u610F\u4F2A\u9020\u8EAB\u4EFD\",\n },\n \"white-list\": {\n desc: \"\u662F\u5426\u5F00\u542F\u51C6\u5165\u767D\u540D\u5355\u9A8C\u8BC1\uFF08\u90E8\u5206\u7248\u672C\u5BF9\u5E94 allow-list\uFF09\",\n values: \"true (\u4EC5\u5141\u8BB8\u767D\u540D\u5355\u4E2D\u7684\u73A9\u5BB6\u8FDB\u5165) | false (\u6240\u6709\u73A9\u5BB6\u5747\u53EF\u8FDB\u5165)\",\n },\n \"allow-list\": {\n desc: \"\u662F\u5426\u5F00\u542F\u51C6\u5165\u767D\u540D\u5355\u9A8C\u8BC1\uFF08\u9700\u914D\u5408 allowlist.json \u4F7F\u7528\uFF09\",\n values: \"true (\u4EC5\u5141\u8BB8\u767D\u540D\u5355\u4E2D\u7684\u73A9\u5BB6\u8FDB\u5165) | false (\u6240\u6709\u73A9\u5BB6\u5747\u53EF\u8FDB\u5165)\",\n },\n \"server-port\": {\n desc: \"\u670D\u52A1\u7AEF\u76D1\u542C\u7684 IPv4 UDP \u7F51\u7EDC\u901A\u4FE1\u7AEF\u53E3\",\n values: \"1 ~ 65535\uFF08\u9ED8\u8BA4\uFF1A19132\uFF09\",\n },\n \"server-portv6\": {\n desc: \"\u670D\u52A1\u7AEF\u76D1\u542C\u7684 IPv6 UDP \u7F51\u7EDC\u901A\u4FE1\u7AEF\u53E3\",\n values: \"1 ~ 65535\uFF08\u9ED8\u8BA4\uFF1A19133\uFF09\",\n },\n \"enable-lan-visibility\": {\n desc: \"\u662F\u5426\u5411\u5C40\u57DF\u7F51\u5E7F\u64AD\u672C\u670D\u52A1\u5668\uFF08\u4F7F\u540C\u5C40\u57DF\u7F51\u73A9\u5BB6\u80FD\u5728\u5BA2\u6237\u7AEF\u300C\u597D\u53CB\u300D\u5217\u8868\u4E2D\u76F4\u63A5\u53D1\u73B0\uFF09\",\n values: \"true | false\",\n },\n \"view-distance\": {\n desc: \"\u670D\u52A1\u7AEF\u5411\u5BA2\u6237\u7AEF\u53D1\u9001\u5730\u56FE\u533A\u5757\u7684\u6700\u5927\u89C6\u8DDD\uFF08\u5355\u4F4D\uFF1A\u533A\u5757\uFF09\",\n values: \"\u6B63\u6574\u6570\uFF08\u5EFA\u8BAE 12 ~ 32\uFF0C\u6570\u503C\u8D8A\u5927\u7F51\u7EDC\u4E0E\u5185\u5B58\u6D88\u8017\u8D8A\u9AD8\uFF09\",\n },\n \"tick-distance\": {\n desc: \"\u4E16\u754C\u5B9E\u4F53\u903B\u8F91\u4E0E\u65B9\u5757\u66F4\u65B0\u7684\u6A21\u62DF\u8BA1\u7B97\u8DDD\u79BB\uFF08\u5355\u4F4D\uFF1A\u533A\u5757\uFF09\",\n values: \"4 ~ 12\uFF08\u6570\u503C\u8D8A\u5C0F\u670D\u52A1\u5668\u6027\u80FD\u8D8A\u597D\uFF0C\u4F4E\u914D\u673A\u578B\u63A8\u8350 4\uFF09\",\n },\n \"player-idle-timeout\": {\n desc: \"\u73A9\u5BB6\u6302\u673A\u65E0\u64CD\u4F5C\u81EA\u52A8\u8E22\u51FA\u8D85\u65F6\u65F6\u95F4\uFF08\u5355\u4F4D\uFF1A\u5206\u949F\uFF09\",\n values: \"0 (\u6C38\u4E0D\u8E22\u51FA) \u6216\u5927\u4E8E 0 \u7684\u6574\u6570\",\n },\n \"max-threads\": {\n desc: \"BDS \u8FD0\u884C\u53EF\u4F7F\u7528\u7684\u6700\u5927\u5DE5\u4F5C\u7EBF\u7A0B\u6570\",\n values: \"0 (\u7531\u670D\u52A1\u7AEF\u6839\u636E CPU \u6838\u5FC3\u6570\u81EA\u52A8\u5206\u914D) \u6216\u6307\u5B9A\u7EBF\u7A0B\u6570\",\n },\n \"level-name\": {\n desc: \"\u8981\u52A0\u8F7D\u7684\u4E16\u754C\u5B58\u6863\u6587\u4EF6\u5939\u540D\u79F0\uFF08\u5BF9\u5E94 worlds/ \u76EE\u5F55\u4E0B\u7684\u5B50\u6587\u4EF6\u5939\uFF09\",\n values: \"\u6587\u4EF6\u5939\u540D\u79F0\uFF08\u9ED8\u8BA4\uFF1ABedrock level\uFF09\",\n },\n \"level-seed\": {\n desc: \"\u5168\u65B0\u4E16\u754C\u751F\u6210\u65F6\u7684\u968F\u673A\u79CD\u5B50\",\n values: \"\u4EFB\u610F\u6570\u5B57\u6216\u6587\u672C\uFF08\u7559\u7A7A\u5219\u6BCF\u6B21\u65B0\u5EFA\u4E16\u754C\u968F\u673A\u751F\u6210\uFF09\",\n },\n \"default-player-permission-level\": {\n desc: \"\u65B0\u73A9\u5BB6\u9996\u6B21\u52A0\u5165\u65F6\u7684\u9ED8\u8BA4\u6743\u9650\u7EA7\u522B\",\n values: \"visitor (\u8BBF\u5BA2\uFF0C\u4E0D\u53EF\u7834\u574F\u6216\u4EA4\u4E92) | member (\u666E\u901A\u6210\u5458) | operator (\u64CD\u4F5C\u5458)\",\n },\n \"texturepack-required\": {\n desc: \"\u662F\u5426\u5F3A\u5236\u73A9\u5BB6\u4E0B\u8F7D\u670D\u52A1\u5668\u6307\u5B9A\u7684\u6750\u8D28\u8D44\u6E90\u5305\u540E\u624D\u80FD\u52A0\u5165\",\n values: \"true (\u5FC5\u987B\u4E0B\u8F7D) | false (\u53EF\u9009\u4E0B\u8F7D)\",\n },\n \"content-log-console-output-enabled\": {\n desc: \"\u662F\u5426\u5C06\u5185\u5BB9\u65E5\u5FD7\uFF08\u6A21\u7EC4/\u884C\u4E3A\u5305\u89E3\u6790\u8B66\u544A\u3001SAPI \u811A\u672C\u62A5\u9519\u4E0E console.log\uFF09\u5B9E\u65F6\u8F93\u51FA\u5230\u63A7\u5236\u53F0\",\n values: \"true | false\",\n tip: \"\u5F00\u53D1\u6216\u8C03\u8BD5\u6A21\u7EC4\u65F6\u5F3A\u70C8\u5EFA\u8BAE\u8BBE\u4E3A true\uFF0C\u4EE5\u4FBF\u5373\u65F6\u67E5\u770B\u9519\u8BEF\",\n },\n \"compression-threshold\": {\n desc: \"\u7F51\u7EDC\u6570\u636E\u5305\u542F\u7528\u538B\u7F29\u7684\u6700\u5C0F\u5B57\u8282\u9608\u503C\",\n values: \"0 (\u5168\u90E8\u538B\u7F29) ~ 65535 \u5B57\u8282\uFF081.20+ \u9ED8\u8BA4\u901A\u5E38\u4E3A 1\uFF09\",\n },\n \"compression-algorithm\": {\n desc: \"\u7F51\u7EDC\u4F20\u8F93\u6570\u636E\u5305\u7684\u538B\u7F29\u7B97\u6CD5\",\n values: \"zlib (\u6807\u51C6\u9AD8\u538B\u7F29\u6BD4) | snappy (\u9AD8\u6027\u80FD\u4F4E\u5EF6\u8FDF\uFF0CCPU \u5F00\u9500\u5C0F)\",\n },\n \"server-authoritative-movement\": {\n desc: \"\u73A9\u5BB6\u79FB\u52A8\u9A8C\u8BC1\u6743\u5A01\u6A21\u5F0F\",\n values: \"server-auth (\u670D\u52A1\u7AEF\u6743\u5A01\u5224\u5B9A) | client-auth (\u5BA2\u6237\u7AEF\u6743\u5A01)\",\n },\n \"player-movement-score-threshold\": {\n desc: \"\u73A9\u5BB6\u79FB\u52A8\u5F02\u5E38\u88AB\u5224\u5B9A\u4E3A\u4F5C\u5F0A\u7684\u7D2F\u8BA1\u5F02\u5E38\u5206\u9608\u503C\",\n values: \"\u6574\u6570\uFF08\u9ED8\u8BA4 20\uFF09\",\n },\n \"player-movement-action-direction-threshold\": {\n desc: \"\u73A9\u5BB6\u653B\u51FB\u6216\u7834\u574F\u52A8\u4F5C\u4E0E\u89C6\u7EBF\u671D\u5411\u5939\u89D2\u504F\u5DEE\u7684\u5224\u5B9A\u9608\u503C\",\n values: \"\u6D6E\u70B9\u6570\uFF08\u9ED8\u8BA4 0.85\uFF09\",\n },\n \"player-movement-distance-threshold\": {\n desc: \"\u73A9\u5BB6\u5355\u6B21\u4F4D\u79FB\u8D85\u51FA\u6B63\u5E38\u8303\u56F4\u7684\u5224\u5B9A\u9608\u503C\",\n values: \"\u6D6E\u70B9\u6570\uFF08\u9ED8\u8BA4 0.3\uFF09\",\n },\n \"player-movement-duration-threshold-in-ms\": {\n desc: \"\u79FB\u52A8\u5F02\u5E38\u5224\u5B9A\u91C7\u6837\u7684\u6ED1\u52A8\u65F6\u95F4\u7A97\u53E3\uFF08\u5355\u4F4D\uFF1A\u6BEB\u79D2\uFF09\",\n values: \"\u6574\u6570\uFF08\u9ED8\u8BA4 500\uFF09\",\n },\n \"correct-player-movement\": {\n desc: \"\u5F53\u68C0\u6D4B\u5230\u73A9\u5BB6\u79FB\u52A8\u4F5C\u5F0A\u6216\u8D85\u6807\u65F6\uFF0C\u662F\u5426\u5F3A\u5236\u5C06\u5176\u62C9\u56DE\u5408\u6CD5\u4F4D\u7F6E\uFF08\u9632\u98DE\u5929/\u52A0\u901F\uFF09\",\n values: \"true (\u5F3A\u5236\u56DE\u62C9\u7EA0\u6B63) | false (\u4EC5\u5728\u540E\u53F0\u8BB0\u5F55\u8B66\u544A)\",\n },\n \"server-authoritative-block-breaking\": {\n desc: \"\u65B9\u5757\u7834\u574F\u52A8\u4F5C\u662F\u5426\u7531\u670D\u52A1\u7AEF\u6743\u5A01\u5224\u5B9A\uFF08\u9632\u6B62\u53D8\u901F\u5237\u65B9\u5757\u7B49\u4F5C\u5F0A\u884C\u4E3A\uFF09\",\n values: \"client-auth | server-auth\",\n },\n \"chat-restriction\": {\n desc: \"\u804A\u5929\u8FC7\u6EE4\u9650\u5236\u7B56\u7565\",\n values: \"None (\u65E0\u9650\u5236) | Dropped (\u9759\u9ED8\u4E22\u5F03\u8FDD\u89C4\u5185\u5BB9) | Disabled (\u5B8C\u5168\u7981\u7528\u804A\u5929)\",\n },\n \"disable-player-interaction\": {\n desc: \"\u662F\u5426\u7981\u7528\u9759\u9ED8\u4EA4\u4E92\u68C0\u6D4B\uFF08\u7528\u4E8E\u6392\u67E5\u7F51\u7EDC\u5EF6\u8FDF\u6216\u9632\u5FEB\u901F\u4EA4\u4E92\uFF09\",\n values: \"true | false\",\n },\n \"client-side-chunk-generation-enabled\": {\n desc: \"\u662F\u5426\u5141\u8BB8\u5BA2\u6237\u7AEF\u5728\u672C\u5730\u751F\u6210\u5C1A\u672A\u52A0\u8F7D\u7684\u5730\u5F62\u533A\u5757\uFF08\u52A0\u5FEB\u957F\u8DDD\u79BB\u63A2\u7D22\u65F6\u7684\u89C6\u89C9\u52A0\u8F7D\u901F\u5EA6\uFF09\",\n values: \"true (\u5141\u8BB8\u5BA2\u6237\u7AEF\u672C\u5730\u9884\u751F\u6210) | false (\u5168\u90E8\u7531\u670D\u52A1\u7AEF\u751F\u6210\u5E76\u4F20\u8F93)\",\n },\n \"block-network-ids-are-hashes\": {\n desc: \"\u65B9\u5757\u5728\u7F51\u7EDC\u4F20\u8F93\u4E2D\u7684\u552F\u4E00\u6807\u8BC6\u662F\u5426\u91C7\u7528\u54C8\u5E0C\u503C\",\n values: \"true | false\",\n },\n \"disable-persona\": {\n desc: \"\u662F\u5426\u7981\u7528\u4E2A\u6027\u5316\u88C5\u626E/\u89D2\u8272\u521B\u5EFA\u5668\uFF08Persona \u76AE\u80A4\uFF09\",\n values: \"true (\u5F3A\u5236\u4F7F\u7528\u7ECF\u5178\u76AE\u80A4) | false (\u5141\u8BB8\u4F7F\u7528\u5B98\u65B9\u634F\u8138\u89D2\u8272)\",\n },\n \"disable-custom-skins\": {\n desc: \"\u662F\u5426\u7981\u7528\u73A9\u5BB6\u4E0A\u4F20\u7684\u81EA\u5B9A\u4E49\u7ECF\u5178\u76AE\u80A4\uFF08\u9632\u6B62\u6076\u610F\u6216\u900F\u660E\u76AE\u80A4\uFF09\",\n values: \"true (\u7981\u7528\u81EA\u5B9A\u4E49\u76AE\u80A4) | false (\u5141\u8BB8\u81EA\u5B9A\u4E49\u76AE\u80A4)\",\n },\n \"emit-server-telemetry\": {\n desc: \"\u662F\u5426\u5411 Mojang \u53D1\u9001\u670D\u52A1\u5668\u9065\u6D4B\u4E0E\u8FD0\u884C\u5065\u5EB7\u8BCA\u65AD\u6570\u636E\",\n values: \"true | false\",\n tip: \"\u4F7F\u7528\u672C\u5E73\u53F0\u65F6\u56E0\u60A8\u5DF2\u540C\u610F Mojang EULA \u534F\u8BAE\uFF0C\u6309\u534F\u8BAE\u4FDD\u6301\u542F\u7528\",\n },\n \"server-build-radius-ratio\": {\n desc: \"\u5141\u8BB8\u73A9\u5BB6\u5EFA\u9020\u548C\u4EA4\u4E92\u7684\u4E16\u754C\u533A\u57DF\u534A\u5F84\u6BD4\u4F8B\",\n values: \"Disabled (\u65E0\u9650\u5236) \u6216 0.0 ~ 1.0 \u7684\u6D6E\u70B9\u6570\",\n },\n \"allow-outbound-script-debugging\": {\n desc: \"\u662F\u5426\u5141\u8BB8\u670D\u52A1\u7AEF\u811A\u672C\u4E3B\u52A8\u8FDE\u63A5\u5916\u90E8\u8C03\u8BD5\u5668\uFF08\u5141\u8BB8 /script debugger connect \u6307\u4EE4\uFF09\",\n values: \"true | false\",\n tip: \"\u4EC5\u5728\u901A\u8FC7 VS Code \u8C03\u8BD5 SAPI \u6A21\u7EC4\u65F6\u5F00\u542F\uFF0C\u751F\u4EA7\u73AF\u5883\u5EFA\u8BAE\u5173\u95ED\",\n },\n \"allow-inbound-script-debugging\": {\n desc: \"\u662F\u5426\u5141\u8BB8\u5916\u90E8\u811A\u672C\u8C03\u8BD5\u5668\u4E3B\u52A8\u8FDE\u63A5\u670D\u52A1\u7AEF\uFF08\u5141\u8BB8 /script debugger listen \u6307\u4EE4\uFF09\",\n values: \"true | false\",\n tip: \"\u4EC5\u5728\u901A\u8FC7 VS Code \u8C03\u8BD5 SAPI \u6A21\u7EC4\u65F6\u5F00\u542F\uFF0C\u751F\u4EA7\u73AF\u5883\u5EFA\u8BAE\u5173\u95ED\",\n },\n \"force-inbound-debug-port\": {\n desc: \"\u811A\u672C\u8C03\u8BD5\u5668\u76D1\u542C\u7684\u4E13\u5C5E\u7F51\u7EDC\u7AEF\u53E3\",\n values: \"1 ~ 65535\uFF08\u9ED8\u8BA4\uFF1A19144\uFF09\",\n },\n \"script-debugger-auto-attach\": {\n desc: \"\u4E16\u754C\u52A0\u8F7D\u65F6\uFF0C\u662F\u5426\u81EA\u52A8\u8FDE\u63A5\u6216\u76D1\u542C\u5916\u90E8\u811A\u672C\u8C03\u8BD5\u5668\",\n values: \"disabled (\u4E0D\u81EA\u52A8\u9644\u52A0) | connect (\u81EA\u52A8\u5411\u5916\u8FDE\u63A5) | listen (\u81EA\u52A8\u5F00\u542F\u7AEF\u53E3\u76D1\u542C)\",\n },\n \"script-debugger-auto-attach-connect-address\": {\n desc: \"\u5F53 auto-attach \u8BBE\u4E3A connect \u65F6\uFF0C\u5C1D\u8BD5\u8FDE\u63A5\u7684\u76EE\u6807\u8C03\u8BD5\u5668\u4E3B\u673A\u4E0E\u7AEF\u53E3\",\n values: \"ip:port\uFF08\u4F8B\u5982 localhost:19144\uFF09\",\n },\n \"websocket-retry-time\": {\n desc: \"\u8FDE\u63A5\u5916\u90E8 WebSocket \u670D\u52A1\u5668\u65AD\u5F00\u540E\u7684\u81EA\u52A8\u91CD\u8BD5\u95F4\u9694\uFF08\u5355\u4F4D\uFF1A\u79D2\uFF09\",\n values: \"\u6B63\u6574\u6570\uFF08\u9ED8\u8BA4 20\uFF09\",\n },\n};\n\n/**\n * \u6839\u636E\u5C5E\u6027 key \u548C\u76EE\u6807\u8BED\u8A00\u83B7\u53D6\u8BF4\u660E\u6587\u6863\n */\nexport function getServerPropertyDoc(key: string, locale: string = \"zh-CN\"): ServerPropertyDoc | undefined {\n const normalizedKey = key.trim().toLowerCase();\n const normalizedLocale = locale.toLowerCase();\n\n if (normalizedLocale === \"zh\" || normalizedLocale.startsWith(\"zh-\")) {\n return SERVER_PROPERTIES_DOCS_ZH_CN[normalizedKey];\n }\n return undefined;\n}\n"],
|
|
5
|
+
"mappings": "AAaO,MAAM,+BAAkE;AAAA,EAC7E,eAAe;AAAA,IACb,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,YAAY;AAAA,IACV,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,kBAAkB;AAAA,IAChB,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,gBAAgB;AAAA,IACd,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,KAAK;AAAA,EACP;AAAA,EACA,eAAe;AAAA,IACb,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,eAAe;AAAA,IACb,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,KAAK;AAAA,EACP;AAAA,EACA,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,eAAe;AAAA,IACb,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,iBAAiB;AAAA,IACf,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,yBAAyB;AAAA,IACvB,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,iBAAiB;AAAA,IACf,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,iBAAiB;AAAA,IACf,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,uBAAuB;AAAA,IACrB,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,eAAe;AAAA,IACb,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,mCAAmC;AAAA,IACjC,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,wBAAwB;AAAA,IACtB,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,sCAAsC;AAAA,IACpC,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,KAAK;AAAA,EACP;AAAA,EACA,yBAAyB;AAAA,IACvB,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,yBAAyB;AAAA,IACvB,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,iCAAiC;AAAA,IAC/B,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,mCAAmC;AAAA,IACjC,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,8CAA8C;AAAA,IAC5C,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,sCAAsC;AAAA,IACpC,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,4CAA4C;AAAA,IAC1C,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,2BAA2B;AAAA,IACzB,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,uCAAuC;AAAA,IACrC,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,oBAAoB;AAAA,IAClB,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,8BAA8B;AAAA,IAC5B,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,wCAAwC;AAAA,IACtC,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,gCAAgC;AAAA,IAC9B,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,mBAAmB;AAAA,IACjB,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,wBAAwB;AAAA,IACtB,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,yBAAyB;AAAA,IACvB,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,KAAK;AAAA,EACP;AAAA,EACA,6BAA6B;AAAA,IAC3B,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,mCAAmC;AAAA,IACjC,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,KAAK;AAAA,EACP;AAAA,EACA,kCAAkC;AAAA,IAChC,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,KAAK;AAAA,EACP;AAAA,EACA,4BAA4B;AAAA,IAC1B,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,+BAA+B;AAAA,IAC7B,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,+CAA+C;AAAA,IAC7C,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,wBAAwB;AAAA,IACtB,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AACF;AAKO,SAAS,qBAAqB,KAAa,SAAiB,SAAwC;AACzG,QAAM,gBAAgB,IAAI,KAAK,EAAE,YAAY;AAC7C,QAAM,mBAAmB,OAAO,YAAY;AAE5C,MAAI,qBAAqB,QAAQ,iBAAiB,WAAW,KAAK,GAAG;AACnE,WAAO,6BAA6B,aAAa;AAAA,EACnD;AACA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|