mc-dashboard/app/api/status/route.ts

51 lines
1.4 KiB
TypeScript
Raw Normal View History

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 },
});
}