import { serverLabel } from '../lib/labels.js'; import CopyField from './CopyField.jsx'; const RETRY = { start_failed: 'Server neu starten', failed: 'Server neu starten', stopped: 'Server neu starten', config_failed: 'Konfiguration wiederholen', ready: 'Konfiguration starten', }; const ACTIVE = ['starting', 'ready', 'configuring', 'configured', 'config_failed', 'failed']; /** Zeigt dem Organisator, ob Live-Daten vom Server ankommen und ob die Map vorbei ist. */ function LiveDataStatus({ state, hasNext }) { const current = state.series.find((s) => s.number === state.currentMapNumber); if (!current) return null; const updatedAt = current.live?.updatedAt; if (current.status === 'done') { const auto = state.autoAdvanceSeconds >= 0; return (
Map {current.number} ist beendet.{' '} {auto ? (hasNext ? `Die nächste Map wird nach ${state.autoAdvanceSeconds} s automatisch geladen, sofern die Serie nicht entschieden ist.` : 'Das Match wird automatisch abgeschlossen.') : (hasNext ? 'Lade jetzt die nächste Map.' : 'Das war die letzte Map – schließ das Match ab.')}
); } return (

{updatedAt ? `Live-Daten vom Server empfangen, zuletzt um ${new Date(updatedAt).toLocaleTimeString('de-DE')}.` : 'Noch keine Live-Daten. Sie kommen, sobald die Aufwärmphase endet und der Server diese Webseite erreicht (LOG_RECEIVER_URL).'}

); } export default function ServerPanel({ state, isOrg, act, busy }) { const { server } = state; const label = serverLabel(server); const closed = ['finished', 'cancelled'].includes(state.status); const sim = server?.simulated; const canRetry = server && !closed && RETRY[server.status] && (server.status !== 'ready' || state.status === 'server_setup'); const hasNext = state.series.some((s) => s.number === (state.currentMapNumber ?? 0) + 1); return (

Spielserver

{label.text}
{server?.message &&

{server.message}

} {sim && (
Demo-Adapter aktiv: Es läuft kein echter CS2-Server. Start, Konfiguration und Verbindungsdaten sind simuliert. Wie die echte Anbindung eingerichtet wird, steht in der README.
)} {!server &&

Für dieses Match wurde noch kein Server angefordert.

} {server && ['starting', 'ready'].includes(server.status) && state.status !== 'server_setup' && (

{sim ? 'Der Start wird während des Vetos simuliert.' : 'Der Server fährt während des Vetos hoch.'} Die Verbindungsdaten erscheinen nach dem Veto.

)} {server?.connect && (

{sim ? 'Spieler-Verbindung (Demo-Beispiel, nicht verbindbar)' : 'Verbindung für Spieler'}

{!sim && In CS2 verbinden}

Server {server.connect.host}:{server.connect.port}. Das Passwort ist nur für Spieler dieses Matches sichtbar.

)} {server?.gotv && (

{sim ? 'CSTV/GOTV (Demo-Beispiel, nicht verbindbar)' : 'Zuschauen über CSTV (GOTV)'}

Übertragung mit {server.gotv.delaySeconds} Sekunden Verzögerung gegen Ghosting. Zuschauer belegen keinen Spielerplatz.

)} {state.viewer.isSpectator && !state.viewer.isOrganizer && server?.status === 'configured' && !server.gotv && (

CSTV ist auf diesem Server deaktiviert.

)} {isOrg && server?.status === 'configured' && } {isOrg && server && !closed && (
{canRetry && ( )} {server.status === 'configured' && ( )} {server.status === 'configured' && state.status === 'live' && hasNext && ( )} {ACTIVE.includes(server.status) && ( )}
)} {isOrg && !closed && (
{['live', 'server_setup'].includes(state.status) && ( )}
)} {server && ACTIVE.includes(server.status) && (

Ungenutzte Server werden nach {server.idleTimeoutMinutes} Minuten automatisch heruntergefahren.

)}
); }