import React, { useState, useEffect, useRef } from 'react'; import { Globe, Sun, CloudRain, CloudLightning, Clock, Users, MapPin, ServerOff } from 'lucide-react'; import { motion } from 'framer-motion'; import { io } from 'socket.io-client'; // 월드 정보 페이지 const WorldsPage = ({ isMobile = false }) => { const [worlds, setWorlds] = useState([]); const [loading, setLoading] = useState(true); const [serverOnline, setServerOnline] = useState(null); const socketRef = useRef(null); // 월드 순서 정렬 함수 (오버월드 -> 네더 -> 엔드) const sortWorlds = (worldList) => { const order = { 'minecraft:overworld': 0, 'minecraft:the_nether': 1, 'minecraft:the_end': 2 }; return [...worldList].sort((a, b) => { const orderA = order[a.dimension] ?? 999; const orderB = order[b.dimension] ?? 999; return orderA - orderB; }); }; useEffect(() => { // 소켓 연결 const socket = io('/', { path: '/socket.io', transports: ['websocket', 'polling'] }); socketRef.current = socket; socket.on('status', (data) => { setServerOnline(data.online); if (!data.online) { setLoading(false); } }); socket.on('worlds', (data) => { setWorlds(sortWorlds(data.worlds || [])); setLoading(false); }); // 초기 데이터 요청 socket.emit('get_worlds'); // 5초마다 갱신 const interval = setInterval(() => { socket.emit('get_worlds'); }, 1000); return () => { clearInterval(interval); socket.disconnect(); }; }, []); // 시간 포맷팅 (틱 -> 시:분) const formatTime = (dayTime) => { const hours = Math.floor(dayTime / 1000); const minutes = Math.floor((dayTime % 1000) / 16.67); const hour24 = (hours + 6) % 24; const ampm = hour24 >= 12 ? '오후' : '오전'; const hour12 = hour24 % 12 || 12; return `${ampm} ${hour12}:${String(Math.floor(minutes)).padStart(2, '0')}`; }; // 날씨 아이콘 const WeatherIcon = ({ type }) => { switch (type) { case 'thunderstorm': return ; case 'rain': return ; default: return ; } }; // 차원 색상 const getDimensionStyle = (dimension) => { if (dimension.includes('nether')) { return { gradient: 'from-red-500/20 to-orange-500/20', border: 'border-red-500/30', text: 'text-red-400' }; } if (dimension.includes('end')) { return { gradient: 'from-purple-500/20 to-pink-500/20', border: 'border-purple-500/30', text: 'text-purple-400' }; } return { gradient: 'from-mc-green/20 to-emerald-500/20', border: 'border-mc-green/30', text: 'text-mc-green' }; }; // 서버 오프라인 상태 - 전체 화면 가운데 정렬 if (serverOnline === false) { return (

서버 오프라인

마인크래프트 서버가 현재 오프라인 상태입니다.
서버가 시작되면 월드 정보를 확인할 수 있습니다.

); } return (
{/* 헤더 */}

월드 정보

{/* 월드 카드 목록 */} {loading ? (
) : worlds.length > 0 ? (
{worlds.map((world, index) => { const style = getDimensionStyle(world.dimension); return (
{/* 상단: 월드 이름 & 날씨/시간 */}

{world.displayName}

{world.playerCount}명 접속 중
{world.weather?.displayName}
{formatTime(world.time?.dayTime || 0)} (Day {world.time?.day || 1})
{/* 하단: 접속 중인 플레이어 목록 */} {world.players && world.players.length > 0 && (
{world.players.map((player) => (
{/* 모바일: 머리만, PC: 전신 */} {player.name}

{player.name}

{player.x}, {player.y}, {player.z}
))}
)} {world.playerCount === 0 && (
현재 접속 중인 플레이어가 없습니다
)}
); })}
) : (

월드 정보를 불러올 수 없습니다.

)}
); }; export default WorldsPage;