Files
status-check/public/js/app.js
MCHost 1ef09e5015 fix
2025-07-09 17:46:31 -04:00

155 lines
6.7 KiB
JavaScript

// Confetti function
function launchConfetti() {
confetti({
particleCount: 100,
spread: 70,
origin: { y: 0.6 },
colors: ['#60a5fa', '#a855f7', '#ec4899']
});
}
// Form submission handler
document.getElementById('serverForm').addEventListener('submit', async (e) => {
e.preventDefault();
const edition = document.getElementById('edition').value;
const connection = document.getElementById('connection').value.trim();
let host, port;
// Check if connection includes a port
if (connection.includes(':')) {
[host, port] = connection.split(':');
} else {
host = connection;
port = '25565'; // Default Minecraft port
}
// Validate hostname (allow subdomains and IPs)
const hostnameRegex = /^(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}|(?:\d{1,3}\.){3}\d{1,3})$/;
if (!hostnameRegex.test(host)) {
alert('Please enter a valid hostname (e.g., raven.my-mc.link or 192.168.1.1)');
return;
}
// Validate port if provided
if (port && (isNaN(port) || port < 1 || port > 65535)) {
alert('Please enter a valid port number (1-65535)');
return;
}
const loadingSpinner = document.getElementById('loadingSpinner');
const statusResult = document.getElementById('statusResult');
const statusContent = document.getElementById('statusContent');
const widgetSection = document.getElementById('widgetSection');
const widgetCode = document.getElementById('widgetCode');
const submitButton = e.target.querySelector('button[type="submit"]');
// Show loading spinner and disable button
loadingSpinner.style.display = 'block';
submitButton.disabled = true;
statusResult.classList.add('hidden');
widgetSection.classList.add('hidden');
statusContent.innerHTML = '<p class="animate-pulse">Checking...</p>';
try {
const response = await fetch(`/${edition}/${host}/${port}`);
if (!response.ok) {
if (response.status === 429) {
throw new Error('RateLimit');
}
throw new Error('Request failed');
}
const result = await response.json();
statusResult.classList.remove('hidden');
if (result.isOnline) {
launchConfetti();
const { data } = result;
const statusData = {};
if (edition === 'java') {
if (data.version?.name?.clean) statusData['Version'] = data.version.name.clean;
if (data.version?.protocol) statusData['Protocol'] = data.version.protocol;
if (data.players?.online != null) statusData['Players Online'] = data.players.online;
if (data.players?.max != null) statusData['Max Players'] = data.players.max;
if (data.motd?.clean) statusData['MOTD'] = data.motd.clean;
if (data.favicon) statusData['Favicon'] = 'Present';
if (data.srv_record) statusData['SRV Record'] = JSON.stringify(data.srv_record);
if (data.mods) statusData['Mods'] = JSON.stringify(data.mods);
} else {
if (data.version) statusData['Version'] = data.version;
if (data.protocol_version) statusData['Protocol'] = data.protocol_version;
if (data.online_players != null) statusData['Players Online'] = data.online_players;
if (data.max_players != null) statusData['Max Players'] = data.max_players;
if (data.motd) statusData['MOTD'] = data.motd.clean;
if (data.gamemode) statusData['Gamemode'] = data.gamemode;
if (data.server_id) statusData['Server ID'] = data.server_id;
}
statusContent.innerHTML = `
<p><strong class="text-blue-400">Status:</strong> <span class="text-green-400">Online</span></p>
${Object.entries(statusData).map(([key, value]) => `
<p><strong class="text-blue-400">${key}:</strong> ${value}</p>
`).join('')}
`;
// Use SRV-resolved host and port if available, else user-provided or default
if (host.includes("my-mc.link")){
host = "my-mc.link"
}
let widgetHost = host;
let widgetPort = result.srvPort || port;
// Show widget section and set widget code
widgetSection.classList.remove('hidden');
const widgetIframe = `<iframe src="https://my-mc.link/widget/${edition}/${widgetHost}/${widgetPort}" width="280" height="145" frameborder="0" scrolling="no"></iframe>`;
widgetCode.textContent = widgetIframe;
} else {
statusContent.innerHTML = `
<p><strong class="text-blue-400">Status:</strong> <span class="text-red-400">Offline</span></p>
<p><strong class="text-blue-400">Error:</strong> Server is not reachable</p>
`;
}
} catch (error) {
statusResult.classList.remove('hidden');
if (error.message === 'RateLimit') {
statusContent.innerHTML = `
<p><strong class="text-blue-400">Status:</strong> <span class="text-yellow-400">Rate Limited</span></p>
<p><strong class="text-blue-400">Message:</strong> You are sending requests too quickly. Please try again in a moment.</p>
`;
} else {
statusContent.innerHTML = `
<p><strong class="text-blue-400">Status:</strong> <span class="text-red-400">Error</span></p>
<p><strong class="text-blue-400">Error:</strong> An error occurred while checking the server status</p>
`;
}
} finally {
// Hide loading spinner and re-enable button
loadingSpinner.style.display = 'none';
submitButton.disabled = false;
}
});
// Handle copy widget code
document.getElementById('copyWidgetCode').addEventListener('click', function () {
const widgetCode = document.getElementById('widgetCode').textContent;
navigator.clipboard.writeText(widgetCode).then(() => {
const alert = document.getElementById('copyAlert');
alert.classList.remove('hidden');
setTimeout(() => {
alert.classList.add('hidden');
}, 3000);
}).catch(err => {
console.error('Failed to copy: ', err);
});
});
// Handle URL-based checks
const path = window.location.pathname.split('/');
if (path[1] && path[2] && path[3]) {
const edition = path[1];
const host = path[2];
const port = path[3];
document.getElementById('edition').value = edition;
document.getElementById('connection').value = `${host}:${port}`;
document.getElementById('serverForm').dispatchEvent(new Event('submit'));
}