WHAT WAS DONE: Replaced static Minecraft servers section with dynamic real-time status display powered by Cloudflare Workers + Pterodactyl Client API. FEATURES IMPLEMENTED: - Real-time server status (Online/Offline) with pulse animation - Live player counts - Auto-refresh every 60 seconds - Graceful error handling - NO IP addresses displayed (Discord-gated security) - 'Join Discord' CTA for connection details TECHNICAL DETAILS: - Fetches from: https://servers-api.michael-b25.workers.dev - Edge-cached (60 second TTL) - Zero manual updates required - IPs stripped at Worker level (never touch frontend) SECURITY: - Server IPs available only in Discord (Awakened+ tier) - Drives community engagement and subscription conversion - Prevents port scanning and unauthorized access When servers added/removed in Pterodactyl, website auto-updates within 60 seconds. Zero code changes needed. Fire + Frost + Foundation = Where Love Builds Legacy 💙 Signed-off-by: Claude (Chronicler #56) <claude@firefrostgaming.com>
138 lines
8.3 KiB
Plaintext
138 lines
8.3 KiB
Plaintext
---
|
|
layout: layouts/base.njk
|
|
title: Our Servers
|
|
description: Nine Minecraft experiences. One community built to last. All servers available to all subscribers.
|
|
---
|
|
|
|
<!-- SERVERS PAGE - HERO -->
|
|
<div style="padding: 100px 40px; background: linear-gradient(135deg, #0f0f1e 0%, #1a1a2e 100%); text-align: center;">
|
|
<h1 style="font-size: 4rem; font-weight: 900; margin-bottom: 30px; color: #ffffff; text-shadow: 2px 2px 8px rgba(0,0,0,0.7);">Our Servers</h1>
|
|
<p style="font-size: 1.5rem; color: #a8dadc; max-width: 900px; margin: 0 auto 40px; line-height: 1.8;">Nine Minecraft experiences. One community built to last.</p>
|
|
<p style="font-size: 1.8rem; color: #FFD700; font-weight: 700;">All servers available to all subscribers</p>
|
|
</div>
|
|
|
|
<!-- MINECRAFT SERVERS - DYNAMIC -->
|
|
<div style="padding: 100px 60px; background: linear-gradient(135deg, #1a1a2e 0%, #0f0f1e 100%);">
|
|
<div style="max-width: 1400px; margin: 0 auto;">
|
|
<div style="text-align: center; margin-bottom: 80px;">
|
|
<h2 style="font-size: 3rem; margin-bottom: 20px; color: #e8f4f8; font-weight: 800;">Live Server Status</h2>
|
|
<p style="font-size: 1.3rem; color: #a8dadc; line-height: 1.7;">Real-time status for all Firefrost Gaming servers.</p>
|
|
</div>
|
|
|
|
<div id="server-grid" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); gap: 40px;">
|
|
<p style="color: #a8dadc; text-align: center; font-size: 1.2rem;">Connecting to the fleet...</p>
|
|
</div>
|
|
|
|
<!-- Discord Access Notice -->
|
|
<div style="margin-top: 60px; background: linear-gradient(135deg, rgba(168, 85, 247, 0.15) 0%, rgba(168, 85, 247, 0.05) 100%); border: 2px solid #A855F7; border-radius: 15px; padding: 40px; text-align: center;">
|
|
<div style="font-size: 2.5rem; margin-bottom: 15px;">🔒</div>
|
|
<h3 style="color: #A855F7; font-size: 1.8rem; margin-bottom: 15px; font-weight: 700;">Server IPs Available in Discord</h3>
|
|
<p style="color: #e8f4f8; font-size: 1.2rem; line-height: 1.7; margin-bottom: 25px;">Connection details are available to Awakened+ subscribers in our Discord community.</p>
|
|
<a href="/discord" style="display: inline-block; background: linear-gradient(135deg, #A855F7 0%, #4ECDC4 100%); color: white; padding: 18px 45px; text-decoration: none; border-radius: 10px; font-weight: 700; font-size: 1.1rem; transition: transform 0.3s;">Join Discord →</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
const grid = document.getElementById('server-grid');
|
|
const WORKER_URL = 'https://servers-api.michael-b25.workers.dev';
|
|
|
|
function fetchServers() {
|
|
fetch(WORKER_URL)
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
if (data.error || !data.servers || data.servers.length === 0) {
|
|
grid.innerHTML = `<p style="color: #ff6b35; text-align: center; font-size: 1.2rem;">Unable to connect to server status. Please try again later.</p>`;
|
|
return;
|
|
}
|
|
|
|
grid.innerHTML = data.servers.map(server => {
|
|
const isOnline = server.status === 'Online';
|
|
const statusColor = isOnline ? '#4ecdc4' : '#ff6b35';
|
|
const playerText = isOnline ? `${server.players} Players` : 'Offline';
|
|
|
|
return `
|
|
<div style="background: linear-gradient(135deg, rgba(78, 205, 196, 0.1) 0%, rgba(78, 205, 196, 0.05) 100%); border: 2px solid ${statusColor}; border-radius: 15px; padding: 35px;">
|
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
|
|
<h3 style="color: #e8f4f8; font-size: 1.8rem; font-weight: 700; margin: 0;">${server.name}</h3>
|
|
<span class="status-badge ${server.status.toLowerCase()}" style="background: ${isOnline ? 'rgba(78, 205, 196, 0.2)' : 'rgba(255, 107, 53, 0.2)'}; color: ${statusColor}; padding: 8px 16px; border-radius: 20px; font-size: 0.9rem; font-weight: 600; display: flex; align-items: center; gap: 8px;">
|
|
${isOnline ? '<span class="pulse-dot"></span>' : ''} ${server.status}
|
|
</span>
|
|
</div>
|
|
<p style="color: #a8dadc; font-size: 1rem; margin-bottom: 15px;">${server.description || 'Minecraft Server'}</p>
|
|
<p style="color: ${statusColor}; font-size: 1.1rem; font-weight: 600;">${playerText}</p>
|
|
</div>
|
|
`;
|
|
}).join('');
|
|
})
|
|
.catch(err => {
|
|
grid.innerHTML = `<p style="color: #ff6b35; text-align: center; font-size: 1.2rem;">Connection error. Please check back shortly.</p>`;
|
|
});
|
|
}
|
|
|
|
// Initial fetch
|
|
fetchServers();
|
|
|
|
// Auto-refresh every 60 seconds
|
|
setInterval(fetchServers, 60000);
|
|
});
|
|
</script>
|
|
|
|
<style>
|
|
.pulse-dot {
|
|
display: inline-block;
|
|
width: 8px;
|
|
height: 8px;
|
|
background-color: #4ecdc4;
|
|
border-radius: 50%;
|
|
animation: pulse 2s infinite;
|
|
}
|
|
|
|
@keyframes pulse {
|
|
0% { box-shadow: 0 0 0 0 rgba(78, 205, 196, 0.7); }
|
|
70% { box-shadow: 0 0 0 6px rgba(78, 205, 196, 0); }
|
|
100% { box-shadow: 0 0 0 0 rgba(78, 205, 196, 0); }
|
|
}
|
|
</style>
|
|
|
|
<!-- SPECIAL SERVICES -->
|
|
<div style="padding: 100px 60px; background: linear-gradient(135deg, #0f0f1e 0%, #1a1a2e 100%);">
|
|
<div style="max-width: 1400px; margin: 0 auto;">
|
|
<div style="text-align: center; margin-bottom: 80px;">
|
|
<div style="font-size: 4rem; margin-bottom: 20px;">⚡</div>
|
|
<h2 style="font-size: 3rem; margin-bottom: 20px; color: #A855F7; font-weight: 800;">Premium Add-Ons</h2>
|
|
<p style="font-size: 1.3rem; color: #a8dadc; line-height: 1.7;">Optional services available for subscribers.</p>
|
|
</div>
|
|
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 50px;">
|
|
|
|
<!-- FoundryVTT -->
|
|
<div style="background: linear-gradient(135deg, rgba(168, 85, 247, 0.15) 0%, rgba(168, 85, 247, 0.05) 100%); border: 3px solid #A855F7; border-radius: 20px; padding: 45px; text-align: center;">
|
|
<h3 style="color: #A855F7; font-size: 2rem; margin-bottom: 15px; font-weight: 700;">FoundryVTT</h3>
|
|
<p style="color: #A855F7; font-size: 1.2rem; margin-bottom: 25px; font-weight: 600;">GM Time Add-On</p>
|
|
<p style="color: #4ecdc4; font-size: 1.1rem; margin-bottom: 20px; font-weight: 600;">foundry.firefrostgaming.com</p>
|
|
<p style="color: #e8f4f8; line-height: 1.8; margin-bottom: 20px;">Virtual tabletop for running epic D&D campaigns. Available as a separate purchase for any subscriber. Run your own world, your own rules.</p>
|
|
<p style="color: #a8dadc; font-size: 0.95rem; font-style: italic;">Separate add-on purchase • 14-day grace period on subscription lapse</p>
|
|
</div>
|
|
|
|
<!-- Hytale -->
|
|
<div style="background: linear-gradient(135deg, rgba(168, 85, 247, 0.15) 0%, rgba(168, 85, 247, 0.05) 100%); border: 3px solid #A855F7; border-radius: 20px; padding: 45px; text-align: center;">
|
|
<h3 style="color: #A855F7; font-size: 2rem; margin-bottom: 15px; font-weight: 700;">Hytale</h3>
|
|
<p style="color: #A855F7; font-size: 1.2rem; margin-bottom: 25px; font-weight: 600;">Coming Soon</p>
|
|
<p style="color: #4ecdc4; font-size: 1.1rem; margin-bottom: 20px; font-weight: 600;">hytale.firefrostgaming.com</p>
|
|
<p style="color: #e8f4f8; line-height: 1.8; margin-bottom: 20px;">The next generation of voxel gaming. We're ready for launch day. When Hytale releases, Firefrost will be there.</p>
|
|
<p style="color: #a8dadc; font-size: 0.95rem; font-style: italic;">Launching when the game releases • Subscription-based access</p>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- JOIN CTA -->
|
|
<div style="padding: 100px 60px; background: linear-gradient(135deg, rgba(78, 205, 196, 0.1) 0%, rgba(168, 85, 247, 0.1) 50%, rgba(255, 107, 53, 0.1) 100%); text-align: center;">
|
|
<h2 style="font-size: 3rem; margin-bottom: 30px; color: #e8f4f8; font-weight: 800;">Ready to Play?</h2>
|
|
<p style="font-size: 1.4rem; color: #a8dadc; margin-bottom: 50px; max-width: 800px; margin-left: auto; margin-right: auto; line-height: 1.7;">Join a community built to last. All servers available to all subscribers.</p>
|
|
<a href="/subscribe" style="display: inline-block; background: linear-gradient(135deg, #FF6B35 0%, #A855F7 50%, #4ECDC4 100%); color: white; padding: 25px 70px; text-decoration: none; border-radius: 12px; font-weight: 700; font-size: 1.3rem; box-shadow: 0 8px 25px rgba(78, 205, 196, 0.5); transition: transform 0.3s;">🔥⚡❄️ Start Your Journey</a>
|
|
</div>
|