diff options
| author | sillylaird <sillyfanboy@gmail.com> | 2026-09-03 00:33:59 +0000 |
|---|---|---|
| committer | sillylaird <sillyfanboy@gmail.com> | 2026-09-03 00:33:59 +0000 |
| commit | 898b52edcb47bcb3e9d6106e74ca73e74ea01e70 (patch) | |
| tree | 85c6ee5ad58b860144551184d4cf86b560c62b91 /gaming/runescape | |
| download | www-main.tar.gz www-main.zip | |
Diffstat (limited to '')
| -rw-r--r-- | gaming/runescape/_lib.php | 182 | ||||
| -rw-r--r-- | gaming/runescape/data.json | 95 | ||||
| -rw-r--r-- | gaming/runescape/index.php | 139 | ||||
| -rw-r--r-- | gaming/runescape/index_jp.php | 66 | ||||
| -rw-r--r-- | gaming/runescape/index_zh.php | 66 | ||||
| -rw-r--r-- | gaming/runescape/runescape.png | bin | 0 -> 206939 bytes |
6 files changed, 548 insertions, 0 deletions
diff --git a/gaming/runescape/_lib.php b/gaming/runescape/_lib.php new file mode 100644 index 0000000..c8fbbab --- /dev/null +++ b/gaming/runescape/_lib.php @@ -0,0 +1,182 @@ +<?php +// Shared read-only helpers for the /gaming/runescape/ page. +// Data is edited via /admin.php?section=runescape; this file just renders it. + +function runescape_valid_url_or_path(string $url): bool { + if ($url === '') return false; + if ($url[0] === '/') return !str_starts_with($url, '//') && !str_contains($url, "\0"); + $scheme = strtolower(parse_url($url, PHP_URL_SCHEME) ?? ''); + if (in_array($scheme, ['http', 'https', 'gemini', 'gopher'], true)) return filter_var($url, FILTER_VALIDATE_URL) !== false; + return false; +} + +function runescape_data(?string $path = null): array { + $path = $path ?? (__DIR__ . '/data.json'); + $empty = [ + 'welcome' => [], + 'screenshots' => [], + 'eras' => [], + 'links_section' => ['title' => 'Server Lists', 'disclaimer' => '', 'items' => []], + ]; + if (!is_file($path)) { + return $empty; + } + $raw = file_get_contents($path); + if ($raw === false || trim($raw) === '') { + return $empty; + } + $data = json_decode($raw, true); + if (!is_array($data)) { + return $empty; + } + $welcome = []; + foreach (($data['welcome'] ?? []) as $line) { + $line = trim((string)$line); + if ($line !== '') $welcome[] = $line; + } + $screenshots = []; + foreach (($data['screenshots'] ?? []) as $shot) { + if (!is_array($shot)) continue; + $filename = trim((string)($shot['filename'] ?? '')); + if ($filename === '' || str_contains($filename, '..') || str_contains($filename, '/')) continue; + $screenshots[] = [ + 'filename' => $filename, + 'caption' => (string)($shot['caption'] ?? ''), + ]; + } + $eras = []; + foreach (($data['eras'] ?? []) as $era) { + if (!is_array($era)) continue; + $title = trim((string)($era['title'] ?? '')); + if ($title === '') continue; + $servers = []; + foreach (($era['servers'] ?? []) as $srv) { + if (!is_array($srv)) continue; + $name = trim((string)($srv['name'] ?? '')); + if ($name === '') continue; + $url = trim((string)($srv['url'] ?? '')); + if ($url !== '' && !runescape_valid_url_or_path($url)) $url = ''; + $highlights = []; + foreach (($srv['highlights'] ?? []) as $hl) { + $hl = trim((string)$hl); + if ($hl !== '') $highlights[] = $hl; + } + $links = []; + foreach (($srv['links'] ?? []) as $lk) { + if (!is_array($lk)) continue; + $label = trim((string)($lk['label'] ?? '')); + $lurl = trim((string)($lk['url'] ?? '')); + if ($label === '' || $lurl === '' || !runescape_valid_url_or_path($lurl)) continue; + $links[] = ['label' => $label, 'url' => $lurl]; + } + $srvImage = trim((string)($srv['image'] ?? '')); + if ($srvImage !== '' && str_contains($srvImage, '..')) $srvImage = ''; + $servers[] = [ + 'id' => (string)($srv['id'] ?? ''), + 'name' => $name, + 'url' => $url, + 'featured' => !empty($srv['featured']), + 'desc' => (string)($srv['desc'] ?? ''), + 'highlights' => $highlights, + 'links' => $links, + 'image' => $srvImage, + ]; + } + $eraImage = trim((string)($era['image'] ?? '')); + if ($eraImage !== '' && str_contains($eraImage, '..')) $eraImage = ''; + $eras[] = [ + 'id' => (string)($era['id'] ?? ''), + 'title' => $title, + 'subtitle' => (string)($era['subtitle'] ?? ''), + 'image' => $eraImage, + 'servers' => $servers, + ]; + } + $linksSection = ['title' => 'Server Lists', 'disclaimer' => '', 'items' => []]; + if (is_array($data['links_section'] ?? null)) { + $ls = $data['links_section']; + $linksSection['title'] = trim((string)($ls['title'] ?? '')) ?: 'Server Lists'; + $linksSection['disclaimer'] = (string)($ls['disclaimer'] ?? ''); + foreach (($ls['items'] ?? []) as $item) { + if (!is_array($item)) continue; + $label = trim((string)($item['label'] ?? '')); + $lurl = trim((string)($item['url'] ?? '')); + if ($label === '' || $lurl === '' || !runescape_valid_url_or_path($lurl)) continue; + $linksSection['items'][] = ['label' => $label, 'url' => $lurl, 'desc' => (string)($item['desc'] ?? '')]; + } + } + return ['welcome' => $welcome, 'screenshots' => $screenshots, 'eras' => $eras, 'links_section' => $linksSection]; +} + +function runescape_screenshot_src(string $filename): string { + $filename = trim($filename); + if ($filename === '' || str_contains($filename, '..') || str_contains($filename, '/')) return ''; + return '/gaming/runescape/images/' . rawurlencode($filename); +} + +/** Public URL for an era/server image (uploaded filename, site path, or absolute URL). */ +function runescape_image_src(string $image): string { + $image = trim($image); + if ($image === '') return ''; + if (str_starts_with($image, 'http://') || str_starts_with($image, 'https://') || str_starts_with($image, '/')) { + return $image; + } + if (str_contains($image, '..') || str_contains($image, "\0")) return ''; + return '/gaming/runescape/images/' . rawurlencode(basename($image)); +} + +/** Render the Welcome list — lines like "::Label::" become bold headings, everything else is a bullet. */ +function runescape_render_welcome(array $lines): void { + $he = fn($s) => htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); + $inList = false; + foreach ($lines as $line) { + if (preg_match('/^::(.+)::$/', trim($line), $m)) { + if ($inList) { echo '</ul>'; $inList = false; } + echo '<p class="machine-title machine-title--sub">' . $he(trim($m[1])) . '</p>'; + continue; + } + if (!$inList) { echo '<ul class="contact-list">'; $inList = true; } + echo '<li>' . $he($line) . '</li>'; + } + if ($inList) echo '</ul>'; +} + +/** Render one server card (used inside an era section). */ +function runescape_render_server(array $srv): void { + $he = fn($s) => htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); + $cardClass = $srv['featured'] ? 'machine machine--notes' : 'machine'; + $img = runescape_image_src((string)($srv['image'] ?? '')); + ?> + <div class="<?= $cardClass ?>"> + <div class="<?= $img !== '' ? 'machine-row' : '' ?>"> + <?php if ($img !== ''): ?> + <img class="machine-thumb" src="<?= $he($img) ?>" alt="<?= $he($srv['name']) ?>" loading="lazy" decoding="async"> + <?php endif; ?> + <div class="machine-info<?= $img !== '' ? ' machine-facts' : '' ?>"> + <div class="machine-title"> + <?php if ($srv['url'] !== ''): ?> + <a href="<?= $he($srv['url']) ?>" target="_blank" rel="noopener noreferrer"><?= $he($srv['name']) ?></a> + <?php else: ?> + <?= $he($srv['name']) ?> + <?php endif; ?> + </div> + <?php if ($srv['desc'] !== ''): ?> + <?= nl2br($he($srv['desc'])) ?> + <?php endif; ?> + <?php if ($srv['highlights']): ?> + <ul class="contact-list"> + <?php foreach ($srv['highlights'] as $hl): ?><li><?= $he($hl) ?></li><?php endforeach; ?> + </ul> + <?php endif; ?> + <?php if ($srv['links']): ?> + <p> + <?php foreach ($srv['links'] as $i => $lk): ?> + <?= $i > 0 ? ' · ' : '' ?><a href="<?= $he($lk['url']) ?>" target="_blank" rel="noopener noreferrer"><?= $he($lk['label']) ?></a> + <?php endforeach; ?> + </p> + <?php endif; ?> + </div> + </div> + </div> + <?php +} diff --git a/gaming/runescape/data.json b/gaming/runescape/data.json new file mode 100644 index 0000000..3b81b94 --- /dev/null +++ b/gaming/runescape/data.json @@ -0,0 +1,95 @@ +{ + "welcome": [], + "screenshots": [], + "eras": [ + { + "id": "2004-lost-city", + "title": "2004 · Lost City Era", + "subtitle": "Preservation servers recreating RuneScape as it was in 2004.", + "servers": [ + { + "id": "lost-city", + "name": "Lost City", + "url": "https://2004.lostcity.rs/", + "featured": true, + "desc": "Open-source recreation of RuneScape 2 as it launched in May 2004, rebuilt from decompiled client/server code and old cache dumps rather than guesswork. Runs live, incrementally-patched revisions instead of one static snapshot.", + "highlights": [ + "Play straight in the browser, no client install required", + "Progresses through real 2004–2005 content updates over time, at the original pace", + "Active dev team, open GitHub repo, public roadmap" + ], + "links": [ + {"label": "Play", "url": "https://2004.lostcity.rs/"}, + {"label": "Website", "url": "https://lostcity.rs/"} + ] + } + ] + }, + { + "id": "other-era-servers", + "title": "Other Era Servers", + "subtitle": "", + "servers": [ + { + "id": "openrsc", + "name": "OpenRSC", + "url": "https://rsc.vet/", + "featured": false, + "desc": "Preservation of RuneScape Classic, the isometric pre-RS2 client from 2001–2003, before the switch to the 3D engine.", + "highlights": [ + "Original 2D isometric client and UI, not a reskin of a later revision", + "Slower, grindier economy typical of the Classic era", + "Small dedicated community focused on historical accuracy" + ], + "links": [] + }, + { + "id": "2006scape", + "name": "2006Scape", + "url": "https://2006scape.org/", + "featured": false, + "desc": "Targets the RS2 client roughly a year after Lost City's starting point — post-Lost City the quest, pre-Evolution of Combat.", + "highlights": [ + "Wilderness and old-style PvP still intact", + "Content built out toward the mid-2000s quest/skill lineup", + "Fan-maintained, community-driven development" + ], + "links": [] + }, + { + "id": "2009scape", + "name": "2009scape", + "url": "https://2009scape.org/", + "featured": false, + "desc": "Open-source continuation of the old RS2 client around the HD graphics upgrade era, before Evolution of Combat and the Grand Exchange changes that followed.", + "highlights": [ + "HD-era graphics with the old tick-based combat system", + "Fully open source, community forks welcome", + "Long-running project with regular content patches" + ], + "links": [] + }, + { + "id": "darkan", + "name": "Darkan", + "url": "https://darkan.org/", + "featured": false, + "desc": "Solo-developed remake targeting the 2011–2012 client, later than the other entries here and closer to modern OSRS's starting point.", + "highlights": [ + "One-person passion project, built from scratch rather than a leaked source", + "Development notes and progress posted publicly", + "Smaller playerbase, actively maintained" + ], + "links": [] + } + ] + } + ], + "links_section": { + "title": "Server Lists", + "disclaimer": "Unofficial private servers, not affiliated with Jagex Ltd.", + "items": [ + {"label": "Rune-Server", "url": "https://rune-server.org/", "desc": "private server development community"} + ] + } +} diff --git a/gaming/runescape/index.php b/gaming/runescape/index.php new file mode 100644 index 0000000..e8aacfa --- /dev/null +++ b/gaming/runescape/index.php @@ -0,0 +1,139 @@ +<?php +require_once __DIR__ . '/_lib.php'; +$rsData = runescape_data(); +?> +<!doctype html> +<html lang="en"> +<head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width,initial-scale=1" /> + <meta name="description" content="RuneScape / OSRS fan page by SillyLaird." /> + <meta property="og:title" content="RuneScape — SillyLaird" /> + <meta property="og:description" content="RuneScape / OSRS fan page by SillyLaird." /> + <meta property="og:image" content="https://www.sillylaird.ca/assets/img/lain.png" /> + <meta property="og:type" content="website" /> + <meta property="og:url" content="https://www.sillylaird.ca/gaming/runescape/" /> + <meta property="og:locale" content="en_US" /> + <meta property="og:locale:alternate" content="ja_JP" /> + <meta property="og:locale:alternate" content="zh_CN" /> + <meta name="twitter:card" content="summary_large_image" /> + <meta name="twitter:title" content="RuneScape — SillyLaird" /> + <meta property="og:description" content="RuneScape / OSRS fan page by SillyLaird." /> + <meta name="twitter:image" content="https://www.sillylaird.ca/assets/img/lain.png" /> + <link rel="canonical" href="https://www.sillylaird.ca/gaming/runescape/" /> + <link rel="alternate" hreflang="x-default" href="https://www.sillylaird.ca/gaming/runescape/" /> + <link rel="alternate" hreflang="en" href="https://www.sillylaird.ca/gaming/runescape/" /> + <link rel="alternate" hreflang="zh" href="https://www.sillylaird.ca/gaming/runescape/index_zh.php" /> + <link rel="alternate" hreflang="ja" href="https://www.sillylaird.ca/gaming/runescape/index_jp.php" /> + <title>RuneScape — SillyLaird</title> + <link rel="icon" href="https://www.sillylaird.ca/assets/img/lain.png" /> + + <link rel="stylesheet" href="/assets/css/fonts.css" /> + <link rel="stylesheet" href="/assets/css/site.css" /> + <link rel="stylesheet" href="/assets/css/skeleton.css" /> + <link rel="stylesheet" href="/assets/css/pages/computers.css" /> +</head> + +<body> + <a class="skip-link" href="#main">Skip to content</a> + <?php include '../../partials/header.php'; ?> + + <main id="main" class="wrap"> + <section aria-labelledby="rs-title"> + <h1 id="rs-title">RuneScape (OSRS)</h1> + + <nav class="colon-nav" aria-label="RuneScape page sections"> + <strong>::Servers::</strong> + <?php foreach ($rsData['eras'] as $era): ?> + <a href="#era-<?= htmlspecialchars($era['id'], ENT_QUOTES, 'UTF-8') ?>-title"><?= htmlspecialchars($era['title'], ENT_QUOTES, 'UTF-8') ?></a> | + <?php endforeach; ?> + <a href="#servers-links-title">Links</a> + <strong>::Scrapbook::</strong> + <a href="#servers-bank-title">Bank Pics</a> + <strong>::Official::</strong> + <a href="https://oldschool.runescape.wiki/" target="_blank" rel="noopener noreferrer">OSRS Wiki</a> + </nav> + + <div class="machine"> + <div class="machine-row"> + <img class="machine-thumb" src="/assets/img/runescape.png" alt="RuneScape" loading="lazy" decoding="async"> + <div class="machine-facts"> + <div class="machine-info"> + <strong>Page added:</strong> 2026-07-25<br> + <strong>Last revised:</strong> 2026-07-25 + </div> + <?php if ($rsData['welcome']): ?> + <?php runescape_render_welcome($rsData['welcome']); ?> + <?php else: ?> + <div class="machine-title machine-title--sub">Welcome</div> + <ul class="contact-list"> + <li>A small fan page / launch pad — official OSRS plus private servers, grouped by era.</li> + <li>Servers listed below are unofficial preservation projects, not affiliated with Jagex Ltd.</li> + <li>Bookmark <a href="/gaming/runescape/">/gaming/runescape/</a> directly — server hosts change over time.</li> + </ul> + <?php endif; ?> + </div> + </div> + </div> + </section> + + <?php foreach ($rsData['eras'] as $era): ?> + <section aria-labelledby="era-<?= htmlspecialchars($era['id'], ENT_QUOTES, 'UTF-8') ?>-title"> + <h2 id="era-<?= htmlspecialchars($era['id'], ENT_QUOTES, 'UTF-8') ?>-title" class="section-accent-title"><?= htmlspecialchars($era['title'], ENT_QUOTES, 'UTF-8') ?></h2> + <?php if ($era['subtitle'] !== ''): ?><p class="muted"><?= htmlspecialchars($era['subtitle'], ENT_QUOTES, 'UTF-8') ?></p><?php endif; ?> + <?php $eraImgSrc = runescape_image_src($era['image']); ?> + <?php if ($eraImgSrc !== ''): ?> + <img class="rs-era-banner" src="<?= htmlspecialchars($eraImgSrc, ENT_QUOTES, 'UTF-8') ?>" alt="<?= htmlspecialchars($era['title'], ENT_QUOTES, 'UTF-8') ?>" loading="lazy" decoding="async"> + <?php endif; ?> + + <?php foreach ($era['servers'] as $srv): ?> + <?php runescape_render_server($srv); ?> + <?php endforeach; ?> + </section> + <?php endforeach; ?> + + <!-- Screenshots are managed at /admin.php?section=runescape — placeholder-box slots + show until real ones are uploaded there; no manual editing needed. --> + <section aria-labelledby="servers-bank-title"> + <h2 id="servers-bank-title" class="section-accent-title">My Bank / Screenshots</h2> + <?php if ($rsData['screenshots']): ?> + <div class="placeholder-grid"> + <?php foreach ($rsData['screenshots'] as $shot): ?> + <figure class="rs-shot"> + <img src="<?= htmlspecialchars(runescape_screenshot_src($shot['filename']), ENT_QUOTES, 'UTF-8') ?>" + alt="<?= htmlspecialchars($shot['caption'] !== '' ? $shot['caption'] : 'RuneScape screenshot', ENT_QUOTES, 'UTF-8') ?>" + loading="lazy" decoding="async"> + <?php if ($shot['caption'] !== ''): ?> + <figcaption class="muted"><?= htmlspecialchars($shot['caption'], ENT_QUOTES, 'UTF-8') ?></figcaption> + <?php endif; ?> + </figure> + <?php endforeach; ?> + </div> + <?php else: ?> + <p class="muted">Placeholder — swap these for real bank/inventory screenshots later.</p> + <div class="placeholder-grid"> + <div class="placeholder-box">Add screenshot 1</div> + <div class="placeholder-box">Add screenshot 2</div> + <div class="placeholder-box">Add screenshot 3</div> + </div> + <?php endif; ?> + </section> + + <section aria-labelledby="servers-links-title"> + <h2 id="servers-links-title" class="section-accent-title"><?= htmlspecialchars($rsData['links_section']['title'], ENT_QUOTES, 'UTF-8') ?></h2> + <?php if ($rsData['links_section']['items']): ?> + <ul class="contact-list"> + <?php foreach ($rsData['links_section']['items'] as $item): ?> + <li><a href="<?= htmlspecialchars($item['url'], ENT_QUOTES, 'UTF-8') ?>" target="_blank" rel="noopener noreferrer"><?= htmlspecialchars($item['label'], ENT_QUOTES, 'UTF-8') ?></a><?= $item['desc'] !== '' ? ' — ' . htmlspecialchars($item['desc'], ENT_QUOTES, 'UTF-8') : '' ?></li> + <?php endforeach; ?> + </ul> + <?php endif; ?> + <?php if ($rsData['links_section']['disclaimer'] !== ''): ?> + <p class="muted"><?= htmlspecialchars($rsData['links_section']['disclaimer'], ENT_QUOTES, 'UTF-8') ?></p> + <?php endif; ?> + </section> + </main> + + <?php include '../../partials/footer.php'; ?> +</body> +</html> diff --git a/gaming/runescape/index_jp.php b/gaming/runescape/index_jp.php new file mode 100644 index 0000000..629dca9 --- /dev/null +++ b/gaming/runescape/index_jp.php @@ -0,0 +1,66 @@ +<!doctype html> +<html lang="ja"> +<head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width,initial-scale=1" /> + <meta name="description" content="RuneScape / OSRS fan page by SillyLaird." /> + <meta property="og:title" content="RuneScape — SillyLaird" /> + <meta property="og:description" content="RuneScape / OSRS fan page by SillyLaird." /> + <meta property="og:image" content="https://www.sillylaird.ca/assets/img/lain.png" /> + <meta property="og:type" content="website" /> + <meta property="og:url" content="https://www.sillylaird.ca/gaming/runescape/index_jp.php" /> + <meta property="og:locale" content="ja_JP" /> + <meta property="og:locale:alternate" content="en_US" /> + <meta property="og:locale:alternate" content="zh_CN" /> + <meta name="twitter:card" content="summary_large_image" /> + <meta name="twitter:title" content="RuneScape — SillyLaird" /> + <meta name="twitter:description" content="RuneScape / OSRS fan page by SillyLaird." /> + <meta name="twitter:image" content="https://www.sillylaird.ca/assets/img/lain.png" /> + <link rel="canonical" href="https://www.sillylaird.ca/gaming/runescape/index_jp.php" /> + <link rel="alternate" hreflang="x-default" href="https://www.sillylaird.ca/gaming/runescape/" /> + <link rel="alternate" hreflang="en" href="https://www.sillylaird.ca/gaming/runescape/" /> + <link rel="alternate" hreflang="zh" href="https://www.sillylaird.ca/gaming/runescape/index_zh.php" /> + <link rel="alternate" hreflang="ja" href="https://www.sillylaird.ca/gaming/runescape/index_jp.php" /> + <meta name="keywords" content="sillylaird, runescape, osrs, gielinor" /> + <title>RuneScape — SillyLaird</title> + <link rel="icon" href="https://www.sillylaird.ca/assets/img/lain.png" /> + + <link rel="stylesheet" href="/assets/css/fonts.css" /> + <link rel="stylesheet" href="/assets/css/site.css" /> + <link rel="stylesheet" href="/assets/css/skeleton.css" /> +</head> + +<body> + <a class="skip-link" href="#main">本文へ移動</a> + <?php include '../../partials/header.php'; ?> + + <main id="main" class="wrap"> + <section aria-labelledby="rs-title"> + <h1 id="rs-title">RuneScape (OSRS)</h1> + <p class="muted">A small fan page / launch pad.</p> + + <img + src="https://oldschool.runescape.wiki/images/thumb/Old_School_RuneScape_logo.png/1200px-Old_School_RuneScape_logo.png?d047b" + alt="Old School RuneScape Logo" + loading="lazy" + decoding="async" class="sb83d4c5326" + /> + + <p class="sd1a2ffa0b4"> + <a class="header-button" href="https://oldschool.runescape.wiki/" target="_blank" rel="noopener noreferrer">Visit OSRS Wiki</a> + </p> + </section> + + <section aria-labelledby="guides-title"> + <h2 id="guides-title">Essential Guides</h2> + <ul class="contact-list"> + <li><a href="#">Combat XP Calculator</a></li> + <li><a href="#">Quest Item Database</a></li> + <li><a href="#">Grand Exchange Tracker</a></li> + </ul> + </section> + </main> + + <?php include '../../partials/footer.php'; ?> +</body> +</html> diff --git a/gaming/runescape/index_zh.php b/gaming/runescape/index_zh.php new file mode 100644 index 0000000..a2cf16f --- /dev/null +++ b/gaming/runescape/index_zh.php @@ -0,0 +1,66 @@ +<!doctype html> +<html lang="zh"> +<head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width,initial-scale=1" /> + <meta name="description" content="RuneScape / OSRS fan page by SillyLaird." /> + <meta property="og:title" content="RuneScape — SillyLaird" /> + <meta property="og:description" content="RuneScape / OSRS fan page by SillyLaird." /> + <meta property="og:image" content="https://www.sillylaird.ca/assets/img/lain.png" /> + <meta property="og:type" content="website" /> + <meta property="og:url" content="https://www.sillylaird.ca/gaming/runescape/index_zh.php" /> + <meta property="og:locale" content="zh_CN" /> + <meta property="og:locale:alternate" content="en_US" /> + <meta property="og:locale:alternate" content="ja_JP" /> + <meta name="twitter:card" content="summary_large_image" /> + <meta name="twitter:title" content="RuneScape — SillyLaird" /> + <meta name="twitter:description" content="RuneScape / OSRS fan page by SillyLaird." /> + <meta name="twitter:image" content="https://www.sillylaird.ca/assets/img/lain.png" /> + <link rel="canonical" href="https://www.sillylaird.ca/gaming/runescape/index_zh.php" /> + <link rel="alternate" hreflang="x-default" href="https://www.sillylaird.ca/gaming/runescape/" /> + <link rel="alternate" hreflang="en" href="https://www.sillylaird.ca/gaming/runescape/" /> + <link rel="alternate" hreflang="zh" href="https://www.sillylaird.ca/gaming/runescape/index_zh.php" /> + <link rel="alternate" hreflang="ja" href="https://www.sillylaird.ca/gaming/runescape/index_jp.php" /> + <meta name="keywords" content="sillylaird, runescape, osrs, gielinor" /> + <title>RuneScape — SillyLaird</title> + <link rel="icon" href="https://www.sillylaird.ca/assets/img/lain.png" /> + + <link rel="stylesheet" href="/assets/css/fonts.css" /> + <link rel="stylesheet" href="/assets/css/site.css" /> + <link rel="stylesheet" href="/assets/css/skeleton.css" /> +</head> + +<body> + <a class="skip-link" href="#main">跳至内容</a> + <?php include '../../partials/header.php'; ?> + + <main id="main" class="wrap"> + <section aria-labelledby="rs-title"> + <h1 id="rs-title">RuneScape (OSRS)</h1> + <p class="muted">A small fan page / launch pad.</p> + + <img + src="https://oldschool.runescape.wiki/images/thumb/Old_School_RuneScape_logo.png/1200px-Old_School_RuneScape_logo.png?d047b" + alt="Old School RuneScape Logo" + loading="lazy" + decoding="async" class="sb83d4c5326" + /> + + <p class="sd1a2ffa0b4"> + <a class="header-button" href="https://oldschool.runescape.wiki/" target="_blank" rel="noopener noreferrer">Visit OSRS Wiki</a> + </p> + </section> + + <section aria-labelledby="guides-title"> + <h2 id="guides-title">Essential Guides</h2> + <ul class="contact-list"> + <li><a href="#">Combat XP Calculator</a></li> + <li><a href="#">Quest Item Database</a></li> + <li><a href="#">Grand Exchange Tracker</a></li> + </ul> + </section> + </main> + + <?php include '../../partials/footer.php'; ?> +</body> +</html> diff --git a/gaming/runescape/runescape.png b/gaming/runescape/runescape.png Binary files differnew file mode 100644 index 0000000..2eb0c44 --- /dev/null +++ b/gaming/runescape/runescape.png |
