Skip to content

Commit

Permalink
Make Add(entity) and Remove(entity) methods to crash when entity is n…
Browse files Browse the repository at this point in the history
…ull, so modders can catch bug in time
  • Loading branch information
DemoJameson committed Aug 3, 2023
1 parent 71a954e commit fbd08d8
Showing 1 changed file with 35 additions and 0 deletions.
35 changes: 35 additions & 0 deletions Celeste.Mod.mm/Patches/Monocle/EntityList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,16 @@ internal void ClearEntities() {
[MonoModIgnore]
[PatchEntityListUpdateLists]
internal extern void UpdateLists();

[MonoModIgnore]
[PatchEntityListAddAndRemove]
internal extern void Add(Entity entity);

[MonoModIgnore]
[PatchEntityListAddAndRemove]
internal extern void Remove(Entity entity);
}

public static class EntityListExt {

// Mods can't access patch_ classes directly.
Expand Down Expand Up @@ -61,6 +70,13 @@ class PatchEntityListUpdateAttribute : Attribute { }
[MonoModCustomMethodAttribute(nameof(MonoModRules.PatchEntityListUpdateLists))]
class PatchEntityListUpdateListsAttribute : Attribute { }

/// <summary>
/// Make Add(entity) and Remove(entity) methods to crash when entity is null
/// so modders can catch bugs in time
/// </summary>
[MonoModCustomMethodAttribute(nameof(MonoModRules.PatchEntityListAddAndRemove))]
class PatchEntityListAddAndRemoveAttribute : Attribute { }

static partial class MonoModRules {

public static void PatchEntityListUpdate(ILContext context, CustomAttribute attrib) {
Expand Down Expand Up @@ -115,5 +131,24 @@ public static void PatchEntityListUpdateLists(ILContext context, CustomAttribute
cursor.Next.Operand = hashRemoveOperand;
}

public static void PatchEntityListAddAndRemove(ILContext context, CustomAttribute attrib) {
// insert the following code at the beginning of the method
// if (entity == null) throw new ArgumentNullException("entity")

TypeDefinition t_ArgumentNullException = MonoModRule.Modder.FindType("System.ArgumentNullException").Resolve();
MethodReference ctor_ArgumentNullException = MonoModRule.Modder.Module.ImportReference(t_ArgumentNullException.FindMethod("System.Void .ctor(System.String)"));

ILCursor cursor = new ILCursor(context);
ILLabel label = cursor.DefineLabel();
cursor.Emit(OpCodes.Ldarg_1);
cursor.Emit(OpCodes.Ldnull);
cursor.Emit(OpCodes.Ceq);
cursor.Emit(OpCodes.Brfalse_S, label);
cursor.Emit(OpCodes.Ldstr, "entity");
cursor.Emit(OpCodes.Newobj, ctor_ArgumentNullException);
cursor.Emit(OpCodes.Throw);
cursor.MarkLabel(label);
}

}
}

0 comments on commit fbd08d8

Please sign in to comment.