@sfmc-bds/bds-tools 0.2.0-beta.13 → 0.2.0-beta.14
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/level-dat.d.ts +21 -3
- package/dist/level-dat.d.ts.map +1 -1
- package/dist/level-dat.js +221 -57
- package/dist/level-dat.js.map +2 -2
- package/dist/level-dat.test.js +50 -3
- package/dist/level-dat.test.js.map +2 -2
- package/dist/world-packs.d.ts +28 -1
- package/dist/world-packs.d.ts.map +1 -1
- package/dist/world-packs.js +93 -16
- package/dist/world-packs.js.map +3 -3
- package/dist/world-packs.test.js +22 -0
- package/dist/world-packs.test.js.map +2 -2
- package/package.json +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/level-dat.test.ts"],
|
|
4
|
-
"sourcesContent": ["import assert from \"node:assert/strict\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport test from \"node:test\";\nimport {\n enableBetaApisInLevelDat,\n parseBedrockLevelDat,\n readLevelDatExperiments,\n TAG_BYTE,\n TAG_COMPOUND,\n TAG_END,\n} from \"./level-dat.js\";\n\nfunction buildMockLevelDat(includeExperiments: boolean, gametestVal?: number): Buffer {\n const rootName = \"\";\n const rootNameBuf = Buffer.from(rootName, \"utf8\");\n\n const childBuffers: Buffer[] = [];\n\n // Random sample tag\n const sampleName = Buffer.from(\"LevelName\", \"utf8\");\n const sampleVal = Buffer.from(\"TestWorld\", \"utf8\");\n const strTag = Buffer.alloc(1 + 2 + sampleName.length + 2 + sampleVal.length);\n strTag.writeUInt8(8, 0); // TAG_String\n strTag.writeUInt16LE(sampleName.length, 1);\n sampleName.copy(strTag, 3);\n strTag.writeUInt16LE(sampleVal.length, 3 + sampleName.length);\n sampleVal.copy(strTag, 5 + sampleName.length);\n childBuffers.push(strTag);\n\n if (includeExperiments) {\n const expName = Buffer.from(\"experiments\", \"utf8\");\n const expChildren: Buffer[] = [];\n\n // experiments_ever_used = 0\n const everUsedName = Buffer.from(\"experiments_ever_used\", \"utf8\");\n const b1 = Buffer.alloc(1 + 2 + everUsedName.length + 1);\n b1.writeUInt8(TAG_BYTE, 0);\n b1.writeUInt16LE(everUsedName.length, 1);\n everUsedName.copy(b1, 3);\n b1.writeInt8(0, 3 + everUsedName.length);\n expChildren.push(b1);\n\n if (gametestVal !== undefined) {\n const gtName = Buffer.from(\"gametest\", \"utf8\");\n const b2 = Buffer.alloc(1 + 2 + gtName.length + 1);\n b2.writeUInt8(TAG_BYTE, 0);\n b2.writeUInt16LE(gtName.length, 1);\n gtName.copy(b2, 3);\n b2.writeInt8(gametestVal, 3 + gtName.length);\n expChildren.push(b2);\n }\n\n expChildren.push(Buffer.from([TAG_END]));\n\n const expHeader = Buffer.alloc(1 + 2 + expName.length);\n expHeader.writeUInt8(TAG_COMPOUND, 0);\n expHeader.writeUInt16LE(expName.length, 1);\n expName.copy(expHeader, 3);\n\n childBuffers.push(Buffer.concat([expHeader, ...expChildren]));\n }\n\n childBuffers.push(Buffer.from([TAG_END]));\n\n const rootHeader = Buffer.alloc(1 + 2 + rootNameBuf.length);\n rootHeader.writeUInt8(TAG_COMPOUND, 0);\n rootHeader.writeUInt16LE(rootNameBuf.length, 1);\n rootNameBuf.copy(rootHeader, 3);\n\n const nbtBody = Buffer.concat([rootHeader, ...childBuffers]);\n\n const fileHeader = Buffer.alloc(8);\n fileHeader.writeUInt32LE(10, 0); // version 10\n fileHeader.writeUInt32LE(nbtBody.length, 4);\n\n return Buffer.concat([fileHeader, nbtBody]);\n}\n\ntest(\"readLevelDatExperiments: correctly reads experiments status\", () => {\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-lvl-test-\"));\n try {\n const file = path.join(tmpDir, \"level.dat\");\n\n // 1. Without gametest\n fs.writeFileSync(file, buildMockLevelDat(true));\n const info1 = readLevelDatExperiments(file);\n assert.ok(info1);\n assert.equal(info1.hasBetaApis, false);\n assert.equal(info1.experimentsEverUsed, false);\n\n // 2. With gametest = 1\n fs.writeFileSync(file, buildMockLevelDat(true, 1));\n const info2 = readLevelDatExperiments(file);\n assert.ok(info2);\n assert.equal(info2.hasBetaApis, true);\n } finally {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n }\n});\n\ntest(\"enableBetaApisInLevelDat: enables gametest and updates header length\", async () => {\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-lvl-test-\"));\n try {\n const file = path.join(tmpDir, \"level.dat\");\n fs.writeFileSync(file, buildMockLevelDat(true));\n\n const res1 = await enableBetaApisInLevelDat(file);\n assert.equal(res1.success, true);\n assert.equal(res1.changed, true);\n assert.ok(res1.backupPath && fs.existsSync(res1.backupPath));\n\n // Check after change\n const info = readLevelDatExperiments(file);\n assert.ok(info);\n assert.equal(info.hasBetaApis, true);\n assert.equal(info.experimentsEverUsed, true);\n assert.equal(info.savedWithToggledExperiments, true);\n\n // Verify header length matches buffer length\n const finalBuf = fs.readFileSync(file);\n const parsed = parseBedrockLevelDat(finalBuf);\n assert.equal(parsed.dataLength, finalBuf.length - 8);\n\n // Idempotency test: second run shouldn't change\n const res2 = await enableBetaApisInLevelDat(file);\n assert.equal(res2.success, true);\n assert.equal(res2.changed, false);\n } finally {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n }\n});\n\ntest(\"
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import assert from \"node:assert/strict\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport test from \"node:test\";\nimport {\n enableBetaApisInLevelDat,\n enableExperimentsInLevelDat,\n KNOWN_EXPERIMENTS,\n parseBedrockLevelDat,\n readLevelDatExperiments,\n resolveExperimentDefinition,\n TAG_BYTE,\n TAG_COMPOUND,\n TAG_END,\n} from \"./level-dat.js\";\n\nfunction buildMockLevelDat(includeExperiments: boolean, gametestVal?: number): Buffer {\n const rootName = \"\";\n const rootNameBuf = Buffer.from(rootName, \"utf8\");\n\n const childBuffers: Buffer[] = [];\n\n // Random sample tag\n const sampleName = Buffer.from(\"LevelName\", \"utf8\");\n const sampleVal = Buffer.from(\"TestWorld\", \"utf8\");\n const strTag = Buffer.alloc(1 + 2 + sampleName.length + 2 + sampleVal.length);\n strTag.writeUInt8(8, 0); // TAG_String\n strTag.writeUInt16LE(sampleName.length, 1);\n sampleName.copy(strTag, 3);\n strTag.writeUInt16LE(sampleVal.length, 3 + sampleName.length);\n sampleVal.copy(strTag, 5 + sampleName.length);\n childBuffers.push(strTag);\n\n if (includeExperiments) {\n const expName = Buffer.from(\"experiments\", \"utf8\");\n const expChildren: Buffer[] = [];\n\n // experiments_ever_used = 0\n const everUsedName = Buffer.from(\"experiments_ever_used\", \"utf8\");\n const b1 = Buffer.alloc(1 + 2 + everUsedName.length + 1);\n b1.writeUInt8(TAG_BYTE, 0);\n b1.writeUInt16LE(everUsedName.length, 1);\n everUsedName.copy(b1, 3);\n b1.writeInt8(0, 3 + everUsedName.length);\n expChildren.push(b1);\n\n if (gametestVal !== undefined) {\n const gtName = Buffer.from(\"gametest\", \"utf8\");\n const b2 = Buffer.alloc(1 + 2 + gtName.length + 1);\n b2.writeUInt8(TAG_BYTE, 0);\n b2.writeUInt16LE(gtName.length, 1);\n gtName.copy(b2, 3);\n b2.writeInt8(gametestVal, 3 + gtName.length);\n expChildren.push(b2);\n }\n\n expChildren.push(Buffer.from([TAG_END]));\n\n const expHeader = Buffer.alloc(1 + 2 + expName.length);\n expHeader.writeUInt8(TAG_COMPOUND, 0);\n expHeader.writeUInt16LE(expName.length, 1);\n expName.copy(expHeader, 3);\n\n childBuffers.push(Buffer.concat([expHeader, ...expChildren]));\n }\n\n childBuffers.push(Buffer.from([TAG_END]));\n\n const rootHeader = Buffer.alloc(1 + 2 + rootNameBuf.length);\n rootHeader.writeUInt8(TAG_COMPOUND, 0);\n rootHeader.writeUInt16LE(rootNameBuf.length, 1);\n rootNameBuf.copy(rootHeader, 3);\n\n const nbtBody = Buffer.concat([rootHeader, ...childBuffers]);\n\n const fileHeader = Buffer.alloc(8);\n fileHeader.writeUInt32LE(10, 0); // version 10\n fileHeader.writeUInt32LE(nbtBody.length, 4);\n\n return Buffer.concat([fileHeader, nbtBody]);\n}\n\ntest(\"readLevelDatExperiments: correctly reads experiments status\", () => {\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-lvl-test-\"));\n try {\n const file = path.join(tmpDir, \"level.dat\");\n\n // 1. Without gametest\n fs.writeFileSync(file, buildMockLevelDat(true));\n const info1 = readLevelDatExperiments(file);\n assert.ok(info1);\n assert.equal(info1.hasBetaApis, false);\n assert.equal(info1.experimentsEverUsed, false);\n assert.equal(info1.knownExperiments.gametest, false);\n assert.equal(info1.knownExperiments.upcoming_creator_features, false);\n\n // 2. With gametest = 1\n fs.writeFileSync(file, buildMockLevelDat(true, 1));\n const info2 = readLevelDatExperiments(file);\n assert.ok(info2);\n assert.equal(info2.hasBetaApis, true);\n assert.equal(info2.knownExperiments.gametest, true);\n } finally {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n }\n});\n\ntest(\"resolveExperimentDefinition: resolves aliases and canonical ids\", () => {\n assert.equal(resolveExperimentDefinition(\"upcoming\")?.id, \"upcoming_creator_features\");\n assert.equal(resolveExperimentDefinition(\"cameras\")?.id, \"experimental_creator_cameras\");\n assert.equal(resolveExperimentDefinition(\"voxel\")?.id, \"voxel_shapes\");\n assert.equal(resolveExperimentDefinition(\"trades\")?.id, \"villager_trades_rebalance\");\n assert.equal(resolveExperimentDefinition(\"drop3\")?.id, \"drop_3_2026\");\n assert.equal(resolveExperimentDefinition(\"wilderness_bound\")?.id, \"drop_3_2026\");\n assert.equal(resolveExperimentDefinition(\"edu\")?.id, \"education\");\n assert.equal(resolveExperimentDefinition(\"unknown_feature\"), null);\n});\n\ntest(\"enableBetaApisInLevelDat: enables gametest and updates header length\", async () => {\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-lvl-test-\"));\n try {\n const file = path.join(tmpDir, \"level.dat\");\n fs.writeFileSync(file, buildMockLevelDat(true));\n\n const res1 = await enableBetaApisInLevelDat(file);\n assert.equal(res1.success, true);\n assert.equal(res1.changed, true);\n assert.ok(res1.backupPath && fs.existsSync(res1.backupPath));\n\n // Check after change\n const info = readLevelDatExperiments(file);\n assert.ok(info);\n assert.equal(info.hasBetaApis, true);\n assert.equal(info.experimentsEverUsed, true);\n assert.equal(info.savedWithToggledExperiments, true);\n\n // Verify header length matches buffer length\n const finalBuf = fs.readFileSync(file);\n const parsed = parseBedrockLevelDat(finalBuf);\n assert.equal(parsed.dataLength, finalBuf.length - 8);\n\n // Idempotency test: second run shouldn't change\n const res2 = await enableBetaApisInLevelDat(file);\n assert.equal(res2.success, true);\n assert.equal(res2.changed, false);\n } finally {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n }\n});\n\ntest(\"enableExperimentsInLevelDat: enables all known experiments and handles education root tag\", async () => {\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-lvl-test-\"));\n try {\n const file = path.join(tmpDir, \"level.dat\");\n fs.writeFileSync(file, buildMockLevelDat(true));\n\n const res = await enableExperimentsInLevelDat(file, \"all\");\n assert.equal(res.success, true);\n assert.equal(res.changed, true);\n\n const info = readLevelDatExperiments(file);\n assert.ok(info);\n assert.equal(info.hasBetaApis, true);\n assert.equal(info.experimentsEverUsed, true);\n assert.equal(info.savedWithToggledExperiments, true);\n\n // All known experiments must be true\n for (const def of KNOWN_EXPERIMENTS) {\n assert.equal(info.knownExperiments[def.id], true, `Experiment ${def.id} should be enabled`);\n }\n\n // Verify root educationFeaturesEnabled is 1\n const finalBuf = fs.readFileSync(file);\n const parsed = parseBedrockLevelDat(finalBuf);\n assert.equal(parsed.dataLength, finalBuf.length - 8);\n\n const eduRoot = parsed.rootChildren.get(\"educationFeaturesEnabled\");\n assert.ok(eduRoot);\n assert.equal(eduRoot.value, 1);\n\n // Second run should be idempotent\n const res2 = await enableExperimentsInLevelDat(file, \"all\");\n assert.equal(res2.success, true);\n assert.equal(res2.changed, false);\n } finally {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n }\n});\n\ntest(\"enableExperimentsInLevelDat: enables specific subset from scratch (no experiments compound)\", async () => {\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-lvl-test-\"));\n try {\n const file = path.join(tmpDir, \"level.dat\");\n fs.writeFileSync(file, buildMockLevelDat(false));\n\n const res = await enableExperimentsInLevelDat(file, [\"upcoming\", \"voxel\", \"edu\"]);\n assert.equal(res.success, true);\n assert.equal(res.changed, true);\n\n const info = readLevelDatExperiments(file);\n assert.ok(info);\n assert.equal(info.knownExperiments.upcoming_creator_features, true);\n assert.equal(info.knownExperiments.voxel_shapes, true);\n assert.equal(info.knownExperiments.education, true);\n assert.equal(info.knownExperiments.gametest, false);\n assert.equal(info.knownExperiments.villager_trades_rebalance, false);\n\n const finalBuf = fs.readFileSync(file);\n const parsed = parseBedrockLevelDat(finalBuf);\n assert.equal(parsed.dataLength, finalBuf.length - 8);\n } finally {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n }\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/world-packs.d.ts
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* - 版本递增与同步:同步升级 manifest 中的版本元数据并对齐世界启用清单版本
|
|
8
8
|
* - 幂等安装与回滚:按 UUID 精确匹配升级与安装计划,支持删除备份至回收站机制
|
|
9
9
|
*/
|
|
10
|
+
import { type LevelDatExperimentsInfo } from "./level-dat.js";
|
|
10
11
|
import { type PackManifestDependency, type WorldPackListReadResult } from "./pack-manager.js";
|
|
12
|
+
export { enableBetaApisInLevelDat, enableExperimentsInLevelDat, KNOWN_EXPERIMENTS, readLevelDatExperiments, resolveExperimentDefinition, type KnownExperimentDefinition, type LevelDatExperimentsInfo, type LevelDatMutateResult, } from "./level-dat.js";
|
|
11
13
|
export type WorldPackKind = "behavior" | "resource";
|
|
12
14
|
export interface PackManifestInfo {
|
|
13
15
|
name: string;
|
|
@@ -61,6 +63,13 @@ export declare function detectPackKindFromManifest(raw: {
|
|
|
61
63
|
type?: string;
|
|
62
64
|
}>;
|
|
63
65
|
}): WorldPackKind | null;
|
|
66
|
+
/**
|
|
67
|
+
* 解析 manifest 中的本地化键(例如 pack.name)。
|
|
68
|
+
*
|
|
69
|
+
* 语言文件优先遵循 texts/languages.json 的声明顺序;声明缺失或不完整时,
|
|
70
|
+
* 再扫描 texts 下其余 .lang 文件。找不到对应键时保留 manifest 原值。
|
|
71
|
+
*/
|
|
72
|
+
export declare function resolvePackLocalizedText(packDir: string, value: string): string;
|
|
64
73
|
export declare function readPackManifestInfo(packDir: string): PackManifestInfo | null;
|
|
65
74
|
/** 深度优先找含 manifest.json 的包根(默认 maxDepth=2,root 自身为 depth 0) */
|
|
66
75
|
export declare function discoverPackRoots(root: string, opts?: {
|
|
@@ -276,6 +285,16 @@ export declare function isBetaApiDependency(dep: PackManifestDependency): boolea
|
|
|
276
285
|
* 诊断指定世界中已启用的行为包对测试版 API(Beta APIs)的依赖与 level.dat 的匹配状况。
|
|
277
286
|
*/
|
|
278
287
|
export declare function checkWorldBetaApiRequirements(bdsRoot: string, levelName: string, installedPacks?: InstalledWorldPack[]): WorldBetaApiDiagnosis;
|
|
288
|
+
export interface WorldExperimentsDiagnosis {
|
|
289
|
+
levelDatExists: boolean;
|
|
290
|
+
levelDatPath: string;
|
|
291
|
+
experimentsInfo: LevelDatExperimentsInfo | null;
|
|
292
|
+
betaApis: WorldBetaApiDiagnosis;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* 诊断指定世界存档的全部实验性玩法开关及与当前已安装行为包的匹配状况。
|
|
296
|
+
*/
|
|
297
|
+
export declare function checkWorldExperimentsDiagnosis(bdsRoot: string, levelName: string, installedPacks?: InstalledWorldPack[]): WorldExperimentsDiagnosis;
|
|
279
298
|
export interface WorldPermissionDiagnosis {
|
|
280
299
|
missingPermissions: Array<{
|
|
281
300
|
pack: InstalledWorldPack;
|
|
@@ -303,6 +322,13 @@ export interface RepairWorldPacksResult {
|
|
|
303
322
|
backupPath?: string | undefined;
|
|
304
323
|
error?: string | undefined;
|
|
305
324
|
} | undefined;
|
|
325
|
+
experimentsResult?: {
|
|
326
|
+
attempted: boolean;
|
|
327
|
+
changed: boolean;
|
|
328
|
+
enabled: string[];
|
|
329
|
+
backupPath?: string | undefined;
|
|
330
|
+
error?: string | undefined;
|
|
331
|
+
} | undefined;
|
|
306
332
|
fixedPermissions?: Array<{
|
|
307
333
|
packName: string;
|
|
308
334
|
moduleName: string;
|
|
@@ -313,9 +339,10 @@ export interface RepairWorldPacksResult {
|
|
|
313
339
|
* 1. 清理清单中已不存在于磁盘的幽灵包 UUID 条目
|
|
314
340
|
* 2. 自动校准清单中与磁盘 manifest 不一致的版本号
|
|
315
341
|
* 3. 自动补齐缺失的 Script API 原生模块权限(config/default/permissions.json)
|
|
316
|
-
* 4. 可选:自动为 level.dat 开启 Beta APIs(若 fixBetaApis 为 true)
|
|
342
|
+
* 4. 可选:自动为 level.dat 开启 Beta APIs(若 fixBetaApis 为 true)或指定实验性功能(enableExperiments)
|
|
317
343
|
*/
|
|
318
344
|
export declare function repairWorldPacksWiring(bdsRoot: string, levelName: string, opts?: {
|
|
319
345
|
fixBetaApis?: boolean;
|
|
346
|
+
enableExperiments?: string[] | "all";
|
|
320
347
|
}): Promise<RepairWorldPacksResult>;
|
|
321
348
|
//# sourceMappingURL=world-packs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"world-packs.d.ts","sourceRoot":"","sources":["../src/world-packs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,EAYL,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC7B,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"world-packs.d.ts","sourceRoot":"","sources":["../src/world-packs.ts"],"names":[],"mappings":"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"}
|
package/dist/world-packs.js
CHANGED
|
@@ -2,21 +2,28 @@ import fs from "node:fs";
|
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { copyDirAsync, readJsonFile } from "./fsx.js";
|
|
5
|
+
import { enableExperimentsInLevelDat, readLevelDatExperiments } from "./level-dat.js";
|
|
5
6
|
import {
|
|
6
7
|
bdsWorldLevelDir,
|
|
7
8
|
bdsWorldsDir,
|
|
8
9
|
disablePackInWorld,
|
|
9
10
|
enablePackInWorld,
|
|
10
11
|
ensureConfigPermission,
|
|
12
|
+
isGametestBetaRequired,
|
|
11
13
|
levelDatPath,
|
|
12
14
|
readPackManifestDependencies,
|
|
13
15
|
readPackManifestHeader,
|
|
14
16
|
readWorldPackList,
|
|
15
|
-
readWorldPackListResult
|
|
16
|
-
isGametestBetaRequired
|
|
17
|
+
readWorldPackListResult
|
|
17
18
|
} from "./pack-manager.js";
|
|
18
|
-
import { enableBetaApisInLevelDat, readLevelDatExperiments } from "./level-dat.js";
|
|
19
19
|
import { extractZipFileToDir } from "./zipx.js";
|
|
20
|
+
import {
|
|
21
|
+
enableBetaApisInLevelDat,
|
|
22
|
+
enableExperimentsInLevelDat as enableExperimentsInLevelDat2,
|
|
23
|
+
KNOWN_EXPERIMENTS,
|
|
24
|
+
readLevelDatExperiments as readLevelDatExperiments2,
|
|
25
|
+
resolveExperimentDefinition
|
|
26
|
+
} from "./level-dat.js";
|
|
20
27
|
const ARCHIVE_EXTS = [".zip", ".mcpack", ".mcaddon"];
|
|
21
28
|
function formatWorldPackFolderName(rawName, kind) {
|
|
22
29
|
let s = String(rawName ?? "");
|
|
@@ -69,6 +76,50 @@ function detectPackKindFromManifest(raw) {
|
|
|
69
76
|
if (types.some((t) => t === "script" || t === "data" || t === "javascript")) return "behavior";
|
|
70
77
|
return null;
|
|
71
78
|
}
|
|
79
|
+
function resolvePackLocalizedText(packDir, value) {
|
|
80
|
+
const textsDir = path.join(packDir, "texts");
|
|
81
|
+
if (!value || !fs.existsSync(textsDir)) return value;
|
|
82
|
+
const languageFiles = [];
|
|
83
|
+
const seen = /* @__PURE__ */ new Set();
|
|
84
|
+
const addLanguageFile = (fileName) => {
|
|
85
|
+
const normalized = path.basename(fileName);
|
|
86
|
+
if (!normalized.toLowerCase().endsWith(".lang") || seen.has(normalized.toLowerCase())) return;
|
|
87
|
+
seen.add(normalized.toLowerCase());
|
|
88
|
+
languageFiles.push(path.join(textsDir, normalized));
|
|
89
|
+
};
|
|
90
|
+
try {
|
|
91
|
+
const declared = readJsonFile(path.join(textsDir, "languages.json"));
|
|
92
|
+
if (Array.isArray(declared)) {
|
|
93
|
+
for (const locale of declared) {
|
|
94
|
+
if (typeof locale === "string" && locale.trim()) addLanguageFile(`${locale.trim()}.lang`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
} catch {
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
for (const entry of fs.readdirSync(textsDir, { withFileTypes: true })) {
|
|
101
|
+
if (entry.isFile()) addLanguageFile(entry.name);
|
|
102
|
+
}
|
|
103
|
+
} catch {
|
|
104
|
+
return value;
|
|
105
|
+
}
|
|
106
|
+
for (const file of languageFiles) {
|
|
107
|
+
if (!fs.existsSync(file)) continue;
|
|
108
|
+
try {
|
|
109
|
+
const lines = fs.readFileSync(file, "utf8").replace(/^\uFEFF/, "").split(/\r?\n/);
|
|
110
|
+
for (const line of lines) {
|
|
111
|
+
const trimmed = line.trimStart();
|
|
112
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
113
|
+
const separator = line.indexOf("=");
|
|
114
|
+
if (separator < 0 || line.slice(0, separator).trim() !== value) continue;
|
|
115
|
+
const localized = line.slice(separator + 1).trim();
|
|
116
|
+
if (localized) return localized;
|
|
117
|
+
}
|
|
118
|
+
} catch {
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return value;
|
|
122
|
+
}
|
|
72
123
|
function readPackManifestInfo(packDir) {
|
|
73
124
|
const file = path.join(packDir, "manifest.json");
|
|
74
125
|
if (!fs.existsSync(file)) return null;
|
|
@@ -83,11 +134,11 @@ function readPackManifestInfo(packDir) {
|
|
|
83
134
|
const version = [Number(ver[0]), Number(ver[1]), Number(ver[2])];
|
|
84
135
|
const description = raw.header?.description;
|
|
85
136
|
return {
|
|
86
|
-
name,
|
|
137
|
+
name: resolvePackLocalizedText(packDir, name),
|
|
87
138
|
uuid,
|
|
88
139
|
version,
|
|
89
140
|
kind,
|
|
90
|
-
...typeof description === "string" ? { description } : {}
|
|
141
|
+
...typeof description === "string" ? { description: resolvePackLocalizedText(packDir, description) } : {}
|
|
91
142
|
};
|
|
92
143
|
} catch {
|
|
93
144
|
return null;
|
|
@@ -257,10 +308,7 @@ function listInstalledWorldPacks(bdsRoot, levelName) {
|
|
|
257
308
|
const worldsDir = bdsWorldsDir(bdsRoot);
|
|
258
309
|
const result = [];
|
|
259
310
|
for (const kind of ["behavior", "resource"]) {
|
|
260
|
-
const parent = path.join(
|
|
261
|
-
worldRoot,
|
|
262
|
-
kind === "behavior" ? "behavior_packs" : "resource_packs"
|
|
263
|
-
);
|
|
311
|
+
const parent = path.join(worldRoot, kind === "behavior" ? "behavior_packs" : "resource_packs");
|
|
264
312
|
const enabledList = readWorldPackList(worldsDir, levelName, kind);
|
|
265
313
|
const enabledMap = new Map(enabledList.map((e) => [e.pack_id, e.version]));
|
|
266
314
|
for (const dir of listPackDirsIn(parent)) {
|
|
@@ -530,10 +578,7 @@ async function uninstallInstalledPack(opts) {
|
|
|
530
578
|
return { action: "deleted" };
|
|
531
579
|
}
|
|
532
580
|
function worldPackParentDir(bdsRoot, levelName, kind) {
|
|
533
|
-
return path.join(
|
|
534
|
-
bdsWorldLevelDir(bdsRoot, levelName),
|
|
535
|
-
kind === "behavior" ? "behavior_packs" : "resource_packs"
|
|
536
|
-
);
|
|
581
|
+
return path.join(bdsWorldLevelDir(bdsRoot, levelName), kind === "behavior" ? "behavior_packs" : "resource_packs");
|
|
537
582
|
}
|
|
538
583
|
function listWorldEnableEntries(bdsRoot, levelName, kind) {
|
|
539
584
|
return listWorldEnableListResult(bdsRoot, levelName, kind).entries;
|
|
@@ -575,6 +620,16 @@ function checkWorldBetaApiRequirements(bdsRoot, levelName, installedPacks) {
|
|
|
575
620
|
requiringPacks
|
|
576
621
|
};
|
|
577
622
|
}
|
|
623
|
+
function checkWorldExperimentsDiagnosis(bdsRoot, levelName, installedPacks) {
|
|
624
|
+
const betaApis = checkWorldBetaApiRequirements(bdsRoot, levelName, installedPacks);
|
|
625
|
+
const info = betaApis.levelDatExists ? readLevelDatExperiments(betaApis.levelDatPath) : null;
|
|
626
|
+
return {
|
|
627
|
+
levelDatExists: betaApis.levelDatExists,
|
|
628
|
+
levelDatPath: betaApis.levelDatPath,
|
|
629
|
+
experimentsInfo: info,
|
|
630
|
+
betaApis
|
|
631
|
+
};
|
|
632
|
+
}
|
|
578
633
|
function checkWorldScriptPermissions(bdsRoot, levelName, installedPacks) {
|
|
579
634
|
const packs = installedPacks ?? listInstalledWorldPacks(bdsRoot, levelName);
|
|
580
635
|
const defaultFile = path.join(bdsRoot, "config", "default", "permissions.json");
|
|
@@ -661,15 +716,27 @@ async function repairWorldPacksWiring(bdsRoot, levelName, opts) {
|
|
|
661
716
|
}
|
|
662
717
|
}
|
|
663
718
|
let betaApisResult = void 0;
|
|
664
|
-
|
|
719
|
+
let experimentsResult = void 0;
|
|
720
|
+
const shouldMutateExperiments = !!opts?.enableExperiments || !!opts?.fixBetaApis;
|
|
721
|
+
if (shouldMutateExperiments) {
|
|
665
722
|
const lPath = levelDatPath(bdsRoot, levelName);
|
|
666
|
-
const
|
|
667
|
-
|
|
723
|
+
const targets = opts?.enableExperiments ?? (opts?.fixBetaApis ? ["gametest"] : []);
|
|
724
|
+
const mutateRes = await enableExperimentsInLevelDat(lPath, targets);
|
|
725
|
+
experimentsResult = {
|
|
668
726
|
attempted: true,
|
|
669
727
|
changed: mutateRes.changed,
|
|
728
|
+
enabled: mutateRes.enabledExperiments ?? [],
|
|
670
729
|
...mutateRes.backupPath ? { backupPath: mutateRes.backupPath } : {},
|
|
671
730
|
...mutateRes.error ? { error: mutateRes.error } : {}
|
|
672
731
|
};
|
|
732
|
+
if (opts?.fixBetaApis) {
|
|
733
|
+
betaApisResult = {
|
|
734
|
+
attempted: true,
|
|
735
|
+
changed: mutateRes.changed,
|
|
736
|
+
...mutateRes.backupPath ? { backupPath: mutateRes.backupPath } : {},
|
|
737
|
+
...mutateRes.error ? { error: mutateRes.error } : {}
|
|
738
|
+
};
|
|
739
|
+
}
|
|
673
740
|
}
|
|
674
741
|
const permDiag = checkWorldScriptPermissions(bdsRoot, levelName, packs);
|
|
675
742
|
let fixedPermissions = void 0;
|
|
@@ -691,16 +758,21 @@ async function repairWorldPacksWiring(bdsRoot, levelName, opts) {
|
|
|
691
758
|
if (betaApisResult) {
|
|
692
759
|
result.betaApisResult = betaApisResult;
|
|
693
760
|
}
|
|
761
|
+
if (experimentsResult) {
|
|
762
|
+
result.experimentsResult = experimentsResult;
|
|
763
|
+
}
|
|
694
764
|
if (fixedPermissions && fixedPermissions.length > 0) {
|
|
695
765
|
result.fixedPermissions = fixedPermissions;
|
|
696
766
|
}
|
|
697
767
|
return result;
|
|
698
768
|
}
|
|
699
769
|
export {
|
|
770
|
+
KNOWN_EXPERIMENTS,
|
|
700
771
|
allocatePackFolderName,
|
|
701
772
|
bumpPackPatchVersion,
|
|
702
773
|
bumpSemVer3,
|
|
703
774
|
checkWorldBetaApiRequirements,
|
|
775
|
+
checkWorldExperimentsDiagnosis,
|
|
704
776
|
checkWorldScriptPermissions,
|
|
705
777
|
choosePackInstallFolderName,
|
|
706
778
|
compareSemVer3,
|
|
@@ -708,6 +780,8 @@ export {
|
|
|
708
780
|
detectPackKindFromManifest,
|
|
709
781
|
disableInstalledPack,
|
|
710
782
|
discoverPackRoots,
|
|
783
|
+
enableBetaApisInLevelDat,
|
|
784
|
+
enableExperimentsInLevelDat2 as enableExperimentsInLevelDat,
|
|
711
785
|
enableInstalledPack,
|
|
712
786
|
ensureVersionGreaterThan,
|
|
713
787
|
expandNestedArchivesInPlace,
|
|
@@ -724,10 +798,13 @@ export {
|
|
|
724
798
|
listWorldEnableListResult,
|
|
725
799
|
maxSemVer3,
|
|
726
800
|
nextEnabledVersion,
|
|
801
|
+
readLevelDatExperiments2 as readLevelDatExperiments,
|
|
727
802
|
readPackDependencyUuids,
|
|
728
803
|
readPackDirOccupancy,
|
|
729
804
|
readPackManifestInfo,
|
|
730
805
|
repairWorldPacksWiring,
|
|
806
|
+
resolveExperimentDefinition,
|
|
807
|
+
resolvePackLocalizedText,
|
|
731
808
|
resolvePackRoots,
|
|
732
809
|
scanDestOccupancy,
|
|
733
810
|
stripWorldPackFolderPrefix,
|