EverestAPI / EverestAPI/Everest

Hook does not work after caller method is hooked.

Open
#147 3 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.