Skip to content

Commit ad46fe9

Browse files
committed
Use HookedMethod
1 parent 375e463 commit ad46fe9

4 files changed

Lines changed: 66 additions & 32 deletions

File tree

RainbowMod/RainbowMod.csproj

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,26 @@
4444
<HintPath>..\Everest\lib-stripped\FNA.dll</HintPath>
4545
<Private>False</Private>
4646
</Reference>
47-
<Reference Include="MonoMod">
48-
<HintPath>..\Everest\lib\MonoMod.exe</HintPath>
47+
<Reference Include="HookedMethod, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
48+
<HintPath>..\packages\HookedMethod.0.3.2-beta\lib\net45\HookedMethod.dll</HintPath>
4949
<Private>False</Private>
5050
</Reference>
51+
<Reference Include="Mono.Cecil, Version=0.10.0.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
52+
<HintPath>..\packages\Mono.Cecil.0.10.0-beta7\lib\net40\Mono.Cecil.dll</HintPath>
53+
<Private>False</Private>
54+
</Reference>
55+
<Reference Include="Mono.Cecil.Mdb, Version=0.10.0.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
56+
<HintPath>..\packages\Mono.Cecil.0.10.0-beta7\lib\net40\Mono.Cecil.Mdb.dll</HintPath>
57+
<Private>False</Private>
58+
</Reference>
59+
<Reference Include="Mono.Cecil.Pdb, Version=0.10.0.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
60+
<HintPath>..\packages\Mono.Cecil.0.10.0-beta7\lib\net40\Mono.Cecil.Pdb.dll</HintPath>
61+
<Private>False</Private>
62+
</Reference>
63+
<Reference Include="MonoMod, Version=18.3.6645.35750, Culture=neutral, processorArchitecture=MSIL">
64+
<HintPath>..\packages\HookedMethod.0.3.2-beta\lib\net45\MonoMod.exe</HintPath>
65+
<Private>True</Private>
66+
</Reference>
5167
<Reference Include="Steamworks.NET">
5268
<HintPath>..\Everest\lib-stripped\Steamworks.NET.dll</HintPath>
5369
<Private>False</Private>

