diff --git a/ASAservers.html b/ASAservers.html
index 419e2bd..574cf05 100644
--- a/ASAservers.html
+++ b/ASAservers.html
@@ -1,189 +1,610 @@
-
-
- ObliStudios · ASA Servers — Live Status
-
-
-
+
+
+ ObliStudios · ASA Servers — Live Status
+
+
+
+
+
+
-
+ html, body {
+ height: 100%
+ }
+
+ body {
+ margin: 0;
+ font: 16px/1.6 Inter,system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;
+ color: var(--text);
+ background: url('img/BestWCoast.png') no-repeat center center fixed;
+ background-size: cover;
+ }
+ /* Soft vignette */
+ body::before {
+ content: "";
+ position: fixed;
+ inset: 0;
+ background: linear-gradient( rgba(0,0,0,0.72) 0%, rgba(0,0,0,0.55) 30%, rgba(0,0,0,0.38) 60%, rgba(0,0,0,0.62) 100% );
+ z-index: -1;
+ }
+
+ a {
+ color: inherit;
+ text-decoration: none
+ }
+
+ .container {
+ max-width: 1100px;
+ margin: 0 auto;
+ padding: 0 20px
+ }
+
+ /* Header (harmonized with other pages) */
+ header {
+ position: sticky;
+ top: 0;
+ z-index: 50;
+ backdrop-filter: saturate(180%) blur(8px);
+ background: rgba(10,11,16,.6);
+ border-bottom: 1px solid var(--line);
+ }
+
+ .nav {
+ height: 68px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between
+ }
+
+ .brand {
+ display: flex;
+ gap: .65rem;
+ align-items: center
+ }
+
+ .brand svg {
+ width: 30px;
+ height: 30px;
+ filter: drop-shadow(0 0 10px rgba(16,227,154,.4))
+ }
+
+ .wordmark {
+ font-weight: 800;
+ letter-spacing: .2px
+ }
+
+ .wordmark em {
+ color: var(--accent);
+ font-style: normal
+ }
+
+ .links {
+ display: flex;
+ gap: 18px;
+ color: var(--muted);
+ font-weight: 600
+ }
+
+ .links a:hover {
+ color: var(--text)
+ }
+
+ /* Hero */
+ h1, h2 {
+ font-family: Cinzel, Inter, serif
+ }
+
+ .hero {
+ padding: 64px 0 24px;
+ }
+
+ h1 {
+ margin: .35rem 0 .4rem;
+ line-height: 1.15;
+ font-size: clamp(2rem, 1rem + 3vw, 3rem)
+ }
+
+ .lead {
+ color: var(--muted);
+ max-width: 70ch
+ }
+
+ .notice {
+ font-size: .9rem;
+ color: #cfd7e0
+ }
+
+ /* Controls bar */
+ .controls {
+ display: flex;
+ gap: 10px;
+ align-items: center;
+ flex-wrap: wrap;
+ padding: 12px;
+ margin: 8px 0 18px;
+ background: rgba(17,20,33,.75);
+ border: 1px solid rgba(255,255,255,.08);
+ border-radius: 12px;
+ backdrop-filter: blur(6px);
+ }
+
+ .controls input, .controls select, .controls button {
+ background: #0a0c12;
+ color: var(--text);
+ border: 1px solid rgba(255,255,255,.08);
+ border-radius: 10px;
+ padding: .55rem .7rem;
+ font-weight: 600;
+ }
+
+ .controls button.primary {
+ background: linear-gradient(135deg,var(--accent),var(--accent2));
+ color: #00140d;
+ border: none;
+ box-shadow: 0 8px 22px rgba(16,227,154,.25);
+ }
+
+ .controls .meta {
+ color: var(--muted);
+ font-size: .95rem;
+ margin-left: auto;
+ display: flex;
+ gap: 12px;
+ align-items: center
+ }
+
+ /* Grid & cards */
+ .grid {
+ display: grid;
+ gap: 18px
+ }
+
+ @media (min-width:760px) {
+ .grid {
+ grid-template-columns: 1fr 1fr
+ }
+ }
+
+ .server-card {
+ background: rgba(17, 20, 33, 0.85);
+ border: 1px solid rgba(255,255,255,0.12);
+ border-radius: var(--radius);
+ backdrop-filter: blur(6px);
+ padding: 14px 16px;
+ box-shadow: var(--shadow);
+ }
+
+ .server-head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ }
+
+ .pill {
+ display: inline-flex;
+ align-items: center;
+ gap: .4rem;
+ padding: .25rem .6rem;
+ border-radius: 999px;
+ font-weight: 800;
+ font-size: .8rem
+ }
+
+ .up {
+ background: #0dc07f22;
+ border: 1px solid #0dc07f66;
+ color: #b6f0dc
+ }
+
+ .down {
+ background: #ff3b3b22;
+ border: 1px solid #ff3b3b66;
+ color: #ffc9c9
+ }
+
+ .muted {
+ color: var(--muted)
+ }
+
+ .ephemeral {
+ font-size: .9rem;
+ color: var(--muted)
+ }
+
+ .row {
+ display: flex;
+ gap: 12px;
+ align-items: center;
+ flex-wrap: wrap
+ }
+
+ .copy {
+ cursor: pointer;
+ border: 1px solid var(--line);
+ border-radius: 10px;
+ padding: .35rem .55rem;
+ font-weight: 700
+ }
+
+ .kvs {
+ display: grid;
+ grid-template-columns: repeat(3,1fr);
+ gap: 8px 14px;
+ margin-top: .5rem
+ }
+
+ .kv strong {
+ display: block;
+ font-size: .9rem;
+ color: var(--muted)
+ }
+
+ .kv span {
+ font-weight: 800
+ }
+
+ /* Player capacity bar */
+ .bar {
+ height: 8px;
+ border-radius: 999px;
+ background: #0a0c12;
+ border: 1px solid rgba(255,255,255,.08);
+ overflow: hidden
+ }
+
+ .bar > i {
+ display: block;
+ height: 100%;
+ background: linear-gradient(90deg,var(--accent),var(--accent2));
+ width: 0%
+ }
+
+ /* Ping chip */
+ .ping {
+ display: inline-flex;
+ align-items: center;
+ gap: .35rem;
+ font-weight: 800
+ }
+
+ .dot {
+ width: 10px;
+ height: 10px;
+ border-radius: 50%
+ }
+
+ /* Skeletons */
+ .skeleton {
+ position: relative;
+ overflow: hidden;
+ border-radius: var(--radius);
+ background: rgba(255,255,255,.06);
+ height: 110px;
+ border: 1px solid rgba(255,255,255,.08)
+ }
+
+ .skeleton::after {
+ content: "";
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,.08), transparent);
+ transform: translateX(-100%);
+ animation: shimmer 1.4s infinite;
+ }
+
+ @keyframes shimmer {
+ 100% {
+ transform: translateX(100%)
+ }
+ }
+
+ /* Footer */
+ .footer {
+ padding: 40px 0 64px;
+ color: var(--muted);
+ border-top: 1px solid var(--line)
+ }
+
+ [hidden] {
+ display: none !important
+ }
+
-
+
-
+
+
+
ARK: Survival Ascended — Live Server Status
+
Real‑time online status, map, players, and ping for every ObliStudios ASA server.
+
This is unofficial and not affiliated with Studio Wildcard.
+
+
+
+
-
ARK: Survival Ascended — Live Server Status
-
Real‑time online status, map, players, and ping for every ObliStudios ASA server.
-
- this is unofficial and not affiliated with Studio Wildcard
-
+
+
+
+ All
+ Online
+ Offline
+
+
+ Sort: Status
+ Sort: Name A→Z
+ Sort: Players
+ Sort: Ping
+
+
Refresh
+
+ —
+ Next update: —
+
+
-
-
- Cluster Status
-
+
+ Cluster Status
+
-
- the servers are running on a best-effort basis, 24/7. occasional downtime may occur for maintenance, updates, or unexpected issues. please refer to our
discord for planned maintenance windows and updates.
-
-
+
+ The servers are running on a best‑effort basis, 24/7. Occasional downtime may occur for maintenance, updates, or unexpected issues.
+ Visit our
for planned maintenance windows and updates.
+
-
+
+
+
-
+ // === TEMPLATES ===
+ function cardTemplate(s, data, ts) {
+ const online = !!(data && data.online);
+ const pill = online
+ ? 'Online '
+ : 'Offline ';
+
+ const map = data?.map || '—';
+ const players = Number.isFinite(data?.players) ? data.players : 0;
+ const maxPlayers = Number.isFinite(data?.maxPlayers) ? data.maxPlayers : null;
+ const ping = Number.isFinite(data?.ping) ? data.ping : null;
+ const endpoint = `${s.host}:${s.port}`;
+
+ const playerBar = Number.isFinite(maxPlayers) ? `
+
+ ${pct(players, maxPlayers)}% capacity
+ ` : '';
+
+ const details = online ? `
+
+
Map ${map}
+
Players ${players}${maxPlayers ? `/${maxPlayers}` : ''}
+
Ping ${pingDot(ping)}${ping ?? '—'} ms
+
+ ${playerBar}
+ ` : `${(data && data.error) ? data.error : 'No response from query port'}
`;
+
+ return `
+
+
+
${s.name}
+ ${pill}
+
+
+
+ Query: ${endpoint}
+ Copy
+
+
+ ${details}
+
+
+ Updated ${timeAgo(ts)}
+
+
+ `;
+ }
+
+ function render() {
+ const q = document.getElementById('q').value.trim().toLowerCase();
+ const filter = document.getElementById('filter').value;
+ const sort = document.getElementById('sort').value;
+
+ let rows = state.slice();
+
+ // Filter
+ rows = rows.filter(({ s, data }) => {
+ const hay = `${s.name} ${data?.map || ''}`.toLowerCase();
+ const matchesQ = !q || hay.includes(q);
+ const online = !!data?.online;
+ const matchesF = filter === 'all' || (filter === 'online' ? online : !online);
+ return matchesQ && matchesF;
+ });
+
+ // Sort
+ const by = {
+ status: (a, b) => Number(b.data?.online || 0) - Number(a.data?.online || 0) || a.s.name.localeCompare(b.s.name),
+ name: (a, b) => a.s.name.localeCompare(b.s.name),
+ players: (a, b) => (b.data?.players || 0) - (a.data?.players || 0),
+ ping: (a, b) => (a.data?.ping ?? 1e9) - (b.data?.ping ?? 1e9),
+ }[sort] || ((a, b) => 0);
+ rows.sort(by);
+
+ // Render
+ $list.innerHTML = rows.map(r => cardTemplate(r.s, r.data, r.fetchedAt)).join('');
+
+ // Summary / meta
+ const total = state.length;
+ const onlineCount = state.filter(r => r.data?.online).length;
+ $summary.textContent = `Online ${onlineCount} / ${total} · Last update ${timeAgo(lastRefresh)}`;
+ }
+
+ // === DATA FETCH ===
+ function fetchWithTimeout(url, ms = 7000) {
+ const ctl = new AbortController();
+ const id = setTimeout(() => ctl.abort(), ms);
+ return fetch(url, { cache: 'no-store', signal: ctl.signal }).finally(() => clearTimeout(id));
+ }
+
+ async function refresh() {
+ lastRefresh = Date.now();
+ nextTick = 30;
+
+ const results = await Promise.all(SERVERS.map(async s => {
+ const url = `${API}?ip=${encodeURIComponent(s.host)}&port=${encodeURIComponent(s.port)}`;
+ try {
+ const r = await fetchWithTimeout(url, 7000);
+ const data = await r.json();
+ return { s, data, fetchedAt: Date.now() };
+ } catch (e) {
+ return { s, data: { online: false, error: String(e) }, fetchedAt: Date.now() };
+ }
+ }));
+
+ state = results;
+ // Persist last successful for offline first‑paint
+ try { localStorage.setItem('asa:last', JSON.stringify({ t: Date.now(), results })); } catch { }
+ render();
+ }
+
+ // Load cached (if present) for instant first paint
+ (function bootFromCache() {
+ try {
+ const cached = JSON.parse(localStorage.getItem('asa:last') || 'null');
+ if (cached && Array.isArray(cached.results)) {
+ state = cached.results;
+ lastRefresh = cached.t || Date.now();
+ render();
+ }
+ } catch { }
+ })();
+
+ // Polling and countdown
+ setInterval(() => {
+ if (nextTick > 0) nextTick--;
+ $next.textContent = `Next update: ${nextTick}s`;
+ if (nextTick === 0) refresh();
+ }, 1000);
+
+ // Wire controls
+ document.getElementById('q').addEventListener('input', render);
+ document.getElementById('filter').addEventListener('change', render);
+ document.getElementById('sort').addEventListener('change', render);
+ document.getElementById('refreshBtn').addEventListener('click', refresh);
+
+ // First live refresh
+ refresh();
+