import { Rcon } from "rcon-client"; import { MC_SERVER_IP, RCON_PORT, RCON_PASSWORD } from "./constants"; let pooled: Rcon | null = null; let connecting: Promise | null = null; let idleTimer: NodeJS.Timeout | null = null; const IDLE_MS = 30_000; async function open(): Promise { const rcon = await Rcon.connect({ host: MC_SERVER_IP, port: RCON_PORT, password: RCON_PASSWORD, timeout: 5000, }); rcon.on("end", () => { if (pooled === rcon) pooled = null; }); rcon.on("error", () => { if (pooled === rcon) pooled = null; }); return rcon; } function scheduleIdleClose() { if (idleTimer) clearTimeout(idleTimer); idleTimer = setTimeout(() => { const r = pooled; pooled = null; idleTimer = null; r?.end().catch(() => {}); }, IDLE_MS); } async function getConnection(): Promise { if (pooled) return pooled; if (connecting) return connecting; connecting = open() .then((r) => { pooled = r; return r; }) .finally(() => { connecting = null; }); return connecting; } export async function sendCommand(command: string): Promise { try { const rcon = await getConnection(); const response = await rcon.send(command); scheduleIdleClose(); return response; } catch (e) { // Drop the pooled connection on any error, retry once with fresh const bad = pooled; pooled = null; bad?.end().catch(() => {}); const rcon = await getConnection(); const response = await rcon.send(command); scheduleIdleClose(); return response; } }