function copyIp() { const ipText = document.getElementById('server-ip').innerText; const tooltip = document.getElementById('copy-tooltip'); navigator.clipboard.writeText(ipText).then(() => { tooltip.innerText = "已复制!"; tooltip.classList.add('show'); setTimeout(() => { tooltip.classList.remove('show'); setTimeout(() => { tooltip.innerText = "点击复制 IP"; }, 200); // Wait for fade out }, 2000); }).catch(err => { console.error('无法复制文本: ', err); tooltip.innerText = "复制失败"; tooltip.classList.add('show'); setTimeout(() => { tooltip.classList.remove('show'); }, 2000); }); } // Sponsors Logic document.addEventListener('DOMContentLoaded', () => { fetchSponsors(); fetchCrowdfunding(); // setupModal(); // Removed, modal is gone fetchServerStatus(); startRuntimeTimer(); }); function startRuntimeTimer() { const startTime = new Date("2021-09-14T09:57:59").getTime(); function update() { const now = new Date().getTime(); const diff = now - startTime; const days = Math.floor(diff / (1000 * 60 * 60 * 24)); const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); const seconds = Math.floor((diff % (1000 * 60)) / 1000); const daysEl = document.getElementById("runtime-days"); const hoursEl = document.getElementById("runtime-hours"); const minutesEl = document.getElementById("runtime-minutes"); const secondsEl = document.getElementById("runtime-seconds"); if (daysEl) daysEl.innerText = days; if (hoursEl) hoursEl.innerText = hours; if (minutesEl) minutesEl.innerText = minutes; if (secondsEl) secondsEl.innerText = seconds; } update(); setInterval(update, 1000); } async function fetchServerStatus() { const countElement = document.getElementById('online-count'); const listElement = document.getElementById('players-list'); const dotElement = document.querySelector('.status-dot'); try { const response = await fetch('https://api.mcstatus.io/v2/status/java/mcpure.lunadeer.cn'); const data = await response.json(); if (data.online) { countElement.innerText = `在线人数: ${data.players.online} / ${data.players.max}`; dotElement.classList.remove('offline'); if (data.players.list && data.players.list.length > 0) { listElement.innerHTML = data.players.list.map(player => `
${player.name_raw}
`).join(''); } else { listElement.innerHTML = '
暂无玩家在线
'; } } else { countElement.innerText = '服务器离线'; dotElement.classList.add('offline'); listElement.innerHTML = '
服务器离线
'; } } catch (error) { console.error('Error fetching server status:', error); countElement.innerText = '无法获取状态'; dotElement.classList.add('offline'); listElement.innerHTML = '
获取失败
'; } } async function fetchCrowdfunding() { try { console.log('Fetching crowdfunding data...'); const response = await fetch('fund_progress.txt'); if (!response.ok) { console.error('Failed to fetch fund_progress.txt:', response.status, response.statusText); return; } const text = await response.text(); console.log('Crowdfunding data received:', text); const lines = text.trim().split('\n'); const funds = []; lines.forEach(line => { // Replace Chinese comma with English comma just in case const normalizedLine = line.replace(/,/g, ','); const parts = normalizedLine.split(','); if (parts.length >= 3) { const name = parts[0].trim(); const current = parseFloat(parts[1].trim()); const target = parseFloat(parts[2].trim()); if (name && !isNaN(current) && !isNaN(target)) { funds.push({ name, current, target }); } } }); console.log('Parsed funds:', funds); if (funds.length > 0) { renderCrowdfunding(funds); const section = document.getElementById('crowdfunding-section'); if (section) { section.style.display = 'block'; console.log('Crowdfunding section displayed'); } else { console.error('Crowdfunding section element not found'); } } else { console.warn('No valid crowdfunding data found'); } } catch (error) { console.error('Error loading crowdfunding data:', error); } } function renderCrowdfunding(funds) { const container = document.getElementById('crowdfunding-grid'); container.innerHTML = funds.map(fund => { const percentage = Math.min(100, Math.max(0, (fund.current / fund.target) * 100)); return `
${fund.name}
¥${fund.current} / ¥${fund.target}
${percentage.toFixed(1)}%
`; }).join(''); } async function fetchSponsors() { try { const response = await fetch('sponsors.txt'); const text = await response.text(); const lines = text.trim().split('\n'); const sponsors = []; const userTotals = {}; lines.forEach(line => { const parts = line.split(','); if (parts.length >= 3) { const name = parts[0].trim(); const project = parts[1].trim(); const amountStr = parts[2].trim().replace('¥', ''); const amount = parseFloat(amountStr); const date = parts[3] ? parts[3].trim() : ''; if (!isNaN(amount)) { sponsors.push({ name, project, amount, date }); if (userTotals[name]) { userTotals[name] += amount; } else { userTotals[name] = amount; } } } }); // Sort users by total amount for Top 3 const sortedUsers = Object.keys(userTotals).map(name => ({ name, total: userTotals[name] })).sort((a, b) => b.total - a.total); renderTopSponsors(sortedUsers.slice(0, 3)); // renderSponsorsTable(sponsors); // Removed as table is now on sponsor.html } catch (error) { console.error('Error loading sponsors:', error); } } function renderTopSponsors(topUsers) { const container = document.getElementById('top-sponsors'); const medals = ['🥇', '🥈', '🥉']; container.innerHTML = topUsers.map((user, index) => ` `).join(''); } /* Removed renderSponsorsTable and setupModal as they are no longer used on index page */