@sfmc-bds/bds-tools 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/check-update.js.map +2 -2
- package/dist/pack-update/bindings.js.map +1 -1
- package/dist/pack-update/types.d.ts +1 -1
- package/dist/pack-update/types.js.map +1 -1
- package/dist/world-packs.d.ts +1 -1
- package/dist/world-packs.d.ts.map +1 -1
- package/dist/world-packs.js.map +2 -2
- package/package.json +3 -3
package/dist/check-update.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/check-update.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * check-update.ts \u2014 BDS \u81EA\u52A8\u66F4\u65B0\u5668 (\u4E3B\u6D41\u7A0B)\n *\n * 1. \u4E34\u65F6 staging \u76EE\u5F55 (mkdtempSync) - \u907F\u514D\u6C61\u67D3\u6570\u636E\u6839\n * 2. \u4E0B\u8F7D/\u89E3\u538B\u5931\u8D25 \u2192 \u81EA\u52A8\u4ECE\u5907\u4EFD\u56DE\u6EDA preserves\n * 3. \u6D41\u5F0F SHA256 \u6821\u9A8C - \u4E0D\u628A 250MB \u6587\u4EF6\u8BFB\u5165\u5185\u5B58\n * 4. \u517C\u5BB9\u7248\u672C\u767D\u540D\u5355 - \u4E0D\u5339\u914D\u5219\u8DF3\u8FC7\u5347\u7EA7\n * 5. QQ \u901A\u77E5\u7EDF\u4E00\u52A0 5s \u8D85\u65F6 - \u6C38\u8FDC\u4E0D\u963B\u585E\u4E3B\u6D41\u7A0B\n * 6. Rollback marker \u843D\u76D8\u5230 <ROOT>/.sfmc/ - \u8DE8\u8FDB\u7A0B / \u8DE8\u91CD\u542F\u53EF\u6062\u590D\n */\n\nimport { bindByteProgressToBar, createNodeServiceLogger, createTerminalProgress } from \"@sfmc-bds/sdk/logs\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { createBdsManager } from \"./bds-manager.js\";\nimport { changelogSectionUrl, fetchChangelog } from \"./changelog.js\";\nimport { copyDirSync, copyFileSyncSafe, emptyDirSync, hashFileAsync, rmSafe } from \"./fsx.js\";\nimport { bdsExePath, bdsInstallRequiredFiles, ensureBdsExecutable } from \"./host-platform.js\";\nimport { httpDownload } from \"./http.js\";\nimport { isMainModule } from \"./is-main.js\";\nimport { loadConfig, LOG_PATH, resolvePaths, ROOT_DIR } from \"./paths.js\";\nimport { probeBdsStatus } from \"./process-probe.js\";\nimport { sendText, sendWithImage } from \"./qqutil.js\";\nimport {\n clearRollbackMarker,\n getDirSize,\n rollbackFromBackup,\n verifyBdsInstall,\n writeRollbackMarker,\n} from \"./rollback.js\";\nimport { ensureEmitServerTelemetry, ensureNetherNetTransport, localizeServerProperties } from \"./server-properties.js\";\nimport { clearTaskbarProgress, isTaskbarSupported, setTaskbarProgress } from \"./taskbar.js\";\nimport { emitUpdateKv, emitUpdateResult } from \"./update-result.js\";\nimport {\n buildDownloadUrls,\n fetchVersionDetails,\n getVersionInfo,\n isVersionCompatible,\n verifyFileHash,\n} from \"./upstream.js\";\nimport { compareVersions, getCurrentVersionAsync, getCurrentVersionSync, saveVersionCache } from \"./version.js\";\nimport { extractZipFileToDir } from \"./zipx.js\";\n\n// \u72EC\u7ACB\u5165\u53E3:source = \"updater\",\u4E0E bds-manager \u7684 \"bds-tools\" \u533A\u5206;\u540C\u843D\u76D8 bds-update.log\nconst log = createNodeServiceLogger({ source: \"updater\", logPath: LOG_PATH });\nconst closeLog = (): void => log.close();\n\nfunction parseArgs(argv: string[]): Record<string, string | boolean> {\n const out: Record<string, string | boolean> = {};\n for (const a of argv) {\n const m = a.match(/^--([\\w-]+)(?:=(.+))?$/);\n if (m) out[m[1]!] = m[2] || true;\n }\n return out;\n}\n\ninterface UpdateContext {\n cfg: ReturnType<typeof loadConfig>;\n channel: \"release\" | \"preview\" | string;\n checkOnly: boolean;\n force: boolean;\n bdsPath: string;\n backupDir: string;\n preserve: string[];\n autoRestart: boolean;\n qqNotify: boolean;\n}\n\nfunction buildContext(): UpdateContext {\n const cfg = loadConfig();\n const args = parseArgs(process.argv.slice(2));\n const { bds_path, backup_dir, preserve } = resolvePaths(cfg);\n const channel = String(args[\"channel\"] || cfg.channel || \"release\");\n return {\n cfg,\n channel,\n checkOnly: !!args[\"check-only\"],\n force: !!args[\"force\"],\n bdsPath: bds_path,\n backupDir: backup_dir,\n preserve,\n autoRestart: !args[\"no-start\"],\n qqNotify: !!cfg.qq_notify,\n };\n}\n\nasync function doBackup(\n bdsPath: string,\n backupDir: string,\n preserve: string[]\n): Promise<{ path: string; size: number }> {\n const dateStr = new Date().toISOString().slice(0, 10);\n const dest = path.join(backupDir, dateStr);\n fs.mkdirSync(dest, { recursive: true });\n\n let anyCopied = false;\n for (const item of preserve) {\n const src = path.join(bdsPath, item);\n const target = path.join(dest, item);\n if (!fs.existsSync(src)) continue;\n fs.mkdirSync(path.dirname(target), { recursive: true });\n if (fs.statSync(src).isDirectory()) copyDirSync(src, target);\n else copyFileSyncSafe(src, target);\n anyCopied = true;\n log.info(`\u5DF2\u5907\u4EFD: ${item}`);\n }\n\n // \u5373\u4F7F\u5168\u90E8 preserve \u90FD\u8DF3\u8FC7\uFF0C\u4E5F\u8BA9\u76EE\u5F55\u5B58\u5728\u4EE5\u4FBF\u8BB0\u5F55\u65F6\u95F4\u6233\n if (!anyCopied) {\n log.info(`\u6CA1\u6709\u9700\u8981\u5907\u4EFD\u7684\u6587\u4EF6 (preserve \u5217\u8868\u4E3A\u7A7A\u6216\u5168\u90E8\u7F3A\u5931)`);\n }\n return { path: dest, size: getDirSize(dest) };\n}\n\n/** \u5F02\u6B65\u6062\u590D preserves \u4ECE\u5907\u4EFD\u5230 BDS \u8DEF\u5F84 */\nasync function restorePreserves(bdsPath: string, backupDir: string, preserve: string[]): Promise<void> {\n for (const item of preserve) {\n const src = path.join(backupDir, item);\n const dest = path.join(bdsPath, item);\n if (!fs.existsSync(src)) continue;\n try {\n if (fs.statSync(src).isDirectory()) {\n if (fs.existsSync(dest)) emptyDirSync(dest);\n copyDirSync(src, dest);\n } else {\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n copyFileSyncSafe(src, dest);\n }\n log.info(`\u5DF2\u6062\u590D: ${item}`);\n } catch (e) {\n log.warn(`\u6062\u590D\u5931\u8D25 ${item}: ${(e as Error).message}`);\n }\n }\n}\n\n/** \u7B49\u5F85\u64CD\u4F5C\u7CFB\u7EDF\u786E\u8BA4 BDS \u9000\u51FA\uFF0C\u907F\u514D\u4ECD\u5360\u7528\u53EF\u6267\u884C\u6587\u4EF6\u65F6\u8986\u76D6\u5B89\u88C5\u76EE\u5F55\u3002 */\nasync function waitForBdsStopped(timeoutMs = 10_000): Promise<void> {\n const deadline = Date.now() + timeoutMs;\n let status = await probeBdsStatus({ rootDir: ROOT_DIR });\n while (status.state !== \"stopped\" && Date.now() < deadline) {\n await new Promise<void>((resolve) => setTimeout(resolve, 250));\n status = await probeBdsStatus({ rootDir: ROOT_DIR });\n }\n if (status.state !== \"stopped\") {\n throw new Error(`BDS \u8FDB\u7A0B ${status.pid} \u4ECD\u5728\u8FD0\u884C\uFF0C\u5DF2\u53D6\u6D88\u6587\u4EF6\u8986\u76D6`);\n }\n}\n\n/** \u628A zip \u89E3\u538B\u5230 destDir (\u8986\u76D6) \u2014 \u7ECF zipx \u5B89\u5168\u89E3\u538B */\nasync function extractZipToBds(zipPath: string, destDir: string): Promise<void> {\n // \u62BD\u51FA\u5230\u4E34\u65F6\u76EE\u5F55\uFF0C\u907F\u514D\u65E7\u5185\u5BB9\u5E72\u6270\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"bds-extract-\"));\n try {\n await extractZipFileToDir(zipPath, tmpDir);\n // \u628A\u4E34\u65F6\u76EE\u5F55\u91CC\u7684\u5185\u5BB9\u590D\u5236\u5230 BDS \u8DEF\u5F84\n for (const entry of fs.readdirSync(tmpDir)) {\n const srcPath = path.join(tmpDir, entry);\n const destPath = path.join(destDir, entry);\n if (fs.statSync(srcPath).isDirectory()) {\n if (fs.existsSync(destPath)) emptyDirSync(destPath);\n copyDirSync(srcPath, destPath);\n } else {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n } finally {\n rmSafe(tmpDir);\n }\n}\n\nexport async function runUpdate(): Promise<number> {\n const startTime = Date.now();\n const ctx = buildContext();\n const { cfg, channel, checkOnly, force, bdsPath, backupDir, preserve, autoRestart, qqNotify } = ctx;\n\n log.info(`===== \u5F00\u59CB\u68C0\u67E5\u66F4\u65B0 (${channel}) =====`);\n fs.mkdirSync(bdsPath, { recursive: true });\n fs.mkdirSync(backupDir, { recursive: true });\n\n // 1. \u5F53\u524D\u7248\u672C\n const exePath = bdsExePath(bdsPath);\n const currentVer = await getCurrentVersionAsync(exePath).catch(() => getCurrentVersionSync(exePath));\n log.info(`\u5F53\u524D\u7248\u672C: ${currentVer}`);\n\n // 2. \u83B7\u53D6\u6700\u65B0\u7248\u672C\n let latestVer: string;\n try {\n const info = await getVersionInfo(cfg, channel);\n latestVer = info.version;\n log.info(`\u6700\u65B0\u7248\u672C: ${latestVer}`);\n const cmp = compareVersions(latestVer, currentVer);\n if (cmp <= 0 && !force) {\n log.info(\"\u5DF2\u662F\u6700\u65B0\u7248\u672C\uFF0C\u65E0\u9700\u66F4\u65B0\");\n if (qqNotify) {\n await sendText(`\u2705 BDS \u5DF2\u662F\u6700\u65B0\u7248\u672C\\n\\n\u5F53\u524D: ${currentVer}\\n\u6700\u65B0: ${latestVer}`);\n }\n emitUpdateKv(\"CURRENT\", currentVer, log);\n emitUpdateKv(\"LATEST\", latestVer, log);\n emitUpdateResult(\"uptodate\", log);\n return 0;\n }\n } catch (e) {\n log.error(`\u83B7\u53D6\u7248\u672C\u4FE1\u606F\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u65E0\u6CD5\u83B7\u53D6\u7248\u672C\u4FE1\u606F: ${(e as Error).message}`);\n return 1;\n }\n\n // \u517C\u5BB9\u6027\u68C0\u67E5\n if (!force && !isVersionCompatible(cfg, latestVer)) {\n log.warn(`${latestVer} \u4E0D\u5728\u517C\u5BB9\u7248\u672C\u767D\u540D\u5355\u4E2D\uFF0C\u8DF3\u8FC7\u5347\u7EA7`);\n if (qqNotify) {\n await sendText(`\u26A0\uFE0F BDS ${latestVer} \u4E0D\u5728\u517C\u5BB9\u6027\u767D\u540D\u5355\uFF0C\u5DF2\u8DF3\u8FC7\u5347\u7EA7\u3002\u8BF7\u4EBA\u5DE5\u786E\u8BA4\u3002`);\n }\n emitUpdateResult(\"skipped\", log);\n return 2;\n }\n\n // 3. \u53D6\u4E0B\u8F7D\u94FE\u63A5\n let downloadUrls: string[];\n let hash: { sha1: string; sha256: string };\n try {\n const details = await fetchVersionDetails(cfg, channel, latestVer);\n downloadUrls = buildDownloadUrls(cfg, channel, latestVer, details);\n hash = { sha1: details.sha1, sha256: details.sha256 };\n } catch (e) {\n log.error(`\u83B7\u53D6\u4E0B\u8F7D\u8BE6\u60C5\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u4E0B\u8F7D\u8BE6\u60C5\u83B7\u53D6\u5931\u8D25: ${(e as Error).message}`);\n return 1;\n }\n\n if (checkOnly) {\n emitUpdateKv(\"CURRENT\", currentVer, log);\n emitUpdateKv(\"LATEST\", latestVer, log);\n emitUpdateKv(\"CHANNEL\", channel, log);\n emitUpdateKv(\"URLS\", String(downloadUrls.length), log);\n emitUpdateResult(\"check-only\", log);\n return 0;\n }\n\n log.info(`\u53D1\u73B0\u65B0\u7248\u672C: ${currentVer} \u2192 ${latestVer}`);\n\n // 4. QQ \u9884\u544A\n if (qqNotify) {\n await sendText(\n `\uD835\uDC0C\uD835\uDC22\uD835\uDC27\uD835\uDC1E\uD835\uDC1C\uD835\uDC2B\uD835\uDC1A\uD835\uDC1F\uD835\uDC2D \uD835\uDC01\uD835\uDC03\uD835\uDC12 \u66F4\u65B0\u901A\u77E5\\n\\n` +\n `\u68C0\u6D4B\u5230\u65B0\u7248\u672C\uFF01\\n\\n` +\n `\u5F53\u524D: ${currentVer}\\n` +\n `\u6700\u65B0: ${latestVer}\\n` +\n `\u9891\u9053: ${channel === \"preview\" ? \"\u9884\u89C8\u7248\" : \"\u6B63\u5F0F\u7248\"}\\n\\n` +\n `\u670D\u52A1\u5668\u5373\u5C06\u5F00\u59CB\u66F4\u65B0~ \u8BF7\u8010\u5FC3\u7B49\u5F85^(*\uFFE3(oo)\uFFE3)^`\n );\n const cl = await fetchChangelog(channel, latestVer);\n if (cl) {\n const text = `\uD83D\uDCCB ${latestVer} \u66F4\u65B0\u5185\u5BB9\u6982\u8981\\n\\n${cl.text.slice(0, 1500)}\\n\\n\u5B8C\u6574\u65E5\u5FD7: ${cl.url}`;\n if (cl.imageBase64) await sendWithImage(text, cl.imageBase64);\n else await sendText(text);\n } else {\n await sendText(`\uD83D\uDCCB ${latestVer} \u66F4\u65B0\u65E5\u5FD7\u76EE\u5F55: ${changelogSectionUrl(channel)}`);\n }\n }\n\n // 5. \u5907\u4EFD\n let backupInfo: { path: string; size: number };\n try {\n backupInfo = await doBackup(bdsPath, backupDir, preserve);\n log.info(`\u5907\u4EFD\u5B8C\u6210: ${backupInfo.path} (${(backupInfo.size / 1024 / 1024).toFixed(1)} MB)`);\n if (qqNotify) {\n await sendText(`\u2705 \u5907\u4EFD\u5B8C\u6210\\n\\n\u5927\u5C0F: ${(backupInfo.size / 1024 / 1024).toFixed(1)} MB\\n\u4F4D\u7F6E: ${backupInfo.path}`);\n }\n } catch (e) {\n log.error(`\u5907\u4EFD\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u5907\u4EFD\u5931\u8D25: ${(e as Error).message}\\n\u64CD\u4F5C\u5DF2\u4E2D\u6B62`);\n return 1;\n }\n\n // 6. \u5199\u56DE\u6EDA\u6807\u8BB0 (\u8DE8\u8FDB\u7A0B\u53EF\u6062\u590D)\n writeRollbackMarker({\n timestamp: Date.now(),\n bds_path: bdsPath,\n backup_dir: backupInfo.path,\n preserve,\n previous_version: currentVer,\n });\n\n // 7. \u505C\u670D\n const bds = createBdsManager({ detached: true });\n try {\n log.info(\"\u505C\u6B62 BDS \u670D\u52A1...\");\n await bds.stop();\n await waitForBdsStopped();\n log.info(\"BDS \u5DF2\u505C\u6B62\");\n } catch (e) {\n log.error(`BDS \u505C\u6B62\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u505C\u670D\u5931\u8D25: ${(e as Error).message}\\n\u64CD\u4F5C\u5DF2\u4E2D\u6B62`);\n clearRollbackMarker();\n return 1;\n }\n\n // 8. \u4E0B\u8F7D (\u5168\u90E8\u5931\u8D25\u5219\u56DE\u6EDA)\n // \u7528 mkdtempSync \u521B\u5EFA\u4E34\u65F6 staging \u76EE\u5F55 - \u907F\u514D\u6C61\u67D3 SCRIPT_DIR\n const stagingDir = fs.mkdtempSync(path.join(os.tmpdir(), \"bds-update-\"));\n const zipPath = path.join(stagingDir, `bedrock-server-${latestVer}.zip`);\n let downloaded = false;\n try {\n log.info(`\u5F00\u59CB\u4E0B\u8F7D ${latestVer}...`);\n if (qqNotify) await sendText(`\uD83D\uDCE5 \u6B63\u5728\u4E0B\u8F7D BDS ${latestVer}...`);\n\n let lastErr: Error | null = null;\n const downloadTimeoutMs = (cfg.download_timeout ?? 120) * 1000;\n /* stderr \u88AB pipe \u65F6\u7531 logger \u8F93\u51FA\u5E26\u6761\u5F62\u56FE\u7684\u8FDB\u5EA6\u884C\uFF0C\u4F9B sfmc REPL \u5C55\u793A\u3002 */\n if (isTaskbarSupported() && process.stdout.isTTY) {\n log.info(\"\u68C0\u6D4B\u5230 Windows Terminal,\u4EFB\u52A1\u680F\u8FDB\u5EA6\u5DF2\u542F\u7528 (OSC 9;4)\");\n }\n for (const url of downloadUrls) {\n /* \u6BCF\u6B21\u5C1D\u8BD5\u65B0\u5EFA bar + binder\uFF0C\u907F\u514D\u5931\u8D25\u91CD\u8BD5\u65F6 started \u72B6\u6001\u6B8B\u7559\uFF08LSP\uFF09 */\n const progressBar = createTerminalProgress({\n stream: process.stderr,\n logger: (msg) => log.info(msg),\n format: \"\u4E0B\u8F7D\u8FDB\u5EA6 | {bar} | {percentage}% | {value}/{total} MB | \u901F\u5EA6: {speed}\",\n });\n const onByteProgress = bindByteProgressToBar(progressBar, {\n speedSampleMs: 0,\n onProgress: (dl, total) => {\n const pct = total > 0 ? (dl / total) * 100 : 0;\n setTaskbarProgress(pct);\n },\n });\n try {\n setTaskbarProgress(0);\n await httpDownload(url, zipPath, {\n totalTimeoutMs: Math.max(downloadTimeoutMs, 600_000), // \u4E0D\u5C11\u4E8E 10 \u5206\u949F\n onProgress: onByteProgress,\n });\n if (progressBar.active) progressBar.stop();\n // \u4E0B\u8F7D\u5B8C\u6210,\u4EFB\u52A1\u680F\u6536\u5230 100% \u7EFF\u6761\u540E\u6E05\u6389\n setTaskbarProgress(100);\n clearTaskbarProgress();\n downloaded = true;\n lastErr = null;\n break;\n } catch (e) {\n if (progressBar.active) progressBar.stop();\n // \u4E0B\u8F7D\u5931\u8D25,\u4EFB\u52A1\u680F\u4EAE\u7EA2\n setTaskbarProgress(100, \"error\");\n clearTaskbarProgress();\n lastErr = e as Error;\n log.warn(`${url} \u4E0D\u53EF\u7528: ${lastErr.message}\uFF0C\u5C1D\u8BD5\u5907\u7528\u5730\u5740...`);\n }\n }\n if (!downloaded && lastErr) throw lastErr;\n\n const zipSizeMB = (fs.statSync(zipPath).size / 1024 / 1024).toFixed(1);\n log.info(`\u4E0B\u8F7D\u5B8C\u6210 (${zipSizeMB} MB)`);\n\n // \u6D41\u5F0F\u54C8\u5E0C\u6821\u9A8C\n if (hash.sha1 || hash.sha256) {\n const algo = hash.sha256 ? \"SHA256\" : \"SHA1\";\n log.info(`\u6821\u9A8C\u6587\u4EF6\u5B8C\u6574\u6027 (${algo})...`);\n const ok = await verifyFileHash(zipPath, hash.sha1, hash.sha256);\n if (!ok) throw new Error(`${algo} \u6821\u9A8C\u4E0D\u901A\u8FC7\uFF0C\u6587\u4EF6\u53EF\u80FD\u635F\u574F`);\n log.info(`${algo} \u6821\u9A8C\u901A\u8FC7`);\n }\n } catch (e) {\n log.error(`\u4E0B\u8F7D\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u4E0B\u8F7D\u5931\u8D25: ${(e as Error).message}\\nBDS \u5DF2\u505C\u6B62\uFF0C\u8BF7\u624B\u52A8\u6062\u590D`);\n // \u81EA\u52A8\u56DE\u6EDA\n rollbackFromBackup({\n timestamp: Date.now(),\n bds_path: bdsPath,\n backup_dir: backupInfo.path,\n preserve,\n previous_version: currentVer,\n });\n rmSafe(stagingDir);\n return 1;\n }\n\n // 9. \u89E3\u538B + \u90E8\u7F72\n try {\n await waitForBdsStopped();\n } catch (e) {\n log.error(`\u90E8\u7F72\u5DF2\u4E2D\u6B62: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n${(e as Error).message}\\n\u5C1A\u672A\u8986\u76D6\u5B89\u88C5\u76EE\u5F55`);\n rmSafe(stagingDir);\n clearRollbackMarker();\n return 1;\n }\n try {\n log.info(\"\u89E3\u538B\u4E2D...\");\n // \u5148\u6E05\u7A7A BDS \u76EE\u5F55\n emptyDirSync(bdsPath);\n await extractZipToBds(zipPath, bdsPath);\n ensureBdsExecutable(exePath);\n log.info(\"\u89E3\u538B\u5B8C\u6210\");\n } catch (e) {\n log.error(`\u89E3\u538B\u5931\u8D25: ${(e as Error).message}`);\n const status = await probeBdsStatus({ rootDir: ROOT_DIR });\n if (status.state !== \"stopped\") {\n // \u5916\u90E8\u5B88\u62A4\u8FDB\u7A0B\u53EF\u80FD\u5728\u90E8\u7F72\u671F\u95F4\u518D\u6B21\u62C9\u8D77 BDS\uFF1B\u4E0D\u80FD\u5BF9\u8FD0\u884C\u4E2D\u7684\u76EE\u5F55\u7EE7\u7EED\u6E05\u7406\u3002\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u89E3\u538B\u5931\u8D25: ${(e as Error).message}\\nBDS \u4ECD\u5728\u8FD0\u884C\uFF0C\u8BF7\u5148\u505C\u670D\u5E76\u624B\u52A8\u6062\u590D`);\n rmSafe(stagingDir);\n return 1;\n }\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u89E3\u538B\u5931\u8D25: ${(e as Error).message}\\nBDS \u5DF2\u505C\u6B62\uFF0C\u8BF7\u624B\u52A8\u6062\u590D`);\n // \u56DE\u6EDA: \u6E05\u7A7A + \u4ECE\u5907\u4EFD\u6062\u590D preserves\n emptyDirSync(bdsPath);\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n rmSafe(stagingDir);\n return 1;\n } finally {\n rmSafe(zipPath); // \u6E05\u6389 staging zip\n }\n\n // 10. \u5B8C\u6574\u6027\u68C0\u67E5 (\u907F\u514D\u89E3\u538B\u51FA\u7A7A/\u7F3A\u6587\u4EF6\u7684\u75C5\u6001\u5305)\n const verify = verifyBdsInstall(bdsPath, bdsInstallRequiredFiles());\n if (!verify.ok) {\n log.error(`\u89E3\u538B\u540E\u7684 BDS \u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5931\u6587\u4EF6: ${verify.missing.join(\", \")}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u90E8\u7F72\u540E\u7F3A\u5931\u5173\u952E\u6587\u4EF6: ${verify.missing.join(\", \")}`);\n emptyDirSync(bdsPath);\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n rmSafe(stagingDir);\n return 1;\n }\n\n // 11. \u6062\u590D preserves (zip \u89E3\u538B\u65F6\u8FD9\u4E9B\u76EE\u5F55\u53EF\u80FD\u88AB\u8986\u76D6)\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n\n // 11b. \u5B89\u88C5\u6536\u5C3E\uFF1A\u8865\u9F50\u5FC5\u8981\u914D\u7F6E\uFF0C\u5E76\u5C06 server.properties \u6CE8\u91CA\u672C\u5730\u5316\n ensureEmitServerTelemetry(bdsPath, log);\n ensureNetherNetTransport(bdsPath, log);\n localizeServerProperties(bdsPath, { logger: log, rootDir: ROOT_DIR });\n\n // 12. \u5199\u5165\u7248\u672C\u7F13\u5B58\n const newExeHash = await hashFileAsync(exePath, \"sha256\").catch(() => \"\");\n if (newExeHash) {\n saveVersionCache(latestVer, newExeHash);\n log.info(`\u5DF2\u8BB0\u5F55\u7248\u672C ${latestVer} \u7684 SHA256`);\n }\n\n // 13. \u542F\u52A8 BDS\n if (autoRestart) {\n try {\n log.info(\"\u542F\u52A8 BDS...\");\n await bds.start();\n } catch (e) {\n log.error(`\u542F\u52A8\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u542F\u52A8\u5931\u8D25: ${(e as Error).message}\\n\u8BF7\u624B\u52A8\u542F\u52A8 BDS`);\n // \u6CE8\u610F: \u6B64\u65F6 BDS \u5DF2\u7ECF\u90E8\u7F72\u5B8C\u6210\uFF0C\u542F\u52A8\u5931\u8D25 \u2192 \u542F\u52A8\u95EE\u9898\uFF0C\u4E0D\u505A\u6587\u4EF6\u7EA7\u56DE\u6EDA\n rmSafe(stagingDir);\n clearRollbackMarker();\n return 1;\n }\n }\n\n rmSafe(stagingDir);\n clearRollbackMarker();\n\n // 14. QQ \u901A\u77E5\u7ED3\u679C\n const durationMs = Date.now() - startTime;\n if (qqNotify) {\n await sendText(\n `\u2705 BDS \u66F4\u65B0\u5B8C\u6210\\n\\n` +\n `${currentVer} \u2192 ${latestVer}\\n` +\n `\u8017\u65F6: ${(durationMs / 1000).toFixed(1)}s\\n` +\n `${autoRestart ? \"\u670D\u52A1\u5668\u5DF2\u91CD\u65B0\u542F\u52A8\" : \"\u8BF7\u624B\u52A8\u91CD\u542F\u670D\u52A1\u5668\"}`\n );\n }\n log.info(`===== \u66F4\u65B0\u5B8C\u6210 (${(durationMs / 1000).toFixed(1)}s) =====`);\n /* \u673A\u5668\u53EF\u8BFB\u7ED3\u679C\u6807\u8BB0\uFF1A\u4F9B sfmc \u7B49\u76D1\u7763\u5668\u5224\u65AD\u300C\u771F\u6B63\u5B8C\u6210\u90E8\u7F72\u300D\uFF0C\u52FF\u4F9D\u8D56\u672C\u5730\u5316\u65E5\u5FD7\u6587\u6848\u3002 */\n emitUpdateResult(\"deployed\", log);\n return 0;\n}\n\nfunction isMain(): boolean {\n // sfmc supervisor \u901A\u8FC7 SFMC_SERVICE \u62C9\u8D77\u5B50\u8FDB\u7A0B\u65F6\u4F18\u5148\u5224\u5B9A\n if (process.env.SFMC_SERVICE === \"update\") return true;\n return isMainModule(import.meta.url);\n}\n\nif (isMain()) {\n runUpdate()\n .then((code) => {\n closeLog();\n process.exit(code);\n })\n .catch((e) => {\n log.error(`\u672A\u6355\u83B7\u9519\u8BEF: ${(e as Error).message}`);\n closeLog();\n process.exit(1);\n });\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/**\n * check-update.ts \u2014 BDS \u81EA\u52A8\u66F4\u65B0\u5668 (\u4E3B\u6D41\u7A0B)\n *\n * 1. \u4E34\u65F6 staging \u76EE\u5F55 (mkdtempSync) - \u907F\u514D\u6C61\u67D3\u6570\u636E\u6839\n * 2. \u4E0B\u8F7D/\u89E3\u538B\u5931\u8D25 \u2192 \u81EA\u52A8\u4ECE\u5907\u4EFD\u56DE\u6EDA preserves\n * 3. \u6D41\u5F0F SHA256 \u6821\u9A8C - \u4E0D\u628A 250MB \u6587\u4EF6\u8BFB\u5165\u5185\u5B58\n * 4. \u517C\u5BB9\u7248\u672C\u767D\u540D\u5355 - \u4E0D\u5339\u914D\u5219\u8DF3\u8FC7\u5347\u7EA7\n * 5. QQ \u901A\u77E5\u7EDF\u4E00\u52A0 5s \u8D85\u65F6 - \u6C38\u8FDC\u4E0D\u963B\u585E\u4E3B\u6D41\u7A0B\n * 6. Rollback marker \u843D\u76D8\u5230 <ROOT>/.sfmc/ - \u8DE8\u8FDB\u7A0B / \u8DE8\u91CD\u542F\u53EF\u6062\u590D\n */\n\nimport { bindByteProgressToBar, createNodeServiceLogger, createTerminalProgress } from \"@sfmc-bds/sdk/logs\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { createBdsManager } from \"./bds-manager.js\";\nimport { changelogSectionUrl, fetchChangelog } from \"./changelog.js\";\nimport { copyDirSync, copyFileSyncSafe, emptyDirSync, hashFileAsync, rmSafe } from \"./fsx.js\";\nimport { bdsExePath, bdsInstallRequiredFiles, ensureBdsExecutable } from \"./host-platform.js\";\nimport { httpDownload } from \"./http.js\";\nimport { isMainModule } from \"./is-main.js\";\nimport { loadConfig, LOG_PATH, resolvePaths, ROOT_DIR } from \"./paths.js\";\nimport { probeBdsStatus } from \"./process-probe.js\";\nimport { sendText, sendWithImage } from \"./qqutil.js\";\nimport {\n clearRollbackMarker,\n getDirSize,\n rollbackFromBackup,\n verifyBdsInstall,\n writeRollbackMarker,\n} from \"./rollback.js\";\nimport { ensureEmitServerTelemetry, ensureNetherNetTransport, localizeServerProperties } from \"./server-properties.js\";\nimport { clearTaskbarProgress, isTaskbarSupported, setTaskbarProgress } from \"./taskbar.js\";\nimport { emitUpdateKv, emitUpdateResult } from \"./update-result.js\";\nimport {\n buildDownloadUrls,\n fetchVersionDetails,\n getVersionInfo,\n isVersionCompatible,\n verifyFileHash,\n} from \"./upstream.js\";\nimport { compareVersions, getCurrentVersionAsync, getCurrentVersionSync, saveVersionCache } from \"./version.js\";\nimport { extractZipFileToDir } from \"./zipx.js\";\n\n// \u72EC\u7ACB\u5165\u53E3:source = \"updater\",\u4E0E bds-manager \u7684 \"bds-tools\" \u533A\u5206;\u540C\u843D\u76D8 bds-update.log\nconst log = createNodeServiceLogger({ source: \"updater\", logPath: LOG_PATH });\nconst closeLog = (): void => log.close();\n\nfunction parseArgs(argv: string[]): Record<string, string | boolean> {\n const out: Record<string, string | boolean> = {};\n for (const a of argv) {\n const m = a.match(/^--([\\w-]+)(?:=(.+))?$/);\n if (m) out[m[1]!] = m[2] || true;\n }\n return out;\n}\n\ninterface UpdateContext {\n cfg: ReturnType<typeof loadConfig>;\n channel: \"release\" | \"preview\" | string;\n checkOnly: boolean;\n force: boolean;\n bdsPath: string;\n backupDir: string;\n preserve: string[];\n autoRestart: boolean;\n qqNotify: boolean;\n}\n\nfunction buildContext(): UpdateContext {\n const cfg = loadConfig();\n const args = parseArgs(process.argv.slice(2));\n const { bds_path, backup_dir, preserve } = resolvePaths(cfg);\n const channel = String(args[\"channel\"] || cfg.channel || \"release\");\n return {\n cfg,\n channel,\n checkOnly: !!args[\"check-only\"],\n force: !!args[\"force\"],\n bdsPath: bds_path,\n backupDir: backup_dir,\n preserve,\n autoRestart: !args[\"no-start\"],\n qqNotify: !!cfg.qq_notify,\n };\n}\n\nasync function doBackup(\n bdsPath: string,\n backupDir: string,\n preserve: string[]\n): Promise<{ path: string; size: number }> {\n const dateStr = new Date().toISOString().slice(0, 10);\n const dest = path.join(backupDir, dateStr);\n fs.mkdirSync(dest, { recursive: true });\n\n let anyCopied = false;\n for (const item of preserve) {\n const src = path.join(bdsPath, item);\n const target = path.join(dest, item);\n if (!fs.existsSync(src)) continue;\n fs.mkdirSync(path.dirname(target), { recursive: true });\n if (fs.statSync(src).isDirectory()) copyDirSync(src, target);\n else copyFileSyncSafe(src, target);\n anyCopied = true;\n log.info(`\u5DF2\u5907\u4EFD: ${item}`);\n }\n\n // \u5373\u4F7F\u5168\u90E8 preserve \u90FD\u8DF3\u8FC7\uFF0C\u4E5F\u8BA9\u76EE\u5F55\u5B58\u5728\u4EE5\u4FBF\u8BB0\u5F55\u65F6\u95F4\u6233\n if (!anyCopied) {\n log.info(`\u6CA1\u6709\u9700\u8981\u5907\u4EFD\u7684\u6587\u4EF6 (preserve \u5217\u8868\u4E3A\u7A7A\u6216\u5168\u90E8\u7F3A\u5931)`);\n }\n return { path: dest, size: getDirSize(dest) };\n}\n\n/** \u5F02\u6B65\u6062\u590D preserves \u4ECE\u5907\u4EFD\u5230 BDS \u8DEF\u5F84 */\nasync function restorePreserves(bdsPath: string, backupDir: string, preserve: string[]): Promise<void> {\n for (const item of preserve) {\n const src = path.join(backupDir, item);\n const dest = path.join(bdsPath, item);\n if (!fs.existsSync(src)) continue;\n try {\n if (fs.statSync(src).isDirectory()) {\n if (fs.existsSync(dest)) emptyDirSync(dest);\n copyDirSync(src, dest);\n } else {\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n copyFileSyncSafe(src, dest);\n }\n log.info(`\u5DF2\u6062\u590D: ${item}`);\n } catch (e) {\n log.warn(`\u6062\u590D\u5931\u8D25 ${item}: ${(e as Error).message}`);\n }\n }\n}\n\n/** \u7B49\u5F85\u64CD\u4F5C\u7CFB\u7EDF\u786E\u8BA4 BDS \u9000\u51FA\uFF0C\u907F\u514D\u4ECD\u5360\u7528\u53EF\u6267\u884C\u6587\u4EF6\u65F6\u8986\u76D6\u5B89\u88C5\u76EE\u5F55\u3002 */\nasync function waitForBdsStopped(timeoutMs = 10_000): Promise<void> {\n const deadline = Date.now() + timeoutMs;\n let status = await probeBdsStatus({ rootDir: ROOT_DIR });\n while (status.state !== \"stopped\" && Date.now() < deadline) {\n await new Promise<void>((resolve) => setTimeout(resolve, 250));\n status = await probeBdsStatus({ rootDir: ROOT_DIR });\n }\n if (status.state !== \"stopped\") {\n throw new Error(`BDS \u8FDB\u7A0B ${status.pid} \u4ECD\u5728\u8FD0\u884C\uFF0C\u5DF2\u53D6\u6D88\u6587\u4EF6\u8986\u76D6`);\n }\n}\n\n/** \u628A zip \u89E3\u538B\u5230 destDir (\u8986\u76D6) \u2014 \u7ECF zipx \u5B89\u5168\u89E3\u538B */\nasync function extractZipToBds(zipPath: string, destDir: string): Promise<void> {\n // \u62BD\u51FA\u5230\u4E34\u65F6\u76EE\u5F55\uFF0C\u907F\u514D\u65E7\u5185\u5BB9\u5E72\u6270\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"bds-extract-\"));\n try {\n await extractZipFileToDir(zipPath, tmpDir);\n // \u628A\u4E34\u65F6\u76EE\u5F55\u91CC\u7684\u5185\u5BB9\u590D\u5236\u5230 BDS \u8DEF\u5F84\n for (const entry of fs.readdirSync(tmpDir)) {\n const srcPath = path.join(tmpDir, entry);\n const destPath = path.join(destDir, entry);\n if (fs.statSync(srcPath).isDirectory()) {\n if (fs.existsSync(destPath)) emptyDirSync(destPath);\n copyDirSync(srcPath, destPath);\n } else {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n } finally {\n rmSafe(tmpDir);\n }\n}\n\nexport async function runUpdate(): Promise<number> {\n const startTime = Date.now();\n const ctx = buildContext();\n const { cfg, channel, checkOnly, force, bdsPath, backupDir, preserve, autoRestart, qqNotify } = ctx;\n\n log.info(`===== \u5F00\u59CB\u68C0\u67E5\u66F4\u65B0 (${channel}) =====`);\n fs.mkdirSync(bdsPath, { recursive: true });\n fs.mkdirSync(backupDir, { recursive: true });\n\n // 1. \u5F53\u524D\u7248\u672C\n const exePath = bdsExePath(bdsPath);\n const currentVer = await getCurrentVersionAsync(exePath).catch(() => getCurrentVersionSync(exePath));\n log.info(`\u5F53\u524D\u7248\u672C: ${currentVer}`);\n\n // 2. \u83B7\u53D6\u6700\u65B0\u7248\u672C\n let latestVer: string;\n try {\n const info = await getVersionInfo(cfg, channel);\n latestVer = info.version;\n log.info(`\u6700\u65B0\u7248\u672C: ${latestVer}`);\n const cmp = compareVersions(latestVer, currentVer);\n if (cmp <= 0 && !force) {\n log.info(\"\u5DF2\u662F\u6700\u65B0\u7248\u672C\uFF0C\u65E0\u9700\u66F4\u65B0\");\n if (qqNotify) {\n await sendText(`\u2705 BDS \u5DF2\u662F\u6700\u65B0\u7248\u672C\\n\\n\u5F53\u524D: ${currentVer}\\n\u6700\u65B0: ${latestVer}`);\n }\n emitUpdateKv(\"CURRENT\", currentVer, log);\n emitUpdateKv(\"LATEST\", latestVer, log);\n emitUpdateResult(\"uptodate\", log);\n return 0;\n }\n } catch (e) {\n log.error(`\u83B7\u53D6\u7248\u672C\u4FE1\u606F\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u65E0\u6CD5\u83B7\u53D6\u7248\u672C\u4FE1\u606F: ${(e as Error).message}`);\n return 1;\n }\n\n // \u517C\u5BB9\u6027\u68C0\u67E5\n if (!force && !isVersionCompatible(cfg, latestVer)) {\n log.warn(`${latestVer} \u4E0D\u5728\u517C\u5BB9\u7248\u672C\u767D\u540D\u5355\u4E2D\uFF0C\u8DF3\u8FC7\u5347\u7EA7`);\n if (qqNotify) {\n await sendText(`\u26A0\uFE0F BDS ${latestVer} \u4E0D\u5728\u517C\u5BB9\u6027\u767D\u540D\u5355\uFF0C\u5DF2\u8DF3\u8FC7\u5347\u7EA7\u3002\u8BF7\u4EBA\u5DE5\u786E\u8BA4\u3002`);\n }\n emitUpdateResult(\"skipped\", log);\n return 2;\n }\n\n // 3. \u53D6\u4E0B\u8F7D\u94FE\u63A5\n let downloadUrls: string[];\n let hash: { sha1: string; sha256: string };\n try {\n const details = await fetchVersionDetails(cfg, channel, latestVer);\n downloadUrls = buildDownloadUrls(cfg, channel, latestVer, details);\n hash = { sha1: details.sha1, sha256: details.sha256 };\n } catch (e) {\n log.error(`\u83B7\u53D6\u4E0B\u8F7D\u8BE6\u60C5\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u4E0B\u8F7D\u8BE6\u60C5\u83B7\u53D6\u5931\u8D25: ${(e as Error).message}`);\n return 1;\n }\n\n if (checkOnly) {\n emitUpdateKv(\"CURRENT\", currentVer, log);\n emitUpdateKv(\"LATEST\", latestVer, log);\n emitUpdateKv(\"CHANNEL\", channel, log);\n emitUpdateKv(\"URLS\", String(downloadUrls.length), log);\n emitUpdateResult(\"check-only\", log);\n return 0;\n }\n\n log.info(`\u53D1\u73B0\u65B0\u7248\u672C: ${currentVer} \u2192 ${latestVer}`);\n\n // 4. QQ \u9884\u544A\n if (qqNotify) {\n await sendText(\n `\uD835\uDC0C\uD835\uDC22\uD835\uDC27\uD835\uDC1E\uD835\uDC1C\uD835\uDC2B\uD835\uDC1A\uD835\uDC1F\uD835\uDC2D \uD835\uDC01\uD835\uDC03\uD835\uDC12 \u66F4\u65B0\u901A\u77E5\\n\\n` +\n `\u68C0\u6D4B\u5230\u65B0\u7248\u672C\uFF01\\n\\n` +\n `\u5F53\u524D: ${currentVer}\\n` +\n `\u6700\u65B0: ${latestVer}\\n` +\n `\u9891\u9053: ${channel === \"preview\" ? \"\u9884\u89C8\u7248\" : \"\u6B63\u5F0F\u7248\"}\\n\\n` +\n `\u670D\u52A1\u5668\u5373\u5C06\u5F00\u59CB\u66F4\u65B0~ \u8BF7\u8010\u5FC3\u7B49\u5F85^(*\uFFE3(oo)\uFFE3)^`\n );\n const cl = await fetchChangelog(channel, latestVer);\n if (cl) {\n const text = `\uD83D\uDCCB ${latestVer} \u66F4\u65B0\u5185\u5BB9\u6982\u8981\\n\\n${cl.text.slice(0, 1500)}\\n\\n\u5B8C\u6574\u65E5\u5FD7: ${cl.url}`;\n if (cl.imageBase64) await sendWithImage(text, cl.imageBase64);\n else await sendText(text);\n } else {\n await sendText(`\uD83D\uDCCB ${latestVer} \u66F4\u65B0\u65E5\u5FD7\u76EE\u5F55: ${changelogSectionUrl(channel)}`);\n }\n }\n\n // 5. \u5907\u4EFD\n let backupInfo: { path: string; size: number };\n try {\n backupInfo = await doBackup(bdsPath, backupDir, preserve);\n log.info(`\u5907\u4EFD\u5B8C\u6210: ${backupInfo.path} (${(backupInfo.size / 1024 / 1024).toFixed(1)} MB)`);\n if (qqNotify) {\n await sendText(`\u2705 \u5907\u4EFD\u5B8C\u6210\\n\\n\u5927\u5C0F: ${(backupInfo.size / 1024 / 1024).toFixed(1)} MB\\n\u4F4D\u7F6E: ${backupInfo.path}`);\n }\n } catch (e) {\n log.error(`\u5907\u4EFD\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u5907\u4EFD\u5931\u8D25: ${(e as Error).message}\\n\u64CD\u4F5C\u5DF2\u4E2D\u6B62`);\n return 1;\n }\n\n // 6. \u5199\u56DE\u6EDA\u6807\u8BB0 (\u8DE8\u8FDB\u7A0B\u53EF\u6062\u590D)\n writeRollbackMarker({\n timestamp: Date.now(),\n bds_path: bdsPath,\n backup_dir: backupInfo.path,\n preserve,\n previous_version: currentVer,\n });\n\n // 7. \u505C\u670D\n const bds = createBdsManager({ detached: true });\n try {\n log.info(\"\u505C\u6B62 BDS \u670D\u52A1...\");\n await bds.stop();\n await waitForBdsStopped();\n log.info(\"BDS \u5DF2\u505C\u6B62\");\n } catch (e) {\n log.error(`BDS \u505C\u6B62\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u505C\u670D\u5931\u8D25: ${(e as Error).message}\\n\u64CD\u4F5C\u5DF2\u4E2D\u6B62`);\n clearRollbackMarker();\n return 1;\n }\n\n // 8. \u4E0B\u8F7D (\u5168\u90E8\u5931\u8D25\u5219\u56DE\u6EDA)\n // \u7528 mkdtempSync \u521B\u5EFA\u4E34\u65F6 staging \u76EE\u5F55 - \u907F\u514D\u6C61\u67D3 SCRIPT_DIR\n const stagingDir = fs.mkdtempSync(path.join(os.tmpdir(), \"bds-update-\"));\n const zipPath = path.join(stagingDir, `bedrock-server-${latestVer}.zip`);\n let downloaded = false;\n try {\n log.info(`\u5F00\u59CB\u4E0B\u8F7D ${latestVer}...`);\n if (qqNotify) await sendText(`\uD83D\uDCE5 \u6B63\u5728\u4E0B\u8F7D BDS ${latestVer}...`);\n\n let lastErr: Error | null = null;\n const downloadTimeoutMs = (cfg.download_timeout ?? 120) * 1000;\n /* stderr \u88AB pipe \u65F6\u7531 logger \u8F93\u51FA\u5E26\u6761\u5F62\u56FE\u7684\u8FDB\u5EA6\u884C\uFF0C\u4F9B sfmc REPL \u5C55\u793A\u3002 */\n if (isTaskbarSupported() && process.stdout.isTTY) {\n log.info(\"\u68C0\u6D4B\u5230 Windows Terminal,\u4EFB\u52A1\u680F\u8FDB\u5EA6\u5DF2\u542F\u7528 (OSC 9;4)\");\n }\n for (const url of downloadUrls) {\n /* \u6BCF\u6B21\u5C1D\u8BD5\u65B0\u5EFA bar + binder\uFF0C\u907F\u514D\u5931\u8D25\u91CD\u8BD5\u65F6 started \u72B6\u6001\u6B8B\u7559\uFF08LSP\uFF09 */\n const progressBar = createTerminalProgress({\n stream: process.stderr,\n logger: (msg: string) => log.info(msg),\n format: \"\u4E0B\u8F7D\u8FDB\u5EA6 | {bar} | {percentage}% | {value}/{total} MB | \u901F\u5EA6: {speed}\",\n });\n const onByteProgress = bindByteProgressToBar(progressBar, {\n speedSampleMs: 0,\n onProgress: (dl: number, total: number) => {\n const pct = total > 0 ? (dl / total) * 100 : 0;\n setTaskbarProgress(pct);\n },\n });\n try {\n setTaskbarProgress(0);\n await httpDownload(url, zipPath, {\n totalTimeoutMs: Math.max(downloadTimeoutMs, 600_000), // \u4E0D\u5C11\u4E8E 10 \u5206\u949F\n onProgress: onByteProgress,\n });\n if (progressBar.active) progressBar.stop();\n // \u4E0B\u8F7D\u5B8C\u6210,\u4EFB\u52A1\u680F\u6536\u5230 100% \u7EFF\u6761\u540E\u6E05\u6389\n setTaskbarProgress(100);\n clearTaskbarProgress();\n downloaded = true;\n lastErr = null;\n break;\n } catch (e) {\n if (progressBar.active) progressBar.stop();\n // \u4E0B\u8F7D\u5931\u8D25,\u4EFB\u52A1\u680F\u4EAE\u7EA2\n setTaskbarProgress(100, \"error\");\n clearTaskbarProgress();\n lastErr = e as Error;\n log.warn(`${url} \u4E0D\u53EF\u7528: ${lastErr.message}\uFF0C\u5C1D\u8BD5\u5907\u7528\u5730\u5740...`);\n }\n }\n if (!downloaded && lastErr) throw lastErr;\n\n const zipSizeMB = (fs.statSync(zipPath).size / 1024 / 1024).toFixed(1);\n log.info(`\u4E0B\u8F7D\u5B8C\u6210 (${zipSizeMB} MB)`);\n\n // \u6D41\u5F0F\u54C8\u5E0C\u6821\u9A8C\n if (hash.sha1 || hash.sha256) {\n const algo = hash.sha256 ? \"SHA256\" : \"SHA1\";\n log.info(`\u6821\u9A8C\u6587\u4EF6\u5B8C\u6574\u6027 (${algo})...`);\n const ok = await verifyFileHash(zipPath, hash.sha1, hash.sha256);\n if (!ok) throw new Error(`${algo} \u6821\u9A8C\u4E0D\u901A\u8FC7\uFF0C\u6587\u4EF6\u53EF\u80FD\u635F\u574F`);\n log.info(`${algo} \u6821\u9A8C\u901A\u8FC7`);\n }\n } catch (e) {\n log.error(`\u4E0B\u8F7D\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u4E0B\u8F7D\u5931\u8D25: ${(e as Error).message}\\nBDS \u5DF2\u505C\u6B62\uFF0C\u8BF7\u624B\u52A8\u6062\u590D`);\n // \u81EA\u52A8\u56DE\u6EDA\n rollbackFromBackup({\n timestamp: Date.now(),\n bds_path: bdsPath,\n backup_dir: backupInfo.path,\n preserve,\n previous_version: currentVer,\n });\n rmSafe(stagingDir);\n return 1;\n }\n\n // 9. \u89E3\u538B + \u90E8\u7F72\n try {\n await waitForBdsStopped();\n } catch (e) {\n log.error(`\u90E8\u7F72\u5DF2\u4E2D\u6B62: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n${(e as Error).message}\\n\u5C1A\u672A\u8986\u76D6\u5B89\u88C5\u76EE\u5F55`);\n rmSafe(stagingDir);\n clearRollbackMarker();\n return 1;\n }\n try {\n log.info(\"\u89E3\u538B\u4E2D...\");\n // \u5148\u6E05\u7A7A BDS \u76EE\u5F55\n emptyDirSync(bdsPath);\n await extractZipToBds(zipPath, bdsPath);\n ensureBdsExecutable(exePath);\n log.info(\"\u89E3\u538B\u5B8C\u6210\");\n } catch (e) {\n log.error(`\u89E3\u538B\u5931\u8D25: ${(e as Error).message}`);\n const status = await probeBdsStatus({ rootDir: ROOT_DIR });\n if (status.state !== \"stopped\") {\n // \u5916\u90E8\u5B88\u62A4\u8FDB\u7A0B\u53EF\u80FD\u5728\u90E8\u7F72\u671F\u95F4\u518D\u6B21\u62C9\u8D77 BDS\uFF1B\u4E0D\u80FD\u5BF9\u8FD0\u884C\u4E2D\u7684\u76EE\u5F55\u7EE7\u7EED\u6E05\u7406\u3002\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u89E3\u538B\u5931\u8D25: ${(e as Error).message}\\nBDS \u4ECD\u5728\u8FD0\u884C\uFF0C\u8BF7\u5148\u505C\u670D\u5E76\u624B\u52A8\u6062\u590D`);\n rmSafe(stagingDir);\n return 1;\n }\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u89E3\u538B\u5931\u8D25: ${(e as Error).message}\\nBDS \u5DF2\u505C\u6B62\uFF0C\u8BF7\u624B\u52A8\u6062\u590D`);\n // \u56DE\u6EDA: \u6E05\u7A7A + \u4ECE\u5907\u4EFD\u6062\u590D preserves\n emptyDirSync(bdsPath);\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n rmSafe(stagingDir);\n return 1;\n } finally {\n rmSafe(zipPath); // \u6E05\u6389 staging zip\n }\n\n // 10. \u5B8C\u6574\u6027\u68C0\u67E5 (\u907F\u514D\u89E3\u538B\u51FA\u7A7A/\u7F3A\u6587\u4EF6\u7684\u75C5\u6001\u5305)\n const verify = verifyBdsInstall(bdsPath, bdsInstallRequiredFiles());\n if (!verify.ok) {\n log.error(`\u89E3\u538B\u540E\u7684 BDS \u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5931\u6587\u4EF6: ${verify.missing.join(\", \")}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u90E8\u7F72\u540E\u7F3A\u5931\u5173\u952E\u6587\u4EF6: ${verify.missing.join(\", \")}`);\n emptyDirSync(bdsPath);\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n rmSafe(stagingDir);\n return 1;\n }\n\n // 11. \u6062\u590D preserves (zip \u89E3\u538B\u65F6\u8FD9\u4E9B\u76EE\u5F55\u53EF\u80FD\u88AB\u8986\u76D6)\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n\n // 11b. \u5B89\u88C5\u6536\u5C3E\uFF1A\u8865\u9F50\u5FC5\u8981\u914D\u7F6E\uFF0C\u5E76\u5C06 server.properties \u6CE8\u91CA\u672C\u5730\u5316\n ensureEmitServerTelemetry(bdsPath, log);\n ensureNetherNetTransport(bdsPath, log);\n localizeServerProperties(bdsPath, { logger: log, rootDir: ROOT_DIR });\n\n // 12. \u5199\u5165\u7248\u672C\u7F13\u5B58\n const newExeHash = await hashFileAsync(exePath, \"sha256\").catch(() => \"\");\n if (newExeHash) {\n saveVersionCache(latestVer, newExeHash);\n log.info(`\u5DF2\u8BB0\u5F55\u7248\u672C ${latestVer} \u7684 SHA256`);\n }\n\n // 13. \u542F\u52A8 BDS\n if (autoRestart) {\n try {\n log.info(\"\u542F\u52A8 BDS...\");\n await bds.start();\n } catch (e) {\n log.error(`\u542F\u52A8\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u542F\u52A8\u5931\u8D25: ${(e as Error).message}\\n\u8BF7\u624B\u52A8\u542F\u52A8 BDS`);\n // \u6CE8\u610F: \u6B64\u65F6 BDS \u5DF2\u7ECF\u90E8\u7F72\u5B8C\u6210\uFF0C\u542F\u52A8\u5931\u8D25 \u2192 \u542F\u52A8\u95EE\u9898\uFF0C\u4E0D\u505A\u6587\u4EF6\u7EA7\u56DE\u6EDA\n rmSafe(stagingDir);\n clearRollbackMarker();\n return 1;\n }\n }\n\n rmSafe(stagingDir);\n clearRollbackMarker();\n\n // 14. QQ \u901A\u77E5\u7ED3\u679C\n const durationMs = Date.now() - startTime;\n if (qqNotify) {\n await sendText(\n `\u2705 BDS \u66F4\u65B0\u5B8C\u6210\\n\\n` +\n `${currentVer} \u2192 ${latestVer}\\n` +\n `\u8017\u65F6: ${(durationMs / 1000).toFixed(1)}s\\n` +\n `${autoRestart ? \"\u670D\u52A1\u5668\u5DF2\u91CD\u65B0\u542F\u52A8\" : \"\u8BF7\u624B\u52A8\u91CD\u542F\u670D\u52A1\u5668\"}`\n );\n }\n log.info(`===== \u66F4\u65B0\u5B8C\u6210 (${(durationMs / 1000).toFixed(1)}s) =====`);\n /* \u673A\u5668\u53EF\u8BFB\u7ED3\u679C\u6807\u8BB0\uFF1A\u4F9B sfmc \u7B49\u76D1\u7763\u5668\u5224\u65AD\u300C\u771F\u6B63\u5B8C\u6210\u90E8\u7F72\u300D\uFF0C\u52FF\u4F9D\u8D56\u672C\u5730\u5316\u65E5\u5FD7\u6587\u6848\u3002 */\n emitUpdateResult(\"deployed\", log);\n return 0;\n}\n\nfunction isMain(): boolean {\n // sfmc supervisor \u901A\u8FC7 SFMC_SERVICE \u62C9\u8D77\u5B50\u8FDB\u7A0B\u65F6\u4F18\u5148\u5224\u5B9A\n if (process.env.SFMC_SERVICE === \"update\") return true;\n return isMainModule(import.meta.url);\n}\n\nif (isMain()) {\n runUpdate()\n .then((code) => {\n closeLog();\n process.exit(code);\n })\n .catch((e) => {\n log.error(`\u672A\u6355\u83B7\u9519\u8BEF: ${(e as Error).message}`);\n closeLog();\n process.exit(1);\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/pack-update/bindings.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * packs/pack-sources.json \u2014 \
|
|
4
|
+
"sourcesContent": ["/**\n * packs/pack-sources.json \u2014 \u8D44\u6E90\u5305\u8FDC\u7A0B\u6E90\u7ED1\u5B9A\n */\nimport { withConfigSchema } from \"@sfmc-bds/sdk/node/config\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { PackUpdateDeps } from \"./deps.js\";\nimport type { PackSourceBinding, PackSourcesFile } from \"./types.js\";\n\nexport function createPackUpdateBindingsApi(deps: Pick<PackUpdateDeps, \"rootDir\">) {\n const { rootDir } = deps;\n\n function packSourcesPath(): string {\n return path.join(rootDir, \"packs\", \"pack-sources.json\");\n }\n\n function readPackSources(): PackSourcesFile {\n const file = packSourcesPath();\n if (!fs.existsSync(file)) return { bindings: {} };\n try {\n const raw = JSON.parse(fs.readFileSync(file, \"utf8\")) as PackSourcesFile & { $schema?: string };\n return { bindings: raw.bindings ?? {} };\n } catch {\n return { bindings: {} };\n }\n }\n\n function writePackSources(data: PackSourcesFile): void {\n const file = packSourcesPath();\n fs.mkdirSync(path.dirname(file), { recursive: true });\n const body = withConfigSchema({ bindings: data.bindings ?? {} }, \"pack_sources\", \"packs\");\n fs.writeFileSync(file, `${JSON.stringify(body, null, 2)}\\n`, \"utf8\");\n }\n\n function getBinding(bpUuid: string): PackSourceBinding | null {\n const all = readPackSources();\n return all.bindings[bpUuid.toLowerCase()] ?? all.bindings[bpUuid] ?? null;\n }\n\n function setBinding(bpUuid: string, binding: PackSourceBinding): void {\n const all = readPackSources();\n const key = bpUuid.toLowerCase();\n /* \u6E05\u7406\u65E7\u5927\u5C0F\u5199\u952E */\n for (const k of Object.keys(all.bindings)) {\n if (k.toLowerCase() === key) delete all.bindings[k];\n }\n all.bindings[key] = binding;\n writePackSources(all);\n }\n\n function removeBinding(bpUuid: string): boolean {\n const all = readPackSources();\n const key = bpUuid.toLowerCase();\n let removed = false;\n for (const k of Object.keys(all.bindings)) {\n if (k.toLowerCase() === key) {\n delete all.bindings[k];\n removed = true;\n }\n }\n if (removed) writePackSources(all);\n return removed;\n }\n\n function listBindings(): Array<{ bpUuid: string; binding: PackSourceBinding }> {\n const all = readPackSources();\n return Object.entries(all.bindings).map(([bpUuid, binding]) => ({ bpUuid, binding }));\n }\n\n return {\n packSourcesPath,\n readPackSources,\n writePackSources,\n getBinding,\n setBinding,\n removeBinding,\n listBindings,\n };\n}\n\nexport type PackUpdateBindingsApi = ReturnType<typeof createPackUpdateBindingsApi>;\n"],
|
|
5
5
|
"mappings": "AAGA,SAAS,wBAAwB;AACjC,OAAO,QAAQ;AACf,OAAO,UAAU;AAIV,SAAS,4BAA4B,MAAuC;AACjF,QAAM,EAAE,QAAQ,IAAI;AAEpB,WAAS,kBAA0B;AACjC,WAAO,KAAK,KAAK,SAAS,SAAS,mBAAmB;AAAA,EACxD;AAEA,WAAS,kBAAmC;AAC1C,UAAM,OAAO,gBAAgB;AAC7B,QAAI,CAAC,GAAG,WAAW,IAAI,EAAG,QAAO,EAAE,UAAU,CAAC,EAAE;AAChD,QAAI;AACF,YAAM,MAAM,KAAK,MAAM,GAAG,aAAa,MAAM,MAAM,CAAC;AACpD,aAAO,EAAE,UAAU,IAAI,YAAY,CAAC,EAAE;AAAA,IACxC,QAAQ;AACN,aAAO,EAAE,UAAU,CAAC,EAAE;AAAA,IACxB;AAAA,EACF;AAEA,WAAS,iBAAiB,MAA6B;AACrD,UAAM,OAAO,gBAAgB;AAC7B,OAAG,UAAU,KAAK,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACpD,UAAM,OAAO,iBAAiB,EAAE,UAAU,KAAK,YAAY,CAAC,EAAE,GAAG,gBAAgB,OAAO;AACxF,OAAG,cAAc,MAAM,GAAG,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAAA,GAAM,MAAM;AAAA,EACrE;AAEA,WAAS,WAAW,QAA0C;AAC5D,UAAM,MAAM,gBAAgB;AAC5B,WAAO,IAAI,SAAS,OAAO,YAAY,CAAC,KAAK,IAAI,SAAS,MAAM,KAAK;AAAA,EACvE;AAEA,WAAS,WAAW,QAAgB,SAAkC;AACpE,UAAM,MAAM,gBAAgB;AAC5B,UAAM,MAAM,OAAO,YAAY;AAE/B,eAAW,KAAK,OAAO,KAAK,IAAI,QAAQ,GAAG;AACzC,UAAI,EAAE,YAAY,MAAM,IAAK,QAAO,IAAI,SAAS,CAAC;AAAA,IACpD;AACA,QAAI,SAAS,GAAG,IAAI;AACpB,qBAAiB,GAAG;AAAA,EACtB;AAEA,WAAS,cAAc,QAAyB;AAC9C,UAAM,MAAM,gBAAgB;AAC5B,UAAM,MAAM,OAAO,YAAY;AAC/B,QAAI,UAAU;AACd,eAAW,KAAK,OAAO,KAAK,IAAI,QAAQ,GAAG;AACzC,UAAI,EAAE,YAAY,MAAM,KAAK;AAC3B,eAAO,IAAI,SAAS,CAAC;AACrB,kBAAU;AAAA,MACZ;AAAA,IACF;AACA,QAAI,QAAS,kBAAiB,GAAG;AACjC,WAAO;AAAA,EACT;AAEA,WAAS,eAAsE;AAC7E,UAAM,MAAM,gBAAgB;AAC5B,WAAO,OAAO,QAAQ,IAAI,QAAQ,EAAE,IAAI,CAAC,CAAC,QAAQ,OAAO,OAAO,EAAE,QAAQ,QAAQ,EAAE;AAAA,EACtF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -43,7 +43,7 @@ export interface StartupUpdateConfig {
|
|
|
43
43
|
skipDisabledBindings: boolean;
|
|
44
44
|
failMode: "continue" | "abort";
|
|
45
45
|
}
|
|
46
|
-
/**
|
|
46
|
+
/** 资源包卸载策略(与 CF 更新同属 packs 生命周期配置) */
|
|
47
47
|
export interface PackUninstallConfig {
|
|
48
48
|
/** true:移入回收站;false:直接删除目录 */
|
|
49
49
|
recycleBin: boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/pack-update/types.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * pack-update \u7C7B\u578B\u5B9A\u4E49\n */\n\nexport type PackReleaseType = \"release\" | \"beta\" | \"alpha\";\n\n/** \u5DF2\u5B9E\u73B0\u7684\u6E90\u63D0\u4F9B\u8005 id\uFF08\u6269\u5C55\u65F6\u53EA\u52A0\u5B57\u9762\u91CF\uFF0C\u7F16\u6392\u5C42\u8D70 PackSourceProvider\uFF09 */\nexport type PackProviderId = \"curseforge\";\n\n/**\n * \u540D\u79F0/slug \u5339\u914D\u7B56\u7565\u3002\n * \u63A2\u6D4B\u4E0E search \u5171\u7528\uFF1B\u52FF\u518D\u52A0\u672A\u63A5\u7EBF\u7684\u5F00\u5173\uFF08\u66FE\u51FA\u73B0 byUuidInArchive/byName \u6B7B\u914D\u7F6E\uFF09\u3002\n */\nexport interface PackUpdateMatchConfig {\n nameMinScore: number;\n stripFolderTags: boolean;\n}\n\n/** CF \u6E90\u4E13\u5C5E\u914D\u7F6E\uFF08\u4E0D\u542B\u901A\u7528 match\uFF1Bmatch \u5728 PackUpdateConfig \u9876\u5C42\uFF09 */\nexport interface CurseForgeProviderConfig {\n enabled: boolean;\n apiKey: string;\n /** \u5B98\u65B9 Core API\uFF0C\u7528\u4E8E getMod / files / download-url */\n baseUrl: string;\n /**\n * \u641C\u7D22\u7528\u955C\u50CF\uFF08\u5B98\u65B9 /v1/mods/search \u90E8\u5206 key \u4F1A 403\uFF09\u3002\n * \u9ED8\u8BA4 https://api.curse.tools/v1/cf\n */\n searchBaseUrl: string;\n /** Minecraft Bedrock = 78022\uFF08\u4E0D\u662F 459\uFF09 */\n gameId: number;\n /** Addons class = 4984\uFF1Bnull \u65F6\u81EA\u52A8\u89E3\u6790 */\n classId: number | null;\n pageSize: number;\n preferredReleaseTypes: PackReleaseType[];\n}\n\nexport interface VersionPolicyConfig {\n authority: \"behavior_pack\";\n onUpdateOverwriteBoth: boolean;\n rpBumpWhenSameMajor: boolean;\n rpBumpComponent: \"patch\" | \"minor\";\n majorHigherSkipRpBump: boolean;\n}\n\nexport interface StartupUpdateConfig {\n sequential: boolean;\n delayMsBetweenPacks: number;\n skipDisabledBindings: boolean;\n failMode: \"continue\" | \"abort\";\n}\n\n/** \
|
|
4
|
+
"sourcesContent": ["/**\n * pack-update \u7C7B\u578B\u5B9A\u4E49\n */\n\nexport type PackReleaseType = \"release\" | \"beta\" | \"alpha\";\n\n/** \u5DF2\u5B9E\u73B0\u7684\u6E90\u63D0\u4F9B\u8005 id\uFF08\u6269\u5C55\u65F6\u53EA\u52A0\u5B57\u9762\u91CF\uFF0C\u7F16\u6392\u5C42\u8D70 PackSourceProvider\uFF09 */\nexport type PackProviderId = \"curseforge\";\n\n/**\n * \u540D\u79F0/slug \u5339\u914D\u7B56\u7565\u3002\n * \u63A2\u6D4B\u4E0E search \u5171\u7528\uFF1B\u52FF\u518D\u52A0\u672A\u63A5\u7EBF\u7684\u5F00\u5173\uFF08\u66FE\u51FA\u73B0 byUuidInArchive/byName \u6B7B\u914D\u7F6E\uFF09\u3002\n */\nexport interface PackUpdateMatchConfig {\n nameMinScore: number;\n stripFolderTags: boolean;\n}\n\n/** CF \u6E90\u4E13\u5C5E\u914D\u7F6E\uFF08\u4E0D\u542B\u901A\u7528 match\uFF1Bmatch \u5728 PackUpdateConfig \u9876\u5C42\uFF09 */\nexport interface CurseForgeProviderConfig {\n enabled: boolean;\n apiKey: string;\n /** \u5B98\u65B9 Core API\uFF0C\u7528\u4E8E getMod / files / download-url */\n baseUrl: string;\n /**\n * \u641C\u7D22\u7528\u955C\u50CF\uFF08\u5B98\u65B9 /v1/mods/search \u90E8\u5206 key \u4F1A 403\uFF09\u3002\n * \u9ED8\u8BA4 https://api.curse.tools/v1/cf\n */\n searchBaseUrl: string;\n /** Minecraft Bedrock = 78022\uFF08\u4E0D\u662F 459\uFF09 */\n gameId: number;\n /** Addons class = 4984\uFF1Bnull \u65F6\u81EA\u52A8\u89E3\u6790 */\n classId: number | null;\n pageSize: number;\n preferredReleaseTypes: PackReleaseType[];\n}\n\nexport interface VersionPolicyConfig {\n authority: \"behavior_pack\";\n onUpdateOverwriteBoth: boolean;\n rpBumpWhenSameMajor: boolean;\n rpBumpComponent: \"patch\" | \"minor\";\n majorHigherSkipRpBump: boolean;\n}\n\nexport interface StartupUpdateConfig {\n sequential: boolean;\n delayMsBetweenPacks: number;\n skipDisabledBindings: boolean;\n failMode: \"continue\" | \"abort\";\n}\n\n/** \u8D44\u6E90\u5305\u5378\u8F7D\u7B56\u7565\uFF08\u4E0E CF \u66F4\u65B0\u540C\u5C5E packs \u751F\u547D\u5468\u671F\u914D\u7F6E\uFF09 */\nexport interface PackUninstallConfig {\n /** true\uFF1A\u79FB\u5165\u56DE\u6536\u7AD9\uFF1Bfalse\uFF1A\u76F4\u63A5\u5220\u9664\u76EE\u5F55 */\n recycleBin: boolean;\n /** \u76F8\u5BF9 SFMC_ROOT \u7684\u56DE\u6536\u7AD9\u8DEF\u5F84\uFF0C\u9ED8\u8BA4 packs/_trash */\n trashRelativeDir: string;\n}\n\n/** \u5378\u8F7D\u7B56\u7565\u5185\u7F6E\u9ED8\u8BA4\uFF08DEFAULTS / resolve / schema \u6587\u6848\u7684\u552F\u4E00\u6743\u5A01\uFF09 */\nexport const DEFAULT_PACK_UNINSTALL: PackUninstallConfig = {\n recycleBin: true,\n trashRelativeDir: \"packs/_trash\",\n};\n\nexport interface PackUpdateConfig {\n enabled: boolean;\n checkOnBdsStart: boolean;\n applyOnBdsStart: boolean;\n askConfirmOnBind: boolean;\n probeSourceAfterInstall: boolean;\n /**\n * \u65B0\u5EFA\u7ED1\u5B9A\u7684\u9ED8\u8BA4 enabled\u3002\n * false \u65F6\u63A2\u6D4B/\u624B\u52A8 bind \u4ECD\u5199\u5165 pack-sources\uFF0C\u4F46\u4E0D\u4F1A\u81EA\u52A8\u68C0\u67E5/\u66F4\u65B0\uFF0C\u9700\u624B\u6539\u6216\u6539\u6B64\u9ED8\u8BA4\u3002\n */\n defaultBindingEnabled: boolean;\n /**\n * \u540D\u79F0/slug \u5339\u914D\u7B56\u7565\uFF08\u6E90\u65E0\u5173\uFF09\u3002\n * \u52FF\u518D\u585E\u8FDB providers.*\uFF08\u66FE\u6302\u5728 curseforge \u4E0B\uFF0C\u8FDD\u53CD DIP/OCP\uFF09\u3002\n */\n match: PackUpdateMatchConfig;\n providers: {\n curseforge: CurseForgeProviderConfig;\n };\n versionPolicy: VersionPolicyConfig;\n startup: StartupUpdateConfig;\n uninstall: PackUninstallConfig;\n}\n\nexport interface PackSourceBinding {\n enabled: boolean;\n provider: PackProviderId;\n projectId: number;\n slug: string;\n websiteUrl: string;\n pairedResourceUuid: string | null;\n lastFileId: number | null;\n lastCheckedAt: string | null;\n lastAppliedFileId: number | null;\n}\n\nexport interface PackSourcesFile {\n bindings: Record<string, PackSourceBinding>;\n}\n\nexport interface SourceSearchHit {\n provider: PackProviderId;\n projectId: number;\n slug: string;\n name: string;\n summary: string;\n websiteUrl: string;\n downloadCount?: number;\n}\n\nexport interface SourceFileRef {\n provider: PackProviderId;\n projectId: number;\n fileId: number;\n fileName: string;\n displayName: string;\n downloadUrl: string;\n fileDate?: string;\n releaseType?: PackReleaseType;\n}\n\n/** \u6E90\u63D0\u4F9B\u8005\u5951\u7EA6\uFF1A\u7F16\u6392\u5C42\u53EA\u4F9D\u8D56\u6B64\u63A5\u53E3\uFF08DIP\uFF09\uFF0C\u5177\u4F53\u5B9E\u73B0\u53EF\u4E92\u6362\uFF08LSP\uFF09 */\nexport interface PackSourceProvider {\n readonly id: PackProviderId;\n isConfigured(): boolean;\n search(query: string): Promise<SourceSearchHit[]>;\n getLatestFile(projectId: number): Promise<SourceFileRef | null>;\n download(file: SourceFileRef, destPath: string, onProgress?: (dl: number, total: number) => void): Promise<void>;\n resolveProject(ref: string | number): Promise<SourceSearchHit | null>;\n}\n\nexport type SemVer3 = [number, number, number];\n\nexport interface VersionCompareResult {\n remoteNewer: boolean;\n majorHigher: boolean;\n shouldBumpRp: boolean;\n}\n"],
|
|
5
5
|
"mappings": "AA6DO,MAAM,yBAA8C;AAAA,EACzD,YAAY;AAAA,EACZ,kBAAkB;AACpB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/world-packs.d.ts
CHANGED
|
@@ -252,7 +252,7 @@ export type UninstallPackResult = {
|
|
|
252
252
|
};
|
|
253
253
|
export type UninstallPackAction = UninstallPackResult["action"];
|
|
254
254
|
/**
|
|
255
|
-
*
|
|
255
|
+
* 卸载已安装资源包:先 disable enable-list,再移入 trashDir 或直接删除目录。
|
|
256
256
|
* trashDir 跨盘符时 fallback 为 copy + rm。
|
|
257
257
|
*/
|
|
258
258
|
export declare function uninstallInstalledPack(opts: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"world-packs.d.ts","sourceRoot":"","sources":["../src/world-packs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,EAAwD,KAAK,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACpH,OAAO,EAYL,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC7B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,wBAAwB,EACxB,2BAA2B,EAC3B,iBAAiB,EACjB,uBAAuB,EACvB,2BAA2B,EAC3B,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,GAC1B,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,UAAU,CAAC;AAEpD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,OAAO,EAAE,OAAO,CAAC;CAClB;AAID,iDAAiD;AACjD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,MAAM,CAStF;AAED,iCAAiC;AACjC,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOlE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAKhE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,gBAAgB,CAAC;IACvB,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACnC,kCAAkC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG,MAAM,CAmBT;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,gBAAgB,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG,MAAM,CAQT;AAED,4CAA4C;AAC5C,wBAAgB,0BAA0B,CAAC,GAAG,EAAE;IAAE,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,aAAa,GAAG,IAAI,CAK5G;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"world-packs.d.ts","sourceRoot":"","sources":["../src/world-packs.ts"],"names":[],"mappings":"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"}
|
package/dist/world-packs.js.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 { 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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",
|
|
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\n .readFileSync(file, \"utf8\")\n .replace(/^\\uFEFF/, \"\")\n .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\" ? { description: resolvePackLocalizedText(packDir, 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(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\u8D44\u6E90\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
6
|
"names": ["enableExperimentsInLevelDat", "readLevelDatExperiments"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sfmc-bds/bds-tools",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "SFMC BDS auto-updater, lifecycle manager, and behavior-pack assembler",
|
|
5
5
|
"author": "Shiroha7z",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"jszip": "^3.10.1",
|
|
56
56
|
"node-html-parser": "^9.0.0",
|
|
57
|
-
"@sfmc-bds/sdk": "0.2.
|
|
57
|
+
"@sfmc-bds/sdk": "0.2.3"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@sfmc-bds/tools": "0.2.
|
|
60
|
+
"@sfmc-bds/tools": "0.2.3"
|
|
61
61
|
},
|
|
62
62
|
"publishConfig": {
|
|
63
63
|
"access": "public",
|