miyakejima/goldsrc-dem-graph
GitHub: miyakejima/goldsrc-dem-graph
一款离线的 GoldSrc .dem 文件分析器,通过 Rust 解析器和 PixiJS 在本地渲染 CS 1.6 KZ/bhop demo 的交互式帧数据图表。
Stars: 1 | Forks: 1
# GoldSrc Demo Graph
用于 CS 1.6 KZ/bhop demo 的离线 `.dem` 文件分析器。通过 Rust 二进制程序在本地解析 GoldSrc demo 帧,并在浏览器中渲染完整的交互式图表(engine fps、mouseX、mouseX 速度、跳跃高度、空中加速数据)——无需上游 API,无需登录。
通过逆向工程 `demo.unique-kz.net` 图表渲染器,并配合专门为 GoldSrc demo 二进制格式构建的 Rust 解析器打造。
## 截图
**Engine FPS — 带有技巧标记的帧时间线**

**MouseX — 随时间变化的偏航角及每次跳跃的详细数据**

**MouseX 速度 — 每帧的偏航角增量**

**跳跃高度 — 每次 bhop 的抛物线轨迹**

## 功能说明
1. 在浏览器中接收上传的本地 `.dem` 文件
2. 调用本地 Rust 解析器二进制程序,将帧数据提取为图表 payload
3. 在浏览器内渲染完整的交互式图表 UI(engine fps、real fps、mouseX、mouseX 速度、跳跃高度)
4. 显示每次跳跃的技巧信息(stand-up bhop、duckbug、edgebug、slidebug、longjump)及其距离、prestrate、strafes、sync 和空中帧数
5. 导出确定性的 CSV 数据集,用于离线 strafe 分析
正常使用过程中不会发起任何网络请求。Rust 解析器在首次运行时通过 Cargo 在本地构建。
## 技术栈
| 层级 | 技术 |
|---|---|
| 前端 | Vite + 原生 JS + [PixiJS](https://pixijs.com/) 7 |
| 开发服务器 | Express 5 + Vite 中间件 |
| Demo 解析器 | Rust (`hldemo` crate) → JSON payload |
| 导出 | CSV(jumps、frames、strafe-helper 数据集) |
## 环境要求
- **Node.js** 20+
- **npm**
- **Rust + Cargo**(通过 [rustup](https://rustup.rs/) 安装)
- Windows、macOS 或 Linux 以及本地浏览器
请查看 [REQUIREMENTS.md](REQUIREMENTS.md) 获取完整的配置清单。
## 快速开始
```
# 1. 安装 JS dependencies
npm install
# 2. 启动 local app(首次运行时构建 Rust parser)
npm run dev
```
打开 [http://localhost:5173](http://localhost:5173),拖入一个 `.dem` 文件,点击 **Parse + Load Graph**。
## 图表视图
| 标签页 | 显示内容 |
|---|---|
| `engine fps` | 每帧的 Engine FPS,带有 100 fps / 83 fps / 50 fps / 25 fps 参考线 |
| `real fps` | 每帧的真实(客户端)FPS |
| `mouseX` | 随时间变化的绝对偏航角 — 点击任意技巧条即可查看完整的跳跃统计数据 |
| `mouseX speed` | 每帧的偏航角增量(度/帧) — 显示 strafe 摆动模式 |
| `jump height` | 每次 bhop 的抛物线 Z 轴高度轨迹,带有青色的 bhop 基准线 |
### 技巧条行(底部面板)
| 行 | 含义 |
|---|---|
| `techniques` | 每次跳跃检测到的技巧:`sbj` (stand-up bhop)、`dj` (duck jump)、`lj` (long jump) 等 |
| `jump` | 帧级别的跳跃按键状态 |
| `ground` | 地面接触帧 |
| `duck` / `duckstate` | 蹲下按键及蹲下状态转换 |
| `forward` / `back` | 前移方向 |
| `moveleft` / `moveright` | 侧移方向 |
## CSV 导出
**Export Everything CSV Pack** 按钮会下载一个包含所有帧数据的 zip 压缩包,便于离线分析。
## 黑盒工具包(可选)
`tools/blackbox/` 包含用于将本地解析器输出与上游 API 响应进行对比的校验脚本。需要配置环境变量:
```
set UNIQUE_AUTH_TOKEN=your_token
set UNIQUE_CSRF_TOKEN=optional_csrf # optional
```
| 脚本 | 用途 |
|---|---|
| `bb:upload` | 将一个包含多个 demo 的文件夹上传到上游 API |
| `bb:fetch` | 获取已上传 demo 的上游图表 payload |
| `bb:parse-local` | 在相同的 demo 上运行本地解析器 |
| `bb:analyze` | 对比本地与上游 payload,生成校准报告 |
| `bb:analyze-bars` | 条带级别的对比报告 |
| `bb:analyze-canonical` | 规范对比报告 |
| `bb:compare-demo` | 单个 demo 的并排差异对比 |
生成的输出将存放于 `re_data/` 目录中,该目录已被有意排除在版本控制之外。
## 项目结构
```
unique-graph-local-tester/
├── src/
│ ├── main.js # App entry — file upload, UI boot, export dispatch
│ ├── style.css
│ ├── upstream/ # Extracted graph renderer (PixiJS-based)
│ │ ├── graph/ # Core graph rendering logic
│ │ │ ├── bars/ # Technique / jump / state bar renderers
│ │ │ ├── graphics/ # Overlay renderers (duck, ground, forward, etc.)
│ │ │ └── models/ # Graph data models
│ │ └── pages/demo/ # Demo page shell
│ └── export/
│ ├── csv-pack.js # Full CSV pack export
│ └── strafe-helper-dataset.js # Strafe-helper CSV export
├── server/
│ └── dev-server.js # Express + Vite dev server; /api/parse-dem endpoint
├── parser-rs/
│ ├── Cargo.toml # hldemo + serde_json
│ └── src/main.rs # GoldSrc .dem → graph JSON payload
├── tools/
│ ├── blackbox/ # Parity and calibration scripts
│ └── smoke-test-csv-pack.mjs # CSV export smoke test
├── docs/
│ ├── architecture.md
│ ├── blackbox-tooling.md
│ └── screenshots/
├── re_data/ # Generated workspace — not committed
└── vite.config.js
```
## 解析器工作原理
Rust 二进制程序使用 [`hldemo`](https://crates.io/crates/hldemo) crate 读取 GoldSrc `.dem` 文件,遍历每一个 demo 帧,并输出供图表渲染器使用的 JSON payload。如果不存在二进制程序,开发服务器会在首次运行时自动构建该解析器。
```
.dem file → hldemo frame iterator → per-frame state extraction → JSON → graph renderer
```
## 许可证
ISC — 请参阅 [LICENSE](LICENSE)。
标签:Mutation, Rust, 代码示例, 可视化, 可视化界面, 数据分析, 数据可视化, 文件解析, 游戏工具, 网络流量审计, 自定义脚本