From da630efc1d5c95816493c2969736ae883e723757 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 14 Mar 2017 14:15:50 -0400 Subject: downgrade to .NET Framework 4.0 for better compatibility on Windows 7–8.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PlatformAssemblyMap.cs | 2 +- .../StardewModdingAPI.AssemblyRewriters.csproj | 14 +++++------ .../packages.config | 2 +- .../StardewModdingAPI.Installer.csproj | 2 +- src/StardewModdingAPI/App.config | 2 +- .../Events/ContentEventHandler.cs | 8 ++++++ src/StardewModdingAPI/Events/ContentEvents.cs | 2 +- .../Framework/InternalExtensions.cs | 29 ++++++++++++++++++++-- .../Framework/Reflection/PrivateProperty.cs | 4 +-- src/StardewModdingAPI/Framework/UpdateHelper.cs | 7 +++--- src/StardewModdingAPI/Program.cs | 24 ++++++------------ src/StardewModdingAPI/StardewModdingAPI.csproj | 20 ++++++++------- src/StardewModdingAPI/packages.config | 4 +-- src/TrainerMod/TrainerMod.csproj | 4 +-- src/TrainerMod/packages.config | 2 +- 15 files changed, 76 insertions(+), 50 deletions(-) create mode 100644 src/StardewModdingAPI/Events/ContentEventHandler.cs (limited to 'src') diff --git a/src/StardewModdingAPI.AssemblyRewriters/PlatformAssemblyMap.cs b/src/StardewModdingAPI.AssemblyRewriters/PlatformAssemblyMap.cs index fce2b187..3ca90149 100644 --- a/src/StardewModdingAPI.AssemblyRewriters/PlatformAssemblyMap.cs +++ b/src/StardewModdingAPI.AssemblyRewriters/PlatformAssemblyMap.cs @@ -49,7 +49,7 @@ namespace StardewModdingAPI.AssemblyRewriters // 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.GetModules().Single().FullyQualifiedName)); } } } diff --git a/src/StardewModdingAPI.AssemblyRewriters/StardewModdingAPI.AssemblyRewriters.csproj b/src/StardewModdingAPI.AssemblyRewriters/StardewModdingAPI.AssemblyRewriters.csproj index a3322e67..15bb15ac 100644 --- a/src/StardewModdingAPI.AssemblyRewriters/StardewModdingAPI.AssemblyRewriters.csproj +++ b/src/StardewModdingAPI.AssemblyRewriters/StardewModdingAPI.AssemblyRewriters.csproj @@ -9,7 +9,7 @@ Properties StardewModdingAPI.AssemblyRewriters StardewModdingAPI.AssemblyRewriters - v4.5 + v4.0 512 @@ -49,16 +49,16 @@ - ..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll - True + ..\packages\Mono.Cecil.0.9.6.4\lib\net40\Mono.Cecil.dll - ..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Mdb.dll - True + ..\packages\Mono.Cecil.0.9.6.4\lib\net40\Mono.Cecil.Mdb.dll - ..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Pdb.dll - True + ..\packages\Mono.Cecil.0.9.6.4\lib\net40\Mono.Cecil.Pdb.dll + + + ..\packages\Mono.Cecil.0.9.6.4\lib\net40\Mono.Cecil.Rocks.dll diff --git a/src/StardewModdingAPI.AssemblyRewriters/packages.config b/src/StardewModdingAPI.AssemblyRewriters/packages.config index 88fbc79d..70ba1aed 100644 --- a/src/StardewModdingAPI.AssemblyRewriters/packages.config +++ b/src/StardewModdingAPI.AssemblyRewriters/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/StardewModdingAPI.Installer/StardewModdingAPI.Installer.csproj b/src/StardewModdingAPI.Installer/StardewModdingAPI.Installer.csproj index e31a1452..366e1c6e 100644 --- a/src/StardewModdingAPI.Installer/StardewModdingAPI.Installer.csproj +++ b/src/StardewModdingAPI.Installer/StardewModdingAPI.Installer.csproj @@ -9,7 +9,7 @@ Properties StardewModdingAPI.Installer StardewModdingAPI.Installer - v4.5 + v4.0 512 true diff --git a/src/StardewModdingAPI/App.config b/src/StardewModdingAPI/App.config index 27cdf0f7..314845f7 100644 --- a/src/StardewModdingAPI/App.config +++ b/src/StardewModdingAPI/App.config @@ -1,7 +1,7 @@ - + diff --git a/src/StardewModdingAPI/Events/ContentEventHandler.cs b/src/StardewModdingAPI/Events/ContentEventHandler.cs new file mode 100644 index 00000000..2a7e75d1 --- /dev/null +++ b/src/StardewModdingAPI/Events/ContentEventHandler.cs @@ -0,0 +1,8 @@ +namespace StardewModdingAPI.Events +{ + /// Represents a method that will handle a content event. + /// The source of the event. + /// The event arguments. + /// This deviates from in allowing T to be an interface instead of a concrete class. While .NET Framework 4.5 allows that, the current .NET Framework 4.0 targeted by SMAPI to improve compatibility does not. + public delegate void ContentEventHandler(object sender, IContentEventHelper e); +} diff --git a/src/StardewModdingAPI/Events/ContentEvents.cs b/src/StardewModdingAPI/Events/ContentEvents.cs index 9418673a..339e90fd 100644 --- a/src/StardewModdingAPI/Events/ContentEvents.cs +++ b/src/StardewModdingAPI/Events/ContentEvents.cs @@ -28,7 +28,7 @@ namespace StardewModdingAPI.Events public static event EventHandler> AfterLocaleChanged; /// Raised when an XNB file is being read into the cache. Mods can change the data here before it's cached. - internal static event EventHandler AfterAssetLoaded; + internal static event ContentEventHandler AfterAssetLoaded; /********* diff --git a/src/StardewModdingAPI/Framework/InternalExtensions.cs b/src/StardewModdingAPI/Framework/InternalExtensions.cs index 4ca79518..46c76656 100644 --- a/src/StardewModdingAPI/Framework/InternalExtensions.cs +++ b/src/StardewModdingAPI/Framework/InternalExtensions.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using StardewModdingAPI.Events; namespace StardewModdingAPI.Framework { @@ -59,12 +60,36 @@ namespace StardewModdingAPI.Framework /// The event handlers. /// The event sender. /// The event arguments. - public static void SafelyRaiseGenericEvent(this IMonitor monitor, string name, IEnumerable handlers, object sender, TEventArgs args) + public static void SafelyRaiseGenericEvent(this IMonitor monitor, string name, IEnumerable handlers, object sender, TEventArgs args) where TEventArgs : EventArgs { if (handlers == null) return; - foreach (EventHandler handler in Enumerable.Cast>(handlers)) + foreach (EventHandler handler in handlers.Cast>()) + { + try + { + handler.Invoke(sender, args); + } + catch (Exception ex) + { + monitor.Log($"A mod failed handling the {name} event:\n{ex.GetLogSummary()}", LogLevel.Error); + } + } + } + + /// Safely raise an event, and intercept any exceptions thrown by its handlers. + /// Encapsulates monitoring and logging. + /// The event name for error messages. + /// The event handlers. + /// The event sender. + /// The event arguments. + public static void SafelyRaiseGenericEvent(this IMonitor monitor, string name, IEnumerable handlers, object sender, IContentEventHelper args) + { + if (handlers == null) + return; + + foreach (ContentEventHandler handler in handlers.Cast()) { try { diff --git a/src/StardewModdingAPI/Framework/Reflection/PrivateProperty.cs b/src/StardewModdingAPI/Framework/Reflection/PrivateProperty.cs index 08204b7e..d89e8e44 100644 --- a/src/StardewModdingAPI/Framework/Reflection/PrivateProperty.cs +++ b/src/StardewModdingAPI/Framework/Reflection/PrivateProperty.cs @@ -60,7 +60,7 @@ namespace StardewModdingAPI.Framework.Reflection { try { - return (TValue)this.PropertyInfo.GetValue(this.Parent); + return (TValue)this.PropertyInfo.GetValue(this.Parent, null); } catch (InvalidCastException) { @@ -78,7 +78,7 @@ namespace StardewModdingAPI.Framework.Reflection { try { - this.PropertyInfo.SetValue(this.Parent, value); + this.PropertyInfo.SetValue(this.Parent, value, null); } catch (InvalidCastException) { diff --git a/src/StardewModdingAPI/Framework/UpdateHelper.cs b/src/StardewModdingAPI/Framework/UpdateHelper.cs index e01e55c8..342a08cf 100644 --- a/src/StardewModdingAPI/Framework/UpdateHelper.cs +++ b/src/StardewModdingAPI/Framework/UpdateHelper.cs @@ -1,7 +1,6 @@ using System.IO; using System.Net; using System.Reflection; -using System.Threading.Tasks; using Newtonsoft.Json; using StardewModdingAPI.Framework.Models; @@ -15,17 +14,17 @@ namespace StardewModdingAPI.Framework *********/ /// Get the latest release from a GitHub repository. /// The name of the repository from which to fetch releases (like "cjsu/SMAPI"). - public static async Task GetLatestVersionAsync(string repository) + public static GitRelease GetLatestVersion(string repository) { // build request // (avoid HttpClient for Mac compatibility) - HttpWebRequest request = WebRequest.CreateHttp($"https://api.github.com/repos/{repository}/releases/latest"); + HttpWebRequest request = (HttpWebRequest)WebRequest.Create($"https://api.github.com/repos/{repository}/releases/latest"); AssemblyName assembly = typeof(UpdateHelper).Assembly.GetName(); request.UserAgent = $"{assembly.Name}/{assembly.Version}"; request.Accept = "application/vnd.github.v3+json"; // fetch data - using (WebResponse response = await request.GetResponseAsync()) + using (WebResponse response = request.GetResponse()) using (Stream responseStream = response.GetResponseStream()) using (StreamReader reader = new StreamReader(responseStream)) { diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs index db7a3df6..81e6518e 100644 --- a/src/StardewModdingAPI/Program.cs +++ b/src/StardewModdingAPI/Program.cs @@ -187,7 +187,7 @@ namespace StardewModdingAPI { try { - GitRelease release = UpdateHelper.GetLatestVersionAsync(Constants.GitHubRepository).Result; + GitRelease release = UpdateHelper.GetLatestVersion(Constants.GitHubRepository); ISemanticVersion latestVersion = new SemanticVersion(release.Tag); if (latestVersion.IsNewerThan(Constants.ApiVersion)) this.Monitor.Log($"You can update SMAPI from version {Constants.ApiVersion} to {latestVersion}", LogLevel.Alert); @@ -446,26 +446,18 @@ namespace StardewModdingAPI continue; } - // validate assembly + // initialise mod try { - if (modAssembly.DefinedTypes.Count(x => x.BaseType == typeof(Mod)) == 0) + // get mod entry type + Type modEntryType = modAssembly.GetExportedTypes().FirstOrDefault(x => x.BaseType == typeof(Mod)); + if(modEntryType == null) { - this.Monitor.Log($"{skippedPrefix} because its DLL has no 'Mod' subclass.", LogLevel.Error); + this.Monitor.Log($"{skippedPrefix} because its DLL has no {typeof(Mod).FullName} entry class.", LogLevel.Error); continue; } - } - catch (Exception ex) - { - this.Monitor.Log($"{skippedPrefix} because its DLL couldn't be loaded.\n{ex.GetLogSummary()}", LogLevel.Error); - continue; - } - - // initialise mod - try - { - // get implementation - TypeInfo modEntryType = modAssembly.DefinedTypes.First(x => x.BaseType == typeof(Mod)); + + // get mod class Mod mod = (Mod)modAssembly.CreateInstance(modEntryType.ToString()); if (mod == null) { diff --git a/src/StardewModdingAPI/StardewModdingAPI.csproj b/src/StardewModdingAPI/StardewModdingAPI.csproj index dceae74e..3a2bb756 100644 --- a/src/StardewModdingAPI/StardewModdingAPI.csproj +++ b/src/StardewModdingAPI/StardewModdingAPI.csproj @@ -9,7 +9,7 @@ Properties StardewModdingAPI StardewModdingAPI - v4.5 + v4.0 512 false @@ -60,7 +60,7 @@ $(SolutionDir)\..\bin\Debug\SMAPI $(SolutionDir)\..\bin\Debug\SMAPI\StardewModdingAPI.xml true - 6 + 7 x86 @@ -79,19 +79,22 @@ - ..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll + ..\packages\Mono.Cecil.0.9.6.4\lib\net40\Mono.Cecil.dll True - ..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Mdb.dll + ..\packages\Mono.Cecil.0.9.6.4\lib\net40\Mono.Cecil.Mdb.dll True - ..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Pdb.dll + ..\packages\Mono.Cecil.0.9.6.4\lib\net40\Mono.Cecil.Pdb.dll True + + ..\packages\Mono.Cecil.0.9.6.4\lib\net40\Mono.Cecil.Rocks.dll + - ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll + ..\packages\Newtonsoft.Json.8.0.3\lib\net40\Newtonsoft.Json.dll True @@ -116,6 +119,7 @@ Properties\GlobalAssemblyInfo.cs + @@ -215,12 +219,10 @@ Designer - - Designer - Always + Always diff --git a/src/StardewModdingAPI/packages.config b/src/StardewModdingAPI/packages.config index e5fa3c3a..1dee2c2a 100644 --- a/src/StardewModdingAPI/packages.config +++ b/src/StardewModdingAPI/packages.config @@ -1,5 +1,5 @@  - - + + \ No newline at end of file diff --git a/src/TrainerMod/TrainerMod.csproj b/src/TrainerMod/TrainerMod.csproj index a6303767..7845bd8c 100644 --- a/src/TrainerMod/TrainerMod.csproj +++ b/src/TrainerMod/TrainerMod.csproj @@ -9,7 +9,7 @@ Properties TrainerMod TrainerMod - v4.5 + v4.0 512 @@ -39,7 +39,7 @@ - ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll + ..\packages\Newtonsoft.Json.8.0.3\lib\net40\Newtonsoft.Json.dll True diff --git a/src/TrainerMod/packages.config b/src/TrainerMod/packages.config index 75e68e71..2c6c3f12 100644 --- a/src/TrainerMod/packages.config +++ b/src/TrainerMod/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file -- cgit