RainbowMod/RainbowModule.cs

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using Celeste.Mod;
22
using FMOD.Studio;
3+
using HookedMethod;
4+
using HM = HookedMethod.HookedMethod;
35
using Microsoft.Xna.Framework;
46
using Monocle;
57
using MonoMod.Detour;
@@ -18,10 +20,9 @@ public class RainbowModule : EverestModule {
1820
public override Type SettingsType => typeof(RainbowModuleSettings);
1921
public static RainbowModuleSettings Settings => (RainbowModuleSettings) Instance._Settings;
2022

21-
// The methods we want to hook.
22-
private readonly static MethodInfo m_GetHairColor = typeof(PlayerHair).GetMethod("GetHairColor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
23-
private readonly static MethodInfo m_GetTrailColor = typeof(Player).GetMethod("GetTrailColor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
24-
private readonly static MethodInfo m_GetHairTexture = typeof(PlayerHair).GetMethod("GetHairTexture", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
23+
private static Hook h_GetHairColor;
24+
private static Hook h_GetTrailColor;
25+
private static Hook h_GetHairTexture;
2526

2627
private static int trailIndex = 0;
2728

@@ -53,12 +54,22 @@ public override void LoadSettings() {
5354

5455
public override void Load() {
5556
// Runtime hooks are quite different from static patches.
56-
Type t_RainbowModule = GetType();
57-
// [trampoline] = [method we want to hook] .Detour< [signature] >( [replacement method] );
58-
orig_GetHairColor = m_GetHairColor.Detour<d_GetHairColor>(t_RainbowModule.GetMethod("GetHairColor"));
59-
orig_GetTrailColor = m_GetTrailColor.Detour<d_GetTrailColor>(t_RainbowModule.GetMethod("GetTrailColor"));
57+
h_GetHairColor = new Hook(
58+
MethodInfoWithDef.CreateAndResolveDef(typeof(PlayerHair).GetMethod("GetHairColor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)),
59+
GetHairColor
60+
);
61+
62+
h_GetTrailColor = new Hook(
63+
MethodInfoWithDef.CreateAndResolveDef(typeof(Player).GetMethod("GetTrailColor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)),
64+
GetTrailColor
65+
);
66+
67+
MethodInfo m_GetHairTexture = typeof(PlayerHair).GetMethod("GetHairTexture", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
6068
if (m_GetHairTexture != null) {
61-
orig_GetHairTexture = m_GetHairTexture.Detour<d_GetHairTexture>(t_RainbowModule.GetMethod("GetHairTexture"));
69+
h_GetHairTexture = new Hook(
70+
MethodInfoWithDef.CreateAndResolveDef(m_GetHairTexture),
71+
GetHairTexture
72+
);
6273
}
6374
}
6475

@@ -68,10 +79,7 @@ public override void LoadContent() {
6879
}
6980

7081
public override void Unload() {
71-
// Let's just hope that nothing else detoured this, as this is depth-based...
72-
RuntimeDetour.Undetour(m_GetHairColor);
73-
RuntimeDetour.Undetour(m_GetTrailColor);
74-
RuntimeDetour.Undetour(m_GetHairTexture);
82+
// TODO: Undoing hooks in HookedMethod?
7583
}
7684

7785
public override void CreateModMenuSection(TextMenu menu, bool inGame, EventInstance snapshot) {
@@ -89,14 +97,14 @@ public override void CreateModMenuSection(TextMenu menu, bool inGame, EventInsta
8997
}
9098
}
9199

92-
// The delegate tells MonoMod.Detour / RuntimeDetour about the method signature.
93-
// Instance (non-static) methods must become static, which means we add "this" as the first argument.
94-
public delegate Color d_GetHairColor(PlayerHair self, int index);
95-
// A field containing the trampoline to the original method.
96-
// You don't need to care about how RuntimeDetour handles this behind the scenes.
97-
public static d_GetHairColor orig_GetHairColor;
98-
public static Color GetHairColor(PlayerHair self, int index) {
99-
Color colorOrig = orig_GetHairColor(self, index);
100+
public static object GetHairColor(HM hook, HM.OriginalMethod origM, HM.Parameters args) {
101+
// C# 7:
102+
var (self, index) = args.As<PlayerHair, int>();
103+
// C# 6:
104+
// PlayerHair self = (PlayerHair) args.RawParams[0];
105+
// int index = (int) args.RawParams[1];
106+
107+
Color colorOrig = origM.As<Color>(args.RawParams);
100108
if (Settings.Mode == RainbowModMode.Off || self.GetSprite().Mode == PlayerSpriteMode.Badeline)
101109
return colorOrig;
102110

@@ -139,19 +147,27 @@ public static Color GetHairColor(PlayerHair self, int index) {
139147
return color;
140148
}
141149

142-
public delegate Color d_GetTrailColor(Player self, bool wasDashB);
143-
public static d_GetTrailColor orig_GetTrailColor;
144-
public static Color GetTrailColor(Player self, bool wasDashB) {
150+
public static object GetTrailColor(HM hook, HM.OriginalMethod origM, HM.Parameters args) {
151+
// C# 7:
152+
var (self, wasDashB) = args.As<Player, bool>();
153+
// C# 6:
154+
// Player self = (Player) args.RawParams[0];
155+
// bool wasDashB = (bool) args.RawParams[1];
156+
145157
if ((Settings.Mode & RainbowModMode.Rainbow) != RainbowModMode.Rainbow || self.Sprite.Mode == PlayerSpriteMode.Badeline || self.Hair == null)
146-
return orig_GetTrailColor(self, wasDashB);
158+
return origM.As<Color>(args.RawParams);
147159

148160
return self.Hair.GetHairColor((trailIndex++) % self.Hair.GetSprite().HairCount);
149161
}
150162

151-
public delegate MTexture d_GetHairTexture(PlayerHair self, int index);
152-
public static d_GetHairTexture orig_GetHairTexture;
153-
public static MTexture GetHairTexture(PlayerHair self, int index) {
154-
MTexture orig = orig_GetHairTexture(self, index);
163+
public static MTexture GetHairTexture(HM hook, HM.OriginalMethod origM, HM.Parameters args) {
164+
// C# 7:
165+
var (self, index) = args.As<PlayerHair, int>();
166+
// C# 6:
167+
// PlayerHair self = (PlayerHair) args.RawParams[0];
168+
// int index = (int) args.RawParams[1];
169+
170+
MTexture orig = origM.As<MTexture>(args.RawParams);
155171
if ((Settings.Mode & RainbowModMode.Fox) != RainbowModMode.Fox || self.GetSprite().Mode == PlayerSpriteMode.Badeline)
156172
return orig;
157173

RainbowMod/metadata.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Name: RainbowMod
2-
Version: 2.1.0
2+
Version: 2.2.0
33
DLL: RainbowMod.dll
44
Dependencies:
55
- Name: Everest

RainbowMod/packages.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
3+
<package id="HookedMethod" version="0.3.2-beta" targetFramework="net452" />
34
<package id="Microsoft.Net.Compilers" version="2.6.1" targetFramework="net452" developmentDependency="true" />
5+
<package id="Mono.Cecil" version="0.10.0-beta7" targetFramework="net452" />
46
<package id="System.ValueTuple" version="4.4.0" targetFramework="net452" />
57
</packages>

0 commit comments

Comments
 (0)