diff --git a/scripts/indexnow.mjs b/scripts/indexnow.mjs index 1139650..06cc26d 100644 --- a/scripts/indexnow.mjs +++ b/scripts/indexnow.mjs @@ -12,14 +12,19 @@ if (!key) { } const host = "unblocked-games.vercel.app"; +const locs = (xml) => + [...xml.matchAll(/([^<]+)<\/loc>/g)].map((m) => m[1]); let urls = []; try { - const xml = readFileSync("dist/sitemap.xml", "utf8"); - urls = [...xml.matchAll(/([^<]+)<\/loc>/g)] - .map((m) => m[1]) - .slice(0, 10000); + // ponytail: astro emits sitemap-index.xml + sitemap-N.xml, never sitemap.xml + const index = readFileSync("dist/sitemap-index.xml", "utf8"); + const children = locs(index).map((u) => u.split("/").pop()); + for (const file of children) { + urls.push(...locs(readFileSync(`dist/${file}`, "utf8"))); + } + urls = urls.slice(0, 10000); } catch { - console.log("IndexNow: dist/sitemap.xml not found, run build first."); + console.log("IndexNow: dist/sitemap-index.xml not found, run build first."); process.exit(1); } diff --git a/src/components/flash.astro b/src/components/flash.astro index 1ccd4e6..bf4d170 100644 --- a/src/components/flash.astro +++ b/src/components/flash.astro @@ -83,6 +83,9 @@ const { gamePath } = Astro.props; var headerOffset = isFs ? 56 : 120; var maxW = isFs ? vw : Math.min(vw - pad * 2, 1040); var maxH = vh - headerOffset - pad * 2; + // ponytail: clamp so short viewports never yield negative px sizes + maxW = Math.max(200, maxW); + maxH = Math.max(200, maxH); var w = maxW; var h = w / ASPECT_RATIO; if (h > maxH) { @@ -114,6 +117,10 @@ const { gamePath } = Astro.props; function ready() { if (destroyed) return; // ponytail: fail fast on script 404/offline, keep polling for slow networks + if (!GAME_PATH) { + showError("Game not available."); + return; + } if (window.__ruffleFailed) { showError("Failed to load Flash player. Please refresh the page."); return; diff --git a/src/layout/layout.astro b/src/layout/layout.astro index d72c775..3a65c54 100644 --- a/src/layout/layout.astro +++ b/src/layout/layout.astro @@ -47,10 +47,12 @@ const gameYear = seo?.year || ""; const pageUrl = slug ? `${siteUrl}/games/${slug}` : siteUrl; // More Games cross-linking — same genre first, then fill from popular -// ponytail: two passes over defaultGames, no new data structures +// ponytail: two passes over knownGames, no new data structures +// ponytail: drop unknown slugs so one stale entry can't crash every page +const knownGames = defaultGames.filter((s) => gamesMap[s]); const moreGames = (() => { - if (!slug || !seo) return defaultGames.slice(0, MORE_GAMES_COUNT); - const rest = defaultGames.filter((s) => s !== slug); + if (!slug || !seo) return knownGames.slice(0, MORE_GAMES_COUNT); + const rest = knownGames.filter((s) => s !== slug); return [ ...rest.filter((s) => gamesMap[s].genre === seo.genre), ...rest.filter((s) => gamesMap[s].genre !== seo.genre), @@ -346,7 +348,7 @@ const moreGames = (() => { sync(); })(); -