@sfmc-bds/bds-tools 0.2.0-beta.11 → 0.2.0-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bds-manager.d.ts.map +1 -1
- package/dist/bds-manager.js +12 -1
- package/dist/bds-manager.js.map +2 -2
- package/dist/check-update.d.ts.map +1 -1
- package/dist/check-update.js +3 -2
- package/dist/check-update.js.map +2 -2
- package/dist/cli-pack-manager.js +11 -1
- package/dist/cli-pack-manager.js.map +2 -2
- package/dist/dependency-negotiator.d.ts +73 -0
- package/dist/dependency-negotiator.d.ts.map +1 -0
- package/dist/dependency-negotiator.js +151 -0
- package/dist/dependency-negotiator.js.map +7 -0
- package/dist/dependency-negotiator.test.js +120 -0
- package/dist/dependency-negotiator.test.js.map +7 -0
- package/dist/level-dat.d.ts +87 -0
- package/dist/level-dat.d.ts.map +1 -0
- package/dist/level-dat.js +326 -0
- package/dist/level-dat.js.map +7 -0
- package/dist/level-dat.test.js +125 -0
- package/dist/level-dat.test.js.map +7 -0
- package/dist/pack-manager.d.ts +18 -6
- package/dist/pack-manager.d.ts.map +1 -1
- package/dist/pack-manager.js +73 -24
- package/dist/pack-manager.js.map +2 -2
- package/dist/server-properties-i18n.d.ts +17 -0
- package/dist/server-properties-i18n.d.ts.map +1 -0
- package/dist/server-properties-i18n.js +197 -0
- package/dist/server-properties-i18n.js.map +7 -0
- package/dist/server-properties.d.ts +22 -0
- package/dist/server-properties.d.ts.map +1 -1
- package/dist/server-properties.js +126 -1
- package/dist/server-properties.js.map +2 -2
- package/dist/server-properties.test.js +127 -0
- package/dist/server-properties.test.js.map +7 -0
- package/dist/world-packs.d.ts +57 -1
- package/dist/world-packs.d.ts.map +1 -1
- package/dist/world-packs.js +159 -1
- package/dist/world-packs.js.map +2 -2
- package/package.json +6 -3
|
@@ -9,4 +9,26 @@ export type ServerPropertiesLogger = {
|
|
|
9
9
|
* @returns true = 本次新追加;false = 跳过
|
|
10
10
|
*/
|
|
11
11
|
export declare function ensureEmitServerTelemetry(bdsRoot: string, logger?: ServerPropertiesLogger): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* 解析并探测当前应当采用的 BDS 本地化语言代码(例如 zh-CN 或 en)。
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveBdsLocale(rootDir?: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* 纯函数:将 server.properties 文本中的注释替换为目标语言的结构化中文说明。
|
|
18
|
+
* 严格保留配置项的 key 与当前生效的 value。若遇到未收录的键或纯注释块,原样保留。
|
|
19
|
+
*/
|
|
20
|
+
export declare function localizeServerPropertiesContent(text: string, locale?: string): {
|
|
21
|
+
content: string;
|
|
22
|
+
modified: boolean;
|
|
23
|
+
};
|
|
24
|
+
export interface LocalizeServerPropertiesOptions {
|
|
25
|
+
locale?: string;
|
|
26
|
+
rootDir?: string;
|
|
27
|
+
logger?: ServerPropertiesLogger;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 对 `<bdsRoot>/server.properties` 中的注释执行本地化重写。
|
|
31
|
+
* @returns true = 本次成功重写并保存;false = 跳过或无改动
|
|
32
|
+
*/
|
|
33
|
+
export declare function localizeServerProperties(bdsRoot: string, options?: LocalizeServerPropertiesOptions): boolean;
|
|
12
34
|
//# sourceMappingURL=server-properties.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-properties.d.ts","sourceRoot":"","sources":["../src/server-properties.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server-properties.d.ts","sourceRoot":"","sources":["../src/server-properties.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,yBAAyB,0BAA0B,CAAC;AACjE,eAAO,MAAM,0BAA0B,+BAA+B,CAAC;AAEvE,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,sBAAsB,GAC9B,OAAO,CAmBT;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CA4BzD;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,MAAM,EACZ,MAAM,GAAE,MAAgB,GACvB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAgGxC;AAED,MAAM,WAAW,+BAA+B;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,sBAAsB,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,+BAA+B,GACxC,OAAO,CAmBT"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { configPath, readJson } from "@sfmc-bds/sdk/node/config";
|
|
1
2
|
import fs from "node:fs";
|
|
2
3
|
import { serverPropertiesPath } from "./pack-manager.js";
|
|
4
|
+
import { ROOT_DIR } from "./paths.js";
|
|
5
|
+
import { getServerPropertyDoc } from "./server-properties-i18n.js";
|
|
3
6
|
const EMIT_SERVER_TELEMETRY_KEY = "emit-server-telemetry";
|
|
4
7
|
const EMIT_SERVER_TELEMETRY_LINE = "emit-server-telemetry=true";
|
|
5
8
|
function ensureEmitServerTelemetry(bdsRoot, logger) {
|
|
@@ -20,9 +23,131 @@ function ensureEmitServerTelemetry(bdsRoot, logger) {
|
|
|
20
23
|
);
|
|
21
24
|
return true;
|
|
22
25
|
}
|
|
26
|
+
function resolveBdsLocale(rootDir) {
|
|
27
|
+
const envLang = process.env.SFMC_LOCALE || process.env.SFMC_LANG;
|
|
28
|
+
if (envLang) {
|
|
29
|
+
return envLang;
|
|
30
|
+
}
|
|
31
|
+
const root = rootDir || ROOT_DIR;
|
|
32
|
+
try {
|
|
33
|
+
const runtime = readJson(configPath(root, "runtime.json"));
|
|
34
|
+
if (runtime?.locale) {
|
|
35
|
+
return runtime.locale;
|
|
36
|
+
}
|
|
37
|
+
} catch {
|
|
38
|
+
}
|
|
39
|
+
const osLangs = [
|
|
40
|
+
process.env.LC_ALL,
|
|
41
|
+
process.env.LC_MESSAGES,
|
|
42
|
+
process.env.LANG,
|
|
43
|
+
Intl.DateTimeFormat().resolvedOptions().locale
|
|
44
|
+
];
|
|
45
|
+
for (const raw of osLangs) {
|
|
46
|
+
if (raw && /^zh\b/i.test(raw)) {
|
|
47
|
+
return "zh-CN";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return "en";
|
|
51
|
+
}
|
|
52
|
+
function localizeServerPropertiesContent(text, locale = "zh-CN") {
|
|
53
|
+
const normalizedLocale = locale.toLowerCase();
|
|
54
|
+
if (!normalizedLocale.startsWith("zh")) {
|
|
55
|
+
return { content: text, modified: false };
|
|
56
|
+
}
|
|
57
|
+
if (!text || text.trim().length === 0) {
|
|
58
|
+
return { content: text, modified: false };
|
|
59
|
+
}
|
|
60
|
+
const eol = text.includes("\r\n") ? "\r\n" : "\n";
|
|
61
|
+
const lines = text.split(/\r?\n/);
|
|
62
|
+
const blocks = [];
|
|
63
|
+
let currentBlock = [];
|
|
64
|
+
let currentKey;
|
|
65
|
+
let currentValue;
|
|
66
|
+
function flushBlock() {
|
|
67
|
+
if (currentBlock.length > 0) {
|
|
68
|
+
blocks.push({
|
|
69
|
+
key: currentKey,
|
|
70
|
+
value: currentValue,
|
|
71
|
+
originalLines: currentBlock
|
|
72
|
+
});
|
|
73
|
+
currentBlock = [];
|
|
74
|
+
currentKey = void 0;
|
|
75
|
+
currentValue = void 0;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const kvRegex = /^\s*([A-Za-z0-9._-]+)\s*=\s*(.*)$/;
|
|
79
|
+
for (let i = 0; i < lines.length; i++) {
|
|
80
|
+
const line = lines[i];
|
|
81
|
+
if (typeof line !== "string") continue;
|
|
82
|
+
const isBlank = line.trim() === "";
|
|
83
|
+
if (isBlank) {
|
|
84
|
+
flushBlock();
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const match = line.match(kvRegex);
|
|
88
|
+
if (match && match[1] !== void 0) {
|
|
89
|
+
if (currentKey !== void 0) {
|
|
90
|
+
flushBlock();
|
|
91
|
+
}
|
|
92
|
+
currentKey = match[1];
|
|
93
|
+
currentValue = match[2] ?? "";
|
|
94
|
+
currentBlock.push(line);
|
|
95
|
+
} else {
|
|
96
|
+
currentBlock.push(line);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
flushBlock();
|
|
100
|
+
const outputBlocks = [];
|
|
101
|
+
for (const block of blocks) {
|
|
102
|
+
if (block.key) {
|
|
103
|
+
const doc = getServerPropertyDoc(block.key, locale);
|
|
104
|
+
if (doc) {
|
|
105
|
+
const outLines = [`${block.key}=${block.value ?? ""}`];
|
|
106
|
+
outLines.push(`# ${doc.desc}`);
|
|
107
|
+
if (doc.values) {
|
|
108
|
+
outLines.push(`# \u53EF\u9009\u503C\uFF1A${doc.values}`);
|
|
109
|
+
}
|
|
110
|
+
if (doc.tip) {
|
|
111
|
+
outLines.push(`# \u63D0\u793A\uFF1A${doc.tip}`);
|
|
112
|
+
}
|
|
113
|
+
outputBlocks.push(outLines.join(eol));
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
outputBlocks.push(block.originalLines.join(eol));
|
|
118
|
+
}
|
|
119
|
+
let newContent = outputBlocks.join(eol + eol);
|
|
120
|
+
if (newContent.length > 0 && !newContent.endsWith(eol)) {
|
|
121
|
+
newContent += eol;
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
content: newContent,
|
|
125
|
+
modified: newContent !== text
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function localizeServerProperties(bdsRoot, options) {
|
|
129
|
+
const file = serverPropertiesPath(bdsRoot);
|
|
130
|
+
if (!fs.existsSync(file)) return false;
|
|
131
|
+
const locale = options?.locale || resolveBdsLocale(options?.rootDir);
|
|
132
|
+
const normalizedLocale = locale.toLowerCase();
|
|
133
|
+
if (!normalizedLocale.startsWith("zh")) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
const raw = fs.readFileSync(file, "utf8");
|
|
137
|
+
const { content, modified } = localizeServerPropertiesContent(raw, locale);
|
|
138
|
+
if (!modified) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
fs.writeFileSync(file, content, "utf8");
|
|
142
|
+
options?.logger?.info("\u5DF2\u5C06 server.properties \u4E2D\u7684\u6CE8\u91CA\u672C\u5730\u5316\u4E3A\u7B80\u4F53\u4E2D\u6587\uFF08\u4FDD\u7559\u6240\u6709\u65E2\u6709\u914D\u7F6E\u503C\uFF09");
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
23
145
|
export {
|
|
24
146
|
EMIT_SERVER_TELEMETRY_KEY,
|
|
25
147
|
EMIT_SERVER_TELEMETRY_LINE,
|
|
26
|
-
ensureEmitServerTelemetry
|
|
148
|
+
ensureEmitServerTelemetry,
|
|
149
|
+
localizeServerProperties,
|
|
150
|
+
localizeServerPropertiesContent,
|
|
151
|
+
resolveBdsLocale
|
|
27
152
|
};
|
|
28
153
|
//# sourceMappingURL=server-properties.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/server-properties.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * server.properties \u8F85\u52A9\uFF1A\u5B89\u88C5/\u542F\u52A8\u65F6\u786E\u4FDD emit-server-telemetry=true\n */\nimport fs from \"node:fs\";\nimport { serverPropertiesPath } from \"./pack-manager.js\";\n\nexport const EMIT_SERVER_TELEMETRY_KEY = \"emit-server-telemetry\";\nexport const EMIT_SERVER_TELEMETRY_LINE = \"emit-server-telemetry=true\";\n\nexport type ServerPropertiesLogger = {\n info: (msg: string) => void;\n};\n\n/**\n * \u82E5 `<bdsRoot>/server.properties` \u4E2D\u5C1A\u65E0 emit-server-telemetry\uFF0C\u5219\u8FFD\u52A0 `=true`\u3002\n * \u5DF2\u6709\u8BE5\u952E\uFF08\u4EFB\u610F\u503C\uFF09\u5219\u8DF3\u8FC7\u3002\u6587\u4EF6\u4E0D\u5B58\u5728\u65F6\u8DF3\u8FC7\uFF08BDS \u5C1A\u672A\u89E3\u538B\uFF09\u3002\n * @returns true = \u672C\u6B21\u65B0\u8FFD\u52A0\uFF1Bfalse = \u8DF3\u8FC7\n */\nexport function ensureEmitServerTelemetry(\n bdsRoot: string,\n logger?: ServerPropertiesLogger\n): boolean {\n const file = serverPropertiesPath(bdsRoot);\n if (!fs.existsSync(file)) return false;\n\n let text = fs.readFileSync(file, \"utf8\");\n if (/^\\s*emit-server-telemetry\\s*=/im.test(text)) {\n return false;\n }\n\n if (text.length > 0 && !text.endsWith(\"\\n\")) {\n text += \"\\n\";\n }\n text += `${EMIT_SERVER_TELEMETRY_LINE}\\n`;\n fs.writeFileSync(file, text, \"utf8\");\n\n logger?.info(\n \"\u5DF2\u5411 server.properties \u8FFD\u52A0 emit-server-telemetry=true\uFF08\u56E0\u60A8\u5DF2\u540C\u610F Mojang EULA\uFF0C\u6309\u534F\u8BAE\u542F\u7528\u670D\u52A1\u5668\u9065\u6D4B\uFF09\"\n );\n return true;\n}\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["/**\n * server-properties.ts \u2014 BDS server.properties \u8F85\u52A9\u5DE5\u5177\u96C6\n *\n * \u804C\u8D23\uFF1A\n * 1. \u5B89\u88C5/\u542F\u52A8\u65F6\u786E\u4FDD emit-server-telemetry=true\n * 2. \u5B89\u88C5/\u66F4\u65B0/\u542F\u52A8\u65F6\u652F\u6301\u5C06\u914D\u7F6E\u6CE8\u91CA\u7ED3\u6784\u5316\u672C\u5730\u5316\uFF08\u5982\u7FFB\u8BD1\u4E3A\u7B80\u4F53\u4E2D\u6587 zh-CN\uFF09\uFF0C\n * \u4E25\u683C\u4FDD\u7559\u6240\u6709\u914D\u7F6E\u952E\uFF08Key\uFF09\u4E0E\u7528\u6237\u914D\u7F6E\u503C\uFF08Value\uFF09\u3002\n */\nimport { configPath, readJson } from \"@sfmc-bds/sdk/node/config\";\nimport fs from \"node:fs\";\nimport { serverPropertiesPath } from \"./pack-manager.js\";\nimport { ROOT_DIR } from \"./paths.js\";\nimport { getServerPropertyDoc } from \"./server-properties-i18n.js\";\n\nexport const EMIT_SERVER_TELEMETRY_KEY = \"emit-server-telemetry\";\nexport const EMIT_SERVER_TELEMETRY_LINE = \"emit-server-telemetry=true\";\n\nexport type ServerPropertiesLogger = {\n info: (msg: string) => void;\n};\n\n/**\n * \u82E5 `<bdsRoot>/server.properties` \u4E2D\u5C1A\u65E0 emit-server-telemetry\uFF0C\u5219\u8FFD\u52A0 `=true`\u3002\n * \u5DF2\u6709\u8BE5\u952E\uFF08\u4EFB\u610F\u503C\uFF09\u5219\u8DF3\u8FC7\u3002\u6587\u4EF6\u4E0D\u5B58\u5728\u65F6\u8DF3\u8FC7\uFF08BDS \u5C1A\u672A\u89E3\u538B\uFF09\u3002\n * @returns true = \u672C\u6B21\u65B0\u8FFD\u52A0\uFF1Bfalse = \u8DF3\u8FC7\n */\nexport function ensureEmitServerTelemetry(\n bdsRoot: string,\n logger?: ServerPropertiesLogger\n): boolean {\n const file = serverPropertiesPath(bdsRoot);\n if (!fs.existsSync(file)) return false;\n\n let text = fs.readFileSync(file, \"utf8\");\n if (/^\\s*emit-server-telemetry\\s*=/im.test(text)) {\n return false;\n }\n\n if (text.length > 0 && !text.endsWith(\"\\n\")) {\n text += \"\\n\";\n }\n text += `${EMIT_SERVER_TELEMETRY_LINE}\\n`;\n fs.writeFileSync(file, text, \"utf8\");\n\n logger?.info(\n \"\u5DF2\u5411 server.properties \u8FFD\u52A0 emit-server-telemetry=true\uFF08\u56E0\u60A8\u5DF2\u540C\u610F Mojang EULA\uFF0C\u6309\u534F\u8BAE\u542F\u7528\u670D\u52A1\u5668\u9065\u6D4B\uFF09\"\n );\n return true;\n}\n\n/**\n * \u89E3\u6790\u5E76\u63A2\u6D4B\u5F53\u524D\u5E94\u5F53\u91C7\u7528\u7684 BDS \u672C\u5730\u5316\u8BED\u8A00\u4EE3\u7801\uFF08\u4F8B\u5982 zh-CN \u6216 en\uFF09\u3002\n */\nexport function resolveBdsLocale(rootDir?: string): string {\n const envLang = process.env.SFMC_LOCALE || process.env.SFMC_LANG;\n if (envLang) {\n return envLang;\n }\n\n const root = rootDir || ROOT_DIR;\n try {\n const runtime = readJson<{ locale?: string }>(configPath(root, \"runtime.json\"));\n if (runtime?.locale) {\n return runtime.locale;\n }\n } catch {\n // \u5FFD\u7565\u5F02\u5E38\uFF0C\u964D\u7EA7\u5230\u7CFB\u7EDF\u8BED\u8A00\u63A2\u6D4B\n }\n\n const osLangs = [\n process.env.LC_ALL,\n process.env.LC_MESSAGES,\n process.env.LANG,\n Intl.DateTimeFormat().resolvedOptions().locale,\n ];\n for (const raw of osLangs) {\n if (raw && /^zh\\b/i.test(raw)) {\n return \"zh-CN\";\n }\n }\n return \"en\";\n}\n\n/**\n * \u7EAF\u51FD\u6570\uFF1A\u5C06 server.properties \u6587\u672C\u4E2D\u7684\u6CE8\u91CA\u66FF\u6362\u4E3A\u76EE\u6807\u8BED\u8A00\u7684\u7ED3\u6784\u5316\u4E2D\u6587\u8BF4\u660E\u3002\n * \u4E25\u683C\u4FDD\u7559\u914D\u7F6E\u9879\u7684 key \u4E0E\u5F53\u524D\u751F\u6548\u7684 value\u3002\u82E5\u9047\u5230\u672A\u6536\u5F55\u7684\u952E\u6216\u7EAF\u6CE8\u91CA\u5757\uFF0C\u539F\u6837\u4FDD\u7559\u3002\n */\nexport function localizeServerPropertiesContent(\n text: string,\n locale: string = \"zh-CN\"\n): { content: string; modified: boolean } {\n const normalizedLocale = locale.toLowerCase();\n // \u76EE\u524D\u4EC5\u5BF9\u4E2D\u6587\u505A\u672C\u5730\u5316\u91CD\u5199\uFF1B\u82F1\u6587\u6216\u5176\u4ED6\u8BED\u8A00\u4FDD\u6301\u539F\u6C41\u539F\u5473\n if (!normalizedLocale.startsWith(\"zh\")) {\n return { content: text, modified: false };\n }\n\n if (!text || text.trim().length === 0) {\n return { content: text, modified: false };\n }\n\n const eol = text.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\";\n const lines = text.split(/\\r?\\n/);\n\n interface Block {\n key: string | undefined;\n value: string | undefined;\n originalLines: string[];\n }\n\n const blocks: Block[] = [];\n let currentBlock: string[] = [];\n let currentKey: string | undefined;\n let currentValue: string | undefined;\n\n function flushBlock() {\n if (currentBlock.length > 0) {\n blocks.push({\n key: currentKey,\n value: currentValue,\n originalLines: currentBlock,\n });\n currentBlock = [];\n currentKey = undefined;\n currentValue = undefined;\n }\n }\n\n const kvRegex = /^\\s*([A-Za-z0-9._-]+)\\s*=\\s*(.*)$/;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (typeof line !== \"string\") continue;\n const isBlank = line.trim() === \"\";\n\n if (isBlank) {\n flushBlock();\n continue;\n }\n\n const match = line.match(kvRegex);\n if (match && match[1] !== undefined) {\n // \u82E5\u5F53\u524D\u5757\u5185\u5DF2\u7ECF\u5B58\u5728\u4E00\u4E2A\u952E\u503C\u5BF9\uFF0C\u5219\u5148\u7ED3\u7B97\u4E0A\u4E00\u5757\n if (currentKey !== undefined) {\n flushBlock();\n }\n currentKey = match[1];\n currentValue = match[2] ?? \"\";\n currentBlock.push(line);\n } else {\n currentBlock.push(line);\n }\n }\n flushBlock();\n\n const outputBlocks: string[] = [];\n\n for (const block of blocks) {\n if (block.key) {\n const doc = getServerPropertyDoc(block.key, locale);\n if (doc) {\n const outLines: string[] = [`${block.key}=${block.value ?? \"\"}`];\n outLines.push(`# ${doc.desc}`);\n if (doc.values) {\n outLines.push(`# \u53EF\u9009\u503C\uFF1A${doc.values}`);\n }\n if (doc.tip) {\n outLines.push(`# \u63D0\u793A\uFF1A${doc.tip}`);\n }\n outputBlocks.push(outLines.join(eol));\n continue;\n }\n }\n // \u672A\u6536\u5F55\u7684\u9879\u6216\u666E\u901A\u6CE8\u91CA\u5757\uFF0C\u4FDD\u7559\u539F\u6587\u672C\n outputBlocks.push(block.originalLines.join(eol));\n }\n\n let newContent = outputBlocks.join(eol + eol);\n if (newContent.length > 0 && !newContent.endsWith(eol)) {\n newContent += eol;\n }\n\n return {\n content: newContent,\n modified: newContent !== text,\n };\n}\n\nexport interface LocalizeServerPropertiesOptions {\n locale?: string;\n rootDir?: string;\n logger?: ServerPropertiesLogger;\n}\n\n/**\n * \u5BF9 `<bdsRoot>/server.properties` \u4E2D\u7684\u6CE8\u91CA\u6267\u884C\u672C\u5730\u5316\u91CD\u5199\u3002\n * @returns true = \u672C\u6B21\u6210\u529F\u91CD\u5199\u5E76\u4FDD\u5B58\uFF1Bfalse = \u8DF3\u8FC7\u6216\u65E0\u6539\u52A8\n */\nexport function localizeServerProperties(\n bdsRoot: string,\n options?: LocalizeServerPropertiesOptions\n): boolean {\n const file = serverPropertiesPath(bdsRoot);\n if (!fs.existsSync(file)) return false;\n\n const locale = options?.locale || resolveBdsLocale(options?.rootDir);\n const normalizedLocale = locale.toLowerCase();\n if (!normalizedLocale.startsWith(\"zh\")) {\n return false;\n }\n\n const raw = fs.readFileSync(file, \"utf8\");\n const { content, modified } = localizeServerPropertiesContent(raw, locale);\n if (!modified) {\n return false;\n }\n\n fs.writeFileSync(file, content, \"utf8\");\n options?.logger?.info(\"\u5DF2\u5C06 server.properties \u4E2D\u7684\u6CE8\u91CA\u672C\u5730\u5316\u4E3A\u7B80\u4F53\u4E2D\u6587\uFF08\u4FDD\u7559\u6240\u6709\u65E2\u6709\u914D\u7F6E\u503C\uFF09\");\n return true;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { describe, it } from "node:test";
|
|
6
|
+
import { rmSafe } from "./fsx.js";
|
|
7
|
+
import {
|
|
8
|
+
ensureEmitServerTelemetry,
|
|
9
|
+
localizeServerProperties,
|
|
10
|
+
localizeServerPropertiesContent,
|
|
11
|
+
resolveBdsLocale
|
|
12
|
+
} from "./server-properties.js";
|
|
13
|
+
const SAMPLE_VANILLA_PROPERTIES = `server-name=Dedicated Server
|
|
14
|
+
# Used as the server name
|
|
15
|
+
# Allowed values: Any string without semicolon symbol.
|
|
16
|
+
|
|
17
|
+
gamemode=survival
|
|
18
|
+
# Sets the game mode for new players.
|
|
19
|
+
# Allowed values: "survival", "creative", or "adventure"
|
|
20
|
+
|
|
21
|
+
force-gamemode=false
|
|
22
|
+
# Prevents the server from sending level settings to clients
|
|
23
|
+
|
|
24
|
+
allow-cheats=false
|
|
25
|
+
# If true then cheats like commands can be used.
|
|
26
|
+
|
|
27
|
+
custom-unknown-flag=hello-world
|
|
28
|
+
# This is a third-party or future setting
|
|
29
|
+
`;
|
|
30
|
+
describe("server-properties: localizeServerPropertiesContent", () => {
|
|
31
|
+
it("\u5C06\u5DF2\u77E5\u914D\u7F6E\u9879\u7684\u82F1\u6587\u6CE8\u91CA\u66FF\u6362\u4E3A\u4E2D\u6587\uFF0C\u4E14\u4E25\u683C\u4FDD\u7559\u7528\u6237\u914D\u7F6E\u503C", () => {
|
|
32
|
+
const customText = `server-name=\u6211\u7684\u4E16\u754C\u670D\u52A1\u5668
|
|
33
|
+
# Used as the server name
|
|
34
|
+
|
|
35
|
+
gamemode=creative
|
|
36
|
+
# Sets the game mode for new players.
|
|
37
|
+
|
|
38
|
+
server-port=25565
|
|
39
|
+
`;
|
|
40
|
+
const { content, modified } = localizeServerPropertiesContent(customText, "zh-CN");
|
|
41
|
+
assert.equal(modified, true);
|
|
42
|
+
assert.match(content, /server-name=我的世界服务器/);
|
|
43
|
+
assert.match(content, /gamemode=creative/);
|
|
44
|
+
assert.match(content, /server-port=25565/);
|
|
45
|
+
assert.match(content, /# 服务器名称(显示在客户端局域网\/好友列表中)/);
|
|
46
|
+
assert.match(content, /# 新玩家首次加入世界时的默认游戏模式/);
|
|
47
|
+
assert.match(content, /# 服务端监听的 IPv4 UDP 网络通信端口/);
|
|
48
|
+
});
|
|
49
|
+
it("\u4FDD\u6301\u5E42\u7B49\u6027\uFF1A\u4E8C\u6B21\u8FD0\u884C\u8F93\u51FA\u5185\u5BB9\u5B8C\u5168\u4E00\u81F4\uFF0Cmodified \u4E3A false", () => {
|
|
50
|
+
const firstRun = localizeServerPropertiesContent(SAMPLE_VANILLA_PROPERTIES, "zh-CN");
|
|
51
|
+
assert.equal(firstRun.modified, true);
|
|
52
|
+
const secondRun = localizeServerPropertiesContent(firstRun.content, "zh-CN");
|
|
53
|
+
assert.equal(secondRun.modified, false);
|
|
54
|
+
assert.equal(secondRun.content, firstRun.content);
|
|
55
|
+
});
|
|
56
|
+
it("\u4FDD\u7559\u672A\u6536\u5F55\u7684\u672A\u77E5\u9879\u4E0E\u7B2C\u4E09\u65B9\u6CE8\u91CA\u4E0D\u53D8", () => {
|
|
57
|
+
const { content } = localizeServerPropertiesContent(SAMPLE_VANILLA_PROPERTIES, "zh-CN");
|
|
58
|
+
assert.match(content, /custom-unknown-flag=hello-world/);
|
|
59
|
+
assert.match(content, /# This is a third-party or future setting/);
|
|
60
|
+
});
|
|
61
|
+
it("\u5F53 locale \u4E3A en \u6216\u975E\u4E2D\u6587\u65F6\uFF0C\u8DF3\u8FC7\u4FEE\u6539\u5E76\u8FD4\u56DE modified: false", () => {
|
|
62
|
+
const resEn = localizeServerPropertiesContent(SAMPLE_VANILLA_PROPERTIES, "en");
|
|
63
|
+
assert.equal(resEn.modified, false);
|
|
64
|
+
assert.equal(resEn.content, SAMPLE_VANILLA_PROPERTIES);
|
|
65
|
+
});
|
|
66
|
+
it("\u7A7A\u6587\u672C\u5B89\u5168\u5904\u7406", () => {
|
|
67
|
+
const res = localizeServerPropertiesContent("", "zh-CN");
|
|
68
|
+
assert.equal(res.modified, false);
|
|
69
|
+
assert.equal(res.content, "");
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe("server-properties: \u6587\u4EF6\u8BFB\u5199\u4E0E\u78C1\u76D8\u96C6\u6210", () => {
|
|
73
|
+
it("localizeServerProperties \u6B63\u786E\u5C31\u5730\u91CD\u5199\u78C1\u76D8\u6587\u4EF6", () => {
|
|
74
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-server-props-"));
|
|
75
|
+
try {
|
|
76
|
+
const propFile = path.join(tmp, "server.properties");
|
|
77
|
+
fs.writeFileSync(propFile, "server-name=TestServer\ngamemode=survival\n", "utf8");
|
|
78
|
+
const msgs = [];
|
|
79
|
+
const ok = localizeServerProperties(tmp, {
|
|
80
|
+
locale: "zh-CN",
|
|
81
|
+
logger: { info: (m) => msgs.push(m) }
|
|
82
|
+
});
|
|
83
|
+
assert.equal(ok, true);
|
|
84
|
+
assert.equal(msgs.length, 1);
|
|
85
|
+
const updated = fs.readFileSync(propFile, "utf8");
|
|
86
|
+
assert.match(updated, /server-name=TestServer/);
|
|
87
|
+
assert.match(updated, /# 服务器名称/);
|
|
88
|
+
const okAgain = localizeServerProperties(tmp, { locale: "zh-CN" });
|
|
89
|
+
assert.equal(okAgain, false);
|
|
90
|
+
} finally {
|
|
91
|
+
rmSafe(tmp);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
it("\u7ED3\u5408 ensureEmitServerTelemetry\uFF1A\u65B0\u8FFD\u52A0\u7684\u9065\u6D4B\u5F00\u5173\u540C\u6837\u80FD\u83B7\u5F97\u4E2D\u6587\u6CE8\u91CA", () => {
|
|
95
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-server-props-telemetry-"));
|
|
96
|
+
try {
|
|
97
|
+
const propFile = path.join(tmp, "server.properties");
|
|
98
|
+
fs.writeFileSync(propFile, "server-name=Dedicated Server\n", "utf8");
|
|
99
|
+
const wrote = ensureEmitServerTelemetry(tmp);
|
|
100
|
+
assert.equal(wrote, true);
|
|
101
|
+
const ok = localizeServerProperties(tmp, { locale: "zh-CN" });
|
|
102
|
+
assert.equal(ok, true);
|
|
103
|
+
const content = fs.readFileSync(propFile, "utf8");
|
|
104
|
+
assert.match(content, /emit-server-telemetry=true/);
|
|
105
|
+
assert.match(content, /# 是否向 Mojang 发送服务器遥测与运行健康诊断数据/);
|
|
106
|
+
assert.match(content, /# 提示:使用本平台时因您已同意 Mojang EULA 协议,按协议保持启用/);
|
|
107
|
+
} finally {
|
|
108
|
+
rmSafe(tmp);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
it("resolveBdsLocale \u652F\u6301\u73AF\u5883\u53D8\u91CF\u4E0E\u7CFB\u7EDF\u56DE\u9000", () => {
|
|
112
|
+
const oldEnv = process.env.SFMC_LOCALE;
|
|
113
|
+
try {
|
|
114
|
+
process.env.SFMC_LOCALE = "zh-CN";
|
|
115
|
+
assert.equal(resolveBdsLocale(), "zh-CN");
|
|
116
|
+
process.env.SFMC_LOCALE = "en";
|
|
117
|
+
assert.equal(resolveBdsLocale(), "en");
|
|
118
|
+
} finally {
|
|
119
|
+
if (oldEnv !== void 0) {
|
|
120
|
+
process.env.SFMC_LOCALE = oldEnv;
|
|
121
|
+
} else {
|
|
122
|
+
delete process.env.SFMC_LOCALE;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
//# sourceMappingURL=server-properties.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/server-properties.test.ts"],
|
|
4
|
+
"sourcesContent": ["import assert from \"node:assert/strict\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { describe, it } from \"node:test\";\nimport { rmSafe } from \"./fsx.js\";\nimport {\n ensureEmitServerTelemetry,\n localizeServerProperties,\n localizeServerPropertiesContent,\n resolveBdsLocale,\n} from \"./server-properties.js\";\n\nconst SAMPLE_VANILLA_PROPERTIES = `server-name=Dedicated Server\n# Used as the server name\n# Allowed values: Any string without semicolon symbol.\n\ngamemode=survival\n# Sets the game mode for new players.\n# Allowed values: \"survival\", \"creative\", or \"adventure\"\n\nforce-gamemode=false\n# Prevents the server from sending level settings to clients\n\nallow-cheats=false\n# If true then cheats like commands can be used.\n\ncustom-unknown-flag=hello-world\n# This is a third-party or future setting\n`;\n\ndescribe(\"server-properties: localizeServerPropertiesContent\", () => {\n it(\"\u5C06\u5DF2\u77E5\u914D\u7F6E\u9879\u7684\u82F1\u6587\u6CE8\u91CA\u66FF\u6362\u4E3A\u4E2D\u6587\uFF0C\u4E14\u4E25\u683C\u4FDD\u7559\u7528\u6237\u914D\u7F6E\u503C\", () => {\n const customText = `server-name=\u6211\u7684\u4E16\u754C\u670D\u52A1\u5668\n# Used as the server name\n\ngamemode=creative\n# Sets the game mode for new players.\n\nserver-port=25565\n`;\n const { content, modified } = localizeServerPropertiesContent(customText, \"zh-CN\");\n assert.equal(modified, true);\n\n // \u9A8C\u8BC1\u503C\u672A\u88AB\u8986\u76D6\u91CD\u7F6E\n assert.match(content, /server-name=\u6211\u7684\u4E16\u754C\u670D\u52A1\u5668/);\n assert.match(content, /gamemode=creative/);\n assert.match(content, /server-port=25565/);\n\n // \u9A8C\u8BC1\u6CE8\u91CA\u5DF2\u8F6C\u4E3A\u4E2D\u6587\n assert.match(content, /# \u670D\u52A1\u5668\u540D\u79F0\uFF08\u663E\u793A\u5728\u5BA2\u6237\u7AEF\u5C40\u57DF\u7F51\\/\u597D\u53CB\u5217\u8868\u4E2D\uFF09/);\n assert.match(content, /# \u65B0\u73A9\u5BB6\u9996\u6B21\u52A0\u5165\u4E16\u754C\u65F6\u7684\u9ED8\u8BA4\u6E38\u620F\u6A21\u5F0F/);\n assert.match(content, /# \u670D\u52A1\u7AEF\u76D1\u542C\u7684 IPv4 UDP \u7F51\u7EDC\u901A\u4FE1\u7AEF\u53E3/);\n });\n\n it(\"\u4FDD\u6301\u5E42\u7B49\u6027\uFF1A\u4E8C\u6B21\u8FD0\u884C\u8F93\u51FA\u5185\u5BB9\u5B8C\u5168\u4E00\u81F4\uFF0Cmodified \u4E3A false\", () => {\n const firstRun = localizeServerPropertiesContent(SAMPLE_VANILLA_PROPERTIES, \"zh-CN\");\n assert.equal(firstRun.modified, true);\n\n const secondRun = localizeServerPropertiesContent(firstRun.content, \"zh-CN\");\n assert.equal(secondRun.modified, false);\n assert.equal(secondRun.content, firstRun.content);\n });\n\n it(\"\u4FDD\u7559\u672A\u6536\u5F55\u7684\u672A\u77E5\u9879\u4E0E\u7B2C\u4E09\u65B9\u6CE8\u91CA\u4E0D\u53D8\", () => {\n const { content } = localizeServerPropertiesContent(SAMPLE_VANILLA_PROPERTIES, \"zh-CN\");\n assert.match(content, /custom-unknown-flag=hello-world/);\n assert.match(content, /# This is a third-party or future setting/);\n });\n\n it(\"\u5F53 locale \u4E3A en \u6216\u975E\u4E2D\u6587\u65F6\uFF0C\u8DF3\u8FC7\u4FEE\u6539\u5E76\u8FD4\u56DE modified: false\", () => {\n const resEn = localizeServerPropertiesContent(SAMPLE_VANILLA_PROPERTIES, \"en\");\n assert.equal(resEn.modified, false);\n assert.equal(resEn.content, SAMPLE_VANILLA_PROPERTIES);\n });\n\n it(\"\u7A7A\u6587\u672C\u5B89\u5168\u5904\u7406\", () => {\n const res = localizeServerPropertiesContent(\"\", \"zh-CN\");\n assert.equal(res.modified, false);\n assert.equal(res.content, \"\");\n });\n});\n\ndescribe(\"server-properties: \u6587\u4EF6\u8BFB\u5199\u4E0E\u78C1\u76D8\u96C6\u6210\", () => {\n it(\"localizeServerProperties \u6B63\u786E\u5C31\u5730\u91CD\u5199\u78C1\u76D8\u6587\u4EF6\", () => {\n const tmp = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-server-props-\"));\n try {\n const propFile = path.join(tmp, \"server.properties\");\n fs.writeFileSync(propFile, \"server-name=TestServer\\ngamemode=survival\\n\", \"utf8\");\n\n const msgs: string[] = [];\n const ok = localizeServerProperties(tmp, {\n locale: \"zh-CN\",\n logger: { info: (m) => msgs.push(m) },\n });\n\n assert.equal(ok, true);\n assert.equal(msgs.length, 1);\n\n const updated = fs.readFileSync(propFile, \"utf8\");\n assert.match(updated, /server-name=TestServer/);\n assert.match(updated, /# \u670D\u52A1\u5668\u540D\u79F0/);\n\n // \u4E8C\u6B21\u6267\u884C\u8DF3\u8FC7\n const okAgain = localizeServerProperties(tmp, { locale: \"zh-CN\" });\n assert.equal(okAgain, false);\n } finally {\n rmSafe(tmp);\n }\n });\n\n it(\"\u7ED3\u5408 ensureEmitServerTelemetry\uFF1A\u65B0\u8FFD\u52A0\u7684\u9065\u6D4B\u5F00\u5173\u540C\u6837\u80FD\u83B7\u5F97\u4E2D\u6587\u6CE8\u91CA\", () => {\n const tmp = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-server-props-telemetry-\"));\n try {\n const propFile = path.join(tmp, \"server.properties\");\n fs.writeFileSync(propFile, \"server-name=Dedicated Server\\n\", \"utf8\");\n\n // 1. \u8FFD\u52A0\u9065\u6D4B\n const wrote = ensureEmitServerTelemetry(tmp);\n assert.equal(wrote, true);\n\n // 2. \u672C\u5730\u5316\n const ok = localizeServerProperties(tmp, { locale: \"zh-CN\" });\n assert.equal(ok, true);\n\n const content = fs.readFileSync(propFile, \"utf8\");\n assert.match(content, /emit-server-telemetry=true/);\n assert.match(content, /# \u662F\u5426\u5411 Mojang \u53D1\u9001\u670D\u52A1\u5668\u9065\u6D4B\u4E0E\u8FD0\u884C\u5065\u5EB7\u8BCA\u65AD\u6570\u636E/);\n assert.match(content, /# \u63D0\u793A\uFF1A\u4F7F\u7528\u672C\u5E73\u53F0\u65F6\u56E0\u60A8\u5DF2\u540C\u610F Mojang EULA \u534F\u8BAE\uFF0C\u6309\u534F\u8BAE\u4FDD\u6301\u542F\u7528/);\n } finally {\n rmSafe(tmp);\n }\n });\n\n it(\"resolveBdsLocale \u652F\u6301\u73AF\u5883\u53D8\u91CF\u4E0E\u7CFB\u7EDF\u56DE\u9000\", () => {\n const oldEnv = process.env.SFMC_LOCALE;\n try {\n process.env.SFMC_LOCALE = \"zh-CN\";\n assert.equal(resolveBdsLocale(), \"zh-CN\");\n\n process.env.SFMC_LOCALE = \"en\";\n assert.equal(resolveBdsLocale(), \"en\");\n } finally {\n if (oldEnv !== undefined) {\n process.env.SFMC_LOCALE = oldEnv;\n } else {\n delete process.env.SFMC_LOCALE;\n }\n }\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/world-packs.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - 版本递增与同步:同步升级 manifest 中的版本元数据并对齐世界启用清单版本
|
|
8
8
|
* - 幂等安装与回滚:按 UUID 精确匹配升级与安装计划,支持删除备份至回收站机制
|
|
9
9
|
*/
|
|
10
|
-
import { type WorldPackListReadResult } from "./pack-manager.js";
|
|
10
|
+
import { type PackManifestDependency, type WorldPackListReadResult } from "./pack-manager.js";
|
|
11
11
|
export type WorldPackKind = "behavior" | "resource";
|
|
12
12
|
export interface PackManifestInfo {
|
|
13
13
|
name: string;
|
|
@@ -262,4 +262,60 @@ export declare function listWorldEnableEntries(bdsRoot: string, levelName: strin
|
|
|
262
262
|
/** 含 parseFail 信号的 enable-list 快照(doctor 用;不暴露 JSON 路径构造细节) */
|
|
263
263
|
export declare function listWorldEnableListResult(bdsRoot: string, levelName: string, kind: WorldPackKind): WorldPackListReadResult;
|
|
264
264
|
export declare function findInstalledPackById(packs: InstalledWorldPack[], id: string): InstalledWorldPack | null;
|
|
265
|
+
export interface WorldBetaApiDiagnosis {
|
|
266
|
+
hasBetaApis: boolean;
|
|
267
|
+
levelDatExists: boolean;
|
|
268
|
+
levelDatPath: string;
|
|
269
|
+
requiringPacks: Array<{
|
|
270
|
+
pack: InstalledWorldPack;
|
|
271
|
+
betaDependencies: PackManifestDependency[];
|
|
272
|
+
}>;
|
|
273
|
+
}
|
|
274
|
+
export declare function isBetaApiDependency(dep: PackManifestDependency): boolean;
|
|
275
|
+
/**
|
|
276
|
+
* 诊断指定世界中已启用的行为包对测试版 API(Beta APIs)的依赖与 level.dat 的匹配状况。
|
|
277
|
+
*/
|
|
278
|
+
export declare function checkWorldBetaApiRequirements(bdsRoot: string, levelName: string, installedPacks?: InstalledWorldPack[]): WorldBetaApiDiagnosis;
|
|
279
|
+
export interface WorldPermissionDiagnosis {
|
|
280
|
+
missingPermissions: Array<{
|
|
281
|
+
pack: InstalledWorldPack;
|
|
282
|
+
moduleName: string;
|
|
283
|
+
}>;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* 诊断行为包依赖的原生模块(如 @minecraft/server-net, @minecraft/diagnostics 等)是否已在 BDS config 中授权。
|
|
287
|
+
*/
|
|
288
|
+
export declare function checkWorldScriptPermissions(bdsRoot: string, levelName: string, installedPacks?: InstalledWorldPack[]): WorldPermissionDiagnosis;
|
|
289
|
+
export interface RepairWorldPacksResult {
|
|
290
|
+
cleanedGhostPacks: Array<{
|
|
291
|
+
kind: WorldPackKind;
|
|
292
|
+
uuid: string;
|
|
293
|
+
}>;
|
|
294
|
+
syncedVersions: Array<{
|
|
295
|
+
kind: WorldPackKind;
|
|
296
|
+
folder: string;
|
|
297
|
+
listVer: string;
|
|
298
|
+
diskVer: string;
|
|
299
|
+
}>;
|
|
300
|
+
betaApisResult?: {
|
|
301
|
+
attempted: boolean;
|
|
302
|
+
changed: boolean;
|
|
303
|
+
backupPath?: string | undefined;
|
|
304
|
+
error?: string | undefined;
|
|
305
|
+
} | undefined;
|
|
306
|
+
fixedPermissions?: Array<{
|
|
307
|
+
packName: string;
|
|
308
|
+
moduleName: string;
|
|
309
|
+
}> | undefined;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* 自愈世界资源包/行为包接线问题:
|
|
313
|
+
* 1. 清理清单中已不存在于磁盘的幽灵包 UUID 条目
|
|
314
|
+
* 2. 自动校准清单中与磁盘 manifest 不一致的版本号
|
|
315
|
+
* 3. 自动补齐缺失的 Script API 原生模块权限(config/default/permissions.json)
|
|
316
|
+
* 4. 可选:自动为 level.dat 开启 Beta APIs(若 fixBetaApis 为 true)
|
|
317
|
+
*/
|
|
318
|
+
export declare function repairWorldPacksWiring(bdsRoot: string, levelName: string, opts?: {
|
|
319
|
+
fixBetaApis?: boolean;
|
|
320
|
+
}): Promise<RepairWorldPacksResult>;
|
|
265
321
|
//# sourceMappingURL=world-packs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"world-packs.d.ts","sourceRoot":"","sources":["../src/world-packs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,
|
|
1
|
+
{"version":3,"file":"world-packs.d.ts","sourceRoot":"","sources":["../src/world-packs.ts"],"names":[],"mappings":"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"}
|