Spieler Online
Server Steuerung
Zur Whitelist hinzufügen
Whitelist Spieler ({whitelistPlayers.length})
Auto-Shutdown
Server automatisch stoppen wenn keine Spieler online sind
import { useState, useEffect, useRef } from 'react' import { useParams, useNavigate } from 'react-router-dom' import { getServers, serverAction, sendRcon, getServerLogs, getWhitelist, getFactorioCurrentSave, getAutoShutdownSettings, setAutoShutdownSettings } from '../api' import { useUser } from '../context/UserContext' import MetricsChart from '../components/MetricsChart' import FactorioWorldManager from '../components/FactorioWorldManager' const getServerLogo = (serverName) => { const name = serverName.toLowerCase() if (name.includes("minecraft") || name.includes("all the mods")) return "/minecraft.png" if (name.includes("factorio")) return "/factorio.png" if (name.includes("vrising") || name.includes("v rising")) return "/vrising.png" if (name.includes("zomboid")) return "/zomboid.png" return null } export default function ServerDetail() { const { serverId } = useParams() const navigate = useNavigate() const { token, isModerator } = useUser() const [server, setServer] = useState(null) const [loading, setLoading] = useState(true) const [activeTab, setActiveTab] = useState('overview') const [rconCommand, setRconCommand] = useState('') const [rconHistory, setRconHistory] = useState([]) const [logs, setLogs] = useState('') const [whitelistPlayers, setWhitelistPlayers] = useState([]) const [whitelistInput, setWhitelistInput] = useState('') const [whitelistLoading, setWhitelistLoading] = useState(false) const [currentSave, setCurrentSave] = useState(null) const [logsUpdated, setLogsUpdated] = useState(null) const logsRef = useRef(null) const rconRef = useRef(null) // Auto-shutdown state const [autoShutdown, setAutoShutdown] = useState({ enabled: false, timeoutMinutes: 15, emptySinceMinutes: null }) const [autoShutdownLoading, setAutoShutdownLoading] = useState(false) const fetchCurrentSave = async () => { if (token && serverId === 'factorio') { try { const result = await getFactorioCurrentSave(token) setCurrentSave(result) } catch (err) { console.error('Failed to fetch current save:', err) } } } const fetchServer = async () => { try { const servers = await getServers(token) const found = servers.find(s => s.id === serverId) if (found) { setServer(found); document.title = found.name + " | Zeasy GSM" } else { navigate('/') } } catch (err) { console.error(err) navigate('/') } finally { setLoading(false) } } const fetchAutoShutdownSettings = async () => { if (token && serverId) { try { const data = await getAutoShutdownSettings(token, serverId) setAutoShutdown(data) } catch (err) { console.error('Failed to load auto-shutdown settings:', err) } } } const handleAutoShutdownToggle = async () => { setAutoShutdownLoading(true) try { await setAutoShutdownSettings(token, serverId, !autoShutdown.enabled, autoShutdown.timeoutMinutes) setAutoShutdown(prev => ({ ...prev, enabled: !prev.enabled })) } catch (err) { console.error(err) } setAutoShutdownLoading(false) } const handleAutoShutdownTimeoutChange = async (newTimeout) => { const timeout = Math.max(1, Math.min(1440, parseInt(newTimeout) || 15)) setAutoShutdown(prev => ({ ...prev, timeoutMinutes: timeout })) clearTimeout(window.autoShutdownSaveTimeout) window.autoShutdownSaveTimeout = setTimeout(async () => { try { await setAutoShutdownSettings(token, serverId, autoShutdown.enabled, timeout) } catch (err) { console.error(err) } }, 500) } useEffect(() => { fetchServer() fetchCurrentSave() const interval = setInterval(() => { fetchServer() fetchCurrentSave() }, 10000) return () => clearInterval(interval) }, [token, serverId]) useEffect(() => { if (activeTab === 'settings' && isModerator) { fetchAutoShutdownSettings() const interval = setInterval(fetchAutoShutdownSettings, 10000) return () => clearInterval(interval) } }, [activeTab, isModerator, token, serverId]) const handleAction = async (action) => { // Immediately set status locally const newStatus = action === 'start' ? 'starting' : (action === 'stop' ? 'stopping' : 'starting') setServer(prev => ({ ...prev, status: newStatus })) try { await serverAction(token, server.id, action) setTimeout(() => { fetchServer() }, 2000) } catch (err) { console.error(err) } } const handleRcon = async (e) => { e.preventDefault() if (!rconCommand.trim()) return const cmd = rconCommand setRconCommand('') try { const { response } = await sendRcon(token, server.id, cmd) setRconHistory([...rconHistory, { cmd, res: response, time: new Date() }]) } catch (err) { setRconHistory([...rconHistory, { cmd, res: 'Error: ' + err.message, time: new Date(), error: true }]) } } const fetchLogs = async () => { try { const data = await getServerLogs(token, server.id, 50) setLogs(data.logs || '') setLogsUpdated(new Date()) if (logsRef.current) { logsRef.current.scrollTop = logsRef.current.scrollHeight } } catch (err) { console.error(err) } } useEffect(() => { if (activeTab === 'console' && isModerator && server) { fetchLogs() const interval = setInterval(fetchLogs, 5000) return () => clearInterval(interval) } }, [activeTab, isModerator, server]) useEffect(() => { if (activeTab === 'whitelist' && isModerator && server?.type === 'minecraft') { fetchWhitelist() } }, [activeTab, server]) useEffect(() => { if (rconRef.current) { rconRef.current.scrollTop = rconRef.current.scrollHeight } }, [rconHistory]) const fetchWhitelist = async () => { if (!server?.hasRcon) return try { const { players } = await getWhitelist(token, server.id) setWhitelistPlayers(players) } catch (err) { console.error("Failed to fetch whitelist:", err) } } const addToWhitelist = async (e) => { e.preventDefault() if (!whitelistInput.trim()) return setWhitelistLoading(true) try { await sendRcon(token, server.id, 'whitelist add ' + whitelistInput.trim()) setWhitelistInput('') await fetchWhitelist() } catch (err) { console.error('Failed to add to whitelist:', err) } finally { setWhitelistLoading(false) } } const removeFromWhitelist = async (player) => { setWhitelistLoading(true) try { await sendRcon(token, server.id, 'whitelist remove ' + player) await fetchWhitelist() } catch (err) { console.error('Failed to remove from whitelist:', err) } finally { setWhitelistLoading(false) } } const formatUptime = (seconds) => { const days = Math.floor(seconds / 86400) const hours = Math.floor((seconds % 86400) / 3600) const minutes = Math.floor((seconds % 3600) / 60) if (days > 0) return days + 'd ' + hours + 'h ' + minutes + 'm' return hours + 'h ' + minutes + 'm' } const tabs = [ { id: 'overview', label: 'Übersicht' }, { id: 'metrics', label: 'Metriken' }, ...(isModerator ? [ { id: 'console', label: 'Konsole' }, ] : []), ...(isModerator && server?.type === 'minecraft' ? [ { id: 'whitelist', label: 'Whitelist' }, ] : []), ...(isModerator && server?.type === 'factorio' ? [ { id: 'worlds', label: 'Welten' }, ] : []), ...(isModerator ? [ { id: 'settings', label: 'Einstellungen' }, ] : []), ] if (loading) { return (
Laufzeit: {formatUptime(server.metrics.uptime)}
)}Server automatisch stoppen wenn keine Spieler online sind