Underground 2 Revived
Play Need for Speed: Underground 2 (2004) in Chrome and Firefox with WebGPU graphics, Web Audio, up to 120 fps widescreen, controller support, free roam and Online races with friends. Fan project, not
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
XAUCORE — DEMO / SYNTHETIC XAUUSD trading simulator
DEMO • SYNTHETIC DATA — no real quotes, no broker, no real accounts, no real trades.
Every price, candle, spread, commission, swap, margin figure and news event is generated by
the app itself. Nothing connects to a real market.
Deployable on Vercel with a Turso (libSQL) database and per-user cloud save: the whole
simulator freezes when you leave the site and resumes exactly where it stopped — 5 minutes,
5 hours or 5 days later, from any device you sign in on.檢視完整 README ↗DEMO • SYNTHETIC DATA — no real quotes, no broker, no real accounts, no real trades.
Every price, candle, spread, commission, swap, margin figure and news event is generated by
the app itself. Nothing connects to a real market.
Deployable on Vercel with a Turso (libSQL) database and per-user cloud save: the whole simulator freezes when you leave the site and resumes exactly where it stopped — 5 minutes, 5 hours or 5 days later, from any device you sign in on.
| Layer | Choice | Notes |
|---|---|---|
| Frontend | Single self-contained public/index.html (vanilla JS, canvas chart). Unchanged from the original project. | The whole simulator is one S object; that object is the save. Vercel serves public/ statically. |
| API | One file per route under api/ — standard Vercel serverless functions (@vercel/node, ESM). | api/health.js, api/me.js, api/state.js, api/lock.js, api/owner.js, api/auth/{register,login,logout}.js. Shared code in api/_lib/ (not routed). |
| Access gate | middleware.js (root, Node runtime) runs before every request. Enforces the "site closed" switch (README §4). Fail-open. | Logic in api/_lib/gate.js, shared with dev-server.js. |
| Database | Turso / libSQL via @libsql/client. Tables users, sessions, states. | No local file in production (Vercel's FS is read-only). Local dev falls back to file:./data/local.db automatically. |
| Auth | Email + password (scrypt) — an account is required, there is no guest mode. Opaque random session tokens, 1-year TTL, revocable. | No JWT library. |
| Sync | localStorage (per-user key xc_state_<id>) = fast cache / offline fallback. Turso = source of truth. Pushed on change (debounced), force-pushed on tab-hide, and a synchronous XHR on pagehide (the ~220 KB state exceeds sendBeacon's 64 KB limit). | Multi-device, offline-tolerant. |
day.elapsedMs, regime.ageMs) from
active wall-time only, and each frame's delta is capped to one frame — a gap of
minutes / hours / days counts as a single 60 ms step, never a leap.visibilitychange stops every timer while the tab is hidden. Nothing advances.POST /api/auth/register {email,password} -> {token,id,email}
POST /api/auth/login {email,password} -> {token,id,email}
POST /api/auth/logout (auth)
GET /api/me (auth) -> {id,email}
GET /api/state (auth) [?sid&meta=1] -> {state,updatedAt,rev,lease} meta=1 omits the blob
POST /api/state {op:"claim",sid,force} (auth) -> {granted,lease} take the driving lease
PUT /api/state {state,sid} (auth) -> {updatedAt,rev,lease} 409 if another sid holds it
also accepts ?token= (unload beacon)
GET /api/health -> {ok:true}
GET /api/lock -> {locked,configured,isOwner} (see §4)
POST /api/lock {locked} (owner cookie)
GET /api/owner -> {configured,isOwner}
POST /api/owner {key} -> Set-Cookie xc_owner
DELETE /api/owner -> clears xc_owner
Requires Node 22+. No Vercel CLI needed — dev-server.js mounts the same api/ handlers
on a plain node:http server and serves public/, exactly like Vercel does.
npm install
npm run dev
Open http://localhost:8777. The database is a local SQLite file at ./data/local.db
(created automatically) unless you set TURSO_* env vars.
npm run devalso powers the Claude Code preview (.claude/launch.json).
Optional — point local dev at the real cloud DB: copy .env.example to .env, fill in the
Turso values, and npm run dev (Node loads .env automatically from v20.6+ only with
--env-file; simplest is node --env-file=.env dev-server.js).
Debug: append ?boot=paused to the URL to restore the saved state without advancing the
simulation.
npm i -g turso # or: brew install tursodatabase/tap/turso
turso auth signup
turso db create xaucore
turso db show xaucore --url # -> TURSO_DATABASE_URL (libsql://xaucore-....turso.io)
turso db tokens create xaucore # -> TURSO_AUTH_TOKEN
Create the schema once (optional — the app also self-creates it on first request):
TURSO_DATABASE_URL=libsql://... TURSO_AUTH_TOKEN=... npm run init-db
git init && git add -A && git commit -m "XAUCORE on Vercel + Turso"
npm i -g vercel
vercel # first run: links/creates the project
In the Vercel project → Settings → Environment Variables add (Production + Preview):
| Name | Value |
|---|---|
TURSO_DATABASE_URL | libsql://xaucore-....turso.io |
TURSO_AUTH_TOKEN | the token from turso db tokens create |
OWNER_KEY (optional) | any long random secret — enables the "site closed" mode (see §7) |
Then:
vercel --prod
No build step, no framework — Vercel serves public/ statically, runs each api/**/*.js
file as a serverless function, and runs middleware.js before page requests. npm install
runs automatically.
A single switch that closes the site to visitors while you keep working on it. Nothing is reset — the simulator, every account and all saved state are untouched; it is purely an access gate.
Enable it: set an OWNER_KEY env var (any long random string) in the Vercel project and
redeploy. Without OWNER_KEY the feature is dormant and the site behaves exactly as before.
Use it: open Настройки симулятора → 🔒 Доступ к сайту.
OWNER_KEY to sign in (sets a signed HttpOnly cookie).ON = closed.What visitors see when closed: a self-contained "Система временно недоступна" page
(served by middleware.js with HTTP 503) — no app, no assets, no internal detail. A discreet
Доступ владельца link on that page lets you sign in with the OWNER_KEY from anywhere.
New sign-ins (/api/auth/login|register) are refused too, so the closed site can't be
scripted into.
Why it can't be bypassed: the page check runs in middleware.js, before routing and
before any static file is served, so deleting CSS, editing JS in DevTools, or deep-linking an
internal route all still hit the gate first (the app is an SPA — every "route" is just /).
Owner identity is a HMAC-signed cookie (key = sha256("xaucore-owner-v2|" + OWNER_KEY)) —
visible in DevTools but impossible to forge without OWNER_KEY. The state-sync API
(/api/state) is left on its normal fast path; it is per-user and token-gated, and a blocked
visitor never gets a token.
Toggling does not redeploy. The flag lives in the Turso settings table (site_locked),
so ON/OFF takes effect within ~5 seconds with no new deployment and no state change.
Locked out? Two independent recoveries, both instant:
OWNER_KEY env var and redeploy → the gate goes dormant (site fully open).DELETE FROM settings WHERE key = 'site_locked'; (or set its value to 0).| Route | Purpose |
|---|---|
GET /api/lock | { locked, configured, isOwner } — public |
POST /api/lock {locked} | flip the switch — owner cookie required |
GET /api/owner | { configured, isOwner } |
POST /api/owner {key} | validate OWNER_KEY → set owner cookie |
DELETE /api/owner | sign out of owner mode |
Local dev: OWNER_KEY=whatever npm run dev — dev-server.js runs the same gate.
xaucore.ioxaucore.io and www.xaucore.io.xaucore.io → A 76.76.21.21 (Vercel's apex IP) or the ALIAS/ANAME Vercel lists.www.xaucore.io → CNAME cname.vercel-dns.com.Current XAUUSD price · Bid / Ask / Spread · Balance · Equity · Margin · Free Margin · Margin Level · all open positions (volume, entry, SL, TP, swap, commission) · Floating P/L · full trade history + statistics · current simulated Day number · time inside the day · complete Price-Engine state (velocity, EMAs, volatility-cluster) · current Market Regime and its age · every Simulator Setting · Manual Market Control settings · the candle history for every timeframe.
Re-opening the site (same browser or a different device signed into the same account) restores all of it exactly and the simulation carries on from there. Nothing moved while you were gone.