三角洲口琴自动演奏
三角洲更新了口琴,无奈五音不全+手残,实在学不会。所以做了这个项目来辅助。

免责声明
这个工具靠Windows 键鼠模拟(SendInput)实现按键,不读游戏内存、不注入进程、不含驱动、不做任何反作弊规避,也不修改游戏文件。
但模拟输入本身仍然可能违反用户协议,并导致账号处罚。使用此项目默认知晓,所有后果由使用者承担。
本身是只个人自用工具,与游戏官方无关。它只是想在游戏里把一首曲子完整弹出来,不是拿来获取任何竞技优势的。
下载
下载地址:https://pan.quark.cn/s/eee9d5b7a8a3
项目介绍
三角洲口风琴 MIDI 演奏器,把 MIDI 旋律轨变成游戏口风琴的按键时序,然后按出来。
游戏里的口风琴只有八个音,另外几个鼠标键管升半音和换八度。想手动弹一首完整的歌很难,手跟不上。这个小工具就是补这一步的:导入一份 MIDI,选一条旋律轨,它把整首曲子翻译成「什么时候、按哪个键、按多久」,然后照着这个时间表发送按键。
- 平台:Windows,.NET 10 + WPF,发布成一个自包含单文件 exe,不用安装
- 读谱:DryWetMIDI,保留原曲的变速段落,不会给你放成匀速
- 发键:只用 Windows 普通的 SendInput,不注入进程、不含驱动、不碰游戏文件
- 默认不输出:打开就是「无输入预览」,一个键都不发;要真往游戏里按,得自己勾上「启用游戏输出」再确认一次风险提示
- 代码规模:核心逻辑 400 行出头,配 22 个单元测试,跑测试不用开游戏
- 配置位置:%LocalAppData%\HarmonicaAutoplay\settings.json,删掉就等于恢复默认
项目地址:
使用方式
使用方式
启动游戏→打开口琴→打开项目→导入 MIDI 文件 → 启用游戏内输出 → 点播放或者按 F8(3 秒延迟)→返回游戏
导入 MIDI
支持 .mid 和 .midi。导入后会列出文件里有音符的轨道(名字 + 音符数),默认选第一条,自己下拉换成更像旋律的那条。鼓轨和伴奏轨音很密,选进去会满屏冲突。
这一步之后可以先点一次「播放 / 继续」——此时如果没勾游戏输出,它就只生成预览、一个键都不发。预览表里每个音一行:时间、MIDI 音高、时长、要按住的键(MouseMiddle+B 就是按住鼠标中键再按 B)。冲突和警告列在预览上方,有问题就不给播。第一次建议把速度调成 0.5 慢慢过一遍,确认时间点和按键对不对。
启用游戏内输出。
勾上会弹一次确认框,看过风险再确定。程序不用手动捕获,它自己找三角洲的窗口,面板上会显示「已自动捕获」和窗口名;显示「等待游戏」就先把游戏打开,或者切回程序激活一下窗口,它会重新找。
点播放,或者按 F8。
有三秒倒计时,足够切回游戏。倒计时期间不发任何键。播放中 F8 暂停 / 继续,F9 停止并回到曲首,两个键都能在设置页改。播放中窗口不在前台(比如你切出去看微信),它会立刻松开所有按键并暂停,回来不会自己继续,得自己按 F8;继续是从当前这个音的开头重弹,不是从延音中间接上。停止、暂停、关程序、程序崩了,都会把按住的键松掉。
几个常遇到的提示:
「未检测到三角洲行动窗口」——先启动游戏。开始演奏前程序会再检测一次。
「快捷键不可用」——这个组合被别的程序占了,换一个;改键失败会退回上一次能用的设置,不会把好的一起弄丢。
「音符重叠 / 有冲突」——同一条轨里有音同时响。游戏乐器一次只发一个音,这类谱子直接不给播,换轨或者用 MIDI 编辑器拆成单声部。
按了没反应、游戏里没动静——大概率是游戏不接受普通模拟输入。这工具只会用
SendInput,游戏不认它就报「输入错误,已松开全部按键」,不会换驱动或注入之类的更强手段。听起来糊、有漏音——把松键间隔调大一点(默认 20 毫秒),或者把速度降下来。
输出模式下程序只认三角洲窗口,前台不是游戏就暂停,所以没有「拿记事本先试试」这条路;想干跑只能用不勾输出的预览模式。
项目结构
├─ src/
│ ├─ Harmonica.Core/ 纯逻辑
│ │ ├─ MidiSong.cs 读 .mid、列轨道、tick → 绝对毫秒
│ │ ├─ HarmonicaConverter.cs 和弦压成单音 + 超出音域折八度
│ │ ├─ GameHarmonicaMapping.cs 音高 → 按键组合
│ │ ├─ PlaybackPlan.cs 校验 + 套速度倍率和松键间隔
│ │ └─ Player.cs 调度器与状态机
│ └─ Harmonica.App/ WPF 外壳 + Win32
│ ├─ MainWindow.xaml(.cs) 演奏 / 设置 / 关于三页,以及全部交互
│ ├─ WindowsInput.cs SendInput 实现,按住键登记
│ ├─ NativeInputSafety.cs 进程级兜底松键,不依赖 WPF 对象
│ ├─ TargetWindow.cs EnumWindows 找游戏窗口
│ ├─ GlobalHotkeys.cs RegisterHotKey,注册失败事务回滚
│ ├─ HotkeySpec.cs 快捷键字符串解析
│ ├─ SettingsStore.cs 配置 JSON 原子写
│ ├─ Themes/ Tokens.xaml 原始/语义 token,Controls.xaml 控件模板
│ └─ Assets/app.ico 脚本生成,不是二进制素材
├─ tests/Harmonica.Core.Tests/ 22 个单测,用替身对象验证按键时序
├─ tools/ make-icon.ps1 画图标,另有两个 UI 调试脚本
├─ docs/ 设计文档、实施计划、UI 改造清单
└─ .nuget-local/ 图标库离线包,断网也能还原核心五个文件加起来 400 行出头,剩下的代码基本都花在界面和 Win32 这边。
项目做了什么
读谱。 导入 .mid / .midi,把文件里有音符的轨道列出来(名字 + 音符数)让你挑一条,程序不替你猜哪条是旋律。原曲里的快慢变化会保留,不会给你放成匀速。
把谱子翻译成按键。 同一时段响几个音时只留最高音,超出可演奏音域的音按相同音名折到最近的八度,压掉了几个音、调了几个八度都会列出来。每个音都会算出「需要同时按住哪些键」交给预览表,比如 MouseMiddle+B 就是鼠标中键加 B 键。默认配置下中音区(C4–B4)只用键盘,不碰鼠标。
播放前先拦一遍。 生成预览时把所有问题一次挑出来:音符重叠、音高没有映射、音符短到放不下松键间隔。有任何一条就不让开始演奏,问题逐条列在预览上方(最多显示 6 条,多的折叠成一行提示)。速度倍率(0.25–4)和松键间隔(0–100 毫秒)可以调,只影响这次的播放计划,不动原文件。
看谱。 预览表逐行给出每个音的时间、MIDI 音高、时长和要按住的键,最多显示前 300 行。不勾游戏输出的时候,程序一个键都不发,可以放心反复试。
播放。 点「播放 / 继续」或者按 F8,先走三秒倒计时,倒计时期间不发键,留时间切回游戏。面板上能看到进度,比如「游戏输出 · 演奏 128/340 · 当前 MIDI 76」。F8 暂停 / 继续,F9 停止并回到曲首,两个键都能改;快捷键注册在系统里,窗口在后台也有效。暂停后继续是把这个音从头重弹一遍,不是从延音的中间接上。
替你按住,也一定替你松开。 游戏窗口不在前台,立刻松开所有按键并暂停,回到游戏不会自动继续,得自己按一次 F8。停止、暂停、关程序,以及程序出异常崩掉,都会把按住的键放开——这是个会替你按住别人窗口按键的程序,漏松一次就卡住一个键。
认窗口。 不用手动点「捕获」,程序自己找三角洲的窗口并显示窗口名,窗口被关掉再打开也能重新认到。
记住你的设置。 八个音符键、三个鼠标修饰键、两个播放快捷键都能改。非法值当场在对应行标红,「保存设置」只在你真的改过并且全部合法时才可点;「恢复默认」要连点两次,第二次之前有 5 秒反悔时间。设置存在 %LocalAppData%\HarmonicaAutoplay\settings.json,下次打开还在;文件坏了会回到默认值,删掉就等于恢复出厂设置。
界面本身。 三页(演奏 / 设置 / 关于),状态一律用颜色 + 图标 + 文字一起表达,不只靠颜色。「关于」页的版本号和构建日期是从程序自己读的,不会和实际版本对不上。高 DPI 下不发虚,窗口大小按屏幕的逻辑分辨率自适应。