feat: complete in-game commands, GUIs, admin panel fixes, and launcher enhancements

This commit is contained in:
scoped committed 2026-09-29 12:14:16 -04:00
1 parent a9ff92e1d1
commit 752f0cc43d
34 files changed
+4170 -181

No files matched your search

+91 -26
View File
@@ -2,7 +2,7 @@
import {
Download, Server, Users, Trophy, Sparkles, HelpCircle, Newspaper,
Copy, Check, ExternalLink, ChevronDown, ChevronUp, Swords, Flame,
Pickaxe, Clock, Box, Shield, Zap, ArrowRight, LogIn, Crown,
Pickaxe, Clock, Box, Shield, Zap, ArrowRight, LogIn, Crown, MessageSquare,
} from '@lucide/svelte';
import { get, formatBytes } from '../lib/api';
import { session } from '../lib/session.svelte';
@@ -171,18 +171,25 @@
<div class="container hero-content">
<div class="hero-badge">
<span class="hero-badge-dot"></span>
<span>{totalOnline} Players Online Now</span>
<span>{block.options?.badge_text || `${totalOnline} Players Online Now`}</span>
</div>
<h1 class="hero-title">{config.hero_title}</h1>
<p class="hero-sub">{config.hero_subtitle}</p>
<h1 class="hero-title">{block.options?.headline || config.hero_title}</h1>
<p class="hero-sub">{block.options?.subtitle || config.hero_subtitle}</p>
<div class="hero-cta-group">
{#if primaryDownload}
{#if block.options?.cta_url}
<a href={block.options.cta_url} target="_blank" class="btn-hero-primary">
<Download size={20} />
<div class="cta-text-group">
<span class="cta-main">{block.options?.cta_text || config.hero_cta_text}</span>
</div>
</a>
{:else if primaryDownload}
<a href={primaryDownload.file_url} class="btn-hero-primary" download>
<Download size={20} />
<div class="cta-text-group">
<span class="cta-main">{config.hero_cta_text}</span>
<span class="cta-main">{block.options?.cta_text || config.hero_cta_text}</span>
<span class="cta-sub">for {primaryDownload.label} ({formatBytes(primaryDownload.size)})</span>
</div>
</a>
@@ -190,18 +197,18 @@
<a href={config.external_download_url} target="_blank" class="btn-hero-primary">
<Download size={20} />
<div class="cta-text-group">
<span class="cta-main">{config.hero_cta_text}</span>
<span class="cta-main">{block.options?.cta_text || config.hero_cta_text}</span>
<span class="cta-sub">Download Latest Release</span>
</div>
</a>
{:else}
<button type="button" class="btn-hero-primary" onclick={() => scrollToSection('download')}>
<Download size={20} />
<span class="cta-main">{config.hero_cta_text}</span>
<span class="cta-main">{block.options?.cta_text || config.hero_cta_text}</span>
</button>
{/if}
{#if config.server_ip}
{#if block.options?.show_ip_copy !== false && config.server_ip}
<button class="btn-hero-secondary" onclick={() => copyIp(config?.server_ip ?? '')}>
{#if copied}<Check size={18} /> Copied Server IP{:else}<Copy size={18} /> Copy Server IP{/if}
</button>
@@ -217,9 +224,12 @@
<div class="section-head">
<h2>{block.title || 'Get the Launcher'}</h2>
<p class="muted">{block.subtitle || 'Custom modpack synchronisation, fast Java auto-updates, and HD skin wardrobe.'}</p>
{#if block.options?.badge_note}
<div class="badge-note-pill">{block.options.badge_note}</div>
{/if}
</div>
<div class="downloads-cards-grid">
<div class="downloads-cards-grid" class:compact-list={block.options?.layout === 'compact'}>
{#each config.hosted_downloads as d}
<div class="download-card" class:recommended={d.platform === detectedOS}>
{#if d.platform === detectedOS}
@@ -260,16 +270,16 @@
<p class="muted">{block.subtitle || 'Connect to our high-performance Minecraft worlds.'}</p>
</div>
{#if publicServers.length}
{#if publicServers.filter((s) => (block.options?.show_offline === false ? s.online : true)).length}
<div class="servers-grid">
{#each publicServers as s}
{#each publicServers.filter((s) => (block.options?.show_offline === false ? s.online : true)) as s}
<div class="server-card">
<div class="server-card-top">
<div class="server-status-pill" class:online={s.online}>
<span class="dot"></span>
<span>{s.online ? `${s.players_online} / ${s.players_max} Online` : 'Offline'}</span>
</div>
{#if s.mc_version}
{#if block.options?.show_badges !== false && s.mc_version}
<span class="mc-ver-tag tiny">{s.mc_version}</span>
{/if}
</div>
@@ -277,7 +287,7 @@
<h3 class="server-card-title">{s.name}</h3>
<div class="server-card-bottom">
<button class="server-copy-btn" onclick={() => copyIp(config?.server_ip ?? '')}>
<span>{config?.server_ip || 'play.server.com'}</span>
<span>{block.options?.cta_label || config?.server_ip || 'play.server.com'}</span>
<Copy size={13} />
</button>
</div>
@@ -442,22 +452,34 @@
</div>
<div class="stats-counter-grid">
<div class="counter-card">
<span class="counter-num">{formatNumber(totalPlayers)}</span>
<span class="counter-label">Total Players</span>
</div>
<div class="counter-card">
<span class="counter-num">{formatTime(totalPlaytime)}</span>
<span class="counter-label">Time Explored</span>
</div>
{#if block.options?.show_players !== false}
<div class="counter-card">
<span class="counter-num">{formatNumber(totalPlayers)}</span>
<span class="counter-label">Total Players</span>
</div>
{/if}
{#if block.options?.show_playtime !== false}
<div class="counter-card">
<span class="counter-num">{formatTime(totalPlaytime)}</span>
<span class="counter-label">Time Explored</span>
</div>
{/if}
{#if block.options?.show_guilds !== false && publicGuilds.length > 0}
<div class="counter-card">
<span class="counter-num">{publicGuilds.length}</span>
<span class="counter-label">Active Guilds</span>
</div>
{/if}
<div class="counter-card">
<span class="counter-num">{publicServers.length}</span>
<span class="counter-label">Connected Servers</span>
</div>
<div class="counter-card">
<span class="counter-num">{instances.length}</span>
<span class="counter-label">Modpack Instances</span>
</div>
{#if block.options?.custom_stat1_label && block.options?.custom_stat1_value}
<div class="counter-card">
<span class="counter-num">{block.options.custom_stat1_value}</span>
<span class="counter-label">{block.options.custom_stat1_label}</span>
</div>
{/if}
</div>
</div>
</section>
@@ -542,6 +564,40 @@
</div>
</div>
</section>
{:else if block.type === 'socials'}
<!-- Socials Block -->
<section class="section" id="socials">
<div class="container">
<div class="section-head">
<h2>{block.title || 'Join Our Community'}</h2>
<p class="muted">{block.subtitle || 'Connect with players, join our Discord, and follow news.'}</p>
</div>
<div class="socials-buttons-grid">
{#if block.options?.discord_url}
<a href={block.options.discord_url} target="_blank" rel="noreferrer" class="social-btn discord">
<MessageSquare size={18} /> Join our Discord
</a>
{/if}
{#if block.options?.store_url}
<a href={block.options.store_url} target="_blank" rel="noreferrer" class="social-btn store">
<Sparkles size={18} /> Visit Webstore
</a>
{/if}
{#if block.options?.media_url}
<a href={block.options.media_url} target="_blank" rel="noreferrer" class="social-btn media">
<Flame size={18} /> YouTube / Twitch
</a>
{/if}
{#if block.options?.social_url}
<a href={block.options.social_url} target="_blank" rel="noreferrer" class="social-btn twitter">
<ExternalLink size={18} /> Follow on Twitter / X
</a>
{/if}
</div>
</div>
</section>
{/if}
{/each}
{/if}
@@ -670,6 +726,15 @@
.footer { border-top: 1px solid rgba(255, 255, 255, 0.08); padding: 40px 0; margin-top: auto; }
.footer-content { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 16px; }
.empty-state-box { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 40px; }
.badge-note-pill { display: inline-flex; align-items: center; padding: 4px 12px; border-radius: 99rem; background: rgba(109, 106, 245, 0.15); color: #a5a3ff; font-size: 13px; font-weight: 600; margin-top: 10px; }
.downloads-cards-grid.compact-list { grid-template-columns: 1fr; }
.socials-buttons-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; margin-top: 24px; }
.social-btn { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 16px 20px; border-radius: 12px; font-weight: 600; text-decoration: none; transition: transform 0.15s, opacity 0.15s; color: #fff; font-size: 15px; }
.social-btn:hover { transform: translateY(-2px); opacity: 0.95; }
.social-btn.discord { background: #5865F2; }
.social-btn.store { background: #8b5cf6; }
.social-btn.media { background: #ef4444; }
.social-btn.twitter { background: #0284c7; }
@media (max-width: 768px) {
.nav-links { display: none; }
.hero-title { font-size: 34px; }