serverviewer / index.html
Candle6468's picture
make a site that checks the status, player count, message of the day, name, and icon of a minecraft server. The user should be able to input the server id. Make the ui layout similar to the minecraft java server browser - Initial Deployment
0b4aca6 verified
Raw
History Blame Contribute Delete
17.3 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Minecraft Server Status Checker</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Minecraft&display=swap');
.minecraft-font {
font-family: 'Minecraft', sans-serif;
}
.server-icon {
width: 64px;
height: 64px;
image-rendering: pixelated;
}
.status-indicator {
width: 12px;
height: 12px;
border-radius: 50%;
}
.online {
background-color: #55FF55;
box-shadow: 0 0 10px #55FF55;
}
.offline {
background-color: #FF5555;
box-shadow: 0 0 10px #FF5555;
}
.server-card {
background-color: #2a2a2a;
border-left: 4px solid #3a3a3a;
transition: all 0.2s ease;
}
.server-card:hover {
background-color: #3a3a3a;
border-left-color: #4a4a4a;
}
.motd {
color: #AAAAAA;
font-family: 'Minecraft', sans-serif;
white-space: pre-wrap;
}
.player-count {
color: #AAAAAA;
}
.search-input {
background-color: #2a2a2a;
border: 2px solid #3a3a3a;
}
.search-input:focus {
outline: none;
border-color: #4a4a4a;
}
.search-button {
background-color: #3a3a3a;
transition: all 0.2s ease;
}
.search-button:hover {
background-color: #4a4a4a;
}
.loading-spinner {
border-top-color: #55FF55;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.player-sample {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
}
.player-sample.expanded {
max-height: 200px;
}
</style>
</head>
<body class="bg-gray-900 text-white min-h-screen">
<div class="container mx-auto px-4 py-8">
<h1 class="text-3xl minecraft-font text-center mb-8 text-green-400">
<i class="fas fa-server mr-2"></i> Minecraft Server Status
</h1>
<div class="max-w-2xl mx-auto mb-8">
<div class="flex">
<input
type="text"
id="serverAddress"
placeholder="Enter server address (e.g., mc.hypixel.net)"
class="search-input flex-grow px-4 py-3 rounded-l focus:border-green-500"
>
<button
id="searchButton"
class="search-button px-6 py-3 rounded-r text-white font-semibold hover:bg-green-600"
>
<i class="fas fa-search mr-2"></i> Check
</button>
</div>
</div>
<div id="errorMessage" class="hidden bg-red-900 text-white p-4 rounded mb-6 text-center"></div>
<div id="loadingSpinner" class="hidden text-center py-8">
<div class="inline-block h-12 w-12 border-4 border-gray-600 rounded-full loading-spinner"></div>
<p class="mt-2">Fetching server data...</p>
</div>
<div id="serverInfo" class="hidden max-w-4xl mx-auto">
<div class="server-card p-6 rounded mb-6 flex flex-col md:flex-row items-start md:items-center">
<div class="flex items-center mb-4 md:mb-0 md:mr-6">
<img id="serverIcon" src="https://api.mcstatus.io/v2/icon/mc.hypixel.net" alt="Server Icon" class="server-icon rounded mr-4">
<div>
<h2 id="serverName" class="text-xl font-bold"></h2>
<div class="flex items-center mt-1">
<div id="statusIndicator" class="status-indicator mr-2"></div>
<span id="serverStatus" class="text-sm"></span>
</div>
</div>
</div>
<div class="flex-grow">
<div class="flex justify-between items-center mb-2">
<div>
<span class="text-gray-400">Players:</span>
<span id="playerCount" class="ml-2 font-semibold"></span>
</div>
<div>
<span class="text-gray-400">Version:</span>
<span id="serverVersion" class="ml-2 font-semibold"></span>
</div>
</div>
<div class="bg-gray-800 p-3 rounded mt-2">
<p class="text-gray-400 mb-1">Message of the Day:</p>
<div id="serverMotd" class="motd"></div>
</div>
<button id="togglePlayersBtn" class="mt-4 text-green-400 hover:text-green-300 text-sm flex items-center">
<i class="fas fa-users mr-1"></i> Show player sample
<i id="togglePlayersIcon" class="fas fa-chevron-down ml-2 text-xs"></i>
</button>
<div id="playerSample" class="player-sample mt-2 bg-gray-800 rounded p-3">
<p class="text-gray-400 mb-2">Online Players:</p>
<div id="playerList" class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-2"></div>
</div>
</div>
</div>
<div class="bg-gray-800 p-4 rounded">
<h3 class="font-bold mb-2 text-green-400"><i class="fas fa-info-circle mr-2"></i> Server Details</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<p><span class="text-gray-400">Address:</span> <span id="serverAddressDisplay" class="font-mono"></span></p>
<p class="mt-1"><span class="text-gray-400">Protocol:</span> <span id="serverProtocol" class="font-mono"></span></p>
</div>
<div>
<p><span class="text-gray-400">Latency:</span> <span id="serverLatency" class="font-mono"></span> ms</p>
<p class="mt-1"><span class="text-gray-400">Last Updated:</span> <span id="lastUpdated" class="font-mono"></span></p>
</div>
</div>
</div>
</div>
<div class="mt-12 text-center text-gray-500 text-sm">
<p>This tool uses the <a href="https://mcstatus.io/" class="text-green-400 hover:underline" target="_blank">mcstatus.io</a> API</p>
<p class="mt-1">Not affiliated with Mojang or Microsoft</p>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const serverAddressInput = document.getElementById('serverAddress');
const searchButton = document.getElementById('searchButton');
const errorMessage = document.getElementById('errorMessage');
const loadingSpinner = document.getElementById('loadingSpinner');
const serverInfo = document.getElementById('serverInfo');
const serverName = document.getElementById('serverName');
const statusIndicator = document.getElementById('statusIndicator');
const serverStatus = document.getElementById('serverStatus');
const playerCount = document.getElementById('playerCount');
const serverVersion = document.getElementById('serverVersion');
const serverMotd = document.getElementById('serverMotd');
const serverIcon = document.getElementById('serverIcon');
const serverAddressDisplay = document.getElementById('serverAddressDisplay');
const serverProtocol = document.getElementById('serverProtocol');
const serverLatency = document.getElementById('serverLatency');
const lastUpdated = document.getElementById('lastUpdated');
const playerList = document.getElementById('playerList');
const togglePlayersBtn = document.getElementById('togglePlayersBtn');
const togglePlayersIcon = document.getElementById('togglePlayersIcon');
const playerSample = document.getElementById('playerSample');
// Check server when button is clicked
searchButton.addEventListener('click', checkServerStatus);
// Also check when Enter is pressed in the input field
serverAddressInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
checkServerStatus();
}
});
// Toggle player sample visibility
togglePlayersBtn.addEventListener('click', function() {
playerSample.classList.toggle('expanded');
const isExpanded = playerSample.classList.contains('expanded');
togglePlayersIcon.className = isExpanded ? 'fas fa-chevron-up ml-2 text-xs' : 'fas fa-chevron-down ml-2 text-xs';
togglePlayersBtn.innerHTML = isExpanded
? '<i class="fas fa-users mr-1"></i> Hide player sample' +
'<i id="togglePlayersIcon" class="fas fa-chevron-up ml-2 text-xs"></i>'
: '<i class="fas fa-users mr-1"></i> Show player sample' +
'<i id="togglePlayersIcon" class="fas fa-chevron-down ml-2 text-xs"></i>';
});
function checkServerStatus() {
const address = serverAddressInput.value.trim();
if (!address) {
showError('Please enter a server address');
return;
}
// Show loading spinner and hide other elements
loadingSpinner.classList.remove('hidden');
errorMessage.classList.add('hidden');
serverInfo.classList.add('hidden');
// Fetch server status from mcstatus.io API
fetch(`https://api.mcstatus.io/v2/status/java/${address}`)
.then(response => {
if (!response.ok) {
throw new Error('Server not found or not responding');
}
return response.json();
})
.then(data => {
displayServerInfo(data, address);
})
.catch(error => {
showError(error.message || 'Failed to fetch server status');
})
.finally(() => {
loadingSpinner.classList.add('hidden');
});
}
function displayServerInfo(data, address) {
// Basic info
serverName.textContent = data.motd.clean || address;
serverAddressDisplay.textContent = address;
// Status
const isOnline = data.online;
if (isOnline) {
statusIndicator.className = 'status-indicator mr-2 online';
serverStatus.textContent = 'Online';
serverStatus.className = 'text-sm text-green-400';
} else {
statusIndicator.className = 'status-indicator mr-2 offline';
serverStatus.textContent = 'Offline';
serverStatus.className = 'text-sm text-red-400';
}
// Players
if (isOnline && data.players) {
playerCount.textContent = `${data.players.online}/${data.players.max}`;
// Player sample
playerList.innerHTML = '';
if (data.players.list && data.players.list.length > 0) {
data.players.list.forEach(player => {
const playerElement = document.createElement('div');
playerElement.className = 'flex items-center';
playerElement.innerHTML = `
<img src="https://mc-heads.net/avatar/${player.name_clean}/24"
alt="${player.name_clean}"
class="rounded-full mr-2"
title="${player.name_clean}">
<span class="truncate">${player.name_clean}</span>
`;
playerList.appendChild(playerElement);
});
} else {
playerList.innerHTML = '<p class="text-gray-500">No player data available</p>';
}
} else {
playerCount.textContent = '0/0';
playerList.innerHTML = '<p class="text-gray-500">No player data available</p>';
}
// Version
if (isOnline && data.version) {
serverVersion.textContent = data.version.name_clean || 'Unknown';
serverProtocol.textContent = data.version.protocol || 'Unknown';
} else {
serverVersion.textContent = 'Unknown';
serverProtocol.textContent = 'Unknown';
}
// MOTD
if (isOnline && data.motd) {
serverMotd.innerHTML = formatMotd(data.motd.html);
} else {
serverMotd.textContent = 'No MOTD available';
}
// Latency
if (isOnline && data.round_trip_latency) {
serverLatency.textContent = Math.round(data.round_trip_latency);
} else {
serverLatency.textContent = 'N/A';
}
// Last updated
const now = new Date();
lastUpdated.textContent = now.toLocaleString();
// Server icon
serverIcon.src = `https://api.mcstatus.io/v2/icon/${address}?${now.getTime()}`;
serverIcon.onerror = function() {
this.src = 'https://api.mcstatus.io/v2/icon/mc.hypixel.net'; // Fallback icon
};
// Show the server info
serverInfo.classList.remove('hidden');
}
function formatMotd(motdHtml) {
// Convert HTML MOTD to formatted text
let formatted = motdHtml
.replace(/<br\s*\/?>/gi, '\n')
.replace(/<[^>]+>/g, '')
.replace(/&nbsp;/g, ' ')
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&amp;/g, '&');
// Trim and clean up
formatted = formatted.trim();
return formatted || 'No MOTD available';
}
function showError(message) {
errorMessage.textContent = message;
errorMessage.classList.remove('hidden');
serverInfo.classList.add('hidden');
}
// Check Hypixel by default for demo purposes
serverAddressInput.value = 'mc.hypixel.net';
// checkServerStatus();
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Candle6468/serverviewer" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>