Skip to content

dbv/dota2-copilot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Dota2 Copilot

一个用 C# / WPF (.NET 8) 写的 Dota 2 桌面辅助 Overlay。基于 Valve 官方提供的 Game State Integration (GSI) 读取本机游戏数据,在屏幕上渲染半透明信息面板并提供语音播报。

合规说明:仅消费 Valve 官方 GSI 在本机回调的 JSON 数据。不做任何注入、内存读取、抓包、按键模拟。这与 Overwolf 等同类做法的原理一致。


界面预览

游戏内 Overlay

半透明置顶浮窗,可拖动 / 缩放 / 鼠标穿透,实时显示英雄状态、神符 / 肉山 / 大招倒计时。

游戏内 Overlay

主面板 · 概览

GSI 连接状态、实时游戏数据、智能建议;支持一键安装 GSI 配置文件、重启 GSI 服务。

主面板 - 概览

主面板 · 快捷键管理

DataGrid 直接查看与编辑全局热键,支持「捕获组合键」一键绑定。

主面板 - 快捷键

主面板 · 经验知识库

按阶段 / 关键词检索游戏经验,可直接编辑 JSON 后热加载。

主面板 - 知识库


目录


功能特性

模块 说明
敌我血量监控 我方英雄实时血条 + 数值;敌方信息基于 GSI hero.team3 节点(观战 / 演示模式可见)
蓝量监控 实时蓝量条 + 数值 + 百分比
神符刷新提示 每 2 分钟周期倒计时;30s / 10s 自动语音播报;区分水神符 / 强化神符 / 赏金能量神符
Roshan 提示 死亡 / 重生窗口(min~max)显示;状态切换自动语音播报
我方 / 敌方大招 大招冷却列表;敌方大招就绪自动语音播报,去抖避免重复
团战关键技能 与大招同列表展示,可在英雄白名单中扩展任意关键技能
经验知识库 内置 JSON 知识库,按阶段 / 英雄 / 关键词检索;按局势(HP/MP/时间)自动推荐建议
全局快捷键 任意时刻呼出主面板 / 显隐 Overlay / 缩放 / 静音
Overlay 缩放 0.5x ~ 2.5x 平滑缩放、不透明度调节、鼠标穿透模式
DPI 自适应 manifest 启用 PerMonitorV2,4K 高分屏文字不糊
设置持久化 所有偏好保存到 %AppData%/Dota2Copilot/settings.json,含一次性迁移逻辑

快速上手

