Skip to content

Commit

Permalink
feat: PatchSuddenDeathAutoRetry
Browse files Browse the repository at this point in the history
  • Loading branch information
rushiiMachine committed Mar 24, 2024
1 parent 9e6449a commit 84b5f84
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 0 deletions.
59 changes: 59 additions & 0 deletions Osu.Patcher.Hook/Patches/PatchSuddenDeathAutoRetry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using HarmonyLib;
using JetBrains.Annotations;
using Osu.Stubs;
using static System.Reflection.Emit.OpCodes;

namespace Osu.Patcher.Hook.Patches;

/// <summary>
/// Makes the Sudden Death mod restart immediately instead of just failing.
/// Changes the following code in <c>osu.GameModes.Play.Rulesets.Ruleset:Fail(...)</c>:
/// <br /><br />
/// From:
/// <code><![CDATA[
/// if ((this.CurrentScore.EnabledMods & Mods.Perfect) > Mods.None)
/// ]]></code>
/// To:
/// <code><![CDATA[
/// const int mask = Mods.Perfect | Mods.SuddenDeath;
/// if ((this.CurrentScore.EnabledMods & mask) > Mods.None)
/// ]]></code>
/// </summary>
[HarmonyPatch]
[UsedImplicitly]
public class PatchSuddenDeathAutoRetry
{
private const int ModPerfect = 1 << 14;
private const int ModSuddenDeath = 1 << 5;

[UsedImplicitly]
[HarmonyTargetMethod]
private static MethodBase Target() => Ruleset.Fail.Reference;

/// <summary>
/// Replace the instruction that loads <c>Mods.Perfect</c> with one
/// that loads <c>Mods.Perfect | Mods.SuddenDeath</c>.
/// </summary>
[UsedImplicitly]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) =>
instructions.Manipulator(
inst => inst.opcode == Ldc_I4 && inst.OperandIs(ModPerfect),
inst => inst.operand = ModPerfect | ModSuddenDeath
);

[UsedImplicitly]
[HarmonyFinalizer]
[SuppressMessage("ReSharper", "InconsistentNaming")]
private static void Finalizer(Exception? __exception)
{
if (__exception != null)
{
Console.WriteLine($"Exception due to {nameof(PatchSuddenDeathAutoRetry)}: {__exception}");
}
}
}
30 changes: 30 additions & 0 deletions Osu.Stubs/Ruleset.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Osu.Stubs.Opcode;
using static System.Reflection.Emit.OpCodes;

namespace Osu.Stubs;

/// <summary>
/// Original: <c>osu.GameModes.Play.Rulesets.Ruleset</c>
/// b20240102.2: <c>#=z35zTtWacH8qc$rYRcsQ6iGtK1MBEurfpzNOeLiQ=</c>
/// </summary>
public static class Ruleset
{
/// <summary>
/// Original: <c>Fail(bool continuousPlay)</c>
/// b20240102.2: <c>#=zWoTE_tk=</c>
/// </summary>
public static LazyMethod Fail = new(
"Ruleset#Fail(...)",
new[]
{
Brtrue_S,
Leave_S,
Ldloca_S,
Constrained,
Callvirt,
Endfinally,
Call,
Ldc_I4_1,
}
);
}

0 comments on commit 84b5f84

Please sign in to comment.