-
Notifications
You must be signed in to change notification settings - Fork 54
[+] New mod GameSystem.SkipBoardNoCheck #50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using AMDaemon; | ||
| using AquaMai.Config.Attributes; | ||
| using Comio.BD15070_4; | ||
| using Mecha; | ||
| using HarmonyLib; | ||
| using System.Reflection.Emit; | ||
| using Manager; | ||
| using UnityEngine; | ||
|
|
||
| namespace AquaMai.Mods.GameSystem; | ||
|
|
||
| [ConfigSection( | ||
| en: "Skip BoardNo check to use the old cab light board 837-15070-02", | ||
| zh: "跳过 BoardNo 检查以使用 837-15070-02(旧框灯板)")] | ||
| public class SkipBoardNoCheck | ||
| { | ||
| [HarmonyTranspiler] | ||
| [HarmonyPatch(typeof(BoardCtrl15070_4), "_md_initBoard_GetBoardInfo")] | ||
| static IEnumerable<CodeInstruction> Transpiler1(IEnumerable<CodeInstruction> instructions) | ||
| { | ||
| var codes = new List<CodeInstruction>(instructions); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: 考虑使用更健壮的模式来匹配目标指令。 通过字符串值匹配操作数容易出错,并且如果方法名称或签名更改,可能会中断。为了可靠性,请直接比较 MethodInfo。 建议的实现: var codes = new List<CodeInstruction>(instructions);
bool patched = false;
// 获取目标 IsEqual 方法的 MethodInfo
var isEqualMethod = typeof(BoardCtrl15070_4).GetMethod("IsEqual", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].opcode == OpCodes.Callvirt &&
codes[i].operand != null &&
codes[i].operand is MethodInfo method &&
method == isEqualMethod)
{
codes[i] = new CodeInstruction(OpCodes.Pop);
codes.Insert(i + 1, new CodeInstruction(OpCodes.Pop));
codes.Insert(i + 2, new CodeInstruction(OpCodes.Ldc_I4_1));
patched = true;如果 var isEqualMethod = typeof(BoardCtrl15070_4).GetMethod("IsEqual", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new[] { typeof(/* param types here */) }, null);此外,请确保你的文件顶部有 Original comment in Englishsuggestion: Consider using a more robust pattern for matching the target instruction. Matching the operand by its string value is error-prone and may break if method names or signatures change. Prefer comparing MethodInfo directly for reliability. Suggested implementation: var codes = new List<CodeInstruction>(instructions);
bool patched = false;
// Get MethodInfo for the target IsEqual method
var isEqualMethod = typeof(BoardCtrl15070_4).GetMethod("IsEqual", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].opcode == OpCodes.Callvirt &&
codes[i].operand != null &&
codes[i].operand is MethodInfo method &&
method == isEqualMethod)
{
codes[i] = new CodeInstruction(OpCodes.Pop);
codes.Insert(i + 1, new CodeInstruction(OpCodes.Pop));
codes.Insert(i + 2, new CodeInstruction(OpCodes.Ldc_I4_1));
patched = true;If the var isEqualMethod = typeof(BoardCtrl15070_4).GetMethod("IsEqual", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new[] { typeof(/* param types here */) }, null);Also, ensure you have |
||
| bool patched = false; | ||
| for (int i = 0; i < codes.Count; i++) | ||
| { | ||
| if (codes[i].opcode == OpCodes.Callvirt && | ||
| codes[i].operand != null && | ||
|
Comment on lines
+19
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: 重复的 Transpiler 逻辑可以重构以提高可维护性。 考虑将共享的修补逻辑移到一个辅助方法中,以最大程度地减少重复并简化未来的更新。 建议的实现: static IEnumerable<CodeInstruction> Transpiler1(IEnumerable<CodeInstruction> instructions)
{
return PatchIsEqualTranspiler(instructions); [HarmonyTranspiler]
[HarmonyPatch(typeof(Bd15070_4Control), "IsNeedFirmUpdate")]
static IEnumerable<CodeInstruction> Transpiler2(IEnumerable<CodeInstruction> instructions)
{
return PatchIsEqualTranspiler(instructions); // 用于重构共享 Transpiler 逻辑的辅助方法
private static IEnumerable<CodeInstruction> PatchIsEqualTranspiler(IEnumerable<CodeInstruction> instructions)
{
var codes = new List<CodeInstruction>(instructions);
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].opcode == OpCodes.Callvirt &&
codes[i].operand != null &&
codes[i].operand.ToString().Contains("IsEqual"))
{
codes[i] = new CodeInstruction(OpCodes.Pop);
codes.Insert(i + 1, new CodeInstruction(OpCodes.Pop));
codes.Insert(i + 2, new CodeInstruction(OpCodes.Ldc_I4_1));
break;
}
}
return codes;
}Original comment in Englishsuggestion: Duplicated transpiler logic could be refactored for maintainability. Consider moving the shared patching logic into a helper method to minimize duplication and simplify future updates. Suggested implementation: static IEnumerable<CodeInstruction> Transpiler1(IEnumerable<CodeInstruction> instructions)
{
return PatchIsEqualTranspiler(instructions); [HarmonyTranspiler]
[HarmonyPatch(typeof(Bd15070_4Control), "IsNeedFirmUpdate")]
static IEnumerable<CodeInstruction> Transpiler2(IEnumerable<CodeInstruction> instructions)
{
return PatchIsEqualTranspiler(instructions); // Helper method to refactor shared transpiler logic
private static IEnumerable<CodeInstruction> PatchIsEqualTranspiler(IEnumerable<CodeInstruction> instructions)
{
var codes = new List<CodeInstruction>(instructions);
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].opcode == OpCodes.Callvirt &&
codes[i].operand != null &&
codes[i].operand.ToString().Contains("IsEqual"))
{
codes[i] = new CodeInstruction(OpCodes.Pop);
codes.Insert(i + 1, new CodeInstruction(OpCodes.Pop));
codes.Insert(i + 2, new CodeInstruction(OpCodes.Ldc_I4_1));
break;
}
}
return codes;
} |
||
| codes[i].operand.ToString().Contains("IsEqual")) | ||
| { | ||
| codes[i] = new CodeInstruction(OpCodes.Pop); | ||
| codes.Insert(i + 1, new CodeInstruction(OpCodes.Pop)); | ||
| codes.Insert(i + 2, new CodeInstruction(OpCodes.Ldc_I4_1)); | ||
|
|
||
| patched = true; | ||
| MelonLoader.MelonLogger.Msg("[SkipBoardNoCheck] 修补 BoardCtrl15070_4._md_initBoard_GetBoardInfo 方法成功"); | ||
| break; | ||
| } | ||
| } | ||
| if (!patched) | ||
| { | ||
| MelonLoader.MelonLogger.Warning("[SkipBoardNoCheck] 未找到需要修补的代码位置:BoardCtrl15070_4._md_initBoard_GetBoardInfo"); | ||
| } | ||
| return codes; | ||
| } | ||
|
|
||
| [HarmonyTranspiler] | ||
| [HarmonyPatch(typeof(Bd15070_4Control), "IsNeedFirmUpdate")] | ||
| static IEnumerable<CodeInstruction> Transpiler2(IEnumerable<CodeInstruction> instructions) | ||
| { | ||
| var codes = new List<CodeInstruction>(instructions); | ||
| bool patched = false; | ||
| for (int i = 0; i < codes.Count; i++) | ||
| { | ||
| if (codes[i].opcode == OpCodes.Callvirt && | ||
| codes[i].operand != null && | ||
| codes[i].operand.ToString().Contains("IsEqual")) | ||
| { | ||
| codes[i] = new CodeInstruction(OpCodes.Pop); | ||
| codes.Insert(i + 1, new CodeInstruction(OpCodes.Pop)); | ||
| codes.Insert(i + 2, new CodeInstruction(OpCodes.Ldc_I4_1)); | ||
|
|
||
| patched = true; | ||
| MelonLoader.MelonLogger.Msg("[SkipBoardNoCheck] 修补 Bd15070_4Control.IsNeedFirmUpdate 方法成功"); | ||
| break; | ||
| } | ||
| } | ||
| if (!patched) | ||
| { | ||
| MelonLoader.MelonLogger.Warning("[SkipBoardNoCheck] 未找到需要修补的代码位置:Bd15070_4Control.IsNeedFirmUpdate"); | ||
| } | ||
| return codes; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (complexity): 考虑重构 Transpiler 方法以使用共享的 IL 修补助手来消除重复代码。
以下是将两个 Transpiler 合并为一个 IL 修补器并删除所有重复的循环/列表逻辑而无需更改任何行为的一种方法:
这消除了所有手动 IL 重复,同时保持了两个补丁和日志的完整性。
Original comment in English
issue (complexity): Consider refactoring the transpiler methods to use a shared helper for IL patching to eliminate duplicated code.
Here’s one way to collapse both transpilers into a single IL‐patcher and remove all of the duplicated loop/list logic without changing any behavior:
This removes all the manual‐IL duplication while keeping both patches and logs intact.