SoCal, the whole bay, a moon, and gates that actually run
Six agents in parallel, and the two city packs independently reported the same blocker: `focusRegions` and `coarseFactor` existed on the `City` type and nothing implemented them. Uniform lattices would have been 2.9M points for Southern California and 3.7M for the expanded bay. Both packs were unloadable as written. `buildAxis` is the answer, and it is honest about its limits: refinement is per axis, not per rectangle, so a focus region sharpens its whole row *and* its whole column. Two regions at opposite corners refine nearly everything between them. Measured, not guessed — the bay went 0.53M points with one region and 1.64M with three, for detail nobody is looking at from a board this wide. One region each, coarse factor ten, and the builds land at 3.8 s and 2.3 s. Then three things that were only ever right because San Francisco was the only city. `maxDistance: 340` and a 170-unit shadow box were constants tuned for a 230-unit board; the bay is 1003 units across and the camera physically could not retreat far enough to frame it. Fog distances were scene units pinned to the same assumption. And `minVisibilityM` defaulted to 4.5 km of honest weather, which over ninety-four kilometres of bay correctly hides three quarters of it — the night view was a black rectangle for a completely reasonable reason. All three now derive from the board. The moon is a real ephemeris and its light is a deliberate lie: 1.15, against a physical ratio of one to four hundred thousand. What is being reproduced is what a moonlit night looks like on a screen in a lit room. The CI gate caught itself, which is the part worth keeping. Port 8431 was already held by a server from an earlier session, so the boot check polled a healthy stranger while the process it started died on EADDRINUSE. It now refuses to run rather than pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="robots" content="noindex" />
|
||||
<title>Sign in — Lumbridge Simulate</title>
|
||||
<style>
|
||||
/* The same stack index.html uses. No webfont, no CDN, nothing to fetch:
|
||||
this page has to work on a box with no network but its own. */
|
||||
* { box-sizing: border-box; }
|
||||
html, body { margin: 0; height: 100%; background: #0d1219;
|
||||
font-family: ui-monospace, "SF Mono", Menlo, monospace; color: rgba(255,255,255,0.72); }
|
||||
body { display: flex; align-items: center; justify-content: center; padding: 1rem; }
|
||||
main { width: 20rem; }
|
||||
h1 { margin: 0; font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase;
|
||||
color: #f2b134; }
|
||||
h1 + p { margin: 0.15rem 0 1.1rem; font-size: 11px; line-height: 1.5;
|
||||
color: rgba(255,255,255,0.42); }
|
||||
form { display: flex; flex-direction: column; gap: 0.5rem;
|
||||
background: rgba(255,255,255,0.04); border-radius: 6px; padding: 0.9rem; }
|
||||
label { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase;
|
||||
color: rgba(255,255,255,0.42); }
|
||||
input { font: inherit; font-size: 13px; padding: 0.5rem 0.6rem; border-radius: 4px;
|
||||
border: 1px solid rgba(255,255,255,0.12); background: rgba(8,12,16,0.6);
|
||||
color: rgba(255,255,255,0.9); }
|
||||
input:focus { outline: none; border-color: #f2b134; }
|
||||
button { font: inherit; font-size: 12px; font-weight: 600; margin-top: 0.35rem;
|
||||
padding: 0.55rem 0.7rem; cursor: pointer; border: 0; border-radius: 6px;
|
||||
color: #10161d; background: #f2b134; }
|
||||
button:hover:enabled { background: #ffc555; }
|
||||
button:disabled { opacity: 0.55; cursor: default; }
|
||||
#note { min-height: 1.4rem; margin: 0.6rem 0 0; font-size: 11px; line-height: 1.4;
|
||||
color: rgba(255,255,255,0.5); }
|
||||
#note.bad { color: #ffb4a2; }
|
||||
footer { margin-top: 0.9rem; font-size: 10px; color: rgba(255,255,255,0.25); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1>Lumbridge Simulate</h1>
|
||||
<p>Tera · sign in to reach a private office.</p>
|
||||
|
||||
<form id="form" autocomplete="on">
|
||||
<label for="username">Username</label>
|
||||
<input id="username" name="username" type="text" autocomplete="username" required
|
||||
autocapitalize="none" autocorrect="off" spellcheck="false" />
|
||||
|
||||
<label for="password">Password</label>
|
||||
<input id="password" name="password" type="password" autocomplete="current-password"
|
||||
required />
|
||||
|
||||
<button id="submit" type="submit">Sign in</button>
|
||||
</form>
|
||||
|
||||
<p id="note" role="status" aria-live="polite"></p>
|
||||
<footer>The session is a cookie this server signs. Nothing leaves the box.</footer>
|
||||
</main>
|
||||
|
||||
<script type="module">
|
||||
const form = document.getElementById("form");
|
||||
const submit = document.getElementById("submit");
|
||||
const note = document.getElementById("note");
|
||||
|
||||
function say(text, bad) {
|
||||
note.textContent = text;
|
||||
note.classList.toggle("bad", bad === true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Where to go once the cookie is set. `?next=` is honoured only when it is
|
||||
* a path on this origin — a redirect target taken from a query string is
|
||||
* how a sign-in page becomes somebody else's phishing hop. A leading `//`
|
||||
* is a protocol-relative URL to another host, which is exactly the case a
|
||||
* `startsWith("/")` check on its own would wave through.
|
||||
*/
|
||||
function destination() {
|
||||
const next = new URLSearchParams(location.search).get("next");
|
||||
if (typeof next !== "string") return "/";
|
||||
if (!next.startsWith("/") || next.startsWith("//")) return "/";
|
||||
return next;
|
||||
}
|
||||
|
||||
// If the cookie is already good, there is nothing to ask for. This also
|
||||
// tells us whether this deployment can sign anyone in at all.
|
||||
try {
|
||||
const res = await fetch("/api/v1/session", { credentials: "same-origin" });
|
||||
const state = res.ok ? await res.json() : null;
|
||||
if (state?.authenticated === true) {
|
||||
location.replace(destination());
|
||||
} else if (state !== null && state.passwordLogin !== true) {
|
||||
form.hidden = true;
|
||||
say("This deployment does not sign people in here.");
|
||||
}
|
||||
} catch {
|
||||
// An unreachable API is not a reason to hide the form; the submit below
|
||||
// will produce a better message than a guess made before anyone typed.
|
||||
}
|
||||
|
||||
form.addEventListener("submit", async (event) => {
|
||||
event.preventDefault();
|
||||
submit.disabled = true;
|
||||
say("Checking…");
|
||||
|
||||
try {
|
||||
const res = await fetch("/api/v1/session", {
|
||||
method: "POST",
|
||||
credentials: "same-origin",
|
||||
headers: { "content-type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
username: form.username.value,
|
||||
password: form.password.value,
|
||||
}),
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
// The token is in an HttpOnly cookie and this page never sees it,
|
||||
// which is the point: a script that can read the session is a
|
||||
// script that can walk off with it.
|
||||
say("Signed in. Taking you back…");
|
||||
location.replace(destination());
|
||||
return;
|
||||
}
|
||||
|
||||
form.password.value = "";
|
||||
if (res.status === 429) {
|
||||
const wait = Number(res.headers.get("retry-after"));
|
||||
say(
|
||||
Number.isFinite(wait) && wait > 0
|
||||
? `Too many attempts. Try again in ${wait} seconds.`
|
||||
: "Too many attempts. Try again shortly.",
|
||||
true,
|
||||
);
|
||||
} else {
|
||||
// Deliberately the server's single message: it does not distinguish
|
||||
// a wrong password from a username that does not exist, and neither
|
||||
// does this page.
|
||||
say("Those credentials were not accepted.", true);
|
||||
}
|
||||
} catch {
|
||||
say("Could not reach the server.", true);
|
||||
} finally {
|
||||
submit.disabled = false;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user