From dd109f235e51c5c4e2754f8685f5d3305ef7143c Mon Sep 17 00:00:00 2001 From: earthwise Date: Thu, 30 Apr 2026 01:40:17 +1200 Subject: [PATCH] prevent `ParticleType` instances from being kept alive forever --- .../Patches/Monocle/ParticleType.cs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Celeste.Mod.mm/Patches/Monocle/ParticleType.cs diff --git a/Celeste.Mod.mm/Patches/Monocle/ParticleType.cs b/Celeste.Mod.mm/Patches/Monocle/ParticleType.cs new file mode 100644 index 000000000..8ba4a0159 --- /dev/null +++ b/Celeste.Mod.mm/Patches/Monocle/ParticleType.cs @@ -0,0 +1,41 @@ +using MonoMod; +using System; +using System.Collections.Generic; +using Mono.Cecil; +using MonoMod.Cil; + +namespace Monocle { + class patch_ParticleType : ParticleType + { + [Obsolete("Unused. ParticleType instances are not added automatically.")] + private static List AllTypes; + + [MonoModIgnore] + [MonoModConstructor] + [PatchParticleTypeCtor] + public extern void ctor(); + + [MonoModIgnore] + [MonoModConstructor] + [PatchParticleTypeCtor] + public extern void ctor(ParticleType copyFrom); + } +} + +namespace MonoMod { + /// + /// Patches the constructor to prevent it from adding all instances to an unused static list, which would keep them all alive forever. + /// + [MonoModCustomMethodAttribute(nameof(MonoModRules.PatchParticleTypeCtor))] + class PatchParticleTypeCtorAttribute : Attribute { } + + static partial class MonoModRules { + public static void PatchParticleTypeCtor(ILContext context, CustomAttribute attrib) { + ILCursor cursor = new(context); + + // remove the `AllTypes.Add(this);` call + cursor.GotoNext(MoveType.Before, instr => instr.MatchLdsfld("Monocle.ParticleType", "AllTypes")); + cursor.RemoveRange(3); + } + } +}