EverestAPI / EverestAPI/Everest
Hook does not work after caller method is hooked.
- Dominant language
- C#
- Stars
- 516
- Forks
- 106
- Avg merge
- 4d 9h
- Merged PRs (30d)
- 5
Description
Here are the recreated steps and examples.
[EverestHookBugExample.zip](https://github.com/EverestAPI/Everest/files/4481788/EverestHookBugExample.zip)
1. If I just Hook `DoScreenWipe`, it works fine. When retry in game will output two logs.
```c#
(04/15/2020 22:15:00) [Everest] [Verbose] [Hook2] On.Celeste.Level.DoScreenWipe wipeIn=False, onComplete=System.Action, hiresSnow=False
(04/15/2020 22:15:00) [Everest] [Verbose] [Hook2] On.Celeste.Level.DoScreenWipe wipeIn=True, onComplete=, hiresSnow=False
```
```c#
public override void Load() {
On.Celeste.Level.DoScreenWipe += JustLogDoScreenWipe;
}
private static void JustLogDoScreenWipe(On.Celeste.Level.orig_DoScreenWipe orig, Level self, bool wipeIn, Action onComplete, bool hiresSnow) {
Logger.Log("Hook2", $"On.Celeste.Level.DoScreenWipe\twipeIn={wipeIn}, onComplete={onComplete}, hiresSnow={hiresSnow}");
orig(self, wipeIn, onComplete, hiresSnow);
}
```
2. Then I hooked `End`, when retry in game the `JustLogDoScreenWipe` will only output one log.
```c#
(04/15/2020 22:25:46) [Everest] [Verbose] [Hook2] On.Celeste.PlayerDeadBody.End
(04/15/2020 22:25:47) [Everest] [Verbose] [Hook2] On.Celeste.Level.DoScreenWipe wipeIn=True, onComplete=, hiresSnow=False
```
```c#
public override void Load() {
On.Celeste.PlayerDeadBody.End += JustLogEnd;
On.Celeste.Level.DoScreenWipe += JustLogDoScreenWipe;
}
public override void Unload() {
On.Celeste.PlayerDeadBody.End -= JustLogEnd;
On.Celeste.Level.DoScreenWipe -= JustLogDoScreenWipe;
}
private void JustLogEnd(On.Celeste.PlayerDeadBody.orig_End orig, PlayerDeadBody self) {
Logger.Log("Hook2", "On.Celeste.PlayerDeadBody.End");
orig(self);
}
private static void JustLogDoScreenWipe(On.Celeste.Level.orig_DoScreenWipe orig, Level self, bool wipeIn, Action onComplete, bool hiresSnow) {
Logger.Log("Hook2", $"On.Celeste.Level.DoScreenWipe\twipeIn={wipeIn}, onComplete={onComplete}, hiresSnow={hiresSnow}");
orig(self, wipeIn, onComplete, hiresSnow);
}
```
It seems that after Hook `End` method, the `DoScreenWipe` method called by `End` method cannot be Hooked.
```c#
private void End()
{
if (!finished)
{
finished = true;
Level level = SceneAs();
if (DeathAction == null)
{
DeathAction = level.Reload;
}
level.DoScreenWipe(wipeIn: false, DeathAction);
}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.