51 lines
1.8 KiB
TypeScript
51 lines
1.8 KiB
TypeScript
import type { RconFailure } from '$ui/stores/servers.js';
|
|
|
|
export interface DecodedRconError {
|
|
reason: RconFailure;
|
|
detail: string;
|
|
}
|
|
|
|
const KNOWN: RconFailure[] = [
|
|
'no-config',
|
|
'no-port',
|
|
'send-error',
|
|
'timeout',
|
|
'bad-reply',
|
|
'no-players'
|
|
];
|
|
|
|
/**
|
|
* Decode the "<reason>:<detail>" string the worker persists into
|
|
* `servers.last_error`. Returns null for empty/legacy strings so the UI can
|
|
* fall back to a generic message.
|
|
*/
|
|
export function decodeRconError(raw: string | null | undefined): DecodedRconError | null {
|
|
if (!raw) return null;
|
|
const idx = raw.indexOf(':');
|
|
if (idx <= 0) return null;
|
|
const reason = raw.slice(0, idx);
|
|
if (!KNOWN.includes(reason as RconFailure)) return null;
|
|
return { reason: reason as RconFailure, detail: raw.slice(idx + 1).trim() };
|
|
}
|
|
|
|
/**
|
|
* Human-facing hint about how to fix each RCON failure. Kept short — the
|
|
* detail already carries the specifics (host, port, byte counts, etc.).
|
|
*/
|
|
export function rconFixHint(reason: RconFailure): string {
|
|
switch (reason) {
|
|
case 'no-config':
|
|
return 'Set RCON_PASSWORD in the container env and restart.';
|
|
case 'no-port':
|
|
return 'Check the host agent and the game port assigned to this server.';
|
|
case 'send-error':
|
|
return 'DNS or route problem — check the RCON host is reachable from this container.';
|
|
case 'timeout':
|
|
return 'Plutonium is not replying on the resolved UDP port. Verify the server is running and the port matches.';
|
|
case 'bad-reply':
|
|
return 'Something is listening but not speaking Plutonium RCON. Check the port and password.';
|
|
case 'no-players':
|
|
return 'Reply parsed but no player table was found — likely a server-side dialect mismatch.';
|
|
}
|
|
}
|