"use client"; import { useEffect, useState, useCallback } from "react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Switch } from "@/components/ui/switch"; import { Skeleton } from "@/components/ui/skeleton"; import { Badge } from "@/components/ui/badge"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Settings, RefreshCw, Download, Server, Map } from "lucide-react"; import { toast } from "sonner"; interface ServerSettings { minecraftPath?: string; serverJar?: string; serverVersion?: string; serverType?: string; maxRam?: number; minRam?: number; rconEnabled?: boolean; rconPort?: number; javaArgs?: string; autoStart?: boolean; restartOnCrash?: boolean; backupEnabled?: boolean; backupSchedule?: string; bluemapEnabled?: boolean; bluemapUrl?: string; } const SERVER_TYPES = ["vanilla", "paper", "spigot", "bukkit", "fabric", "forge", "bedrock"]; export default function ServerPage() { const [settings, setSettings] = useState({}); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [versions, setVersions] = useState([]); const [loadingVersions, setLoadingVersions] = useState(false); const [selectedType, setSelectedType] = useState("paper"); const fetchSettings = useCallback(async () => { try { const res = await fetch("/api/server/settings"); if (res.ok) { const data = await res.json(); if (data.settings) { setSettings(data.settings); setSelectedType(data.settings.serverType ?? "paper"); } } } finally { setLoading(false); } }, []); const fetchVersions = useCallback(async (type: string) => { setLoadingVersions(true); try { const res = await fetch(`/api/server/versions?type=${type}`); if (res.ok) setVersions((await res.json()).versions); } finally { setLoadingVersions(false); } }, []); useEffect(() => { fetchSettings(); }, [fetchSettings]); useEffect(() => { fetchVersions(selectedType); }, [selectedType, fetchVersions]); const save = async (updates: Partial) => { setSaving(true); try { const res = await fetch("/api/server/settings", { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(updates), }); if (!res.ok) throw new Error((await res.json()).error); setSettings((prev) => ({ ...prev, ...updates })); toast.success("Settings saved"); } catch (err) { toast.error(err instanceof Error ? err.message : "Failed to save"); } finally { setSaving(false); } }; if (loading) { return (
{Array.from({ length: 3 }).map((_, i) => ( ))}
); } return (

Server Settings

Configure your Minecraft server and CubeAdmin options

General Performance Updates Integrations {/* General */} Server Configuration
setSettings(p => ({ ...p, minecraftPath: e.target.value }))} placeholder="/opt/minecraft/server" className="bg-zinc-800 border-zinc-700 text-white placeholder:text-zinc-500 font-mono text-sm" />
setSettings(p => ({ ...p, serverJar: e.target.value }))} placeholder="server.jar" className="bg-zinc-800 border-zinc-700 text-white placeholder:text-zinc-500 font-mono text-sm" />

Auto-start on boot

Start server when CubeAdmin starts

save({ autoStart: v })} />

Auto-restart on crash

Automatically restart if server crashes

save({ restartOnCrash: v })} />
{/* Performance */} JVM Settings
setSettings(p => ({ ...p, minRam: parseInt(e.target.value) }))} className="bg-zinc-800 border-zinc-700 text-white" min={256} />
setSettings(p => ({ ...p, maxRam: parseInt(e.target.value) }))} className="bg-zinc-800 border-zinc-700 text-white" min={512} />
setSettings(p => ({ ...p, javaArgs: e.target.value }))} placeholder="-XX:+UseG1GC -XX:MaxGCPauseMillis=200" className="bg-zinc-800 border-zinc-700 text-white placeholder:text-zinc-500 font-mono text-sm" />

Aikar's flags are applied by default with the Docker image.

{/* Updates */} Server Version
⚠️

Changing server version requires a server restart. Always backup first!

{/* Integrations */} BlueMap Integration

Enable BlueMap

Show the 3D map in the Map section

save({ bluemapEnabled: v })} />
{settings.bluemapEnabled && (
setSettings(p => ({ ...p, bluemapUrl: e.target.value }))} placeholder="http://localhost:8100" className="bg-zinc-800 border-zinc-700 text-white placeholder:text-zinc-500 font-mono text-sm" />

The URL where BlueMap is accessible from your browser.

)}
); }