summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/StardewModdingAPI.AssemblyRewriters/Finders/EventFinder.cs19
-rw-r--r--src/StardewModdingAPI.AssemblyRewriters/Finders/FieldFinder.cs17
-rw-r--r--src/StardewModdingAPI.AssemblyRewriters/Finders/MethodFinder.cs17
-rw-r--r--src/StardewModdingAPI.AssemblyRewriters/Finders/TypeFinder.cs36
-rw-r--r--src/StardewModdingAPI.AssemblyRewriters/IInstructionRewriter.cs9
-rw-r--r--src/StardewModdingAPI.AssemblyRewriters/Rewriters/FieldReplaceRewriter.cs2
-rw-r--r--src/StardewModdingAPI.AssemblyRewriters/Rewriters/FieldToPropertyRewriter.cs2
-rw-r--r--src/StardewModdingAPI.AssemblyRewriters/Rewriters/MethodParentRewriter.cs12
-rw-r--r--src/StardewModdingAPI/Framework/AssemblyLoader.cs20
9 files changed, 119 insertions, 15 deletions
diff --git a/src/StardewModdingAPI.AssemblyRewriters/Finders/EventFinder.cs b/src/StardewModdingAPI.AssemblyRewriters/Finders/EventFinder.cs
index bcceee32..c0051469 100644
--- a/src/StardewModdingAPI.AssemblyRewriters/Finders/EventFinder.cs
+++ b/src/StardewModdingAPI.AssemblyRewriters/Finders/EventFinder.cs
@@ -37,6 +37,18 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders
this.NounPhrase = nounPhrase ?? $"{fullTypeName}.{eventName} event";
}
+ /// <summary>Rewrite a method definition for compatibility.</summary>
+ /// <param name="module">The module being rewritten.</param>
+ /// <param name="method">The method definition to rewrite.</param>
+ /// <param name="assemblyMap">Metadata for mapping assemblies to the current platform.</param>
+ /// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
+ /// <returns>Returns whether the instruction was rewritten.</returns>
+ /// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
+ public virtual bool Rewrite(ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
+ {
+ return false;
+ }
+
/// <summary>Rewrite a CIL instruction for compatibility.</summary>
/// <param name="module">The module being rewritten.</param>
/// <param name="cil">The CIL rewriter.</param>
@@ -45,9 +57,9 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
- public bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
+ public virtual bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
- if (!this.IsMatch(instruction, platformChanged))
+ if (!this.IsMatch(instruction))
return false;
throw new IncompatibleInstructionException(this.NounPhrase);
@@ -59,8 +71,7 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders
*********/
/// <summary>Get whether a CIL instruction matches.</summary>
/// <param name="instruction">The IL instruction.</param>
- /// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
- protected bool IsMatch(Instruction instruction, bool platformChanged)
+ protected bool IsMatch(Instruction instruction)
{
MethodReference methodRef = RewriteHelper.AsMethodReference(instruction);
return
diff --git a/src/StardewModdingAPI.AssemblyRewriters/Finders/FieldFinder.cs b/src/StardewModdingAPI.AssemblyRewriters/Finders/FieldFinder.cs
index cdfc3bd5..b44883e9 100644
--- a/src/StardewModdingAPI.AssemblyRewriters/Finders/FieldFinder.cs
+++ b/src/StardewModdingAPI.AssemblyRewriters/Finders/FieldFinder.cs
@@ -37,6 +37,18 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders
this.NounPhrase = nounPhrase ?? $"{fullTypeName}.{fieldName} field";
}
+ /// <summary>Rewrite a method definition for compatibility.</summary>
+ /// <param name="module">The module being rewritten.</param>
+ /// <param name="method">The method definition to rewrite.</param>
+ /// <param name="assemblyMap">Metadata for mapping assemblies to the current platform.</param>
+ /// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
+ /// <returns>Returns whether the instruction was rewritten.</returns>
+ /// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
+ public virtual bool Rewrite(ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
+ {
+ return false;
+ }
+
/// <summary>Rewrite a CIL instruction for compatibility.</summary>
/// <param name="module">The module being rewritten.</param>
/// <param name="cil">The CIL rewriter.</param>
@@ -47,7 +59,7 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public virtual bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
- if (!this.IsMatch(instruction, platformChanged))
+ if (!this.IsMatch(instruction))
return false;
throw new IncompatibleInstructionException(this.NounPhrase);
@@ -59,8 +71,7 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders
*********/
/// <summary>Get whether a CIL instruction matches.</summary>
/// <param name="instruction">The IL instruction.</param>
- /// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
- protected bool IsMatch(Instruction instruction, bool platformChanged)
+ protected bool IsMatch(Instruction instruction)
{
FieldReference fieldRef = RewriteHelper.AsFieldReference(instruction);
return
diff --git a/src/StardewModdingAPI.AssemblyRewriters/Finders/MethodFinder.cs b/src/StardewModdingAPI.AssemblyRewriters/Finders/MethodFinder.cs
index 2efcbb0f..19dda58a 100644
--- a/src/StardewModdingAPI.AssemblyRewriters/Finders/MethodFinder.cs
+++ b/src/StardewModdingAPI.AssemblyRewriters/Finders/MethodFinder.cs
@@ -37,6 +37,18 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders
this.NounPhrase = nounPhrase ?? $"{fullTypeName}.{methodName} method";
}
+ /// <summary>Rewrite a method definition for compatibility.</summary>
+ /// <param name="module">The module being rewritten.</param>
+ /// <param name="method">The method definition to rewrite.</param>
+ /// <param name="assemblyMap">Metadata for mapping assemblies to the current platform.</param>
+ /// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
+ /// <returns>Returns whether the instruction was rewritten.</returns>
+ /// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
+ public virtual bool Rewrite(ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
+ {
+ return false;
+ }
+
/// <summary>Rewrite a CIL instruction for compatibility.</summary>
/// <param name="module">The module being rewritten.</param>
/// <param name="cil">The CIL rewriter.</param>
@@ -47,7 +59,7 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
- if (!this.IsMatch(instruction, platformChanged))
+ if (!this.IsMatch(instruction))
return false;
throw new IncompatibleInstructionException(this.NounPhrase);
@@ -59,8 +71,7 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders
*********/
/// <summary>Get whether a CIL instruction matches.</summary>
/// <param name="instruction">The IL instruction.</param>
- /// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
- protected bool IsMatch(Instruction instruction, bool platformChanged)
+ protected bool IsMatch(Instruction instruction)
{
MethodReference methodRef = RewriteHelper.AsMethodReference(instruction);
return
diff --git a/src/StardewModdingAPI.AssemblyRewriters/Finders/TypeFinder.cs b/src/StardewModdingAPI.AssemblyRewriters/Finders/TypeFinder.cs
index 96cbb229..0e4d6824 100644
--- a/src/StardewModdingAPI.AssemblyRewriters/Finders/TypeFinder.cs
+++ b/src/StardewModdingAPI.AssemblyRewriters/Finders/TypeFinder.cs
@@ -33,6 +33,21 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders
this.NounPhrase = nounPhrase ?? $"{fullTypeName} type";
}
+ /// <summary>Rewrite a method definition for compatibility.</summary>
+ /// <param name="module">The module being rewritten.</param>
+ /// <param name="method">The method definition to rewrite.</param>
+ /// <param name="assemblyMap">Metadata for mapping assemblies to the current platform.</param>
+ /// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
+ /// <returns>Returns whether the instruction was rewritten.</returns>
+ /// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
+ public virtual bool Rewrite(ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
+ {
+ if (!this.IsMatch(method))
+ return false;
+
+ throw new IncompatibleInstructionException(this.NounPhrase);
+ }
+
/// <summary>Rewrite a CIL instruction for compatibility.</summary>
/// <param name="module">The module being rewritten.</param>
/// <param name="cil">The CIL rewriter.</param>
@@ -43,7 +58,7 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public virtual bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
- if (!this.IsMatch(instruction, platformChanged))
+ if (!this.IsMatch(instruction))
return false;
throw new IncompatibleInstructionException(this.NounPhrase);
@@ -54,9 +69,24 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders
** Protected methods
*********/
/// <summary>Get whether a CIL instruction matches.</summary>
+ /// <param name="method">The method deifnition.</param>
+ protected bool IsMatch(MethodDefinition method)
+ {
+ if (method.ReturnType.FullName == this.FullTypeName)
+ return true;
+
+ foreach (VariableDefinition variable in method.Body.Variables)
+ {
+ if (variable.VariableType.FullName == this.FullTypeName)
+ return true;
+ }
+
+ return false;
+ }
+
+ /// <summary>Get whether a CIL instruction matches.</summary>
/// <param name="instruction">The IL instruction.</param>
- /// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
- protected bool IsMatch(Instruction instruction, bool platformChanged)
+ protected bool IsMatch(Instruction instruction)
{
string fullName = this.FullTypeName;
diff --git a/src/StardewModdingAPI.AssemblyRewriters/IInstructionRewriter.cs b/src/StardewModdingAPI.AssemblyRewriters/IInstructionRewriter.cs
index 3a7b1365..2f16b23d 100644
--- a/src/StardewModdingAPI.AssemblyRewriters/IInstructionRewriter.cs
+++ b/src/StardewModdingAPI.AssemblyRewriters/IInstructionRewriter.cs
@@ -16,6 +16,15 @@ namespace StardewModdingAPI.AssemblyRewriters
/*********
** Methods
*********/
+ /// <summary>Rewrite a method definition for compatibility.</summary>
+ /// <param name="module">The module being rewritten.</param>
+ /// <param name="method">The method definition to rewrite.</param>
+ /// <param name="assemblyMap">Metadata for mapping assemblies to the current platform.</param>
+ /// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
+ /// <returns>Returns whether the instruction was rewritten.</returns>
+ /// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
+ bool Rewrite(ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged);
+
/// <summary>Rewrite a CIL instruction for compatibility.</summary>
/// <param name="module">The module being rewritten.</param>
/// <param name="cil">The CIL rewriter.</param>
diff --git a/src/StardewModdingAPI.AssemblyRewriters/Rewriters/FieldReplaceRewriter.cs b/src/StardewModdingAPI.AssemblyRewriters/Rewriters/FieldReplaceRewriter.cs
index 95663c49..73844073 100644
--- a/src/StardewModdingAPI.AssemblyRewriters/Rewriters/FieldReplaceRewriter.cs
+++ b/src/StardewModdingAPI.AssemblyRewriters/Rewriters/FieldReplaceRewriter.cs
@@ -42,7 +42,7 @@ namespace StardewModdingAPI.AssemblyRewriters.Rewriters
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public override bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
- if (!this.IsMatch(instruction, platformChanged))
+ if (!this.IsMatch(instruction))
return false;
FieldReference newRef = module.Import(this.ToField);
diff --git a/src/StardewModdingAPI.AssemblyRewriters/Rewriters/FieldToPropertyRewriter.cs b/src/StardewModdingAPI.AssemblyRewriters/Rewriters/FieldToPropertyRewriter.cs
index a25f3fef..3f57042d 100644
--- a/src/StardewModdingAPI.AssemblyRewriters/Rewriters/FieldToPropertyRewriter.cs
+++ b/src/StardewModdingAPI.AssemblyRewriters/Rewriters/FieldToPropertyRewriter.cs
@@ -42,7 +42,7 @@ namespace StardewModdingAPI.AssemblyRewriters.Rewriters
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public override bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
- if (!this.IsMatch(instruction, platformChanged))
+ if (!this.IsMatch(instruction))
return false;
string methodPrefix = instruction.OpCode == OpCodes.Ldsfld || instruction.OpCode == OpCodes.Ldfld ? "get" : "set";
diff --git a/src/StardewModdingAPI.AssemblyRewriters/Rewriters/MethodParentRewriter.cs b/src/StardewModdingAPI.AssemblyRewriters/Rewriters/MethodParentRewriter.cs
index 3ec8c704..035ef211 100644
--- a/src/StardewModdingAPI.AssemblyRewriters/Rewriters/MethodParentRewriter.cs
+++ b/src/StardewModdingAPI.AssemblyRewriters/Rewriters/MethodParentRewriter.cs
@@ -43,6 +43,18 @@ namespace StardewModdingAPI.AssemblyRewriters.Rewriters
this.OnlyIfPlatformChanged = onlyIfPlatformChanged;
}
+ /// <summary>Rewrite a method definition for compatibility.</summary>
+ /// <param name="module">The module being rewritten.</param>
+ /// <param name="method">The method definition to rewrite.</param>
+ /// <param name="assemblyMap">Metadata for mapping assemblies to the current platform.</param>
+ /// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
+ /// <returns>Returns whether the instruction was rewritten.</returns>
+ /// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
+ public bool Rewrite(ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
+ {
+ return false;
+ }
+
/// <summary>Rewrite a CIL instruction for compatibility.</summary>
/// <param name="module">The module being rewritten.</param>
/// <param name="cil">The CIL rewriter.</param>
diff --git a/src/StardewModdingAPI/Framework/AssemblyLoader.cs b/src/StardewModdingAPI/Framework/AssemblyLoader.cs
index 5d00c525..f6fe89f5 100644
--- a/src/StardewModdingAPI/Framework/AssemblyLoader.cs
+++ b/src/StardewModdingAPI/Framework/AssemblyLoader.cs
@@ -198,6 +198,26 @@ namespace StardewModdingAPI.Framework
IInstructionRewriter[] rewriters = Constants.GetRewriters().ToArray();
foreach (MethodDefinition method in this.GetMethods(module))
{
+ // check method definition
+ foreach (IInstructionRewriter rewriter in rewriters)
+ {
+ try
+ {
+ if (rewriter.Rewrite(module, method, this.AssemblyMap, platformChanged))
+ {
+ this.LogOnce(this.Monitor, loggedMessages, $"Rewrote {assembly.Name.Name} to fix {rewriter.NounPhrase}...");
+ anyRewritten = true;
+ }
+ }
+ catch (IncompatibleInstructionException)
+ {
+ if (!assumeCompatible)
+ throw new IncompatibleInstructionException(rewriter.NounPhrase, $"Found an incompatible CIL instruction ({rewriter.NounPhrase}) while loading assembly {assembly.Name.Name}.");
+ this.LogOnce(this.Monitor, loggedMessages, $"Found an incompatible CIL instruction ({rewriter.NounPhrase}) while loading assembly {assembly.Name.Name}, but SMAPI is configured to allow it anyway. The mod may crash or behave unexpectedly.", LogLevel.Warn);
+ }
+ }
+
+ // check CIL instructions
ILProcessor cil = method.Body.GetILProcessor();
foreach (Instruction instruction in cil.Body.Instructions.ToArray())
{