import { status } from "minecraft-server-util"; const MOD_API_URL = process.env.MOD_API_URL || "http://minecraft-server:8080"; // 캐시된 데이터 let cachedStatus = null; let cachedPlayers = []; /** * 모드 API에서 상태 가져오기 */ async function fetchModStatus() { try { const response = await fetch(`${MOD_API_URL}/status`); if (response.ok) return await response.json(); return null; } catch (error) { console.error("[ModAPI] 상태 조회 실패:", error.message); return null; } } /** * MOTD 가져오기 (마인크래프트 프로토콜 사용) */ async function fetchMotd() { try { const result = await status("minecraft-server", 25565, { timeout: 5000 }); return { motd: result.motd?.html || null, icon: result.favicon || null, }; } catch (error) { return { motd: null, icon: null }; } } /** * 클라이언트용 상태 포맷 변환 */ function formatStatusForClient(modStatus, motdData) { if (!modStatus) { return { online: false, motd: null, players: { current: 0, max: 0, list: [] }, version: "Unknown", icon: null, uptime: "오프라인", tps: 0, mspt: 0, memoryUsedMb: 0, memoryMaxMb: 0, }; } const uptimeMinutes = modStatus.uptimeMinutes || 0; const days = Math.floor(uptimeMinutes / 1440); const hours = Math.floor((uptimeMinutes % 1440) / 60); const minutes = uptimeMinutes % 60; let uptime; if (days > 0) uptime = `${days}일 ${hours}시간`; else if (hours > 0) uptime = `${hours}시간 ${minutes}분`; else uptime = `${minutes}분`; return { online: modStatus.online, motd: motdData?.motd || null, icon: motdData?.icon || null, players: { current: modStatus.players?.current || 0, max: modStatus.players?.max || 20, list: modStatus.players?.online?.map((p) => ({ name: p.name, uuid: p.uuid, id: p.uuid, isOp: p.isOp, })) || [], }, version: modStatus.version || "Unknown", modLoader: modStatus.modLoader || null, uptime: modStatus.online ? uptime : "오프라인", difficulty: modStatus.difficulty || "알 수 없음", gameRules: modStatus.gameRules || {}, mods: modStatus.mods || [], tps: modStatus.tps || 0, mspt: modStatus.mspt || 0, memoryUsedMb: modStatus.memoryUsedMb || 0, memoryMaxMb: modStatus.memoryMaxMb || 0, }; } /** * 전체 플레이어 목록 조회 */ async function fetchAllPlayers() { try { const response = await fetch(`${MOD_API_URL}/players`); if (response.ok) { const data = await response.json(); return data.players || []; } return []; } catch (error) { console.error("[ModAPI] 플레이어 목록 조회 실패:", error.message); return []; } } /** * 특정 플레이어 정보 조회 */ async function fetchPlayerDetail(uuid) { try { const response = await fetch(`${MOD_API_URL}/player/${uuid}`); if (response.ok) return await response.json(); return null; } catch (error) { console.error("[ModAPI] 플레이어 조회 실패:", error.message); return null; } } /** * 주기적 데이터 갱신 */ async function refreshData() { const [modStatus, motdData, players] = await Promise.all([ fetchModStatus(), fetchMotd(), fetchAllPlayers(), ]); cachedStatus = formatStatusForClient(modStatus, motdData); cachedPlayers = players; return { cachedStatus, cachedPlayers }; } const getCachedStatus = () => cachedStatus; const getCachedPlayers = () => cachedPlayers; export { MOD_API_URL, fetchModStatus, fetchMotd, formatStatusForClient, fetchAllPlayers, fetchPlayerDetail, refreshData, getCachedStatus, getCachedPlayers, };