@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
package/dist/world-packs.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/world-packs.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * world-packs.ts \u2014 \u901A\u7528 Minecraft \u57FA\u5CA9\u7248\u4E16\u754C\u884C\u4E3A\u5305\uFF08BP\uFF09\u4E0E\u8D44\u6E90\u5305\uFF08RP\uFF09\u7BA1\u7406\u5DE5\u5177\n *\n * \u6838\u5FC3\u80FD\u529B\uFF1A\n * - \u683C\u5F0F\u4E0E\u547D\u540D\u89C4\u8303\u5316\uFF1A\u8FC7\u6EE4 Minecraft \u989C\u8272\u683C\u5F0F\u7801\uFF0C\u81EA\u52A8\u8865\u5145 `[BP]` / `[RP]` \u524D\u7F00\u53CA\u51B2\u7A81\u907F\u8BA9\n * - \u538B\u7F29\u5305\u9012\u5F52\u89E3\u6784\uFF1A\u652F\u6301 `.zip`\u3001`.mcpack`\u3001`.mcaddon` \u5D4C\u5957\u5305\u89E3\u538B\u5E76\u667A\u80FD\u8BC6\u522B BP \u4E0E RP \u6839\u76EE\u5F55\n * - \u7248\u672C\u9012\u589E\u4E0E\u540C\u6B65\uFF1A\u540C\u6B65\u5347\u7EA7 manifest \u4E2D\u7684\u7248\u672C\u5143\u6570\u636E\u5E76\u5BF9\u9F50\u4E16\u754C\u542F\u7528\u6E05\u5355\u7248\u672C\n * - \u5E42\u7B49\u5B89\u88C5\u4E0E\u56DE\u6EDA\uFF1A\u6309 UUID \u7CBE\u786E\u5339\u914D\u5347\u7EA7\u4E0E\u5B89\u88C5\u8BA1\u5212\uFF0C\u652F\u6301\u5220\u9664\u5907\u4EFD\u81F3\u56DE\u6536\u7AD9\u673A\u5236\n */\n\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { copyDirAsync, readJsonFile } from \"./fsx.js\";\nimport {\n bdsWorldLevelDir,\n bdsWorldsDir,\n disablePackInWorld,\n enablePackInWorld,\n ensureConfigPermission,\n levelDatPath,\n readPackManifestDependencies,\n readPackManifestHeader,\n readWorldPackList,\n readWorldPackListResult,\n isGametestBetaRequired,\n type PackManifestDependency,\n type WorldPackListReadResult,\n} from \"./pack-manager.js\";\nimport { enableBetaApisInLevelDat, readLevelDatExperiments } from \"./level-dat.js\";\nimport { extractZipFileToDir } from \"./zipx.js\";\n\nexport type WorldPackKind = \"behavior\" | \"resource\";\n\nexport interface PackManifestInfo {\n name: string;\n uuid: string;\n version: [number, number, number];\n kind: WorldPackKind;\n description?: string;\n}\n\nexport interface InstalledWorldPack {\n kind: WorldPackKind;\n folderName: string;\n dir: string;\n name: string;\n uuid: string;\n version: [number, number, number];\n enabled: boolean;\n}\n\nconst ARCHIVE_EXTS = [\".zip\", \".mcpack\", \".mcaddon\"] as const;\n\n/** \u6EE4\u6389 \u00A7x\uFF08Minecraft \u683C\u5F0F\u7801\uFF09\u3001\u6B8B\u4F59\u538B\u7F29\u540E\u7F00\uFF0C\u52A0 [BP]/[RP] \u524D\u7F00 */\nexport function formatWorldPackFolderName(rawName: string, kind: WorldPackKind): string {\n let s = String(rawName ?? \"\");\n s = s.replace(/\u00A7[0-9a-zA-Z]/g, \"\");\n s = s.replace(/\\.(zip|mcpack|mcaddon)$/i, \"\");\n s = s.replace(/\\s+/g, \" \").trim();\n if (!s) s = \"pack\";\n const prefix = kind === \"resource\" ? \"[RP]\" : \"[BP]\";\n if (s.startsWith(\"[RP]\") || s.startsWith(\"[BP]\")) return s;\n return `${prefix} ${s}`;\n}\n\n/** \u53BB\u6389\u5DF2\u6709 [BP]/[RP] \u524D\u7F00\uFF0C\u5F97\u5230\u6587\u4EF6\u5939\u540D\u4E3B\u5E72 */\nexport function stripWorldPackFolderPrefix(rawName: string): string {\n return String(rawName ?? \"\")\n .replace(/^\\[BP\\]\\s*/i, \"\")\n .replace(/^\\[RP\\]\\s*/i, \"\")\n .replace(/\\.(zip|mcpack|mcaddon)$/i, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\n/**\n * \u5F52\u6863\u5185\u5E38\u89C1\u5360\u4F4D\u76EE\u5F55\u540D\uFF08B / R / BP / RP\uFF09\u8FC7\u77ED\u6216\u8FC7\u6CDB\uFF0C\u4E0D\u80FD\u4F5C\u4E3A\u4E16\u754C\u76EE\u5F55\u540D\uFF0C\n * \u5426\u5219\u4E0D\u540C\u5305\u4F1A\u649E\u5230\u540C\u4E00\u8DEF\u5F84\u5E76\u88AB\u8BEF\u5224\u4E3A\u300C\u8986\u76D6\u300D\u3002\n */\nexport function isGenericPackFolderStem(rawName: string): boolean {\n const s = stripWorldPackFolderPrefix(rawName);\n if (!s) return true;\n if (s.length <= 2) return true;\n return /^(bp|rp|b|r|pack|packs|behavior|behaviours?|resource|resources)$/i.test(s);\n}\n\n/**\n * \u9009\u5B9A\u5B89\u88C5\u6587\u4EF6\u5939\u540D\uFF1Ahint \u8FC7\u6CDB\u65F6\u6539\u7528 manifest.name\uFF1B\u518D\u4E0E\u5DF2\u5360\u7528\u540D\u907F\u8BA9\uFF08\u4E0D\u540C uuid \u4E0D\u4E92\u76F8\u8986\u76D6\uFF09\u3002\n * \u7EAF\u51FD\u6570\uFF1A\u53EA\u4F9D\u8D56 taken \u96C6\u5408\uFF0C\u4FBF\u4E8E\u8868\u9A71\u52A8\u5355\u6D4B\uFF08DRY\uFF1Adecide / choose \u5171\u7528\uFF09\u3002\n */\nexport function allocatePackFolderName(opts: {\n hint?: string;\n info: PackManifestInfo;\n takenFolderNames: Iterable<string>;\n /** \u540C uuid \u66F4\u65B0\u65F6\u5141\u8BB8\u5360\u7528\u7684\u5DF2\u6709\u76EE\u5F55\u540D\uFF08\u4E0D\u89E6\u53D1\u907F\u8BA9\uFF09 */\n allowFolderName?: string;\n}): string {\n const hint = (opts.hint && opts.hint.trim()) || \"\";\n const preferred = isGenericPackFolderStem(hint) ? opts.info.name || hint || \"pack\" : hint;\n let folderName = formatWorldPackFolderName(preferred, opts.info.kind);\n const allow = opts.allowFolderName ? path.basename(opts.allowFolderName) : null;\n if (allow && folderName === allow) return folderName;\n\n const taken = new Set([...opts.takenFolderNames].filter((n) => n !== allow));\n if (!taken.has(folderName)) return folderName;\n\n /* \u540C\u540D\u4E0D\u540C\u5305\uFF1Amanifest \u540D + uuid \u524D\u7F00\uFF1B\u4ECD\u649E\u5219\u9012\u589E */\n const withUuid = formatWorldPackFolderName(\n `${stripWorldPackFolderPrefix(preferred)} ${opts.info.uuid.slice(0, 8)}`,\n opts.info.kind\n );\n if (!taken.has(withUuid)) return withUuid;\n let i = 2;\n while (taken.has(`${withUuid}_${i}`)) i++;\n return `${withUuid}_${i}`;\n}\n\n/**\n * \u9009\u5B9A\u5B89\u88C5\u6587\u4EF6\u5939\u540D\uFF08\u8BFB destParent \u5360\u7528\uFF09\u3002\n * \u51B3\u7B56\u6743\u5A01\u89C1 allocatePackFolderName / decidePackInstallPlan\u3002\n */\nexport function choosePackInstallFolderName(opts: {\n hint?: string;\n info: PackManifestInfo;\n destParent: string;\n allowFolderName?: string;\n}): string {\n const taken = listPackDirsIn(opts.destParent).map((d) => path.basename(d));\n return allocatePackFolderName({\n info: opts.info,\n takenFolderNames: taken,\n ...(opts.hint !== undefined ? { hint: opts.hint } : {}),\n ...(opts.allowFolderName !== undefined ? { allowFolderName: opts.allowFolderName } : {}),\n });\n}\n\n/** \u6839\u636E manifest modules[].type \u5224\u5B9A BP / RP */\nexport function detectPackKindFromManifest(raw: {\n modules?: Array<{ type?: string }>;\n}): WorldPackKind | null {\n const types = (raw.modules ?? []).map((m) => String(m.type ?? \"\").toLowerCase());\n if (types.includes(\"resources\")) return \"resource\";\n if (types.some((t) => t === \"script\" || t === \"data\" || t === \"javascript\")) return \"behavior\";\n return null;\n}\n\nexport function readPackManifestInfo(packDir: string): PackManifestInfo | null {\n const file = path.join(packDir, \"manifest.json\");\n if (!fs.existsSync(file)) return null;\n try {\n const raw = readJsonFile<{\n header?: { name?: string; uuid?: string; version?: number[]; description?: string };\n modules?: Array<{ type?: string }>;\n }>(file);\n const kind = detectPackKindFromManifest(raw);\n const uuid = raw.header?.uuid;\n const ver = raw.header?.version;\n const name = raw.header?.name;\n if (!kind || typeof uuid !== \"string\" || !Array.isArray(ver) || ver.length < 3) return null;\n if (typeof name !== \"string\" || !name) return null;\n const version: [number, number, number] = [Number(ver[0]), Number(ver[1]), Number(ver[2])];\n const description = raw.header?.description;\n return {\n name,\n uuid,\n version,\n kind,\n ...(typeof description === \"string\" ? { description } : {}),\n };\n } catch {\n return null;\n }\n}\n\n/** \u6DF1\u5EA6\u4F18\u5148\u627E\u542B manifest.json \u7684\u5305\u6839\uFF08\u9ED8\u8BA4 maxDepth=2\uFF0Croot \u81EA\u8EAB\u4E3A depth 0\uFF09 */\nexport function discoverPackRoots(root: string, opts?: { maxDepth?: number }): string[] {\n const maxDepth = opts?.maxDepth ?? 2;\n const out: string[] = [];\n const abs = path.resolve(root);\n if (!fs.existsSync(abs)) return out;\n\n function walk(dir: string, depth: number): void {\n const manifest = path.join(dir, \"manifest.json\");\n if (fs.existsSync(manifest) && fs.statSync(manifest).isFile()) {\n out.push(dir);\n return; // \u5305\u6839\u4E0D\u518D\u4E0B\u94BB\n }\n if (depth >= maxDepth) return;\n let entries;\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const e of entries) {\n if (!e.isDirectory()) continue;\n if (e.name.startsWith(\".\") || e.name === \"node_modules\") continue;\n walk(path.join(dir, e.name), depth + 1);\n }\n }\n\n const st = fs.statSync(abs);\n if (st.isDirectory()) walk(abs, 0);\n return out;\n}\n\nexport function isPackArchive(filePath: string): boolean {\n const lower = filePath.toLowerCase();\n return ARCHIVE_EXTS.some((ext) => lower.endsWith(ext));\n}\n\n/** \u53BB\u6389 .zip/.mcpack/.mcaddon \u540E\u7F00\u5F97\u5230 stem */\nfunction archiveStem(filePath: string): string {\n const base = path.basename(filePath);\n const lower = base.toLowerCase();\n for (const ext of ARCHIVE_EXTS) {\n if (lower.endsWith(ext)) return base.slice(0, -ext.length);\n }\n return path.parse(base).name;\n}\n\n/** \u5F52\u6863\u89E3\u538B\u76EE\u6807\uFF1A\u540C\u7EA7 stem \u76EE\u5F55\uFF1B\u91CD\u540D\u5219\u52A0 _2/_3\u2026 */\nfunction uniqueSiblingExtractDir(archivePath: string): string {\n const parent = path.dirname(archivePath);\n let dest = path.join(parent, archiveStem(archivePath) || \"pack\");\n if (!fs.existsSync(dest)) return dest;\n let i = 2;\n while (fs.existsSync(`${dest}_${i}`)) i++;\n return `${dest}_${i}`;\n}\n\n/**\n * \u5217\u51FA\u76EE\u5F55\u6811\u5185\u7684\u5305\u5F52\u6863\u6587\u4EF6\u3002\n * \u5DF2\u662F\u5305\u6839\uFF08\u542B manifest.json\uFF09\u7684\u76EE\u5F55\u4E0D\u518D\u4E0B\u94BB\uFF0C\u907F\u514D\u8BEF\u89E3\u538B\u5305\u5185\u8D44\u6E90\u3002\n */\nexport function listPackArchiveFiles(root: string, opts?: { maxDepth?: number }): string[] {\n const maxDepth = opts?.maxDepth ?? 4;\n const out: string[] = [];\n const abs = path.resolve(root);\n if (!fs.existsSync(abs) || !fs.statSync(abs).isDirectory()) return out;\n\n function walk(dir: string, depth: number): void {\n if (fs.existsSync(path.join(dir, \"manifest.json\"))) return;\n let entries;\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const e of entries) {\n if (e.name.startsWith(\".\") || e.name === \"node_modules\") continue;\n const full = path.join(dir, e.name);\n if (e.isFile() && isPackArchive(full)) {\n out.push(full);\n continue;\n }\n if (e.isDirectory() && depth < maxDepth) walk(full, depth + 1);\n }\n }\n\n walk(abs, 0);\n return out;\n}\n\n/**\n * \u5728\u4E34\u65F6\u6811\u5185\u539F\u5730\u5C55\u5F00\u5D4C\u5957\u5F52\u6863\uFF1A\u89E3\u538B\u5230\u540C\u7EA7\u76EE\u5F55\u5E76\u5220\u9664\u5F52\u6863\u6587\u4EF6\uFF0C\u591A\u8F6E\u76F4\u81F3\u6CA1\u6709\u65B0\u5F52\u6863\u3002\n * \u4EC5\u5E94\u5BF9\u6211\u4EEC\u81EA\u5DF1\u7684 staging\uFF0C\u7981\u6B62\u7528\u4E8E\u7528\u6237 inbox \u539F\u76EE\u5F55\u3002\n */\nexport async function expandNestedArchivesInPlace(\n workDir: string,\n opts?: { maxRounds?: number; maxScanDepth?: number }\n): Promise<number> {\n const maxRounds = opts?.maxRounds ?? 3;\n const maxScanDepth = opts?.maxScanDepth ?? 4;\n let expanded = 0;\n for (let round = 0; round < maxRounds; round++) {\n const archives = listPackArchiveFiles(workDir, { maxDepth: maxScanDepth });\n if (archives.length === 0) break;\n for (const arch of archives) {\n const dest = uniqueSiblingExtractDir(arch);\n await fs.promises.mkdir(dest, { recursive: true });\n await extractZipFileToDir(arch, dest);\n await fs.promises.unlink(arch);\n expanded++;\n }\n }\n return expanded;\n}\n\nexport type ResolvePackRootsResult = {\n roots: string[];\n /** \u6E05\u7406\u672C\u8F6E\u521B\u5EFA\u7684\u5168\u90E8\u4E34\u65F6\u76EE\u5F55\uFF08\u53EF\u5B89\u5168\u591A\u6B21\u8C03\u7528\uFF09 */\n dispose: () => void;\n};\n\n/**\n * \u7EDF\u4E00\u5305\u6839\u89E3\u6790\uFF1A\u76EE\u5F55 / \u9876\u5C42\u5F52\u6863 / \u5D4C\u5957 .mcpack|.zip|.mcaddon\u3002\n * \u89C4\u5219\uFF1A\u5148\u5C55\u5F00\u5F52\u6863\u4E3A\u76EE\u5F55\u6811\uFF0C\u518D\u53EA\u8BA4\u542B manifest.json \u7684\u76EE\u5F55\u4E3A\u5305\u6839\u3002\n * \u7528\u6237\u76EE\u5F55\u5185\u7684\u5D4C\u5957\u5F52\u6863\u89E3\u5230\u72EC\u7ACB temp\uFF0C\u4E0D\u4FEE\u6539\u539F\u76EE\u5F55\u3002\n */\nexport async function resolvePackRoots(\n src: string,\n opts?: { maxDirDepth?: number; maxArchiveRounds?: number }\n): Promise<ResolvePackRootsResult> {\n const maxDirDepth = opts?.maxDirDepth ?? 4;\n const maxArchiveRounds = opts?.maxArchiveRounds ?? 3;\n const temps: string[] = [];\n const dispose = (): void => {\n for (const d of temps.splice(0, temps.length)) {\n try {\n fs.rmSync(d, { recursive: true, force: true });\n } catch {\n /* ignore */\n }\n }\n };\n\n const abs = path.resolve(src);\n if (!fs.existsSync(abs)) return { roots: [], dispose };\n\n try {\n const st = fs.statSync(abs);\n if (st.isFile()) {\n if (!isPackArchive(abs)) return { roots: [], dispose };\n const tmp = await extractArchiveToTemp(abs);\n temps.push(tmp);\n await expandNestedArchivesInPlace(tmp, {\n maxRounds: maxArchiveRounds,\n maxScanDepth: maxDirDepth,\n });\n return { roots: discoverPackRoots(tmp, { maxDepth: maxDirDepth }), dispose };\n }\n\n if (!st.isDirectory()) return { roots: [], dispose };\n\n const nestedArchives = listPackArchiveFiles(abs, { maxDepth: maxDirDepth });\n if (nestedArchives.length === 0) {\n return { roots: discoverPackRoots(abs, { maxDepth: maxDirDepth }), dispose };\n }\n\n /* \u76EE\u5F55\u5305\u6839 + \u5404\u5D4C\u5957\u5F52\u6863\u5404\u81EA\u89E3\u5230 temp\uFF08\u4E0D\u6539\u7528\u6237\u76EE\u5F55\uFF09 */\n const roots = discoverPackRoots(abs, { maxDepth: maxDirDepth });\n const seen = new Set(roots.map((r) => path.resolve(r)));\n for (const arch of nestedArchives) {\n const tmp = await extractArchiveToTemp(arch);\n temps.push(tmp);\n await expandNestedArchivesInPlace(tmp, {\n maxRounds: maxArchiveRounds,\n maxScanDepth: maxDirDepth,\n });\n for (const r of discoverPackRoots(tmp, { maxDepth: maxDirDepth })) {\n const key = path.resolve(r);\n if (seen.has(key)) continue;\n seen.add(key);\n roots.push(r);\n }\n }\n return { roots, dispose };\n } catch (e) {\n dispose();\n throw e;\n }\n}\n\n/** \u89E3\u538B zip/mcpack/mcaddon \u5230\u4E34\u65F6\u76EE\u5F55\uFF0C\u8FD4\u56DE\u8BE5\u76EE\u5F55\uFF08\u7ECF zipx \u9632 zip-slip\uFF09 */\nexport async function extractArchiveToTemp(filePath: string): Promise<string> {\n const tmp = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-pack-\"));\n await extractZipFileToDir(filePath, tmp);\n return tmp;\n}\n\nfunction listPackDirsIn(parent: string): string[] {\n if (!fs.existsSync(parent)) return [];\n const out: string[] = [];\n for (const e of fs.readdirSync(parent, { withFileTypes: true })) {\n if (!e.isDirectory()) continue;\n const dir = path.join(parent, e.name);\n if (fs.existsSync(path.join(dir, \"manifest.json\"))) out.push(dir);\n }\n return out;\n}\n\n/** \u626B\u63CF\u4E16\u754C\u5185\u5DF2\u5B89\u88C5 BP/RP \u76EE\u5F55 */\nexport function listInstalledWorldPacks(bdsRoot: string, levelName: string): InstalledWorldPack[] {\n const worldRoot = bdsWorldLevelDir(bdsRoot, levelName);\n const worldsDir = bdsWorldsDir(bdsRoot);\n const result: InstalledWorldPack[] = [];\n\n for (const kind of [\"behavior\", \"resource\"] as const) {\n const parent = path.join(\n worldRoot,\n kind === \"behavior\" ? \"behavior_packs\" : \"resource_packs\"\n );\n const enabledList = readWorldPackList(worldsDir, levelName, kind);\n const enabledMap = new Map(enabledList.map((e) => [e.pack_id, e.version] as const));\n\n for (const dir of listPackDirsIn(parent)) {\n const info = readPackManifestInfo(dir);\n if (!info || info.kind !== kind) {\n // \u4ECD\u5C1D\u8BD5\u7528 header \u5C55\u793A\uFF08enabled \u4E0E\u6B63\u5E38\u8DEF\u5F84\u540C\u5951\u7EA6\uFF1Aenable-list \u542B uuid \u2192 LSP\uFF09\n const header = readPackManifestHeader(dir);\n if (!header) continue;\n result.push({\n kind,\n folderName: path.basename(dir),\n dir,\n name: path.basename(dir),\n uuid: header.uuid,\n version: header.version,\n enabled: enabledMap.has(header.uuid),\n });\n continue;\n }\n result.push({\n kind: info.kind,\n folderName: path.basename(dir),\n dir,\n name: info.name,\n uuid: info.uuid,\n version: info.version,\n enabled: enabledMap.has(info.uuid),\n });\n }\n }\n return result;\n}\n\n/**\n * \u5C06\u76EE\u6807\u5305 manifest.json \u4E2D\u7684 Patch \u7248\u672C\u53F7\u9012\u589E\uFF08+1\uFF09\u5E76\u6301\u4E45\u5316\u5199\u56DE\u3002\n *\n * @param packDir \u5305\u6839\u76EE\u5F55\u8DEF\u5F84\u3002\n * @returns \u9012\u589E\u540E\u7684\u7248\u672C\u4E09\u5143\u7EC4 `[major, minor, patch]`\u3002\n */\nexport function bumpPackPatchVersion(packDir: string): [number, number, number] {\n const file = path.join(packDir, \"manifest.json\");\n if (!fs.existsSync(file)) throw new Error(`manifest.json missing: ${packDir}`);\n const raw = readJsonFile<{\n header?: { version?: number[] };\n modules?: Array<{ version?: number[] }>;\n }>(file);\n const ver = raw.header?.version;\n if (!Array.isArray(ver) || ver.length < 3) throw new Error(`invalid header.version in ${file}`);\n const next: [number, number, number] = [Number(ver[0]), Number(ver[1]), Number(ver[2]) + 1];\n return writePackHeaderVersion(packDir, next);\n}\n\n/**\n * \u5411\u76EE\u6807\u5305\u7684 manifest.json \u5199\u5165\u65B0\u7684\u7248\u672C\u53F7\uFF0C\u5E76\u540C\u6B65\u66F4\u65B0\u5185\u90E8 modules \u7684 patch \u7248\u672C\u3002\n *\n * @param packDir \u5305\u6839\u76EE\u5F55\u8DEF\u5F84\u3002\n * @param next \u5F85\u5199\u5165\u7684\u7248\u672C\u4E09\u5143\u7EC4\u3002\n * @returns \u5199\u5165\u786E\u8BA4\u7684\u7248\u672C\u4E09\u5143\u7EC4\u3002\n */\nexport function writePackHeaderVersion(\n\n packDir: string,\n next: [number, number, number]\n): [number, number, number] {\n const file = path.join(packDir, \"manifest.json\");\n if (!fs.existsSync(file)) throw new Error(`manifest.json missing: ${packDir}`);\n const raw = readJsonFile<{\n header?: { version?: number[] };\n modules?: Array<{ version?: number[] }>;\n }>(file);\n if (!raw.header) raw.header = {};\n raw.header.version = next;\n if (Array.isArray(raw.modules)) {\n for (const m of raw.modules) {\n if (Array.isArray(m.version) && m.version.length >= 3) {\n m.version = [Number(m.version[0]), Number(m.version[1]), next[2]];\n }\n }\n }\n fs.writeFileSync(file, `${JSON.stringify(raw, null, 2)}\\n`, \"utf8\");\n return next;\n}\n\n/** \u8BFB\u53D6 BP manifest \u4E2D\u4F9D\u8D56\u7684\u8D44\u6E90\u5305 uuid\uFF08\u975E @minecraft \u6A21\u5757\uFF09 */\nexport function readPackDependencyUuids(packDir: string): string[] {\n const file = path.join(packDir, \"manifest.json\");\n if (!fs.existsSync(file)) return [];\n try {\n const raw = readJsonFile<{\n dependencies?: Array<{ uuid?: string; module_name?: string }>;\n }>(file);\n return (raw.dependencies ?? [])\n .map((d) => d.uuid)\n .filter((u): u is string => typeof u === \"string\" && u.length > 0);\n } catch {\n return [];\n }\n}\n\n/** \u6BD4\u8F83 SemVer \u4E09\u5143\u7EC4\uFF1Ba>b \u6B63\uFF0Ca<b \u8D1F\uFF0C\u76F8\u7B49 0 */\nexport function compareSemVer3(\n a: [number, number, number],\n b: [number, number, number]\n): number {\n for (let i = 0; i < 3; i++) {\n const d = a[i]! - b[i]!;\n if (d !== 0) return d;\n }\n return 0;\n}\n\n/** \u53D6\u8F83\u5927\u7684 SemVer \u4E09\u5143\u7EC4 */\nexport function maxSemVer3(\n a: [number, number, number],\n b: [number, number, number]\n): [number, number, number] {\n return compareSemVer3(a, b) >= 0 ? a : b;\n}\n\n/** \u6309 component \u62AC\u4E00\u7EA7 */\nexport function bumpSemVer3(\n v: [number, number, number],\n component: \"patch\" | \"minor\"\n): [number, number, number] {\n return component === \"minor\" ? [v[0], v[1] + 1, 0] : [v[0], v[1], v[2] + 1];\n}\n\n/**\n * \u8FDB\u670D\u542F\u7528\u7248\u672C\uFF1Amax(\u8FDC\u7A0B/\u65B0\u5305, \u65E7\u542F\u7528) \u518D\u62AC\u4E00\u7EA7\u3002\n * \u5355\u4E00\u89C4\u5219\uFF0C\u7981\u6B62 while \u8FFD\u8D76\uFF08\u4F5C\u8005\u4E71\u5199\u9AD8\u7248\u672C\u5982 [1,21,100] \u65F6\u4E5F\u80FD\u4E00\u6B21\u7B97\u5B8C\uFF09\u3002\n */\nexport function nextEnabledVersion(\n remote: [number, number, number],\n previous: [number, number, number],\n component: \"patch\" | \"minor\" = \"patch\"\n): [number, number, number] {\n return bumpSemVer3(maxSemVer3(remote, previous), component);\n}\n\n/**\n * \u5C06\u5305\u76EE\u5F55 manifest \u62AC\u5230 nextEnabledVersion(\u5F53\u524D, previous)\u3002\n * previous \u4E00\u822C\u4E3A\u66F4\u65B0\u524D\u5DF2\u5B89\u88C5 RP / \u4E16\u754C enable \u5217\u8868\u4E2D\u7684\u7248\u672C\u3002\n */\nexport function ensureVersionGreaterThan(\n packDir: string,\n previous: [number, number, number],\n component: \"patch\" | \"minor\" = \"patch\"\n): [number, number, number] {\n const info = readPackManifestInfo(packDir);\n if (!info) throw new Error(`cannot read pack version: ${packDir}`);\n const next = nextEnabledVersion(info.version, previous, component);\n return writePackHeaderVersion(packDir, next);\n}\n\nexport interface InstallPackResult {\n ok: boolean;\n skipped?: boolean;\n reason?: string;\n destDir?: string;\n folderName?: string;\n info?: PackManifestInfo;\n conflict?: { existing: PackManifestInfo & { dir: string }; incoming: PackManifestInfo };\n}\n\n/** \u76EE\u6807\u7236\u76EE\u5F55\u5185\u5DF2\u5360\u7528\u9879\uFF08\u4F9B\u7EAF\u51B3\u7B56\uFF0C\u4E0D\u542B FS \u526F\u4F5C\u7528\uFF09 */\nexport type DestOccupancy = {\n folderName: string;\n dir: string;\n uuid: string | null;\n version: [number, number, number] | null;\n /** \u53EF\u8BFB\u65F6\u7684\u5C55\u793A\u540D\uFF1B\u51B3\u7B56\u4E0D\u4F9D\u8D56\uFF0C\u4EC5\u4F9B conflict UI */\n name?: string;\n /** \u53EF\u8BFB\u65F6\u7684\u5305\u7C7B\u578B\uFF1B\u51B3\u7B56\u5C55\u793A\u4F18\u5148\u7528\u771F\u5B9E kind\uFF0C\u907F\u514D\u4F2A\u9020 incoming.kind\uFF08LSP\uFF09 */\n kind?: WorldPackKind;\n};\n\nexport type PackInstallPlan =\n | { kind: \"fresh\"; folderName: string; incoming: PackManifestInfo }\n | {\n kind: \"overwriteInPlace\";\n folderName: string;\n dir: string;\n incoming: PackManifestInfo;\n existing: PackManifestInfo & { dir: string };\n }\n | {\n kind: \"needConfirm\";\n folderName: string;\n dir: string;\n incoming: PackManifestInfo;\n existing: PackManifestInfo & { dir: string };\n };\n\n/**\n * \u8BFB\u5355\u76EE\u5F55\u5360\u7528\u4E8B\u5B9E\uFF08info \u4F18\u5148\uFF0C\u5426\u5219 header\uFF09\u3002\n * \u89E3\u6790\u5931\u8D25\u8FD4\u56DE null\uFF1B\u4E0D\u629B BOM\uFF08readJsonFile \u5DF2\u5265\u79BB\uFF09\u3002\n */\nexport function readPackDirOccupancy(dir: string): {\n uuid: string;\n version: [number, number, number];\n name?: string;\n kind?: WorldPackKind;\n} | null {\n const info = readPackManifestInfo(dir);\n if (info) {\n return {\n uuid: info.uuid,\n version: info.version,\n name: info.name,\n kind: info.kind,\n };\n }\n const header = readPackManifestHeader(dir);\n if (header) {\n return { uuid: header.uuid, version: header.version };\n }\n return null;\n}\n\n/** \u626B\u63CF destParent \u4E0B\u542B manifest \u7684\u76EE\u5F55\u5360\u7528\uFF08\u5355\u4E00\u4E8B\u5B9E\u6E90\uFF1AreadPackDirOccupancy\uFF09 */\nexport function scanDestOccupancy(destParent: string): DestOccupancy[] {\n const out: DestOccupancy[] = [];\n for (const dir of listPackDirsIn(destParent)) {\n let facts: ReturnType<typeof readPackDirOccupancy> = null;\n try {\n // DRY\uFF1A\u4E0E readPackDirOccupancy \u5171\u7528 info\u2192header \u56DE\u9000\uFF0C\u7981\u6B62\u5185\u8054\u53CC\u8BFB\n facts = readPackDirOccupancy(dir);\n } catch {\n /* manifest \u4E0D\u53EF\u8BFB\u5219\u5360\u4F4D uuid \u4E3A\u7A7A */\n }\n out.push({\n folderName: path.basename(dir),\n dir,\n uuid: facts?.uuid ?? null,\n version: facts?.version ?? null,\n ...(facts?.name ? { name: facts.name } : {}),\n ...(facts?.kind ? { kind: facts.kind } : {}),\n });\n }\n return out;\n}\n\n/**\n * \u7EAF\u51B3\u7B56\uFF1A\u88C5\u5230\u54EA\u3001\u662F\u5426\u9700\u786E\u8BA4\u3001\u662F\u5426\u539F\u5730\u8986\u76D6\u3002\n * \u540C uuid\uFF1Aincoming \u7248\u672C\u4E25\u683C\u66F4\u5927 \u2192 \u9759\u9ED8\u8986\u76D6\uFF1B\u2264 \u5DF2\u6709\u4E14 !force \u2192 needConfirm\uFF1Bforce \u2192 \u539F\u5730\u8986\u76D6\u3002\n */\nexport function decidePackInstallPlan(opts: {\n incoming: PackManifestInfo;\n hint?: string;\n occupancy: readonly DestOccupancy[];\n force?: boolean;\n}): PackInstallPlan {\n const force = Boolean(opts.force);\n const incomingUuid = opts.incoming.uuid.toLowerCase();\n const same = opts.occupancy.find((o) => o.uuid != null && o.uuid.toLowerCase() === incomingUuid);\n\n if (same) {\n const existingVersion: [number, number, number] = same.version ?? [0, 0, 0];\n const existing: PackManifestInfo & { dir: string } = {\n name: same.name ?? same.folderName,\n uuid: same.uuid!,\n version: existingVersion,\n kind: same.kind ?? opts.incoming.kind,\n dir: same.dir,\n };\n\n const newer = compareSemVer3(opts.incoming.version, existing.version) > 0;\n if (force || newer) {\n return {\n kind: \"overwriteInPlace\",\n folderName: same.folderName,\n dir: same.dir,\n incoming: opts.incoming,\n existing,\n };\n }\n return {\n kind: \"needConfirm\",\n folderName: same.folderName,\n dir: same.dir,\n incoming: opts.incoming,\n existing,\n };\n }\n\n const folderName = allocatePackFolderName({\n info: opts.incoming,\n takenFolderNames: opts.occupancy.map((o) => o.folderName),\n ...(opts.hint !== undefined ? { hint: opts.hint } : {}),\n });\n return { kind: \"fresh\", folderName, incoming: opts.incoming };\n}\n\n/** \u843D\u76D8\u540E\u6821\u9A8C\uFF1A\u9632\u6B62\u65C1\u8DEF\u5B89\u88C5 / \u62F7\u8D1D\u5931\u8D25\u4ECD\u62A5\u6210\u529F */\nexport function verifyInstalledPack(\n destDir: string,\n incoming: PackManifestInfo\n): { ok: true; info: PackManifestInfo } | { ok: false; reason: string } {\n const info = readPackManifestInfo(destDir);\n if (!info) return { ok: false, reason: \"verify: dest has no readable manifest\" };\n if (info.uuid.toLowerCase() !== incoming.uuid.toLowerCase()) {\n return { ok: false, reason: `verify: uuid mismatch got=${info.uuid} want=${incoming.uuid}` };\n }\n if (info.kind !== incoming.kind) {\n return { ok: false, reason: `verify: kind mismatch got=${info.kind} want=${incoming.kind}` };\n }\n if (compareSemVer3(info.version, incoming.version) !== 0) {\n return {\n ok: false,\n reason: `verify: version mismatch got=${info.version.join(\".\")} want=${incoming.version.join(\".\")}`,\n };\n }\n return { ok: true, info };\n}\n\n/**\n * \u5C06\u5305\u76EE\u5F55\u5B89\u88C5\u5230 destParent\uFF08behavior_packs \u6216 resource_packs\uFF09\u3002\n * \u7F16\u6392\uFF1Ascan \u2192 decide \u2192 apply \u2192 verify\u3002\u540C uuid \u7248\u672C\u66F4\u9AD8\u65F6\u9759\u9ED8\u539F\u5730\u8986\u76D6\u3002\n */\nexport async function installPackDirectory(opts: {\n srcDir: string;\n destParent: string;\n folderName?: string;\n force?: boolean;\n}): Promise<InstallPackResult> {\n const info = readPackManifestInfo(opts.srcDir);\n if (!info) {\n return { ok: false, reason: \"invalid or unrecognized manifest.json\" };\n }\n\n await fs.promises.mkdir(opts.destParent, { recursive: true });\n\n const occupancy = scanDestOccupancy(opts.destParent);\n const plan = decidePackInstallPlan({\n incoming: info,\n hint: opts.folderName ?? path.basename(opts.srcDir),\n occupancy,\n ...(opts.force !== undefined ? { force: opts.force } : {}),\n });\n\n if (plan.kind === \"needConfirm\") {\n return {\n ok: false,\n skipped: true,\n reason: \"conflict\",\n conflict: {\n existing: plan.existing,\n incoming: info,\n },\n };\n }\n\n const destDir = path.join(opts.destParent, plan.folderName);\n if (plan.kind === \"overwriteInPlace\" && path.resolve(plan.dir) !== path.resolve(destDir)) {\n return {\n ok: false,\n reason: `invariant: overwrite path drift plan.dir=${plan.dir} destDir=${destDir}`,\n };\n }\n\n if (fs.existsSync(destDir)) {\n await fs.promises.rm(destDir, { recursive: true, force: true });\n }\n await copyDirAsync(opts.srcDir, destDir);\n\n const verified = verifyInstalledPack(destDir, info);\n if (!verified.ok) {\n return { ok: false, reason: verified.reason, folderName: plan.folderName, info };\n }\n return { ok: true, destDir, folderName: plan.folderName, info: verified.info };\n}\n\n/** \u5B89\u88C5\u540E\u5199\u5165\u4E16\u754C enable \u6E05\u5355 */\nexport async function enableInstalledPack(opts: {\n bdsRoot: string;\n levelName: string;\n info: PackManifestInfo;\n}): Promise<void> {\n await enablePackInWorld({\n worldsDir: bdsWorldsDir(opts.bdsRoot),\n levelName: opts.levelName,\n kind: opts.info.kind,\n packUuid: opts.info.uuid,\n version: opts.info.version,\n });\n}\n\n/** \u4ECE\u4E16\u754C enable \u6E05\u5355\u79FB\u9664 */\nexport async function disableInstalledPack(opts: {\n bdsRoot: string;\n levelName: string;\n kind: WorldPackKind;\n packUuid: string;\n version: [number, number, number];\n}): Promise<void> {\n await disablePackInWorld({\n worldsDir: bdsWorldsDir(opts.bdsRoot),\n levelName: opts.levelName,\n kind: opts.kind,\n packUuid: opts.packUuid,\n version: opts.version,\n });\n}\n\nexport type UninstallPackResult =\n | { action: \"trashed\"; dest: string }\n | { action: \"deleted\" }\n | { action: \"missing\" };\n\nexport type UninstallPackAction = UninstallPackResult[\"action\"];\n\n/**\n * \u5378\u8F7D\u5DF2\u5B89\u88C5\u4E16\u754C\u5305\uFF1A\u5148 disable enable-list\uFF0C\u518D\u79FB\u5165 trashDir \u6216\u76F4\u63A5\u5220\u9664\u76EE\u5F55\u3002\n * trashDir \u8DE8\u76D8\u7B26\u65F6 fallback \u4E3A copy + rm\u3002\n */\nexport async function uninstallInstalledPack(opts: {\n bdsRoot: string;\n levelName: string;\n pack: InstalledWorldPack;\n /** \u63D0\u4F9B\u5219\u79FB\u5165\u8BE5\u76EE\u5F55\uFF1Bnull/\u7701\u7565\u5219\u76F4\u63A5\u5220\u9664 */\n trashDir?: string | null;\n}): Promise<UninstallPackResult> {\n await disableInstalledPack({\n bdsRoot: opts.bdsRoot,\n levelName: opts.levelName,\n kind: opts.pack.kind,\n packUuid: opts.pack.uuid,\n version: opts.pack.version,\n });\n\n if (!fs.existsSync(opts.pack.dir)) {\n return { action: \"missing\" };\n }\n\n const trashDir = opts.trashDir?.trim() || null;\n if (trashDir) {\n await fs.promises.mkdir(trashDir, { recursive: true });\n const stamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n let dest = path.join(trashDir, opts.pack.folderName);\n if (fs.existsSync(dest)) {\n dest = path.join(trashDir, `${opts.pack.folderName}-${stamp}`);\n }\n try {\n await fs.promises.rename(opts.pack.dir, dest);\n } catch {\n await copyDirAsync(opts.pack.dir, dest);\n await fs.promises.rm(opts.pack.dir, { recursive: true, force: true });\n }\n return { action: \"trashed\", dest };\n }\n\n await fs.promises.rm(opts.pack.dir, { recursive: true, force: true });\n return { action: \"deleted\" };\n}\n\nexport function worldPackParentDir(\n bdsRoot: string,\n levelName: string,\n kind: WorldPackKind\n): string {\n return path.join(\n bdsWorldLevelDir(bdsRoot, levelName),\n kind === \"behavior\" ? \"behavior_packs\" : \"resource_packs\"\n );\n}\n\n/** \u4E16\u754C enable-list \u6743\u5A01\u8BFB\u53D6 \u2014 \u59D4\u6258 pack-manager\uFF08\u4F9B doctor \u7B49\uFF0C\u907F\u514D\u786C\u7F16\u7801\u6587\u4EF6\u540D\uFF09 */\nexport function listWorldEnableEntries(\n bdsRoot: string,\n levelName: string,\n kind: WorldPackKind\n): Array<{ pack_id: string; version: [number, number, number] }> {\n return listWorldEnableListResult(bdsRoot, levelName, kind).entries;\n}\n\n/** \u542B parseFail \u4FE1\u53F7\u7684 enable-list \u5FEB\u7167\uFF08doctor \u7528\uFF1B\u4E0D\u66B4\u9732 JSON \u8DEF\u5F84\u6784\u9020\u7EC6\u8282\uFF09 */\nexport function listWorldEnableListResult(\n bdsRoot: string,\n levelName: string,\n kind: WorldPackKind\n): WorldPackListReadResult {\n return readWorldPackListResult(bdsWorldsDir(bdsRoot), levelName, kind);\n}\n\nexport function findInstalledPackById(\n packs: InstalledWorldPack[],\n id: string\n): InstalledWorldPack | null {\n const q = id.trim().toLowerCase();\n return (\n packs.find(\n (p) =>\n p.uuid.toLowerCase() === q ||\n p.folderName.toLowerCase() === q ||\n p.name.toLowerCase() === q ||\n p.folderName.toLowerCase().includes(q) ||\n p.name.toLowerCase().includes(q)\n ) ?? null\n );\n}\n\nexport interface WorldBetaApiDiagnosis {\n hasBetaApis: boolean;\n levelDatExists: boolean;\n levelDatPath: string;\n requiringPacks: Array<{\n pack: InstalledWorldPack;\n betaDependencies: PackManifestDependency[];\n }>;\n}\n\nexport function isBetaApiDependency(dep: PackManifestDependency): boolean {\n return isGametestBetaRequired(dep);\n}\n\n/**\n * \u8BCA\u65AD\u6307\u5B9A\u4E16\u754C\u4E2D\u5DF2\u542F\u7528\u7684\u884C\u4E3A\u5305\u5BF9\u6D4B\u8BD5\u7248 API\uFF08Beta APIs\uFF09\u7684\u4F9D\u8D56\u4E0E level.dat \u7684\u5339\u914D\u72B6\u51B5\u3002\n */\nexport function checkWorldBetaApiRequirements(\n bdsRoot: string,\n levelName: string,\n installedPacks?: InstalledWorldPack[]\n): WorldBetaApiDiagnosis {\n const lPath = levelDatPath(bdsRoot, levelName);\n const exists = fs.existsSync(lPath);\n const expInfo = exists ? readLevelDatExperiments(lPath) : null;\n const hasBetaApis = expInfo?.hasBetaApis ?? false;\n\n const packs = installedPacks ?? listInstalledWorldPacks(bdsRoot, levelName);\n const requiringPacks: WorldBetaApiDiagnosis[\"requiringPacks\"] = [];\n\n for (const p of packs) {\n if (p.kind !== \"behavior\" || !p.enabled) continue;\n const deps = readPackManifestDependencies(p.dir);\n const betaDeps = deps.filter(isBetaApiDependency);\n if (betaDeps.length > 0) {\n requiringPacks.push({\n pack: p,\n betaDependencies: betaDeps,\n });\n }\n }\n\n return {\n hasBetaApis,\n levelDatExists: exists,\n levelDatPath: lPath,\n requiringPacks,\n };\n}\n\nexport interface WorldPermissionDiagnosis {\n missingPermissions: Array<{\n pack: InstalledWorldPack;\n moduleName: string;\n }>;\n}\n\n/**\n * \u8BCA\u65AD\u884C\u4E3A\u5305\u4F9D\u8D56\u7684\u539F\u751F\u6A21\u5757\uFF08\u5982 @minecraft/server-net, @minecraft/diagnostics \u7B49\uFF09\u662F\u5426\u5DF2\u5728 BDS config \u4E2D\u6388\u6743\u3002\n */\nexport function checkWorldScriptPermissions(\n bdsRoot: string,\n levelName: string,\n installedPacks?: InstalledWorldPack[]\n): WorldPermissionDiagnosis {\n const packs = installedPacks ?? listInstalledWorldPacks(bdsRoot, levelName);\n const defaultFile = path.join(bdsRoot, \"config\", \"default\", \"permissions.json\");\n const defaultModules = new Set<string>();\n if (fs.existsSync(defaultFile)) {\n try {\n const raw = readJsonFile<{ allowed_modules?: string[] }>(defaultFile);\n if (Array.isArray(raw.allowed_modules)) {\n for (const m of raw.allowed_modules) defaultModules.add(m);\n }\n } catch {}\n }\n\n const missingPermissions: WorldPermissionDiagnosis[\"missingPermissions\"] = [];\n\n for (const p of packs) {\n if (p.kind !== \"behavior\" || !p.enabled) continue;\n const deps = readPackManifestDependencies(p.dir);\n // \u68C0\u67E5\u53D7\u9650\u539F\u751F\u6A21\u5757\n const privilegedDeps = deps.filter((d) => {\n const m = d.module_name ?? \"\";\n return m === \"@minecraft/server-net\" || m === \"@minecraft/server-admin\" || m === \"@minecraft/diagnostics\";\n });\n\n if (privilegedDeps.length === 0) continue;\n\n const headerInfo = readPackManifestHeader(p.dir);\n const uuids = Array.from(new Set([p.uuid, ...(headerInfo?.moduleUuid ? [headerInfo.moduleUuid] : [])]));\n const packAllowed = new Set<string>();\n for (const u of uuids) {\n const f = path.join(bdsRoot, \"config\", u, \"permissions.json\");\n if (fs.existsSync(f)) {\n try {\n const raw = readJsonFile<{ allowed_modules?: string[] }>(f);\n if (Array.isArray(raw.allowed_modules)) {\n for (const m of raw.allowed_modules) packAllowed.add(m);\n }\n } catch {}\n }\n }\n\n for (const dep of privilegedDeps) {\n const mod = dep.module_name!;\n if (!defaultModules.has(mod) && !packAllowed.has(mod)) {\n missingPermissions.push({ pack: p, moduleName: mod });\n }\n }\n }\n\n return { missingPermissions };\n}\n\nexport interface RepairWorldPacksResult {\n cleanedGhostPacks: Array<{ kind: WorldPackKind; uuid: string }>;\n syncedVersions: Array<{\n kind: WorldPackKind;\n folder: string;\n listVer: string;\n diskVer: string;\n }>;\n betaApisResult?: {\n attempted: boolean;\n changed: boolean;\n backupPath?: string | undefined;\n error?: string | undefined;\n } | undefined;\n fixedPermissions?: Array<{\n packName: string;\n moduleName: string;\n }> | undefined;\n}\n\n/**\n * \u81EA\u6108\u4E16\u754C\u8D44\u6E90\u5305/\u884C\u4E3A\u5305\u63A5\u7EBF\u95EE\u9898\uFF1A\n * 1. \u6E05\u7406\u6E05\u5355\u4E2D\u5DF2\u4E0D\u5B58\u5728\u4E8E\u78C1\u76D8\u7684\u5E7D\u7075\u5305 UUID \u6761\u76EE\n * 2. \u81EA\u52A8\u6821\u51C6\u6E05\u5355\u4E2D\u4E0E\u78C1\u76D8 manifest \u4E0D\u4E00\u81F4\u7684\u7248\u672C\u53F7\n * 3. \u81EA\u52A8\u8865\u9F50\u7F3A\u5931\u7684 Script API \u539F\u751F\u6A21\u5757\u6743\u9650\uFF08config/default/permissions.json\uFF09\n * 4. \u53EF\u9009\uFF1A\u81EA\u52A8\u4E3A level.dat \u5F00\u542F Beta APIs\uFF08\u82E5 fixBetaApis \u4E3A true\uFF09\n */\nexport async function repairWorldPacksWiring(\n bdsRoot: string,\n levelName: string,\n opts?: { fixBetaApis?: boolean }\n): Promise<RepairWorldPacksResult> {\n const packs = listInstalledWorldPacks(bdsRoot, levelName);\n const cleanedGhostPacks: RepairWorldPacksResult[\"cleanedGhostPacks\"] = [];\n const syncedVersions: RepairWorldPacksResult[\"syncedVersions\"] = [];\n\n for (const kind of [\"behavior\", \"resource\"] as const) {\n const snap = listWorldEnableListResult(bdsRoot, levelName, kind);\n const byUuid = new Map(packs.filter((p) => p.kind === kind).map((p) => [p.uuid, p]));\n for (const e of snap.entries) {\n const p = byUuid.get(e.pack_id);\n if (!p) {\n // \u5E7D\u7075\u5305\uFF1A\u4ECE\u4E16\u754C\u6E05\u5355\u79FB\u9664\n const entryVer: [number, number, number] =\n Array.isArray(e.version) && e.version.length >= 3\n ? [Number(e.version[0]), Number(e.version[1]), Number(e.version[2])]\n : [1, 0, 0];\n await disablePackInWorld({\n worldsDir: bdsWorldsDir(bdsRoot),\n levelName,\n kind,\n packUuid: e.pack_id,\n version: entryVer,\n });\n cleanedGhostPacks.push({ kind, uuid: e.pack_id });\n } else {\n const ev = e.version;\n if (\n Array.isArray(ev) &&\n ev.length >= 3 &&\n (ev[0] !== p.version[0] || ev[1] !== p.version[1] || ev[2] !== p.version[2])\n ) {\n // \u7248\u672C\u9519\u4F4D\uFF1A\u6309\u78C1\u76D8\u7248\u672C\u91CD\u65B0\u6FC0\u6D3B\u540C\u6B65\n await enablePackInWorld({\n worldsDir: bdsWorldsDir(bdsRoot),\n levelName,\n kind,\n packUuid: p.uuid,\n version: p.version,\n });\n syncedVersions.push({\n kind,\n folder: p.folderName,\n listVer: ev.join(\".\"),\n diskVer: p.version.join(\".\"),\n });\n }\n }\n }\n }\n\n let betaApisResult: RepairWorldPacksResult[\"betaApisResult\"] = undefined;\n if (opts?.fixBetaApis) {\n const lPath = levelDatPath(bdsRoot, levelName);\n const mutateRes = await enableBetaApisInLevelDat(lPath);\n betaApisResult = {\n attempted: true,\n changed: mutateRes.changed,\n ...(mutateRes.backupPath ? { backupPath: mutateRes.backupPath } : {}),\n ...(mutateRes.error ? { error: mutateRes.error } : {}),\n };\n }\n\n // \u4FEE\u590D\u811A\u672C\u539F\u751F\u6A21\u5757\u6743\u9650\n const permDiag = checkWorldScriptPermissions(bdsRoot, levelName, packs);\n let fixedPermissions: RepairWorldPacksResult[\"fixedPermissions\"] = undefined;\n if (permDiag.missingPermissions.length > 0) {\n fixedPermissions = [];\n for (const item of permDiag.missingPermissions) {\n const headerInfo = readPackManifestHeader(item.pack.dir);\n await ensureConfigPermission(bdsRoot, item.pack.uuid, headerInfo?.moduleUuid);\n fixedPermissions.push({\n packName: item.pack.name || item.pack.folderName,\n moduleName: item.moduleName,\n });\n }\n }\n\n const result: RepairWorldPacksResult = {\n cleanedGhostPacks,\n syncedVersions,\n };\n if (betaApisResult) {\n result.betaApisResult = betaApisResult;\n }\n if (fixedPermissions && fixedPermissions.length > 0) {\n result.fixedPermissions = fixedPermissions;\n }\n\n return result;\n}\n\n"],
|
|
5
|
-
"mappings": "AAUA,OAAO,QAAQ;AACf,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,cAAc,oBAAoB;AAC3C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP,SAAS,0BAA0B,+BAA+B;AAClE,SAAS,2BAA2B;AAsBpC,MAAM,eAAe,CAAC,QAAQ,WAAW,UAAU;AAG5C,SAAS,0BAA0B,SAAiB,MAA6B;AACtF,MAAI,IAAI,OAAO,WAAW,EAAE;AAC5B,MAAI,EAAE,QAAQ,iBAAiB,EAAE;AACjC,MAAI,EAAE,QAAQ,4BAA4B,EAAE;AAC5C,MAAI,EAAE,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAChC,MAAI,CAAC,EAAG,KAAI;AACZ,QAAM,SAAS,SAAS,aAAa,SAAS;AAC9C,MAAI,EAAE,WAAW,MAAM,KAAK,EAAE,WAAW,MAAM,EAAG,QAAO;AACzD,SAAO,GAAG,MAAM,IAAI,CAAC;AACvB;AAGO,SAAS,2BAA2B,SAAyB;AAClE,SAAO,OAAO,WAAW,EAAE,EACxB,QAAQ,eAAe,EAAE,EACzB,QAAQ,eAAe,EAAE,EACzB,QAAQ,4BAA4B,EAAE,EACtC,QAAQ,QAAQ,GAAG,EACnB,KAAK;AACV;AAMO,SAAS,wBAAwB,SAA0B;AAChE,QAAM,IAAI,2BAA2B,OAAO;AAC5C,MAAI,CAAC,EAAG,QAAO;AACf,MAAI,EAAE,UAAU,EAAG,QAAO;AAC1B,SAAO,oEAAoE,KAAK,CAAC;AACnF;AAMO,SAAS,uBAAuB,MAM5B;AACT,QAAM,OAAQ,KAAK,QAAQ,KAAK,KAAK,KAAK,KAAM;AAChD,QAAM,YAAY,wBAAwB,IAAI,IAAI,KAAK,KAAK,QAAQ,QAAQ,SAAS;AACrF,MAAI,aAAa,0BAA0B,WAAW,KAAK,KAAK,IAAI;AACpE,QAAM,QAAQ,KAAK,kBAAkB,KAAK,SAAS,KAAK,eAAe,IAAI;AAC3E,MAAI,SAAS,eAAe,MAAO,QAAO;AAE1C,QAAM,QAAQ,IAAI,IAAI,CAAC,GAAG,KAAK,gBAAgB,EAAE,OAAO,CAAC,MAAM,MAAM,KAAK,CAAC;AAC3E,MAAI,CAAC,MAAM,IAAI,UAAU,EAAG,QAAO;AAGnC,QAAM,WAAW;AAAA,IACf,GAAG,2BAA2B,SAAS,CAAC,IAAI,KAAK,KAAK,KAAK,MAAM,GAAG,CAAC,CAAC;AAAA,IACtE,KAAK,KAAK;AAAA,EACZ;AACA,MAAI,CAAC,MAAM,IAAI,QAAQ,EAAG,QAAO;AACjC,MAAI,IAAI;AACR,SAAO,MAAM,IAAI,GAAG,QAAQ,IAAI,CAAC,EAAE,EAAG;AACtC,SAAO,GAAG,QAAQ,IAAI,CAAC;AACzB;AAMO,SAAS,4BAA4B,MAKjC;AACT,QAAM,QAAQ,eAAe,KAAK,UAAU,EAAE,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;AACzE,SAAO,uBAAuB;AAAA,IAC5B,MAAM,KAAK;AAAA,IACX,kBAAkB;AAAA,IAClB,GAAI,KAAK,SAAS,SAAY,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;AAAA,IACrD,GAAI,KAAK,oBAAoB,SAAY,EAAE,iBAAiB,KAAK,gBAAgB,IAAI,CAAC;AAAA,EACxF,CAAC;AACH;AAGO,SAAS,2BAA2B,KAElB;AACvB,QAAM,SAAS,IAAI,WAAW,CAAC,GAAG,IAAI,CAAC,MAAM,OAAO,EAAE,QAAQ,EAAE,EAAE,YAAY,CAAC;AAC/E,MAAI,MAAM,SAAS,WAAW,EAAG,QAAO;AACxC,MAAI,MAAM,KAAK,CAAC,MAAM,MAAM,YAAY,MAAM,UAAU,MAAM,YAAY,EAAG,QAAO;AACpF,SAAO;AACT;AAEO,SAAS,qBAAqB,SAA0C;AAC7E,QAAM,OAAO,KAAK,KAAK,SAAS,eAAe;AAC/C,MAAI,CAAC,GAAG,WAAW,IAAI,EAAG,QAAO;AACjC,MAAI;AACF,UAAM,MAAM,aAGT,IAAI;AACP,UAAM,OAAO,2BAA2B,GAAG;AAC3C,UAAM,OAAO,IAAI,QAAQ;AACzB,UAAM,MAAM,IAAI,QAAQ;AACxB,UAAM,OAAO,IAAI,QAAQ;AACzB,QAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,GAAG,KAAK,IAAI,SAAS,EAAG,QAAO;AACvF,QAAI,OAAO,SAAS,YAAY,CAAC,KAAM,QAAO;AAC9C,UAAM,UAAoC,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC;AACzF,UAAM,cAAc,IAAI,QAAQ;AAChC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,OAAO,gBAAgB,WAAW,EAAE,YAAY,IAAI,CAAC;AAAA,IAC3D;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,kBAAkB,MAAc,MAAwC;AACtF,QAAM,WAAW,MAAM,YAAY;AACnC,QAAM,MAAgB,CAAC;AACvB,QAAM,MAAM,KAAK,QAAQ,IAAI;AAC7B,MAAI,CAAC,GAAG,WAAW,GAAG,EAAG,QAAO;AAEhC,WAAS,KAAK,KAAa,OAAqB;AAC9C,UAAM,WAAW,KAAK,KAAK,KAAK,eAAe;AAC/C,QAAI,GAAG,WAAW,QAAQ,KAAK,GAAG,SAAS,QAAQ,EAAE,OAAO,GAAG;AAC7D,UAAI,KAAK,GAAG;AACZ;AAAA,IACF;AACA,QAAI,SAAS,SAAU;AACvB,QAAI;AACJ,QAAI;AACF,gBAAU,GAAG,YAAY,KAAK,EAAE,eAAe,KAAK,CAAC;AAAA,IACvD,QAAQ;AACN;AAAA,IACF;AACA,eAAW,KAAK,SAAS;AACvB,UAAI,CAAC,EAAE,YAAY,EAAG;AACtB,UAAI,EAAE,KAAK,WAAW,GAAG,KAAK,EAAE,SAAS,eAAgB;AACzD,WAAK,KAAK,KAAK,KAAK,EAAE,IAAI,GAAG,QAAQ,CAAC;AAAA,IACxC;AAAA,EACF;AAEA,QAAM,KAAK,GAAG,SAAS,GAAG;AAC1B,MAAI,GAAG,YAAY,EAAG,MAAK,KAAK,CAAC;AACjC,SAAO;AACT;AAEO,SAAS,cAAc,UAA2B;AACvD,QAAM,QAAQ,SAAS,YAAY;AACnC,SAAO,aAAa,KAAK,CAAC,QAAQ,MAAM,SAAS,GAAG,CAAC;AACvD;AAGA,SAAS,YAAY,UAA0B;AAC7C,QAAM,OAAO,KAAK,SAAS,QAAQ;AACnC,QAAM,QAAQ,KAAK,YAAY;AAC/B,aAAW,OAAO,cAAc;AAC9B,QAAI,MAAM,SAAS,GAAG,EAAG,QAAO,KAAK,MAAM,GAAG,CAAC,IAAI,MAAM;AAAA,EAC3D;AACA,SAAO,KAAK,MAAM,IAAI,EAAE;AAC1B;AAGA,SAAS,wBAAwB,aAA6B;AAC5D,QAAM,SAAS,KAAK,QAAQ,WAAW;AACvC,MAAI,OAAO,KAAK,KAAK,QAAQ,YAAY,WAAW,KAAK,MAAM;AAC/D,MAAI,CAAC,GAAG,WAAW,IAAI,EAAG,QAAO;AACjC,MAAI,IAAI;AACR,SAAO,GAAG,WAAW,GAAG,IAAI,IAAI,CAAC,EAAE,EAAG;AACtC,SAAO,GAAG,IAAI,IAAI,CAAC;AACrB;AAMO,SAAS,qBAAqB,MAAc,MAAwC;AACzF,QAAM,WAAW,MAAM,YAAY;AACnC,QAAM,MAAgB,CAAC;AACvB,QAAM,MAAM,KAAK,QAAQ,IAAI;AAC7B,MAAI,CAAC,GAAG,WAAW,GAAG,KAAK,CAAC,GAAG,SAAS,GAAG,EAAE,YAAY,EAAG,QAAO;AAEnE,WAAS,KAAK,KAAa,OAAqB;AAC9C,QAAI,GAAG,WAAW,KAAK,KAAK,KAAK,eAAe,CAAC,EAAG;AACpD,QAAI;AACJ,QAAI;AACF,gBAAU,GAAG,YAAY,KAAK,EAAE,eAAe,KAAK,CAAC;AAAA,IACvD,QAAQ;AACN;AAAA,IACF;AACA,eAAW,KAAK,SAAS;AACvB,UAAI,EAAE,KAAK,WAAW,GAAG,KAAK,EAAE,SAAS,eAAgB;AACzD,YAAM,OAAO,KAAK,KAAK,KAAK,EAAE,IAAI;AAClC,UAAI,EAAE,OAAO,KAAK,cAAc,IAAI,GAAG;AACrC,YAAI,KAAK,IAAI;AACb;AAAA,MACF;AACA,UAAI,EAAE,YAAY,KAAK,QAAQ,SAAU,MAAK,MAAM,QAAQ,CAAC;AAAA,IAC/D;AAAA,EACF;AAEA,OAAK,KAAK,CAAC;AACX,SAAO;AACT;AAMA,eAAsB,4BACpB,SACA,MACiB;AACjB,QAAM,YAAY,MAAM,aAAa;AACrC,QAAM,eAAe,MAAM,gBAAgB;AAC3C,MAAI,WAAW;AACf,WAAS,QAAQ,GAAG,QAAQ,WAAW,SAAS;AAC9C,UAAM,WAAW,qBAAqB,SAAS,EAAE,UAAU,aAAa,CAAC;AACzE,QAAI,SAAS,WAAW,EAAG;AAC3B,eAAW,QAAQ,UAAU;AAC3B,YAAM,OAAO,wBAAwB,IAAI;AACzC,YAAM,GAAG,SAAS,MAAM,MAAM,EAAE,WAAW,KAAK,CAAC;AACjD,YAAM,oBAAoB,MAAM,IAAI;AACpC,YAAM,GAAG,SAAS,OAAO,IAAI;AAC7B;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAaA,eAAsB,iBACpB,KACA,MACiC;AACjC,QAAM,cAAc,MAAM,eAAe;AACzC,QAAM,mBAAmB,MAAM,oBAAoB;AACnD,QAAM,QAAkB,CAAC;AACzB,QAAM,UAAU,MAAY;AAC1B,eAAW,KAAK,MAAM,OAAO,GAAG,MAAM,MAAM,GAAG;AAC7C,UAAI;AACF,WAAG,OAAO,GAAG,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,MAC/C,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAEA,QAAM,MAAM,KAAK,QAAQ,GAAG;AAC5B,MAAI,CAAC,GAAG,WAAW,GAAG,EAAG,QAAO,EAAE,OAAO,CAAC,GAAG,QAAQ;AAErD,MAAI;AACF,UAAM,KAAK,GAAG,SAAS,GAAG;AAC1B,QAAI,GAAG,OAAO,GAAG;AACf,UAAI,CAAC,cAAc,GAAG,EAAG,QAAO,EAAE,OAAO,CAAC,GAAG,QAAQ;AACrD,YAAM,MAAM,MAAM,qBAAqB,GAAG;AAC1C,YAAM,KAAK,GAAG;AACd,YAAM,4BAA4B,KAAK;AAAA,QACrC,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO,EAAE,OAAO,kBAAkB,KAAK,EAAE,UAAU,YAAY,CAAC,GAAG,QAAQ;AAAA,IAC7E;AAEA,QAAI,CAAC,GAAG,YAAY,EAAG,QAAO,EAAE,OAAO,CAAC,GAAG,QAAQ;AAEnD,UAAM,iBAAiB,qBAAqB,KAAK,EAAE,UAAU,YAAY,CAAC;AAC1E,QAAI,eAAe,WAAW,GAAG;AAC/B,aAAO,EAAE,OAAO,kBAAkB,KAAK,EAAE,UAAU,YAAY,CAAC,GAAG,QAAQ;AAAA,IAC7E;AAGA,UAAM,QAAQ,kBAAkB,KAAK,EAAE,UAAU,YAAY,CAAC;AAC9D,UAAM,OAAO,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC;AACtD,eAAW,QAAQ,gBAAgB;AACjC,YAAM,MAAM,MAAM,qBAAqB,IAAI;AAC3C,YAAM,KAAK,GAAG;AACd,YAAM,4BAA4B,KAAK;AAAA,QACrC,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,iBAAW,KAAK,kBAAkB,KAAK,EAAE,UAAU,YAAY,CAAC,GAAG;AACjE,cAAM,MAAM,KAAK,QAAQ,CAAC;AAC1B,YAAI,KAAK,IAAI,GAAG,EAAG;AACnB,aAAK,IAAI,GAAG;AACZ,cAAM,KAAK,CAAC;AAAA,MACd;AAAA,IACF;AACA,WAAO,EAAE,OAAO,QAAQ;AAAA,EAC1B,SAAS,GAAG;AACV,YAAQ;AACR,UAAM;AAAA,EACR;AACF;AAGA,eAAsB,qBAAqB,UAAmC;AAC5E,QAAM,MAAM,GAAG,YAAY,KAAK,KAAK,GAAG,OAAO,GAAG,YAAY,CAAC;AAC/D,QAAM,oBAAoB,UAAU,GAAG;AACvC,SAAO;AACT;AAEA,SAAS,eAAe,QAA0B;AAChD,MAAI,CAAC,GAAG,WAAW,MAAM,EAAG,QAAO,CAAC;AACpC,QAAM,MAAgB,CAAC;AACvB,aAAW,KAAK,GAAG,YAAY,QAAQ,EAAE,eAAe,KAAK,CAAC,GAAG;AAC/D,QAAI,CAAC,EAAE,YAAY,EAAG;AACtB,UAAM,MAAM,KAAK,KAAK,QAAQ,EAAE,IAAI;AACpC,QAAI,GAAG,WAAW,KAAK,KAAK,KAAK,eAAe,CAAC,EAAG,KAAI,KAAK,GAAG;AAAA,EAClE;AACA,SAAO;AACT;AAGO,SAAS,wBAAwB,SAAiB,WAAyC;AAChG,QAAM,YAAY,iBAAiB,SAAS,SAAS;AACrD,QAAM,YAAY,aAAa,OAAO;AACtC,QAAM,SAA+B,CAAC;AAEtC,aAAW,QAAQ,CAAC,YAAY,UAAU,GAAY;AACpD,UAAM,SAAS,KAAK;AAAA,MAClB;AAAA,MACA,SAAS,aAAa,mBAAmB;AAAA,IAC3C;AACA,UAAM,cAAc,kBAAkB,WAAW,WAAW,IAAI;AAChE,UAAM,aAAa,IAAI,IAAI,YAAY,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,OAAO,CAAU,CAAC;AAElF,eAAW,OAAO,eAAe,MAAM,GAAG;AACxC,YAAM,OAAO,qBAAqB,GAAG;AACrC,UAAI,CAAC,QAAQ,KAAK,SAAS,MAAM;AAE/B,cAAM,SAAS,uBAAuB,GAAG;AACzC,YAAI,CAAC,OAAQ;AACb,eAAO,KAAK;AAAA,UACV;AAAA,UACA,YAAY,KAAK,SAAS,GAAG;AAAA,UAC7B;AAAA,UACA,MAAM,KAAK,SAAS,GAAG;AAAA,UACvB,MAAM,OAAO;AAAA,UACb,SAAS,OAAO;AAAA,UAChB,SAAS,WAAW,IAAI,OAAO,IAAI;AAAA,QACrC,CAAC;AACD;AAAA,MACF;AACA,aAAO,KAAK;AAAA,QACV,MAAM,KAAK;AAAA,QACX,YAAY,KAAK,SAAS,GAAG;AAAA,QAC7B;AAAA,QACA,MAAM,KAAK;AAAA,QACX,MAAM,KAAK;AAAA,QACX,SAAS,KAAK;AAAA,QACd,SAAS,WAAW,IAAI,KAAK,IAAI;AAAA,MACnC,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAQO,SAAS,qBAAqB,SAA2C;AAC9E,QAAM,OAAO,KAAK,KAAK,SAAS,eAAe;AAC/C,MAAI,CAAC,GAAG,WAAW,IAAI,EAAG,OAAM,IAAI,MAAM,0BAA0B,OAAO,EAAE;AAC7E,QAAM,MAAM,aAGT,IAAI;AACP,QAAM,MAAM,IAAI,QAAQ;AACxB,MAAI,CAAC,MAAM,QAAQ,GAAG,KAAK,IAAI,SAAS,EAAG,OAAM,IAAI,MAAM,6BAA6B,IAAI,EAAE;AAC9F,QAAM,OAAiC,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC;AAC1F,SAAO,uBAAuB,SAAS,IAAI;AAC7C;AASO,SAAS,uBAEd,SACA,MAC0B;AAC1B,QAAM,OAAO,KAAK,KAAK,SAAS,eAAe;AAC/C,MAAI,CAAC,GAAG,WAAW,IAAI,EAAG,OAAM,IAAI,MAAM,0BAA0B,OAAO,EAAE;AAC7E,QAAM,MAAM,aAGT,IAAI;AACP,MAAI,CAAC,IAAI,OAAQ,KAAI,SAAS,CAAC;AAC/B,MAAI,OAAO,UAAU;AACrB,MAAI,MAAM,QAAQ,IAAI,OAAO,GAAG;AAC9B,eAAW,KAAK,IAAI,SAAS;AAC3B,UAAI,MAAM,QAAQ,EAAE,OAAO,KAAK,EAAE,QAAQ,UAAU,GAAG;AACrD,UAAE,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AACA,KAAG,cAAc,MAAM,GAAG,KAAK,UAAU,KAAK,MAAM,CAAC,CAAC;AAAA,GAAM,MAAM;AAClE,SAAO;AACT;AAGO,SAAS,wBAAwB,SAA2B;AACjE,QAAM,OAAO,KAAK,KAAK,SAAS,eAAe;AAC/C,MAAI,CAAC,GAAG,WAAW,IAAI,EAAG,QAAO,CAAC;AAClC,MAAI;AACF,UAAM,MAAM,aAET,IAAI;AACP,YAAQ,IAAI,gBAAgB,CAAC,GAC1B,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,OAAO,CAAC,MAAmB,OAAO,MAAM,YAAY,EAAE,SAAS,CAAC;AAAA,EACrE,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAGO,SAAS,eACd,GACA,GACQ;AACR,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,IAAI,EAAE,CAAC,IAAK,EAAE,CAAC;AACrB,QAAI,MAAM,EAAG,QAAO;AAAA,EACtB;AACA,SAAO;AACT;AAGO,SAAS,WACd,GACA,GAC0B;AAC1B,SAAO,eAAe,GAAG,CAAC,KAAK,IAAI,IAAI;AACzC;AAGO,SAAS,YACd,GACA,WAC0B;AAC1B,SAAO,cAAc,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;AAC5E;AAMO,SAAS,mBACd,QACA,UACA,YAA+B,SACL;AAC1B,SAAO,YAAY,WAAW,QAAQ,QAAQ,GAAG,SAAS;AAC5D;AAMO,SAAS,yBACd,SACA,UACA,YAA+B,SACL;AAC1B,QAAM,OAAO,qBAAqB,OAAO;AACzC,MAAI,CAAC,KAAM,OAAM,IAAI,MAAM,6BAA6B,OAAO,EAAE;AACjE,QAAM,OAAO,mBAAmB,KAAK,SAAS,UAAU,SAAS;AACjE,SAAO,uBAAuB,SAAS,IAAI;AAC7C;AA6CO,SAAS,qBAAqB,KAK5B;AACP,QAAM,OAAO,qBAAqB,GAAG;AACrC,MAAI,MAAM;AACR,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,IACb;AAAA,EACF;AACA,QAAM,SAAS,uBAAuB,GAAG;AACzC,MAAI,QAAQ;AACV,WAAO,EAAE,MAAM,OAAO,MAAM,SAAS,OAAO,QAAQ;AAAA,EACtD;AACA,SAAO;AACT;AAGO,SAAS,kBAAkB,YAAqC;AACrE,QAAM,MAAuB,CAAC;AAC9B,aAAW,OAAO,eAAe,UAAU,GAAG;AAC5C,QAAI,QAAiD;AACrD,QAAI;AAEF,cAAQ,qBAAqB,GAAG;AAAA,IAClC,QAAQ;AAAA,IAER;AACA,QAAI,KAAK;AAAA,MACP,YAAY,KAAK,SAAS,GAAG;AAAA,MAC7B;AAAA,MACA,MAAM,OAAO,QAAQ;AAAA,MACrB,SAAS,OAAO,WAAW;AAAA,MAC3B,GAAI,OAAO,OAAO,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,MAC1C,GAAI,OAAO,OAAO,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,IAC5C,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAMO,SAAS,sBAAsB,MAKlB;AAClB,QAAM,QAAQ,QAAQ,KAAK,KAAK;AAChC,QAAM,eAAe,KAAK,SAAS,KAAK,YAAY;AACpD,QAAM,OAAO,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE,QAAQ,QAAQ,EAAE,KAAK,YAAY,MAAM,YAAY;AAE/F,MAAI,MAAM;AACR,UAAM,kBAA4C,KAAK,WAAW,CAAC,GAAG,GAAG,CAAC;AAC1E,UAAM,WAA+C;AAAA,MACnD,MAAM,KAAK,QAAQ,KAAK;AAAA,MACxB,MAAM,KAAK;AAAA,MACX,SAAS;AAAA,MACT,MAAM,KAAK,QAAQ,KAAK,SAAS;AAAA,MACjC,KAAK,KAAK;AAAA,IACZ;AAEA,UAAM,QAAQ,eAAe,KAAK,SAAS,SAAS,SAAS,OAAO,IAAI;AACxE,QAAI,SAAS,OAAO;AAClB,aAAO;AAAA,QACL,MAAM;AAAA,QACN,YAAY,KAAK;AAAA,QACjB,KAAK,KAAK;AAAA,QACV,UAAU,KAAK;AAAA,QACf;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,YAAY,KAAK;AAAA,MACjB,KAAK,KAAK;AAAA,MACV,UAAU,KAAK;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAa,uBAAuB;AAAA,IACxC,MAAM,KAAK;AAAA,IACX,kBAAkB,KAAK,UAAU,IAAI,CAAC,MAAM,EAAE,UAAU;AAAA,IACxD,GAAI,KAAK,SAAS,SAAY,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;AAAA,EACvD,CAAC;AACD,SAAO,EAAE,MAAM,SAAS,YAAY,UAAU,KAAK,SAAS;AAC9D;AAGO,SAAS,oBACd,SACA,UACsE;AACtE,QAAM,OAAO,qBAAqB,OAAO;AACzC,MAAI,CAAC,KAAM,QAAO,EAAE,IAAI,OAAO,QAAQ,wCAAwC;AAC/E,MAAI,KAAK,KAAK,YAAY,MAAM,SAAS,KAAK,YAAY,GAAG;AAC3D,WAAO,EAAE,IAAI,OAAO,QAAQ,6BAA6B,KAAK,IAAI,SAAS,SAAS,IAAI,GAAG;AAAA,EAC7F;AACA,MAAI,KAAK,SAAS,SAAS,MAAM;AAC/B,WAAO,EAAE,IAAI,OAAO,QAAQ,6BAA6B,KAAK,IAAI,SAAS,SAAS,IAAI,GAAG;AAAA,EAC7F;AACA,MAAI,eAAe,KAAK,SAAS,SAAS,OAAO,MAAM,GAAG;AACxD,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,QAAQ,gCAAgC,KAAK,QAAQ,KAAK,GAAG,CAAC,SAAS,SAAS,QAAQ,KAAK,GAAG,CAAC;AAAA,IACnG;AAAA,EACF;AACA,SAAO,EAAE,IAAI,MAAM,KAAK;AAC1B;AAMA,eAAsB,qBAAqB,MAKZ;AAC7B,QAAM,OAAO,qBAAqB,KAAK,MAAM;AAC7C,MAAI,CAAC,MAAM;AACT,WAAO,EAAE,IAAI,OAAO,QAAQ,wCAAwC;AAAA,EACtE;AAEA,QAAM,GAAG,SAAS,MAAM,KAAK,YAAY,EAAE,WAAW,KAAK,CAAC;AAE5D,QAAM,YAAY,kBAAkB,KAAK,UAAU;AACnD,QAAM,OAAO,sBAAsB;AAAA,IACjC,UAAU;AAAA,IACV,MAAM,KAAK,cAAc,KAAK,SAAS,KAAK,MAAM;AAAA,IAClD;AAAA,IACA,GAAI,KAAK,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,EAC1D,CAAC;AAED,MAAI,KAAK,SAAS,eAAe;AAC/B,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,UAAU;AAAA,QACR,UAAU,KAAK;AAAA,QACf,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,KAAK,KAAK,KAAK,YAAY,KAAK,UAAU;AAC1D,MAAI,KAAK,SAAS,sBAAsB,KAAK,QAAQ,KAAK,GAAG,MAAM,KAAK,QAAQ,OAAO,GAAG;AACxF,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,QAAQ,4CAA4C,KAAK,GAAG,YAAY,OAAO;AAAA,IACjF;AAAA,EACF;AAEA,MAAI,GAAG,WAAW,OAAO,GAAG;AAC1B,UAAM,GAAG,SAAS,GAAG,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EAChE;AACA,QAAM,aAAa,KAAK,QAAQ,OAAO;AAEvC,QAAM,WAAW,oBAAoB,SAAS,IAAI;AAClD,MAAI,CAAC,SAAS,IAAI;AAChB,WAAO,EAAE,IAAI,OAAO,QAAQ,SAAS,QAAQ,YAAY,KAAK,YAAY,KAAK;AAAA,EACjF;AACA,SAAO,EAAE,IAAI,MAAM,SAAS,YAAY,KAAK,YAAY,MAAM,SAAS,KAAK;AAC/E;AAGA,eAAsB,oBAAoB,MAIxB;AAChB,QAAM,kBAAkB;AAAA,IACtB,WAAW,aAAa,KAAK,OAAO;AAAA,IACpC,WAAW,KAAK;AAAA,IAChB,MAAM,KAAK,KAAK;AAAA,IAChB,UAAU,KAAK,KAAK;AAAA,IACpB,SAAS,KAAK,KAAK;AAAA,EACrB,CAAC;AACH;AAGA,eAAsB,qBAAqB,MAMzB;AAChB,QAAM,mBAAmB;AAAA,IACvB,WAAW,aAAa,KAAK,OAAO;AAAA,IACpC,WAAW,KAAK;AAAA,IAChB,MAAM,KAAK;AAAA,IACX,UAAU,KAAK;AAAA,IACf,SAAS,KAAK;AAAA,EAChB,CAAC;AACH;AAaA,eAAsB,uBAAuB,MAMZ;AAC/B,QAAM,qBAAqB;AAAA,IACzB,SAAS,KAAK;AAAA,IACd,WAAW,KAAK;AAAA,IAChB,MAAM,KAAK,KAAK;AAAA,IAChB,UAAU,KAAK,KAAK;AAAA,IACpB,SAAS,KAAK,KAAK;AAAA,EACrB,CAAC;AAED,MAAI,CAAC,GAAG,WAAW,KAAK,KAAK,GAAG,GAAG;AACjC,WAAO,EAAE,QAAQ,UAAU;AAAA,EAC7B;AAEA,QAAM,WAAW,KAAK,UAAU,KAAK,KAAK;AAC1C,MAAI,UAAU;AACZ,UAAM,GAAG,SAAS,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AACrD,UAAM,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,QAAQ,SAAS,GAAG;AAC3D,QAAI,OAAO,KAAK,KAAK,UAAU,KAAK,KAAK,UAAU;AACnD,QAAI,GAAG,WAAW,IAAI,GAAG;AACvB,aAAO,KAAK,KAAK,UAAU,GAAG,KAAK,KAAK,UAAU,IAAI,KAAK,EAAE;AAAA,IAC/D;AACA,QAAI;AACF,YAAM,GAAG,SAAS,OAAO,KAAK,KAAK,KAAK,IAAI;AAAA,IAC9C,QAAQ;AACN,YAAM,aAAa,KAAK,KAAK,KAAK,IAAI;AACtC,YAAM,GAAG,SAAS,GAAG,KAAK,KAAK,KAAK,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IACtE;AACA,WAAO,EAAE,QAAQ,WAAW,KAAK;AAAA,EACnC;AAEA,QAAM,GAAG,SAAS,GAAG,KAAK,KAAK,KAAK,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACpE,SAAO,EAAE,QAAQ,UAAU;AAC7B;AAEO,SAAS,mBACd,SACA,WACA,MACQ;AACR,SAAO,KAAK;AAAA,IACV,iBAAiB,SAAS,SAAS;AAAA,IACnC,SAAS,aAAa,mBAAmB;AAAA,EAC3C;AACF;AAGO,SAAS,uBACd,SACA,WACA,MAC+D;AAC/D,SAAO,0BAA0B,SAAS,WAAW,IAAI,EAAE;AAC7D;AAGO,SAAS,0BACd,SACA,WACA,MACyB;AACzB,SAAO,wBAAwB,aAAa,OAAO,GAAG,WAAW,IAAI;AACvE;AAEO,SAAS,sBACd,OACA,IAC2B;AAC3B,QAAM,IAAI,GAAG,KAAK,EAAE,YAAY;AAChC,SACE,MAAM;AAAA,IACJ,CAAC,MACC,EAAE,KAAK,YAAY,MAAM,KACzB,EAAE,WAAW,YAAY,MAAM,KAC/B,EAAE,KAAK,YAAY,MAAM,KACzB,EAAE,WAAW,YAAY,EAAE,SAAS,CAAC,KACrC,EAAE,KAAK,YAAY,EAAE,SAAS,CAAC;AAAA,EACnC,KAAK;AAET;AAYO,SAAS,oBAAoB,KAAsC;AACxE,SAAO,uBAAuB,GAAG;AACnC;AAKO,SAAS,8BACd,SACA,WACA,gBACuB;AACvB,QAAM,QAAQ,aAAa,SAAS,SAAS;AAC7C,QAAM,SAAS,GAAG,WAAW,KAAK;AAClC,QAAM,UAAU,SAAS,wBAAwB,KAAK,IAAI;AAC1D,QAAM,cAAc,SAAS,eAAe;AAE5C,QAAM,QAAQ,kBAAkB,wBAAwB,SAAS,SAAS;AAC1E,QAAM,iBAA0D,CAAC;AAEjE,aAAW,KAAK,OAAO;AACrB,QAAI,EAAE,SAAS,cAAc,CAAC,EAAE,QAAS;AACzC,UAAM,OAAO,6BAA6B,EAAE,GAAG;AAC/C,UAAM,WAAW,KAAK,OAAO,mBAAmB;AAChD,QAAI,SAAS,SAAS,GAAG;AACvB,qBAAe,KAAK;AAAA,QAClB,MAAM;AAAA,QACN,kBAAkB;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd;AAAA,EACF;AACF;AAYO,SAAS,4BACd,SACA,WACA,gBAC0B;AAC1B,QAAM,QAAQ,kBAAkB,wBAAwB,SAAS,SAAS;AAC1E,QAAM,cAAc,KAAK,KAAK,SAAS,UAAU,WAAW,kBAAkB;AAC9E,QAAM,iBAAiB,oBAAI,IAAY;AACvC,MAAI,GAAG,WAAW,WAAW,GAAG;AAC9B,QAAI;AACF,YAAM,MAAM,aAA6C,WAAW;AACpE,UAAI,MAAM,QAAQ,IAAI,eAAe,GAAG;AACtC,mBAAW,KAAK,IAAI,gBAAiB,gBAAe,IAAI,CAAC;AAAA,MAC3D;AAAA,IACF,QAAQ;AAAA,IAAC;AAAA,EACX;AAEA,QAAM,qBAAqE,CAAC;AAE5E,aAAW,KAAK,OAAO;AACrB,QAAI,EAAE,SAAS,cAAc,CAAC,EAAE,QAAS;AACzC,UAAM,OAAO,6BAA6B,EAAE,GAAG;AAE/C,UAAM,iBAAiB,KAAK,OAAO,CAAC,MAAM;AACxC,YAAM,IAAI,EAAE,eAAe;AAC3B,aAAO,MAAM,2BAA2B,MAAM,6BAA6B,MAAM;AAAA,IACnF,CAAC;AAED,QAAI,eAAe,WAAW,EAAG;AAEjC,UAAM,aAAa,uBAAuB,EAAE,GAAG;AAC/C,UAAM,QAAQ,MAAM,KAAK,oBAAI,IAAI,CAAC,EAAE,MAAM,GAAI,YAAY,aAAa,CAAC,WAAW,UAAU,IAAI,CAAC,CAAE,CAAC,CAAC;AACtG,UAAM,cAAc,oBAAI,IAAY;AACpC,eAAW,KAAK,OAAO;AACrB,YAAM,IAAI,KAAK,KAAK,SAAS,UAAU,GAAG,kBAAkB;AAC5D,UAAI,GAAG,WAAW,CAAC,GAAG;AACpB,YAAI;AACF,gBAAM,MAAM,aAA6C,CAAC;AAC1D,cAAI,MAAM,QAAQ,IAAI,eAAe,GAAG;AACtC,uBAAW,KAAK,IAAI,gBAAiB,aAAY,IAAI,CAAC;AAAA,UACxD;AAAA,QACF,QAAQ;AAAA,QAAC;AAAA,MACX;AAAA,IACF;AAEA,eAAW,OAAO,gBAAgB;AAChC,YAAM,MAAM,IAAI;AAChB,UAAI,CAAC,eAAe,IAAI,GAAG,KAAK,CAAC,YAAY,IAAI,GAAG,GAAG;AACrD,2BAAmB,KAAK,EAAE,MAAM,GAAG,YAAY,IAAI,CAAC;AAAA,MACtD;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,mBAAmB;AAC9B;AA6BA,eAAsB,uBACpB,SACA,WACA,MACiC;AACjC,QAAM,QAAQ,wBAAwB,SAAS,SAAS;AACxD,QAAM,oBAAiE,CAAC;AACxE,QAAM,iBAA2D,CAAC;AAElE,aAAW,QAAQ,CAAC,YAAY,UAAU,GAAY;AACpD,UAAM,OAAO,0BAA0B,SAAS,WAAW,IAAI;AAC/D,UAAM,SAAS,IAAI,IAAI,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACnF,eAAW,KAAK,KAAK,SAAS;AAC5B,YAAM,IAAI,OAAO,IAAI,EAAE,OAAO;AAC9B,UAAI,CAAC,GAAG;AAEN,cAAM,WACJ,MAAM,QAAQ,EAAE,OAAO,KAAK,EAAE,QAAQ,UAAU,IAC5C,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,IACjE,CAAC,GAAG,GAAG,CAAC;AACd,cAAM,mBAAmB;AAAA,UACvB,WAAW,aAAa,OAAO;AAAA,UAC/B;AAAA,UACA;AAAA,UACA,UAAU,EAAE;AAAA,UACZ,SAAS;AAAA,QACX,CAAC;AACD,0BAAkB,KAAK,EAAE,MAAM,MAAM,EAAE,QAAQ,CAAC;AAAA,MAClD,OAAO;AACL,cAAM,KAAK,EAAE;AACb,YACE,MAAM,QAAQ,EAAE,KAChB,GAAG,UAAU,MACZ,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,IAC1E;AAEA,gBAAM,kBAAkB;AAAA,YACtB,WAAW,aAAa,OAAO;AAAA,YAC/B;AAAA,YACA;AAAA,YACA,UAAU,EAAE;AAAA,YACZ,SAAS,EAAE;AAAA,UACb,CAAC;AACD,yBAAe,KAAK;AAAA,YAClB;AAAA,YACA,QAAQ,EAAE;AAAA,YACV,SAAS,GAAG,KAAK,GAAG;AAAA,YACpB,SAAS,EAAE,QAAQ,KAAK,GAAG;AAAA,UAC7B,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,iBAA2D;AAC/D,MAAI,MAAM,aAAa;AACrB,UAAM,QAAQ,aAAa,SAAS,SAAS;AAC7C,UAAM,YAAY,MAAM,yBAAyB,KAAK;AACtD,qBAAiB;AAAA,MACf,WAAW;AAAA,MACX,SAAS,UAAU;AAAA,MACnB,GAAI,UAAU,aAAa,EAAE,YAAY,UAAU,WAAW,IAAI,CAAC;AAAA,MACnE,GAAI,UAAU,QAAQ,EAAE,OAAO,UAAU,MAAM,IAAI,CAAC;AAAA,IACtD;AAAA,EACF;AAGA,QAAM,WAAW,4BAA4B,SAAS,WAAW,KAAK;AACtE,MAAI,mBAA+D;AACnE,MAAI,SAAS,mBAAmB,SAAS,GAAG;AAC1C,uBAAmB,CAAC;AACpB,eAAW,QAAQ,SAAS,oBAAoB;AAC9C,YAAM,aAAa,uBAAuB,KAAK,KAAK,GAAG;AACvD,YAAM,uBAAuB,SAAS,KAAK,KAAK,MAAM,YAAY,UAAU;AAC5E,uBAAiB,KAAK;AAAA,QACpB,UAAU,KAAK,KAAK,QAAQ,KAAK,KAAK;AAAA,QACtC,YAAY,KAAK;AAAA,MACnB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,SAAiC;AAAA,IACrC;AAAA,IACA;AAAA,EACF;AACA,MAAI,gBAAgB;AAClB,WAAO,iBAAiB;AAAA,EAC1B;AACA,MAAI,oBAAoB,iBAAiB,SAAS,GAAG;AACnD,WAAO,mBAAmB;AAAA,EAC5B;AAEA,SAAO;AACT;",
|
|
6
|
-
"names": []
|
|
4
|
+
"sourcesContent": ["/**\n * world-packs.ts \u2014 \u901A\u7528 Minecraft \u57FA\u5CA9\u7248\u4E16\u754C\u884C\u4E3A\u5305\uFF08BP\uFF09\u4E0E\u8D44\u6E90\u5305\uFF08RP\uFF09\u7BA1\u7406\u5DE5\u5177\n *\n * \u6838\u5FC3\u80FD\u529B\uFF1A\n * - \u683C\u5F0F\u4E0E\u547D\u540D\u89C4\u8303\u5316\uFF1A\u8FC7\u6EE4 Minecraft \u989C\u8272\u683C\u5F0F\u7801\uFF0C\u81EA\u52A8\u8865\u5145 `[BP]` / `[RP]` \u524D\u7F00\u53CA\u51B2\u7A81\u907F\u8BA9\n * - \u538B\u7F29\u5305\u9012\u5F52\u89E3\u6784\uFF1A\u652F\u6301 `.zip`\u3001`.mcpack`\u3001`.mcaddon` \u5D4C\u5957\u5305\u89E3\u538B\u5E76\u667A\u80FD\u8BC6\u522B BP \u4E0E RP \u6839\u76EE\u5F55\n * - \u7248\u672C\u9012\u589E\u4E0E\u540C\u6B65\uFF1A\u540C\u6B65\u5347\u7EA7 manifest \u4E2D\u7684\u7248\u672C\u5143\u6570\u636E\u5E76\u5BF9\u9F50\u4E16\u754C\u542F\u7528\u6E05\u5355\u7248\u672C\n * - \u5E42\u7B49\u5B89\u88C5\u4E0E\u56DE\u6EDA\uFF1A\u6309 UUID \u7CBE\u786E\u5339\u914D\u5347\u7EA7\u4E0E\u5B89\u88C5\u8BA1\u5212\uFF0C\u652F\u6301\u5220\u9664\u5907\u4EFD\u81F3\u56DE\u6536\u7AD9\u673A\u5236\n */\n\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { copyDirAsync, readJsonFile } from \"./fsx.js\";\nimport { enableExperimentsInLevelDat, readLevelDatExperiments, type LevelDatExperimentsInfo } from \"./level-dat.js\";\nimport {\n bdsWorldLevelDir,\n bdsWorldsDir,\n disablePackInWorld,\n enablePackInWorld,\n ensureConfigPermission,\n isGametestBetaRequired,\n levelDatPath,\n readPackManifestDependencies,\n readPackManifestHeader,\n readWorldPackList,\n readWorldPackListResult,\n type PackManifestDependency,\n type WorldPackListReadResult,\n} from \"./pack-manager.js\";\nimport { extractZipFileToDir } from \"./zipx.js\";\nexport {\n enableBetaApisInLevelDat,\n enableExperimentsInLevelDat,\n KNOWN_EXPERIMENTS,\n readLevelDatExperiments,\n resolveExperimentDefinition,\n type KnownExperimentDefinition,\n type LevelDatExperimentsInfo,\n type LevelDatMutateResult,\n} from \"./level-dat.js\";\n\nexport type WorldPackKind = \"behavior\" | \"resource\";\n\nexport interface PackManifestInfo {\n name: string;\n uuid: string;\n version: [number, number, number];\n kind: WorldPackKind;\n description?: string;\n}\n\nexport interface InstalledWorldPack {\n kind: WorldPackKind;\n folderName: string;\n dir: string;\n name: string;\n uuid: string;\n version: [number, number, number];\n enabled: boolean;\n}\n\nconst ARCHIVE_EXTS = [\".zip\", \".mcpack\", \".mcaddon\"] as const;\n\n/** \u6EE4\u6389 \u00A7x\uFF08Minecraft \u683C\u5F0F\u7801\uFF09\u3001\u6B8B\u4F59\u538B\u7F29\u540E\u7F00\uFF0C\u52A0 [BP]/[RP] \u524D\u7F00 */\nexport function formatWorldPackFolderName(rawName: string, kind: WorldPackKind): string {\n let s = String(rawName ?? \"\");\n s = s.replace(/\u00A7[0-9a-zA-Z]/g, \"\");\n s = s.replace(/\\.(zip|mcpack|mcaddon)$/i, \"\");\n s = s.replace(/\\s+/g, \" \").trim();\n if (!s) s = \"pack\";\n const prefix = kind === \"resource\" ? \"[RP]\" : \"[BP]\";\n if (s.startsWith(\"[RP]\") || s.startsWith(\"[BP]\")) return s;\n return `${prefix} ${s}`;\n}\n\n/** \u53BB\u6389\u5DF2\u6709 [BP]/[RP] \u524D\u7F00\uFF0C\u5F97\u5230\u6587\u4EF6\u5939\u540D\u4E3B\u5E72 */\nexport function stripWorldPackFolderPrefix(rawName: string): string {\n return String(rawName ?? \"\")\n .replace(/^\\[BP\\]\\s*/i, \"\")\n .replace(/^\\[RP\\]\\s*/i, \"\")\n .replace(/\\.(zip|mcpack|mcaddon)$/i, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\n/**\n * \u5F52\u6863\u5185\u5E38\u89C1\u5360\u4F4D\u76EE\u5F55\u540D\uFF08B / R / BP / RP\uFF09\u8FC7\u77ED\u6216\u8FC7\u6CDB\uFF0C\u4E0D\u80FD\u4F5C\u4E3A\u4E16\u754C\u76EE\u5F55\u540D\uFF0C\n * \u5426\u5219\u4E0D\u540C\u5305\u4F1A\u649E\u5230\u540C\u4E00\u8DEF\u5F84\u5E76\u88AB\u8BEF\u5224\u4E3A\u300C\u8986\u76D6\u300D\u3002\n */\nexport function isGenericPackFolderStem(rawName: string): boolean {\n const s = stripWorldPackFolderPrefix(rawName);\n if (!s) return true;\n if (s.length <= 2) return true;\n return /^(bp|rp|b|r|pack|packs|behavior|behaviours?|resource|resources)$/i.test(s);\n}\n\n/**\n * \u9009\u5B9A\u5B89\u88C5\u6587\u4EF6\u5939\u540D\uFF1Ahint \u8FC7\u6CDB\u65F6\u6539\u7528 manifest.name\uFF1B\u518D\u4E0E\u5DF2\u5360\u7528\u540D\u907F\u8BA9\uFF08\u4E0D\u540C uuid \u4E0D\u4E92\u76F8\u8986\u76D6\uFF09\u3002\n * \u7EAF\u51FD\u6570\uFF1A\u53EA\u4F9D\u8D56 taken \u96C6\u5408\uFF0C\u4FBF\u4E8E\u8868\u9A71\u52A8\u5355\u6D4B\uFF08DRY\uFF1Adecide / choose \u5171\u7528\uFF09\u3002\n */\nexport function allocatePackFolderName(opts: {\n hint?: string;\n info: PackManifestInfo;\n takenFolderNames: Iterable<string>;\n /** \u540C uuid \u66F4\u65B0\u65F6\u5141\u8BB8\u5360\u7528\u7684\u5DF2\u6709\u76EE\u5F55\u540D\uFF08\u4E0D\u89E6\u53D1\u907F\u8BA9\uFF09 */\n allowFolderName?: string;\n}): string {\n const hint = (opts.hint && opts.hint.trim()) || \"\";\n const preferred = isGenericPackFolderStem(hint) ? opts.info.name || hint || \"pack\" : hint;\n let folderName = formatWorldPackFolderName(preferred, opts.info.kind);\n const allow = opts.allowFolderName ? path.basename(opts.allowFolderName) : null;\n if (allow && folderName === allow) return folderName;\n\n const taken = new Set([...opts.takenFolderNames].filter((n) => n !== allow));\n if (!taken.has(folderName)) return folderName;\n\n /* \u540C\u540D\u4E0D\u540C\u5305\uFF1Amanifest \u540D + uuid \u524D\u7F00\uFF1B\u4ECD\u649E\u5219\u9012\u589E */\n const withUuid = formatWorldPackFolderName(\n `${stripWorldPackFolderPrefix(preferred)} ${opts.info.uuid.slice(0, 8)}`,\n opts.info.kind\n );\n if (!taken.has(withUuid)) return withUuid;\n let i = 2;\n while (taken.has(`${withUuid}_${i}`)) i++;\n return `${withUuid}_${i}`;\n}\n\n/**\n * \u9009\u5B9A\u5B89\u88C5\u6587\u4EF6\u5939\u540D\uFF08\u8BFB destParent \u5360\u7528\uFF09\u3002\n * \u51B3\u7B56\u6743\u5A01\u89C1 allocatePackFolderName / decidePackInstallPlan\u3002\n */\nexport function choosePackInstallFolderName(opts: {\n hint?: string;\n info: PackManifestInfo;\n destParent: string;\n allowFolderName?: string;\n}): string {\n const taken = listPackDirsIn(opts.destParent).map((d) => path.basename(d));\n return allocatePackFolderName({\n info: opts.info,\n takenFolderNames: taken,\n ...(opts.hint !== undefined ? { hint: opts.hint } : {}),\n ...(opts.allowFolderName !== undefined ? { allowFolderName: opts.allowFolderName } : {}),\n });\n}\n\n/** \u6839\u636E manifest modules[].type \u5224\u5B9A BP / RP */\nexport function detectPackKindFromManifest(raw: { modules?: Array<{ type?: string }> }): WorldPackKind | null {\n const types = (raw.modules ?? []).map((m) => String(m.type ?? \"\").toLowerCase());\n if (types.includes(\"resources\")) return \"resource\";\n if (types.some((t) => t === \"script\" || t === \"data\" || t === \"javascript\")) return \"behavior\";\n return null;\n}\n\n/**\n * \u89E3\u6790 manifest \u4E2D\u7684\u672C\u5730\u5316\u952E\uFF08\u4F8B\u5982 pack.name\uFF09\u3002\n *\n * \u8BED\u8A00\u6587\u4EF6\u4F18\u5148\u9075\u5FAA texts/languages.json \u7684\u58F0\u660E\u987A\u5E8F\uFF1B\u58F0\u660E\u7F3A\u5931\u6216\u4E0D\u5B8C\u6574\u65F6\uFF0C\n * \u518D\u626B\u63CF texts \u4E0B\u5176\u4F59 .lang \u6587\u4EF6\u3002\u627E\u4E0D\u5230\u5BF9\u5E94\u952E\u65F6\u4FDD\u7559 manifest \u539F\u503C\u3002\n */\nexport function resolvePackLocalizedText(packDir: string, value: string): string {\n const textsDir = path.join(packDir, \"texts\");\n if (!value || !fs.existsSync(textsDir)) return value;\n\n const languageFiles: string[] = [];\n const seen = new Set<string>();\n const addLanguageFile = (fileName: string): void => {\n const normalized = path.basename(fileName);\n if (!normalized.toLowerCase().endsWith(\".lang\") || seen.has(normalized.toLowerCase())) return;\n seen.add(normalized.toLowerCase());\n languageFiles.push(path.join(textsDir, normalized));\n };\n\n try {\n const declared = readJsonFile<unknown>(path.join(textsDir, \"languages.json\"));\n if (Array.isArray(declared)) {\n for (const locale of declared) {\n if (typeof locale === \"string\" && locale.trim()) addLanguageFile(`${locale.trim()}.lang`);\n }\n }\n } catch {\n // languages.json \u53EF\u9009\u4E14\u7B2C\u4E09\u65B9\u5305\u4E2D\u5076\u6709\u635F\u574F\uFF0C\u7EE7\u7EED\u56DE\u9000\u626B\u63CF .lang \u6587\u4EF6\u3002\n }\n\n try {\n for (const entry of fs.readdirSync(textsDir, { withFileTypes: true })) {\n if (entry.isFile()) addLanguageFile(entry.name);\n }\n } catch {\n return value;\n }\n\n for (const file of languageFiles) {\n if (!fs.existsSync(file)) continue;\n try {\n const lines = fs.readFileSync(file, \"utf8\").replace(/^\\uFEFF/, \"\").split(/\\r?\\n/);\n for (const line of lines) {\n const trimmed = line.trimStart();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const separator = line.indexOf(\"=\");\n if (separator < 0 || line.slice(0, separator).trim() !== value) continue;\n const localized = line.slice(separator + 1).trim();\n if (localized) return localized;\n }\n } catch {\n // \u5355\u4E2A\u8BED\u8A00\u6587\u4EF6\u4E0D\u53EF\u8BFB\u65F6\u7EE7\u7EED\u5C1D\u8BD5\u5176\u4ED6\u8BED\u8A00\uFF0C\u907F\u514D\u6574\u4E2A\u5305\u5931\u53BB\u5C55\u793A\u4FE1\u606F\u3002\n }\n }\n return value;\n}\n\nexport function readPackManifestInfo(packDir: string): PackManifestInfo | null {\n const file = path.join(packDir, \"manifest.json\");\n if (!fs.existsSync(file)) return null;\n try {\n const raw = readJsonFile<{\n header?: { name?: string; uuid?: string; version?: number[]; description?: string };\n modules?: Array<{ type?: string }>;\n }>(file);\n const kind = detectPackKindFromManifest(raw);\n const uuid = raw.header?.uuid;\n const ver = raw.header?.version;\n const name = raw.header?.name;\n if (!kind || typeof uuid !== \"string\" || !Array.isArray(ver) || ver.length < 3) return null;\n if (typeof name !== \"string\" || !name) return null;\n const version: [number, number, number] = [Number(ver[0]), Number(ver[1]), Number(ver[2])];\n const description = raw.header?.description;\n return {\n name: resolvePackLocalizedText(packDir, name),\n uuid,\n version,\n kind,\n ...(typeof description === \"string\"\n ? { description: resolvePackLocalizedText(packDir, description) }\n : {}),\n };\n } catch {\n return null;\n }\n}\n\n/** \u6DF1\u5EA6\u4F18\u5148\u627E\u542B manifest.json \u7684\u5305\u6839\uFF08\u9ED8\u8BA4 maxDepth=2\uFF0Croot \u81EA\u8EAB\u4E3A depth 0\uFF09 */\nexport function discoverPackRoots(root: string, opts?: { maxDepth?: number }): string[] {\n const maxDepth = opts?.maxDepth ?? 2;\n const out: string[] = [];\n const abs = path.resolve(root);\n if (!fs.existsSync(abs)) return out;\n\n function walk(dir: string, depth: number): void {\n const manifest = path.join(dir, \"manifest.json\");\n if (fs.existsSync(manifest) && fs.statSync(manifest).isFile()) {\n out.push(dir);\n return; // \u5305\u6839\u4E0D\u518D\u4E0B\u94BB\n }\n if (depth >= maxDepth) return;\n let entries;\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const e of entries) {\n if (!e.isDirectory()) continue;\n if (e.name.startsWith(\".\") || e.name === \"node_modules\") continue;\n walk(path.join(dir, e.name), depth + 1);\n }\n }\n\n const st = fs.statSync(abs);\n if (st.isDirectory()) walk(abs, 0);\n return out;\n}\n\nexport function isPackArchive(filePath: string): boolean {\n const lower = filePath.toLowerCase();\n return ARCHIVE_EXTS.some((ext) => lower.endsWith(ext));\n}\n\n/** \u53BB\u6389 .zip/.mcpack/.mcaddon \u540E\u7F00\u5F97\u5230 stem */\nfunction archiveStem(filePath: string): string {\n const base = path.basename(filePath);\n const lower = base.toLowerCase();\n for (const ext of ARCHIVE_EXTS) {\n if (lower.endsWith(ext)) return base.slice(0, -ext.length);\n }\n return path.parse(base).name;\n}\n\n/** \u5F52\u6863\u89E3\u538B\u76EE\u6807\uFF1A\u540C\u7EA7 stem \u76EE\u5F55\uFF1B\u91CD\u540D\u5219\u52A0 _2/_3\u2026 */\nfunction uniqueSiblingExtractDir(archivePath: string): string {\n const parent = path.dirname(archivePath);\n let dest = path.join(parent, archiveStem(archivePath) || \"pack\");\n if (!fs.existsSync(dest)) return dest;\n let i = 2;\n while (fs.existsSync(`${dest}_${i}`)) i++;\n return `${dest}_${i}`;\n}\n\n/**\n * \u5217\u51FA\u76EE\u5F55\u6811\u5185\u7684\u5305\u5F52\u6863\u6587\u4EF6\u3002\n * \u5DF2\u662F\u5305\u6839\uFF08\u542B manifest.json\uFF09\u7684\u76EE\u5F55\u4E0D\u518D\u4E0B\u94BB\uFF0C\u907F\u514D\u8BEF\u89E3\u538B\u5305\u5185\u8D44\u6E90\u3002\n */\nexport function listPackArchiveFiles(root: string, opts?: { maxDepth?: number }): string[] {\n const maxDepth = opts?.maxDepth ?? 4;\n const out: string[] = [];\n const abs = path.resolve(root);\n if (!fs.existsSync(abs) || !fs.statSync(abs).isDirectory()) return out;\n\n function walk(dir: string, depth: number): void {\n if (fs.existsSync(path.join(dir, \"manifest.json\"))) return;\n let entries;\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const e of entries) {\n if (e.name.startsWith(\".\") || e.name === \"node_modules\") continue;\n const full = path.join(dir, e.name);\n if (e.isFile() && isPackArchive(full)) {\n out.push(full);\n continue;\n }\n if (e.isDirectory() && depth < maxDepth) walk(full, depth + 1);\n }\n }\n\n walk(abs, 0);\n return out;\n}\n\n/**\n * \u5728\u4E34\u65F6\u6811\u5185\u539F\u5730\u5C55\u5F00\u5D4C\u5957\u5F52\u6863\uFF1A\u89E3\u538B\u5230\u540C\u7EA7\u76EE\u5F55\u5E76\u5220\u9664\u5F52\u6863\u6587\u4EF6\uFF0C\u591A\u8F6E\u76F4\u81F3\u6CA1\u6709\u65B0\u5F52\u6863\u3002\n * \u4EC5\u5E94\u5BF9\u6211\u4EEC\u81EA\u5DF1\u7684 staging\uFF0C\u7981\u6B62\u7528\u4E8E\u7528\u6237 inbox \u539F\u76EE\u5F55\u3002\n */\nexport async function expandNestedArchivesInPlace(\n workDir: string,\n opts?: { maxRounds?: number; maxScanDepth?: number }\n): Promise<number> {\n const maxRounds = opts?.maxRounds ?? 3;\n const maxScanDepth = opts?.maxScanDepth ?? 4;\n let expanded = 0;\n for (let round = 0; round < maxRounds; round++) {\n const archives = listPackArchiveFiles(workDir, { maxDepth: maxScanDepth });\n if (archives.length === 0) break;\n for (const arch of archives) {\n const dest = uniqueSiblingExtractDir(arch);\n await fs.promises.mkdir(dest, { recursive: true });\n await extractZipFileToDir(arch, dest);\n await fs.promises.unlink(arch);\n expanded++;\n }\n }\n return expanded;\n}\n\nexport type ResolvePackRootsResult = {\n roots: string[];\n /** \u6E05\u7406\u672C\u8F6E\u521B\u5EFA\u7684\u5168\u90E8\u4E34\u65F6\u76EE\u5F55\uFF08\u53EF\u5B89\u5168\u591A\u6B21\u8C03\u7528\uFF09 */\n dispose: () => void;\n};\n\n/**\n * \u7EDF\u4E00\u5305\u6839\u89E3\u6790\uFF1A\u76EE\u5F55 / \u9876\u5C42\u5F52\u6863 / \u5D4C\u5957 .mcpack|.zip|.mcaddon\u3002\n * \u89C4\u5219\uFF1A\u5148\u5C55\u5F00\u5F52\u6863\u4E3A\u76EE\u5F55\u6811\uFF0C\u518D\u53EA\u8BA4\u542B manifest.json \u7684\u76EE\u5F55\u4E3A\u5305\u6839\u3002\n * \u7528\u6237\u76EE\u5F55\u5185\u7684\u5D4C\u5957\u5F52\u6863\u89E3\u5230\u72EC\u7ACB temp\uFF0C\u4E0D\u4FEE\u6539\u539F\u76EE\u5F55\u3002\n */\nexport async function resolvePackRoots(\n src: string,\n opts?: { maxDirDepth?: number; maxArchiveRounds?: number }\n): Promise<ResolvePackRootsResult> {\n const maxDirDepth = opts?.maxDirDepth ?? 4;\n const maxArchiveRounds = opts?.maxArchiveRounds ?? 3;\n const temps: string[] = [];\n const dispose = (): void => {\n for (const d of temps.splice(0, temps.length)) {\n try {\n fs.rmSync(d, { recursive: true, force: true });\n } catch {\n /* ignore */\n }\n }\n };\n\n const abs = path.resolve(src);\n if (!fs.existsSync(abs)) return { roots: [], dispose };\n\n try {\n const st = fs.statSync(abs);\n if (st.isFile()) {\n if (!isPackArchive(abs)) return { roots: [], dispose };\n const tmp = await extractArchiveToTemp(abs);\n temps.push(tmp);\n await expandNestedArchivesInPlace(tmp, {\n maxRounds: maxArchiveRounds,\n maxScanDepth: maxDirDepth,\n });\n return { roots: discoverPackRoots(tmp, { maxDepth: maxDirDepth }), dispose };\n }\n\n if (!st.isDirectory()) return { roots: [], dispose };\n\n const nestedArchives = listPackArchiveFiles(abs, { maxDepth: maxDirDepth });\n if (nestedArchives.length === 0) {\n return { roots: discoverPackRoots(abs, { maxDepth: maxDirDepth }), dispose };\n }\n\n /* \u76EE\u5F55\u5305\u6839 + \u5404\u5D4C\u5957\u5F52\u6863\u5404\u81EA\u89E3\u5230 temp\uFF08\u4E0D\u6539\u7528\u6237\u76EE\u5F55\uFF09 */\n const roots = discoverPackRoots(abs, { maxDepth: maxDirDepth });\n const seen = new Set(roots.map((r) => path.resolve(r)));\n for (const arch of nestedArchives) {\n const tmp = await extractArchiveToTemp(arch);\n temps.push(tmp);\n await expandNestedArchivesInPlace(tmp, {\n maxRounds: maxArchiveRounds,\n maxScanDepth: maxDirDepth,\n });\n for (const r of discoverPackRoots(tmp, { maxDepth: maxDirDepth })) {\n const key = path.resolve(r);\n if (seen.has(key)) continue;\n seen.add(key);\n roots.push(r);\n }\n }\n return { roots, dispose };\n } catch (e) {\n dispose();\n throw e;\n }\n}\n\n/** \u89E3\u538B zip/mcpack/mcaddon \u5230\u4E34\u65F6\u76EE\u5F55\uFF0C\u8FD4\u56DE\u8BE5\u76EE\u5F55\uFF08\u7ECF zipx \u9632 zip-slip\uFF09 */\nexport async function extractArchiveToTemp(filePath: string): Promise<string> {\n const tmp = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-pack-\"));\n await extractZipFileToDir(filePath, tmp);\n return tmp;\n}\n\nfunction listPackDirsIn(parent: string): string[] {\n if (!fs.existsSync(parent)) return [];\n const out: string[] = [];\n for (const e of fs.readdirSync(parent, { withFileTypes: true })) {\n if (!e.isDirectory()) continue;\n const dir = path.join(parent, e.name);\n if (fs.existsSync(path.join(dir, \"manifest.json\"))) out.push(dir);\n }\n return out;\n}\n\n/** \u626B\u63CF\u4E16\u754C\u5185\u5DF2\u5B89\u88C5 BP/RP \u76EE\u5F55 */\nexport function listInstalledWorldPacks(bdsRoot: string, levelName: string): InstalledWorldPack[] {\n const worldRoot = bdsWorldLevelDir(bdsRoot, levelName);\n const worldsDir = bdsWorldsDir(bdsRoot);\n const result: InstalledWorldPack[] = [];\n\n for (const kind of [\"behavior\", \"resource\"] as const) {\n const parent = path.join(worldRoot, kind === \"behavior\" ? \"behavior_packs\" : \"resource_packs\");\n const enabledList = readWorldPackList(worldsDir, levelName, kind);\n const enabledMap = new Map(enabledList.map((e) => [e.pack_id, e.version] as const));\n\n for (const dir of listPackDirsIn(parent)) {\n const info = readPackManifestInfo(dir);\n if (!info || info.kind !== kind) {\n // \u4ECD\u5C1D\u8BD5\u7528 header \u5C55\u793A\uFF08enabled \u4E0E\u6B63\u5E38\u8DEF\u5F84\u540C\u5951\u7EA6\uFF1Aenable-list \u542B uuid \u2192 LSP\uFF09\n const header = readPackManifestHeader(dir);\n if (!header) continue;\n result.push({\n kind,\n folderName: path.basename(dir),\n dir,\n name: path.basename(dir),\n uuid: header.uuid,\n version: header.version,\n enabled: enabledMap.has(header.uuid),\n });\n continue;\n }\n result.push({\n kind: info.kind,\n folderName: path.basename(dir),\n dir,\n name: info.name,\n uuid: info.uuid,\n version: info.version,\n enabled: enabledMap.has(info.uuid),\n });\n }\n }\n return result;\n}\n\n/**\n * \u5C06\u76EE\u6807\u5305 manifest.json \u4E2D\u7684 Patch \u7248\u672C\u53F7\u9012\u589E\uFF08+1\uFF09\u5E76\u6301\u4E45\u5316\u5199\u56DE\u3002\n *\n * @param packDir \u5305\u6839\u76EE\u5F55\u8DEF\u5F84\u3002\n * @returns \u9012\u589E\u540E\u7684\u7248\u672C\u4E09\u5143\u7EC4 `[major, minor, patch]`\u3002\n */\nexport function bumpPackPatchVersion(packDir: string): [number, number, number] {\n const file = path.join(packDir, \"manifest.json\");\n if (!fs.existsSync(file)) throw new Error(`manifest.json missing: ${packDir}`);\n const raw = readJsonFile<{\n header?: { version?: number[] };\n modules?: Array<{ version?: number[] }>;\n }>(file);\n const ver = raw.header?.version;\n if (!Array.isArray(ver) || ver.length < 3) throw new Error(`invalid header.version in ${file}`);\n const next: [number, number, number] = [Number(ver[0]), Number(ver[1]), Number(ver[2]) + 1];\n return writePackHeaderVersion(packDir, next);\n}\n\n/**\n * \u5411\u76EE\u6807\u5305\u7684 manifest.json \u5199\u5165\u65B0\u7684\u7248\u672C\u53F7\uFF0C\u5E76\u540C\u6B65\u66F4\u65B0\u5185\u90E8 modules \u7684 patch \u7248\u672C\u3002\n *\n * @param packDir \u5305\u6839\u76EE\u5F55\u8DEF\u5F84\u3002\n * @param next \u5F85\u5199\u5165\u7684\u7248\u672C\u4E09\u5143\u7EC4\u3002\n * @returns \u5199\u5165\u786E\u8BA4\u7684\u7248\u672C\u4E09\u5143\u7EC4\u3002\n */\nexport function writePackHeaderVersion(packDir: string, next: [number, number, number]): [number, number, number] {\n const file = path.join(packDir, \"manifest.json\");\n if (!fs.existsSync(file)) throw new Error(`manifest.json missing: ${packDir}`);\n const raw = readJsonFile<{\n header?: { version?: number[] };\n modules?: Array<{ version?: number[] }>;\n }>(file);\n if (!raw.header) raw.header = {};\n raw.header.version = next;\n if (Array.isArray(raw.modules)) {\n for (const m of raw.modules) {\n if (Array.isArray(m.version) && m.version.length >= 3) {\n m.version = [Number(m.version[0]), Number(m.version[1]), next[2]];\n }\n }\n }\n fs.writeFileSync(file, `${JSON.stringify(raw, null, 2)}\\n`, \"utf8\");\n return next;\n}\n\n/** \u8BFB\u53D6 BP manifest \u4E2D\u4F9D\u8D56\u7684\u8D44\u6E90\u5305 uuid\uFF08\u975E @minecraft \u6A21\u5757\uFF09 */\nexport function readPackDependencyUuids(packDir: string): string[] {\n const file = path.join(packDir, \"manifest.json\");\n if (!fs.existsSync(file)) return [];\n try {\n const raw = readJsonFile<{\n dependencies?: Array<{ uuid?: string; module_name?: string }>;\n }>(file);\n return (raw.dependencies ?? [])\n .map((d) => d.uuid)\n .filter((u): u is string => typeof u === \"string\" && u.length > 0);\n } catch {\n return [];\n }\n}\n\n/** \u6BD4\u8F83 SemVer \u4E09\u5143\u7EC4\uFF1Ba>b \u6B63\uFF0Ca<b \u8D1F\uFF0C\u76F8\u7B49 0 */\nexport function compareSemVer3(a: [number, number, number], b: [number, number, number]): number {\n for (let i = 0; i < 3; i++) {\n const d = a[i]! - b[i]!;\n if (d !== 0) return d;\n }\n return 0;\n}\n\n/** \u53D6\u8F83\u5927\u7684 SemVer \u4E09\u5143\u7EC4 */\nexport function maxSemVer3(a: [number, number, number], b: [number, number, number]): [number, number, number] {\n return compareSemVer3(a, b) >= 0 ? a : b;\n}\n\n/** \u6309 component \u62AC\u4E00\u7EA7 */\nexport function bumpSemVer3(v: [number, number, number], component: \"patch\" | \"minor\"): [number, number, number] {\n return component === \"minor\" ? [v[0], v[1] + 1, 0] : [v[0], v[1], v[2] + 1];\n}\n\n/**\n * \u8FDB\u670D\u542F\u7528\u7248\u672C\uFF1Amax(\u8FDC\u7A0B/\u65B0\u5305, \u65E7\u542F\u7528) \u518D\u62AC\u4E00\u7EA7\u3002\n * \u5355\u4E00\u89C4\u5219\uFF0C\u7981\u6B62 while \u8FFD\u8D76\uFF08\u4F5C\u8005\u4E71\u5199\u9AD8\u7248\u672C\u5982 [1,21,100] \u65F6\u4E5F\u80FD\u4E00\u6B21\u7B97\u5B8C\uFF09\u3002\n */\nexport function nextEnabledVersion(\n remote: [number, number, number],\n previous: [number, number, number],\n component: \"patch\" | \"minor\" = \"patch\"\n): [number, number, number] {\n return bumpSemVer3(maxSemVer3(remote, previous), component);\n}\n\n/**\n * \u5C06\u5305\u76EE\u5F55 manifest \u62AC\u5230 nextEnabledVersion(\u5F53\u524D, previous)\u3002\n * previous \u4E00\u822C\u4E3A\u66F4\u65B0\u524D\u5DF2\u5B89\u88C5 RP / \u4E16\u754C enable \u5217\u8868\u4E2D\u7684\u7248\u672C\u3002\n */\nexport function ensureVersionGreaterThan(\n packDir: string,\n previous: [number, number, number],\n component: \"patch\" | \"minor\" = \"patch\"\n): [number, number, number] {\n const info = readPackManifestInfo(packDir);\n if (!info) throw new Error(`cannot read pack version: ${packDir}`);\n const next = nextEnabledVersion(info.version, previous, component);\n return writePackHeaderVersion(packDir, next);\n}\n\nexport interface InstallPackResult {\n ok: boolean;\n skipped?: boolean;\n reason?: string;\n destDir?: string;\n folderName?: string;\n info?: PackManifestInfo;\n conflict?: { existing: PackManifestInfo & { dir: string }; incoming: PackManifestInfo };\n}\n\n/** \u76EE\u6807\u7236\u76EE\u5F55\u5185\u5DF2\u5360\u7528\u9879\uFF08\u4F9B\u7EAF\u51B3\u7B56\uFF0C\u4E0D\u542B FS \u526F\u4F5C\u7528\uFF09 */\nexport type DestOccupancy = {\n folderName: string;\n dir: string;\n uuid: string | null;\n version: [number, number, number] | null;\n /** \u53EF\u8BFB\u65F6\u7684\u5C55\u793A\u540D\uFF1B\u51B3\u7B56\u4E0D\u4F9D\u8D56\uFF0C\u4EC5\u4F9B conflict UI */\n name?: string;\n /** \u53EF\u8BFB\u65F6\u7684\u5305\u7C7B\u578B\uFF1B\u51B3\u7B56\u5C55\u793A\u4F18\u5148\u7528\u771F\u5B9E kind\uFF0C\u907F\u514D\u4F2A\u9020 incoming.kind\uFF08LSP\uFF09 */\n kind?: WorldPackKind;\n};\n\nexport type PackInstallPlan =\n | { kind: \"fresh\"; folderName: string; incoming: PackManifestInfo }\n | {\n kind: \"overwriteInPlace\";\n folderName: string;\n dir: string;\n incoming: PackManifestInfo;\n existing: PackManifestInfo & { dir: string };\n }\n | {\n kind: \"needConfirm\";\n folderName: string;\n dir: string;\n incoming: PackManifestInfo;\n existing: PackManifestInfo & { dir: string };\n };\n\n/**\n * \u8BFB\u5355\u76EE\u5F55\u5360\u7528\u4E8B\u5B9E\uFF08info \u4F18\u5148\uFF0C\u5426\u5219 header\uFF09\u3002\n * \u89E3\u6790\u5931\u8D25\u8FD4\u56DE null\uFF1B\u4E0D\u629B BOM\uFF08readJsonFile \u5DF2\u5265\u79BB\uFF09\u3002\n */\nexport function readPackDirOccupancy(dir: string): {\n uuid: string;\n version: [number, number, number];\n name?: string;\n kind?: WorldPackKind;\n} | null {\n const info = readPackManifestInfo(dir);\n if (info) {\n return {\n uuid: info.uuid,\n version: info.version,\n name: info.name,\n kind: info.kind,\n };\n }\n const header = readPackManifestHeader(dir);\n if (header) {\n return { uuid: header.uuid, version: header.version };\n }\n return null;\n}\n\n/** \u626B\u63CF destParent \u4E0B\u542B manifest \u7684\u76EE\u5F55\u5360\u7528\uFF08\u5355\u4E00\u4E8B\u5B9E\u6E90\uFF1AreadPackDirOccupancy\uFF09 */\nexport function scanDestOccupancy(destParent: string): DestOccupancy[] {\n const out: DestOccupancy[] = [];\n for (const dir of listPackDirsIn(destParent)) {\n let facts: ReturnType<typeof readPackDirOccupancy> = null;\n try {\n // DRY\uFF1A\u4E0E readPackDirOccupancy \u5171\u7528 info\u2192header \u56DE\u9000\uFF0C\u7981\u6B62\u5185\u8054\u53CC\u8BFB\n facts = readPackDirOccupancy(dir);\n } catch {\n /* manifest \u4E0D\u53EF\u8BFB\u5219\u5360\u4F4D uuid \u4E3A\u7A7A */\n }\n out.push({\n folderName: path.basename(dir),\n dir,\n uuid: facts?.uuid ?? null,\n version: facts?.version ?? null,\n ...(facts?.name ? { name: facts.name } : {}),\n ...(facts?.kind ? { kind: facts.kind } : {}),\n });\n }\n return out;\n}\n\n/**\n * \u7EAF\u51B3\u7B56\uFF1A\u88C5\u5230\u54EA\u3001\u662F\u5426\u9700\u786E\u8BA4\u3001\u662F\u5426\u539F\u5730\u8986\u76D6\u3002\n * \u540C uuid\uFF1Aincoming \u7248\u672C\u4E25\u683C\u66F4\u5927 \u2192 \u9759\u9ED8\u8986\u76D6\uFF1B\u2264 \u5DF2\u6709\u4E14 !force \u2192 needConfirm\uFF1Bforce \u2192 \u539F\u5730\u8986\u76D6\u3002\n */\nexport function decidePackInstallPlan(opts: {\n incoming: PackManifestInfo;\n hint?: string;\n occupancy: readonly DestOccupancy[];\n force?: boolean;\n}): PackInstallPlan {\n const force = Boolean(opts.force);\n const incomingUuid = opts.incoming.uuid.toLowerCase();\n const same = opts.occupancy.find((o) => o.uuid != null && o.uuid.toLowerCase() === incomingUuid);\n\n if (same) {\n const existingVersion: [number, number, number] = same.version ?? [0, 0, 0];\n const existing: PackManifestInfo & { dir: string } = {\n name: same.name ?? same.folderName,\n uuid: same.uuid!,\n version: existingVersion,\n kind: same.kind ?? opts.incoming.kind,\n dir: same.dir,\n };\n\n const newer = compareSemVer3(opts.incoming.version, existing.version) > 0;\n if (force || newer) {\n return {\n kind: \"overwriteInPlace\",\n folderName: same.folderName,\n dir: same.dir,\n incoming: opts.incoming,\n existing,\n };\n }\n return {\n kind: \"needConfirm\",\n folderName: same.folderName,\n dir: same.dir,\n incoming: opts.incoming,\n existing,\n };\n }\n\n const folderName = allocatePackFolderName({\n info: opts.incoming,\n takenFolderNames: opts.occupancy.map((o) => o.folderName),\n ...(opts.hint !== undefined ? { hint: opts.hint } : {}),\n });\n return { kind: \"fresh\", folderName, incoming: opts.incoming };\n}\n\n/** \u843D\u76D8\u540E\u6821\u9A8C\uFF1A\u9632\u6B62\u65C1\u8DEF\u5B89\u88C5 / \u62F7\u8D1D\u5931\u8D25\u4ECD\u62A5\u6210\u529F */\nexport function verifyInstalledPack(\n destDir: string,\n incoming: PackManifestInfo\n): { ok: true; info: PackManifestInfo } | { ok: false; reason: string } {\n const info = readPackManifestInfo(destDir);\n if (!info) return { ok: false, reason: \"verify: dest has no readable manifest\" };\n if (info.uuid.toLowerCase() !== incoming.uuid.toLowerCase()) {\n return { ok: false, reason: `verify: uuid mismatch got=${info.uuid} want=${incoming.uuid}` };\n }\n if (info.kind !== incoming.kind) {\n return { ok: false, reason: `verify: kind mismatch got=${info.kind} want=${incoming.kind}` };\n }\n if (compareSemVer3(info.version, incoming.version) !== 0) {\n return {\n ok: false,\n reason: `verify: version mismatch got=${info.version.join(\".\")} want=${incoming.version.join(\".\")}`,\n };\n }\n return { ok: true, info };\n}\n\n/**\n * \u5C06\u5305\u76EE\u5F55\u5B89\u88C5\u5230 destParent\uFF08behavior_packs \u6216 resource_packs\uFF09\u3002\n * \u7F16\u6392\uFF1Ascan \u2192 decide \u2192 apply \u2192 verify\u3002\u540C uuid \u7248\u672C\u66F4\u9AD8\u65F6\u9759\u9ED8\u539F\u5730\u8986\u76D6\u3002\n */\nexport async function installPackDirectory(opts: {\n srcDir: string;\n destParent: string;\n folderName?: string;\n force?: boolean;\n}): Promise<InstallPackResult> {\n const info = readPackManifestInfo(opts.srcDir);\n if (!info) {\n return { ok: false, reason: \"invalid or unrecognized manifest.json\" };\n }\n\n await fs.promises.mkdir(opts.destParent, { recursive: true });\n\n const occupancy = scanDestOccupancy(opts.destParent);\n const plan = decidePackInstallPlan({\n incoming: info,\n hint: opts.folderName ?? path.basename(opts.srcDir),\n occupancy,\n ...(opts.force !== undefined ? { force: opts.force } : {}),\n });\n\n if (plan.kind === \"needConfirm\") {\n return {\n ok: false,\n skipped: true,\n reason: \"conflict\",\n conflict: {\n existing: plan.existing,\n incoming: info,\n },\n };\n }\n\n const destDir = path.join(opts.destParent, plan.folderName);\n if (plan.kind === \"overwriteInPlace\" && path.resolve(plan.dir) !== path.resolve(destDir)) {\n return {\n ok: false,\n reason: `invariant: overwrite path drift plan.dir=${plan.dir} destDir=${destDir}`,\n };\n }\n\n if (fs.existsSync(destDir)) {\n await fs.promises.rm(destDir, { recursive: true, force: true });\n }\n await copyDirAsync(opts.srcDir, destDir);\n\n const verified = verifyInstalledPack(destDir, info);\n if (!verified.ok) {\n return { ok: false, reason: verified.reason, folderName: plan.folderName, info };\n }\n return { ok: true, destDir, folderName: plan.folderName, info: verified.info };\n}\n\n/** \u5B89\u88C5\u540E\u5199\u5165\u4E16\u754C enable \u6E05\u5355 */\nexport async function enableInstalledPack(opts: {\n bdsRoot: string;\n levelName: string;\n info: PackManifestInfo;\n}): Promise<void> {\n await enablePackInWorld({\n worldsDir: bdsWorldsDir(opts.bdsRoot),\n levelName: opts.levelName,\n kind: opts.info.kind,\n packUuid: opts.info.uuid,\n version: opts.info.version,\n });\n}\n\n/** \u4ECE\u4E16\u754C enable \u6E05\u5355\u79FB\u9664 */\nexport async function disableInstalledPack(opts: {\n bdsRoot: string;\n levelName: string;\n kind: WorldPackKind;\n packUuid: string;\n version: [number, number, number];\n}): Promise<void> {\n await disablePackInWorld({\n worldsDir: bdsWorldsDir(opts.bdsRoot),\n levelName: opts.levelName,\n kind: opts.kind,\n packUuid: opts.packUuid,\n version: opts.version,\n });\n}\n\nexport type UninstallPackResult = { action: \"trashed\"; dest: string } | { action: \"deleted\" } | { action: \"missing\" };\n\nexport type UninstallPackAction = UninstallPackResult[\"action\"];\n\n/**\n * \u5378\u8F7D\u5DF2\u5B89\u88C5\u4E16\u754C\u5305\uFF1A\u5148 disable enable-list\uFF0C\u518D\u79FB\u5165 trashDir \u6216\u76F4\u63A5\u5220\u9664\u76EE\u5F55\u3002\n * trashDir \u8DE8\u76D8\u7B26\u65F6 fallback \u4E3A copy + rm\u3002\n */\nexport async function uninstallInstalledPack(opts: {\n bdsRoot: string;\n levelName: string;\n pack: InstalledWorldPack;\n /** \u63D0\u4F9B\u5219\u79FB\u5165\u8BE5\u76EE\u5F55\uFF1Bnull/\u7701\u7565\u5219\u76F4\u63A5\u5220\u9664 */\n trashDir?: string | null;\n}): Promise<UninstallPackResult> {\n await disableInstalledPack({\n bdsRoot: opts.bdsRoot,\n levelName: opts.levelName,\n kind: opts.pack.kind,\n packUuid: opts.pack.uuid,\n version: opts.pack.version,\n });\n\n if (!fs.existsSync(opts.pack.dir)) {\n return { action: \"missing\" };\n }\n\n const trashDir = opts.trashDir?.trim() || null;\n if (trashDir) {\n await fs.promises.mkdir(trashDir, { recursive: true });\n const stamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n let dest = path.join(trashDir, opts.pack.folderName);\n if (fs.existsSync(dest)) {\n dest = path.join(trashDir, `${opts.pack.folderName}-${stamp}`);\n }\n try {\n await fs.promises.rename(opts.pack.dir, dest);\n } catch {\n await copyDirAsync(opts.pack.dir, dest);\n await fs.promises.rm(opts.pack.dir, { recursive: true, force: true });\n }\n return { action: \"trashed\", dest };\n }\n\n await fs.promises.rm(opts.pack.dir, { recursive: true, force: true });\n return { action: \"deleted\" };\n}\n\nexport function worldPackParentDir(bdsRoot: string, levelName: string, kind: WorldPackKind): string {\n return path.join(bdsWorldLevelDir(bdsRoot, levelName), kind === \"behavior\" ? \"behavior_packs\" : \"resource_packs\");\n}\n\n/** \u4E16\u754C enable-list \u6743\u5A01\u8BFB\u53D6 \u2014 \u59D4\u6258 pack-manager\uFF08\u4F9B doctor \u7B49\uFF0C\u907F\u514D\u786C\u7F16\u7801\u6587\u4EF6\u540D\uFF09 */\nexport function listWorldEnableEntries(\n bdsRoot: string,\n levelName: string,\n kind: WorldPackKind\n): Array<{ pack_id: string; version: [number, number, number] }> {\n return listWorldEnableListResult(bdsRoot, levelName, kind).entries;\n}\n\n/** \u542B parseFail \u4FE1\u53F7\u7684 enable-list \u5FEB\u7167\uFF08doctor \u7528\uFF1B\u4E0D\u66B4\u9732 JSON \u8DEF\u5F84\u6784\u9020\u7EC6\u8282\uFF09 */\nexport function listWorldEnableListResult(\n bdsRoot: string,\n levelName: string,\n kind: WorldPackKind\n): WorldPackListReadResult {\n return readWorldPackListResult(bdsWorldsDir(bdsRoot), levelName, kind);\n}\n\nexport function findInstalledPackById(packs: InstalledWorldPack[], id: string): InstalledWorldPack | null {\n const q = id.trim().toLowerCase();\n return (\n packs.find(\n (p) =>\n p.uuid.toLowerCase() === q ||\n p.folderName.toLowerCase() === q ||\n p.name.toLowerCase() === q ||\n p.folderName.toLowerCase().includes(q) ||\n p.name.toLowerCase().includes(q)\n ) ?? null\n );\n}\n\nexport interface WorldBetaApiDiagnosis {\n hasBetaApis: boolean;\n levelDatExists: boolean;\n levelDatPath: string;\n requiringPacks: Array<{\n pack: InstalledWorldPack;\n betaDependencies: PackManifestDependency[];\n }>;\n}\n\nexport function isBetaApiDependency(dep: PackManifestDependency): boolean {\n return isGametestBetaRequired(dep);\n}\n\n/**\n * \u8BCA\u65AD\u6307\u5B9A\u4E16\u754C\u4E2D\u5DF2\u542F\u7528\u7684\u884C\u4E3A\u5305\u5BF9\u6D4B\u8BD5\u7248 API\uFF08Beta APIs\uFF09\u7684\u4F9D\u8D56\u4E0E level.dat \u7684\u5339\u914D\u72B6\u51B5\u3002\n */\nexport function checkWorldBetaApiRequirements(\n bdsRoot: string,\n levelName: string,\n installedPacks?: InstalledWorldPack[]\n): WorldBetaApiDiagnosis {\n const lPath = levelDatPath(bdsRoot, levelName);\n const exists = fs.existsSync(lPath);\n const expInfo = exists ? readLevelDatExperiments(lPath) : null;\n const hasBetaApis = expInfo?.hasBetaApis ?? false;\n\n const packs = installedPacks ?? listInstalledWorldPacks(bdsRoot, levelName);\n const requiringPacks: WorldBetaApiDiagnosis[\"requiringPacks\"] = [];\n\n for (const p of packs) {\n if (p.kind !== \"behavior\" || !p.enabled) continue;\n const deps = readPackManifestDependencies(p.dir);\n const betaDeps = deps.filter(isBetaApiDependency);\n if (betaDeps.length > 0) {\n requiringPacks.push({\n pack: p,\n betaDependencies: betaDeps,\n });\n }\n }\n\n return {\n hasBetaApis,\n levelDatExists: exists,\n levelDatPath: lPath,\n requiringPacks,\n };\n}\n\nexport interface WorldExperimentsDiagnosis {\n levelDatExists: boolean;\n levelDatPath: string;\n experimentsInfo: LevelDatExperimentsInfo | null;\n betaApis: WorldBetaApiDiagnosis;\n}\n\n/**\n * \u8BCA\u65AD\u6307\u5B9A\u4E16\u754C\u5B58\u6863\u7684\u5168\u90E8\u5B9E\u9A8C\u6027\u73A9\u6CD5\u5F00\u5173\u53CA\u4E0E\u5F53\u524D\u5DF2\u5B89\u88C5\u884C\u4E3A\u5305\u7684\u5339\u914D\u72B6\u51B5\u3002\n */\nexport function checkWorldExperimentsDiagnosis(\n bdsRoot: string,\n levelName: string,\n installedPacks?: InstalledWorldPack[]\n): WorldExperimentsDiagnosis {\n const betaApis = checkWorldBetaApiRequirements(bdsRoot, levelName, installedPacks);\n const info = betaApis.levelDatExists ? readLevelDatExperiments(betaApis.levelDatPath) : null;\n return {\n levelDatExists: betaApis.levelDatExists,\n levelDatPath: betaApis.levelDatPath,\n experimentsInfo: info,\n betaApis,\n };\n}\n\nexport interface WorldPermissionDiagnosis {\n missingPermissions: Array<{\n pack: InstalledWorldPack;\n moduleName: string;\n }>;\n}\n\n/**\n * \u8BCA\u65AD\u884C\u4E3A\u5305\u4F9D\u8D56\u7684\u539F\u751F\u6A21\u5757\uFF08\u5982 @minecraft/server-net, @minecraft/diagnostics \u7B49\uFF09\u662F\u5426\u5DF2\u5728 BDS config \u4E2D\u6388\u6743\u3002\n */\nexport function checkWorldScriptPermissions(\n bdsRoot: string,\n levelName: string,\n installedPacks?: InstalledWorldPack[]\n): WorldPermissionDiagnosis {\n const packs = installedPacks ?? listInstalledWorldPacks(bdsRoot, levelName);\n const defaultFile = path.join(bdsRoot, \"config\", \"default\", \"permissions.json\");\n const defaultModules = new Set<string>();\n if (fs.existsSync(defaultFile)) {\n try {\n const raw = readJsonFile<{ allowed_modules?: string[] }>(defaultFile);\n if (Array.isArray(raw.allowed_modules)) {\n for (const m of raw.allowed_modules) defaultModules.add(m);\n }\n } catch {}\n }\n\n const missingPermissions: WorldPermissionDiagnosis[\"missingPermissions\"] = [];\n\n for (const p of packs) {\n if (p.kind !== \"behavior\" || !p.enabled) continue;\n const deps = readPackManifestDependencies(p.dir);\n // \u68C0\u67E5\u53D7\u9650\u539F\u751F\u6A21\u5757\n const privilegedDeps = deps.filter((d) => {\n const m = d.module_name ?? \"\";\n return m === \"@minecraft/server-net\" || m === \"@minecraft/server-admin\" || m === \"@minecraft/diagnostics\";\n });\n\n if (privilegedDeps.length === 0) continue;\n\n const headerInfo = readPackManifestHeader(p.dir);\n const uuids = Array.from(new Set([p.uuid, ...(headerInfo?.moduleUuid ? [headerInfo.moduleUuid] : [])]));\n const packAllowed = new Set<string>();\n for (const u of uuids) {\n const f = path.join(bdsRoot, \"config\", u, \"permissions.json\");\n if (fs.existsSync(f)) {\n try {\n const raw = readJsonFile<{ allowed_modules?: string[] }>(f);\n if (Array.isArray(raw.allowed_modules)) {\n for (const m of raw.allowed_modules) packAllowed.add(m);\n }\n } catch {}\n }\n }\n\n for (const dep of privilegedDeps) {\n const mod = dep.module_name!;\n if (!defaultModules.has(mod) && !packAllowed.has(mod)) {\n missingPermissions.push({ pack: p, moduleName: mod });\n }\n }\n }\n\n return { missingPermissions };\n}\n\nexport interface RepairWorldPacksResult {\n cleanedGhostPacks: Array<{ kind: WorldPackKind; uuid: string }>;\n syncedVersions: Array<{\n kind: WorldPackKind;\n folder: string;\n listVer: string;\n diskVer: string;\n }>;\n betaApisResult?:\n | {\n attempted: boolean;\n changed: boolean;\n backupPath?: string | undefined;\n error?: string | undefined;\n }\n | undefined;\n experimentsResult?:\n | {\n attempted: boolean;\n changed: boolean;\n enabled: string[];\n backupPath?: string | undefined;\n error?: string | undefined;\n }\n | undefined;\n fixedPermissions?:\n | Array<{\n packName: string;\n moduleName: string;\n }>\n | undefined;\n}\n\n/**\n * \u81EA\u6108\u4E16\u754C\u8D44\u6E90\u5305/\u884C\u4E3A\u5305\u63A5\u7EBF\u95EE\u9898\uFF1A\n * 1. \u6E05\u7406\u6E05\u5355\u4E2D\u5DF2\u4E0D\u5B58\u5728\u4E8E\u78C1\u76D8\u7684\u5E7D\u7075\u5305 UUID \u6761\u76EE\n * 2. \u81EA\u52A8\u6821\u51C6\u6E05\u5355\u4E2D\u4E0E\u78C1\u76D8 manifest \u4E0D\u4E00\u81F4\u7684\u7248\u672C\u53F7\n * 3. \u81EA\u52A8\u8865\u9F50\u7F3A\u5931\u7684 Script API \u539F\u751F\u6A21\u5757\u6743\u9650\uFF08config/default/permissions.json\uFF09\n * 4. \u53EF\u9009\uFF1A\u81EA\u52A8\u4E3A level.dat \u5F00\u542F Beta APIs\uFF08\u82E5 fixBetaApis \u4E3A true\uFF09\u6216\u6307\u5B9A\u5B9E\u9A8C\u6027\u529F\u80FD\uFF08enableExperiments\uFF09\n */\nexport async function repairWorldPacksWiring(\n bdsRoot: string,\n levelName: string,\n opts?: {\n fixBetaApis?: boolean;\n enableExperiments?: string[] | \"all\";\n }\n): Promise<RepairWorldPacksResult> {\n const packs = listInstalledWorldPacks(bdsRoot, levelName);\n const cleanedGhostPacks: RepairWorldPacksResult[\"cleanedGhostPacks\"] = [];\n const syncedVersions: RepairWorldPacksResult[\"syncedVersions\"] = [];\n\n for (const kind of [\"behavior\", \"resource\"] as const) {\n const snap = listWorldEnableListResult(bdsRoot, levelName, kind);\n const byUuid = new Map(packs.filter((p) => p.kind === kind).map((p) => [p.uuid, p]));\n for (const e of snap.entries) {\n const p = byUuid.get(e.pack_id);\n if (!p) {\n // \u5E7D\u7075\u5305\uFF1A\u4ECE\u4E16\u754C\u6E05\u5355\u79FB\u9664\n const entryVer: [number, number, number] =\n Array.isArray(e.version) && e.version.length >= 3\n ? [Number(e.version[0]), Number(e.version[1]), Number(e.version[2])]\n : [1, 0, 0];\n await disablePackInWorld({\n worldsDir: bdsWorldsDir(bdsRoot),\n levelName,\n kind,\n packUuid: e.pack_id,\n version: entryVer,\n });\n cleanedGhostPacks.push({ kind, uuid: e.pack_id });\n } else {\n const ev = e.version;\n if (\n Array.isArray(ev) &&\n ev.length >= 3 &&\n (ev[0] !== p.version[0] || ev[1] !== p.version[1] || ev[2] !== p.version[2])\n ) {\n // \u7248\u672C\u9519\u4F4D\uFF1A\u6309\u78C1\u76D8\u7248\u672C\u91CD\u65B0\u6FC0\u6D3B\u540C\u6B65\n await enablePackInWorld({\n worldsDir: bdsWorldsDir(bdsRoot),\n levelName,\n kind,\n packUuid: p.uuid,\n version: p.version,\n });\n syncedVersions.push({\n kind,\n folder: p.folderName,\n listVer: ev.join(\".\"),\n diskVer: p.version.join(\".\"),\n });\n }\n }\n }\n }\n\n let betaApisResult: RepairWorldPacksResult[\"betaApisResult\"] = undefined;\n let experimentsResult: RepairWorldPacksResult[\"experimentsResult\"] = undefined;\n\n const shouldMutateExperiments = !!opts?.enableExperiments || !!opts?.fixBetaApis;\n if (shouldMutateExperiments) {\n const lPath = levelDatPath(bdsRoot, levelName);\n const targets: string[] | \"all\" = opts?.enableExperiments ?? (opts?.fixBetaApis ? [\"gametest\"] : []);\n const mutateRes = await enableExperimentsInLevelDat(lPath, targets);\n\n experimentsResult = {\n attempted: true,\n changed: mutateRes.changed,\n enabled: mutateRes.enabledExperiments ?? [],\n ...(mutateRes.backupPath ? { backupPath: mutateRes.backupPath } : {}),\n ...(mutateRes.error ? { error: mutateRes.error } : {}),\n };\n\n if (opts?.fixBetaApis) {\n betaApisResult = {\n attempted: true,\n changed: mutateRes.changed,\n ...(mutateRes.backupPath ? { backupPath: mutateRes.backupPath } : {}),\n ...(mutateRes.error ? { error: mutateRes.error } : {}),\n };\n }\n }\n\n // \u4FEE\u590D\u811A\u672C\u539F\u751F\u6A21\u5757\u6743\u9650\n const permDiag = checkWorldScriptPermissions(bdsRoot, levelName, packs);\n let fixedPermissions: RepairWorldPacksResult[\"fixedPermissions\"] = undefined;\n if (permDiag.missingPermissions.length > 0) {\n fixedPermissions = [];\n for (const item of permDiag.missingPermissions) {\n const headerInfo = readPackManifestHeader(item.pack.dir);\n await ensureConfigPermission(bdsRoot, item.pack.uuid, headerInfo?.moduleUuid);\n fixedPermissions.push({\n packName: item.pack.name || item.pack.folderName,\n moduleName: item.moduleName,\n });\n }\n }\n\n const result: RepairWorldPacksResult = {\n cleanedGhostPacks,\n syncedVersions,\n };\n if (betaApisResult) {\n result.betaApisResult = betaApisResult;\n }\n if (experimentsResult) {\n result.experimentsResult = experimentsResult;\n }\n if (fixedPermissions && fixedPermissions.length > 0) {\n result.fixedPermissions = fixedPermissions;\n }\n\n return result;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["enableExperimentsInLevelDat", "readLevelDatExperiments"]
|
|
7
7
|
}
|
package/dist/world-packs.test.js
CHANGED
|
@@ -672,5 +672,27 @@ describe("world-packs primitives", () => {
|
|
|
672
672
|
assert.equal(info.name, "\xA7l\xA7a\u795E\u91D1");
|
|
673
673
|
assert.equal(info.kind, "resource");
|
|
674
674
|
});
|
|
675
|
+
it("readPackManifestInfo \u5C06 pack.name \u89E3\u6790\u4E3A\u8BED\u8A00\u5305\u540D\u79F0\uFF0C\u5E76\u5728\u5217\u8868\u4E2D\u4FDD\u7559\u771F\u5B9E\u6587\u4EF6\u5939\u540D", async () => {
|
|
676
|
+
const { listInstalledWorldPacks, readPackManifestInfo } = await import("./world-packs.js");
|
|
677
|
+
const bds = path.join(tmp, "localized-bds");
|
|
678
|
+
const level = "LocalizedWorld";
|
|
679
|
+
const folderName = "[RP] \u539F\u59CB\u8D44\u6E90\u5305\u6587\u4EF6\u5939";
|
|
680
|
+
const dir = path.join(bds, "worlds", level, "resource_packs", folderName);
|
|
681
|
+
const uuid = "ce6a8b4f-f349-47e5-b196-9b4249870a6a";
|
|
682
|
+
writeManifest(dir, { name: "pack.name", uuid, version: [1, 2, 3], type: "resources" });
|
|
683
|
+
fs.mkdirSync(path.join(dir, "texts"), { recursive: true });
|
|
684
|
+
fs.writeFileSync(path.join(dir, "texts", "languages.json"), JSON.stringify(["zh_CN", "en_US"]));
|
|
685
|
+
fs.writeFileSync(
|
|
686
|
+
path.join(dir, "texts", "zh_CN.lang"),
|
|
687
|
+
"\uFEFF# \u8D44\u6E90\u5305\u672C\u5730\u5316\npack.name=\u795E\u5947\u8D44\u6E90\u5305\npack.description=\u8BF4\u660E=\u53EF\u4EE5\u5305\u542B\u7B49\u53F7\n",
|
|
688
|
+
"utf8"
|
|
689
|
+
);
|
|
690
|
+
fs.writeFileSync(path.join(dir, "texts", "en_US.lang"), "pack.name=Amazing Resource Pack\n", "utf8");
|
|
691
|
+
assert.equal(readPackManifestInfo(dir)?.name, "\u795E\u5947\u8D44\u6E90\u5305");
|
|
692
|
+
const listed = listInstalledWorldPacks(bds, level);
|
|
693
|
+
assert.equal(listed.length, 1);
|
|
694
|
+
assert.equal(listed[0]?.folderName, folderName);
|
|
695
|
+
assert.equal(listed[0]?.name, "\u795E\u5947\u8D44\u6E90\u5305");
|
|
696
|
+
});
|
|
675
697
|
});
|
|
676
698
|
//# sourceMappingURL=world-packs.test.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/world-packs.test.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * world-packs \u539F\u8BED\u5355\u6D4B\uFF1Aformat / bump / discover / list-installed\n */\nimport assert from \"node:assert/strict\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { after, before, describe, it } from \"node:test\";\nimport { fileURLToPath } from \"node:url\";\nimport { spawnSync } from \"node:child_process\";\n\nconst CLI = path.join(path.dirname(fileURLToPath(import.meta.url)), \"..\", \"dist\", \"cli-pack-manager.js\");\n\nfunction run(args) {\n const r = spawnSync(process.execPath, [CLI, ...args], { encoding: \"utf8\" });\n return { status: r.status, out: r.stdout ?? \"\", err: r.stderr ?? \"\" };\n}\n\nfunction writeManifest(dir, { name, uuid, version, type }) {\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(\n path.join(dir, \"manifest.json\"),\n JSON.stringify(\n {\n format_version: 2,\n header: { name, uuid, version, description: \"test\" },\n modules: [{ type, uuid: cryptoRandom(), version }],\n },\n null,\n 2\n )\n );\n}\n\nfunction cryptoRandom() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\ndescribe(\"world-packs primitives\", () => {\n /** @type {string} */\n let tmp;\n before(() => {\n tmp = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-wp-\"));\n });\n after(() => {\n fs.rmSync(tmp, { recursive: true, force: true });\n });\n\n it(\"formatWorldPackFolderName \u53BB\u683C\u5F0F\u7801/\u540E\u7F00\u5E76\u52A0\u524D\u7F00\", async () => {\n const { formatWorldPackFolderName, isGenericPackFolderStem } = await import(\"./world-packs.js\");\n assert.equal(formatWorldPackFolderName(\"\u00A7aCool\u00A7l Textures.mcpack\", \"resource\"), \"[RP] Cool Textures\");\n assert.equal(formatWorldPackFolderName(\"My BP.zip\", \"behavior\"), \"[BP] My BP\");\n assert.equal(formatWorldPackFolderName(\"[RP] Already\", \"resource\"), \"[RP] Already\");\n assert.equal(isGenericPackFolderStem(\"B\"), true);\n assert.equal(isGenericPackFolderStem(\"[RP] R\"), true);\n assert.equal(isGenericPackFolderStem(\"Slash Blade\"), false);\n });\n\n it(\"discoverPackRoots maxDepth=2\", async () => {\n const { discoverPackRoots } = await import(\"./world-packs.js\");\n const root = path.join(tmp, \"discover\");\n const nested = path.join(root, \"outer\", \"inner-pack\");\n writeManifest(nested, {\n name: \"Inner\",\n uuid: \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n version: [1, 0, 0],\n type: \"resources\",\n });\n const found = discoverPackRoots(root, { maxDepth: 2 });\n assert.ok(found.some((p) => path.resolve(p) === path.resolve(nested)));\n });\n\n it(\"resolvePackRoots\uFF1A\u6241\u5E73\u76EE\u5F55 / \u5B50\u76EE\u5F55 BP+RP\", async () => {\n const { resolvePackRoots, readPackManifestInfo } = await import(\"./world-packs.js\");\n const flat = path.join(tmp, \"flat-pack\");\n writeManifest(flat, {\n name: \"FlatBP\",\n uuid: \"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\",\n version: [1, 0, 0],\n type: \"data\",\n });\n const flatRes = await resolvePackRoots(flat);\n try {\n assert.equal(flatRes.roots.length, 1);\n assert.equal(readPackManifestInfo(flatRes.roots[0])?.name, \"FlatBP\");\n } finally {\n flatRes.dispose();\n }\n\n const nest = path.join(tmp, \"nest-dir\");\n writeManifest(path.join(nest, \"BP\"), {\n name: \"NestBP\",\n uuid: \"cccccccc-cccc-cccc-cccc-cccccccccccc\",\n version: [1, 0, 0],\n type: \"data\",\n });\n writeManifest(path.join(nest, \"RP\"), {\n name: \"NestRP\",\n uuid: \"dddddddd-dddd-dddd-dddd-dddddddddddd\",\n version: [1, 0, 0],\n type: \"resources\",\n });\n const nestRes = await resolvePackRoots(nest);\n try {\n assert.equal(nestRes.roots.length, 2);\n const kinds = nestRes.roots.map((r) => readPackManifestInfo(r)?.kind).sort();\n assert.deepEqual(kinds, [\"behavior\", \"resource\"]);\n } finally {\n nestRes.dispose();\n }\n });\n\n it(\"resolvePackRoots\uFF1Amcaddon \u5185\u5D4C mcpack + zip \u5957\u5A03\", async () => {\n const JSZip = (await import(\"jszip\")).default;\n const { resolvePackRoots, readPackManifestInfo } = await import(\"./world-packs.js\");\n\n async function zipDirAsArchive(entries, outFile) {\n const zip = new JSZip();\n for (const [name, content] of entries) {\n zip.file(name, content);\n }\n const buf = await zip.generateAsync({ type: \"nodebuffer\" });\n fs.mkdirSync(path.dirname(outFile), { recursive: true });\n fs.writeFileSync(outFile, buf);\n }\n\n function manifestJson({ name, uuid, version, type }) {\n return JSON.stringify({\n format_version: 2,\n header: { name, uuid, version, description: \"test\" },\n modules: [{ type, uuid: cryptoRandom(), version }],\n });\n }\n\n /* \u5185\u5C42 RP \u4F5C\u4E3A .mcpack */\n const rpMcpack = path.join(tmp, \"nested-build\", \"inner-rp.mcpack\");\n await zipDirAsArchive(\n [\n [\n \"manifest.json\",\n manifestJson({\n name: \"InnerRP\",\n uuid: \"eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee\",\n version: [1, 0, 0],\n type: \"resources\",\n }),\n ],\n ],\n rpMcpack\n );\n\n /* \u5916\u5C42 .mcaddon\uFF1A\u6587\u4EF6\u5939 BP + \u5D4C\u5957 .mcpack */\n const bpManifest = manifestJson({\n name: \"OuterBP\",\n uuid: \"ffffffff-ffff-ffff-ffff-ffffffffffff\",\n version: [1, 0, 0],\n type: \"data\",\n });\n const addon = path.join(tmp, \"nested-build\", \"bundle.mcaddon\");\n const zip = new JSZip();\n zip.file(\"BP/manifest.json\", bpManifest);\n zip.file(\"inner-rp.mcpack\", fs.readFileSync(rpMcpack));\n fs.writeFileSync(addon, await zip.generateAsync({ type: \"nodebuffer\" }));\n\n const addonRes = await resolvePackRoots(addon);\n try {\n assert.equal(addonRes.roots.length, 2, `roots=${JSON.stringify(addonRes.roots)}`);\n const names = addonRes.roots.map((r) => readPackManifestInfo(r)?.name).sort();\n assert.deepEqual(names, [\"InnerRP\", \"OuterBP\"]);\n } finally {\n addonRes.dispose();\n }\n\n /* zip \u2192 mcpack \u2192 pack\uFF08\u53CC\u5C42\u5957\u5A03\uFF09 */\n const leafMcpack = path.join(tmp, \"nested-build\", \"leaf.mcpack\");\n await zipDirAsArchive(\n [\n [\n \"manifest.json\",\n manifestJson({\n name: \"LeafPack\",\n uuid: \"12121212-1212-1212-1212-121212121212\",\n version: [2, 0, 0],\n type: \"data\",\n }),\n ],\n ],\n leafMcpack\n );\n const outerZip = path.join(tmp, \"nested-build\", \"outer.zip\");\n const z2 = new JSZip();\n z2.file(\"leaf.mcpack\", fs.readFileSync(leafMcpack));\n fs.writeFileSync(outerZip, await z2.generateAsync({ type: \"nodebuffer\" }));\n\n const zipRes = await resolvePackRoots(outerZip);\n try {\n assert.equal(zipRes.roots.length, 1);\n assert.equal(readPackManifestInfo(zipRes.roots[0])?.name, \"LeafPack\");\n } finally {\n zipRes.dispose();\n }\n });\n\n it(\"bumpPackPatchVersion \u540C\u6B65 header \u4E0E modules\", async () => {\n const { bumpPackPatchVersion, readPackManifestInfo } = await import(\"./world-packs.js\");\n const dir = path.join(tmp, \"bump-rp\");\n writeManifest(dir, {\n name: \"BumpMe\",\n uuid: \"11111111-2222-3333-4444-555555555555\",\n version: [1, 2, 3],\n type: \"resources\",\n });\n const next = bumpPackPatchVersion(dir);\n assert.deepEqual(next, [1, 2, 4]);\n const info = readPackManifestInfo(dir);\n assert.deepEqual(info?.version, [1, 2, 4]);\n const raw = JSON.parse(fs.readFileSync(path.join(dir, \"manifest.json\"), \"utf8\"));\n assert.deepEqual(raw.modules[0].version, [1, 2, 4]);\n });\n\n it(\"ensureVersionGreaterThan / nextEnabledVersion\uFF1Abump(max(\u65B0\u5305, \u65E7\u7248))\", async () => {\n const { ensureVersionGreaterThan, nextEnabledVersion, readPackManifestInfo } = await import(\n \"./world-packs.js\"\n );\n assert.deepEqual(nextEnabledVersion([1, 0, 0], [1, 21, 100], \"patch\"), [1, 21, 101]);\n /* \u590D\u73B0\uFF1A\u65E7 Slash Blade RP=[1,21,100]\uFF0C\u8FDC\u7A0B\u65B0\u5305=[1,0,0] */\n const dir = path.join(tmp, \"bump-floor\");\n writeManifest(dir, {\n name: \"SlashRp\",\n uuid: \"8b450660-c968-3d5e-696e-b7f14c03388a\",\n version: [1, 0, 0],\n type: \"resources\",\n });\n const next = ensureVersionGreaterThan(dir, [1, 21, 100], \"patch\");\n assert.deepEqual(next, [1, 21, 101]);\n assert.deepEqual(readPackManifestInfo(dir)?.version, [1, 21, 101]);\n });\n\n it(\"list-installed CLI + listInstalledWorldPacks\", async () => {\n const { listInstalledWorldPacks } = await import(\"./world-packs.js\");\n const bds = path.join(tmp, \"bds\");\n const level = \"Bedrock level\";\n const rpDir = path.join(bds, \"worlds\", level, \"resource_packs\", \"[RP] Tex\");\n writeManifest(rpDir, {\n name: \"Tex\",\n uuid: \"99999999-8888-7777-6666-555555555555\",\n version: [0, 1, 0],\n type: \"resources\",\n });\n fs.mkdirSync(path.join(bds, \"worlds\", level), { recursive: true });\n fs.writeFileSync(\n path.join(bds, \"worlds\", level, \"world_resource_packs.json\"),\n JSON.stringify([{ pack_id: \"99999999-8888-7777-6666-555555555555\", version: [0, 1, 0] }])\n );\n\n const list = listInstalledWorldPacks(bds, level);\n assert.equal(list.length, 1);\n assert.equal(list[0].enabled, true);\n assert.equal(list[0].kind, \"resource\");\n\n const cli = run([\"list-installed\", \"--bds-root\", bds, \"--level\", level]);\n assert.equal(cli.status, 0, cli.err || cli.out);\n const parsed = JSON.parse(cli.out.trim());\n assert.equal(parsed.length, 1);\n });\n\n it(\"bump-version CLI\", async () => {\n const dir = path.join(tmp, \"cli-bump\");\n writeManifest(dir, {\n name: \"CliBump\",\n uuid: \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\",\n version: [2, 0, 0],\n type: \"resources\",\n });\n const cli = run([\"bump-version\", \"--pack-dir\", dir]);\n assert.equal(cli.status, 0, cli.err || cli.out);\n const { version } = JSON.parse(cli.out.trim());\n assert.deepEqual(version, [2, 0, 1]);\n });\n\n it(\"scanDestOccupancy / readPackDirOccupancy\uFF1A\u5B8C\u6574\u4E0E\u6B8B\u7F3A manifest\", async () => {\n const { scanDestOccupancy, readPackDirOccupancy, formatWorldPackFolderName } = await import(\n \"./world-packs.js\"\n );\n const parent = path.join(tmp, \"occupancy-scan\");\n const fullName = formatWorldPackFolderName(\"Full\", \"resource\");\n const brokenName = formatWorldPackFolderName(\"Broken\", \"behavior\");\n const fullDir = path.join(parent, fullName);\n const brokenDir = path.join(parent, brokenName);\n writeManifest(fullDir, {\n name: \"Full Pack\",\n uuid: \"11111111-1111-1111-1111-111111111111\",\n version: [2, 3, 4],\n type: \"resources\",\n });\n fs.mkdirSync(brokenDir, { recursive: true });\n fs.writeFileSync(\n path.join(brokenDir, \"manifest.json\"),\n JSON.stringify({\n format_version: 2,\n header: {\n name: \"Broken Pack\",\n uuid: \"22222222-2222-2222-2222-222222222222\",\n version: [9, 0, 1],\n },\n modules: [],\n })\n );\n\n const fullFacts = readPackDirOccupancy(fullDir);\n assert.equal(fullFacts?.uuid, \"11111111-1111-1111-1111-111111111111\");\n assert.deepEqual(fullFacts?.version, [2, 3, 4]);\n assert.equal(fullFacts?.kind, \"resource\");\n\n const brokenFacts = readPackDirOccupancy(brokenDir);\n assert.equal(brokenFacts?.uuid, \"22222222-2222-2222-2222-222222222222\");\n assert.deepEqual(brokenFacts?.version, [9, 0, 1]);\n assert.equal(brokenFacts?.kind, undefined);\n\n const occ = scanDestOccupancy(parent);\n assert.equal(occ.length, 2);\n const byFolder = Object.fromEntries(occ.map((o) => [o.folderName, o]));\n assert.equal(byFolder[fullName]?.uuid, \"11111111-1111-1111-1111-111111111111\");\n assert.equal(byFolder[fullName]?.kind, \"resource\");\n assert.equal(byFolder[brokenName]?.uuid, \"22222222-2222-2222-2222-222222222222\");\n assert.equal(byFolder[brokenName]?.kind, undefined);\n });\n\n it(\"decidePackInstallPlan \u8868\u9A71\u52A8\", async () => {\n const { decidePackInstallPlan, formatWorldPackFolderName } = await import(\"./world-packs.js\");\n const uuidA = \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\";\n const uuidB = \"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\";\n const mk = (over) => ({\n name: \"Foo\",\n uuid: uuidB,\n version: [1, 0, 0],\n kind: \"behavior\",\n ...over,\n });\n\n const cases = [\n {\n title: \"\u7A7A\u5360\u7528 + hint B \u2192 fresh \u7528 manifest \u540D\",\n incoming: mk({ name: \"Foo\", uuid: uuidB }),\n hint: \"B\",\n occupancy: [],\n force: false,\n expectKind: \"fresh\",\n expectFolder: \"[BP] Foo\",\n },\n {\n title: \"\u5DF2\u6709 [BP] B uuidA + \u65B0 uuidB hint B \u2192 fresh \u4E14\u4E0D\u5360\u7528 B\",\n incoming: mk({ name: \"pack.name\", uuid: uuidB, version: [5, 0, 4] }),\n hint: \"B\",\n occupancy: [\n {\n folderName: \"[BP] B\",\n dir: \"/x/[BP] B\",\n uuid: uuidA,\n version: [1, 0, 0],\n name: \"Slash\",\n },\n ],\n force: false,\n expectKind: \"fresh\",\n expectFolderNot: \"[BP] B\",\n },\n {\n title: \"\u540C uuid \u7248\u672C\u66F4\u9AD8 !force \u2192 overwriteInPlace\",\n incoming: mk({ name: \"Slash v2\", uuid: uuidA, version: [1, 2, 0] }),\n hint: \"Other\",\n occupancy: [\n {\n folderName: \"[BP] B\",\n dir: \"/x/[BP] B\",\n uuid: uuidA,\n version: [1, 1, 0],\n name: \"Slash\",\n },\n ],\n force: false,\n expectKind: \"overwriteInPlace\",\n expectFolder: \"[BP] B\",\n },\n {\n title: \"\u540C uuid \u7248\u672C\u76F8\u7B49 !force \u2192 needConfirm\",\n incoming: mk({ name: \"Slash\", uuid: uuidA, version: [1, 1, 0] }),\n hint: \"Other\",\n occupancy: [\n {\n folderName: \"[BP] B\",\n dir: \"/x/[BP] B\",\n uuid: uuidA,\n version: [1, 1, 0],\n name: \"Slash\",\n },\n ],\n force: false,\n expectKind: \"needConfirm\",\n expectFolder: \"[BP] B\",\n },\n {\n title: \"\u540C uuid \u7248\u672C\u66F4\u4F4E !force \u2192 needConfirm\",\n incoming: mk({ name: \"Slash\", uuid: uuidA, version: [1, 0, 0] }),\n hint: \"Other\",\n occupancy: [\n {\n folderName: \"[BP] B\",\n dir: \"/x/[BP] B\",\n uuid: uuidA,\n version: [1, 1, 0],\n name: \"Slash\",\n },\n ],\n force: false,\n expectKind: \"needConfirm\",\n expectFolder: \"[BP] B\",\n },\n {\n title: \"\u540C uuid \u964D\u7EA7 + force \u2192 overwriteInPlace\",\n incoming: mk({ name: \"Slash old\", uuid: uuidA, version: [1, 0, 0] }),\n hint: \"Other\",\n occupancy: [\n {\n folderName: \"[BP] B\",\n dir: \"/x/[BP] B\",\n uuid: uuidA,\n version: [1, 1, 0],\n name: \"Slash\",\n },\n ],\n force: true,\n expectKind: \"overwriteInPlace\",\n expectFolder: \"[BP] B\",\n },\n {\n title: \"\u4E24\u4EBA\u540D\u649E\u8F66 \u2192 fresh \u5E26 uuid \u540E\u7F00\",\n incoming: mk({ name: \"Cool\", uuid: uuidB, version: [1, 0, 0] }),\n hint: \"Cool\",\n occupancy: [\n {\n folderName: formatWorldPackFolderName(\"Cool\", \"behavior\"),\n dir: \"/x/a\",\n uuid: uuidA,\n version: [1, 0, 0],\n },\n ],\n force: false,\n expectKind: \"fresh\",\n expectFolder: formatWorldPackFolderName(`Cool ${uuidB.slice(0, 8)}`, \"behavior\"),\n },\n ];\n\n for (const c of cases) {\n const plan = decidePackInstallPlan({\n incoming: c.incoming,\n hint: c.hint,\n occupancy: c.occupancy,\n force: c.force,\n });\n assert.equal(plan.kind, c.expectKind, c.title);\n if (c.expectFolder) assert.equal(plan.folderName, c.expectFolder, c.title);\n if (c.expectFolderNot) assert.notEqual(plan.folderName, c.expectFolderNot, c.title);\n if (plan.kind === \"overwriteInPlace\" || plan.kind === \"needConfirm\") {\n assert.equal(plan.folderName, c.occupancy[0].folderName, `${c.title}: \u5FC5\u987B\u539F\u5730`);\n }\n }\n });\n\n it(\"installPackDirectory FS\uFF1A\u5F02 uuid \u6362\u540D\uFF1B\u7248\u672C\u5347\u7EA7\u9759\u9ED8\u8986\u76D6\uFF1B\u540C\u7248\u9700 force\", async () => {\n const { installPackDirectory, formatWorldPackFolderName, readPackManifestInfo } = await import(\n \"./world-packs.js\"\n );\n const dest = path.join(tmp, \"conflict-parent\");\n\n const existingB = path.join(dest, formatWorldPackFolderName(\"B\", \"behavior\"));\n writeManifest(existingB, {\n name: \"Slash Blade\",\n uuid: \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\",\n version: [1, 0, 0],\n type: \"data\",\n });\n\n /* \u5F02 uuid + hint B \u2192 \u6362\u540D\uFF0C\u4E0D\u78B0\u65E7\u5305 */\n const src = path.join(tmp, \"incoming-bp\");\n writeManifest(src, {\n name: \"pack.name\",\n uuid: \"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\",\n version: [5, 0, 4],\n type: \"data\",\n });\n const r = await installPackDirectory({\n srcDir: src,\n destParent: dest,\n folderName: \"B\",\n force: false,\n });\n assert.equal(r.ok, true, r.reason);\n assert.notEqual(path.basename(r.destDir), path.basename(existingB));\n assert.equal(readPackManifestInfo(existingB)?.uuid, \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\");\n\n /* \u540C uuid \u7248\u672C\u66F4\u9AD8 \u2192 \u9759\u9ED8\u539F\u5730\u8986\u76D6\uFF08\u65E0\u9700 force\uFF09 */\n const srcUp = path.join(tmp, \"incoming-upgrade\");\n writeManifest(srcUp, {\n name: \"Slash Blade v2\",\n uuid: \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\",\n version: [2, 0, 0],\n type: \"data\",\n });\n const up = await installPackDirectory({\n srcDir: srcUp,\n destParent: dest,\n folderName: \"Totally Different Hint\",\n force: false,\n });\n assert.equal(up.ok, true, up.reason);\n assert.equal(up.conflict, undefined);\n assert.equal(up.destDir && path.basename(up.destDir), path.basename(existingB));\n assert.equal(readPackManifestInfo(existingB)?.version.join(\".\"), \"2.0.0\");\n assert.equal(fs.readdirSync(dest).filter((n) => n.startsWith(\"[BP]\")).length, 2);\n\n /* \u540C\u7248 \u2192 needConfirm\uFF1Bforce \u540E\u539F\u5730 */\n const srcSame = path.join(tmp, \"incoming-same-ver\");\n writeManifest(srcSame, {\n name: \"Slash Blade v2b\",\n uuid: \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\",\n version: [2, 0, 0],\n type: \"data\",\n });\n const c = await installPackDirectory({\n srcDir: srcSame,\n destParent: dest,\n force: false,\n });\n assert.equal(c.ok, false);\n assert.equal(c.reason, \"conflict\");\n\n const forced = await installPackDirectory({\n srcDir: srcSame,\n destParent: dest,\n force: true,\n });\n assert.equal(forced.ok, true, forced.reason);\n assert.equal(forced.destDir && path.basename(forced.destDir), path.basename(existingB));\n assert.equal(readPackManifestInfo(existingB)?.name, \"Slash Blade v2b\");\n });\n\n it(\"installPackDirectory\uFF1A\u6B8B\u7F3A manifest \u5360\u7528\u76EE\u5F55\u65F6\u6362\u540D\u800C\u975E\u8986\u76D6\", async () => {\n const { installPackDirectory, formatWorldPackFolderName } = await import(\"./world-packs.js\");\n const dest = path.join(tmp, \"broken-parent\");\n const folderName = formatWorldPackFolderName(\"Broken\", \"resource\");\n const existingDir = path.join(dest, folderName);\n fs.mkdirSync(existingDir, { recursive: true });\n fs.writeFileSync(\n path.join(existingDir, \"manifest.json\"),\n JSON.stringify({\n format_version: 2,\n header: {\n name: \"Broken\",\n uuid: \"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\",\n version: [1, 0, 0],\n },\n modules: [],\n })\n );\n const src = path.join(tmp, \"incoming-rp\");\n writeManifest(src, {\n name: \"Incoming\",\n uuid: \"cccccccc-cccc-cccc-cccc-cccccccccccc\",\n version: [1, 0, 0],\n type: \"resources\",\n });\n const r = await installPackDirectory({\n srcDir: src,\n destParent: dest,\n folderName: \"Broken\",\n force: false,\n });\n assert.equal(r.ok, true, r.reason);\n assert.notEqual(r.destDir && path.basename(r.destDir), folderName);\n const still = JSON.parse(fs.readFileSync(path.join(existingDir, \"manifest.json\"), \"utf8\"));\n assert.equal(still.header.uuid, \"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\");\n });\n\n it(\"installPackDirectory\uFF1A\u6B8B\u7F3A manifest \u540C uuid \u2192 \u6309\u7248\u672C\u51B3\u7B56\uFF08\u975E\u65C1\u8DEF\u65B0\u76EE\u5F55\uFF09\", async () => {\n const { installPackDirectory, formatWorldPackFolderName, readPackManifestInfo } = await import(\n \"./world-packs.js\"\n );\n const dest = path.join(tmp, \"broken-same-uuid\");\n const folderName = formatWorldPackFolderName(\"Legacy\", \"behavior\");\n const existingDir = path.join(dest, folderName);\n fs.mkdirSync(existingDir, { recursive: true });\n const uuid = \"eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee\";\n fs.writeFileSync(\n path.join(existingDir, \"manifest.json\"),\n JSON.stringify({\n format_version: 2,\n header: { name: \"Legacy\", uuid, version: [1, 0, 0] },\n modules: [],\n })\n );\n const srcSame = path.join(tmp, \"incoming-same-broken\");\n writeManifest(srcSame, {\n name: \"Fixed\",\n uuid,\n version: [1, 0, 0],\n type: \"data\",\n });\n const c = await installPackDirectory({\n srcDir: srcSame,\n destParent: dest,\n folderName: \"OtherHint\",\n force: false,\n });\n assert.equal(c.ok, false);\n assert.equal(c.reason, \"conflict\");\n assert.equal(c.conflict?.existing.dir, existingDir);\n\n const srcUp = path.join(tmp, \"incoming-up-broken\");\n writeManifest(srcUp, {\n name: \"Fixed v2\",\n uuid,\n version: [1, 1, 0],\n type: \"data\",\n });\n const up = await installPackDirectory({\n srcDir: srcUp,\n destParent: dest,\n folderName: \"OtherHint\",\n force: false,\n });\n assert.equal(up.ok, true, up.reason);\n assert.equal(up.destDir, existingDir);\n assert.equal(readPackManifestInfo(existingDir)?.version.join(\".\"), \"1.1.0\");\n });\n\n it(\"uninstallInstalledPack\uFF1A\u56DE\u6536\u7AD9 / purge / \u76EE\u5F55\u7F3A\u5931\", async () => {\n const { uninstallInstalledPack, listInstalledWorldPacks } = await import(\"./world-packs.js\");\n const bds = path.join(tmp, \"uninstall-bds\");\n const level = \"Bedrock level\";\n const folder = \"[BP] Gone\";\n const uuid = \"dddddddd-dddd-dddd-dddd-dddddddddddd\";\n const packDir = path.join(bds, \"worlds\", level, \"behavior_packs\", folder);\n writeManifest(packDir, {\n name: \"Gone\",\n uuid,\n version: [1, 0, 0],\n type: \"data\",\n });\n fs.mkdirSync(path.join(bds, \"worlds\", level), { recursive: true });\n fs.writeFileSync(\n path.join(bds, \"worlds\", level, \"world_behavior_packs.json\"),\n JSON.stringify([{ pack_id: uuid, version: [1, 0, 0] }])\n );\n\n const packs = listInstalledWorldPacks(bds, level);\n assert.equal(packs.length, 1);\n const trash = path.join(tmp, \"trash-bin\");\n const trashed = await uninstallInstalledPack({\n bdsRoot: bds,\n levelName: level,\n pack: packs[0],\n trashDir: trash,\n });\n assert.equal(trashed.action, \"trashed\");\n assert.ok(trashed.dest && fs.existsSync(trashed.dest));\n assert.equal(fs.existsSync(packDir), false);\n const enable = JSON.parse(\n fs.readFileSync(path.join(bds, \"worlds\", level, \"world_behavior_packs.json\"), \"utf8\")\n );\n assert.equal(enable.length, 0);\n\n /* \u76EE\u5F55\u5DF2\u4E0D\u5728 list \u4E2D\uFF1B\u6784\u9020 missing \u573A\u666F */\n const phantom = {\n ...packs[0],\n dir: path.join(bds, \"worlds\", level, \"behavior_packs\", \"no-such\"),\n enabled: false,\n };\n const missing = await uninstallInstalledPack({\n bdsRoot: bds,\n levelName: level,\n pack: phantom,\n trashDir: trash,\n });\n assert.equal(missing.action, \"missing\");\n\n /* purge\uFF1A\u518D\u88C5\u4E00\u4E2A\u76F4\u63A5\u5220 */\n const folder2 = \"[BP] PurgeMe\";\n const uuid2 = \"eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee\";\n const packDir2 = path.join(bds, \"worlds\", level, \"behavior_packs\", folder2);\n writeManifest(packDir2, {\n name: \"PurgeMe\",\n uuid: uuid2,\n version: [1, 0, 0],\n type: \"data\",\n });\n fs.writeFileSync(\n path.join(bds, \"worlds\", level, \"world_behavior_packs.json\"),\n JSON.stringify([{ pack_id: uuid2, version: [1, 0, 0] }])\n );\n const packs2 = listInstalledWorldPacks(bds, level);\n const purged = await uninstallInstalledPack({\n bdsRoot: bds,\n levelName: level,\n pack: packs2.find((p) => p.uuid === uuid2),\n trashDir: null,\n });\n assert.equal(purged.action, \"deleted\");\n assert.equal(fs.existsSync(packDir2), false);\n });\n\n it(\"readPackManifestInfo \u9047 UTF-8 BOM \u4ECD\u53EF\u8BFB\u51FA uuid/name\uFF08\u5265\u79BB\u517C\u5BB9\uFF09\", async () => {\n const { readPackManifestInfo } = await import(\"./world-packs.js\");\n const dir = path.join(tmp, \"bom-rp\");\n fs.mkdirSync(dir, { recursive: true });\n const body = JSON.stringify(\n {\n format_version: 2,\n header: {\n name: \"\u00A7l\u00A7a\u795E\u91D1\",\n uuid: \"2b6de4b1-1f74-4c6e-937b-77f5e9c1f199\",\n version: [1, 0, 4],\n },\n modules: [{ type: \"resources\", uuid: \"1c710355-15e2-4293-8574-788eec05d35f\", version: [1, 0, 4] }],\n },\n null,\n 2\n );\n fs.writeFileSync(path.join(dir, \"manifest.json\"), `\\uFEFF${body}`, \"utf8\");\n const info = readPackManifestInfo(dir);\n assert.ok(info);\n assert.equal(info.uuid, \"2b6de4b1-1f74-4c6e-937b-77f5e9c1f199\");\n assert.equal(info.name, \"\u00A7l\u00A7a\u795E\u91D1\");\n assert.equal(info.kind, \"resource\");\n });\n});\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * world-packs \u539F\u8BED\u5355\u6D4B\uFF1Aformat / bump / discover / list-installed\n */\nimport assert from \"node:assert/strict\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { after, before, describe, it } from \"node:test\";\nimport { fileURLToPath } from \"node:url\";\nimport { spawnSync } from \"node:child_process\";\n\nconst CLI = path.join(path.dirname(fileURLToPath(import.meta.url)), \"..\", \"dist\", \"cli-pack-manager.js\");\n\nfunction run(args) {\n const r = spawnSync(process.execPath, [CLI, ...args], { encoding: \"utf8\" });\n return { status: r.status, out: r.stdout ?? \"\", err: r.stderr ?? \"\" };\n}\n\nfunction writeManifest(dir, { name, uuid, version, type }) {\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(\n path.join(dir, \"manifest.json\"),\n JSON.stringify(\n {\n format_version: 2,\n header: { name, uuid, version, description: \"test\" },\n modules: [{ type, uuid: cryptoRandom(), version }],\n },\n null,\n 2\n )\n );\n}\n\nfunction cryptoRandom() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\ndescribe(\"world-packs primitives\", () => {\n /** @type {string} */\n let tmp;\n before(() => {\n tmp = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-wp-\"));\n });\n after(() => {\n fs.rmSync(tmp, { recursive: true, force: true });\n });\n\n it(\"formatWorldPackFolderName \u53BB\u683C\u5F0F\u7801/\u540E\u7F00\u5E76\u52A0\u524D\u7F00\", async () => {\n const { formatWorldPackFolderName, isGenericPackFolderStem } = await import(\"./world-packs.js\");\n assert.equal(formatWorldPackFolderName(\"\u00A7aCool\u00A7l Textures.mcpack\", \"resource\"), \"[RP] Cool Textures\");\n assert.equal(formatWorldPackFolderName(\"My BP.zip\", \"behavior\"), \"[BP] My BP\");\n assert.equal(formatWorldPackFolderName(\"[RP] Already\", \"resource\"), \"[RP] Already\");\n assert.equal(isGenericPackFolderStem(\"B\"), true);\n assert.equal(isGenericPackFolderStem(\"[RP] R\"), true);\n assert.equal(isGenericPackFolderStem(\"Slash Blade\"), false);\n });\n\n it(\"discoverPackRoots maxDepth=2\", async () => {\n const { discoverPackRoots } = await import(\"./world-packs.js\");\n const root = path.join(tmp, \"discover\");\n const nested = path.join(root, \"outer\", \"inner-pack\");\n writeManifest(nested, {\n name: \"Inner\",\n uuid: \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n version: [1, 0, 0],\n type: \"resources\",\n });\n const found = discoverPackRoots(root, { maxDepth: 2 });\n assert.ok(found.some((p) => path.resolve(p) === path.resolve(nested)));\n });\n\n it(\"resolvePackRoots\uFF1A\u6241\u5E73\u76EE\u5F55 / \u5B50\u76EE\u5F55 BP+RP\", async () => {\n const { resolvePackRoots, readPackManifestInfo } = await import(\"./world-packs.js\");\n const flat = path.join(tmp, \"flat-pack\");\n writeManifest(flat, {\n name: \"FlatBP\",\n uuid: \"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\",\n version: [1, 0, 0],\n type: \"data\",\n });\n const flatRes = await resolvePackRoots(flat);\n try {\n assert.equal(flatRes.roots.length, 1);\n assert.equal(readPackManifestInfo(flatRes.roots[0])?.name, \"FlatBP\");\n } finally {\n flatRes.dispose();\n }\n\n const nest = path.join(tmp, \"nest-dir\");\n writeManifest(path.join(nest, \"BP\"), {\n name: \"NestBP\",\n uuid: \"cccccccc-cccc-cccc-cccc-cccccccccccc\",\n version: [1, 0, 0],\n type: \"data\",\n });\n writeManifest(path.join(nest, \"RP\"), {\n name: \"NestRP\",\n uuid: \"dddddddd-dddd-dddd-dddd-dddddddddddd\",\n version: [1, 0, 0],\n type: \"resources\",\n });\n const nestRes = await resolvePackRoots(nest);\n try {\n assert.equal(nestRes.roots.length, 2);\n const kinds = nestRes.roots.map((r) => readPackManifestInfo(r)?.kind).sort();\n assert.deepEqual(kinds, [\"behavior\", \"resource\"]);\n } finally {\n nestRes.dispose();\n }\n });\n\n it(\"resolvePackRoots\uFF1Amcaddon \u5185\u5D4C mcpack + zip \u5957\u5A03\", async () => {\n const JSZip = (await import(\"jszip\")).default;\n const { resolvePackRoots, readPackManifestInfo } = await import(\"./world-packs.js\");\n\n async function zipDirAsArchive(entries, outFile) {\n const zip = new JSZip();\n for (const [name, content] of entries) {\n zip.file(name, content);\n }\n const buf = await zip.generateAsync({ type: \"nodebuffer\" });\n fs.mkdirSync(path.dirname(outFile), { recursive: true });\n fs.writeFileSync(outFile, buf);\n }\n\n function manifestJson({ name, uuid, version, type }) {\n return JSON.stringify({\n format_version: 2,\n header: { name, uuid, version, description: \"test\" },\n modules: [{ type, uuid: cryptoRandom(), version }],\n });\n }\n\n /* \u5185\u5C42 RP \u4F5C\u4E3A .mcpack */\n const rpMcpack = path.join(tmp, \"nested-build\", \"inner-rp.mcpack\");\n await zipDirAsArchive(\n [\n [\n \"manifest.json\",\n manifestJson({\n name: \"InnerRP\",\n uuid: \"eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee\",\n version: [1, 0, 0],\n type: \"resources\",\n }),\n ],\n ],\n rpMcpack\n );\n\n /* \u5916\u5C42 .mcaddon\uFF1A\u6587\u4EF6\u5939 BP + \u5D4C\u5957 .mcpack */\n const bpManifest = manifestJson({\n name: \"OuterBP\",\n uuid: \"ffffffff-ffff-ffff-ffff-ffffffffffff\",\n version: [1, 0, 0],\n type: \"data\",\n });\n const addon = path.join(tmp, \"nested-build\", \"bundle.mcaddon\");\n const zip = new JSZip();\n zip.file(\"BP/manifest.json\", bpManifest);\n zip.file(\"inner-rp.mcpack\", fs.readFileSync(rpMcpack));\n fs.writeFileSync(addon, await zip.generateAsync({ type: \"nodebuffer\" }));\n\n const addonRes = await resolvePackRoots(addon);\n try {\n assert.equal(addonRes.roots.length, 2, `roots=${JSON.stringify(addonRes.roots)}`);\n const names = addonRes.roots.map((r) => readPackManifestInfo(r)?.name).sort();\n assert.deepEqual(names, [\"InnerRP\", \"OuterBP\"]);\n } finally {\n addonRes.dispose();\n }\n\n /* zip \u2192 mcpack \u2192 pack\uFF08\u53CC\u5C42\u5957\u5A03\uFF09 */\n const leafMcpack = path.join(tmp, \"nested-build\", \"leaf.mcpack\");\n await zipDirAsArchive(\n [\n [\n \"manifest.json\",\n manifestJson({\n name: \"LeafPack\",\n uuid: \"12121212-1212-1212-1212-121212121212\",\n version: [2, 0, 0],\n type: \"data\",\n }),\n ],\n ],\n leafMcpack\n );\n const outerZip = path.join(tmp, \"nested-build\", \"outer.zip\");\n const z2 = new JSZip();\n z2.file(\"leaf.mcpack\", fs.readFileSync(leafMcpack));\n fs.writeFileSync(outerZip, await z2.generateAsync({ type: \"nodebuffer\" }));\n\n const zipRes = await resolvePackRoots(outerZip);\n try {\n assert.equal(zipRes.roots.length, 1);\n assert.equal(readPackManifestInfo(zipRes.roots[0])?.name, \"LeafPack\");\n } finally {\n zipRes.dispose();\n }\n });\n\n it(\"bumpPackPatchVersion \u540C\u6B65 header \u4E0E modules\", async () => {\n const { bumpPackPatchVersion, readPackManifestInfo } = await import(\"./world-packs.js\");\n const dir = path.join(tmp, \"bump-rp\");\n writeManifest(dir, {\n name: \"BumpMe\",\n uuid: \"11111111-2222-3333-4444-555555555555\",\n version: [1, 2, 3],\n type: \"resources\",\n });\n const next = bumpPackPatchVersion(dir);\n assert.deepEqual(next, [1, 2, 4]);\n const info = readPackManifestInfo(dir);\n assert.deepEqual(info?.version, [1, 2, 4]);\n const raw = JSON.parse(fs.readFileSync(path.join(dir, \"manifest.json\"), \"utf8\"));\n assert.deepEqual(raw.modules[0].version, [1, 2, 4]);\n });\n\n it(\"ensureVersionGreaterThan / nextEnabledVersion\uFF1Abump(max(\u65B0\u5305, \u65E7\u7248))\", async () => {\n const { ensureVersionGreaterThan, nextEnabledVersion, readPackManifestInfo } = await import(\n \"./world-packs.js\"\n );\n assert.deepEqual(nextEnabledVersion([1, 0, 0], [1, 21, 100], \"patch\"), [1, 21, 101]);\n /* \u590D\u73B0\uFF1A\u65E7 Slash Blade RP=[1,21,100]\uFF0C\u8FDC\u7A0B\u65B0\u5305=[1,0,0] */\n const dir = path.join(tmp, \"bump-floor\");\n writeManifest(dir, {\n name: \"SlashRp\",\n uuid: \"8b450660-c968-3d5e-696e-b7f14c03388a\",\n version: [1, 0, 0],\n type: \"resources\",\n });\n const next = ensureVersionGreaterThan(dir, [1, 21, 100], \"patch\");\n assert.deepEqual(next, [1, 21, 101]);\n assert.deepEqual(readPackManifestInfo(dir)?.version, [1, 21, 101]);\n });\n\n it(\"list-installed CLI + listInstalledWorldPacks\", async () => {\n const { listInstalledWorldPacks } = await import(\"./world-packs.js\");\n const bds = path.join(tmp, \"bds\");\n const level = \"Bedrock level\";\n const rpDir = path.join(bds, \"worlds\", level, \"resource_packs\", \"[RP] Tex\");\n writeManifest(rpDir, {\n name: \"Tex\",\n uuid: \"99999999-8888-7777-6666-555555555555\",\n version: [0, 1, 0],\n type: \"resources\",\n });\n fs.mkdirSync(path.join(bds, \"worlds\", level), { recursive: true });\n fs.writeFileSync(\n path.join(bds, \"worlds\", level, \"world_resource_packs.json\"),\n JSON.stringify([{ pack_id: \"99999999-8888-7777-6666-555555555555\", version: [0, 1, 0] }])\n );\n\n const list = listInstalledWorldPacks(bds, level);\n assert.equal(list.length, 1);\n assert.equal(list[0].enabled, true);\n assert.equal(list[0].kind, \"resource\");\n\n const cli = run([\"list-installed\", \"--bds-root\", bds, \"--level\", level]);\n assert.equal(cli.status, 0, cli.err || cli.out);\n const parsed = JSON.parse(cli.out.trim());\n assert.equal(parsed.length, 1);\n });\n\n it(\"bump-version CLI\", async () => {\n const dir = path.join(tmp, \"cli-bump\");\n writeManifest(dir, {\n name: \"CliBump\",\n uuid: \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\",\n version: [2, 0, 0],\n type: \"resources\",\n });\n const cli = run([\"bump-version\", \"--pack-dir\", dir]);\n assert.equal(cli.status, 0, cli.err || cli.out);\n const { version } = JSON.parse(cli.out.trim());\n assert.deepEqual(version, [2, 0, 1]);\n });\n\n it(\"scanDestOccupancy / readPackDirOccupancy\uFF1A\u5B8C\u6574\u4E0E\u6B8B\u7F3A manifest\", async () => {\n const { scanDestOccupancy, readPackDirOccupancy, formatWorldPackFolderName } = await import(\n \"./world-packs.js\"\n );\n const parent = path.join(tmp, \"occupancy-scan\");\n const fullName = formatWorldPackFolderName(\"Full\", \"resource\");\n const brokenName = formatWorldPackFolderName(\"Broken\", \"behavior\");\n const fullDir = path.join(parent, fullName);\n const brokenDir = path.join(parent, brokenName);\n writeManifest(fullDir, {\n name: \"Full Pack\",\n uuid: \"11111111-1111-1111-1111-111111111111\",\n version: [2, 3, 4],\n type: \"resources\",\n });\n fs.mkdirSync(brokenDir, { recursive: true });\n fs.writeFileSync(\n path.join(brokenDir, \"manifest.json\"),\n JSON.stringify({\n format_version: 2,\n header: {\n name: \"Broken Pack\",\n uuid: \"22222222-2222-2222-2222-222222222222\",\n version: [9, 0, 1],\n },\n modules: [],\n })\n );\n\n const fullFacts = readPackDirOccupancy(fullDir);\n assert.equal(fullFacts?.uuid, \"11111111-1111-1111-1111-111111111111\");\n assert.deepEqual(fullFacts?.version, [2, 3, 4]);\n assert.equal(fullFacts?.kind, \"resource\");\n\n const brokenFacts = readPackDirOccupancy(brokenDir);\n assert.equal(brokenFacts?.uuid, \"22222222-2222-2222-2222-222222222222\");\n assert.deepEqual(brokenFacts?.version, [9, 0, 1]);\n assert.equal(brokenFacts?.kind, undefined);\n\n const occ = scanDestOccupancy(parent);\n assert.equal(occ.length, 2);\n const byFolder = Object.fromEntries(occ.map((o) => [o.folderName, o]));\n assert.equal(byFolder[fullName]?.uuid, \"11111111-1111-1111-1111-111111111111\");\n assert.equal(byFolder[fullName]?.kind, \"resource\");\n assert.equal(byFolder[brokenName]?.uuid, \"22222222-2222-2222-2222-222222222222\");\n assert.equal(byFolder[brokenName]?.kind, undefined);\n });\n\n it(\"decidePackInstallPlan \u8868\u9A71\u52A8\", async () => {\n const { decidePackInstallPlan, formatWorldPackFolderName } = await import(\"./world-packs.js\");\n const uuidA = \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\";\n const uuidB = \"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\";\n const mk = (over) => ({\n name: \"Foo\",\n uuid: uuidB,\n version: [1, 0, 0],\n kind: \"behavior\",\n ...over,\n });\n\n const cases = [\n {\n title: \"\u7A7A\u5360\u7528 + hint B \u2192 fresh \u7528 manifest \u540D\",\n incoming: mk({ name: \"Foo\", uuid: uuidB }),\n hint: \"B\",\n occupancy: [],\n force: false,\n expectKind: \"fresh\",\n expectFolder: \"[BP] Foo\",\n },\n {\n title: \"\u5DF2\u6709 [BP] B uuidA + \u65B0 uuidB hint B \u2192 fresh \u4E14\u4E0D\u5360\u7528 B\",\n incoming: mk({ name: \"pack.name\", uuid: uuidB, version: [5, 0, 4] }),\n hint: \"B\",\n occupancy: [\n {\n folderName: \"[BP] B\",\n dir: \"/x/[BP] B\",\n uuid: uuidA,\n version: [1, 0, 0],\n name: \"Slash\",\n },\n ],\n force: false,\n expectKind: \"fresh\",\n expectFolderNot: \"[BP] B\",\n },\n {\n title: \"\u540C uuid \u7248\u672C\u66F4\u9AD8 !force \u2192 overwriteInPlace\",\n incoming: mk({ name: \"Slash v2\", uuid: uuidA, version: [1, 2, 0] }),\n hint: \"Other\",\n occupancy: [\n {\n folderName: \"[BP] B\",\n dir: \"/x/[BP] B\",\n uuid: uuidA,\n version: [1, 1, 0],\n name: \"Slash\",\n },\n ],\n force: false,\n expectKind: \"overwriteInPlace\",\n expectFolder: \"[BP] B\",\n },\n {\n title: \"\u540C uuid \u7248\u672C\u76F8\u7B49 !force \u2192 needConfirm\",\n incoming: mk({ name: \"Slash\", uuid: uuidA, version: [1, 1, 0] }),\n hint: \"Other\",\n occupancy: [\n {\n folderName: \"[BP] B\",\n dir: \"/x/[BP] B\",\n uuid: uuidA,\n version: [1, 1, 0],\n name: \"Slash\",\n },\n ],\n force: false,\n expectKind: \"needConfirm\",\n expectFolder: \"[BP] B\",\n },\n {\n title: \"\u540C uuid \u7248\u672C\u66F4\u4F4E !force \u2192 needConfirm\",\n incoming: mk({ name: \"Slash\", uuid: uuidA, version: [1, 0, 0] }),\n hint: \"Other\",\n occupancy: [\n {\n folderName: \"[BP] B\",\n dir: \"/x/[BP] B\",\n uuid: uuidA,\n version: [1, 1, 0],\n name: \"Slash\",\n },\n ],\n force: false,\n expectKind: \"needConfirm\",\n expectFolder: \"[BP] B\",\n },\n {\n title: \"\u540C uuid \u964D\u7EA7 + force \u2192 overwriteInPlace\",\n incoming: mk({ name: \"Slash old\", uuid: uuidA, version: [1, 0, 0] }),\n hint: \"Other\",\n occupancy: [\n {\n folderName: \"[BP] B\",\n dir: \"/x/[BP] B\",\n uuid: uuidA,\n version: [1, 1, 0],\n name: \"Slash\",\n },\n ],\n force: true,\n expectKind: \"overwriteInPlace\",\n expectFolder: \"[BP] B\",\n },\n {\n title: \"\u4E24\u4EBA\u540D\u649E\u8F66 \u2192 fresh \u5E26 uuid \u540E\u7F00\",\n incoming: mk({ name: \"Cool\", uuid: uuidB, version: [1, 0, 0] }),\n hint: \"Cool\",\n occupancy: [\n {\n folderName: formatWorldPackFolderName(\"Cool\", \"behavior\"),\n dir: \"/x/a\",\n uuid: uuidA,\n version: [1, 0, 0],\n },\n ],\n force: false,\n expectKind: \"fresh\",\n expectFolder: formatWorldPackFolderName(`Cool ${uuidB.slice(0, 8)}`, \"behavior\"),\n },\n ];\n\n for (const c of cases) {\n const plan = decidePackInstallPlan({\n incoming: c.incoming,\n hint: c.hint,\n occupancy: c.occupancy,\n force: c.force,\n });\n assert.equal(plan.kind, c.expectKind, c.title);\n if (c.expectFolder) assert.equal(plan.folderName, c.expectFolder, c.title);\n if (c.expectFolderNot) assert.notEqual(plan.folderName, c.expectFolderNot, c.title);\n if (plan.kind === \"overwriteInPlace\" || plan.kind === \"needConfirm\") {\n assert.equal(plan.folderName, c.occupancy[0].folderName, `${c.title}: \u5FC5\u987B\u539F\u5730`);\n }\n }\n });\n\n it(\"installPackDirectory FS\uFF1A\u5F02 uuid \u6362\u540D\uFF1B\u7248\u672C\u5347\u7EA7\u9759\u9ED8\u8986\u76D6\uFF1B\u540C\u7248\u9700 force\", async () => {\n const { installPackDirectory, formatWorldPackFolderName, readPackManifestInfo } = await import(\n \"./world-packs.js\"\n );\n const dest = path.join(tmp, \"conflict-parent\");\n\n const existingB = path.join(dest, formatWorldPackFolderName(\"B\", \"behavior\"));\n writeManifest(existingB, {\n name: \"Slash Blade\",\n uuid: \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\",\n version: [1, 0, 0],\n type: \"data\",\n });\n\n /* \u5F02 uuid + hint B \u2192 \u6362\u540D\uFF0C\u4E0D\u78B0\u65E7\u5305 */\n const src = path.join(tmp, \"incoming-bp\");\n writeManifest(src, {\n name: \"pack.name\",\n uuid: \"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\",\n version: [5, 0, 4],\n type: \"data\",\n });\n const r = await installPackDirectory({\n srcDir: src,\n destParent: dest,\n folderName: \"B\",\n force: false,\n });\n assert.equal(r.ok, true, r.reason);\n assert.notEqual(path.basename(r.destDir), path.basename(existingB));\n assert.equal(readPackManifestInfo(existingB)?.uuid, \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\");\n\n /* \u540C uuid \u7248\u672C\u66F4\u9AD8 \u2192 \u9759\u9ED8\u539F\u5730\u8986\u76D6\uFF08\u65E0\u9700 force\uFF09 */\n const srcUp = path.join(tmp, \"incoming-upgrade\");\n writeManifest(srcUp, {\n name: \"Slash Blade v2\",\n uuid: \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\",\n version: [2, 0, 0],\n type: \"data\",\n });\n const up = await installPackDirectory({\n srcDir: srcUp,\n destParent: dest,\n folderName: \"Totally Different Hint\",\n force: false,\n });\n assert.equal(up.ok, true, up.reason);\n assert.equal(up.conflict, undefined);\n assert.equal(up.destDir && path.basename(up.destDir), path.basename(existingB));\n assert.equal(readPackManifestInfo(existingB)?.version.join(\".\"), \"2.0.0\");\n assert.equal(fs.readdirSync(dest).filter((n) => n.startsWith(\"[BP]\")).length, 2);\n\n /* \u540C\u7248 \u2192 needConfirm\uFF1Bforce \u540E\u539F\u5730 */\n const srcSame = path.join(tmp, \"incoming-same-ver\");\n writeManifest(srcSame, {\n name: \"Slash Blade v2b\",\n uuid: \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\",\n version: [2, 0, 0],\n type: \"data\",\n });\n const c = await installPackDirectory({\n srcDir: srcSame,\n destParent: dest,\n force: false,\n });\n assert.equal(c.ok, false);\n assert.equal(c.reason, \"conflict\");\n\n const forced = await installPackDirectory({\n srcDir: srcSame,\n destParent: dest,\n force: true,\n });\n assert.equal(forced.ok, true, forced.reason);\n assert.equal(forced.destDir && path.basename(forced.destDir), path.basename(existingB));\n assert.equal(readPackManifestInfo(existingB)?.name, \"Slash Blade v2b\");\n });\n\n it(\"installPackDirectory\uFF1A\u6B8B\u7F3A manifest \u5360\u7528\u76EE\u5F55\u65F6\u6362\u540D\u800C\u975E\u8986\u76D6\", async () => {\n const { installPackDirectory, formatWorldPackFolderName } = await import(\"./world-packs.js\");\n const dest = path.join(tmp, \"broken-parent\");\n const folderName = formatWorldPackFolderName(\"Broken\", \"resource\");\n const existingDir = path.join(dest, folderName);\n fs.mkdirSync(existingDir, { recursive: true });\n fs.writeFileSync(\n path.join(existingDir, \"manifest.json\"),\n JSON.stringify({\n format_version: 2,\n header: {\n name: \"Broken\",\n uuid: \"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\",\n version: [1, 0, 0],\n },\n modules: [],\n })\n );\n const src = path.join(tmp, \"incoming-rp\");\n writeManifest(src, {\n name: \"Incoming\",\n uuid: \"cccccccc-cccc-cccc-cccc-cccccccccccc\",\n version: [1, 0, 0],\n type: \"resources\",\n });\n const r = await installPackDirectory({\n srcDir: src,\n destParent: dest,\n folderName: \"Broken\",\n force: false,\n });\n assert.equal(r.ok, true, r.reason);\n assert.notEqual(r.destDir && path.basename(r.destDir), folderName);\n const still = JSON.parse(fs.readFileSync(path.join(existingDir, \"manifest.json\"), \"utf8\"));\n assert.equal(still.header.uuid, \"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\");\n });\n\n it(\"installPackDirectory\uFF1A\u6B8B\u7F3A manifest \u540C uuid \u2192 \u6309\u7248\u672C\u51B3\u7B56\uFF08\u975E\u65C1\u8DEF\u65B0\u76EE\u5F55\uFF09\", async () => {\n const { installPackDirectory, formatWorldPackFolderName, readPackManifestInfo } = await import(\n \"./world-packs.js\"\n );\n const dest = path.join(tmp, \"broken-same-uuid\");\n const folderName = formatWorldPackFolderName(\"Legacy\", \"behavior\");\n const existingDir = path.join(dest, folderName);\n fs.mkdirSync(existingDir, { recursive: true });\n const uuid = \"eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee\";\n fs.writeFileSync(\n path.join(existingDir, \"manifest.json\"),\n JSON.stringify({\n format_version: 2,\n header: { name: \"Legacy\", uuid, version: [1, 0, 0] },\n modules: [],\n })\n );\n const srcSame = path.join(tmp, \"incoming-same-broken\");\n writeManifest(srcSame, {\n name: \"Fixed\",\n uuid,\n version: [1, 0, 0],\n type: \"data\",\n });\n const c = await installPackDirectory({\n srcDir: srcSame,\n destParent: dest,\n folderName: \"OtherHint\",\n force: false,\n });\n assert.equal(c.ok, false);\n assert.equal(c.reason, \"conflict\");\n assert.equal(c.conflict?.existing.dir, existingDir);\n\n const srcUp = path.join(tmp, \"incoming-up-broken\");\n writeManifest(srcUp, {\n name: \"Fixed v2\",\n uuid,\n version: [1, 1, 0],\n type: \"data\",\n });\n const up = await installPackDirectory({\n srcDir: srcUp,\n destParent: dest,\n folderName: \"OtherHint\",\n force: false,\n });\n assert.equal(up.ok, true, up.reason);\n assert.equal(up.destDir, existingDir);\n assert.equal(readPackManifestInfo(existingDir)?.version.join(\".\"), \"1.1.0\");\n });\n\n it(\"uninstallInstalledPack\uFF1A\u56DE\u6536\u7AD9 / purge / \u76EE\u5F55\u7F3A\u5931\", async () => {\n const { uninstallInstalledPack, listInstalledWorldPacks } = await import(\"./world-packs.js\");\n const bds = path.join(tmp, \"uninstall-bds\");\n const level = \"Bedrock level\";\n const folder = \"[BP] Gone\";\n const uuid = \"dddddddd-dddd-dddd-dddd-dddddddddddd\";\n const packDir = path.join(bds, \"worlds\", level, \"behavior_packs\", folder);\n writeManifest(packDir, {\n name: \"Gone\",\n uuid,\n version: [1, 0, 0],\n type: \"data\",\n });\n fs.mkdirSync(path.join(bds, \"worlds\", level), { recursive: true });\n fs.writeFileSync(\n path.join(bds, \"worlds\", level, \"world_behavior_packs.json\"),\n JSON.stringify([{ pack_id: uuid, version: [1, 0, 0] }])\n );\n\n const packs = listInstalledWorldPacks(bds, level);\n assert.equal(packs.length, 1);\n const trash = path.join(tmp, \"trash-bin\");\n const trashed = await uninstallInstalledPack({\n bdsRoot: bds,\n levelName: level,\n pack: packs[0],\n trashDir: trash,\n });\n assert.equal(trashed.action, \"trashed\");\n assert.ok(trashed.dest && fs.existsSync(trashed.dest));\n assert.equal(fs.existsSync(packDir), false);\n const enable = JSON.parse(\n fs.readFileSync(path.join(bds, \"worlds\", level, \"world_behavior_packs.json\"), \"utf8\")\n );\n assert.equal(enable.length, 0);\n\n /* \u76EE\u5F55\u5DF2\u4E0D\u5728 list \u4E2D\uFF1B\u6784\u9020 missing \u573A\u666F */\n const phantom = {\n ...packs[0],\n dir: path.join(bds, \"worlds\", level, \"behavior_packs\", \"no-such\"),\n enabled: false,\n };\n const missing = await uninstallInstalledPack({\n bdsRoot: bds,\n levelName: level,\n pack: phantom,\n trashDir: trash,\n });\n assert.equal(missing.action, \"missing\");\n\n /* purge\uFF1A\u518D\u88C5\u4E00\u4E2A\u76F4\u63A5\u5220 */\n const folder2 = \"[BP] PurgeMe\";\n const uuid2 = \"eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee\";\n const packDir2 = path.join(bds, \"worlds\", level, \"behavior_packs\", folder2);\n writeManifest(packDir2, {\n name: \"PurgeMe\",\n uuid: uuid2,\n version: [1, 0, 0],\n type: \"data\",\n });\n fs.writeFileSync(\n path.join(bds, \"worlds\", level, \"world_behavior_packs.json\"),\n JSON.stringify([{ pack_id: uuid2, version: [1, 0, 0] }])\n );\n const packs2 = listInstalledWorldPacks(bds, level);\n const purged = await uninstallInstalledPack({\n bdsRoot: bds,\n levelName: level,\n pack: packs2.find((p) => p.uuid === uuid2),\n trashDir: null,\n });\n assert.equal(purged.action, \"deleted\");\n assert.equal(fs.existsSync(packDir2), false);\n });\n\n it(\"readPackManifestInfo \u9047 UTF-8 BOM \u4ECD\u53EF\u8BFB\u51FA uuid/name\uFF08\u5265\u79BB\u517C\u5BB9\uFF09\", async () => {\n const { readPackManifestInfo } = await import(\"./world-packs.js\");\n const dir = path.join(tmp, \"bom-rp\");\n fs.mkdirSync(dir, { recursive: true });\n const body = JSON.stringify(\n {\n format_version: 2,\n header: {\n name: \"\u00A7l\u00A7a\u795E\u91D1\",\n uuid: \"2b6de4b1-1f74-4c6e-937b-77f5e9c1f199\",\n version: [1, 0, 4],\n },\n modules: [{ type: \"resources\", uuid: \"1c710355-15e2-4293-8574-788eec05d35f\", version: [1, 0, 4] }],\n },\n null,\n 2\n );\n fs.writeFileSync(path.join(dir, \"manifest.json\"), `\\uFEFF${body}`, \"utf8\");\n const info = readPackManifestInfo(dir);\n assert.ok(info);\n assert.equal(info.uuid, \"2b6de4b1-1f74-4c6e-937b-77f5e9c1f199\");\n assert.equal(info.name, \"\u00A7l\u00A7a\u795E\u91D1\");\n assert.equal(info.kind, \"resource\");\n });\n\n it(\"readPackManifestInfo \u5C06 pack.name \u89E3\u6790\u4E3A\u8BED\u8A00\u5305\u540D\u79F0\uFF0C\u5E76\u5728\u5217\u8868\u4E2D\u4FDD\u7559\u771F\u5B9E\u6587\u4EF6\u5939\u540D\", async () => {\n const { listInstalledWorldPacks, readPackManifestInfo } = await import(\"./world-packs.js\");\n const bds = path.join(tmp, \"localized-bds\");\n const level = \"LocalizedWorld\";\n const folderName = \"[RP] \u539F\u59CB\u8D44\u6E90\u5305\u6587\u4EF6\u5939\";\n const dir = path.join(bds, \"worlds\", level, \"resource_packs\", folderName);\n const uuid = \"ce6a8b4f-f349-47e5-b196-9b4249870a6a\";\n writeManifest(dir, { name: \"pack.name\", uuid, version: [1, 2, 3], type: \"resources\" });\n fs.mkdirSync(path.join(dir, \"texts\"), { recursive: true });\n fs.writeFileSync(path.join(dir, \"texts\", \"languages.json\"), JSON.stringify([\"zh_CN\", \"en_US\"]));\n fs.writeFileSync(\n path.join(dir, \"texts\", \"zh_CN.lang\"),\n \"\\uFEFF# \u8D44\u6E90\u5305\u672C\u5730\u5316\\npack.name=\u795E\u5947\u8D44\u6E90\u5305\\npack.description=\u8BF4\u660E=\u53EF\u4EE5\u5305\u542B\u7B49\u53F7\\n\",\n \"utf8\"\n );\n fs.writeFileSync(path.join(dir, \"texts\", \"en_US.lang\"), \"pack.name=Amazing Resource Pack\\n\", \"utf8\");\n\n assert.equal(readPackManifestInfo(dir)?.name, \"\u795E\u5947\u8D44\u6E90\u5305\");\n const listed = listInstalledWorldPacks(bds, level);\n assert.equal(listed.length, 1);\n assert.equal(listed[0]?.folderName, folderName);\n assert.equal(listed[0]?.name, \"\u795E\u5947\u8D44\u6E90\u5305\");\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["zip"]
|
|
7
7
|
}
|