内容
# Dota 2 工作室 MCP
一个 [MCP](https://modelcontextprotocol.io) 服务器,允许 AI 助手(Claude Code、Claude Desktop、Cursor 等)使用工作室工具开发 **Dota 2 自定义游戏**:编辑 KeyValues,搭建技能/修饰语/物品/单位/英雄/Panorama,搜索 VScript(Lua)modding API,并构建和启动游戏。
它**具有模板感知能力**:对于 [ModDota TypeScript 插件模板](https://github.com/ModDota/TypeScript-Addon-Template),它会搭建 TypeScript(`@registerAbility` / `@registerModifier`,KV `ScriptFile` 指向编译后的 `.lua`,`#base` 连接)并驱动模板的 `npm` 脚本。它还具有原始 Lua + `resourcecompiler.exe` 的备用方案,适用于非 tstl 插件。
> 状态:正在运行 — **107 个工具**,端到端测试。它可以搜索工作室中的自定义游戏并下载它们(在客户端之外)(SteamCMD)进行研究,生成整个可玩地图(基于 Dota 瓦片网格的 terrain 塑造 + 实体 + 路径 → 编译 → .vpk),在不启动游戏的情况下以图像预览它们,编辑 KV1 + KV3(声音事件/粒子)数据,从 VPK 直接读取基础游戏文件,并搭建 TS/Lua 内容、Panorama、自定义事件和网络表。它还可以通过 **VConsole2** 协议(经过验证的运行客户端:连接、发送命令、读取实时输出、热重载、重启、截图、错误监视)和捆绑的、可搜索的 VScript API 副本、Panorama JS API、ModDota 指南和从已发布的游戏中提炼的 **77** 个设计模式的知识库(`dota_patterns`)进行实时调试循环。
## 功能
| 领域 | 工具 |
| --- | --- |
| **诊断和状态** | `dota_doctor`、`addon_list`、`addon_info`、`dota_status`、`addon_audit` |
| **KeyValues** | `kv_read`、`kv_get_entry`、`kv_upsert_entry`、`kv_remove_entry`、`kv_validate`、`kv_format` |
| **搭建** | `scaffold_ability`、`scaffold_modifier`、`scaffold_item`、`scaffold_unit`、`scaffold_hero`、`scaffold_panorama_panel` |
| **系统搭建器** | `scaffold_notifications`、`scaffold_nettable_binding`、`scaffold_rpc`、`scaffold_save_codes`、`scaffold_hud_panel`、`scaffold_wave_system`、`scaffold_shop`、`scaffold_talent_tree`(从已发布的游戏中提炼的成熟基础设施) |
| **VScript API** | `lua_api_search`、`lua_api_get`、`lua_api_class_methods` |
| **构建和启动** | `addon_build`、`addon_compile_content`、`addon_launch_tools`、`addon_launch_custom_game`、`addon_link` |
| **实时调试循环** | `dota_send_console_command`、`dota_read_console_log`、`dota_reload_scripts`、`dota_restart_game`、`dota_dev_cycle`、`dota_screenshot`、`dota_watch_errors`、`dota_wait_for`、`dota_perf` |
| **窗口和输入** | `dota_window`、`dota_focus_window`、`dota_click`、`dota_type`、`dota_input` |
| **游戏内 DebugSDK** | `addon_attach_debug_sdk`、`addon_detach_debug_sdk`、`dota_lua_eval`、`dota_debug_dump`、`dota_selftest` |
| **参考库** | `ref_harvest`、`ref_harvest_top`、`ref_list`、`ref_search`、`ref_find`、`ref_passport`、`ref_inspect`、`ref_get`、`ref_recipe`、`ref_curate`、`ref_stats`、`asset_db`(SQLite 索引:按类型/扩展名/名称快速结构化搜索) |
| **文档和参考** | `docs_search`、`docs_get`、`docs_list`、`dota_patterns`、`panorama_api_search`、`panorama_api_get`、`tools_catalog` |
| **地图** | `map_create`、`map_add_entity`、`map_to_text`、`map_from_text`、`map_compile`、`map_list` |
| **地图生成** | `map_build`、`map_terrain`、`map_preview`、`map_tile_to_world`、`entity_catalog`、`scaffold_td` |
| **参考游戏** | `workshop_search`、`workshop_download`、`workshop_list`、`workshop_inspect`、`workshop_read`、`workshop_grep`、`panorama_decompile` |
| **资产预览(引擎外)** | `asset_preview`(粒子/纹理/模型 → 内联联系表图像 + HTML 图库)、`sound_preview`(声音 → 内联波形/图标图像 + 可播放的 HTML 音频板 + 内联音频)、`preview_studio` / `preview_studio_stop`(交互式图库 + 公共共享链接:动画粒子、3D 模型、音频播放器、单击选择)— 通过 ValveResourceFormat 解码,无需启动 Dota |
| **声音和 KV3** | `soundevents_list`、`soundevents_get`、`soundevents_upsert`、`kv3_read` |
| **资产和基础游戏** | `assets_list`、`assets_search`、`vpk_find`、`vpk_read`、`base_kv_entry` |
| **事件和网络表** | `scaffold_custom_event`、`scaffold_net_table` |
所有内容都已捆绑,因此搜索**离线**有效:
- VScript(Lua)API — 97 个类 / 242 个全局变量 / 72 个枚举,从 [@moddota/dota-data](https://github.com/ModDota/dota-data)。
- Panorama JS API — 62 个接口 / 约 880 个成员 / 18 个全局变量,从 [@moddota/panorama-types](https://github.com/ModDota/TypeScriptDeclarations)。
- 93 个指南页面:83 篇 ModDota 文章(脚本、技能、修饰语、单位、Panorama、资产、工具)来自 [moddota.com](https://moddota.com),一个任务导向的 **自定义游戏烹饪书** 索引(`guides/custom-game-cookbook`)将工具/文档/模式联系起来,加上九个手动编写的参考资料捆绑在 MCP 中 — **Panorama 中的粒子和效果**(`panorama/particles-and-effects`)和 **Dota 2 Panorama CSS 参考**(`panorama/dota-css-reference`),以及从对 34 款已发布自定义游戏的深入分析中提炼的七个文档:**Panorama 动画和效果烹饪书**(`panorama/animations-cookbook`)、**自定义游戏 HUD 和 UX 模式**(`panorama/hud-ux-patterns`)、**自定义游戏架构和系统模式**(`scripting/custom-game-architecture`)、**粒子、声音和游戏感觉**(`scripting/particles-sound-gamefeel`)、**AI 和战斗模式**(`scripting/ai-combat-patterns`)、**劫持和扩展 Dota 的原生 HUD**(`panorama/native-hud-hijacking`)和 **高级技术和引擎限制解决方法**(`scripting/advanced-techniques`)。
- 一个 `dota_patterns` 知识库,包含 **77** 个可重用的工程模式,每个模式都归因于已发布的游戏(从 58 个已反编译的参考语料库中提炼)。
## 要求
- Node.js ≥ 18(在 Node 25 上开发)
- Dota 2 + 免费的 **Dota 2 工作室工具** DLC 安装
- Windows(构建/启动外壳到 `dota2.exe` / `resourcecompiler.exe`;KV + API 工具是跨平台的)
## 安装
```bash
git clone https://github.com/ex3lite/Dota2_Workshop_MCP.git
cd Dota2_Workshop_MCP
npm install # 也通过 prepare 脚本构建
npm run build:data # (可选)刷新捆绑的 VScript API + Panorama API + ModDota 指南
```
`npm install` 运行 `npm run build`,生成 `dist/index.js`(服务器入口点)。
## 配置
服务器需要知道两件事:
- **哪个插件项目** 您正在开发 — 将 `DOTA2_ADDON_DIR` 设置为插件根目录(带有 `package.json` / `game` / `content` 的文件夹),或将 `projectRoot` 传递给任何工具。
- **Dota 2 在哪里** — 从 Windows 注册表 + `libraryfolders.vdf` 自动检测。如果检测失败,请覆盖 `DOTA2_PATH`(指向您的 `dota 2 beta` 文件夹)。
### Claude Code
将 [`examples/claude-code.mcp.json`](examples/claude-code.mcp.json) 复制到您的插件仓库中作为 `.mcp.json`(调整两个路径),或:
```bash
claude mcp add dota2-workshop --env DOTA2_ADDON_DIR=C:\path\to\addon -- node C:\path\to\Dota2_Workshop_MCP\dist\index.js
```
### Claude Desktop
将 [`examples/claude-desktop.config.json`](examples/claude-desktop.config.json) 合并到 `"%APPDATA%\Claude\claude_desktop_config.json"`(绝对路径;重启应用程序)。
### Cursor / 其他 IDE
使用 [`examples/cursor.mcp.json`](examples/cursor.mcp.json) 在 `.cursor/mcp.json` 或 `~/.cursor/mcp.json`。任何 stdio MCP 客户端都有效 — 只有配置位置不同。
## 典型流程
1. `dota_doctor` — 确认找到 Dota,检测到插件,并且它链接到 `dota_addons`。
2. `scaffold_ability` `{ name: "my_hero_fireball", behavior: "point" }` — 编写 TS 源代码、`npc_abilities_custom.txt` 块和本地化令牌。
3. `lua_api_search` / `lua_api_get` — 在编写逻辑时查找确切的 VScript 签名。
4. `addon_build` — 编译 TypeScript → Lua(`npm run build`)。
5. `addon_launch_custom_game` `{ map: "..." }` — 启动工具模式并启动地图。
所有构建/启动工具都接受 `dryRun: true` 以预览确切的命令而不运行它。
## 实时调试和迭代
调试工具通过 **VConsole2** 协议驱动正在运行的游戏 — 与 `vconsole2.exe` 使用的相同通道。在 `-tools` 模式下,游戏监听 `127.0.0.1:29000`(使用 `-vconport` 或 MCP 端的 `DOTA2_VCONPORT` 环境变量覆盖)。这是 Windows 上可靠的路径:经典的 `-netconport` telnet 控制台自 2023 年起在 Windows 上已损坏,而 `console.log` 会在客户端退出时缓冲,因此从 VConsole `PRNT` 流读取实时输出。
启动工具已经传递 `-tools`(和 `-vconport`),因此在 `addon_launch_custom_game` 之后通道可用。然后:
- **`dota_send_console_command`** — 运行任何控制台命令并返回它打印的输出。
- **`dota_read_console_log`** — 读取最近的实时控制台输出(带有可选的 `grep`)。
- **`dota_reload_scripts`** — 编译 + `script_reload`(热重载 Lua 而无需重启)。
- **`dota_restart_game`** — `taskkill` + 重启 + 重新连接(对于无法热重载的更改)。
- **`dota_dev_cycle`** — 一次调用:构建,然后选择最便宜的应用路径(如果重载错误,则带有 `autoRestart`)。
- **`dota_screenshot`** — 两个变体:**`game`** = 游戏内渲染通过 `jpeg` 控制台命令(真正的渲染帧); **`window`** = Dota 2 窗口使用 **真实屏幕像素** 捕获(所以 3D 视口不是黑色 — 像 `PrintWindow` 一样),首先聚焦窗口。(`print` = 离屏 PrintWindow,用于遮挡的窗口。)
- **`dota_watch_errors`** — 扫描实时控制台的 Lua/引擎错误(脚本错误、堆栈跟踪、*.lua:NN,...)。
- **`dota_wait_for`** — 阻止直到控制台行匹配(可选地在发送命令后)— 用于排序测试。
更改内容与需要重启的内容:
| 更改 | 操作 |
| --- | --- |
| Lua 函数体 | `dota_reload_scripts`(`script_reload`) |
| Panorama(xml/css/js)| 编译后自动重载 — 无需重启 |
| KV 文件(`npc_*_custom.txt`) | `dota_restart_game`(完整重启) |
| 新/删除脚本、更改类结构、注册 | `dota_restart_game` |
> 提示:ModDota 模板使用 `Dynamic_Wrap`/`GameRules.Addon.Reload()`,因此重载的代码被拾取 — 为 `script_reload` 生效保持事件监听器包装。## 窗口控制和输入注入
在 Windows 上驱动游戏窗口并注入鼠标/键盘(OS 级别)。默认情况下,坐标是**客户端相对**的(渲染区域的左上角),因此它们与窗口截图显示的内容一致;使用 `nx`/`ny` 获取客户端区域的分数。所有操作都批处理到单个 PowerShell 调用中,因此序列运行速度快。
- **`dota_focus_window`** — 焦点(`focus:true`,击败 Windows 前景锁定的 `AttachThreadInput`)或发送到后台(`focus:false`)。聚焦后需要可靠的点击。
- **`dota_window`** — `info`(几何 + 前景/最小化状态)、`focus`/`unfocus`/`minimize`/`restore`/`maximize`/`show`/`hide` 或 `move`(x/y/w/h)。
- **`dota_click`** — 移动 + 点击(左/右/中,双击)`x,y` 或 `nx,ny`。
- **`dota_type`** — 输入文字,或发送 `keys` 键(`{ENTER}`、{ESC}`、`^a`,...)。
- **`dota_input`** — 一个完整的 `actions` 序列(移动/点击/按下/抬起/拖动/滚动/键入/文本/睡眠)在一调用中 — 编写自测试交互的方式。
## 游戏内 DebugSDK + 自测试
**DebugSDK** 是与 MCP 捆绑的独立 Lua 模块。将它附加到任何插件,它注册 `mcp_*` 控制台命令,MCP 通过 VConsole 进行驱动,用于 **确定性** 控制和检查 — 自测试的快速可靠路径(无需像素猜测)。
- **`addon_attach_debug_sdk`** — 将 `mcp_debug.lua` 复制到插件并将 `require("mcp_debug")` 插入游戏模式引导(TS *或* Lua)。幂等;`addon_detach_debug_sdk` 反转它。然后 `addon_build`(tstl)+ `dota_restart_game`。
- **`dota_lua_eval`** — 在实时服务器上运行 Lua 片段并获取 JSON 结果(`mcp_eval`)。
- **`dota_debug_dump`** — 将游戏状态作为 JSON 导出:`state`(时间/阶段/玩家)、`heroes`、单位)、`heroes`、`units` (`mcp_dump`)。
- **`dota_selftest`** — 一个有组织的冒烟测试:可选地启动地图,ping SDK,运行 `commands`,检查 `asserts`(Lua 布尔值 → 通过/失败通过 `mcp_assert`),监视错误,并截图 — 返回单个通过/失败报告。
SDK 还公开了 `mcp_spawn`、`mcp_gold`、`mcp_level`、`mcp_item`、`mcp_event`(触发自定义 UI 事件)、`mcp_hud`(干净的截图)和 `mcp_pause` — 所有这些也可以通过 `dota_send_console_command` 调用。
## 参考库 — 收集和搜索已发布的游戏
构建一个**持久的、自组织的**本地库,用于存储自定义游戏源代码,然后按需搜索(“一个已发布的游戏如何做到 X?”)。存储在 `~/.dota2-workshop-mcp/reflib` 下(可覆盖 `DOTA2_REFLIB_DIR`)。
- **`ref_harvest`** — 按 `query`(或传递 `ids`)搜索工作室,可选 `download:true` 通过 SteamCMD,提取代码(lua/KV/panorama),**评估代码质量**(0-100;奖励实质/结构/注释,惩罚混淆),分类 **主题**(塔防、自动国际象棋、ARPG、竞技场、UI-heavy、后端,...),并索引它。
- **`ref_search`** — 在所有提取的代码中进行全文搜索,按质量排名靠前的游戏优先显示。
- **`ref_list` / `ref_inspect` / `ref_get`** — 浏览库,列出游戏的文件,读取一个。
- **`ref_curate`** — 使用 `dryRun` 修剪低质量/混淆的游戏。
- **`ref_stats`** — 库摘要。
## 从描述中生成地图
将请求诸如 *"一个带有中央平台的小型方形地图,由道路环绕,怪物行走 — 塔防"* 的请求转换为真正的地图:
- **`map_build`** — 一次调用:克隆模板,形状地形,放置实体,布局路径,注册并编译。地形操作在 **Dota 瓦片网格** (`verticesHeight` / `verticesWater` / `cellsTileSet`) 上进行操作,涉及形状 (`rect` / `circle` / `ring` / `path`): 提升平台,修建道路(不同的瓦片集),填充水沟等。
- **`map_terrain`** — 将地形操作应用于现有地图。
- **`map_preview`** — 将地图渲染为顶视图,生成**数据图像,无需启动游戏** — 快速迭代布局的快速方法(水 = 蓝色,道路 = 棕色,草 = 绿色,按高度阴影)。
- **`entity_catalog`** — 可放置实体参考(spawners,`path_track` 路径点,触发器,灯光,道具,...),以便您知道放置什么。
- **`map_tile_to_world`** — 将瓦片坐标转换为世界单位,以便地形和实体对齐。
坐标:地形操作使用瓦片单位(默认 64×64 网格;世界 = 原点 + 瓦片×256);实体/路径位置使用世界单位。
## 从其他自定义游戏中学习
查找、获取和解剖任何已发布的自定义游戏 — 与客户端使用的相同 Steam UGC 后端,由外部驱动:
- **`workshop_search`** — 按名称搜索(例如 `"tower defense"`)→ ids, 标题, 订阅者数量。
- **`workshop_download`** — 通过 SteamCMD 下载 ID(匿名;自动安装 SteamCMD)。无需 Dota 自定义游戏的 Steam 登录。默认情况下,它会**提取代码并反编译编译后的全景**到参考库,以便立即浏览/搜索(`extract:false` 跳过)。
- **`workshop_grep`** — **在所有下载/订阅的游戏中对代码进行全文搜索**,直接从它们的 VPK 中(lua/KV/panorama,编译后的全景在运行时反编译)— 将范围限定为一个 `id` 或搜索所有内容;按 `ext` 过滤以加快速度。
- **`workshop_list` / `workshop_inspect` / `workshop_read`** — 列出本地项目(订阅 + 下载)并直接从 VPK 读取文件进行研究。已发布的游戏提供 **编译** 全景(`.vcss_c`/`.vjs_c`/`.vxml_c`);`workshop_read` (和 `vpk_read`)**自动反编译** 这些文件为 CSS/JS/XML 源代码,因此您可以研究真正的发货 UI、动画和 HUD。
- **参考库** (`ref_harvest` / `ref_search` / …) — 将游戏收集到一个持久的、按质量评分的、按主题分类的本地代码库(包括反编译的 UI 全景)并按需搜索。
- **`asset_db`** — **所有 unpacked 游戏中的文件 SQLite 索引**,因此通过 **kind/extension/name** 查找任何模型/粒子/声音/纹理的查询是一个快速的结构化查询而不是扫描。`action=search` (默认)/ `stats` / `rebuild`;自动更新下载/解包时。示例:`asset_db query="tower" kind="model"`。
因此,您可以从 *"流行的 TD 如何生成波?"* 转到在几步之内阅读其实际的 `waves.lua`。
## 从描述中生成地图
将请求诸如 *"一个带有中央平台的小型方形地图,由道路环绕,怪物行走 — 塔防"* 的请求转换为真正的地图:
- **`map_build`** — 一次调用:克隆模板,形状地形,放置实体,布局路径,注册并编译。地形操作在 **Dota 瓦片网格** (`verticesHeight` / `verticesWater` / `cellsTileSet`) 上进行操作,涉及形状 (`rect` / `circle` / `ring` / `path`): 提升平台,修建道路(不同的瓦片集),填充水沟等。
- **`map_terrain`** — 将地形操作应用于现有地图。
- **`map_preview`** — 将地图渲染为顶视图,生成**数据图像,无需启动游戏** — 快速迭代布局的快速方法(水 = 蓝色,道路 = 棕色,草 = 绿色,按高度阴影)。
- **`entity_catalog`** — 可放置实体参考(spawners,`path_track` 路径点,触发器,灯光,道具,...),以便您知道放置什么。
- **`map_tile_to_world`** — 将瓦片坐标转换为世界单位,以便地形和实体对齐。
坐标:地形操作使用瓦片单位(默认 64×64 网格;世界 = 原点 + 瓦片×256);实体/路径位置使用世界单位。
### 预览资产而无需启动 Dota
直接从下载的游戏中获取眼球粒子、纹理、模型和声音 — 通过 [ValveResourceFormat](https://github.com/ValveResourceFormat/ValveResourceFormat)(自动安装于首次使用,Windows)进行引擎外解码。两种工具都返回 **聊天中的内联图像**(编号的联系表),因此预览可以在 **远程访问** 中查看,而无需打开浏览器,并且会写入一个自包含的 HTML 页面以进行更丰富的本地查看。
- **`asset_preview`** — 查找匹配的粒子(`.vpcf`)、纹理(`.vtex`)或模型(`.vmdl`),解码它们(纹理 → PNG,模型 → GLB,粒子 → 其精灵纹理),并返回编号的联系表图像内联 + 具有交互式 3D `<model-viewer>` 的 HTML 图库。示例:`asset_preview query="spark" kind="particle"`。
- **`sound_preview`** — 查找匹配的声音(`.vsnd`),解码它们,并返回内联图像(罕见 PCM 声音的实际幅度波形;MP3 的标签扬声器图块 + 准确持续时间,通常的 Dota 编码器 — MP3 不能在引擎外波形转换)+ 具有实际 `<audio>` 播放器的 HTML **声音板**;小声音也内联嵌入为可播放的音频。示例:`sound_preview query="explosion"`。
- **`preview_studio`** — 构建一个丰富的 **交互式** 图库,并在 **公共分享链接**(Cloudflare 快速隧道)上公开,您可以在任何浏览器中打开,包括通过远程访问的手机。粒子会根据其实际 `.vpcf` 参数(移动 + 发光)重放为动画叠加板;模型是交互式 3D(旋转);声音有播放器。每个卡片都有一个稳定的 **ID**(P#/M#/S#/T#)和一个 **«选择» 按钮**:通过点击选择(点击会发布到图库服务器)或告诉代理 ID。`preview_selections` 返回已点击的内容,`preview_pick id="M3,P7"` 解析显式 ID — 两者都将选择映射回源游戏 + 资产路径。`preview_studio_stop` 会将其关闭。
## 内置引用(离线)
无需离开编辑器即可查找内容:
- **`lua_api_search` / `lua_api_get`** — VScript(Lua)服务器 API。
- **`panorama_api_search` / `panorama_api_get`** — Panorama JS API。全局变量解析为其接口:`panorama_api_get $`、`panorama_api_get GameEvents`、`panorama_api_get Players.GetLocalPlayer`。
- **`docs_search` / `docs_get` / `docs_list`** — ModDota 指南。浏览使用 `docs_list`,搜索使用 `docs_search modifier`,阅读使用 `docs_get abilities/ability-keyvalues`。
- **`tools_catalog`** —精选的工具/库/引用列表(按类别或查询过滤)。
## 构建地图
`.vmap` 文件是 DMX 文档。MCP 通过 Valve 的 `dmxconvert.exe` 以文本方式编辑它们(二进制 ↔ keyvalues2),然后使用 `resourcecompiler`(`-game <dota>/game/dota`)编译为可玩的 `.vpk` — 一个经过验证的端到端流程。
- **`map_create`** — 将官方模板地图(地面 + 照明 + 队伍出生点)克隆到您的插件中,并在 `addoninfo.txt` 中注册它。传递 `compile: true` 以立即生成 `.vpk`。
- **`map_add_entity`** — 放置任何实体(`info_player_start_*`、`npc_dota_spawner`、`env_*`、`prop_dynamic`、`point_*`,...)及其原点/角度/属性。
- **`map_to_text` / `map_from_text`** — 读取/写入完整的 vmap DMX 文本以进行任意编辑。
- **`map_compile`** — 编译地图的 `.vmap` → `.vpk`。
- **`map_list`** — 列出具有源/编译状态的地图。
然后启动它:`addon_launch_custom_game map="<name>"`。
> 限制:定制 **几何体**(地形/笔刷工作 — `CDmePolygonMesh` 半边数据)由 **Hammer** 编写。MCP 通过克隆工作底座并放置实体来构建地图;它不会从头开始雕刻任意网格。
## 注释和限制
- `kv_read` 返回文件自己的包装块并列出 `#base` 包含项,但尚未内联 `#base` 文件 — 直接通过 `path` 读取它们。
- 使用 `kv_upsert_entry` 编辑条目会保留其他条目的注释;编辑的条目会根据您的 JSON 重新生成。
- 英雄只能通过覆盖现有英雄来创建(`scaffold_hero` 编写一个 `override_hero` 块)— 这是 Dota 引擎的约束。
## 开发
```bash
npm run dev # 从源代码运行服务器 via tsx
npm test # KV 解析器/序列化器单元测试
npm run smoke # 通过 stdio 启动服务器并端到端地测试工具
```
## 许可证
MIT — 请参阅 [LICENSE](LICENSE)。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器