import { NextRequest, NextResponse } from "next/server"; import { existsSync } from "fs"; import { join } from "path"; import { execSync, exec } from "child_process"; import { auth } from "@/lib/auth"; import { waitForServer } from "@/lib/mods"; export const dynamic = "force-dynamic"; const BACKUP_DIR = "/home/minecraft/server/backups"; const WORLD_DIR = "/home/minecraft/server/world"; const SERVER_DIR = "/home/minecraft/server"; export async function POST(req: NextRequest) { const session = await auth(); if (!session) { return NextResponse.json({ error: "Unauthorized" }, { status: 403 }); } const { name } = await req.json(); if (!name || !name.endsWith(".tar.gz") || name.includes("/") || name.includes("..")) { return NextResponse.json({ error: "Invalid name" }, { status: 400 }); } const filePath = join(BACKUP_DIR, name); if (!existsSync(filePath)) { return NextResponse.json({ error: "Backup not found" }, { status: 404 }); } try { // Stop server execSync("sudo systemctl stop minecraft.service", { timeout: 30000 }); // Wait for it to stop await new Promise((r) => setTimeout(r, 5000)); // Remove current world execSync(`rm -rf ${WORLD_DIR}`); // Extract backup execSync(`tar xzf ${filePath} -C ${SERVER_DIR}`); // Start server await new Promise((resolve, reject) => { exec("sudo systemctl start minecraft.service", (err) => { if (err) reject(err); else resolve(); }); }); const online = await waitForServer(90000); return NextResponse.json({ success: true, online, message: online ? `World restored from "${name}". Server is online.` : `World restored from "${name}". Server is starting...`, }); } catch (e) { return NextResponse.json( { success: false, message: (e as Error).message }, { status: 500 } ); } }