@sfmc-bds/cli 0.1.0 → 0.2.0-beta.0
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/README.md +7 -1
- package/dist/cli-result.d.ts +12 -0
- package/dist/cli-result.d.ts.map +1 -0
- package/dist/cli-result.js +15 -0
- package/dist/cli-result.js.map +7 -0
- package/dist/commands-behavior-pack.d.ts +11 -42
- package/dist/commands-behavior-pack.d.ts.map +1 -1
- package/dist/commands-behavior-pack.js +40 -159
- package/dist/commands-behavior-pack.js.map +7 -1
- package/dist/commands-reload.d.ts +9 -0
- package/dist/commands-reload.d.ts.map +1 -0
- package/dist/commands-reload.js +30 -0
- package/dist/commands-reload.js.map +7 -0
- package/dist/commands.d.ts +7 -0
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +182 -172
- package/dist/commands.js.map +7 -1
- package/dist/i18n/index.d.ts +26 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +107 -0
- package/dist/i18n/index.js.map +7 -0
- package/dist/i18n/locales/en.d.ts +381 -0
- package/dist/i18n/locales/en.d.ts.map +1 -0
- package/dist/i18n/locales/en.js +393 -0
- package/dist/i18n/locales/en.js.map +7 -0
- package/dist/i18n/locales/zh-CN.d.ts +4 -0
- package/dist/i18n/locales/zh-CN.d.ts.map +1 -0
- package/dist/i18n/locales/zh-CN.js +379 -0
- package/dist/i18n/locales/zh-CN.js.map +7 -0
- package/dist/i18n/types.d.ts +7 -0
- package/dist/i18n/types.d.ts.map +1 -0
- package/dist/i18n/types.js +17 -0
- package/dist/i18n/types.js.map +7 -0
- package/dist/index.d.ts +5 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +51 -43
- package/dist/index.js.map +7 -1
- package/dist/interactive-prompts.d.ts +8 -0
- package/dist/interactive-prompts.d.ts.map +1 -0
- package/dist/interactive-prompts.js +57 -0
- package/dist/interactive-prompts.js.map +7 -0
- package/dist/locale-command.d.ts +3 -0
- package/dist/locale-command.d.ts.map +1 -0
- package/dist/locale-command.js +19 -0
- package/dist/locale-command.js.map +7 -0
- package/dist/logs.d.ts +22 -4
- package/dist/logs.d.ts.map +1 -1
- package/dist/logs.js +208 -193
- package/dist/logs.js.map +7 -1
- package/dist/main.js +135 -173
- package/dist/main.js.map +7 -1
- package/dist/module-commands.d.ts +43 -4
- package/dist/module-commands.d.ts.map +1 -1
- package/dist/module-commands.js +440 -327
- package/dist/module-commands.js.map +7 -1
- package/dist/module-fingerprint.d.ts +7 -0
- package/dist/module-fingerprint.d.ts.map +1 -0
- package/dist/module-fingerprint.js +31 -0
- package/dist/module-fingerprint.js.map +7 -0
- package/dist/module-wizard.d.ts +14 -0
- package/dist/module-wizard.d.ts.map +1 -0
- package/dist/module-wizard.js +313 -0
- package/dist/module-wizard.js.map +7 -0
- package/dist/pack-lifecycle.d.ts +95 -0
- package/dist/pack-lifecycle.d.ts.map +1 -0
- package/dist/pack-lifecycle.js +634 -0
- package/dist/pack-lifecycle.js.map +7 -0
- package/dist/pack-update/bindings.d.ts +12 -0
- package/dist/pack-update/bindings.d.ts.map +1 -0
- package/dist/pack-update/bindings.js +64 -0
- package/dist/pack-update/bindings.js.map +7 -0
- package/dist/pack-update/config.d.ts +22 -0
- package/dist/pack-update/config.d.ts.map +1 -0
- package/dist/pack-update/config.js +141 -0
- package/dist/pack-update/config.js.map +7 -0
- package/dist/pack-update/providers/curseforge.d.ts +23 -0
- package/dist/pack-update/providers/curseforge.d.ts.map +1 -0
- package/dist/pack-update/providers/curseforge.js +209 -0
- package/dist/pack-update/providers/curseforge.js.map +7 -0
- package/dist/pack-update/providers/index.d.ts +16 -0
- package/dist/pack-update/providers/index.d.ts.map +1 -0
- package/dist/pack-update/providers/index.js +37 -0
- package/dist/pack-update/providers/index.js.map +7 -0
- package/dist/pack-update/service.d.ts +21 -0
- package/dist/pack-update/service.d.ts.map +1 -0
- package/dist/pack-update/service.js +567 -0
- package/dist/pack-update/service.js.map +7 -0
- package/dist/pack-update/types.d.ts +126 -0
- package/dist/pack-update/types.d.ts.map +1 -0
- package/dist/pack-update/types.js +8 -0
- package/dist/pack-update/types.js.map +7 -0
- package/dist/pack-update/version-policy.d.ts +80 -0
- package/dist/pack-update/version-policy.d.ts.map +1 -0
- package/dist/pack-update/version-policy.js +216 -0
- package/dist/pack-update/version-policy.js.map +7 -0
- package/dist/registry.d.ts +12 -4
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +73 -106
- package/dist/registry.js.map +7 -1
- package/dist/remote-agent.d.ts.map +1 -1
- package/dist/remote-agent.js +160 -176
- package/dist/remote-agent.js.map +7 -1
- package/dist/repl.d.ts +4 -0
- package/dist/repl.d.ts.map +1 -1
- package/dist/repl.js +683 -605
- package/dist/repl.js.map +7 -1
- package/dist/runtime.d.ts +40 -14
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +185 -62
- package/dist/runtime.js.map +7 -1
- package/dist/services.d.ts +2 -0
- package/dist/services.d.ts.map +1 -1
- package/dist/services.js +251 -238
- package/dist/services.js.map +7 -1
- package/dist/sfmc-modules-root.d.ts +24 -0
- package/dist/sfmc-modules-root.d.ts.map +1 -0
- package/dist/sfmc-modules-root.js +70 -0
- package/dist/sfmc-modules-root.js.map +7 -0
- package/dist/theme.d.ts +4 -0
- package/dist/theme.d.ts.map +1 -1
- package/dist/theme.js +134 -48
- package/dist/theme.js.map +7 -1
- package/dist/wizard.d.ts.map +1 -1
- package/dist/wizard.js +363 -438
- package/dist/wizard.js.map +7 -1
- package/dist/world-packs.d.ts +22 -0
- package/dist/world-packs.d.ts.map +1 -0
- package/dist/world-packs.js +872 -0
- package/dist/world-packs.js.map +7 -0
- package/package.json +10 -10
- package/dist/dispatcher.d.ts +0 -13
- package/dist/dispatcher.d.ts.map +0 -1
- package/dist/dispatcher.js +0 -23
- package/dist/dispatcher.js.map +0 -1
- package/dist/terminal.d.ts +0 -3
- package/dist/terminal.d.ts.map +0 -1
- package/dist/terminal.js +0 -178
- package/dist/terminal.js.map +0 -1
package/dist/services.js
CHANGED
|
@@ -1,259 +1,272 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ensureCoreConfigs,
|
|
3
|
+
loadEnsuredConfig,
|
|
4
|
+
DEFAULT_BDS_UPDATER_CONFIG,
|
|
5
|
+
DEFAULT_DB_CONFIG,
|
|
6
|
+
DEFAULT_QQ_CONFIG
|
|
7
|
+
} from "@sfmc-bds/sdk/node/config";
|
|
2
8
|
import { spawn } from "node:child_process";
|
|
3
9
|
import { EventEmitter } from "node:events";
|
|
4
10
|
import fs from "node:fs";
|
|
5
11
|
import path from "node:path";
|
|
6
12
|
import { inferLevel, pushLog as pushUnifiedLog } from "./logs.js";
|
|
7
13
|
import { ROOT, spawnService } from "./runtime.js";
|
|
8
|
-
|
|
9
|
-
|
|
14
|
+
import { ensurePackUpdateConfigFile } from "./pack-update/config.js";
|
|
15
|
+
import { ROOT as ROOT2 } from "./runtime.js";
|
|
16
|
+
const SERVICE_NAMES = ["bds", "db", "qq", "llbot"];
|
|
10
17
|
class Service {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
name;
|
|
19
|
+
title;
|
|
20
|
+
proc = null;
|
|
21
|
+
running = false;
|
|
22
|
+
pid = 0;
|
|
23
|
+
startTime = null;
|
|
24
|
+
logs = [];
|
|
25
|
+
events = new EventEmitter();
|
|
26
|
+
def;
|
|
27
|
+
manualStop = false;
|
|
28
|
+
constructor(def) {
|
|
29
|
+
this.name = def.name;
|
|
30
|
+
this.title = def.title;
|
|
31
|
+
this.def = def;
|
|
32
|
+
}
|
|
33
|
+
get uptime() {
|
|
34
|
+
if (!this.startTime || !this.running) return "\u2014";
|
|
35
|
+
const ms = Date.now() - this.startTime.getTime();
|
|
36
|
+
const m = Math.floor(ms / 6e4);
|
|
37
|
+
const h = Math.floor(m / 60);
|
|
38
|
+
if (h > 0) return `${h}h ${m % 60}m`;
|
|
39
|
+
if (m > 0) return `${m}m`;
|
|
40
|
+
return `${Math.floor(ms / 1e3)}s`;
|
|
41
|
+
}
|
|
42
|
+
pushLog(text, stream) {
|
|
43
|
+
const line = { time: /* @__PURE__ */ new Date(), text, stream };
|
|
44
|
+
this.logs.push(line);
|
|
45
|
+
if (this.logs.length > 2e3) this.logs.splice(0, this.logs.length - 2e3);
|
|
46
|
+
this.events.emit("log", line);
|
|
47
|
+
const level = stream === "stderr" ? "error" : inferLevel(text);
|
|
48
|
+
pushUnifiedLog(text, this.name, level);
|
|
49
|
+
}
|
|
50
|
+
async start() {
|
|
51
|
+
if (this.running) return;
|
|
52
|
+
if (this.def.validate) {
|
|
53
|
+
const v = this.def.validate();
|
|
54
|
+
if (v) throw new Error(v);
|
|
25
55
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return "—";
|
|
29
|
-
const ms = Date.now() - this.startTime.getTime();
|
|
30
|
-
const m = Math.floor(ms / 60000);
|
|
31
|
-
const h = Math.floor(m / 60);
|
|
32
|
-
if (h > 0)
|
|
33
|
-
return `${h}h ${m % 60}m`;
|
|
34
|
-
if (m > 0)
|
|
35
|
-
return `${m}m`;
|
|
36
|
-
return `${Math.floor(ms / 1000)}s`;
|
|
56
|
+
if (this.def.beforeStart) {
|
|
57
|
+
await this.def.beforeStart();
|
|
37
58
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
this.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
for (const line of d.toString().split("\n").filter(Boolean)) {
|
|
83
|
-
this.pushLog(line, "stderr");
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
child.on("exit", (code) => {
|
|
87
|
-
this.events.emit("output", `exited (code: ${code})`, "info");
|
|
88
|
-
this.cleanup();
|
|
89
|
-
if (!this.manualStop && this.def.autoRestart) {
|
|
90
|
-
setTimeout(() => {
|
|
91
|
-
void this.start();
|
|
92
|
-
}, this.def.restartDelay);
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
async stop() {
|
|
97
|
-
if (!this.proc || !this.running)
|
|
98
|
-
return;
|
|
99
|
-
this.manualStop = true;
|
|
100
|
-
this.events.emit("output", "stopping...", "info");
|
|
101
|
-
if (this.def.stopCommand && this.proc.stdin) {
|
|
102
|
-
this.proc.stdin.write(this.def.stopCommand + "\n");
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
this.proc.kill("SIGTERM");
|
|
106
|
-
}
|
|
107
|
-
return new Promise((resolve) => {
|
|
108
|
-
const timeout = setTimeout(() => {
|
|
109
|
-
if (this.proc) {
|
|
110
|
-
this.events.emit("output", "force kill", "error");
|
|
111
|
-
try {
|
|
112
|
-
this.proc.kill("SIGKILL");
|
|
113
|
-
}
|
|
114
|
-
catch {
|
|
115
|
-
/* ignore */
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
resolve();
|
|
119
|
-
}, this.def.stopTimeout);
|
|
120
|
-
this.proc?.on("exit", () => {
|
|
121
|
-
clearTimeout(timeout);
|
|
122
|
-
resolve();
|
|
123
|
-
});
|
|
124
|
-
});
|
|
59
|
+
this.manualStop = false;
|
|
60
|
+
const spawnOpts = {
|
|
61
|
+
cwd: this.def.cwd,
|
|
62
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
63
|
+
env: this.def.env ? { ...process.env, ...this.def.env } : process.env
|
|
64
|
+
};
|
|
65
|
+
const child = this.def.service ? spawnService(this.def.service, this.def.args ?? [], spawnOpts) : spawn(this.def.cmd, this.def.args ?? [], spawnOpts);
|
|
66
|
+
this.proc = child;
|
|
67
|
+
this.pid = child.pid ?? 0;
|
|
68
|
+
this.running = true;
|
|
69
|
+
this.startTime = /* @__PURE__ */ new Date();
|
|
70
|
+
this.events.emit("output", `started (PID ${this.pid})`, "info");
|
|
71
|
+
child.on("error", (e) => {
|
|
72
|
+
this.events.emit("output", `process error: ${e.message}`, "error");
|
|
73
|
+
this.cleanup();
|
|
74
|
+
});
|
|
75
|
+
child.stdout?.on("data", (d) => {
|
|
76
|
+
for (const line of d.toString().split("\n").filter(Boolean)) {
|
|
77
|
+
this.pushLog(line, "stdout");
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
child.stderr?.on("data", (d) => {
|
|
81
|
+
for (const line of d.toString().split("\n").filter(Boolean)) {
|
|
82
|
+
this.pushLog(line, "stderr");
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
child.on("exit", (code) => {
|
|
86
|
+
this.events.emit("output", `exited (code: ${code})`, "info");
|
|
87
|
+
this.cleanup();
|
|
88
|
+
if (!this.manualStop && this.def.autoRestart) {
|
|
89
|
+
setTimeout(() => {
|
|
90
|
+
void this.start();
|
|
91
|
+
}, this.def.restartDelay);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
async stop() {
|
|
96
|
+
if (!this.proc || !this.running) return;
|
|
97
|
+
this.manualStop = true;
|
|
98
|
+
this.events.emit("output", "stopping...", "info");
|
|
99
|
+
if (this.def.stopCommand && this.proc.stdin) {
|
|
100
|
+
this.proc.stdin.write(this.def.stopCommand + "\n");
|
|
101
|
+
} else {
|
|
102
|
+
this.proc.kill("SIGTERM");
|
|
125
103
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
this.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
104
|
+
return new Promise((resolve) => {
|
|
105
|
+
const timeout = setTimeout(() => {
|
|
106
|
+
if (this.proc) {
|
|
107
|
+
this.events.emit("output", "force kill", "error");
|
|
108
|
+
try {
|
|
109
|
+
this.proc.kill("SIGKILL");
|
|
110
|
+
} catch {
|
|
111
|
+
}
|
|
134
112
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
cleanup()
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
113
|
+
resolve();
|
|
114
|
+
}, this.def.stopTimeout);
|
|
115
|
+
this.proc?.on("exit", () => {
|
|
116
|
+
clearTimeout(timeout);
|
|
117
|
+
resolve();
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
forceStop() {
|
|
122
|
+
const child = this.proc;
|
|
123
|
+
this.manualStop = true;
|
|
124
|
+
this.cleanup();
|
|
125
|
+
if (!child) return;
|
|
126
|
+
try {
|
|
127
|
+
child.kill("SIGKILL");
|
|
128
|
+
} catch {
|
|
150
129
|
}
|
|
130
|
+
}
|
|
131
|
+
async restart() {
|
|
132
|
+
await this.stop();
|
|
133
|
+
await this.start();
|
|
134
|
+
}
|
|
135
|
+
getRecentLogs(n) {
|
|
136
|
+
return this.logs.slice(-n);
|
|
137
|
+
}
|
|
138
|
+
cleanup() {
|
|
139
|
+
this.proc = null;
|
|
140
|
+
this.running = false;
|
|
141
|
+
this.pid = 0;
|
|
142
|
+
}
|
|
151
143
|
}
|
|
152
144
|
function createServices() {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
145
|
+
ensureCoreConfigs(ROOT, ["bds_updater", "qq_config", "db_config"]);
|
|
146
|
+
ensurePackUpdateConfigFile();
|
|
147
|
+
const bdsCfg = loadEnsuredConfig(
|
|
148
|
+
ROOT,
|
|
149
|
+
"bds_updater.json",
|
|
150
|
+
"bds_updater",
|
|
151
|
+
{ ...DEFAULT_BDS_UPDATER_CONFIG }
|
|
152
|
+
);
|
|
153
|
+
const qqCfg = loadEnsuredConfig(
|
|
154
|
+
ROOT,
|
|
155
|
+
"qq_config.json",
|
|
156
|
+
"qq_config",
|
|
157
|
+
{ ...DEFAULT_QQ_CONFIG }
|
|
158
|
+
);
|
|
159
|
+
const dbCfg = loadEnsuredConfig(
|
|
160
|
+
ROOT,
|
|
161
|
+
"db_config.json",
|
|
162
|
+
"db_config",
|
|
163
|
+
{ ...DEFAULT_DB_CONFIG }
|
|
164
|
+
);
|
|
165
|
+
const bdsPath = bdsCfg.bds_path ?? ROOT;
|
|
166
|
+
const llbotEnabled = qqCfg.llbot_enabled !== false;
|
|
167
|
+
const llbotPath = qqCfg.llbot_path ?? "D:\\LLBot-CLI-win-x64\\llbot.exe";
|
|
168
|
+
const llbotCwd = qqCfg.llbot_cwd ?? "D:\\LLBot-CLI-win-x64";
|
|
169
|
+
const dbPort = dbCfg.db_port ?? 3001;
|
|
170
|
+
const bdsExe = path.resolve(bdsPath, "bedrock_server.exe");
|
|
171
|
+
return {
|
|
172
|
+
bds: new Service({
|
|
173
|
+
name: "bds",
|
|
174
|
+
title: "BDS",
|
|
175
|
+
cmd: bdsExe,
|
|
176
|
+
args: [],
|
|
177
|
+
cwd: bdsPath,
|
|
178
|
+
stopCommand: "stop",
|
|
179
|
+
stopTimeout: 3e4,
|
|
180
|
+
autoRestart: bdsCfg.crash_restart !== false,
|
|
181
|
+
restartDelay: 5e3,
|
|
182
|
+
validate: () => {
|
|
183
|
+
if (!fs.existsSync(bdsExe)) return `not found: ${bdsExe}`;
|
|
184
|
+
return null;
|
|
185
|
+
},
|
|
186
|
+
beforeStart: async () => {
|
|
187
|
+
const { scanAndInstallInbox } = await import("./world-packs.js");
|
|
188
|
+
await scanAndInstallInbox({ interactive: false });
|
|
189
|
+
const { runPackUpdatesOnBdsStart } = await import("./pack-update/service.js");
|
|
190
|
+
await runPackUpdatesOnBdsStart();
|
|
191
|
+
const { ensurePacksReady } = await import("./pack-lifecycle.js");
|
|
192
|
+
await ensurePacksReady();
|
|
193
|
+
}
|
|
194
|
+
}),
|
|
195
|
+
db: new Service({
|
|
196
|
+
name: "db",
|
|
197
|
+
title: "DB Server",
|
|
198
|
+
service: "db",
|
|
199
|
+
cwd: ROOT,
|
|
200
|
+
stopTimeout: 1e4,
|
|
201
|
+
autoRestart: true,
|
|
202
|
+
restartDelay: 3e3,
|
|
203
|
+
env: { DB_PORT: String(dbPort) }
|
|
204
|
+
}),
|
|
205
|
+
qq: new Service({
|
|
206
|
+
name: "qq",
|
|
207
|
+
title: "QQ Bridge",
|
|
208
|
+
service: "qq",
|
|
209
|
+
cwd: ROOT,
|
|
210
|
+
stopTimeout: 1e4,
|
|
211
|
+
autoRestart: true,
|
|
212
|
+
restartDelay: 3e3
|
|
213
|
+
}),
|
|
214
|
+
llbot: new Service({
|
|
215
|
+
name: "llbot",
|
|
216
|
+
title: "LLBot",
|
|
217
|
+
cmd: llbotPath,
|
|
218
|
+
args: [],
|
|
219
|
+
cwd: llbotCwd,
|
|
220
|
+
stopTimeout: 1e4,
|
|
221
|
+
autoRestart: false,
|
|
222
|
+
restartDelay: 5e3,
|
|
223
|
+
validate: () => {
|
|
224
|
+
if (!llbotEnabled) return "LLBot disabled (llbot_enabled=false)";
|
|
225
|
+
if (!fs.existsSync(llbotPath)) return `not found: ${llbotPath}`;
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
})
|
|
229
|
+
};
|
|
221
230
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
231
|
+
let services = createServices();
|
|
232
|
+
function refreshServices() {
|
|
233
|
+
forceStopAll();
|
|
234
|
+
services = createServices();
|
|
226
235
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
catch (e) {
|
|
237
|
-
svc.events.emit("output", `start error: ${e.message}`, "error");
|
|
238
|
-
}
|
|
236
|
+
const START_ORDER = ["db", "qq", "llbot", "bds"];
|
|
237
|
+
async function startAll() {
|
|
238
|
+
for (const name of START_ORDER) {
|
|
239
|
+
const svc = services[name];
|
|
240
|
+
if (!svc) continue;
|
|
241
|
+
try {
|
|
242
|
+
await svc.start();
|
|
243
|
+
} catch (e) {
|
|
244
|
+
svc.events.emit("output", `start error: ${e.message}`, "error");
|
|
239
245
|
}
|
|
246
|
+
}
|
|
240
247
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
.map((name) => services[name])
|
|
245
|
-
.filter((service) => Boolean(service?.running))
|
|
246
|
-
.map((service) => service.stop());
|
|
247
|
-
await Promise.allSettled(pending);
|
|
248
|
+
async function stopAll() {
|
|
249
|
+
const pending = [...START_ORDER].reverse().map((name) => services[name]).filter((service) => Boolean(service?.running)).map((service) => service.stop());
|
|
250
|
+
await Promise.allSettled(pending);
|
|
248
251
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
service.forceStop();
|
|
252
|
+
function forceStopAll() {
|
|
253
|
+
for (const service of Object.values(services)) service.forceStop();
|
|
252
254
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
255
|
+
function serviceStatus() {
|
|
256
|
+
return SERVICE_NAMES.map((name) => {
|
|
257
|
+
const service = services[name];
|
|
258
|
+
return { name, title: service.title, running: service.running, pid: service.pid, uptime: service.uptime };
|
|
259
|
+
});
|
|
258
260
|
}
|
|
259
|
-
|
|
261
|
+
export {
|
|
262
|
+
ROOT2 as ROOT,
|
|
263
|
+
SERVICE_NAMES,
|
|
264
|
+
START_ORDER,
|
|
265
|
+
forceStopAll,
|
|
266
|
+
refreshServices,
|
|
267
|
+
serviceStatus,
|
|
268
|
+
services,
|
|
269
|
+
startAll,
|
|
270
|
+
stopAll
|
|
271
|
+
};
|
|
272
|
+
//# sourceMappingURL=services.js.map
|
package/dist/services.js.map
CHANGED
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/services.ts"],
|
|
4
|
+
"sourcesContent": ["import type { BdsUpdaterConfig, DBConfig, QQBridgeConfig } from \"@sfmc-bds/sdk/node/config\";\nimport {\n ensureCoreConfigs,\n loadEnsuredConfig,\n DEFAULT_BDS_UPDATER_CONFIG,\n DEFAULT_DB_CONFIG,\n DEFAULT_QQ_CONFIG,\n} from \"@sfmc-bds/sdk/node/config\";\nimport { spawn, type ChildProcess, type IOType } from \"node:child_process\";\nimport { EventEmitter } from \"node:events\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { inferLevel, pushLog as pushUnifiedLog } from \"./logs.js\";\nimport { ROOT, spawnService, type ServiceId } from \"./runtime.js\";\nimport { ensurePackUpdateConfigFile } from \"./pack-update/config.js\";\n\nexport { ROOT } from \"./runtime.js\";\n\nexport interface LogLine {\n time: Date;\n text: string;\n stream: \"stdout\" | \"stderr\";\n}\n\nexport type ServiceName = \"bds\" | \"db\" | \"qq\" | \"llbot\";\nexport const SERVICE_NAMES: ServiceName[] = [\"bds\", \"db\", \"qq\", \"llbot\"];\n\nexport interface ServiceStatus {\n name: ServiceName;\n title: string;\n running: boolean;\n pid: number;\n uptime: string;\n}\n\ninterface ServiceDef {\n name: ServiceName;\n title: string;\n service?: ServiceId;\n cmd?: string;\n args?: string[];\n cwd: string;\n env?: Record<string, string>;\n stopCommand?: string;\n stopTimeout: number;\n autoRestart: boolean;\n restartDelay: number;\n validate?: () => string | null;\n /** \u542F\u52A8\u524D\u94A9\u5B50(\u5982 BDS \u88C5\u8F7D\u4E00\u81F4\u6027\u6821\u9A8C);\u5931\u8D25\u5219\u7981\u6B62 spawn */\n beforeStart?: () => Promise<void>;\n}\n\nclass Service {\n name: ServiceName;\n title: string;\n proc: ChildProcess | null = null;\n running = false;\n pid = 0;\n startTime: Date | null = null;\n logs: LogLine[] = [];\n events = new EventEmitter();\n\n private def: ServiceDef;\n private manualStop = false;\n\n constructor(def: ServiceDef) {\n this.name = def.name;\n this.title = def.title;\n this.def = def;\n }\n\n get uptime(): string {\n if (!this.startTime || !this.running) return \"\u2014\";\n const ms = Date.now() - this.startTime.getTime();\n const m = Math.floor(ms / 60000);\n const h = Math.floor(m / 60);\n if (h > 0) return `${h}h ${m % 60}m`;\n if (m > 0) return `${m}m`;\n return `${Math.floor(ms / 1000)}s`;\n }\n\n pushLog(text: string, stream: \"stdout\" | \"stderr\"): void {\n const line: LogLine = { time: new Date(), text, stream };\n this.logs.push(line);\n if (this.logs.length > 2000) this.logs.splice(0, this.logs.length - 2000);\n this.events.emit(\"log\", line);\n // stderr \u89C6\u4E3A error; stdout \u7528 inferLevel \u63A8\u65AD (bare \u5B50\u8FDB\u7A0B\u7EAF text \u65F6\u9ED8\u8BA4 info,\n // BDS \u7B49\u81EA\u5E26 [LEVEL] \u6807\u7B7E\u7684\u4ECD\u53EF\u6B63\u786E\u63A8\u65AD)\n const level = stream === \"stderr\" ? \"error\" : inferLevel(text);\n pushUnifiedLog(text, this.name, level);\n }\n\n async start(): Promise<void> {\n if (this.running) return;\n if (this.def.validate) {\n const v = this.def.validate();\n if (v) throw new Error(v);\n }\n if (this.def.beforeStart) {\n await this.def.beforeStart();\n }\n this.manualStop = false;\n const spawnOpts = {\n cwd: this.def.cwd,\n stdio: [\"pipe\", \"pipe\", \"pipe\"] as Array<IOType>,\n env: this.def.env ? { ...process.env, ...this.def.env } : process.env,\n };\n const child = this.def.service\n ? spawnService(this.def.service, this.def.args ?? [], spawnOpts)\n : spawn(this.def.cmd as string, this.def.args ?? [], spawnOpts);\n //child.unref();\n this.proc = child;\n this.pid = child.pid ?? 0;\n this.running = true;\n this.startTime = new Date();\n this.events.emit(\"output\", `started (PID ${this.pid})`, \"info\");\n\n child.on(\"error\", (e) => {\n this.events.emit(\"output\", `process error: ${e.message}`, \"error\");\n this.cleanup();\n });\n\n child.stdout?.on(\"data\", (d: Buffer) => {\n for (const line of d.toString().split(\"\\n\").filter(Boolean)) {\n this.pushLog(line, \"stdout\");\n }\n });\n child.stderr?.on(\"data\", (d: Buffer) => {\n for (const line of d.toString().split(\"\\n\").filter(Boolean)) {\n this.pushLog(line, \"stderr\");\n }\n });\n\n child.on(\"exit\", (code) => {\n this.events.emit(\"output\", `exited (code: ${code})`, \"info\");\n this.cleanup();\n if (!this.manualStop && this.def.autoRestart) {\n setTimeout(() => {\n void this.start();\n }, this.def.restartDelay);\n }\n });\n }\n\n async stop(): Promise<void> {\n if (!this.proc || !this.running) return;\n this.manualStop = true;\n this.events.emit(\"output\", \"stopping...\", \"info\");\n\n if (this.def.stopCommand && this.proc.stdin) {\n this.proc.stdin.write(this.def.stopCommand + \"\\n\");\n } else {\n this.proc.kill(\"SIGTERM\");\n }\n\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n if (this.proc) {\n this.events.emit(\"output\", \"force kill\", \"error\");\n try {\n this.proc.kill(\"SIGKILL\");\n } catch {\n /* ignore */\n }\n }\n resolve();\n }, this.def.stopTimeout);\n\n this.proc?.on(\"exit\", () => {\n clearTimeout(timeout);\n resolve();\n });\n });\n }\n\n forceStop(): void {\n const child = this.proc;\n this.manualStop = true;\n this.cleanup();\n if (!child) return;\n try {\n child.kill(\"SIGKILL\");\n } catch {\n /* ignore */\n }\n }\n\n async restart(): Promise<void> {\n await this.stop();\n await this.start();\n }\n\n getRecentLogs(n: number): LogLine[] {\n return this.logs.slice(-n);\n }\n\n private cleanup(): void {\n this.proc = null;\n this.running = false;\n this.pid = 0;\n }\n}\n\nfunction createServices(): Record<ServiceName, Service> {\n /* \u5404\u670D\u52A1/CLI \u7528 SDK ensureCoreConfigs \u64AD\u79CD\uFF08\u542B $schema\uFF09\uFF0C\u4E0D\u518D\u4ECE configs-default \u62F7\u8D1D\u3002 */\n ensureCoreConfigs(ROOT, [\"bds_updater\", \"qq_config\", \"db_config\"]);\n ensurePackUpdateConfigFile();\n const bdsCfg = loadEnsuredConfig(\n ROOT,\n \"bds_updater.json\",\n \"bds_updater\",\n { ...DEFAULT_BDS_UPDATER_CONFIG } as Record<string, unknown>\n ) as BdsUpdaterConfig;\n const qqCfg = loadEnsuredConfig(\n ROOT,\n \"qq_config.json\",\n \"qq_config\",\n { ...DEFAULT_QQ_CONFIG } as Record<string, unknown>\n ) as QQBridgeConfig;\n const dbCfg = loadEnsuredConfig(\n ROOT,\n \"db_config.json\",\n \"db_config\",\n { ...DEFAULT_DB_CONFIG } as Record<string, unknown>\n ) as DBConfig;\n const bdsPath = bdsCfg.bds_path ?? ROOT;\n const llbotEnabled = qqCfg.llbot_enabled !== false;\n const llbotPath = qqCfg.llbot_path ?? \"D:\\\\LLBot-CLI-win-x64\\\\llbot.exe\";\n const llbotCwd = qqCfg.llbot_cwd ?? \"D:\\\\LLBot-CLI-win-x64\";\n const dbPort = dbCfg.db_port ?? 3001;\n const bdsExe = path.resolve(bdsPath, \"bedrock_server.exe\");\n\n return {\n bds: new Service({\n name: \"bds\",\n title: \"BDS\",\n cmd: bdsExe,\n args: [],\n cwd: bdsPath,\n stopCommand: \"stop\",\n stopTimeout: 30000,\n autoRestart: bdsCfg.crash_restart !== false,\n restartDelay: 5000,\n validate: () => {\n if (!fs.existsSync(bdsExe)) return `not found: ${bdsExe}`;\n return null;\n },\n beforeStart: async () => {\n /* \u5148\u88C5\u6536\u4EF6\u7BB1\u7B2C\u4E09\u65B9\u5305\uFF0C\u518D\u68C0\u67E5 CF \u66F4\u65B0\uFF0C\u518D\u8DD1\u6A21\u5757\u805A\u5408\u95F8\u95E8 */\n const { scanAndInstallInbox } = await import(\"./world-packs.js\");\n await scanAndInstallInbox({ interactive: false });\n const { runPackUpdatesOnBdsStart } = await import(\"./pack-update/service.js\");\n await runPackUpdatesOnBdsStart();\n const { ensurePacksReady } = await import(\"./pack-lifecycle.js\");\n await ensurePacksReady();\n },\n }),\n\n db: new Service({\n name: \"db\",\n title: \"DB Server\",\n service: \"db\",\n cwd: ROOT,\n stopTimeout: 10000,\n autoRestart: true,\n restartDelay: 3000,\n env: { DB_PORT: String(dbPort) },\n }),\n\n qq: new Service({\n name: \"qq\",\n title: \"QQ Bridge\",\n service: \"qq\",\n cwd: ROOT,\n stopTimeout: 10000,\n autoRestart: true,\n restartDelay: 3000,\n }),\n\n llbot: new Service({\n name: \"llbot\",\n title: \"LLBot\",\n cmd: llbotPath,\n args: [],\n cwd: llbotCwd,\n stopTimeout: 10000,\n autoRestart: false,\n restartDelay: 5000,\n validate: () => {\n if (!llbotEnabled) return \"LLBot disabled (llbot_enabled=false)\";\n if (!fs.existsSync(llbotPath)) return `not found: ${llbotPath}`;\n return null;\n },\n }),\n };\n}\n\nexport let services: Record<ServiceName, Service> = createServices();\n\nexport function refreshServices(): void {\n forceStopAll();\n services = createServices();\n}\n\nexport const START_ORDER: ServiceName[] = [\"db\", \"qq\", \"llbot\", \"bds\"];\n\nexport async function startAll(): Promise<void> {\n for (const name of START_ORDER) {\n const svc = services[name];\n if (!svc) continue;\n try {\n await svc.start();\n } catch (e) {\n svc.events.emit(\"output\", `start error: ${(e as Error).message}`, \"error\");\n }\n }\n}\n\nexport async function stopAll(): Promise<void> {\n const pending = [...START_ORDER]\n .reverse()\n .map((name) => services[name])\n .filter((service): service is Service => Boolean(service?.running))\n .map((service) => service.stop());\n await Promise.allSettled(pending);\n}\n\nexport function forceStopAll(): void {\n for (const service of Object.values(services)) service.forceStop();\n}\n\nexport function serviceStatus(): ServiceStatus[] {\n return SERVICE_NAMES.map((name) => {\n const service = services[name];\n return { name, title: service.title, running: service.running, pid: service.pid, uptime: service.uptime };\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["ROOT"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface SfmcModulePackage {
|
|
2
|
+
/** packages/ 下的文件夹名(install id) */
|
|
3
|
+
id: string;
|
|
4
|
+
/** 绝对路径 */
|
|
5
|
+
path: string;
|
|
6
|
+
/** manifest 中的逻辑 id,缺省为 feature-<folder> */
|
|
7
|
+
logicalId: string;
|
|
8
|
+
name: string;
|
|
9
|
+
}
|
|
10
|
+
/** 自动探测旁路 sfmc-modules(不要求根目录有 package.json)。 */
|
|
11
|
+
export declare function detectSiblingSfmcModulesRoot(): string | null;
|
|
12
|
+
/** 从 runtime.json 读取曾保存的 sfmc-modules 根。 */
|
|
13
|
+
export declare function readPersistedSfmcModulesRoot(rootDir?: string): string | null;
|
|
14
|
+
/** 写入 runtime.json,下次免输路径。 */
|
|
15
|
+
export declare function persistSfmcModulesRoot(modulesRoot: string, rootDir?: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* 解析 sfmc-modules 根目录。
|
|
18
|
+
* 优先级:SFMC_MODULES_ROOT 环境变量 → runtime.json → 旁路 ../sfmc-modules
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveSfmcModulesRoot(rootDir?: string): string | null;
|
|
21
|
+
/** 枚举 sfmc-modules/packages 下可安装的模块包。 */
|
|
22
|
+
export declare function listSfmcModulePackages(modulesRoot: string): SfmcModulePackage[];
|
|
23
|
+
export declare function packageDirForId(modulesRoot: string, folderId: string): string;
|
|
24
|
+
//# sourceMappingURL=sfmc-modules-root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sfmc-modules-root.d.ts","sourceRoot":"","sources":["../src/sfmc-modules-root.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,iBAAiB;IAChC,mCAAmC;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW;IACX,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAOD,iDAAiD;AACjD,wBAAgB,4BAA4B,IAAI,MAAM,GAAG,IAAI,CAG5D;AAED,4CAA4C;AAC5C,wBAAgB,4BAA4B,CAAC,OAAO,GAAE,MAAa,GAAG,MAAM,GAAG,IAAI,CAMlF;AAED,8BAA8B;AAC9B,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,MAAa,GAAG,IAAI,CAGxF;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,MAAa,GAAG,MAAM,GAAG,IAAI,CAS5E;AAED,yCAAyC;AACzC,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,iBAAiB,EAAE,CA2B/E;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE7E"}
|