// Status / players / whitelist sidebar panels. Polled (not streamed) because the // data they show changes infrequently. Logs use SSE -- see console.js. "use strict"; import { api, escapeHtml } from "./api.js"; import { state, rebuildKnownPlayers } from "./state.js"; export async function tickStatus() { const pill = document.getElementById("statusPill"); const text = document.getElementById("statusText"); const memEl = document.getElementById("memUsage"); const memBar = document.getElementById("memBar"); const cpuCur = document.getElementById("cpuCurrent"); const cpuBar = document.getElementById("cpuBar"); const cpuMax = document.getElementById("cpuMax"); const cpuAvg = document.getElementById("cpuAvg"); function renderResources(s) { if (s.memoryBytes != null) { const usedGB = s.memoryBytes / (1024 ** 3); const maxGB = s.memoryMaxMB ? s.memoryMaxMB / 1024 : null; memEl.textContent = maxGB ? `${usedGB.toFixed(2)} / ${maxGB.toFixed(1)} GB` : `${usedGB.toFixed(2)} GB`; memBar.style.width = maxGB ? `${Math.min(100, (usedGB / maxGB) * 100)}%` : "0%"; } else { memEl.textContent = "--"; memBar.style.width = "0%"; } if (s.cpu) { cpuCur.textContent = `${s.cpu.current.toFixed(1)} %`; cpuBar.style.width = `${Math.min(100, s.cpu.current)}%`; cpuMax.textContent = `${s.cpu.max.toFixed(1)}%`; cpuAvg.textContent = `${s.cpu.avg.toFixed(1)}%`; } else { cpuCur.textContent = "--"; cpuBar.style.width = "0%"; cpuMax.textContent = "--"; cpuAvg.textContent = "--"; } } try { const s = await api("/api/status"); if (s.running) { pill.className = "status-pill online"; text.textContent = "Online"; document.getElementById("pid").textContent = s.pid ?? "--"; const secs = Math.floor(s.uptime ?? 0); const h = Math.floor(secs / 3600), m = Math.floor((secs % 3600) / 60); document.getElementById("uptime").textContent = `${h}h ${m}m`; renderResources(s); } else { pill.className = "status-pill offline"; text.textContent = "Offline"; document.getElementById("pid").textContent = "--"; document.getElementById("uptime").textContent = "--"; renderResources({ memoryBytes: null, cpu: null, memoryMaxMB: null }); } const pv = s.packVersion; document.getElementById("packVersion").textContent = pv?.name ? `${pv.name} v${pv.version}` : "--"; // World size -- even when server is offline we can still report disk usage. const worldEl = document.getElementById("worldSize"); if (worldEl) { const b = s.worldSizeBytes; if (b == null || b === 0) worldEl.textContent = "--"; else if (b < 1024 * 1024) worldEl.textContent = `${(b / 1024).toFixed(0)} KB`; else if (b < 1024 * 1024 * 1024) worldEl.textContent = `${(b / (1024 * 1024)).toFixed(1)} MB`; else worldEl.textContent = `${(b / (1024 * 1024 * 1024)).toFixed(2)} GB`; } } catch { pill.className = "status-pill offline"; text.textContent = "Disconnected"; } } export async function tickPlayers() { try { const p = await api("/api/players"); state.onlinePlayers = (p.players || []).slice(); document.getElementById("playerCount").textContent = p.online >= 0 ? p.online : "?"; const list = document.getElementById("players"); if (state.onlinePlayers.length === 0) { list.innerHTML = '
  • No-one online
  • '; } else { list.innerHTML = state.onlinePlayers.map(n => `
  • ${escapeHtml(n)}
  • `).join(""); } } catch {} rebuildKnownPlayers(); } export async function tickWhitelist() { try { const w = await api("/api/whitelist"); state.whitelistedPlayers = (w.players || []).slice(); const list = document.getElementById("whitelist"); if (state.whitelistedPlayers.length === 0) { list.innerHTML = '
  • No players whitelisted yet
  • '; } else { list.innerHTML = state.whitelistedPlayers.map(n => `
  • ${escapeHtml(n)}
  • ` ).join(""); } } catch {} rebuildKnownPlayers(); } // MC takes ~1-2 s to look up a UUID via Mojang and write whitelist.json. // Refresh shortly after a user-triggered add/remove instead of waiting for the // 30-second polling tick. let pendingRefresh; export function refreshWhitelistSoon() { clearTimeout(pendingRefresh); pendingRefresh = setTimeout(tickWhitelist, 1500); setTimeout(tickWhitelist, 4000); // belt-and-braces if Mojang is slow }