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,即可验证所有权并自行管理介绍。
一分钟完成验证开源 iRacing 赛季日历和调度软件。浏览所有系列,按类别筛选,并检查您拥有的赛道以规划赛季。添加您的内容以查看在单个赛季锦标赛中有多少赛道符合条件。
AI 翻译
Open-source iRacing season calendar and scheduler. Browse all series, filter by category, and check which tracks you own to plan your season. Add your content to see how many tracks are eligible in one season tournament.
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
A Next.js web application for browsing iRacing season schedules. Includes a PDF extraction script to generate structured data from official iRacing season PDFs.
Open http://localhost:3000 to view the calendar.
Use the extraction script to convert an iRacing season PDF into the JSON data file:
The script parses the PDF, extracts series and track data, and writes iracing-season-data.json to the project root. The app reads this file at build time.
Keeping the calendar up to date (automatic)查看完整 README ↗A Next.js web application for browsing iRacing season schedules. Includes a PDF extraction script to generate structured data from official iRacing season PDFs.
npm install
npm run dev
Open http://localhost:3000 to view the calendar.
Use the extraction script to convert an iRacing season PDF into the JSON data file:
# Basic usage
node extract-season-data.js path/to/iracing-season.pdf
# Custom output path
node extract-season-data.js path/to/iracing-season.pdf --output data/custom-output.json
The script parses the PDF, extracts series and track data, and writes iracing-season-data.json to the project root. The app reads this file at build time.
data/iracing-season-data.json is refreshed automatically from the official
iRacing season schedule PDF, which iRacing publishes at a stable, public,
unauthenticated URL:
https://members-assets.iracing.com/public/schedulepdf/SeasonSchedule.pdf
The filename contains no season, so the same URL always serves the current one — the calendar rolls over on its own when a new season starts. No iRacing credentials are involved.
# Download, parse, validate, and update the data file if anything changed
npm run sync-pdf
# See what would change without writing
npm run sync-pdf -- --dry-run
# Parse a PDF you already have
npm run sync-pdf -- --pdf path/to/SeasonSchedule.pdf
.github/workflows/update-season-data.yml runs this daily and commits the data
file when it changes.
Because PDF parsing is more brittle than a JSON API, sync-season-pdf.js
refuses to write when the result looks wrong — too few series, series with no
schedule, unparseable dates, a sudden collapse in series count, or a season
that moves backwards. A layout change fails the workflow loudly instead of
committing a broken calendar.
The canonical source of truth for series and schedules is the official
iRacing Data API. sync-season-data.js can
pull the current season directly from it instead of parsing a PDF by hand.
Heads up — OAuth required. iRacing retired legacy username/password authentication with the 2026 Season 1 release (2025-12-09); the old
members-ng.iracing.com/authendpoint now returns HTTP 405. API access now requires an OAuth2 client (client_id+client_secret) registered at oauth.iracing.com/accountmanagement. iRacing has temporarily paused issuing new client IDs while they review third-party usage. This path is therefore dormant — the project syncs from the public schedule PDF instead, which needs no credentials.sync-season-data.jsis kept ready for the day registration reopens.
# Fetch the current season and update data/iracing-season-data.json if changed
IRACING_CLIENT_ID=... IRACING_CLIENT_SECRET=... \
[email protected] IRACING_PASSWORD=secret \
npm run sync-data
# Just check whether anything changed (no write)
npm run sync-data -- --dry-run
# Transform a previously-saved API response (no credentials needed — handy for testing)
npm run sync-data -- --from-json path/to/series-seasons.json
How it works:
password_limited grant against
POST https://oauth.iracing.com/oauth2/token. Secrets are never sent in
clear text — each is masked as base64(sha256(secret + id)) (the
client_secret with the client_id, the password with the email).GET /data/series/seasons?include_series=true (and /data/carclass/get
for car names) with the resulting Bearer token, following the signed S3
link each endpoint returns..github/workflows/update-season-data.yml no longer uses this path — it syncs
from the public PDF instead. To switch back once you have a client, set these
repository secrets (Settings → Secrets and variables → Actions) and point the
workflow's sync step at sync-season-data.js:
| Secret | Description |
|---|---|
IRACING_CLIENT_ID | OAuth client id |
IRACING_CLIENT_SECRET | OAuth client secret |
IRACING_EMAIL | iRacing account email |
IRACING_PASSWORD | iRacing account password |
Because iRacing announces the reopening only on their forums and in release
notes, .github/workflows/watch-iracing-oauth.yml polls the two doc pages that
carry the pause notice every Monday and opens an issue when the notice
disappears. Run it by hand any time:
npm run check-oauth
Exit codes: 0 still paused, 3 notice gone (may be open), 1 indeterminate
(page moved or unreachable). The check is text-based, so confirm on
oauth.iracing.com/accountmanagement
before acting — iRacing may simply have reworded the page.
Normally you don't need this — npm run sync-pdf fetches the current PDF for
you. Use this only to parse a PDF the public URL doesn't serve (an older
season, or a copy from the forums):
npm run extract-data -- path/to/season.pdfdata/iracing-season-data.jsonNote this writes the data file directly, with none of the validation guards
sync-season-pdf.js applies.
iracing-calendar/
├── extract-season-data.js # PDF parsing script
├── iracing-season-data.json # Generated season data (committed)
├── src/
│ ├── app/
│ │ ├── layout.tsx # Root layout
│ │ ├── page.tsx # Series list (home page)
│ │ ├── not-found.tsx # 404 page
│ │ ├── globals.css # Global styles
│ │ └── series/
│ │ └── [id]/
│ │ └── page.tsx # Series detail page
│ ├── components/
│ │ ├── Header.tsx # Navigation header
│ │ ├── Footer.tsx # Page footer
│ │ ├── SearchBar.tsx # Search input + category filters + view toggle
│ │ ├── SeriesCard.tsx # Individual series card (grid & list)
│ │ ├── SeriesList.tsx # Series grid/list container
│ │ └── SeriesDetail.tsx # Full schedule view for a series
│ └── lib/
│ ├── types.ts # TypeScript type definitions
│ ├── data.ts # Data loading and filtering
│ └── utils.ts # Date formatting, week status, colors
├── package.json
├── next.config.ts
├── tsconfig.json
└── tailwind.config.ts (if present)
| Command | Description |
|---|---|
npm run dev | Start development server |
npm run build | Build for production |
npm start | Start production server |
npm run lint | Run ESLint |
npm run extract-data -- <pdf> | Extract data from a season PDF |
npm run sync-data | Sync data from the official iRacing Data API |