环境要求

  • Windows 10 / 11
  • .NET 8 SDK(下载
  • Steam 上正版 Dota 2

1. 构建运行

# 克隆/进入项目目录后
dotnet build .\Dota2Copilot.sln -c Release
.\src\Dota2Copilot\bin\Release\net8.0-windows\Dota2Copilot.exe

启动后会同时出现:

  • Overlay 浮窗(默认右上角,可拖动)
  • 主面板(默认显示,关闭按钮等于隐藏到后台)

2. 安装 GSI 配置(一次性)

打开主面板 → 概览 → 安装 GSI 配置文件,选择 Dota 2 的 game/dota 目录,常见位置:

<Steam>/steamapps/common/dota 2 beta/game/dota

程序会自动写入:

<dota>/cfg/gamestate_integration/gamestate_integration_dota2copilot.cfg

3. Dota 2 启动项

在 Steam 库中右键 Dota 2 → 属性 → 启动选项 中追加:

-gamestateintegration

重启游戏。开打后 GSI 会向 http://127.0.0.1:39999/ 自动 POST JSON。


默认快捷键

都可以在主面板「快捷键」页捕获修改。失败时会单条提示哪个键被占用,其它键继续生效。

功能 默认
显示/隐藏 主面板 Ctrl + Shift + D
显示/隐藏 Overlay Ctrl + Alt + O
放大 Overlay Ctrl + Alt + =
缩小 Overlay Ctrl + Alt + -
静音/恢复 语音 Ctrl + Alt + M

避开 Ctrl+Shift+O / F12 / Ctrl+Alt+A 等被 Steam、NVIDIA、微信/QQ 截图、输入法占用的键。


使用说明

主面板(5 个 Tab)

1. 概览

  • GSI 端口配置 + 重启 GSI 服务 + 安装 GSI 配置文件
  • 实时游戏数据:游戏状态 / 英雄 / 神符 / 肉山
  • 智能建议:根据当前 HP/MP/游戏时间自动从知识库挑一条建议
  • 隐藏到后台:等同关闭按钮,应用仍在运行
  • 退出 Copilot:完全结束应用

概览页

2. 界面 / Overlay

  • UI 缩放:滑块 0.5x ~ 2.5x(也可用 Ctrl+Alt+= / Ctrl+Alt+-
  • 不透明度:0.3 ~ 1.0
  • 鼠标穿透:勾选后 Overlay 不抢点击,但也无法拖动;要调位置先取消勾选
  • 显示 / 隐藏 Overlay 按钮
  • 显示项开关(血量/蓝量/神符/肉山/我方大招/敌方大招/关键技能)

3. 语音提示

  • 启用开关、音量、语速
  • "测试语音"按钮验证 TTS

4. 快捷键

  • DataGrid 显示所有热键
  • 选中行 → "捕获组合键" → 按下任意组合 → "应用并保存"
  • 单键冲突会弹窗指出哪个键被占用,其它键照样生效

快捷键

5. 经验知识库

  • 关键词搜索 + 阶段筛选(early / mid / late)
  • "刷新"按钮热重载磁盘上的 knowledge_base.json
  • "打开知识库 JSON" 直接在记事本里编辑

经验知识库

Overlay

  • 拖动:左键按住任意空白处即可(鼠标穿透模式下需关闭穿透)
  • 缩放:快捷键或主面板滑块
  • 位置/大小/不透明度:自动持久化到设置文件,下次启动恢复

游戏内 Overlay


架构设计

┌─────────────────────────────────────────────────────────────┐
│                        WPF Process                          │
│                                                             │
│  ┌────────────────┐   POST /     ┌─────────────────────┐    │
│  │  Dota 2 Game   │ ───────────▶ │   GsiHttpServer     │    │
│  │  (-gameint…)   │   JSON       │  (HttpListener)     │    │
│  └────────────────┘              └──────────┬──────────┘    │
│                                             │ PayloadReceived│
│                                             ▼               │
│                                  ┌─────────────────────┐    │
│                                  │  GameStateTracker   │    │
│                                  │  - GSI 解析归一化   │    │
│                                  │  - 神符/Roshan 计时 │    │
│                                  │  - 大招就绪事件     │    │
│                                  │  - INotifyProperty  │    │
│                                  └──────┬──────────────┘    │
│                                         │ Property/Alert    │
│       ┌─────────────────────────────────┼─────┐             │
│       ▼                                 ▼     ▼             │
│  ┌──────────┐  ┌──────────────┐  ┌──────────────────┐      │
│  │ Overlay  │  │  MainWindow  │  │  VoiceService    │      │
│  │ Window   │  │  (Tabs)      │  │  (SAPI 队列)     │      │
│  └──────────┘  └──────┬───────┘  └──────────────────┘      │
│                       │                                     │
│              ┌────────┴────────┐                            │
│              ▼                 ▼                            │
│     ┌───────────────┐  ┌──────────────┐                     │
│     │ HotkeyManager │  │ KnowledgeBase│                     │
│     │ (Win32 hotkey)│  │ (JSON 检索)  │                     │
│     └───────────────┘  └──────────────┘                     │
│                                                             │
│              ┌────────────┐                                 │
│              │AppSettings │  %AppData%/Dota2Copilot/        │
│              │            │  settings.json                  │
│              └────────────┘                                 │
└─────────────────────────────────────────────────────────────┘

关键模块说明

Gsi/GsiHttpServer

  • 基于 System.Net.HttpListener 的轻量服务,只接受 127.0.0.1 的 POST
  • 默认端口 39999,可在主面板修改并热重启
  • 反序列化为 GsiPayload 后通过 PayloadReceived 事件传出
  • 解析失败 / 端口异常通过 ServerError 事件上报,不会让进程崩溃

Services/GameStateTracker

  • 实现 INotifyPropertyChanged,WPF 控件可直接绑定
  • 同时兼容单人模式(GSI 平铺字段)和观战/Demo 模式(team2/team3 → playerN 嵌套结构)
  • 神符规则clock_time mod 120 计算下次刷新;30s/10s 触发 AlertRaised;类型识别水/强化/赏金能量
  • Roshan:优先取顶层 roshan 节点,回退到 map.roshan_state;状态变化触发语音
  • 大招就绪去抖:用 Dictionary<owner|name, bool> 记录上一次状态,避免重复播报

Services/HotkeyManager

  • 封装 Win32 RegisterHotKey / UnregisterHotKey
  • 通过 HwndSource 拦截 WM_HOTKEY = 0x0312 消息
  • 默认带 MOD_NOREPEAT 防长按重复触发
  • 注册失败抛带 WinErr=N 的异常,上层做友好提示

Services/VoiceService

  • 基于 System.Speech.Synthesis.SpeechSynthesizer
  • 单线程 BlockingCollection<string> 队列,避免 UI 线程被 Speak 阻塞
  • 启动时自动选择系统中第一个 zh-* 语音

Services/KnowledgeBase

  • 简单 JSON 文件 + LINQ 多字段过滤
  • Recommend(gameTime, hero, hpPct, mpPct) 根据局势返回最匹配条目
  • 支持热重载("刷新"按钮)

Views/OverlayWindow

  • WindowStyle=None + AllowsTransparency=True + Topmost=True
  • 整体放在一个 <Grid> 上挂 ScaleTransform,缩放即改 ScaleX/Y
  • WS_EX_TOOLWINDOW 防止出现在 Alt+Tab;WS_EX_TRANSPARENT 切换鼠标穿透
  • 通过 App.State.PropertyChanged 自动刷新

Views/MainWindow

  • 5 个 Tab + 全局热键 Attach 点
  • 关闭按钮重写为隐藏:保证应用驻留后台、热键继续生效
  • "退出 Copilot" 按钮才真正 Application.Shutdown()

数据流

Dota 2 (GSI cfg)
   │  POST JSON  (~10 Hz, "throttle 0.1" 控制)
   ▼
GsiHttpServer ── PayloadReceived ──▶ Dispatcher.Invoke
                                          │
                                          ▼
                                  GameStateTracker.Apply
                                  ├─▶ INotifyPropertyChanged ──▶ OverlayWindow / MainWindow
                                  └─▶ AlertRaised ──▶ VoiceService.Speak

UI 线程性能要点:

  • HTTP 接收在线程池,反序列化也在线程池
  • State.Apply 与 UI 更新走 Dispatcher
  • 大招列表用 BindingList<UltimateInfo> + ResetBindings() 批量刷新

项目结构

dota2-copilot/
├─ Dota2Copilot.sln
├─ README.md
├─ .gitignore
├─ demo/                            README 中引用的截图
│  ├─ overlay.png
│  ├─ main-overview.png
│  ├─ main-hotkeys.png
│  └─ main-knowledge.png
└─ src/Dota2Copilot/
   ├─ Dota2Copilot.csproj            .NET 8 + WPF + System.Speech
   ├─ app.manifest                   PerMonitorV2 DPI 感知
   ├─ App.xaml / App.xaml.cs         全局服务装配 / 启动迁移
   ├─ Gsi/
   │  ├─ GsiPayload.cs               GSI JSON 模型
   │  └─ GsiHttpServer.cs            127.0.0.1:39999 HttpListener
   ├─ Services/
   │  ├─ GameStateTracker.cs         状态聚合 / 神符 / Roshan / 大招事件
   │  ├─ HotkeyManager.cs            Win32 RegisterHotKey 封装
   │  ├─ VoiceService.cs             SAPI 中文 TTS 队列
   │  ├─ KnowledgeBase.cs            经验库 + 局势自动推荐
   │  └─ AppSettings.cs              配置持久化
   ├─ Views/
   │  ├─ OverlayWindow.xaml(.cs)     无边框透明置顶悬浮,可拖动/缩放/穿透
   │  └─ MainWindow.xaml(.cs)        概览 / Overlay / 语音 / 热键 / 知识库
   └─ Resources/
      ├─ knowledge_base.json         可热编辑的经验条目
      └─ gamestate_integration_dota2copilot.cfg

配置文件

应用设置:%AppData%\Dota2Copilot\settings.json

默认 说明
GsiPort 39999 GSI 监听端口
VoiceEnabled true 语音总开关
VoiceVolume / VoiceRate 90 / 1 音量 0-100、语速 -10 ~ 10
OverlayScale 1.4 启动缩放(< 1.2 会自动迁移到 1.4)
OverlayOpacity 0.85 Overlay 不透明度
OverlayLeft / OverlayTop 100 / 100 Overlay 屏幕位置
Show* true 各显示项开关
Hotkeys dict 功能 ID → 组合键字符串

自动迁移App.xaml.cs.Application_Startup):

  • OverlayScale < 1.2 → 升到 1.4
  • toggle_overlay == "Ctrl+Shift+O" → 改为 "Ctrl+Alt+O"(避开 Steam)

GSI 配置:gamestate_integration_dota2copilot.cfg

"uri"      "http://127.0.0.1:39999/"
"timeout"  "5.0"
"buffer"   "0.1"
"throttle" "0.1"
"heartbeat" "10.0"
"data" {
    "provider 1, map 1, player 1, hero 1, abilities 1,
     items 1, events 1, buildings 1, league 1, draft 1,
     wearables 1, minimap 1, roshan 1, couriers 1,
     neutralitems 1"
}

知识库:Resources/knowledge_base.json

[
  {
    "phase": "early",          // early / mid / late,可空
    "hero": "invoker",         // 英雄 internal name 子串匹配,可空
    "tags": ["卡尔", "连招"],   // 关键词检索时也会匹配
    "title": "祈求者团战",
    "advice": "ZEEE 阵地战;EMP 在团前留蓝量..."
  }
]

扩展开发

新增一条快捷键功能

  1. AppSettings.Hotkeys 默认表里加键,例如 ["screenshot"] = "Ctrl+Alt+P"
  2. MainWindow.InitHotkeyRows() 添加 DataGrid 行
  3. MainWindow.HandleHotkey(string id)case "screenshot": 分支

新增 Overlay 上的字段

  1. GameStateTracker 加属性 + INotifyPropertyChanged 通知
  2. OverlayWindow.xaml 拖一个 <TextBlock> 绑定即可
  3. 必要时在 Apply() / ApplyAbilities() 里补解析

新增语音事件

  1. GameStateTracker 找到合适的状态变化点
  2. AlertRaised?.Invoke(this, new GameAlert(GameAlertType.Custom, "提示词"))
  3. App.xaml.cs 已统一桥接到 VoiceService.Speak

自定义知识库

直接编辑 Resources/knowledge_base.json,主面板「经验知识库 → 刷新」热加载。


故障排查

启动报 NRE / XAML 解析异常

  • 已修:XAML 里 IsSelected="True" 触发的 SelectionChanged 在控件初始化前被回调。RefreshKnowledgeGrid 加了 IsLoaded 守卫
  • 如还遇到,请贴 stack trace

重新构建报错 "文件被 Dota2Copilot 锁定"

旧实例还在后台。PowerShell 运行:

Get-Process Dota2Copilot -ErrorAction SilentlyContinue | Stop-Process -Force

然后再 dotnet build

弹窗"快捷键注册失败 (xxx): WinErr=1409"

ERROR_HOTKEY_ALREADY_REGISTERED,组合键已被其他程序占用。常见占用方:

  • Steam Overlay(截图键,常占 Ctrl+Shift+O / F12
  • NVIDIA GeForce Experience / ShadowPlay
  • 微信、QQ 截图(Ctrl+Alt+A
  • 各类输入法

进入主面板「快捷键」→ 选中行 → 捕获组合键 → 换一个不冲突的组合 → 应用并保存。

Overlay 看不见 / 不在最上层

  • Dota 2 用 独占全屏 时 Overlay 会被遮蔽,请改"全屏窗口化"
  • 多显示器:先把 Overlay 拖到 Dota 2 所在显示器(关闭"鼠标穿透"才能拖)
  • 检查 OverlayLeft/Top 是否被拖到屏幕外,删除 settings.json 重置

没有声音 / 中文发音怪

  • 系统设置 → 时间和语言 → 语音 → 添加"中文(简体,中国)"语音包
  • 重启应用(语音引擎在启动时选择 voice)
  • 主面板「语音提示 → 测试语音」验证

GSI 没数据

  • 启动项是否加了 -gamestateintegration
  • cfg 文件名必须以 gamestate_integration_ 开头
  • 端口被占?主面板"重启 GSI 服务"换一个端口,并同步修改 cfg 中的 uri
  • Windows 防火墙首次会弹窗,记得放行(仅 127.0.0.1 实际不需要)

文字模糊(高 DPI 屏)

  • 项目已开启 PerMonitorV2 应该不会糊;若仍糊,确认 exe 属性 → 兼容性 → DPI 缩放设置 没被强制覆盖

删除所有偏好回到默认

关闭应用后删除:

%AppData%\Dota2Copilot\settings.json

下次启动会用全新默认值。

About

dota2 助手

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages