import { NextResponse } from "next/server"; import { status } from "minecraft-server-util"; import { execSync } from "child_process"; import { MC_SERVER_IP, MC_SERVER_PORT } from "@/lib/constants"; import { sendCommand } from "@/lib/rcon"; export const dynamic = "force-dynamic"; export async function GET() { // Tier 1: MC protocol ping (fastest, gives player/version info) try { const result = await status(MC_SERVER_IP, MC_SERVER_PORT, { timeout: 5000, }); return NextResponse.json({ online: true, players: { online: result.players.online, max: result.players.max }, version: result.version.name, motd: result.motd.clean, }); } catch {} // Tier 2: RCON (server is online but protocol ping failed) try { const response = await sendCommand("list"); const match = response.match(/There are (\d+) of a max of (\d+) players/); return NextResponse.json({ online: true, players: { online: match ? parseInt(match[1], 10) : 0, max: match ? parseInt(match[2], 10) : 20, }, }); } catch {} // Tier 3: systemctl (process alive but not yet accepting connections) let starting = false; try { const out = execSync("systemctl is-active minecraft.service", { encoding: "utf8", }).trim(); starting = out === "active" || out === "activating"; } catch {} return NextResponse.json({ online: false, starting, players: { online: 0, max: 0 }, }); }