# 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 --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 ` - 安装器自动匹配 `command_rules` 中的 `update_community` 规则 - 如需无界面静默更新:在 `command_rules` 中将该规则 `silent` 设为 `true`,或调用时追加 `--silent` 参数(`R0Installer.exe update_community --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) ); ```