[+] New mod GameSystem.SkipBoardNoCheck#50
Conversation
Skip BoardNo Check to use 837-15070-02 as 837-15070-04. (use HarmonyTranspiler,)
审阅者指南引入了一个新的模组,通过向两个目标方法注入 Harmony 转译器来绕过旧版 837-15070-02 板卡的板号检查,并将新模组注册到配置中。 Harmony 转译器修补 BoardCtrl15070_4._md_initBoard_GetBoardInfo 的时序图sequenceDiagram
participant Harmony as HarmonyTranspiler
participant BoardCtrl as BoardCtrl15070_4
participant Logger as MelonLogger
Harmony->>BoardCtrl: Patch _md_initBoard_GetBoardInfo
BoardCtrl->>Harmony: Provide instructions
Harmony->>BoardCtrl: Replace IsEqual call with always true
Harmony->>Logger: Log patch success or warning
Harmony 转译器修补 Bd15070_4Control.IsNeedFirmUpdate 的时序图sequenceDiagram
participant Harmony as HarmonyTranspiler
participant BdControl as Bd15070_4Control
participant Logger as MelonLogger
Harmony->>BdControl: Patch IsNeedFirmUpdate
BdControl->>Harmony: Provide instructions
Harmony->>BdControl: Replace IsEqual call with always true
Harmony->>Logger: Log patch success or warning
新 SkipBoardNoCheck 模组的类图classDiagram
class SkipBoardNoCheck {
<<ConfigSection>>
+Transpiler1(instructions)
+Transpiler2(instructions)
}
SkipBoardNoCheck --|> HarmonyTranspiler
SkipBoardNoCheck --|> HarmonyPatch
HarmonyPatch <|-- BoardCtrl15070_4
HarmonyPatch <|-- Bd15070_4Control
BoardCtrl15070_4 : _md_initBoard_GetBoardInfo()
Bd15070_4Control : IsNeedFirmUpdate()
文件级别更改
提示和命令与 Sourcery 互动
自定义您的体验访问您的 控制面板 以:
获取帮助Original review guide in EnglishReviewer's GuideIntroduces a new mod that bypasses board number checks for the legacy 837-15070-02 board by injecting Harmony transpilers into two target methods, and registers the new mod in the configuration. Sequence diagram for Harmony transpiler patching BoardCtrl15070_4._md_initBoard_GetBoardInfosequenceDiagram
participant Harmony as HarmonyTranspiler
participant BoardCtrl as BoardCtrl15070_4
participant Logger as MelonLogger
Harmony->>BoardCtrl: Patch _md_initBoard_GetBoardInfo
BoardCtrl->>Harmony: Provide instructions
Harmony->>BoardCtrl: Replace IsEqual call with always true
Harmony->>Logger: Log patch success or warning
Sequence diagram for Harmony transpiler patching Bd15070_4Control.IsNeedFirmUpdatesequenceDiagram
participant Harmony as HarmonyTranspiler
participant BdControl as Bd15070_4Control
participant Logger as MelonLogger
Harmony->>BdControl: Patch IsNeedFirmUpdate
BdControl->>Harmony: Provide instructions
Harmony->>BdControl: Replace IsEqual call with always true
Harmony->>Logger: Log patch success or warning
Class diagram for the new SkipBoardNoCheck modclassDiagram
class SkipBoardNoCheck {
<<ConfigSection>>
+Transpiler1(instructions)
+Transpiler2(instructions)
}
SkipBoardNoCheck --|> HarmonyTranspiler
SkipBoardNoCheck --|> HarmonyPatch
HarmonyPatch <|-- BoardCtrl15070_4
HarmonyPatch <|-- Bd15070_4Control
BoardCtrl15070_4 : _md_initBoard_GetBoardInfo()
Bd15070_4Control : IsNeedFirmUpdate()
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
你好 - 我已经审阅了你的更改,它们看起来很棒!
AI 代理提示
请解决此代码审查中的评论:
## 单独评论
### 评论 1
<location> `AquaMai.Mods/GameSystem/SkipBoardNoCheck.cs:23` </location>
<code_context>
+ [HarmonyPatch(typeof(BoardCtrl15070_4), "_md_initBoard_GetBoardInfo")]
+ static IEnumerable<CodeInstruction> Transpiler1(IEnumerable<CodeInstruction> instructions)
+ {
+ var codes = new List<CodeInstruction>(instructions);
+ bool patched = false;
+ for (int i = 0; i < codes.Count; i++)
</code_context>
<issue_to_address>
考虑使用更健壮的模式来匹配目标指令。
通过字符串值匹配操作数容易出错,并且如果方法名称或签名更改,可能会中断。为了可靠性,请直接比较 MethodInfo。
建议的实现:
```csharp
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;
```
如果 `IsEqual` 方法被重载,你可能需要在 `GetMethod` 中指定参数类型。例如:
```csharp
var isEqualMethod = typeof(BoardCtrl15070_4).GetMethod("IsEqual", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new[] { typeof(/* param types here */) }, null);
```
此外,请确保你的文件顶部有 `using System.Reflection;`(如果尚未存在)。
</issue_to_address>
### 评论 2
<location> `AquaMai.Mods/GameSystem/SkipBoardNoCheck.cs:19` </location>
<code_context>
+ return codes;
+ }
+
+ [HarmonyTranspiler]
+ [HarmonyPatch(typeof(Bd15070_4Control), "IsNeedFirmUpdate")]
+ static IEnumerable<CodeInstruction> Transpiler2(IEnumerable<CodeInstruction> instructions)
+ {
+ var codes = new List<CodeInstruction>(instructions);
</code_context>
<issue_to_address>
重复的 Transpiler 逻辑可以重构以提高可维护性。
考虑将共享的修补逻辑移到一个辅助方法中,以最大程度地减少重复并简化未来的更新。
建议的实现:
```csharp
static IEnumerable<CodeInstruction> Transpiler1(IEnumerable<CodeInstruction> instructions)
{
return PatchIsEqualTranspiler(instructions);
```
```csharp
[HarmonyTranspiler]
[HarmonyPatch(typeof(Bd15070_4Control), "IsNeedFirmUpdate")]
static IEnumerable<CodeInstruction> Transpiler2(IEnumerable<CodeInstruction> instructions)
{
return PatchIsEqualTranspiler(instructions);
```
```csharp
// 用于重构共享 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;
}
```
</issue_to_address>
### 评论 3
<location> `AquaMai.Mods/GameSystem/SkipBoardNoCheck.cs:21` </location>
<code_context>
+{
+ [HarmonyTranspiler]
+ [HarmonyPatch(typeof(BoardCtrl15070_4), "_md_initBoard_GetBoardInfo")]
+ static IEnumerable<CodeInstruction> Transpiler1(IEnumerable<CodeInstruction> instructions)
+ {
+ var codes = new List<CodeInstruction>(instructions);
</code_context>
<issue_to_address>
考虑重构 Transpiler 方法以使用共享的 IL 修补助手来消除重复代码。
以下是将两个 Transpiler 合并为一个 IL 修补器并删除所有重复的循环/列表逻辑而无需更改任何行为的一种方法:
```csharp
// 1) 执行 “Pop, Pop, Ldc_I4_1” 替换 + 日志记录的通用助手
static IEnumerable<CodeInstruction> ReplaceIsEqual(
IEnumerable<CodeInstruction> instructions,
string contextName)
{
var codes = instructions.ToList();
bool patched = false;
for (int i = 0; i < codes.Count; i++)
{
var instr = codes[i];
if (instr.opcode == OpCodes.Callvirt
&& instr.operand != null
&& instr.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));
MelonLoader.MelonLogger.Msg(
$"[SkipBoardNoCheck] 修补 {contextName} 方法成功");
patched = true;
break;
}
}
if (!patched)
MelonLoader.MelonLogger.Warning(
$"[SkipBoardNoCheck] 未找到需要修补的代码位置:{contextName}");
return codes;
}
```
```csharp
// 2) 单个 Transpiler 方法,修补到两个目标,
// 将其自己的上下文字符串传递给助手
[HarmonyPatch(typeof(BoardCtrl15070_4), "_md_initBoard_GetBoardInfo")]
[HarmonyPatch(typeof(Bd15070_4Control), "IsNeedFirmUpdate")]
public static class SkipBoardNoCheck
{
[HarmonyTranspiler]
static IEnumerable<CodeInstruction> Transpiler1(
IEnumerable<CodeInstruction> instrs)
=> ReplaceIsEqual(
instrs,
"BoardCtrl15070_4._md_initBoard_GetBoardInfo");
[HarmonyTranspiler]
static IEnumerable<CodeInstruction> Transpiler2(
IEnumerable<CodeInstruction> instrs)
=> ReplaceIsEqual(
instrs,
"Bd15070_4Control.IsNeedFirmUpdate");
}
```
这消除了所有手动 IL 重复,同时保持了两个补丁和日志的完整性。
</issue_to_address>请帮助我变得更有用!请在每个评论上点击 👍 或 👎,我将使用这些反馈来改进你的评论。
Original comment in English
Hey there - I've reviewed your changes and they look great!
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location> `AquaMai.Mods/GameSystem/SkipBoardNoCheck.cs:23` </location>
<code_context>
+ [HarmonyPatch(typeof(BoardCtrl15070_4), "_md_initBoard_GetBoardInfo")]
+ static IEnumerable<CodeInstruction> Transpiler1(IEnumerable<CodeInstruction> instructions)
+ {
+ var codes = new List<CodeInstruction>(instructions);
+ bool patched = false;
+ for (int i = 0; i < codes.Count; i++)
</code_context>
<issue_to_address>
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:
```csharp
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 `IsEqual` method is overloaded, you may need to specify the parameter types in `GetMethod`. For example:
```csharp
var isEqualMethod = typeof(BoardCtrl15070_4).GetMethod("IsEqual", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new[] { typeof(/* param types here */) }, null);
```
Also, ensure you have `using System.Reflection;` at the top of your file if not already present.
</issue_to_address>
### Comment 2
<location> `AquaMai.Mods/GameSystem/SkipBoardNoCheck.cs:19` </location>
<code_context>
+ return codes;
+ }
+
+ [HarmonyTranspiler]
+ [HarmonyPatch(typeof(Bd15070_4Control), "IsNeedFirmUpdate")]
+ static IEnumerable<CodeInstruction> Transpiler2(IEnumerable<CodeInstruction> instructions)
+ {
+ var codes = new List<CodeInstruction>(instructions);
</code_context>
<issue_to_address>
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:
```csharp
static IEnumerable<CodeInstruction> Transpiler1(IEnumerable<CodeInstruction> instructions)
{
return PatchIsEqualTranspiler(instructions);
```
```csharp
[HarmonyTranspiler]
[HarmonyPatch(typeof(Bd15070_4Control), "IsNeedFirmUpdate")]
static IEnumerable<CodeInstruction> Transpiler2(IEnumerable<CodeInstruction> instructions)
{
return PatchIsEqualTranspiler(instructions);
```
```csharp
// 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;
}
```
</issue_to_address>
### Comment 3
<location> `AquaMai.Mods/GameSystem/SkipBoardNoCheck.cs:21` </location>
<code_context>
+{
+ [HarmonyTranspiler]
+ [HarmonyPatch(typeof(BoardCtrl15070_4), "_md_initBoard_GetBoardInfo")]
+ static IEnumerable<CodeInstruction> Transpiler1(IEnumerable<CodeInstruction> instructions)
+ {
+ var codes = new List<CodeInstruction>(instructions);
</code_context>
<issue_to_address>
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:
```csharp
// 1) Common helper that does the “Pop, Pop, Ldc_I4_1” replace + logging
static IEnumerable<CodeInstruction> ReplaceIsEqual(
IEnumerable<CodeInstruction> instructions,
string contextName)
{
var codes = instructions.ToList();
bool patched = false;
for (int i = 0; i < codes.Count; i++)
{
var instr = codes[i];
if (instr.opcode == OpCodes.Callvirt
&& instr.operand != null
&& instr.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));
MelonLoader.MelonLogger.Msg(
$"[SkipBoardNoCheck] 修补 {contextName} 方法成功");
patched = true;
break;
}
}
if (!patched)
MelonLoader.MelonLogger.Warning(
$"[SkipBoardNoCheck] 未找到需要修补的代码位置:{contextName}");
return codes;
}
```
```csharp
// 2) Single transpiler method, patched to both targets,
// passing its own context string into the helper
[HarmonyPatch(typeof(BoardCtrl15070_4), "_md_initBoard_GetBoardInfo")]
[HarmonyPatch(typeof(Bd15070_4Control), "IsNeedFirmUpdate")]
public static class SkipBoardNoCheck
{
[HarmonyTranspiler]
static IEnumerable<CodeInstruction> Transpiler1(
IEnumerable<CodeInstruction> instrs)
=> ReplaceIsEqual(
instrs,
"BoardCtrl15070_4._md_initBoard_GetBoardInfo");
[HarmonyTranspiler]
static IEnumerable<CodeInstruction> Transpiler2(
IEnumerable<CodeInstruction> instrs)
=> ReplaceIsEqual(
instrs,
"Bd15070_4Control.IsNeedFirmUpdate");
}
```
This removes all the manual‐IL duplication while keeping both patches and logs intact.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| [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.
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;如果 IsEqual 方法被重载,你可能需要在 GetMethod 中指定参数类型。例如:
var isEqualMethod = typeof(BoardCtrl15070_4).GetMethod("IsEqual", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new[] { typeof(/* param types here */) }, null);此外,请确保你的文件顶部有 using System.Reflection;(如果尚未存在)。
Original comment in English
suggestion: 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 IsEqual method is overloaded, you may need to specify the parameter types in GetMethod. For example:
var isEqualMethod = typeof(BoardCtrl15070_4).GetMethod("IsEqual", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new[] { typeof(/* param types here */) }, null);Also, ensure you have using System.Reflection; at the top of your file if not already present.
| [HarmonyTranspiler] | ||
| [HarmonyPatch(typeof(BoardCtrl15070_4), "_md_initBoard_GetBoardInfo")] | ||
| static IEnumerable<CodeInstruction> Transpiler1(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 && |
There was a problem hiding this comment.
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 English
suggestion: 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;
}| { | ||
| [HarmonyTranspiler] | ||
| [HarmonyPatch(typeof(BoardCtrl15070_4), "_md_initBoard_GetBoardInfo")] | ||
| static IEnumerable<CodeInstruction> Transpiler1(IEnumerable<CodeInstruction> instructions) |
There was a problem hiding this comment.
issue (complexity): 考虑重构 Transpiler 方法以使用共享的 IL 修补助手来消除重复代码。
以下是将两个 Transpiler 合并为一个 IL 修补器并删除所有重复的循环/列表逻辑而无需更改任何行为的一种方法:
// 1) 执行 “Pop, Pop, Ldc_I4_1” 替换 + 日志记录的通用助手
static IEnumerable<CodeInstruction> ReplaceIsEqual(
IEnumerable<CodeInstruction> instructions,
string contextName)
{
var codes = instructions.ToList();
bool patched = false;
for (int i = 0; i < codes.Count; i++)
{
var instr = codes[i];
if (instr.opcode == OpCodes.Callvirt
&& instr.operand != null
&& instr.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));
MelonLoader.MelonLogger.Msg(
$"[SkipBoardNoCheck] 修补 {contextName} 方法成功");
patched = true;
break;
}
}
if (!patched)
MelonLoader.MelonLogger.Warning(
$"[SkipBoardNoCheck] 未找到需要修补的代码位置:{contextName}");
return codes;
}// 2) 单个 Transpiler 方法,修补到两个目标,
// 将其自己的上下文字符串传递给助手
[HarmonyPatch(typeof(BoardCtrl15070_4), "_md_initBoard_GetBoardInfo")]
[HarmonyPatch(typeof(Bd15070_4Control), "IsNeedFirmUpdate")]
public static class SkipBoardNoCheck
{
[HarmonyTranspiler]
static IEnumerable<CodeInstruction> Transpiler1(
IEnumerable<CodeInstruction> instrs)
=> ReplaceIsEqual(
instrs,
"BoardCtrl15070_4._md_initBoard_GetBoardInfo");
[HarmonyTranspiler]
static IEnumerable<CodeInstruction> Transpiler2(
IEnumerable<CodeInstruction> instrs)
=> ReplaceIsEqual(
instrs,
"Bd15070_4Control.IsNeedFirmUpdate");
}这消除了所有手动 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:
// 1) Common helper that does the “Pop, Pop, Ldc_I4_1” replace + logging
static IEnumerable<CodeInstruction> ReplaceIsEqual(
IEnumerable<CodeInstruction> instructions,
string contextName)
{
var codes = instructions.ToList();
bool patched = false;
for (int i = 0; i < codes.Count; i++)
{
var instr = codes[i];
if (instr.opcode == OpCodes.Callvirt
&& instr.operand != null
&& instr.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));
MelonLoader.MelonLogger.Msg(
$"[SkipBoardNoCheck] 修补 {contextName} 方法成功");
patched = true;
break;
}
}
if (!patched)
MelonLoader.MelonLogger.Warning(
$"[SkipBoardNoCheck] 未找到需要修补的代码位置:{contextName}");
return codes;
}// 2) Single transpiler method, patched to both targets,
// passing its own context string into the helper
[HarmonyPatch(typeof(BoardCtrl15070_4), "_md_initBoard_GetBoardInfo")]
[HarmonyPatch(typeof(Bd15070_4Control), "IsNeedFirmUpdate")]
public static class SkipBoardNoCheck
{
[HarmonyTranspiler]
static IEnumerable<CodeInstruction> Transpiler1(
IEnumerable<CodeInstruction> instrs)
=> ReplaceIsEqual(
instrs,
"BoardCtrl15070_4._md_initBoard_GetBoardInfo");
[HarmonyTranspiler]
static IEnumerable<CodeInstruction> Transpiler2(
IEnumerable<CodeInstruction> instrs)
=> ReplaceIsEqual(
instrs,
"Bd15070_4Control.IsNeedFirmUpdate");
}This removes all the manual‐IL duplication while keeping both patches and logs intact.
|
ai说的我一个都看不懂,但是代码既然能跑,就不用动,性能差异是微乎其微的。 |
|
ETN973 漏的 |
Skip "BoardNo check" to use the old cab light board 837-15070-02 on Sinmai. Tested. Use [HarmonyTranspiler].
Sourcery 总结
添加一个新的 GameSystem.SkipBoardNoCheck mod,该mod使用 Harmony transpilers 来覆盖电路板验证和固件更新检查,从而支持旧版 837-15070-02 驾驶室灯板。
新功能:
改进:
Original summary in English
Summary by Sourcery
Add a new GameSystem.SkipBoardNoCheck mod that uses Harmony transpilers to override board validation and firmware update checks, enabling support for the legacy 837-15070-02 cab light board.
New Features:
Enhancements: