diff --git a/site/account-ready.html b/site/account-ready.html index e74b95e..09a979d 100644 --- a/site/account-ready.html +++ b/site/account-ready.html @@ -24,7 +24,7 @@ - Connection GuideLeaderboardsDropsBestiaryAccount + Connection GuideLeaderboardsDropsBestiaryAccount diff --git a/site/account-unverified.html b/site/account-unverified.html index ab1ac0a..b0f4043 100644 --- a/site/account-unverified.html +++ b/site/account-unverified.html @@ -30,7 +30,7 @@ - Connection Guide + Connection Guide Leaderboards Drops Bestiary diff --git a/site/account.html b/site/account.html index d54d084..c192ff6 100644 --- a/site/account.html +++ b/site/account.html @@ -28,7 +28,7 @@ - Connection Guide + Connection Guide Leaderboards Drops Bestiary diff --git a/site/bestiary.html b/site/bestiary.html index df684e6..2cec262 100644 --- a/site/bestiary.html +++ b/site/bestiary.html @@ -24,7 +24,7 @@ - Connection GuideLeaderboardsDropsBestiaryAccount + Connection GuideLeaderboardsDropsBestiaryAccount diff --git a/site/docs/guide/connection/common-problems.md b/site/docs/guide/connection/common-problems.md new file mode 100644 index 0000000..f2967d0 --- /dev/null +++ b/site/docs/guide/connection/common-problems.md @@ -0,0 +1,24 @@ +# Common Problems + +Common connection and setup problems. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/connection/dreamcast/flycast-bba.md b/site/docs/guide/connection/dreamcast/flycast-bba.md new file mode 100644 index 0000000..cc59d15 --- /dev/null +++ b/site/docs/guide/connection/dreamcast/flycast-bba.md @@ -0,0 +1,24 @@ +# Flycast BBA + +Connect Flycast using the broadband adapter style setup. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/connection/dreamcast/flycast-dialup.md b/site/docs/guide/connection/dreamcast/flycast-dialup.md new file mode 100644 index 0000000..c0e1502 --- /dev/null +++ b/site/docs/guide/connection/dreamcast/flycast-dialup.md @@ -0,0 +1,24 @@ +# Flycast Dialup + +Connect Flycast using the dialup/modem style setup. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/connection/dreamcast/hardware.md b/site/docs/guide/connection/dreamcast/hardware.md new file mode 100644 index 0000000..5c4f148 --- /dev/null +++ b/site/docs/guide/connection/dreamcast/hardware.md @@ -0,0 +1,48 @@ +# V2 - Dreamcast + +Most Dreamcast PSO V2 versions can likely connect. PSO Peeps officially supports: + + Version 2 Final Revision US + +This support statement includes PSO Peeps patches; patches are built and tested against that version. Direct support for Version 2 Final Revision JP is planned. + +## Network settings + +Use the PSO Peeps server address: + + 65.21.79.231 (EU) + 108.175.11.140 (US) + +--- + +## What you need + +- A real Dreamcast +- A normal retail PSO Ver.2 disc +- A working Dreamcast online setup, such as DreamPi or another working modem/BBA setup + +## Retail disc + DNS method + +Some Dreamcast setups can connect with a normal retail PSO Ver.2 disc by setting the Dreamcast DNS server to PSO Peeps. + +Set the Dreamcast DNS to: + + Primary DNS: 65.21.79.231 (EU) or 108.175.11.140 (US) + Secondary DNS: 0.0.0.0 / blank / your normal fallback DNS + +Use automatic IP settings unless your Dreamcast network setup requires manual values. + +## Steps + +1. Confirm your Dreamcast online setup works. +2. Boot the normal retail PSO Ver.2 disc. +3. Open the Dreamcast/PSO network settings. +4. Set the primary DNS to: + + 65.21.79.231 (EU) or 108.175.11.140 (US) + +5. Save the network settings. +6. Select your character. +7. Choose **Online Game**. +8. Connect to PSO Peeps. +9. Select the PSO Peeps ship/destination. diff --git a/site/docs/guide/connection/gamecube/dolphin.md b/site/docs/guide/connection/gamecube/dolphin.md new file mode 100644 index 0000000..49d896d --- /dev/null +++ b/site/docs/guide/connection/gamecube/dolphin.md @@ -0,0 +1,24 @@ +# Dolphin + +Connect through Dolphin. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/connection/gamecube/hardware-bba.md b/site/docs/guide/connection/gamecube/hardware-bba.md new file mode 100644 index 0000000..38191c8 --- /dev/null +++ b/site/docs/guide/connection/gamecube/hardware-bba.md @@ -0,0 +1,24 @@ +# GameCube Hardware BBA + +Connect a real GameCube using a broadband adapter. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/connection/gamecube/nintendont.md b/site/docs/guide/connection/gamecube/nintendont.md new file mode 100644 index 0000000..b06a165 --- /dev/null +++ b/site/docs/guide/connection/gamecube/nintendont.md @@ -0,0 +1,24 @@ +# Nintendont + +Connect through Nintendont. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/connection/overview.md b/site/docs/guide/connection/overview.md new file mode 100644 index 0000000..14ab829 --- /dev/null +++ b/site/docs/guide/connection/overview.md @@ -0,0 +1,54 @@ +# Connection Guide + +This guide explains how to connect to PSO Peeps Online Live from Dreamcast, GameCube, PC V2, Blue Burst, Flycast, Dolphin, and Nintendont. Android via Winlator is on the roadmap and has its own section. + +## Server addresses + +- **US Server:** `108.175.11.140` +- **EU Server:** `65.21.79.231` + +Characters on US and EU servers cannot play together. However, you can easily switch servers by updating your DNS settings for your client or console and retain your saves for V2 and V3 if you ever need to. + +## Main supported versions + +- Dreamcast PSO Ver.2 +- PC PSO Ver.2 +- GameCube Episode I & II +- GameCube Episode III +- Blue Burst + +PSO Peeps supports crossplay between supported client versions. Some features and behavior can differ by client version because Dreamcast V2, PC V2, GameCube, Episode III, and Blue Burst are not identical games. See the Crossplay sections for more. + +--- + +## Before you start + +Do not use a client that is still configured for Sylverant, Schtserv, Ephinea, Ultima, or another server. + +Do not publicly post your serial number, access key, guild card, or account credentials. + +## Supported discs and clients + +PSO Peeps officially supports the following versions for direct support: + + Dreamcast - Version 2 Final Revision US + PC - Version 2 with our patched exe files tracked by the PC patch server + GameCube - V1.2 Plus US + Blue Burst - Tethella Ver12513_Multi with our patched exe files tracked by the BB patch server + +All PSO discs and clients are supported for connection to PSO Peeps. We cannot offer direct support on versions outside the list above. + +If you are using a pre-patched disc from another server, such as Sylverant, Schtserv, Ephinea, or Ultima, we cannot support issues related to that disc. We can only support issues related to our own patches. Convert to the PSO Peeps client or disc before requesting support. + +If an issue is specific to newserv, Sylverant Patcher, or services like Nintendont, refer to those services and communities to open issues or get help. + +## Reporting connection issues + +If you are reporting a connection issue, always include: + + Game version: + Hardware/emulator: + Client/disc used: + Ship selected: + Approximate time of the issue: + What happened: diff --git a/site/docs/guide/connection/pc/blue-burst-linux.md b/site/docs/guide/connection/pc/blue-burst-linux.md new file mode 100644 index 0000000..3831edf --- /dev/null +++ b/site/docs/guide/connection/pc/blue-burst-linux.md @@ -0,0 +1,24 @@ +# Blue Burst on Linux + +Connect the Blue Burst client on Linux. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/connection/pc/blue-burst-windows.md b/site/docs/guide/connection/pc/blue-burst-windows.md new file mode 100644 index 0000000..ff41223 --- /dev/null +++ b/site/docs/guide/connection/pc/blue-burst-windows.md @@ -0,0 +1,24 @@ +# Blue Burst on Windows + +Connect the Blue Burst client on Windows. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/connection/pc/pc-linux.md b/site/docs/guide/connection/pc/pc-linux.md new file mode 100644 index 0000000..1a4bb2e --- /dev/null +++ b/site/docs/guide/connection/pc/pc-linux.md @@ -0,0 +1,24 @@ +# PSO PC on Linux + +Connect the original PSO PC client on Linux. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/connection/pc/pc-windows.md b/site/docs/guide/connection/pc/pc-windows.md new file mode 100644 index 0000000..a58067a --- /dev/null +++ b/site/docs/guide/connection/pc/pc-windows.md @@ -0,0 +1,24 @@ +# PSO PC on Windows + +Connect the original PSO PC client on Windows. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/connection/phantasy-star-portable.md b/site/docs/guide/connection/phantasy-star-portable.md new file mode 100644 index 0000000..427a275 --- /dev/null +++ b/site/docs/guide/connection/phantasy-star-portable.md @@ -0,0 +1,24 @@ +# Phantasy Star Portable + +Phantasy Star Portable connection notes. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/connection/quick-reference.md b/site/docs/guide/connection/quick-reference.md new file mode 100644 index 0000000..053c42e --- /dev/null +++ b/site/docs/guide/connection/quick-reference.md @@ -0,0 +1,22 @@ +# Quick Reference + +Fast connection reference for PSO Peeps. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Guide sections + +- Dreamcast: Hardware, Flycast Dialup, Flycast BBA +- PC: PSO PC on Windows/Linux, Blue Burst on Windows/Linux +- GameCube: Hardware BBA, Dolphin, Nintendont +- Xbox +- Phantasy Star Portable +- Server-side saves +- Common problems + +## Notes + +TODO: Add ports, DNS/proxy notes, account/key requirements, and client-specific quirks here. diff --git a/site/docs/guide/connection/server-side-saves.md b/site/docs/guide/connection/server-side-saves.md new file mode 100644 index 0000000..45325d9 --- /dev/null +++ b/site/docs/guide/connection/server-side-saves.md @@ -0,0 +1,24 @@ +# Server-side Saves + +How PSO Peeps server-side saves work. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/connection/xbox.md b/site/docs/guide/connection/xbox.md new file mode 100644 index 0000000..9cfb322 --- /dev/null +++ b/site/docs/guide/connection/xbox.md @@ -0,0 +1,24 @@ +# Xbox + +Xbox connection notes. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/hardcore/brutal-peeps.md b/site/docs/guide/hardcore/brutal-peeps.md new file mode 100644 index 0000000..d97acbb --- /dev/null +++ b/site/docs/guide/hardcore/brutal-peeps.md @@ -0,0 +1,24 @@ +# Hardcore Brutal Peeps + +Brutal Peeps information for Hardcore. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/hardcore/getting-started.md b/site/docs/guide/hardcore/getting-started.md new file mode 100644 index 0000000..7d4cfa3 --- /dev/null +++ b/site/docs/guide/hardcore/getting-started.md @@ -0,0 +1,24 @@ +# Hardcore Getting Started + +Start here for Hardcore Peeps. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/hardcore/meseta-and-bank-limits.md b/site/docs/guide/hardcore/meseta-and-bank-limits.md new file mode 100644 index 0000000..b4f89a5 --- /dev/null +++ b/site/docs/guide/hardcore/meseta-and-bank-limits.md @@ -0,0 +1,24 @@ +# Meseta and Bank Limits + +Hardcore meseta and bank limits. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/hardcore/points-system.md b/site/docs/guide/hardcore/points-system.md new file mode 100644 index 0000000..cbe247a --- /dev/null +++ b/site/docs/guide/hardcore/points-system.md @@ -0,0 +1,24 @@ +# Points System + +Hardcore points system information. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/hardcore/progression.md b/site/docs/guide/hardcore/progression.md new file mode 100644 index 0000000..e75d2f3 --- /dev/null +++ b/site/docs/guide/hardcore/progression.md @@ -0,0 +1,24 @@ +# Hardcore Progression + +Hardcore progression rules and expectations. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/peeps/brutal-peeps.md b/site/docs/guide/peeps/brutal-peeps.md new file mode 100644 index 0000000..799212b --- /dev/null +++ b/site/docs/guide/peeps/brutal-peeps.md @@ -0,0 +1,24 @@ +# Brutal Peeps + +Brutal Peeps information for normal play. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/peeps/crossplay-rooms.md b/site/docs/guide/peeps/crossplay-rooms.md new file mode 100644 index 0000000..df980ca --- /dev/null +++ b/site/docs/guide/peeps/crossplay-rooms.md @@ -0,0 +1,24 @@ +# Crossplay Rooms + +How crossplay rooms work on PSO Peeps. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/peeps/getting-started.md b/site/docs/guide/peeps/getting-started.md new file mode 100644 index 0000000..1228f54 --- /dev/null +++ b/site/docs/guide/peeps/getting-started.md @@ -0,0 +1,24 @@ +# Peeps Getting Started + +Start here for normal PSO Peeps play. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/docs/guide/peeps/xp-periods.md b/site/docs/guide/peeps/xp-periods.md new file mode 100644 index 0000000..619a2a9 --- /dev/null +++ b/site/docs/guide/peeps/xp-periods.md @@ -0,0 +1,24 @@ +# XP Periods + +XP period information for PSO Peeps. + +## Server addresses + +- US Server: `108.175.11.140` +- EU Server: `65.21.79.231` + +## Overview + +TODO: Fill in the converted guide content for this page. + +## Requirements + +TODO + +## Setup + +TODO + +## Notes + +TODO diff --git a/site/drops.html b/site/drops.html index da162e6..50c949c 100644 --- a/site/drops.html +++ b/site/drops.html @@ -24,7 +24,7 @@ - Connection GuideLeaderboardsDropsBestiaryAccount + Connection GuideLeaderboardsDropsBestiaryAccount diff --git a/site/guide.html b/site/guide.html new file mode 100644 index 0000000..05f55c3 --- /dev/null +++ b/site/guide.html @@ -0,0 +1,112 @@ + + + + + + Guide - PSO Peeps + + + + + + + + + + + + P + PSO PEEPS + + Signed in as chuudoku + + + + + + + + Connection GuideLeaderboardsDropsBestiaryAccount + + + + + Guide + + + Use this guide to connect to PSO Peeps, learn the normal Peeps setup, or review Hardcore Peeps rules and progression. + Both ships are available below. + + + + + US Server + 108.175.11.140 + + + EU Server + 65.21.79.231 + + + + + + Guide + + + + + Section + + + + + Platform + + + + + System + + + + + + + Guide content will load here. + + + + + + + + + diff --git a/site/guide.js b/site/guide.js new file mode 100644 index 0000000..f4004fd --- /dev/null +++ b/site/guide.js @@ -0,0 +1,492 @@ +(() => { + "use strict"; + + const SERVER_INFO = { + us: "108.175.11.140", + eu: "65.21.79.231", + }; + + const GUIDE_TREE = { + connection: { + label: "Connection Guide", + children: { + overview: { + label: "Overview", + doc: "docs/guide/connection/overview.md", + }, + dreamcast: { + label: "Dreamcast", + children: { + hardware: { + label: "Hardware", + doc: "docs/guide/connection/dreamcast/hardware.md", + }, + flycastDialup: { + label: "Flycast (Dialup)", + doc: "docs/guide/connection/dreamcast/flycast-dialup.md", + }, + flycastBba: { + label: "Flycast (BBA)", + doc: "docs/guide/connection/dreamcast/flycast-bba.md", + }, + }, + }, + pc: { + label: "PC", + children: { + pc: { + label: "PC", + children: { + windows: { + label: "Windows", + doc: "docs/guide/connection/pc/pc-windows.md", + }, + linux: { + label: "Linux", + doc: "docs/guide/connection/pc/pc-linux.md", + }, + }, + }, + blueBurst: { + label: "Blue Burst", + children: { + windows: { + label: "Windows", + doc: "docs/guide/connection/pc/blue-burst-windows.md", + }, + linux: { + label: "Linux", + doc: "docs/guide/connection/pc/blue-burst-linux.md", + }, + }, + }, + }, + }, + gamecube: { + label: "GameCube", + children: { + hardwareBba: { + label: "Hardware (BBA)", + doc: "docs/guide/connection/gamecube/hardware-bba.md", + }, + dolphin: { + label: "Dolphin", + doc: "docs/guide/connection/gamecube/dolphin.md", + }, + nintendont: { + label: "Nintendont", + doc: "docs/guide/connection/gamecube/nintendont.md", + }, + }, + }, + xbox: { + label: "Xbox", + doc: "docs/guide/connection/xbox.md", + }, + psp: { + label: "Phantasy Star Portable", + doc: "docs/guide/connection/phantasy-star-portable.md", + }, + serverSideSaves: { + label: "Server-side saves", + doc: "docs/guide/connection/server-side-saves.md", + }, + commonProblems: { + label: "Common problems", + doc: "docs/guide/connection/common-problems.md", + }, + quickReference: { + label: "Quick reference", + doc: "docs/guide/connection/quick-reference.md", + }, + }, + }, + peeps: { + label: "Peeps Guide", + children: { + gettingStarted: { + label: "Getting Started", + doc: "docs/guide/peeps/getting-started.md", + }, + crossplayRooms: { + label: "Crossplay Rooms", + doc: "docs/guide/peeps/crossplay-rooms.md", + }, + xpPeriods: { + label: "XP Periods", + doc: "docs/guide/peeps/xp-periods.md", + }, + brutalPeeps: { + label: "Brutal Peeps", + doc: "docs/guide/peeps/brutal-peeps.md", + }, + }, + }, + hardcore: { + label: "Hardcore Peeps Guide", + children: { + gettingStarted: { + label: "Getting Started", + doc: "docs/guide/hardcore/getting-started.md", + }, + progression: { + label: "Progression", + doc: "docs/guide/hardcore/progression.md", + }, + mesetaAndBankLimits: { + label: "Meseta and Bank Limits", + doc: "docs/guide/hardcore/meseta-and-bank-limits.md", + }, + pointsSystem: { + label: "Points System", + doc: "docs/guide/hardcore/points-system.md", + }, + brutalPeeps: { + label: "Brutal Peeps", + doc: "docs/guide/hardcore/brutal-peeps.md", + }, + }, + }, + }; + + const qs = (sel) => document.querySelector(sel); + const selects = [ + qs("#guide-level-0"), + qs("#guide-level-1"), + qs("#guide-level-2"), + qs("#guide-level-3"), + ]; + const wrappers = [ + null, + qs("#guide-level-1-wrap"), + qs("#guide-level-2-wrap"), + qs("#guide-level-3-wrap"), + ]; + const labels = [ + null, + qs('label[for="guide-level-1"]'), + qs('label[for="guide-level-2"]'), + qs('label[for="guide-level-3"]'), + ]; + const box = qs("#guide-content"); + + let pendingPath = null; + let loadingPath = ""; + const mdCache = new Map(); + + function esc(value) { + return String(value ?? "") + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll('"', """) + .replaceAll("'", "'"); + } + + function nodeChildren(node) { + return node && node.children ? Object.entries(node.children) : []; + } + + function fillSelect(select, children, preferredValue) { + if (!select) return ""; + + const entries = Object.entries(children || {}); + const previous = preferredValue || select.value; + select.innerHTML = ""; + + for (const [key, child] of entries) { + const opt = document.createElement("option"); + opt.value = key; + opt.textContent = child.label; + select.appendChild(opt); + } + + if (entries.some(([key]) => key === previous)) { + select.value = previous; + } else if (entries.length) { + select.value = entries[0][0]; + } + + return select.value; + } + + function setStatus(message, kind = "") { + if (!box) return; + box.innerHTML = `${esc(message)}`; + } + + function pathLabels(path) { + let node = { children: GUIDE_TREE }; + const out = []; + + for (const key of path) { + const next = node.children?.[key]; + if (!next) break; + out.push(next.label); + node = next; + } + + return out; + } + + function safeHref(raw) { + const href = String(raw || "").trim(); + if (/^(https?:|mailto:|#|\/|\.\/|\.\.\/)/i.test(href)) return href; + if (!/^[a-z][a-z0-9+.-]*:/i.test(href)) return href; + return "#"; + } + + function inlineMarkdown(raw) { + const codeSpans = []; + let text = String(raw ?? "").replace(/`([^`]+)`/g, (_, code) => { + const token = `@@CODE${codeSpans.length}@@`; + codeSpans.push(`${esc(code)}`); + return token; + }); + + let html = esc(text); + + html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, label, href) => { + return `${label}`; + }); + + html = html + .replace(/\*\*([^*]+)\*\*/g, "$1") + .replace(/\*([^*]+)\*/g, "$1"); + + codeSpans.forEach((span, index) => { + html = html.replaceAll(`@@CODE${index}@@`, span); + }); + + return html; + } + + function renderMarkdown(markdown) { + const lines = String(markdown || "").replace(/\r\n/g, "\n").split("\n"); + const out = []; + let paragraph = []; + let list = []; + let orderedList = []; + let code = []; + let inFence = false; + const fence = String.fromCharCode(96, 96, 96); + + function flushParagraph() { + if (!paragraph.length) return; + out.push(`${inlineMarkdown(paragraph.join(" "))}`); + paragraph = []; + } + + function flushList() { + if (!list.length) return; + out.push(`${list.map((item) => `${inlineMarkdown(item)}`).join("")}`); + list = []; + } + + function flushOrderedList() { + if (!orderedList.length) return; + out.push(`${orderedList.map((item) => `${inlineMarkdown(item)}`).join("")}`); + orderedList = []; + } + + function flushCode() { + if (!code.length) return; + out.push(`${esc(code.join("\n"))}`); + code = []; + } + + function flushTextBlocks() { + flushParagraph(); + flushList(); + flushOrderedList(); + } + + for (const line of lines) { + const trimmed = line.trim(); + + if (trimmed.startsWith(fence)) { + flushTextBlocks(); + if (inFence) { + flushCode(); + inFence = false; + } else { + inFence = true; + code = []; + } + continue; + } + + if (inFence) { + code.push(line); + continue; + } + + if (/^ {4,}/.test(line)) { + flushTextBlocks(); + code.push(line.replace(/^ {4}/, "")); + continue; + } + + if (code.length && trimmed === "") { + flushCode(); + continue; + } + + if (code.length) { + flushCode(); + } + + if (!trimmed) { + flushTextBlocks(); + continue; + } + + if (/^(-{3,}|\*{3,}|_{3,})$/.test(trimmed)) { + flushTextBlocks(); + out.push(""); + continue; + } + + const heading = trimmed.match(/^(#{1,5})\s+(.+)$/); + if (heading) { + flushTextBlocks(); + const level = Math.min(heading[1].length + 1, 6); + out.push(`${inlineMarkdown(heading[2])}`); + continue; + } + + const bullet = line.match(/^\s*[-*]\s+(.+)$/); + if (bullet) { + flushParagraph(); + flushOrderedList(); + list.push(bullet[1]); + continue; + } + + const ordered = line.match(/^\s*\d+\.\s+(.+)$/); + if (ordered) { + flushParagraph(); + flushList(); + orderedList.push(ordered[1]); + continue; + } + + paragraph.push(trimmed); + } + + flushTextBlocks(); + flushCode(); + + return `${out.join("\n")}`; + } + + async function loadDoc(node, path) { + if (!node.doc) { + setStatus("Choose a guide page from the menus above."); + return; + } + + const pathKey = path.join("/"); + loadingPath = pathKey; + setStatus(`Loading ${pathLabels(path).join(" › ")}...`); + + try { + let markdown = mdCache.get(node.doc); + if (!markdown) { + const response = await fetch(node.doc, { cache: "no-cache" }); + if (!response.ok) { + throw new Error(`Unable to load ${node.doc} (${response.status})`); + } + markdown = await response.text(); + mdCache.set(node.doc, markdown); + } + + if (loadingPath !== pathKey) return; + + const breadcrumb = pathLabels(path).join(" › "); + box.innerHTML = ` + ${esc(breadcrumb)} + ${renderMarkdown(markdown)} + `; + } catch (err) { + if (loadingPath !== pathKey) return; + setStatus(err?.message || "Unable to load guide page.", "error"); + } + } + + function updateHash(path) { + const next = `#${path.join("/")}`; + if (window.location.hash !== next) { + history.replaceState(null, "", next); + } + } + + function readHashPath() { + const raw = window.location.hash.replace(/^#/, "").trim(); + if (!raw) return null; + return raw.split("/").filter(Boolean); + } + + function syncGuide(changedLevel = -1) { + if (!box || selects.some((select) => !select)) return; + + if (changedLevel >= 0) { + for (let i = changedLevel + 1; i < selects.length; i += 1) { + selects[i].value = ""; + } + } + + let node = { children: GUIDE_TREE }; + const path = []; + + for (let level = 0; level < selects.length; level += 1) { + const select = selects[level]; + + if (!node.children) { + for (let hideLevel = level; hideLevel < wrappers.length; hideLevel += 1) { + if (wrappers[hideLevel]) wrappers[hideLevel].hidden = true; + } + break; + } + + const preferred = pendingPath?.[level] || select.value; + const selected = fillSelect(select, node.children, preferred); + + if (wrappers[level]) wrappers[level].hidden = false; + + const current = node.children[selected]; + path.push(selected); + node = current; + + if (labels[level]) { + labels[level].textContent = + level === 1 && path[0] === "connection" ? "Platform" : + level === 1 ? "Topic" : + level === 2 && path[0] === "connection" && path[1] === "pc" ? "Client" : + level === 2 && path[0] === "connection" ? "Setup" : + level === 3 ? "System" : + "Option"; + } + } + + pendingPath = null; + + for (let level = 1; level < wrappers.length; level += 1) { + const parent = path.slice(0, level).reduce((cur, key) => cur?.children?.[key], { children: GUIDE_TREE }); + if (!parent?.children && wrappers[level]) wrappers[level].hidden = true; + } + + updateHash(path); + loadDoc(node, path); + } + + document.addEventListener("DOMContentLoaded", () => { + pendingPath = readHashPath(); + + selects.forEach((select, index) => { + select?.addEventListener("change", () => syncGuide(index)); + }); + + syncGuide(); + }); +})(); diff --git a/site/index.html b/site/index.html index 4c1ac1c..38908c0 100644 --- a/site/index.html +++ b/site/index.html @@ -37,7 +37,7 @@ - Connection Guide + Connection Guide Leaderboards Drops Bestiary diff --git a/site/leaderboards.html b/site/leaderboards.html index a6281c8..1fe8dc4 100644 --- a/site/leaderboards.html +++ b/site/leaderboards.html @@ -24,7 +24,7 @@ - Connection GuideLeaderboardsDropsBestiaryAccount + Connection GuideLeaderboardsDropsBestiaryAccount diff --git a/site/style.css b/site/style.css index d5eb819..5c2e027 100644 --- a/site/style.css +++ b/site/style.css @@ -1915,3 +1915,344 @@ button.inline-link, } } +/* Local guide page */ +.guide-layout { + gap: 12px; +} + +.guide-control-card { + display: block; +} + +.guide-intro { + max-width: 920px; + margin: 0 0 18px; + color: var(--muted-text); + line-height: 1.55; +} + +.guide-server-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 12px; + margin: 0 0 18px; +} + +.guide-server-card { + border: 1px solid var(--panel-border); + border-radius: 10px; + padding: 14px 16px; + background: rgba(0, 0, 0, 0.22); +} + +.guide-server-card span { + display: block; + margin-bottom: 6px; + color: var(--muted-text); + font-size: 0.72rem; + font-weight: 800; + letter-spacing: 0.12em; + text-transform: uppercase; +} + +.guide-server-card strong { + color: var(--text); + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace; + font-size: 0.95rem; +} + +.placeholder-form.guide-controls { + display: grid; + grid-template-columns: repeat(4, minmax(150px, 1fr)); + gap: 12px; + margin: 0; +} + +.guide-control { + min-width: 0; +} + +.guide-box.blank-data-box { + display: block; + min-height: 360px; + padding: 28px 32px; + text-align: left; +} + +.guide-status { + color: var(--muted-text); +} + +.guide-status--error { + color: #ffb4b4; +} + +.guide-breadcrumb { + margin-bottom: 18px; + color: var(--muted-text); + font-size: 0.78rem; + font-weight: 800; + letter-spacing: 0.08em; +} + +.guide-doc { + max-width: 880px; + margin: 0 auto; + color: var(--text); + line-height: 1.65; +} + +.guide-doc h2, +.guide-doc h3, +.guide-doc h4, +.guide-doc h5 { + margin: 1.35em 0 0.55em; + color: var(--text); +} + +.guide-doc h2:first-child { + margin-top: 0; +} + +.guide-doc p { + margin: 0 0 1em; +} + +.guide-doc ul { + margin: 0 0 1em 1.4em; + padding: 0; +} + +.guide-doc li { + margin: 0.3em 0; +} + +.guide-doc code { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace; +} + +.guide-doc pre { + overflow-x: auto; + padding: 12px; + border-radius: 10px; + background: rgba(0, 0, 0, 0.45); +} + +@media (max-width: 900px) { + .placeholder-form.guide-controls { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} + +@media (max-width: 640px) { + .guide-server-grid, + .placeholder-form.guide-controls { + grid-template-columns: 1fr; + } + + .guide-box.blank-data-box { + padding: 22px; + } +} + +/* Guide markdown readability fixes */ +.guide-box.blank-data-box { + align-items: stretch; + justify-content: flex-start; + font-size: 1rem; + font-weight: 400; + letter-spacing: normal; + text-transform: none; +} + +.guide-box .guide-breadcrumb { + text-align: left; +} + +.guide-doc { + font-weight: 400; + letter-spacing: normal; + text-transform: none; +} + +.guide-doc h2 { + font-size: 1.55rem; + font-weight: 800; +} + +.guide-doc h3 { + font-size: 1.15rem; + font-weight: 800; +} + +.guide-doc p, +.guide-doc li { + color: var(--text); + font-weight: 400; +} + +.guide-doc strong { + font-weight: 800; +} + +.guide-doc hr { + margin: 24px 0; + border: 0; + border-top: 1px solid var(--panel-border); +} + +.guide-doc pre { + margin: 12px 0 22px; + white-space: pre; +} + +.guide-doc pre code { + display: block; + color: var(--text); + font-weight: 400; + line-height: 1.45; +} + +/* Guide Markdown polish */ +.guide-box.blank-data-box { + align-items: stretch !important; + justify-content: flex-start !important; + text-align: left !important; + font-size: 1rem !important; + font-weight: 400 !important; + letter-spacing: normal !important; + text-transform: none !important; +} + +.guide-doc { + max-width: 880px; + margin: 0 auto; + color: var(--text); + line-height: 1.65; + font-size: 1rem; + font-weight: 400 !important; + letter-spacing: normal !important; + text-transform: none !important; +} + +.guide-doc h2 { + margin: 0 0 18px; + font-size: 1.8rem; + line-height: 1.2; + font-weight: 800; +} + +.guide-doc h3 { + margin: 28px 0 12px; + font-size: 1.25rem; + line-height: 1.3; + font-weight: 800; +} + +.guide-doc p { + margin: 0 0 18px; + color: var(--text); + font-weight: 400; +} + +.guide-doc ul { + margin: 0 0 20px 1.35rem; + padding: 0; +} + +.guide-doc li { + margin: 7px 0; + color: var(--text); + font-weight: 400; +} + +.guide-doc li::marker { + color: #e6adc1; +} + +.guide-doc strong { + font-weight: 800; +} + +.guide-doc hr { + margin: 28px 0; + border: 0; + border-top: 1px solid rgba(230, 173, 193, 0.25); +} + +.guide-doc pre { + display: block; + box-sizing: border-box; + width: 100%; + margin: 12px 0 24px; + padding: 16px 18px; + overflow-x: auto; + white-space: pre; + border: 1px solid rgba(230, 173, 193, 0.28); + border-radius: 10px; + background: rgba(70, 35, 48, 0.28); +} + +.guide-doc pre code { + display: block; + color: var(--text); + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace; + font-size: 0.92rem; + line-height: 1.45; + font-weight: 400; +} + +.guide-doc code { + padding: 0.08rem 0.25rem; + border: 1px solid rgba(230, 173, 193, 0.25); + border-radius: 4px; + background: rgba(70, 35, 48, 0.28); + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace; +} + +.guide-doc pre code { + padding: 0; + border: 0; + background: transparent; +} + +/* Guide Markdown neutral site-color override */ +.guide-doc li::marker { + color: var(--muted-text) !important; +} + +.guide-doc hr { + border-top-color: var(--panel-border) !important; +} + +.guide-doc pre { + border-color: var(--panel-border) !important; + background: rgba(0, 0, 0, 0.24) !important; +} + +.guide-doc code { + border-color: var(--panel-border) !important; + background: rgba(0, 0, 0, 0.24) !important; + color: var(--text) !important; +} + +.guide-doc pre code { + border: 0 !important; + background: transparent !important; + color: var(--text) !important; +} + +/* Guide ordered-list support */ +.guide-doc ol { + margin: 0 0 20px 1.35rem; + padding: 0; +} + +.guide-doc ol li { + margin: 7px 0; + padding-left: 0.25rem; +} + +.guide-doc ol li::marker { + color: var(--muted-text); +}
+ Use this guide to connect to PSO Peeps, learn the normal Peeps setup, or review Hardcore Peeps rules and progression. + Both ships are available below. +
${esc(code)}
${inlineMarkdown(paragraph.join(" "))}
${esc(code.join("\n"))}