summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/SMAPI/Framework/ModLoading/AssemblyDefinitionResolver.cs9
-rw-r--r--src/SMAPI/Framework/ModLoading/AssemblyLoader.cs37
-rw-r--r--src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs12
-rw-r--r--src/SMAPI/Framework/ModLoading/Rewriters/FieldReplaceRewriter.cs2
-rw-r--r--src/SMAPI/Framework/ModLoading/Rewriters/FieldToPropertyRewriter.cs2
-rw-r--r--src/SMAPI/Framework/ModLoading/Rewriters/MethodParentRewriter.cs2
-rw-r--r--src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs2
-rw-r--r--src/SMAPI/Program.cs4
-rw-r--r--src/SMAPI/StardewModdingAPI.csproj12
-rw-r--r--src/SMAPI/packages.config2
10 files changed, 48 insertions, 36 deletions
diff --git a/src/SMAPI/Framework/ModLoading/AssemblyDefinitionResolver.cs b/src/SMAPI/Framework/ModLoading/AssemblyDefinitionResolver.cs
index d85a9a28..33cd6ebd 100644
--- a/src/SMAPI/Framework/ModLoading/AssemblyDefinitionResolver.cs
+++ b/src/SMAPI/Framework/ModLoading/AssemblyDefinitionResolver.cs
@@ -36,15 +36,6 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <param name="parameters">The assembly reader parameters.</param>
public override AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters) => this.ResolveName(name.Name) ?? base.Resolve(name, parameters);
- /// <summary>Resolve an assembly reference.</summary>
- /// <param name="fullName">The assembly full name (including version, etc).</param>
- public override AssemblyDefinition Resolve(string fullName) => this.ResolveName(fullName) ?? base.Resolve(fullName);
-
- /// <summary>Resolve an assembly reference.</summary>
- /// <param name="fullName">The assembly full name (including version, etc).</param>
- /// <param name="parameters">The assembly reader parameters.</param>
- public override AssemblyDefinition Resolve(string fullName, ReaderParameters parameters) => this.ResolveName(fullName) ?? base.Resolve(fullName, parameters);
-
/*********
** Private methods
diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
index 2fb2aba7..d41774a9 100644
--- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
+++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
@@ -12,7 +12,7 @@ using StardewModdingAPI.Metadata;
namespace StardewModdingAPI.Framework.ModLoading
{
/// <summary>Preprocesses and loads mod assemblies.</summary>
- internal class AssemblyLoader
+ internal class AssemblyLoader : IDisposable
{
/*********
** Properties
@@ -20,9 +20,6 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <summary>Encapsulates monitoring and logging.</summary>
private readonly IMonitor Monitor;
- /// <summary>Whether to enable developer mode logging.</summary>
- private readonly bool IsDeveloperMode;
-
/// <summary>Metadata for mapping assemblies to the current platform.</summary>
private readonly PlatformAssemblyMap AssemblyMap;
@@ -32,6 +29,9 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <summary>A minimal assembly definition resolver which resolves references to known loaded assemblies.</summary>
private readonly AssemblyDefinitionResolver AssemblyDefinitionResolver;
+ /// <summary>The objects to dispose as part of this instance.</summary>
+ private readonly HashSet<IDisposable> Disposables = new HashSet<IDisposable>();
+
/*********
** Public methods
@@ -39,13 +39,11 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <summary>Construct an instance.</summary>
/// <param name="targetPlatform">The current game platform.</param>
/// <param name="monitor">Encapsulates monitoring and logging.</param>
- /// <param name="isDeveloperMode">Whether to enable developer mode logging.</param>
- public AssemblyLoader(Platform targetPlatform, IMonitor monitor, bool isDeveloperMode)
+ public AssemblyLoader(Platform targetPlatform, IMonitor monitor)
{
this.Monitor = monitor;
- this.IsDeveloperMode = isDeveloperMode;
- this.AssemblyMap = Constants.GetAssemblyMap(targetPlatform);
- this.AssemblyDefinitionResolver = new AssemblyDefinitionResolver();
+ this.AssemblyMap = this.TrackForDisposal(Constants.GetAssemblyMap(targetPlatform));
+ this.AssemblyDefinitionResolver = this.TrackForDisposal(new AssemblyDefinitionResolver());
// generate type => assembly lookup for types which should be rewritten
this.TypeAssemblies = new Dictionary<string, Assembly>();
@@ -144,10 +142,26 @@ namespace StardewModdingAPI.Framework.ModLoading
.FirstOrDefault(p => p.GetName().Name == shortName);
}
+ /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
+ public void Dispose()
+ {
+ foreach (IDisposable instance in this.Disposables)
+ instance.Dispose();
+ }
+
/*********
** Private methods
*********/
+ /// <summary>Track an object for disposal as part of the assembly loader.</summary>
+ /// <typeparam name="T">The instance type.</typeparam>
+ /// <param name="instance">The disposable instance.</param>
+ private T TrackForDisposal<T>(T instance) where T : IDisposable
+ {
+ this.Disposables.Add(instance);
+ return instance;
+ }
+
/****
** Assembly parsing
****/
@@ -166,9 +180,8 @@ namespace StardewModdingAPI.Framework.ModLoading
// read assembly
byte[] assemblyBytes = File.ReadAllBytes(file.FullName);
- AssemblyDefinition assembly;
- using (Stream readStream = new MemoryStream(assemblyBytes))
- assembly = AssemblyDefinition.ReadAssembly(readStream, new ReaderParameters(ReadingMode.Deferred) { AssemblyResolver = assemblyResolver });
+ Stream readStream = this.TrackForDisposal(new MemoryStream(assemblyBytes));
+ AssemblyDefinition assembly = this.TrackForDisposal(AssemblyDefinition.ReadAssembly(readStream, new ReaderParameters(ReadingMode.Immediate) { AssemblyResolver = assemblyResolver, InMemory = true }));
// skip if already visited
if (visitedAssemblyNames.Contains(assembly.Name.Name))
diff --git a/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs b/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs
index f0a28b4a..01460dce 100644
--- a/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs
+++ b/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@@ -7,7 +8,7 @@ using StardewModdingAPI.Internal;
namespace StardewModdingAPI.Framework.ModLoading
{
/// <summary>Metadata for mapping assemblies to the current <see cref="Platform"/>.</summary>
- internal class PlatformAssemblyMap
+ internal class PlatformAssemblyMap : IDisposable
{
/*********
** Accessors
@@ -50,7 +51,14 @@ namespace StardewModdingAPI.Framework.ModLoading
// cache assembly metadata
this.Targets = targetAssemblies;
this.TargetReferences = this.Targets.ToDictionary(assembly => assembly, assembly => AssemblyNameReference.Parse(assembly.FullName));
- this.TargetModules = this.Targets.ToDictionary(assembly => assembly, assembly => ModuleDefinition.ReadModule(assembly.Modules.Single().FullyQualifiedName));
+ this.TargetModules = this.Targets.ToDictionary(assembly => assembly, assembly => ModuleDefinition.ReadModule(assembly.Modules.Single().FullyQualifiedName, new ReaderParameters { InMemory = true }));
+ }
+
+ /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
+ public void Dispose()
+ {
+ foreach (ModuleDefinition module in this.TargetModules.Values)
+ module.Dispose();
}
}
}
diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/FieldReplaceRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/FieldReplaceRewriter.cs
index 63358b39..806a074f 100644
--- a/src/SMAPI/Framework/ModLoading/Rewriters/FieldReplaceRewriter.cs
+++ b/src/SMAPI/Framework/ModLoading/Rewriters/FieldReplaceRewriter.cs
@@ -42,7 +42,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters
if (!this.IsMatch(instruction))
return InstructionHandleResult.None;
- FieldReference newRef = module.Import(this.ToField);
+ FieldReference newRef = module.ImportReference(this.ToField);
cil.Replace(instruction, cil.Create(instruction.OpCode, newRef));
return InstructionHandleResult.Rewritten;
}
diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/FieldToPropertyRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/FieldToPropertyRewriter.cs
index b1fa377a..e6ede9e3 100644
--- a/src/SMAPI/Framework/ModLoading/Rewriters/FieldToPropertyRewriter.cs
+++ b/src/SMAPI/Framework/ModLoading/Rewriters/FieldToPropertyRewriter.cs
@@ -50,7 +50,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters
return InstructionHandleResult.None;
string methodPrefix = instruction.OpCode == OpCodes.Ldsfld || instruction.OpCode == OpCodes.Ldfld ? "get" : "set";
- MethodReference propertyRef = module.Import(this.Type.GetMethod($"{methodPrefix}_{this.PropertyName}"));
+ MethodReference propertyRef = module.ImportReference(this.Type.GetMethod($"{methodPrefix}_{this.PropertyName}"));
cil.Replace(instruction, cil.Create(OpCodes.Call, propertyRef));
return InstructionHandleResult.Rewritten;
diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/MethodParentRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/MethodParentRewriter.cs
index 974fcf4c..99bd9125 100644
--- a/src/SMAPI/Framework/ModLoading/Rewriters/MethodParentRewriter.cs
+++ b/src/SMAPI/Framework/ModLoading/Rewriters/MethodParentRewriter.cs
@@ -64,7 +64,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters
return InstructionHandleResult.None;
MethodReference methodRef = (MethodReference)instruction.Operand;
- methodRef.DeclaringType = module.Import(this.ToType);
+ methodRef.DeclaringType = module.ImportReference(this.ToType);
return InstructionHandleResult.Rewritten;
}
diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs
index 74f2fcdd..5c7db902 100644
--- a/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs
+++ b/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs
@@ -135,7 +135,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters
{
// root type
if (type.FullName == this.FromTypeName)
- return module.Import(this.ToType);
+ return module.ImportReference(this.ToType);
// generic arguments
if (type is GenericInstanceType genericType)
diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs
index 53f3749a..7b5176a0 100644
--- a/src/SMAPI/Program.cs
+++ b/src/SMAPI/Program.cs
@@ -686,7 +686,7 @@ namespace StardewModdingAPI
// show update errors
if (errors.Length != 0)
- this.Monitor.Log("Encountered errors fetching updates for some mods:\n" + errors.ToString(), LogLevel.Trace);
+ this.Monitor.Log("Encountered errors fetching updates for some mods:\n" + errors, LogLevel.Trace);
// show update alerts
if (updates.Any())
@@ -796,7 +796,7 @@ namespace StardewModdingAPI
);
// get assembly loaders
- AssemblyLoader modAssemblyLoader = new AssemblyLoader(Constants.Platform, this.Monitor, this.Settings.DeveloperMode);
+ AssemblyLoader modAssemblyLoader = new AssemblyLoader(Constants.Platform, this.Monitor);
AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => modAssemblyLoader.ResolveAssembly(e.Name);
InterfaceProxyFactory proxyFactory = new InterfaceProxyFactory();
diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj
index bd9e2422..2e3ba1cd 100644
--- a/src/SMAPI/StardewModdingAPI.csproj
+++ b/src/SMAPI/StardewModdingAPI.csproj
@@ -58,16 +58,16 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\lib\0Harmony.dll</HintPath>
</Reference>
- <Reference Include="Mono.Cecil, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
- <HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll</HintPath>
+ <Reference Include="Mono.Cecil, Version=0.10.0.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
+ <HintPath>..\packages\Mono.Cecil.0.10.0\lib\net40\Mono.Cecil.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="Mono.Cecil.Mdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
- <HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Mdb.dll</HintPath>
+ <Reference Include="Mono.Cecil.Mdb, Version=0.10.0.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
+ <HintPath>..\packages\Mono.Cecil.0.10.0\lib\net40\Mono.Cecil.Mdb.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="Mono.Cecil.Pdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
- <HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Pdb.dll</HintPath>
+ <Reference Include="Mono.Cecil.Pdb, Version=0.10.0.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
+ <HintPath>..\packages\Mono.Cecil.0.10.0\lib\net40\Mono.Cecil.Pdb.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
diff --git a/src/SMAPI/packages.config b/src/SMAPI/packages.config
index 3347b037..84c6bed0 100644
--- a/src/SMAPI/packages.config
+++ b/src/SMAPI/packages.config
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="LargeAddressAware" version="1.0.3" targetFramework="net45" />
- <package id="Mono.Cecil" version="0.9.6.4" targetFramework="net45" />
+ <package id="Mono.Cecil" version="0.10.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net45" />
</packages> \ No newline at end of file