382 lines
11 KiB
Markdown
382 lines
11 KiB
Markdown
# YRTV 2.0.0 Beta · Superjacky6 Self-hosted Edition
|
||
|
||
> Created by **Superjacky6** · jacky / jk / yr / jacky0987
|
||
|
||
YRTV 是面向固定 CS2 战队的私人数据站。它不是公共玩家排行榜,而是让队员拥有类似职业选手的个人主页,并为战队提供比赛档案、队内比较、阵容分析、对手情报和战术工具。
|
||
|
||
当前 Beta 版本已经建立可重复运行的数据流水线、数据库治理、职业主页和可追溯的阵容版本模型,重点服务 active roster。
|
||
|
||
## 当前基线
|
||
|
||
- 208 场比赛
|
||
- 1,181 名采集到的玩家
|
||
- 2,080 条玩家比赛记录
|
||
- 4,315 个回合
|
||
- 33,560 条回合事件
|
||
- 38,423 条经济记录
|
||
- 9 名 active roster 队员
|
||
- 885 条 roster 逐场历史
|
||
- 76 条地图统计
|
||
- 236 条武器统计
|
||
- 54 条时间窗口统计
|
||
- 54 条个人职业纪录
|
||
- 36 个 roster 二人组
|
||
- 200 个实际 2-5 人阵容组合
|
||
- 208 份赛后报告
|
||
- 885 份队员赛后对比
|
||
- 203 次职业纪录刷新事件
|
||
- 2 个战队赛季
|
||
- 111 个日/周/月/季/年度奖项
|
||
- 19 条正面/负面/趣味数据发现
|
||
- 36 枚地图与 ELO 分段勋章
|
||
- 40 项自动化测试通过
|
||
- 43 项数据完整性检查通过
|
||
|
||
数据规模会随导入变化,Admin 数据完整性中心显示的结果是运行时事实。
|
||
|
||
## 核心功能
|
||
|
||
### 玩家职业主页
|
||
|
||
- Rating、K/D、ADR、KAST 等生涯数据
|
||
- Aim、Clutch、Pistol、Defense、Utility、Stability、Economy、Pace 八维能力
|
||
- 生涯、最近 10/20/30 场、最近 30/90 天阶段统计
|
||
- 可切换时间窗口的 Rating 趋势
|
||
- 最高 Rating、最多击杀、最高 ADR、最高 K/D、最多爆头和最长连胜
|
||
- 每项个人纪录可追溯到具体比赛
|
||
- 地图表现、比赛历史、Party 信息、队内排名和留言板
|
||
- 缺失或尚未实现的指标显示为 `N/A`,不使用伪造分数
|
||
|
||
### 比赛中心
|
||
|
||
- 比赛列表、地图、比分、平均 ELO 和己方结果
|
||
- 自动赛后报告与队内 MVP
|
||
- 相对此前 20 场的 Rating、K/D、ADR 变化
|
||
- 本场纪录刷新、状态标签和最强二人组
|
||
- Active roster 与 Party 识别
|
||
- 双方玩家表现和 Rating 排序
|
||
- Head-to-head 击杀矩阵
|
||
- 回合事件、经济和装备信息
|
||
- 原始比赛数据查看
|
||
|
||
### 战队与战术
|
||
|
||
- Active roster 管理
|
||
- Roster version 生效区间和历史版本
|
||
- Starter、substitute、member 角色管理
|
||
- 战队履历、赛季战绩和地图表现
|
||
- 实际同队二人组与 2-5 人阵容组合
|
||
- 玩家搜索、签入和移出
|
||
- 2-5 人同队比赛与 Chemistry 分析
|
||
- 对手档案和真实交手记录
|
||
- 地图战术板、阵容数据中心和经济工具
|
||
- Wiki、玩家标签、备注和评论
|
||
|
||
### 赛季与荣誉
|
||
|
||
- 按日历年度生成战队赛季
|
||
- 赛季战绩、Rating、最佳地图和赛季选手
|
||
- 单日最佳、星期最佳、月度最佳、季度最佳、年度最佳
|
||
- 周/月/季/年奖项使用最低场次门槛
|
||
- 个人主页展示荣誉数量和近期奖章
|
||
- 每次职业纪录刷新保留时间和对应比赛
|
||
|
||
### 发现与勋章
|
||
|
||
- 独立 `/discover/` 发现模块
|
||
- 高光、低谷和趣味数据同时展示
|
||
- 爆种、尽力局、躺赢、低谷、稳定性、夜间比赛和连胜等发现
|
||
- 每张达到门槛的地图评选金银铜
|
||
- 每个达到门槛的 ELO 分段评选金银铜
|
||
- 勋章最低 5 场,展示 Rating、K/D、ADR、胜率和样本数
|
||
- 个人职业主页同步展示已获得勋章
|
||
|
||
### 数据运营
|
||
|
||
- Admin 上传 `iframe_network.json`
|
||
- 自动识别唯一 `g161-*` 比赛 ID
|
||
- JSON 结构、必要接口、哈希和重复比赛校验
|
||
- 后台执行 L1 → L2 → L3
|
||
- 实时查看作业阶段、进度、日志和耗时
|
||
- 数据完整性中心与 JSON 报告
|
||
- 独立运营总览、比赛导入、作业中心、数据质量、查询控制台和系统信息
|
||
- 数据库对象目录与只读 SQL 执行耗时
|
||
- L1/L2/L3/Web 文件状态和回滚快照可视化
|
||
- 后台写操作使用 CSRF 防护
|
||
|
||
## Docker 自托管
|
||
|
||
推荐给其他战队使用 Docker Compose:
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
# 修改 SECRET_KEY、ADMIN_TOKEN、VIEWER_TOKEN
|
||
|
||
docker compose up -d --build
|
||
```
|
||
|
||
默认访问 `http://127.0.0.1:5001`。首次空安装:
|
||
|
||
1. 使用 `.env` 中的 `ADMIN_TOKEN` 登录 `/admin/`。
|
||
2. 首次启动向导创建战队和 roster。
|
||
3. 从 `/admin/import-match` 上传自己的 `iframe_network.json`。
|
||
|
||
运行数据保存在 `YRTV_DATA_PATH`,默认是 Git 忽略的
|
||
`./runtime-data`。`git pull` 或重建镜像不会覆盖该目录。
|
||
|
||
### 迁移当前数据
|
||
|
||
当前仓库内已有数据迁移到外置目录:
|
||
|
||
```bash
|
||
make prepare-data
|
||
cp .env.example .env
|
||
docker compose up -d --build
|
||
```
|
||
|
||
迁移使用 SQLite Backup API,不修改源数据库,并生成
|
||
`runtime-data/migration-manifest.json`、SHA256 和 `quick_check` 结果。
|
||
|
||
## Python 开发模式
|
||
|
||
环境要求:
|
||
|
||
- macOS/Linux
|
||
- Python 3.9+
|
||
- SQLite 3
|
||
|
||
安装并启动:
|
||
|
||
```bash
|
||
make install
|
||
|
||
export SECRET_KEY='replace-with-a-random-secret'
|
||
export ADMIN_TOKEN='replace-with-an-admin-token'
|
||
|
||
make run
|
||
```
|
||
|
||
默认地址:
|
||
|
||
- 应用:`http://127.0.0.1:5000`
|
||
- Admin:`/admin/`
|
||
- 比赛导入:`/admin/import-match`
|
||
- 数据完整性:`/admin/data-integrity`
|
||
|
||
生产进程入口:
|
||
|
||
```bash
|
||
.venv/bin/gunicorn wsgi:app
|
||
```
|
||
|
||
## 常用命令
|
||
|
||
```bash
|
||
make run # 启动 Flask
|
||
make check # 编译检查 + 自动化测试
|
||
make pipeline # 备份后执行完整 L1 -> L2 -> L3
|
||
make bootstrap # 初始化空运行时数据库
|
||
make prepare-data # 复制现有数据到 runtime-data
|
||
make docker-up # 构建并启动容器
|
||
make docker-logs # 查看容器日志
|
||
|
||
make l1 # 仅构建 L1
|
||
make l2 # 仅构建 L2
|
||
make l3 # 仅构建 active roster L3
|
||
make l3-all # 为全部采集玩家构建 L3
|
||
```
|
||
|
||
正常维护优先使用 `make pipeline`。单层命令主要用于开发和排错。
|
||
|
||
## 比赛导入
|
||
|
||
推荐从 Admin 页面上传完整的 `iframe_network.json`。
|
||
|
||
导入流程:
|
||
|
||
1. 验证 UTF-8 和 JSON 结构。
|
||
2. 从网络 URL 中提取唯一比赛 ID。
|
||
3. 检查 match 和 round 必要接口。
|
||
4. 计算 SHA256,拒绝相同数据重复导入。
|
||
5. 保存到 `output_arena/<match_id>/iframe_network.json`。
|
||
6. 创建 `etl_jobs` 作业。
|
||
7. 备份 L1/L2/L3。
|
||
8. 串行执行三个 Builder。
|
||
9. 验证目标比赛具有 10 名玩家和回合事实。
|
||
10. 成功提交;失败自动恢复备份。
|
||
|
||
仓库当前不包含自动访问 5E 网页的下载器,因此首页 URL 输入不会抓取数据。
|
||
|
||
## 数据架构
|
||
|
||
```text
|
||
iframe_network.json
|
||
|
|
||
v
|
||
L1 raw capture
|
||
|
|
||
v
|
||
L2 normalized facts
|
||
|
|
||
v
|
||
L3 roster features and profile marts
|
||
|
|
||
v
|
||
Flask services and player profiles
|
||
```
|
||
|
||
### L1:原始层
|
||
|
||
- 数据库:`database/L1/L1.db`
|
||
- Builder:`database/L1/L1_Builder.py`
|
||
- Grain:每场比赛一份完整网络抓包
|
||
- 核心表:`raw_iframe_network`
|
||
|
||
### L2:事实层
|
||
|
||
- 数据库:`database/L2/L2.db`
|
||
- Schema:`database/L2/schema.sql`
|
||
- Builder:`database/L2/L2_Builder.py`
|
||
- 核心表:
|
||
- `dim_players`
|
||
- `dim_maps`
|
||
- `fact_matches`
|
||
- `fact_match_teams`
|
||
- `fact_match_players`
|
||
- `fact_match_players_t`
|
||
- `fact_match_players_ct`
|
||
- `fact_rounds`
|
||
- `fact_round_events`
|
||
- `fact_round_player_economy`
|
||
|
||
### L3:特征与主页集市
|
||
|
||
- 数据库:`database/L3/L3.db`
|
||
- Schema:`database/L3/schema.sql`
|
||
- Builder:`database/L3/L3_Builder.py`
|
||
- 核心表:
|
||
- `dm_player_features`
|
||
- `dm_player_match_history`
|
||
- `dm_player_map_stats`
|
||
- `dm_player_weapon_stats`
|
||
- `dm_player_period_stats`
|
||
- `dm_player_records`
|
||
- `dm_duo_stats`
|
||
- `dm_lineup_stats`
|
||
- `dm_match_reports`
|
||
- `dm_match_player_reports`
|
||
- `dm_player_record_events`
|
||
- `dm_team_season_stats`
|
||
- `dm_player_awards`
|
||
- `dm_discovery_insights`
|
||
- `dm_performance_medals`
|
||
|
||
### Web:应用状态
|
||
|
||
- 数据库:`database/Web/Web_App.sqlite`
|
||
- Schema:`database/Web/schema.sql`
|
||
- 当前 schema version:3
|
||
- 保存 lineup、玩家备注、评论、Wiki、战术板、导入登记和 ETL 作业
|
||
|
||
## 数据库治理
|
||
|
||
- 所有运行路径集中定义在 `database/paths.py`
|
||
- `YRTV_DATA_DIR` 可将数据库、备份、锁和导入文件移出代码仓库
|
||
- 未设置 `YRTV_DATA_DIR` 时继续兼容原 `database/` 数据路径
|
||
- 完整编排入口为 `database/pipeline.py`
|
||
- 同一时间只允许一个 pipeline
|
||
- Pipeline 运行前备份 L1/L2/L3
|
||
- 失败时恢复三层数据库,Web 作业日志继续保留
|
||
- 备份位于 `database/backups/`
|
||
- 自动保留最近 3 组备份
|
||
- Web schema 使用 `schema_migrations` 记录版本
|
||
- 高频玩家历史、Party、事件和经济查询具有专用索引
|
||
- 数据库和目录规则详见 `database/README.md`
|
||
|
||
## 访问模式
|
||
|
||
- `SITE_VISIBILITY=public`:前台公开,Admin 仍需令牌。
|
||
- `SITE_VISIBILITY=private`:前台需要 `VIEWER_TOKEN`。
|
||
- `/healthz` 始终开放给 Docker 和反向代理健康检查。
|
||
- 后台写操作具有 CSRF 防护。
|
||
|
||
Docker 示例默认使用 `private`。
|
||
|
||
## 品牌与许可证
|
||
|
||
- 主品牌:`Superjacky6`
|
||
- 项目签名:`jacky / jk / yr / jacky0987`
|
||
- 页面、报告、后台、元数据、CLI 和容器镜像保留品牌署名
|
||
- 比赛事实和统计指标中不写入水印
|
||
- 许可证:AGPL-3.0-or-later
|
||
- 署名规则:`NOTICE.md`
|
||
|
||
## 数据质量
|
||
|
||
Admin 数据完整性中心检查:
|
||
|
||
- 四个 SQLite 数据库的 `quick_check`
|
||
- 必要表和 Web schema version
|
||
- 玩家比赛、回合事件的引用完整性
|
||
- 每场比赛玩家数量
|
||
- 玩家身份覆盖
|
||
- 高频查询索引
|
||
- Active roster 的 L3 特征覆盖
|
||
- 逐场历史与总场次一致性
|
||
- 真实队内 percentile
|
||
- 地图、武器、时间窗口和职业纪录集市
|
||
- 占位空间指标
|
||
- Web 外键、active lineup 和 pipeline 并发
|
||
- 备份数量与存储规模
|
||
|
||
运行测试:
|
||
|
||
```bash
|
||
make check
|
||
```
|
||
|
||
## 目录结构
|
||
|
||
```text
|
||
yrtv/
|
||
├── database/
|
||
│ ├── L1/ # 原始抓包与 Builder
|
||
│ ├── L2/ # 事实层、Schema、Processor
|
||
│ ├── L3/ # 特征层、Schema、Processor
|
||
│ ├── Web/ # 应用数据库 Schema
|
||
│ ├── paths.py # 统一路径
|
||
│ ├── maintenance.py # 备份、恢复、健康检查
|
||
│ ├── job_store.py # ETL 作业状态
|
||
│ └── pipeline.py # 完整流水线
|
||
├── docker/
|
||
│ └── entrypoint.sh
|
||
├── tests/ # 自动化测试
|
||
├── utils/ # JSON 结构分析工具
|
||
├── web/
|
||
│ ├── routes/
|
||
│ ├── services/
|
||
│ ├── templates/
|
||
│ └── static/
|
||
├── Makefile
|
||
├── Dockerfile
|
||
├── docker-compose.yml
|
||
├── .env.example
|
||
├── requirements.txt
|
||
└── wsgi.py
|
||
```
|
||
|
||
## Beta 限制
|
||
|
||
- 当前主要数据源为 5E iframe 网络响应。
|
||
- 不包含自动网页下载器和 Demo parser。
|
||
- 支持独立 Viewer Token 和 Admin Token,但不提供开放注册或多用户权限系统。
|
||
- SQLite 适合当前单战队规模,不面向高并发多租户。
|
||
- 部分高级空间能力需要地图边界、路径和 Demo 数据,当前显示 `N/A`。
|
||
- `StatsService` 仍保留部分兼容逻辑;新功能已拆入 Player Profile、Team Performance、Roster Version 等领域服务。
|
||
|
||
## 版本
|
||
|
||
当前版本:`2.0.0 Beta`
|
||
|
||
这一版本的目标是建立可信、可恢复、可持续导入的私人战队 HLTV 基线,而不是冻结产品功能。
|