卫戍协议:盟约 web remake — initial import

Online co-op browser remake of Arknights' Stronghold Protocol: Alliance
(client-simulated combat, official waves/bonds/items/strategies, 3D board,
facing wheel, operator loadout, official emotes, deployment scripts).
This commit is contained in:
sganggs committed 2026-09-29 16:21:31 +08:00
commit 01a44cd288
408 files changed
+308986

No files matched your search

+106
View File
@@ -0,0 +1,106 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<!-- A landscape game: no page zoom (iOS additionally needs the gesture handling of js/ui/device.js), full-bleed behind
notches (viewport-fit=cover; css/devices.css keeps the HUD inside the safe area). -->
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover" />
<meta name="theme-color" content="#0c0f0e" />
<meta name="color-scheme" content="dark" />
<meta name="format-detection" content="telephone=no" />
<!-- "Add to Home Screen" (iOS / Android) opens full screen without browser bars -->
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="卫戍协议" />
<meta name="description" content="卫戍协议:盟约 · 网页联机复刻(非官方同人作品)" />
<title>卫戍协议:盟约 · STRONGHOLD PROTOCOL</title>
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Crect width='24' height='24' fill='%230c0f0e'/%3E%3Cpath fill='%234ed8af' d='M5 3h3v2h2V3h4v2h2V3h3v5l-2 2v7l2 2v2H5v-2l2-2v-7L5 8z'/%3E%3C/svg%3E" />
<!-- Web fonts: never render-blocking (LAN/offline play must still start); system fallbacks in theme.css. -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link rel="stylesheet" media="print" onload="this.media='all'"
href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700;900&family=Oxanium:wght@400;500;600;700&family=Rajdhani:wght@500;600;700&display=swap" />
<!-- Self-hosted Bender / Novecento (provided by the assets pipeline). -->
<link rel="stylesheet" href="/fonts/fonts.css" />
<link rel="stylesheet" href="/css/theme.css" />
<link rel="stylesheet" href="/css/components.css" />
<link rel="stylesheet" href="/css/screens/title.css" />
<link rel="stylesheet" href="/css/screens/lobby.css" />
<link rel="stylesheet" href="/css/screens/room.css" />
<link rel="stylesheet" href="/css/screens/game.css" />
<link rel="stylesheet" href="/css/screens/game-shop.css" />
<link rel="stylesheet" href="/css/screens/game-panels.css" />
<link rel="stylesheet" href="/css/screens/briefing.css" />
<link rel="stylesheet" href="/css/screens/draft.css" />
<link rel="stylesheet" href="/css/screens/result.css" />
<link rel="stylesheet" href="/css/screens/guide.css" />
<link rel="stylesheet" href="/css/screens/loadout.css" />
<link rel="stylesheet" href="/css/emotes.css" />
<link rel="stylesheet" href="/css/devices.css" />
<script type="importmap">
{ "imports": { "preact": "/vendor/preact.module.js", "preact/hooks": "/vendor/hooks.module.js", "htm": "/vendor/htm.module.js" } }
</script>
<link rel="modulepreload" href="/vendor/preact.module.js" />
<link rel="modulepreload" href="/vendor/hooks.module.js" />
<link rel="modulepreload" href="/vendor/htm.module.js" />
<link rel="modulepreload" href="/js/main.js" />
<!-- Battlefield renderer libs (classic scripts, injected by js/render/app.js when a match view mounts): warm the cache
at low priority so entering the match doesn't wait on ~800 KB of script. -->
<link rel="prefetch" href="/vendor/pixi.min.js" as="script" />
<link rel="prefetch" href="/vendor/pixi-spine.js" as="script" />
</head>
<body>
<div id="app"></div>
<div id="boot" class="boot" aria-hidden="true">
<div class="boot__inner">
<div class="boot__hex"></div>
<div class="boot__text">STRONGHOLD PROTOCOL</div>
<div id="boot-err" class="boot__err"></div>
</div>
</div>
<div class="rotate-hint" role="alert">
<div class="rotate-hint__phone"></div>
<div class="rotate-hint__title">请将设备横屏</div>
<div>卫戍协议:盟约 需要横屏显示以获得完整体验</div>
<div class="rotate-hint__micro">ROTATE DEVICE</div>
</div>
<noscript><p style="color:#c3cbc7;text-align:center;padding:40px">需要启用 JavaScript 才能运行本游戏。</p></noscript>
<script>
// Boot diagnostics (plain ES5: runs everywhere). A browser too old for the app says so instead of spinning forever:
// no ES modules (nomodule below), a module graph that cannot load (e.g. import maps: Safari / iOS < 16.4), or no
// boot after 9 s.
window.__spBootFail = function (why) {
var e = document.getElementById('boot-err');
if (!e || e.getAttribute('data-final')) return;
var im = false;
try { im = !!(window.HTMLScriptElement && HTMLScriptElement.supports && HTMLScriptElement.supports('importmap')); } catch (x) { im = false; }
e.textContent = why === 'old' || !im
? '当前浏览器版本过旧,无法运行本游戏。请升级到 iOS / iPadOS 16.4+(Safari 16.4+)、Chrome / Edge 90+ 或 Firefox 108+ 后刷新。'
: '游戏脚本加载失败,请检查网络连接后刷新页面。';
e.setAttribute('data-final', '1');
};
// a module graph that fails to link (bare specifier without import-map support) reports here, not on the <script>
window.addEventListener('error', function (ev) {
var b = document.getElementById('boot');
if (!b || b.classList.contains('is-done')) return;
if (/specifier|resolve|import|module/i.test(String(ev && ev.message))) window.__spBootFail('load');
});
</script>
<script type="module" src="/js/main.js" onerror="window.__spBootFail && window.__spBootFail('load')"></script>
<script nomodule>window.__spBootFail && window.__spBootFail('old');</script>
<script>
// If modules never boot (very old browser / blocked script), explain instead of spinning forever.
setTimeout(function () {
var b = document.getElementById('boot'), e = document.getElementById('boot-err');
if (b && !b.classList.contains('is-done') && e && !e.textContent) e.textContent = '加载时间较长…如长时间无响应,请使用最新版 Chrome / Edge / Safari / Firefox 并刷新页面。';
}, 9000);
</script>
</body>
</html>