@kzheart_/mc-pilot 0.4.0 → 0.4.1
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.
|
@@ -60,6 +60,8 @@ export declare class ClientInstanceManager {
|
|
|
60
60
|
inWorld: boolean;
|
|
61
61
|
position: unknown;
|
|
62
62
|
}>;
|
|
63
|
+
private buildDiagnostics;
|
|
64
|
+
private formatDiagnostics;
|
|
63
65
|
getClient(name?: string): Promise<ClientRuntimeEntry>;
|
|
64
66
|
loadMeta(clientName: string): Promise<ClientInstanceMeta>;
|
|
65
67
|
updateMeta(clientName: string, updates: Partial<ClientInstanceMeta>): Promise<ClientInstanceMeta>;
|
|
@@ -190,6 +190,7 @@ export class ClientInstanceManager {
|
|
|
190
190
|
const requireWorld = options.requireWorld ?? true;
|
|
191
191
|
// 阶段 A:等 WS 连通
|
|
192
192
|
let connected = false;
|
|
193
|
+
let lastConnectError;
|
|
193
194
|
while (Date.now() < deadline) {
|
|
194
195
|
try {
|
|
195
196
|
const ws = new WebSocketClient(wsUrl);
|
|
@@ -197,12 +198,22 @@ export class ClientInstanceManager {
|
|
|
197
198
|
connected = true;
|
|
198
199
|
break;
|
|
199
200
|
}
|
|
200
|
-
catch {
|
|
201
|
+
catch (err) {
|
|
202
|
+
lastConnectError = err instanceof Error ? err.message : String(err);
|
|
201
203
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
202
204
|
}
|
|
203
205
|
}
|
|
204
206
|
if (!connected) {
|
|
205
|
-
|
|
207
|
+
const diag = this.buildDiagnostics(entry.pid, entry.wsPort, {
|
|
208
|
+
wsConnected: false,
|
|
209
|
+
inWorld: false,
|
|
210
|
+
lastError: lastConnectError
|
|
211
|
+
});
|
|
212
|
+
throw new MctError({
|
|
213
|
+
code: "TIMEOUT",
|
|
214
|
+
message: `Timed out after ${timeoutSeconds}s waiting for client ${clientName} (${wsUrl}). ${this.formatDiagnostics(diag)}`,
|
|
215
|
+
details: diag
|
|
216
|
+
}, 2);
|
|
206
217
|
}
|
|
207
218
|
if (!requireWorld) {
|
|
208
219
|
return { connected: true, url: wsUrl };
|
|
@@ -221,16 +232,47 @@ export class ClientInstanceManager {
|
|
|
221
232
|
break;
|
|
222
233
|
}
|
|
223
234
|
}
|
|
224
|
-
catch {
|
|
225
|
-
|
|
235
|
+
catch (err) {
|
|
236
|
+
lastErrorCode = err instanceof Error ? `WS_ERROR(${err.message})` : "WS_ERROR";
|
|
226
237
|
}
|
|
227
238
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
228
239
|
}
|
|
240
|
+
const diag = this.buildDiagnostics(entry.pid, entry.wsPort, {
|
|
241
|
+
wsConnected: true,
|
|
242
|
+
inWorld: false,
|
|
243
|
+
lastError: lastErrorCode
|
|
244
|
+
});
|
|
229
245
|
throw new MctError({
|
|
230
246
|
code: "TIMEOUT",
|
|
231
|
-
message: `
|
|
247
|
+
message: `Timed out after ${timeoutSeconds}s waiting for client ${clientName} to join a world (${wsUrl}). ${this.formatDiagnostics(diag)} Tip: try \`mct client reconnect --address <server>\` or \`mct client launch --force\`.`,
|
|
248
|
+
details: diag
|
|
232
249
|
}, 2);
|
|
233
250
|
}
|
|
251
|
+
buildDiagnostics(pid, wsPort, extras) {
|
|
252
|
+
const processAlive = isProcessRunning(pid);
|
|
253
|
+
const portListening = getListeningPids(wsPort).length > 0;
|
|
254
|
+
return {
|
|
255
|
+
pid,
|
|
256
|
+
processAlive,
|
|
257
|
+
wsPort,
|
|
258
|
+
portListening,
|
|
259
|
+
wsConnected: extras.wsConnected,
|
|
260
|
+
inWorld: extras.inWorld,
|
|
261
|
+
lastError: extras.lastError
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
formatDiagnostics(diag) {
|
|
265
|
+
const parts = [
|
|
266
|
+
`processAlive=${diag.processAlive}`,
|
|
267
|
+
`portListening=${diag.portListening}`,
|
|
268
|
+
`wsConnected=${diag.wsConnected}`,
|
|
269
|
+
`inWorld=${diag.inWorld}`
|
|
270
|
+
];
|
|
271
|
+
if (diag.lastError) {
|
|
272
|
+
parts.push(`lastError=${diag.lastError}`);
|
|
273
|
+
}
|
|
274
|
+
return `Diagnostics: ${parts.join(", ")}.`;
|
|
275
|
+
}
|
|
234
276
|
async getClient(name) {
|
|
235
277
|
const state = await this.globalState.readClientState();
|
|
236
278
|
const resolvedName = name ?? state.defaultClient;
|