fix: 修复未启用按键相关功能时 FixDebugKeyboardInput 失效的问题 - #143
Conversation
审查者指南通过在相关内层方法完成 Harmony patch 后,使用独立 Harmony 实例对外层 caller 执行一次临时 patch/unpatch,强制 Mono JIT 重新编译并避免内联旧实现,从而恢复 ESC、输入检测及触摸面板等依赖功能;同时将既有临时 workaround 统一为可复用的全局或按 Mod 调用机制。 Harmony patch 后 Mono JIT 重新编译的时序图sequenceDiagram
participant Startup
participant HarmonyPatchRecompile
participant GameMainObject
participant GameMain
participant DebugInput
participant InputManager
Startup->>DebugInput: Harmony patch GetKeyDown
Startup->>InputManager: Harmony patch GetSystemInputDown
Startup->>HarmonyPatchRecompile: RecompileMethod(GameMainObject.Update)
HarmonyPatchRecompile->>GameMainObject: temporary Patch(Update)
HarmonyPatchRecompile->>GameMainObject: Unpatch(Update)
Startup->>HarmonyPatchRecompile: RecompileMethod(GameMain.Update)
HarmonyPatchRecompile->>GameMain: temporary Patch(Update)
HarmonyPatchRecompile->>GameMain: Unpatch(Update)
GameMainObject->>DebugInput: GetKeyDown
GameMain->>InputManager: GetSystemInputDown
文件级变更
提示和命令与 Sourcery 交互
自定义使用体验访问你的控制面板:
获取帮助Original review guide in EnglishReviewer's Guide通过在相关内层方法完成 Harmony patch 后,使用独立 Harmony 实例对外层 caller 执行一次临时 patch/unpatch,强制 Mono JIT 重新编译并避免内联旧实现,从而恢复 ESC、输入检测及触摸面板等依赖功能;同时将既有临时 workaround 统一为可复用的全局或按 Mod 调用机制。 Sequence diagram for Mono JIT recompilation after Harmony patchessequenceDiagram
participant Startup
participant HarmonyPatchRecompile
participant GameMainObject
participant GameMain
participant DebugInput
participant InputManager
Startup->>DebugInput: Harmony patch GetKeyDown
Startup->>InputManager: Harmony patch GetSystemInputDown
Startup->>HarmonyPatchRecompile: RecompileMethod(GameMainObject.Update)
HarmonyPatchRecompile->>GameMainObject: temporary Patch(Update)
HarmonyPatchRecompile->>GameMainObject: Unpatch(Update)
Startup->>HarmonyPatchRecompile: RecompileMethod(GameMain.Update)
HarmonyPatchRecompile->>GameMain: temporary Patch(Update)
HarmonyPatchRecompile->>GameMain: Unpatch(Update)
GameMainObject->>DebugInput: GetKeyDown
GameMain->>InputManager: GetSystemInputDown
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
嗨——我已经审阅了你的更改,整体看起来很棒!
Sourcery 评估
已批准。
请帮助我变得更有用!请对每条评论点击 👍 或 👎,我会利用这些反馈来改进评审。
Original comment in English
Hey - I've reviewed your changes and they look great!
Sourcery assessment
Approved.
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Pull request overview
该 PR 针对 AquaMai 的 FixDebugKeyboardInput 修复项在特定场景下不生效的问题(表现为未启用按键相关功能时 ESC 无法退出等),通过额外对 GameMainObject.Update() 施加 Harmony Patch 来规避 Mono JIT 将 DebugInput.GetKeyDown() 优化内联为常量 false 的情况,从而恢复相关按键功能的可用性。
Changes:
- 在
FixDebugKeyboardInput启用时,新增对GameMainObject.Update()的 Harmony Prefix Patch(空方法)以触发重新编译/取消内联优化。 - 为引用
GameMainObject增加using Main;。
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| [HarmonyPrefix] | ||
| [HarmonyPatch(typeof(GameMainObject), "Update")] | ||
| private static void RepatchGameMainObjectUpdate() | ||
| { | ||
| } |
There was a problem hiding this comment.
All reported issues were addressed across 1 file
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
There was a problem hiding this comment.
All reported issues were addressed across 1 file (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
|
如果是这样的话,那是不是, 983f887 和 dbd22a0 本质上也都是这样的问题,(因为当时我们也是用类似的加一个空Patch的方法解决的) AquaMai/AquaMai.Mods/GameSystem/TestProof.cs Lines 78 to 88 in 983f887 |
|
能写成 |
|
或者说我们是不是应该把 TestProof.cs 那边的移过去 |
他一开始倒正是这样写的,见 7dd58d3。但后面 ca6e3d0 刻意改成了现在的形式,也许是看了cubic-dev-ai的建议 #143 (comment) ,觉得
我觉得也许应该这样做。但具体的原理/最佳的修复方式,可能还得再研究/确认,以及用mml真机回归测试一下。我明天试试吧 |
|
好呀,那等你 |
|
贴一点目前为止的分析: AquaMai/AquaMai.Core/Startup.cs Lines 197 to 206 in c925700 所以,加一个空patch就能好的本质,也就相当于把(PR开头提到的开启虚拟投币、重置触摸面板等涉及对 然后关于 #143 (comment) 中所提的。它们不是针对 据此我正在思考best practice的解决方案当中。等我后续的消息 |
|
交了两个commit,尝试系统性地分析、记录和解决此问题。新增了 AquaMai.Core/Helpers/HarmonyPatchRecompile.cs 注意:还没在mml真机上做测试,所以我先draft掉,等我做好测试之后会ready回来。 |
先感谢 @Starrah 和 @clansty 大晚上在看我的PR,辛苦了w |
确实是参考了 |
我试了你的配置,发现在我这里还是没法复现。我看了我手上游戏的反编译代码,发现我这里的debugInput是正确的UnityEngine实现,可能根本不需要被patch。所以这应该是特定于“某些游戏版本”的问题。 |
|
mml相关的两个问题,在我这里真机测试没有回归问题。 |
There was a problem hiding this comment.
嘿——我发现了 1 个问题
给 AI 代理的提示
请处理本次代码审查中的评论:
## 单独评论
### 评论 1
<location path="AquaMai.Core/Helpers/HarmonyPatchRecompile.cs" line_range="61" />
<code_context>
+ /// </summary>
+ /// <param name="type">和 methodName、argumentTypes 参数一起,指定需要触发重新编译的方法</param>
+ public static void RecompileMethod(Type type, string methodName, Type[] argumentTypes = null)
+ => RecompileMethod(AccessTools.Method(type, methodName, argumentTypes));
+
+ private static void DummyPrefixImpl()
</code_context>
<issue_to_address>
**issue (bug_risk):** 当 `AccessTools.Method` 无法解析请求的方法时,该重载会将 `null` 传递给 `RecompileMethod(MethodBase)`。如果 `harmony.Patch` 拒绝该值,那么 catch 块在报告错误时会解引用 `method.DeclaringType`,导致原本应显示的警告被启动期间或模组的 `OnAfterPatch` 中未处理的 `NullReferenceException` 所替代。
**触发条件:** 当特定游戏版本的目标方法不存在,或调用方提供了无效的方法名称/签名时。
**建议修复:** 在执行修补前检查 `null`,并从该重载中记录类型和方法名称;或者直接返回,不调用 `MethodBase` 重载。
</issue_to_address>Sourcery 评估
等待批准。 请先处理 1 个发现的问题。
阻塞性发现:AquaMai.Core/Helpers/HarmonyPatchRecompile.cs:61
帮助我变得更有用!请在每条评论上点击 👍 或 👎,我会利用反馈来改进审查结果。
Original comment in English
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="AquaMai.Core/Helpers/HarmonyPatchRecompile.cs" line_range="61" />
<code_context>
+ /// </summary>
+ /// <param name="type">和 methodName、argumentTypes 参数一起,指定需要触发重新编译的方法</param>
+ public static void RecompileMethod(Type type, string methodName, Type[] argumentTypes = null)
+ => RecompileMethod(AccessTools.Method(type, methodName, argumentTypes));
+
+ private static void DummyPrefixImpl()
</code_context>
<issue_to_address>
**issue (bug_risk):** When `AccessTools.Method` cannot resolve the requested method, the overload passes `null` to `RecompileMethod(MethodBase)`. If `harmony.Patch` rejects that value, the catch block dereferences `method.DeclaringType` while reporting the error, so the intended warning is replaced by an unhandled `NullReferenceException` during startup or a mod's `OnAfterPatch`.
**Triggers:** When a game-version-specific target method is absent or a caller supplies an invalid method name/signature.
**Suggested fix:** Check for `null` before patching and log the type and method name from the overload, or return without calling the `MethodBase` overload.
</issue_to_address>Sourcery assessment
Approval pending. 1 finding to address first.
Blocking findings: AquaMai.Core/Helpers/HarmonyPatchRecompile.cs:61
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
All reported issues were addressed across 4 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic




该问题最直接的表现是:在未启用任何使用
KeyListener的功能时(如虚拟投币、重置触摸面板),按下ESC无法退出游戏。其他依赖FixDebugKeyboardInput的按键功能也会受到同样影响。由于
KeyListener.CheckLongPush()的优先级在GetKeyDown()之前,导致 Mono JIT 在编译GameMainObject.Update()时(此时DebugInput.GetKeyDown()还没被Patch),将GetKeyDown()优化内联成 false该方法用于在Patch
DebugInput.GetKeyDown()后重新PatchUpdate()让 Mono JIT 重新编译取消内联优化Sourcery 摘要
通过在相关内层方法补丁完成后重新编译外层调用方法,恢复受 Mono JIT 内联影响的按键和输入功能。
错误修复:
改进:
Original summary in English
Sourcery 总结
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
错误修复:
改进:
Original summary in English
Summary by Sourcery
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
Bug Fixes:
Enhancements:
Original summary in English
Sourcery 总结
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
错误修复:
改进:
Original summary in English
Summary by Sourcery
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
Bug Fixes:
Enhancements:
Original summary in English
Sourcery 摘要
通过在相关内层方法补丁完成后重新编译外层调用方法,恢复受 Mono JIT 内联影响的按键和输入功能。
错误修复:
改进:
Original summary in English
Sourcery 总结
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
错误修复:
改进:
Original summary in English
Summary by Sourcery
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
Bug Fixes:
Enhancements:
Original summary in English
Sourcery 总结
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
错误修复:
改进:
Original summary in English
Summary by Sourcery
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
Bug Fixes:
Enhancements:
Original summary in English
Sourcery 摘要
通过在相关内层方法补丁完成后重新编译外层调用方法,恢复受 Mono JIT 内联影响的按键和输入功能。
错误修复:
改进:
Original summary in English
Sourcery 总结
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
错误修复:
改进:
Original summary in English
Summary by Sourcery
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
Bug Fixes:
Enhancements:
Original summary in English
Sourcery 总结
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
错误修复:
改进:
Original summary in English
Summary by Sourcery
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
Bug Fixes:
Enhancements:
Original summary in English
Sourcery 摘要
通过在相关内层方法补丁完成后重新编译外层调用方法,恢复受 Mono JIT 内联影响的按键和输入功能。
错误修复:
改进:
Original summary in English
Sourcery 总结
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
错误修复:
改进:
Original summary in English
Summary by Sourcery
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
Bug Fixes:
Enhancements:
Original summary in English
Sourcery 总结
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
错误修复:
改进:
Original summary in English
Summary by Sourcery
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
Bug Fixes:
Enhancements:
Original summary in English
Sourcery 摘要
通过在相关内层方法补丁完成后重新编译外层调用方法,恢复受 Mono JIT 内联影响的按键和输入功能。
错误修复:
改进:
Original summary in English
Sourcery 总结
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
错误修复:
改进:
Original summary in English
Summary by Sourcery
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
Bug Fixes:
Enhancements:
Original summary in English
Sourcery 总结
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
错误修复:
改进:
Original summary in English
Summary by Sourcery
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
Bug Fixes:
Enhancements:
Original summary in English
Sourcery 摘要
通过在相关内层方法补丁完成后重新编译外层调用方法,恢复受 Mono JIT 内联影响的按键和输入功能。
错误修复:
改进:
Original summary in English
Sourcery 总结
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
错误修复:
改进:
Original summary in English
Summary by Sourcery
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
Bug Fixes:
Enhancements:
Original summary in English
Sourcery 总结
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
错误修复:
改进:
Original summary in English
Summary by Sourcery
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
Bug Fixes:
Enhancements:
Original summary in English
Sourcery 摘要
通过在相关内层方法补丁完成后重新编译外层调用方法,恢复受 Mono JIT 内联影响的按键和输入功能。
错误修复:
改进:
Original summary in English
Sourcery 总结
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
错误修复:
改进:
Original summary in English
Summary by Sourcery
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
Bug Fixes:
Enhancements:
Original summary in English
Sourcery 总结
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
错误修复:
改进:
Original summary in English
Summary by Sourcery
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
Bug Fixes:
Enhancements:
Original summary in English
Sourcery 摘要
通过在相关内层方法补丁完成后重新编译外层调用方法,恢复受 Mono JIT 内联影响的按键和输入功能。
错误修复:
改进:
Original summary in English
Sourcery 总结
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
错误修复:
改进:
Original summary in English
Summary by Sourcery
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
Bug Fixes:
Enhancements:
Original summary in English
Sourcery 总结
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
错误修复:
改进:
Original summary in English
Summary by Sourcery
通过在相关内层方法完成补丁后重新编译调用方,确保 Mono JIT 使用最新的 Harmony 补丁实现。
Bug Fixes:
Enhancements: