Files
fast_install/API_SPECIFICATION.md

919 lines
41 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# R0Installer 云端配置 API 规范文档
## 概述
为了支持越来越多的应用接入,R0Installer 将从硬编码配置迁移到云端 API 驱动。改造后,安装器/更新器的所有项目参数、命令映射、文件名检测规则都从云端获取,无需更新程序即可新增/修改需要管理的应用。
---
## 一、总体架构
```
┌──────────────┐ ┌───────────────────┐ ┌──────────────────┐
│ R0Installer │──────>│ 云端 Config API │<──────│ 管理后台 │
│ (客户端) │ │ (你实现的后端) │ │ (配置管理) │
└──────────────┘ └───────────────────┘ └──────────────────┘
```
客户端启动后首先调用 **项目配置 API** 获取当前项目的所有动态参数,然后再执行安装/更新流程。
---
## 二、API 清单
| # | API | 方法 | 用途 |
| --- | --------------------------------------------------- | --- | ---------------------- |
| 1 | `/v3/config/projects` | GET | 获取所有可用项目列表 |
| 2 | `/v3/config/project/{project_id}` | GET | 获取单个项目的完整配置 |
| 3 | `/v3/config/installer` | GET | 获取安装器自身的全局配置(文件名检测规则等) |
| 4 | `/v3/version/index?project={project_id}` | GET | 获取指定项目的最新版本信息(安装用) |
| 5 | `/v3/update/check?project={project_id}&v={version}` | GET | 检查指定项目是否有更新(更新用) |
> **Base URL 建议**: `https://a-p-i.r0csgo.com`
> **所有请求携带 Header**: `User-Agent: r0_installer`
---
## 三、API 详细规范
### API 1: 获取所有可用项目列表
**用途**: 安装器启动时获取所有可管理的项目列表,用于 UI 展示或自动匹配。
```
GET /v3/config/projects
```
**请求参数**: 无
**响应示例**:
```json
{
"code": 0,
"message": "success",
"data": {
"projects": [
{
"project_id": "r0_arena",
"display_name": "R0对战平台",
"description": "R0对战平台客户端",
"icon_url": "https://cdn.r0csgo.com/icons/r0_arena.ico",
"enabled": true
},
{
"project_id": "r0_guard",
"display_name": "R0反作弊",
"description": "R0反作弊系统",
"icon_url": "https://cdn.r0csgo.com/icons/r0_guard.ico",
"enabled": true
},
{
"project_id": "r0_launcher",
"display_name": "R0启动器",
"description": "R0游戏启动器",
"icon_url": "https://cdn.r0csgo.com/icons/r0_launcher.ico",
"enabled": true
}
]
}
}
```
**字段说明**:
| 字段 | 类型 | 必填 | 说明 |
| ------------------------- | ------ | --- | --------------------- |
| `projects[].project_id` | string | 是 | 项目唯一标识符,用于后续所有 API 调用 |
| `projects[].display_name` | string | 是 | 项目显示名称(用于 UI) |
| `projects[].description` | string | 否 | 项目描述 |
| `projects[].icon_url` | string | 否 | 项目图标 URL |
| `projects[].enabled` | bool | 是 | 是否启用(false 时客户端跳过该项目) |
---
### API 2: 获取单个项目的完整配置
**用途**: 获取某个项目的所有安装/更新参数配置,这是 **核心 API**,包含原来所有硬编码的参数。
```
GET /v3/config/project/{project_id}
```
**请求参数**:
| 参数 | 位置 | 类型 | 必填 | 说明 |
| ------------ | ---- | ------ | --- | ----------------- |
| `project_id` | path | string | 是 | 项目ID,如 `r0_arena` |
**响应示例(主客户端项目 `r0_arena`)**:
```json
{
"code": 0,
"message": "success",
"data": {
"project_id": "r0_arena",
"display_name": "R0对战平台",
"install": {
"window_title": "R0对战平台安装程序",
"steps": [
{
"step_id": "runtime",
"display_name": "环境检查",
"type": "runtime_check",
"enabled": true
},
{
"step_id": "anticheat",
"display_name": "反作弊安装",
"type": "download_and_run",
"enabled": true,
"download_url_field": "download_url_ac_cdn",
"temp_filename": "r0_guard.exe",
"installer_args": "",
"wait_for_exit": true
},
{
"step_id": "main",
"display_name": "主程序安装",
"type": "download_and_run",
"enabled": true,
"download_url_field": "download_url_cdn",
"temp_filename_template": "r0_arena_v{version}.exe",
"installer_args": "",
"wait_for_exit": false
}
]
},
"update": {
"window_title": "R0对战平台更新程序",
"command": "update",
"check_api": "/v3/update/check?project=r0_arena&v={0}",
"processes_to_close": ["r0_arena", "R0对战平台"],
"launch_after_update": "R0对战平台.exe",
"temp_filename_template": "r0_arena_v{version}.exe",
"hold_file": null,
"supports_incremental": true
},
"update_ac": {
"window_title": "R0反作弊更新程序",
"command": "update_ac",
"check_api": "/v3/update/check?project=r0_guard&v={0}",
"processes_to_close": ["R0Guard"],
"launch_after_update": "R0Guard.exe",
"temp_filename_template": "r0_guard_v{version}.exe",
"hold_file": "ac.hold_install",
"supports_incremental": true,
"silent": true,
"silent_install_args": "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
},
"runtime_requirements": [
{
"runtime_id": "vc_redist",
"display_name": "VC++运行库",
"enabled": true,
"always_install": true,
"detection": {
"type": "registry",
"keys": [
"SOFTWARE\\Microsoft\\VisualStudio\\14.0\\VC\\Runtimes\\x86",
"SOFTWARE\\Microsoft\\VisualStudio\\14.0\\VC\\Runtimes\\x64",
"SOFTWARE\\Microsoft\\VisualStudio\\15.0\\VC\\Runtimes\\x86",
"SOFTWARE\\Microsoft\\VisualStudio\\15.0\\VC\\Runtimes\\x64",
"SOFTWARE\\Microsoft\\VisualStudio\\16.0\\VC\\Runtimes\\x86",
"SOFTWARE\\Microsoft\\VisualStudio\\16.0\\VC\\Runtimes\\x64",
"SOFTWARE\\Microsoft\\VisualStudio\\17.0\\VC\\Runtimes\\x86",
"SOFTWARE\\Microsoft\\VisualStudio\\17.0\\VC\\Runtimes\\x64"
],
"value_name": "Installed",
"expected_value": 1
},
"download_url_x86": "https://cdn.r0csgo.com/runtime/VC_redist.x86.exe",
"download_url_x64": "https://cdn.r0csgo.com/runtime/VC_redist.x64.exe",
"temp_filename_template": "VC_redist.{arch}.exe",
"install_args": "/install /passive /norestart"
},
{
"runtime_id": "dotnet_desktop",
"display_name": ".NET运行库",
"enabled": false,
"always_install": false,
"detection": {
"type": "dotnet_runtime",
"runtime_name": "Microsoft.WindowsDesktop.App",
"version": "8.0.21"
},
"download_url_x86": "https://cdn.r0csgo.com/runtime/windowsdesktop-runtime-8.0.21-win-x86.exe",
"download_url_x64": "https://cdn.r0csgo.com/runtime/windowsdesktop-runtime-8.0.21-win-x64.exe",
"temp_filename_template": "windowsdesktop-runtime-{version}-win-{arch}.exe",
"install_args": "/install /passive /norestart"
},
{
"runtime_id": "aspnet_core",
"display_name": "ASP.NET Core运行库",
"enabled": false,
"always_install": false,
"detection": {
"type": "dotnet_runtime",
"runtime_name": "Microsoft.AspNetCore.App",
"version": "8.0.21"
},
"download_url_x86": "https://cdn.r0csgo.com/runtime/aspnetcore-runtime-8.0.21-win-x86.exe",
"download_url_x64": "https://cdn.r0csgo.com/runtime/aspnetcore-runtime-8.0.21-win-x64.exe",
"temp_filename_template": "aspnetcore-runtime-{version}-win-{arch}.exe",
"install_args": "/install /passive /norestart"
}
],
"download_config": {
"chunk_size": 10485760,
"max_threads": 8,
"retry_count": 3,
"timeout_ms": 30000,
"user_agent": "r0_installer"
}
}
}
```
**响应示例(新增项目,例如 `r0_launcher`**:
```json
{
"code": 0,
"message": "success",
"data": {
"project_id": "r0_launcher",
"display_name": "R0启动器",
"install": {
"window_title": "R0启动器安装程序",
"steps": [
{
"step_id": "runtime",
"display_name": "环境检查",
"type": "runtime_check",
"enabled": true
},
{
"step_id": "main",
"display_name": "启动器安装",
"type": "download_and_run",
"enabled": true,
"download_url_field": "download_url_cdn",
"temp_filename_template": "r0_launcher_v{version}.exe",
"installer_args": "",
"wait_for_exit": false
}
]
},
"update": {
"window_title": "R0启动器更新程序",
"command": "update",
"check_api": "/v3/update/check?project=r0_launcher&v={0}",
"processes_to_close": ["R0Launcher", "r0_launcher"],
"launch_after_update": "R0Launcher.exe",
"temp_filename_template": "r0_launcher_v{version}.exe",
"hold_file": null,
"supports_incremental": true
},
"runtime_requirements": [
{
"runtime_id": "dotnet_desktop",
"display_name": ".NET 9.0运行库",
"enabled": true,
"always_install": false,
"detection": {
"type": "dotnet_runtime",
"runtime_name": "Microsoft.WindowsDesktop.App",
"version": "9.0.3"
},
"download_url_x86": "https://cdn.r0csgo.com/runtime/windowsdesktop-runtime-9.0.3-win-x86.exe",
"download_url_x64": "https://cdn.r0csgo.com/runtime/windowsdesktop-runtime-9.0.3-win-x64.exe",
"temp_filename_template": "windowsdesktop-runtime-9.0.3-win-{arch}.exe",
"install_args": "/install /passive /norestart"
}
],
"download_config": {
"chunk_size": 10485760,
"max_threads": 8,
"retry_count": 3,
"timeout_ms": 30000,
"user_agent": "r0_installer"
}
}
}
```
**install.steps 字段说明**:
| 字段 | 类型 | 必填 | 说明 |
| ------------------------ | ------ | --- | ---------------------------- |
| `step_id` | string | 是 | 步骤唯一标识 |
| `display_name` | string | 是 | 步骤显示名称(用于 UI 步骤指示器) |
| `type` | string | 是 | 步骤类型,见下方类型说明 |
| `enabled` | bool | 是 | 是否启用此步骤 |
| `download_url_field` | string | 条件 | 对应版本信息 API 中的下载地址字段名 |
| `temp_filename` | string | 条件 | 固定的临时文件名(无版本号时用) |
| `temp_filename_template` | string | 条件 | 临时文件名模板,`{version}` 会被替换为版本号 |
| `installer_args` | string | 否 | 安装器启动参数 |
| `wait_for_exit` | bool | 否 | 是否等待安装器退出(默认 true) |
**步骤类型(`type`**:
| 类型 | 说明 |
| ---------------------- | ---------------- |
| `runtime_check` | 运行环境检查与安装 |
| `download_and_run` | 下载文件并运行安装器 |
| `download_and_extract` | 下载文件并解压到指定目录(预留) |
**runtime_requirements 字段说明**:
| 字段 | 类型 | 必填 | 说明 |
| ------------------------ | ------ | --- | ---------------------------------------------- |
| `runtime_id` | string | 是 | 运行库唯一标识 |
| `display_name` | string | 是 | 显示名称 |
| `enabled` | bool | 是 | 是否启用检测和安装 |
| `always_install` | bool | 是 | true=无论是否已安装都重装;false=检测后按需安装 |
| `detection` | object | 是 | 检测方式配置 |
| `download_url_x86` | string | 是 | x86 下载地址 |
| `download_url_x64` | string | 是 | x64 下载地址 |
| `temp_filename_template` | string | 是 | 临时文件名模板(`{arch}` → x86/x64, `{version}` → 版本号) |
| `install_args` | string | 是 | 安装器命令行参数 |
**detection 类型说明**:
| detection.type | 额外字段 | 说明 |
| ---------------- | -------------------------------------- | ------------------------------ |
| `registry` | `keys`, `value_name`, `expected_value` | 检查注册表键值 |
| `dotnet_runtime` | `runtime_name`, `version` | 通过 `dotnet --list-runtimes` 检查 |
| `file_exists` | `path` | 检查文件是否存在(预留) |
| `command_output` | `command`, `args`, `contains` | 检查命令输出是否包含字符串(预留) |
---
### API 3: 获取安装器全局配置(文件名检测规则)
**用途**: 替代硬编码的 `DetectInstallMode()` 逻辑。安装器启动时根据自身 exe 文件名匹配规则,确定要安装哪个项目以及安装模式。
```
GET /v3/config/installer
```
**请求参数**: 无
**响应示例**:
```json
{
"code": 0,
"message": "success",
"data": {
"installer_version": "2.0",
"min_client_version": "1.0.0.0",
"filename_rules": [
{
"pattern": "R0ClientInstaller",
"match_type": "starts_with",
"case_sensitive": false,
"project_id": "r0_arena",
"install_mode": "client_only",
"description": "仅安装R0对战平台客户端"
},
{
"pattern": "R0AcInstaller",
"match_type": "starts_with",
"case_sensitive": false,
"project_id": "r0_arena",
"install_mode": "ac_only",
"description": "仅安装R0对战平台环境和反作弊"
},
{
"pattern": "R0Installer",
"match_type": "starts_with",
"case_sensitive": false,
"project_id": "r0_arena",
"install_mode": "full",
"description": "完整安装R0对战平台"
},
{
"pattern": "R0LauncherInstaller",
"match_type": "starts_with",
"case_sensitive": false,
"project_id": "r0_launcher",
"install_mode": "full",
"description": "完整安装R0启动器"
}
],
"command_rules": [
{
"command": "update",
"project_id": "r0_arena",
"update_target": "update",
"silent": false,
"description": "R0对战平台主程序更新"
},
{
"command": "update_ac",
"project_id": "r0_arena",
"update_target": "update_ac",
"silent": true,
"description": "R0对战平台反作弊更新(静默,无界面)"
},
{
"command": "update_launcher",
"project_id": "r0_launcher",
"update_target": "update",
"silent": false,
"description": "R0启动器更新"
}
],
"default_project_id": "r0_arena",
"default_install_mode": "full"
}
}
```
**filename_rules 字段说明**:
| 字段 | 类型 | 必填 | 说明 |
| ---------------- | ------ | --- | --------------------------------------------- |
| `pattern` | string | 是 | 匹配模式字符串 |
| `match_type` | string | 是 | 匹配方式:`starts_with``contains``exact``regex` |
| `case_sensitive` | bool | 是 | 是否区分大小写 |
| `project_id` | string | 是 | 匹配成功后使用的项目ID |
| `install_mode` | string | 是 | 安装模式:`full``client_only``ac_only` |
| `description` | string | 否 | 规则描述 |
> **匹配优先级**:按数组顺序从前到后匹配,第一个命中的规则生效。因此应把更具体的规则放在前面(如 `R0ClientInstaller` 在 `R0Installer` 之前)。
**command_rules 字段说明**:
| 字段 | 类型 | 必填 | 说明 |
| --------------- | ------ | --- | -------------------------------------- |
| `command` | string | 是 | 命令行参数(第一个参数),如 `update``update_ac` |
| `project_id` | string | 是 | 对应的项目ID |
| `update_target` | string | 是 | 项目配置中的更新目标键名(`update``update_ac` 等) |
| `silent` | bool | 否 | 是否强制静默更新(不显示界面,后台自动完成)。默认 `false`。也可在 `project_config.{update_target}` 中配置同名字段 |
| `description` | string | 否 | 规则描述 |
> **静默更新**:当 `command_rules[].silent` 或对应 `update_target` 配置中的 `silent` 为 `true` 时,更新器不会弹出任何窗口,直接在后台下载并应用更新;更新完成后按 `launch_after_update` 自动拉起主程序。
> 除服务端配置外,调用方也可在命令行追加 `--silent`(或 `-s` / `/silent` / `/s`)强制静默,例如:`R0Installer.exe update <version> --silent`。
> 静默模式下,更新结果仍会通过标准输出返回 `OK`(成功/无更新)或 `ERROR`(失败),方便调用方判断。
>
> **全量包静默安装参数 `silent_install_args`**:配置在 `update_target` 配置块中(如上 `update_ac` 示例)。当静默执行 `update_type=full` 时,更新器会把该参数传给下载到的安装包并等待其安装完成。
> 安装包由 Inno Setup 打包,默认参数为 `/VERYSILENT /SUPPRESSMSGBOXES /NORESTART``/VERYSILENT` 完全无界面、`/SUPPRESSMSGBOXES` 抑制弹窗、`/NORESTART` 不自动重启)。如需自定义可覆盖该字段,例如追加 `/CLOSEAPPLICATIONS /RESTARTAPPLICATIONS`。
> 增量更新(`incremental` / `multi_incremental`)在更新器进程内直接应用补丁,本身就无界面,不涉及该参数。
---
### API 4: 获取项目最新版本信息(安装用)
**用途**: 替代原有 `/v2/version/index`,但支持多项目。
```
GET /v3/version/index?project={project_id}
```
**请求参数**:
| 参数 | 位置 | 类型 | 必填 | 说明 |
| --------- | ----- | ------ | --- | ---- |
| `project` | query | string | 是 | 项目ID |
**响应示例(`r0_arena`**:
```json
{
"code": 0,
"message": "success",
"data": {
"project_id": "r0_arena",
"version": "3.0.5",
"download_url_cdn": "https://cdn.r0csgo.com/releases/r0_arena_v3.0.5.exe",
"download_url_ac_cdn": "https://cdn.r0csgo.com/releases/r0_guard_v2.1.0.exe",
"threads": 8,
"changelog": "修复了若干问题",
"runtime_download_url": {
"VC_REDISTRIB_X86_URL": "https://cdn.r0csgo.com/runtime/VC_redist.x86.exe",
"VC_REDISTRIB_X64_URL": "https://cdn.r0csgo.com/runtime/VC_redist.x64.exe",
"DOTNET_SDK_X86_URL": "https://cdn.r0csgo.com/runtime/windowsdesktop-runtime-8.0.21-win-x86.exe",
"DOTNET_SDK_X64_URL": "https://cdn.r0csgo.com/runtime/windowsdesktop-runtime-8.0.21-win-x64.exe",
"ASPNET_CORE_X86_URL": "https://cdn.r0csgo.com/runtime/aspnetcore-runtime-8.0.21-win-x86.exe",
"ASPNET_CORE_X64_URL": "https://cdn.r0csgo.com/runtime/aspnetcore-runtime-8.0.21-win-x64.exe"
}
}
}
```
> **注意**: 此 API 的 `runtime_download_url` 字段可以覆盖项目配置中的运行库下载地址,用于紧急切换 CDN 等场景。客户端优先使用此处的地址,如果此处未提供则 fallback 到项目配置中的地址。
**响应示例(`r0_launcher`**:
```json
{
"code": 0,
"message": "success",
"data": {
"project_id": "r0_launcher",
"version": "1.2.0",
"download_url_cdn": "https://cdn.r0csgo.com/releases/r0_launcher_v1.2.0.exe",
"threads": 8,
"changelog": "新增游戏管理功能"
}
}
```
---
### API 5: 检查更新
**用途**: 替代原有的 `/v2/update/check``/v2/update/check_ac`,统一为一个接口。
```
GET /v3/update/check?project={project_id}&v={current_version}
```
**请求参数**:
| 参数 | 位置 | 类型 | 必填 | 说明 |
| --------- | ----- | ------ | --- | ------------------------------------------ |
| `project` | query | string | 是 | 项目ID,如 `r0_arena``r0_guard``r0_launcher` |
| `v` | query | string | 是 | 当前版本号 |
**响应示例(无更新)**:
```json
{
"code": 0,
"message": "success",
"data": {
"has_update": false,
"latest_version": "3.0.5",
"current_version": "3.0.5"
}
}
```
**响应示例(全量更新)**:
```json
{
"code": 0,
"message": "success",
"data": {
"has_update": true,
"latest_version": "3.1.0",
"current_version": "3.0.3",
"update_type": "full",
"download_url": "https://cdn.r0csgo.com/releases/r0_arena_v3.1.0.exe",
"file_size": "156000000",
"total_size": "156000000",
"changelog": "大版本更新,需要全量安装",
"threads": 8,
"silent": true
}
}
```
> **按版本指定静默更新(`silent` 字段)**:在本接口的响应中返回 `"silent": true`,即可让“更新到该目标版本”这一次走静默(无界面)流程;返回 `false` 则强制弹界面。
> 这是**云端按版本控制**的开关:你在版本表里给某个版本打上静默标记,服务端检查更新命中该版本时下发 `silent`,客户端即据此决定。
> 优先级:命令行 `--silent` > 本接口的 `silent` 字段 > `command_rules[].silent` / `update_target.silent`。若本接口未返回 `silent` 字段,则回退到命令/更新目标级配置。
> `silent` 字段对 `full` / `incremental` / `multi_incremental` 三种更新类型都生效。全量包静默安装所用参数见前文 `silent_install_args`。
**响应示例(单个增量更新)**:
```json
{
"code": 0,
"message": "success",
"data": {
"has_update": true,
"latest_version": "3.0.6",
"current_version": "3.0.5",
"update_type": "incremental",
"download_url": "https://cdn.r0csgo.com/patches/r0_arena_3.0.5_to_3.0.6.zip",
"file_size": "5200000",
"total_size": "5200000",
"changelog": "修复了登录问题",
"threads": 8,
"silent": false
}
}
```
> 上例 `"silent": false` 表示该版本明确要求**弹界面**更新;省略该字段则由命令/更新目标级配置决定。
**响应示例(多步增量更新)**:
```json
{
"code": 0,
"message": "success",
"data": {
"has_update": true,
"latest_version": "3.0.8",
"current_version": "3.0.5",
"update_type": "multi_incremental",
"total_size": "15600000",
"changelog": "多版本增量更新",
"threads": 8,
"incremental_updates": [
{
"from_version": "3.0.5",
"to_version": "3.0.6",
"download_url": "https://cdn.r0csgo.com/patches/r0_arena_3.0.5_to_3.0.6.zip",
"file_size": "5200000",
"changelog": "修复了登录问题"
},
{
"from_version": "3.0.6",
"to_version": "3.0.7",
"download_url": "https://cdn.r0csgo.com/patches/r0_arena_3.0.6_to_3.0.7.zip",
"file_size": "4800000",
"changelog": "性能优化"
},
{
"from_version": "3.0.7",
"to_version": "3.0.8",
"download_url": "https://cdn.r0csgo.com/patches/r0_arena_3.0.7_to_3.0.8.zip",
"file_size": "5600000",
"changelog": "新增功能"
}
]
}
}
```
---
## 四、现有硬编码 → API 字段对照表
以下是当前代码中所有硬编码参数到 API 的映射关系,方便你实现后端时理解每个字段的来源:
### 4.1 Program.cs 中的硬编码
| 原硬编码 | 原始值 | 新来源 |
| ------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `UPDATE_CHECK_API` | `https://a-p-i.r0csgo.com/v2/update/check?v={0}` | `installer_config.command_rules` → 匹配到 project → `project_config.update.check_api` |
| `UPDATE_CHECK_AC_API` | `https://a-p-i.r0csgo.com/v2/update/check_ac?v={0}` | `installer_config.command_rules` → 匹配到 project → `project_config.update_ac.check_api` |
| `DetectInstallMode()` 中的文件名判断 `R0ClientInstaller` | 硬编码前缀 | `installer_config.filename_rules[].pattern` |
| `DetectInstallMode()` 中的文件名判断 `R0AcInstaller` | 硬编码前缀 | `installer_config.filename_rules[].pattern` |
| `command == "update"` | 硬编码命令 | `installer_config.command_rules[].command` |
| `command == "update_ac"` | 硬编码命令 | `installer_config.command_rules[].command` |
### 4.2 MainForm.cs 中的硬编码
| 原硬编码 | 原始值 | 新来源 |
| ---------------------------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| `API_URL` | `https://a-p-i.r0csgo.com/v2/version/index` | `/v3/version/index?project={project_id}` |
| `DEFAULT_VC_REDISTRIB_X86_URL` | `https://cdn.r0csgo.com/runtime/VC_redist.x86.exe` | `project_config.runtime_requirements[].download_url_x86` |
| `DEFAULT_VC_REDISTRIB_X64_URL` | `https://cdn.r0csgo.com/runtime/VC_redist.x64.exe` | `project_config.runtime_requirements[].download_url_x64` |
| `DEFAULT_DOTNET_SDK_X64_URL` | `https://cdn.r0csgo.com/runtime/windowsdesktop-runtime-8.0.21-win-x64.exe` | `project_config.runtime_requirements[].download_url_x64` |
| `DEFAULT_DOTNET_SDK_X86_URL` | `https://cdn.r0csgo.com/runtime/windowsdesktop-runtime-8.0.21-win-x86.exe` | `project_config.runtime_requirements[].download_url_x86` |
| `DEFAULT_ASPNET_CORE_X64_URL` | `https://cdn.r0csgo.com/runtime/aspnetcore-runtime-8.0.21-win-x64.exe` | `project_config.runtime_requirements[].download_url_x64` |
| `DEFAULT_ASPNET_CORE_X86_URL` | `https://cdn.r0csgo.com/runtime/aspnetcore-runtime-8.0.21-win-x86.exe` | `project_config.runtime_requirements[].download_url_x86` |
| `CHUNK_SIZE` = 10MB | 10485760 | `project_config.download_config.chunk_size` |
| `DEFAULT_MAX_THREADS` = 8 | 8 | `project_config.download_config.max_threads` |
| `INSTALL_VC_RUNTIME` = true | true | `project_config.runtime_requirements[runtime_id=vc_redist].enabled` |
| `INSTALL_DOTNET_RUNTIME` = false | false | `project_config.runtime_requirements[runtime_id=dotnet_desktop].enabled` |
| `INSTALL_ASPNET_RUNTIME` = false | false | `project_config.runtime_requirements[runtime_id=aspnet_core].enabled` |
| `USER_AGENT` | `r0_installer` | `project_config.download_config.user_agent` |
| 窗口标题 `R0对战平台安装程序` | 硬编码 | `project_config.install.window_title` |
| 步骤名称 `1. 环境检查` / `2. 反作弊安装` / `3. 主程序安装` | 硬编码 | `project_config.install.steps[].display_name` |
| 临时文件名 `r0_guard.exe` | 硬编码 | `project_config.install.steps[step_id=anticheat].temp_filename` |
| 临时文件名模板 `r0_arena_v{0}.exe` | 硬编码 | `project_config.install.steps[step_id=main].temp_filename_template` |
| 关闭进程 `r0_arena`, `R0对战平台` | 硬编码 | `project_config.update.processes_to_close` |
| 注册表检测路径 | 硬编码列表 | `project_config.runtime_requirements[].detection.keys` |
| dotnet 版本检测 `8.0.21` | 硬编码 | `project_config.runtime_requirements[].detection.version` |
| VC++ 安装参数 `/install /passive /norestart` | 硬编码 | `project_config.runtime_requirements[].install_args` |
### 4.3 UpdateManager.cs 中的硬编码
| 原硬编码 | 原始值 | 新来源 |
| --------------------------- | ------------------------------------------------- | ---------------------------------------------- |
| `UPDATE_CHECK_API` | `https://a-p-i.r0csgo.com/v2/update/check?v={0}` | `project_config.update.check_api` |
| `UPDATE_CHECK_AC_API` | `https://a-p-i.r0csgo.com/v2/update/check_ac?v={0}` | `project_config.update_ac.check_api` |
| 临时文件名 `r0_arena_v{0}.exe` | 硬编码 | `project_config.update.temp_filename_template` |
| 临时文件名 `r0_patch_{guid}.zip` | 硬编码前缀 | 保持不变(通用增量包命名,与项目无关) |
### 4.4 UpdateForm.cs 中的硬编码
| 原硬编码 | 原始值 | 新来源 |
| --------------------------------- | --- | -------------------------------------------------------------------------------------------- |
| 窗口标题 `R0反作弊更新程序` / `R0对战平台更新程序` | 硬编码 | `project_config.update.window_title` / `project_config.update_ac.window_title` |
| 关闭进程 `R0Guard` | 硬编码 | `project_config.update_ac.processes_to_close` |
| 关闭进程 `r0_arena`, `R0对战平台` | 硬编码 | `project_config.update.processes_to_close` |
| hold 文件名 `ac.hold_install` | 硬编码 | `project_config.update_ac.hold_file` |
| 启动程序 `R0Guard.exe` / `R0对战平台.exe` | 硬编码 | `project_config.update.launch_after_update` / `project_config.update_ac.launch_after_update` |
---
## 五、客户端改造后的启动流程
```
程序启动
├─> 1. 调用 GET /v3/config/installer 获取全局配置(缓存到本地)
├─> 2. 判断启动模式:
│ ├─ 有命令行参数(如 update / update_ac / update_launcher
│ │ └─> 从 command_rules 匹配 → 得到 project_id 和 update_target
│ │ └─> 调用 GET /v3/config/project/{project_id} 获取项目配置
│ │ └─> 使用 project_config.{update_target}.check_api 检查更新
│ │ └─> 判断是否静默(命令行 --silent / command_rules.silent / update_target.silent
│ │ ├─ 静默:后台执行更新,无界面(SilentUpdater
│ │ └─ 非静默:弹出更新窗口执行更新(UpdateForm)
│ │
│ └─ 无命令行参数(安装模式)
│ └─> 从 filename_rules 匹配 exe 文件名 → 得到 project_id 和 install_mode
│ └─> 调用 GET /v3/config/project/{project_id} 获取项目配置
│ └─> 调用 GET /v3/version/index?project={project_id} 获取版本信息
│ └─> 按 install.steps 和 install_mode 执行安装步骤
└─> 3. 完成
```
---
## 六、错误响应格式
所有 API 统一使用以下错误格式:
```json
{
"code": 1001,
"message": "项目不存在",
"data": null
}
```
**错误码定义**:
| 错误码 | 说明 |
| ---- | ------- |
| 0 | 成功 |
| 1001 | 项目不存在 |
| 1002 | 版本参数无效 |
| 1003 | 配置不存在 |
| 5000 | 服务器内部错误 |
---
## 七、缓存策略建议
| API | 缓存时间 | 说明 |
| ------------------------- | ---- | ---------- |
| `/v3/config/installer` | 1小时 | 文件名规则变化不频繁 |
| `/v3/config/project/{id}` | 30分钟 | 项目配置变化不频繁 |
| `/v3/version/index` | 不缓存 | 需要实时获取最新版本 |
| `/v3/update/check` | 不缓存 | 需要实时检查更新 |
客户端应在本地缓存 `installer``project` 配置,在网络不可用时使用缓存版本作为 fallback。
---
## 八、向后兼容方案
为了平滑过渡,建议:
1. **v2 API 继续保留**,旧版安装器仍然可以工作
2. **v3 API 新增**,新版安装器使用 v3
3. 客户端先尝试调用 v3,如果 404 则 fallback 到 v2 行为(使用内置硬编码默认值)
4. `project_config` 缓存到 `%TEMP%\r0_installer_config_{project_id}.json`API 不可用时读取缓存
---
## 九、新增应用接入流程(后续操作指南)
假设要新增一个叫 "R0社区" 的应用:
1. **后端操作**:
- 在数据库中新增项目 `r0_community`
- 配置该项目的安装步骤、运行库需求、更新参数
-`installer` 配置中添加 `filename_rules``command_rules`
2. **发布安装器**:
- 编译安装器,命名为 `R0CommunityInstaller.exe`
- 安装器无需改代码,会自动从 API 获取 `r0_community` 项目的配置
3. **发布更新器**:
- 应用内调用 `R0Installer.exe update_community <version>`
- 安装器自动匹配 `command_rules` 中的 `update_community` 规则
- 如需无界面静默更新:在 `command_rules` 中将该规则 `silent` 设为 `true`,或调用时追加 `--silent` 参数(`R0Installer.exe update_community <version> --silent`
---
## 十、数据库表结构建议
### projects 表
```sql
CREATE TABLE projects (
id INT PRIMARY KEY AUTO_INCREMENT,
project_id VARCHAR(50) UNIQUE NOT NULL,
display_name VARCHAR(100) NOT NULL,
description TEXT,
icon_url VARCHAR(500),
enabled TINYINT(1) DEFAULT 1,
config_json JSON NOT NULL, -- 存储完整的项目配置 JSON
created_at DATETIME DEFAULT NOW(),
updated_at DATETIME DEFAULT NOW() ON UPDATE NOW()
);
```
### installer_config 表
```sql
CREATE TABLE installer_config (
id INT PRIMARY KEY AUTO_INCREMENT,
config_key VARCHAR(50) UNIQUE NOT NULL, -- 如 'global'
filename_rules JSON NOT NULL,
command_rules JSON NOT NULL,
default_project VARCHAR(50),
default_mode VARCHAR(20),
created_at DATETIME DEFAULT NOW(),
updated_at DATETIME DEFAULT NOW() ON UPDATE NOW()
);
```
### project_versions 表
```sql
CREATE TABLE project_versions (
id INT PRIMARY KEY AUTO_INCREMENT,
project_id VARCHAR(50) NOT NULL,
version VARCHAR(50) NOT NULL,
download_url VARCHAR(500) NOT NULL,
file_size BIGINT DEFAULT 0,
changelog TEXT,
threads INT DEFAULT 8,
extra_downloads JSON, -- 额外下载项(如反作弊包)
runtime_urls JSON, -- 运行库下载地址覆盖
is_latest TINYINT(1) DEFAULT 0,
created_at DATETIME DEFAULT NOW(),
UNIQUE KEY (project_id, version)
);
```
### project_patches 表(增量更新包)
```sql
CREATE TABLE project_patches (
id INT PRIMARY KEY AUTO_INCREMENT,
project_id VARCHAR(50) NOT NULL,
from_version VARCHAR(50) NOT NULL,
to_version VARCHAR(50) NOT NULL,
download_url VARCHAR(500) NOT NULL,
file_size BIGINT DEFAULT 0,
changelog TEXT,
created_at DATETIME DEFAULT NOW(),
UNIQUE KEY (project_id, from_version, to_version)
);
```