From 45f4f85b7e74e0cffd345310d6aabc95c12dac26 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 13 Apr 2018 23:47:24 -0400 Subject: add MacOS detection --- src/SMAPI/Framework/ModLoading/AssemblyLoader.cs | 1 + src/SMAPI/Framework/ModLoading/Platform.cs | 12 ------------ src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs | 1 + 3 files changed, 2 insertions(+), 12 deletions(-) delete mode 100644 src/SMAPI/Framework/ModLoading/Platform.cs (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs index a60f63da..bf9b6450 100644 --- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs +++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Reflection; using Mono.Cecil; using Mono.Cecil.Cil; +using StardewModdingAPI.Common; using StardewModdingAPI.Framework.Exceptions; using StardewModdingAPI.Metadata; diff --git a/src/SMAPI/Framework/ModLoading/Platform.cs b/src/SMAPI/Framework/ModLoading/Platform.cs deleted file mode 100644 index 45e881c4..00000000 --- a/src/SMAPI/Framework/ModLoading/Platform.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace StardewModdingAPI.Framework.ModLoading -{ - /// The game's platform version. - internal enum Platform - { - /// The Linux/Mac version of the game. - Mono, - - /// The Windows version of the game. - Windows - } -} diff --git a/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs b/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs index 463f45e8..9499b538 100644 --- a/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs +++ b/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using Mono.Cecil; +using StardewModdingAPI.Common; namespace StardewModdingAPI.Framework.ModLoading { -- cgit From bb2c52386015829c161a56d418f3795335559d8a Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 15 Apr 2018 01:14:28 -0400 Subject: tweak trace logs for readability when loading mods --- src/SMAPI/Framework/ModLoading/AssemblyLoader.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs index bf9b6450..feaee047 100644 --- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs +++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs @@ -99,13 +99,13 @@ namespace StardewModdingAPI.Framework.ModLoading continue; // rewrite assembly - bool changed = this.RewriteAssembly(mod, assembly.Definition, assumeCompatible, loggedMessages, logPrefix: " "); + bool changed = this.RewriteAssembly(mod, assembly.Definition, assumeCompatible, loggedMessages, logPrefix: " "); // load assembly if (changed) { if (!oneAssembly) - this.Monitor.Log($" Loading {assembly.File.Name} (rewritten in memory)...", LogLevel.Trace); + this.Monitor.Log($" Loading {assembly.File.Name} (rewritten in memory)...", LogLevel.Trace); using (MemoryStream outStream = new MemoryStream()) { assembly.Definition.Write(outStream); @@ -116,7 +116,7 @@ namespace StardewModdingAPI.Framework.ModLoading else { if (!oneAssembly) - this.Monitor.Log($" Loading {assembly.File.Name}...", LogLevel.Trace); + this.Monitor.Log($" Loading {assembly.File.Name}...", LogLevel.Trace); lastAssembly = Assembly.UnsafeLoadFrom(assembly.File.FullName); } @@ -290,22 +290,22 @@ namespace StardewModdingAPI.Framework.ModLoading case InstructionHandleResult.DetectedGamePatch: this.Monitor.LogOnce(loggedMessages, $"{logPrefix}Detected game patcher ({handler.NounPhrase}) in assembly {filename}."); - this.Monitor.LogOnce(loggedMessages, $"{mod.DisplayName} patches the game, which may impact game stability. If you encounter problems, try removing this mod first.", LogLevel.Warn); + this.Monitor.LogOnce(loggedMessages, $"{logPrefix}{mod.DisplayName} patches the game, which may impact game stability. If you encounter problems, try removing this mod first.", LogLevel.Warn); break; case InstructionHandleResult.DetectedSaveSerialiser: this.Monitor.LogOnce(loggedMessages, $"{logPrefix}Detected possible save serialiser change ({handler.NounPhrase}) in assembly {filename}."); - this.Monitor.LogOnce(loggedMessages, $"{mod.DisplayName} seems to change the save serialiser. It may change your saves in such a way that they won't work without this mod in the future.", LogLevel.Warn); + this.Monitor.LogOnce(loggedMessages, $"{logPrefix}{mod.DisplayName} seems to change the save serialiser. It may change your saves in such a way that they won't work without this mod in the future.", LogLevel.Warn); break; case InstructionHandleResult.DetectedUnvalidatedUpdateTick: this.Monitor.LogOnce(loggedMessages, $"{logPrefix}Detected reference to {handler.NounPhrase} in assembly {filename}."); - this.Monitor.LogOnce(loggedMessages, $"{mod.DisplayName} uses a specialised SMAPI event that may crash the game or corrupt your save file. If you encounter problems, try removing this mod first.", LogLevel.Warn); + this.Monitor.LogOnce(loggedMessages, $"{logPrefix}{mod.DisplayName} uses a specialised SMAPI event that may crash the game or corrupt your save file. If you encounter problems, try removing this mod first.", LogLevel.Warn); break; case InstructionHandleResult.DetectedDynamic: this.Monitor.LogOnce(loggedMessages, $"{logPrefix}Detected 'dynamic' keyword ({handler.NounPhrase}) in assembly {filename}."); - this.Monitor.LogOnce(loggedMessages, $"{mod.DisplayName} uses the 'dynamic' keyword, which isn't compatible with Stardew Valley on Linux or Mac.", + this.Monitor.LogOnce(loggedMessages, $"{logPrefix}{mod.DisplayName} uses the 'dynamic' keyword, which isn't compatible with Stardew Valley on Linux or Mac.", #if SMAPI_FOR_WINDOWS this.IsDeveloperMode ? LogLevel.Warn : LogLevel.Debug #else -- cgit From 4af998024cf47ed90a2177c42b77217208685f50 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 17 Apr 2018 21:12:03 -0400 Subject: add warning in developer mode for mods with no update keys --- src/SMAPI/Framework/ModLoading/ModMetadata.cs | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/ModMetadata.cs b/src/SMAPI/Framework/ModLoading/ModMetadata.cs index 1a0f9994..af888b71 100644 --- a/src/SMAPI/Framework/ModLoading/ModMetadata.cs +++ b/src/SMAPI/Framework/ModLoading/ModMetadata.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using StardewModdingAPI.Framework.ModData; namespace StardewModdingAPI.Framework.ModLoading @@ -102,5 +103,13 @@ namespace StardewModdingAPI.Framework.ModLoading this.Api = api; return this; } + + /// Whether the mod has at least one update key set. + public bool HasUpdateKeys() + { + return + this.Manifest?.UpdateKeys != null + && this.Manifest.UpdateKeys.Any(key => !string.IsNullOrWhiteSpace(key)); + } } } -- cgit From e80e6564b374b9b5a37748f1a42e10025d92776f Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 18 Apr 2018 20:58:25 -0400 Subject: detect broken references to fields which changed generic type (#453) Previously generic types couldn't be compared correctly, since we'd end up with false differences like "Dictionary`1 != Dictionary". That seems to be fixed now, possibly due to the PDB file being included. --- .../ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs index b5e45742..2cbb3a8e 100644 --- a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs +++ b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs @@ -59,10 +59,6 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders FieldReference fieldRef = RewriteHelper.AsFieldReference(instruction); if (fieldRef != null && this.ShouldValidate(fieldRef.DeclaringType)) { - // can't compare generic type parameters between definition and reference - if (fieldRef.FieldType.IsGenericInstance || fieldRef.FieldType.IsGenericParameter) - return InstructionHandleResult.None; - // get target field FieldDefinition targetField = fieldRef.DeclaringType.Resolve()?.Fields.FirstOrDefault(p => p.Name == fieldRef.Name); if (targetField == null) -- cgit From 1b527f0b2573ba54024cdee80680983030246f4f Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 19 Apr 2018 19:11:50 -0400 Subject: detect broken references to methods which changed generic return type (#453) Previously generic types couldn't be compared correctly, since we'd end up with false differences like "Dictionary`1 != Dictionary". That seems to be fixed now, possibly due to the PDB file being included. --- .../ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs index 2cbb3a8e..ecad649a 100644 --- a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs +++ b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs @@ -78,10 +78,6 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders MethodReference methodReference = RewriteHelper.AsMethodReference(instruction); if (methodReference != null && this.ShouldValidate(methodReference.DeclaringType)) { - // can't compare generic type parameters between definition and reference - if (methodReference.ReturnType.IsGenericInstance || methodReference.ReturnType.IsGenericParameter) - return InstructionHandleResult.None; - // get potential targets MethodDefinition[] candidateMethods = methodReference.DeclaringType.Resolve()?.Methods.Where(found => found.Name == methodReference.Name).ToArray(); if (candidateMethods == null || !candidateMethods.Any()) -- cgit From 9cebd83cb968a61e809bd721056fd9fc17f3b5fe Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Mon, 23 Apr 2018 18:15:58 -0400 Subject: show update-key warnings before checking mod status, enable in non-dev mode --- src/SMAPI/Framework/ModLoading/ModMetadata.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/ModMetadata.cs b/src/SMAPI/Framework/ModLoading/ModMetadata.cs index af888b71..d3a33e7a 100644 --- a/src/SMAPI/Framework/ModLoading/ModMetadata.cs +++ b/src/SMAPI/Framework/ModLoading/ModMetadata.cs @@ -104,11 +104,18 @@ namespace StardewModdingAPI.Framework.ModLoading return this; } + /// Whether the mod manifest was loaded (regardless of whether the mod itself was loaded). + public bool HasManifest() + { + return this.Manifest != null; + } + /// Whether the mod has at least one update key set. public bool HasUpdateKeys() { return - this.Manifest?.UpdateKeys != null + this.HasManifest() + && this.Manifest.UpdateKeys != null && this.Manifest.UpdateKeys.Any(key => !string.IsNullOrWhiteSpace(key)); } } -- cgit From 009a387526ee10b18d0ed3030d6e8868edf17203 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 1 May 2018 18:44:39 -0400 Subject: unify SMAPI.AssemblyRewriters and SMAPI.Common projects --- src/SMAPI/Framework/ModLoading/AssemblyLoader.cs | 2 +- src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs index feaee047..6c0e1c14 100644 --- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs +++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs @@ -5,8 +5,8 @@ using System.Linq; using System.Reflection; using Mono.Cecil; using Mono.Cecil.Cil; -using StardewModdingAPI.Common; using StardewModdingAPI.Framework.Exceptions; +using StardewModdingAPI.Internal; using StardewModdingAPI.Metadata; namespace StardewModdingAPI.Framework.ModLoading diff --git a/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs b/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs index 9499b538..f0a28b4a 100644 --- a/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs +++ b/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using Mono.Cecil; -using StardewModdingAPI.Common; +using StardewModdingAPI.Internal; namespace StardewModdingAPI.Framework.ModLoading { -- cgit From 5121ae7b4a0b97b9e227b67903d0c6c88f3a3982 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 5 May 2018 22:18:52 -0400 Subject: enforce mod ID convention (only alphanumeric, hyphen, dot, and underscore) --- src/SMAPI/Framework/ModLoading/ModResolver.cs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs index a9896278..cec37fca 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text.RegularExpressions; using StardewModdingAPI.Framework.Exceptions; using StardewModdingAPI.Framework.ModData; using StardewModdingAPI.Framework.Models; @@ -194,8 +195,15 @@ namespace StardewModdingAPI.Framework.ModLoading missingFields.Add(nameof(IManifest.UniqueID)); if (missingFields.Any()) + { mod.SetStatus(ModMetadataStatus.Failed, $"its manifest is missing required fields ({string.Join(", ", missingFields)})."); + continue; + } } + + // validate ID format + if (Regex.IsMatch(mod.Manifest.UniqueID, "[^a-z0-9_.-]", RegexOptions.IgnoreCase)) + mod.SetStatus(ModMetadataStatus.Failed, "its manifest specifies an invalid ID (IDs must only contain letters, numbers, underscores, periods, or hyphens)."); } // validate IDs are unique -- cgit From b9036f212e7898f9cd13006024d63aec61d50ed6 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 12 May 2018 22:52:28 -0400 Subject: group mod warnings in console --- src/SMAPI/Framework/ModLoading/AssemblyLoader.cs | 16 ++++-------- src/SMAPI/Framework/ModLoading/ModMetadata.cs | 11 +++++++++ src/SMAPI/Framework/ModLoading/ModWarning.cs | 31 ++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 src/SMAPI/Framework/ModLoading/ModWarning.cs (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs index 6c0e1c14..2fb2aba7 100644 --- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs +++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs @@ -285,33 +285,27 @@ namespace StardewModdingAPI.Framework.ModLoading this.Monitor.LogOnce(loggedMessages, $"{logPrefix}Broken code in {filename}: {handler.NounPhrase}."); if (!assumeCompatible) throw new IncompatibleInstructionException(handler.NounPhrase, $"Found an incompatible CIL instruction ({handler.NounPhrase}) while loading assembly {filename}."); - this.Monitor.LogOnce(loggedMessages, $"{logPrefix}Found broken code ({handler.NounPhrase}) while loading assembly {filename}, but SMAPI is configured to allow it anyway. The mod may crash or behave unexpectedly.", LogLevel.Warn); + mod.SetWarning(ModWarning.BrokenCodeLoaded); break; case InstructionHandleResult.DetectedGamePatch: this.Monitor.LogOnce(loggedMessages, $"{logPrefix}Detected game patcher ({handler.NounPhrase}) in assembly {filename}."); - this.Monitor.LogOnce(loggedMessages, $"{logPrefix}{mod.DisplayName} patches the game, which may impact game stability. If you encounter problems, try removing this mod first.", LogLevel.Warn); + mod.SetWarning(ModWarning.PatchesGame); break; case InstructionHandleResult.DetectedSaveSerialiser: this.Monitor.LogOnce(loggedMessages, $"{logPrefix}Detected possible save serialiser change ({handler.NounPhrase}) in assembly {filename}."); - this.Monitor.LogOnce(loggedMessages, $"{logPrefix}{mod.DisplayName} seems to change the save serialiser. It may change your saves in such a way that they won't work without this mod in the future.", LogLevel.Warn); + mod.SetWarning(ModWarning.ChangesSaveSerialiser); break; case InstructionHandleResult.DetectedUnvalidatedUpdateTick: this.Monitor.LogOnce(loggedMessages, $"{logPrefix}Detected reference to {handler.NounPhrase} in assembly {filename}."); - this.Monitor.LogOnce(loggedMessages, $"{logPrefix}{mod.DisplayName} uses a specialised SMAPI event that may crash the game or corrupt your save file. If you encounter problems, try removing this mod first.", LogLevel.Warn); + mod.SetWarning(ModWarning.UsesUnvalidatedUpdateTick); break; case InstructionHandleResult.DetectedDynamic: this.Monitor.LogOnce(loggedMessages, $"{logPrefix}Detected 'dynamic' keyword ({handler.NounPhrase}) in assembly {filename}."); - this.Monitor.LogOnce(loggedMessages, $"{logPrefix}{mod.DisplayName} uses the 'dynamic' keyword, which isn't compatible with Stardew Valley on Linux or Mac.", -#if SMAPI_FOR_WINDOWS - this.IsDeveloperMode ? LogLevel.Warn : LogLevel.Debug -#else - LogLevel.Warn -#endif - ); + mod.SetWarning(ModWarning.UsesDynamic); break; case InstructionHandleResult.None: diff --git a/src/SMAPI/Framework/ModLoading/ModMetadata.cs b/src/SMAPI/Framework/ModLoading/ModMetadata.cs index d3a33e7a..e4ec7e3b 100644 --- a/src/SMAPI/Framework/ModLoading/ModMetadata.cs +++ b/src/SMAPI/Framework/ModLoading/ModMetadata.cs @@ -25,6 +25,9 @@ namespace StardewModdingAPI.Framework.ModLoading /// The metadata resolution status. public ModMetadataStatus Status { get; private set; } + /// Indicates non-error issues with the mod. + public ModWarning Warnings { get; private set; } + /// The reason the metadata is invalid, if any. public string Error { get; private set; } @@ -71,6 +74,14 @@ namespace StardewModdingAPI.Framework.ModLoading return this; } + /// Set a warning flag for the mod. + /// The warning to set. + public IModMetadata SetWarning(ModWarning warning) + { + this.Warnings |= warning; + return this; + } + /// Set the mod instance. /// The mod instance to set. public IModMetadata SetMod(IMod mod) diff --git a/src/SMAPI/Framework/ModLoading/ModWarning.cs b/src/SMAPI/Framework/ModLoading/ModWarning.cs new file mode 100644 index 00000000..0e4b2570 --- /dev/null +++ b/src/SMAPI/Framework/ModLoading/ModWarning.cs @@ -0,0 +1,31 @@ +using System; +using StardewModdingAPI.Events; + +namespace StardewModdingAPI.Framework.ModLoading +{ + /// Indicates a detected non-error mod issue. + [Flags] + internal enum ModWarning + { + /// No issues detected. + None = 0, + + /// SMAPI detected incompatible code in the mod, but was configured to load it anyway. + BrokenCodeLoaded = 1, + + /// The mod affects the save serializer in a way that may make saves unloadable without the mod. + ChangesSaveSerialiser = 2, + + /// The mod patches the game in a way that may impact stability. + PatchesGame = 4, + + /// The mod uses the dynamic keyword which won't work on Linux/Mac. + UsesDynamic = 8, + + /// The mod references which may impact stability. + UsesUnvalidatedUpdateTick = 16, + + /// The mod has no update keys set. + NoUpdateKeys = 32 + } +} -- cgit From 47cfd6cd3d9a5f57be48a638bc8feca32006f7af Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 13 May 2018 23:03:31 -0400 Subject: tweak not-compatible messages --- src/SMAPI/Framework/ModLoading/ModResolver.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs index cec37fca..b5339183 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -99,7 +99,7 @@ namespace StardewModdingAPI.Framework.ModLoading case ModStatus.AssumeBroken: { // get reason - string reasonPhrase = mod.DataRecord.StatusReasonPhrase ?? "it's outdated"; + string reasonPhrase = mod.DataRecord.StatusReasonPhrase ?? "it's no longer compatible"; // get update URLs List updateUrls = new List(); -- cgit From 69b17f1db87d9aeb5dd6d6f9c81ac9ac62f2a6d3 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 25 May 2018 02:06:28 -0400 Subject: move PathUtilities into toolkit (#532) --- src/SMAPI/Framework/ModLoading/ModResolver.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs index b5339183..d46caa55 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -7,7 +7,7 @@ using StardewModdingAPI.Framework.Exceptions; using StardewModdingAPI.Framework.ModData; using StardewModdingAPI.Framework.Models; using StardewModdingAPI.Framework.Serialisation; -using StardewModdingAPI.Framework.Utilities; +using StardewModdingAPI.Toolkit.Utilities; namespace StardewModdingAPI.Framework.ModLoading { -- cgit From 625c538f244519700f3942b2b2969845db9a99b0 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 5 Jun 2018 20:22:46 -0400 Subject: move manifest parsing into toolkit (#532) --- src/SMAPI/Framework/ModLoading/ModResolver.cs | 37 +++++++++++++++------------ 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs index d46caa55..ddc8650c 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; -using StardewModdingAPI.Framework.Exceptions; using StardewModdingAPI.Framework.ModData; using StardewModdingAPI.Framework.Models; -using StardewModdingAPI.Framework.Serialisation; +using StardewModdingAPI.Toolkit.Serialisation; using StardewModdingAPI.Toolkit.Utilities; +using ToolkitManifest = StardewModdingAPI.Toolkit.Serialisation.Models.Manifest; namespace StardewModdingAPI.Framework.ModLoading { @@ -28,25 +28,28 @@ namespace StardewModdingAPI.Framework.ModLoading { // read file Manifest manifest = null; - string path = Path.Combine(modDir.FullName, "manifest.json"); string error = null; - try { - manifest = jsonHelper.ReadJsonFile(path); - if (manifest == null) + string path = Path.Combine(modDir.FullName, "manifest.json"); + try { - error = File.Exists(path) - ? "its manifest is invalid." - : "it doesn't have a manifest."; + ToolkitManifest rawManifest = jsonHelper.ReadJsonFile(path); + if (rawManifest == null) + { + error = File.Exists(path) + ? "its manifest is invalid." + : "it doesn't have a manifest."; + } + manifest = new Manifest(rawManifest); + } + catch (SParseException ex) + { + error = $"parsing its manifest failed: {ex.Message}"; + } + catch (Exception ex) + { + error = $"parsing its manifest failed:\n{ex.GetLogSummary()}"; } - } - catch (SParseException ex) - { - error = $"parsing its manifest failed: {ex.Message}"; - } - catch (Exception ex) - { - error = $"parsing its manifest failed:\n{ex.GetLogSummary()}"; } // parse internal data record (if any) -- cgit From 94e59482fc86da15d2e3f0599f46294b0b82ad62 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 9 Jun 2018 16:24:21 -0400 Subject: fix incorrect error when a mod has no manifest --- src/SMAPI/Framework/ModLoading/ModResolver.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs index ddc8650c..3366e8c1 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -40,7 +40,8 @@ namespace StardewModdingAPI.Framework.ModLoading ? "its manifest is invalid." : "it doesn't have a manifest."; } - manifest = new Manifest(rawManifest); + else + manifest = new Manifest(rawManifest); } catch (SParseException ex) { -- cgit From 5b9e365b5d252e2d1e957303c6b06fa1b3ae2f14 Mon Sep 17 00:00:00 2001 From: Dan Volchek Date: Sun, 10 Jun 2018 13:15:53 -0700 Subject: add version info to ModMetadata, change update checking to consider preview versions --- src/SMAPI/Framework/ModLoading/ModMetadata.cs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/ModMetadata.cs b/src/SMAPI/Framework/ModLoading/ModMetadata.cs index e4ec7e3b..8f544da3 100644 --- a/src/SMAPI/Framework/ModLoading/ModMetadata.cs +++ b/src/SMAPI/Framework/ModLoading/ModMetadata.cs @@ -43,6 +43,15 @@ namespace StardewModdingAPI.Framework.ModLoading /// The mod-provided API (if any). public object Api { get; private set; } + /// The latest version of the mod. + public ISemanticVersion LatestVersion { get; private set; } + + /// The latest preview version of the mod, if any. + public ISemanticVersion LatestPreviewVersion { get; private set; } + + /// The error checking for updates for this mod, if any. + public string UpdateCheckError { get; private set; } + /// Whether the mod is a content pack. public bool IsContentPack => this.Manifest?.ContentPackFor != null; @@ -115,6 +124,24 @@ namespace StardewModdingAPI.Framework.ModLoading return this; } + /// Set the update status. + /// The latest version. + /// The latest preview version. + public IModMetadata SetUpdateStatus(ISemanticVersion latestVersion, ISemanticVersion latestPreviewVersion) + { + this.LatestVersion = latestVersion; + this.LatestPreviewVersion = latestPreviewVersion; + return this; + } + + // Set the update status, indicating an error happened. + /// The error checking for updates, if any. + public IModMetadata SetUpdateStatus(string updateCheckError) + { + this.UpdateCheckError = updateCheckError; + return this; + } + /// Whether the mod manifest was loaded (regardless of whether the mod itself was loaded). public bool HasManifest() { -- cgit From 1fa2632289134c39f268c374bb290549f28751d5 Mon Sep 17 00:00:00 2001 From: Dan Volchek Date: Sun, 10 Jun 2018 14:19:05 -0700 Subject: seperate IModMetadata methods, call them correctly when updating --- src/SMAPI/Framework/ModLoading/ModMetadata.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/ModMetadata.cs b/src/SMAPI/Framework/ModLoading/ModMetadata.cs index 8f544da3..1ead1387 100644 --- a/src/SMAPI/Framework/ModLoading/ModMetadata.cs +++ b/src/SMAPI/Framework/ModLoading/ModMetadata.cs @@ -124,19 +124,25 @@ namespace StardewModdingAPI.Framework.ModLoading return this; } - /// Set the update status. + /// Set the update version. /// The latest version. - /// The latest preview version. - public IModMetadata SetUpdateStatus(ISemanticVersion latestVersion, ISemanticVersion latestPreviewVersion) + public IModMetadata SetUpdateVersion(ISemanticVersion latestVersion) { this.LatestVersion = latestVersion; + return this; + } + + /// Set the preview update version. + /// The latest preview version. + public IModMetadata SetPreviewUpdateVersion(ISemanticVersion latestPreviewVersion) + { this.LatestPreviewVersion = latestPreviewVersion; return this; } - // Set the update status, indicating an error happened. - /// The error checking for updates, if any. - public IModMetadata SetUpdateStatus(string updateCheckError) + /// Set the error that occured while checking for updates. + /// The error checking for updates. + public IModMetadata SetUpdateError(string updateCheckError) { this.UpdateCheckError = updateCheckError; return this; -- cgit From 0b2e46d55cb09a169c7bb64ade37c82fc8233cb3 Mon Sep 17 00:00:00 2001 From: Dan Volchek Date: Sun, 10 Jun 2018 15:05:59 -0700 Subject: refactor IModMetadata update info --- src/SMAPI/Framework/ModLoading/ModMetadata.cs | 36 ++++++++++----------------- 1 file changed, 13 insertions(+), 23 deletions(-) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/ModMetadata.cs b/src/SMAPI/Framework/ModLoading/ModMetadata.cs index 1ead1387..88d2770c 100644 --- a/src/SMAPI/Framework/ModLoading/ModMetadata.cs +++ b/src/SMAPI/Framework/ModLoading/ModMetadata.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using StardewModdingAPI.Framework.ModData; +using StardewModdingAPI.Framework.ModUpdateChecking; namespace StardewModdingAPI.Framework.ModLoading { @@ -43,14 +44,11 @@ namespace StardewModdingAPI.Framework.ModLoading /// The mod-provided API (if any). public object Api { get; private set; } - /// The latest version of the mod. - public ISemanticVersion LatestVersion { get; private set; } + /// The update status of this mod (if any). + public ModUpdateStatus UpdateStatus { get; private set; } - /// The latest preview version of the mod, if any. - public ISemanticVersion LatestPreviewVersion { get; private set; } - - /// The error checking for updates for this mod, if any. - public string UpdateCheckError { get; private set; } + /// The preview update status of this mod (if any). + public ModUpdateStatus PreviewUpdateStatus { get; private set; } /// Whether the mod is a content pack. public bool IsContentPack => this.Manifest?.ContentPackFor != null; @@ -124,27 +122,19 @@ namespace StardewModdingAPI.Framework.ModLoading return this; } - /// Set the update version. - /// The latest version. - public IModMetadata SetUpdateVersion(ISemanticVersion latestVersion) - { - this.LatestVersion = latestVersion; - return this; - } - - /// Set the preview update version. - /// The latest preview version. - public IModMetadata SetPreviewUpdateVersion(ISemanticVersion latestPreviewVersion) + /// Set the update status. + /// The mod update status. + public IModMetadata SetUpdateStatus(ModUpdateStatus updateStatus) { - this.LatestPreviewVersion = latestPreviewVersion; + this.UpdateStatus = updateStatus; return this; } - /// Set the error that occured while checking for updates. - /// The error checking for updates. - public IModMetadata SetUpdateError(string updateCheckError) + /// Set the preview update status. + /// The mod preview update status. + public IModMetadata SetPreviewUpdateStatus(ModUpdateStatus previewUpdateStatus) { - this.UpdateCheckError = updateCheckError; + this.PreviewUpdateStatus = previewUpdateStatus; return this; } -- cgit From d401aff3307f6e2e1641610fdd912b572d6b04c1 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 19 Jun 2018 22:10:15 -0400 Subject: rewrite update checks (#551) --- src/SMAPI/Framework/ModLoading/ModMetadata.cs | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/ModMetadata.cs b/src/SMAPI/Framework/ModLoading/ModMetadata.cs index 88d2770c..02a77778 100644 --- a/src/SMAPI/Framework/ModLoading/ModMetadata.cs +++ b/src/SMAPI/Framework/ModLoading/ModMetadata.cs @@ -1,7 +1,7 @@ using System; using System.Linq; using StardewModdingAPI.Framework.ModData; -using StardewModdingAPI.Framework.ModUpdateChecking; +using StardewModdingAPI.Toolkit.Framework.Clients.WebApi; namespace StardewModdingAPI.Framework.ModLoading { @@ -44,11 +44,8 @@ namespace StardewModdingAPI.Framework.ModLoading /// The mod-provided API (if any). public object Api { get; private set; } - /// The update status of this mod (if any). - public ModUpdateStatus UpdateStatus { get; private set; } - - /// The preview update status of this mod (if any). - public ModUpdateStatus PreviewUpdateStatus { get; private set; } + /// The update-check metadata for this mod (if any). + public ModEntryModel UpdateCheckData { get; private set; } /// Whether the mod is a content pack. public bool IsContentPack => this.Manifest?.ContentPackFor != null; @@ -122,19 +119,11 @@ namespace StardewModdingAPI.Framework.ModLoading return this; } - /// Set the update status. - /// The mod update status. - public IModMetadata SetUpdateStatus(ModUpdateStatus updateStatus) - { - this.UpdateStatus = updateStatus; - return this; - } - - /// Set the preview update status. - /// The mod preview update status. - public IModMetadata SetPreviewUpdateStatus(ModUpdateStatus previewUpdateStatus) + /// Set the update-check metadata for this mod. + /// The update-check metadata. + public IModMetadata SetUpdateData(ModEntryModel data) { - this.PreviewUpdateStatus = previewUpdateStatus; + this.UpdateCheckData = data; return this; } -- cgit From ebc603844a3931bedbd512761ba8f152a4f5a09c Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 24 Jun 2018 19:49:34 -0400 Subject: update to Mono.Cecil 0.10 --- .../ModLoading/AssemblyDefinitionResolver.cs | 9 ------ src/SMAPI/Framework/ModLoading/AssemblyLoader.cs | 37 +++++++++++++++------- .../Framework/ModLoading/PlatformAssemblyMap.cs | 12 +++++-- .../ModLoading/Rewriters/FieldReplaceRewriter.cs | 2 +- .../Rewriters/FieldToPropertyRewriter.cs | 2 +- .../ModLoading/Rewriters/MethodParentRewriter.cs | 2 +- .../ModLoading/Rewriters/TypeReferenceRewriter.cs | 2 +- 7 files changed, 39 insertions(+), 27 deletions(-) (limited to 'src/SMAPI/Framework/ModLoading') 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 /// The assembly reader parameters. public override AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters) => this.ResolveName(name.Name) ?? base.Resolve(name, parameters); - /// Resolve an assembly reference. - /// The assembly full name (including version, etc). - public override AssemblyDefinition Resolve(string fullName) => this.ResolveName(fullName) ?? base.Resolve(fullName); - - /// Resolve an assembly reference. - /// The assembly full name (including version, etc). - /// The assembly reader parameters. - 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 { /// Preprocesses and loads mod assemblies. - internal class AssemblyLoader + internal class AssemblyLoader : IDisposable { /********* ** Properties @@ -20,9 +20,6 @@ namespace StardewModdingAPI.Framework.ModLoading /// Encapsulates monitoring and logging. private readonly IMonitor Monitor; - /// Whether to enable developer mode logging. - private readonly bool IsDeveloperMode; - /// Metadata for mapping assemblies to the current platform. private readonly PlatformAssemblyMap AssemblyMap; @@ -32,6 +29,9 @@ namespace StardewModdingAPI.Framework.ModLoading /// A minimal assembly definition resolver which resolves references to known loaded assemblies. private readonly AssemblyDefinitionResolver AssemblyDefinitionResolver; + /// The objects to dispose as part of this instance. + private readonly HashSet Disposables = new HashSet(); + /********* ** Public methods @@ -39,13 +39,11 @@ namespace StardewModdingAPI.Framework.ModLoading /// Construct an instance. /// The current game platform. /// Encapsulates monitoring and logging. - /// Whether to enable developer mode logging. - 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(); @@ -144,10 +142,26 @@ namespace StardewModdingAPI.Framework.ModLoading .FirstOrDefault(p => p.GetName().Name == shortName); } + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + public void Dispose() + { + foreach (IDisposable instance in this.Disposables) + instance.Dispose(); + } + /********* ** Private methods *********/ + /// Track an object for disposal as part of the assembly loader. + /// The instance type. + /// The disposable instance. + private T TrackForDisposal(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 { /// Metadata for mapping assemblies to the current . - 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 })); + } + + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + 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) -- cgit From 316242eeb2b6b6e711ab98f64c147a59c1d0aab8 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 24 Jun 2018 21:29:10 -0400 Subject: merge ISemanticVersion interfaces into new project (#532) --- .../Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs index 5c7db902..de9c439a 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs @@ -17,6 +17,9 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters /// The new type to reference. private readonly Type ToType; + /// A lambda which indicates whether a matching type reference should be rewritten. + private readonly Func ShouldRewrite; + /********* ** Public methods @@ -24,11 +27,13 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters /// Construct an instance. /// The full type name to which to find references. /// The new type to reference. - public TypeReferenceRewriter(string fromTypeFullName, Type toType) + /// A lambda which indicates whether a matching type reference should be rewritten. + public TypeReferenceRewriter(string fromTypeFullName, Type toType, Func shouldRewrite = null) : base(fromTypeFullName, InstructionHandleResult.None) { this.FromTypeName = fromTypeFullName; this.ToType = toType; + this.ShouldRewrite = shouldRewrite ?? (type => true); } /// Perform the predefined logic for a method if applicable. @@ -135,7 +140,11 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters { // root type if (type.FullName == this.FromTypeName) + { + if (!this.ShouldRewrite(type)) + return type; return module.ImportReference(this.ToType); + } // generic arguments if (type is GenericInstanceType genericType) -- cgit From b08e27d13a1f0c82656df95212fc40588b3b5314 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 24 Jun 2018 21:51:51 -0400 Subject: merge IManifest interfaces into new project (#532) --- src/SMAPI/Framework/ModLoading/ModResolver.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs index 3366e8c1..fde921e6 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -4,10 +4,9 @@ using System.IO; using System.Linq; using System.Text.RegularExpressions; using StardewModdingAPI.Framework.ModData; -using StardewModdingAPI.Framework.Models; using StardewModdingAPI.Toolkit.Serialisation; +using StardewModdingAPI.Toolkit.Serialisation.Models; using StardewModdingAPI.Toolkit.Utilities; -using ToolkitManifest = StardewModdingAPI.Toolkit.Serialisation.Models.Manifest; namespace StardewModdingAPI.Framework.ModLoading { @@ -33,15 +32,13 @@ namespace StardewModdingAPI.Framework.ModLoading string path = Path.Combine(modDir.FullName, "manifest.json"); try { - ToolkitManifest rawManifest = jsonHelper.ReadJsonFile(path); - if (rawManifest == null) + manifest = jsonHelper.ReadJsonFile(path); + if (manifest == null) { error = File.Exists(path) ? "its manifest is invalid." : "it doesn't have a manifest."; } - else - manifest = new Manifest(rawManifest); } catch (SParseException ex) { -- cgit From 08b37c70a35edd413e0da0c408e77d255200cf63 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 24 Jun 2018 23:04:23 -0400 Subject: move type match lambda up into TypeFinder (#532) --- src/SMAPI/Framework/ModLoading/Finders/TypeFinder.cs | 10 ++++++++-- .../ModLoading/Rewriters/TypeReferenceRewriter.cs | 18 +++++++----------- 2 files changed, 15 insertions(+), 13 deletions(-) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/Finders/TypeFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/TypeFinder.cs index 45349def..79045241 100644 --- a/src/SMAPI/Framework/ModLoading/Finders/TypeFinder.cs +++ b/src/SMAPI/Framework/ModLoading/Finders/TypeFinder.cs @@ -1,3 +1,4 @@ +using System; using System.Linq; using Mono.Cecil; using Mono.Cecil.Cil; @@ -16,6 +17,9 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders /// The result to return for matching instructions. private readonly InstructionHandleResult Result; + /// A lambda which overrides a matched type. + protected readonly Func ShouldIgnore; + /********* ** Accessors @@ -30,11 +34,13 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders /// Construct an instance. /// The full type name to match. /// The result to return for matching instructions. - public TypeFinder(string fullTypeName, InstructionHandleResult result) + /// A lambda which overrides a matched type. + public TypeFinder(string fullTypeName, InstructionHandleResult result, Func shouldIgnore = null) { this.FullTypeName = fullTypeName; this.Result = result; this.NounPhrase = $"{fullTypeName} type"; + this.ShouldIgnore = shouldIgnore ?? (p => false); } /// Perform the predefined logic for a method if applicable. @@ -113,7 +119,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders protected bool IsMatch(TypeReference type) { // root type - if (type.FullName == this.FullTypeName) + if (type.FullName == this.FullTypeName && !this.ShouldIgnore(type)) return true; // generic arguments diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs index de9c439a..1bef4df4 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs @@ -17,9 +17,6 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters /// The new type to reference. private readonly Type ToType; - /// A lambda which indicates whether a matching type reference should be rewritten. - private readonly Func ShouldRewrite; - /********* ** Public methods @@ -27,13 +24,12 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters /// Construct an instance. /// The full type name to which to find references. /// The new type to reference. - /// A lambda which indicates whether a matching type reference should be rewritten. - public TypeReferenceRewriter(string fromTypeFullName, Type toType, Func shouldRewrite = null) - : base(fromTypeFullName, InstructionHandleResult.None) + /// A lambda which overrides a matched type. + public TypeReferenceRewriter(string fromTypeFullName, Type toType, Func shouldIgnore = null) + : base(fromTypeFullName, InstructionHandleResult.None, shouldIgnore) { this.FromTypeName = fromTypeFullName; this.ToType = toType; - this.ShouldRewrite = shouldRewrite ?? (type => true); } /// Perform the predefined logic for a method if applicable. @@ -138,22 +134,22 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters /// The type to replace if it matches. private TypeReference RewriteIfNeeded(ModuleDefinition module, TypeReference type) { - // root type + // current type if (type.FullName == this.FromTypeName) { - if (!this.ShouldRewrite(type)) + if (this.ShouldIgnore(type)) return type; return module.ImportReference(this.ToType); } - // generic arguments + // recurse into generic arguments if (type is GenericInstanceType genericType) { for (int i = 0; i < genericType.GenericArguments.Count; i++) genericType.GenericArguments[i] = this.RewriteIfNeeded(module, genericType.GenericArguments[i]); } - // generic parameters (e.g. constraints) + // recurse into generic parameters (e.g. constraints) for (int i = 0; i < type.GenericParameters.Count; i++) type.GenericParameters[i] = new GenericParameter(this.RewriteIfNeeded(module, type.GenericParameters[i])); -- cgit From 06437b80aca329e749da2af79f4ed4d1a24db1b7 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 24 Jun 2018 23:08:06 -0400 Subject: only rewrite type references if necessary (#532) --- .../ModLoading/Rewriters/TypeReferenceRewriter.cs | 43 +++++++++------------- 1 file changed, 18 insertions(+), 25 deletions(-) (limited to 'src/SMAPI/Framework/ModLoading') diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs index 1bef4df4..cf840dcc 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs @@ -44,7 +44,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters // return type if (this.IsMatch(method.ReturnType)) { - method.ReturnType = this.RewriteIfNeeded(module, method.ReturnType); + this.RewriteIfNeeded(module, method.ReturnType, newType => method.ReturnType = newType); rewritten = true; } @@ -53,7 +53,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters { if (this.IsMatch(parameter.ParameterType)) { - parameter.ParameterType = this.RewriteIfNeeded(module, parameter.ParameterType); + this.RewriteIfNeeded(module, parameter.ParameterType, newType => parameter.ParameterType = newType); rewritten = true; } } @@ -64,9 +64,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters var parameter = method.GenericParameters[i]; if (this.IsMatch(parameter)) { - TypeReference newType = this.RewriteIfNeeded(module, parameter); - if (newType != parameter) - method.GenericParameters[i] = new GenericParameter(parameter.Name, newType); + this.RewriteIfNeeded(module, parameter, newType => method.GenericParameters[i] = new GenericParameter(parameter.Name, newType)); rewritten = true; } } @@ -76,7 +74,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters { if (this.IsMatch(variable.VariableType)) { - variable.VariableType = this.RewriteIfNeeded(module, variable.VariableType); + this.RewriteIfNeeded(module, variable.VariableType, newType => variable.VariableType = newType); rewritten = true; } } @@ -101,27 +99,23 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters FieldRefe