# TurboSu 赛车遥测仪表盘 — 基于 Web 的 B/S 架构外置仪表盘,支持多种赛车游戏遥测数据实时显示。 ![License](https://img.shields.io/badge/license-Apache%202.0-blue) ![Python](https://img.shields.io/badge/python-3.10%2B-blue) ![Platform](https://img.shields.io/badge/platform-web%20%7C%20lan-brightgreen) ## 功能特性 - **多游戏支持** — 插件化架构,内置 Forza Horizon 4/5、Forza Motorsport、Assetto Corsa/ACC、F1、iRacing - **社区扩展** — 游戏插件可独立打包导入导出 (`.tsp`),方便社区贡献小众游戏支持 - **实时仪表盘** — 速度表、转速表、档位指示器、圈速计时器 - **独立仪表盘** — 每个仪表盘是独立文件夹 (`manifest.json` + `index.html`),启动自动扫描 - **场景模式** — 多仪表盘布局组合,支持多比例画布切换 - **局域网共享** — 仪表盘/场景生成独立链接,手机/平板/笔记本均可全屏访问 - **跨端自适应** — 响应式布局:桌面侧边栏 / 平板折叠 / 手机底部导航 - **比例约束渲染** — 仪表盘可指定比例 (`auto`/`16:9`/`4:3`/`1:1`) 和渲染模式 (`contain`/`cover`/`fill`/`center`) - **HyperOS 风格** — Miuix 设计语言,毛玻璃模糊效果,日间/夜间模式 - **社区分发** — 仪表盘 `.tsd`、场景 `.tss`、插件 `.tsp` — zip 格式,便于分享 ## 快速开始 ### 环境要求 - Python 3.10+ - pip ### 运行 ```bash git clone ssh://git@git.yeij.top:2222/AskaEth/TurboSu.git cd TurboSu # 一键启动 (自动创建 venv 并安装依赖) ./run.sh # 或手动启动 python3 -m venv venv && source venv/bin/activate pip install -r requirements.txt python app.py ``` 浏览器访问 `http://localhost:9527` ## 使用指南 ### 1. 选择游戏 侧边栏 → 游戏列表展开 → 选择你要玩的游戏。列表来自 `games/builtin/` (内置) 和 `games/user/` (社区)。 ### 2. 配置遥测输出 在各游戏中开启 UDP 数据输出功能: | 游戏 | 设置位置 | 端口 | |------|----------|------| | Forza Horizon 4/5 | 设置 → HUD与游戏 → 数据输出 | 20777 | | Forza Motorsport | 设置 → 游戏玩法 → UDP数据输出 | 20777 | | Assetto Corsa | 内容管理器 → 自定义UDP | 9996 | | ACC | 设置 → 电子设备 → UDP | 20777 | | F1 24 | 设置 → 遥测设置 → UDP | 20777 | | iRacing | 选项 → 杂项 → 数据记录 | 20777 | ### 3. 浏览仪表盘 侧边栏 → 仪表盘 → 浏览/分类筛选 → 点击卡片在新标签打开全屏仪表盘。 链接自动复制,局域网设备可直接访问。右键卡片可导出 `.tsd` 文件。 ### 4. 创建场景 侧边栏 → 场景 → 新建场景 → 编辑添加多个仪表盘 → 选择画布比例 → 渲染。 场景卡片支持导出 `.tss`,页面顶栏可导入。 ### 5. 数据调试 侧边栏 → 数据测试 → 实时查看解析字段和原始 JSON 数据流。 ## 开发指南 ### 自定义仪表盘格式 每个仪表盘是一个独立文件夹,放在 `dashboards/` 或 `data/dashboards/`: ``` dashboards/my_dashboard/ ├── manifest.json # 元信息 └── index.html # 完整独立页面 (含 WS 连接 + 数据绑定) ``` #### manifest.json ```json { "id": "my_dashboard", "name": "我的仪表盘", "category": "custom", "description": "简短描述", "author": "你的名字", "version": "1.0.0", "config": { "icon": "🏎️", "aspect_ratio": "16:9", "render_mode": "contain" } } ``` #### index.html 完全独立的 HTML 页面。需包含: - WebSocket 连接到 `ws:///ws` 接收遥测数据 - `data-bind` 属性绑定数据字段(如 `data-bind="speed_kmh"`) - 比例约束渲染逻辑(参考内置仪表盘) 打包分发:将整个文件夹压缩为 zip,改后缀为 `.tsd`。 ### 自定义游戏插件 插件文件夹放在 `games/user/`: ``` games/user/my_game/ ├── manifest.json # 元信息 └── parser.py # 解析逻辑 (get_parser() + parse()) ``` #### manifest.json ```json { "id": "my_game", "name": "我的游戏", "parser_type": "forza", "description": "自定义游戏遥测", "author": "你的名字", "version": "1.0.0", "default_port": 20777 } ``` #### parser.py ```python import time from server.telemetry.data import TelemetryData def get_parser(): return MyGameParser() class MyGameParser: def game_id(self) -> str: return "my_game" def parse(self, data: bytes, addr: tuple) -> TelemetryData: td = TelemetryData(game_id="my_game", timestamp=time.time()) td.raw = {"raw_hex": data.hex(), "length": len(data)} # 解析你的游戏数据... # td.speed_kmh = ... # td.rpm = ... # td.gear = ... return td ``` 打包分发:将文件夹压缩为 zip,改后缀为 `.tsp`,在设置页面导入。 ### TelemetryData 可用字段 | 字段 | 类型 | 说明 | |------|------|------| | `speed_kmh` | float | 速度 (km/h) | | `speed_mph` | float | 速度 (mph) | | `rpm` | float | 发动机转速 | | `max_rpm` | float | 最大转速 | | `gear` | int | 档位 (0=N, -1=R) | | `throttle` | float | 油门 (0~1) | | `brake` | float | 刹车 (0~1) | | `clutch` | float | 离合 (0~1) | | `handbrake` | float | 手刹 (0~1) | | `steering` | float | 转向 (-1~1) | | `lap_time` | float | 当前圈速 (秒) | | `best_lap` | float | 最佳圈速 (秒) | | `last_lap` | float | 上圈时间 (秒) | | `lap_number` | int | 圈数 | | `fuel` | float | 燃油 | | `boost` | float | 涡轮增压 | | `horsepower` | float | 马力 | | `torque` | float | 扭矩 | | `position_x/y/z` | float | 坐标 | | `engine_temp` | float | 发动机温度 | | `oil_temp` | float | 油温 | | `raw` | dict | 原始数据 | ## 项目结构 ``` TurboSu/ ├── app.py # FastAPI 主入口 (lifespan) ├── run.sh # 一键启动脚本 ├── requirements.txt ├── config/settings.py # 全局配置 (JSON 持久化) ├── server/ │ ├── api.py # REST API (状态/配置/CRUD/导入导出) │ ├── websocket.py # WebSocket 广播 (30fps 限流) │ ├── game_manager.py # 游戏插件发现/加载/导入导出(.tsp) │ └── telemetry/ │ ├── data.py # TelemetryData 27字段数据类 │ ├── listener.py # UDP 异步监听器 │ └── parsers/ # 内置解析器 (base/forza/ac/acc/f1/iracing) ├── games/ │ ├── builtin/ # 7 款内置游戏插件 │ │ ├── forza_horizon_5/ # manifest.json + parser.py │ │ ├── forza_horizon_4/ │ │ ├── forza_motorsport/ │ │ ├── assetto_corsa/ │ │ ├── assetto_corsa_competizione/ │ │ ├── f1_24/ │ │ └── iracing/ │ └── user/ # 社区插件 (运行时安装) ├── dashboards/ # 内置仪表盘 (4 款) │ ├── speedometer/ # manifest.json + index.html │ ├── tachometer/ │ ├── gear_indicator/ │ └── lap_timer/ ├── models/ │ ├── dashboard.py # 仪表盘模型 + 自动扫描 + zip导入导出 │ └── scene.py # 场景模型 + 画布/布局 + zip导入导出 ├── templates/ │ ├── index.html # 主 SPA 页面 │ └── scene.html # 场景渲染页 (iframe组合) ├── static/ │ ├── css/ │ │ ├── miuix.css # HyperOS/Miuix 样式框架 (CSS变量+毛玻璃+主题) │ │ └── main.css # 布局 + 跨端响应式 (3断点) │ └── js/ │ ├── app.js / router.js # 应用入口 + Hash路由 │ ├── api.js / ws.js # API + WebSocket 客户端 │ ├── components/ # sidebar.js / topbar.js │ ├── pages/ # home / dashboard / scene / debug / settings │ └── utils/ # theme.js / toast.js ├── data/ # 运行时数据 (user dashboards, scenes, config) ├── logs/ # 日志 (轮转文件, 10MB x5) ├── README.md └── CONTRIBUTING.md ``` ## 导入导出格式 | 格式 | 后缀 | 本质 | 说明 | |------|------|------|------| | 仪表盘 | `.tsd` | zip | 含 `manifest.json` + `index.html` | | 场景 | `.tss` | zip | 含 `scene.json` | | 游戏插件 | `.tsp` | zip | 含 `manifest.json` + `parser.py` | ## 作者 **Yei.J. (AskaEth)** ## 许可证 Apache License 2.0