From 517a9d82fc1234b6c6ae6f1e45ef7c0f160ee6c5 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Mon, 21 Nov 2016 19:25:53 -0500 Subject: preprocess mods through Mono.Cecil to allow rewriting later (#166) --- src/StardewModdingAPI/Program.cs | 77 +++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 29 deletions(-) (limited to 'src/StardewModdingAPI/Program.cs') diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs index d31a1d39..12b6cad4 100644 --- a/src/StardewModdingAPI/Program.cs +++ b/src/StardewModdingAPI/Program.cs @@ -33,6 +33,9 @@ namespace StardewModdingAPI /// The full path to the folder containing mods. private static readonly string ModPath = Path.Combine(Constants.ExecutionPath, "Mods"); + /// The full path to the folder containing cached SMAPI data. + private static readonly string CachePath = Path.Combine(Program.ModPath, ".cache"); + /// The log file to which to write messages. private static readonly LogFileManager LogFile = new LogFileManager(Constants.LogPath); @@ -126,6 +129,7 @@ namespace StardewModdingAPI Program.Monitor.Log("Loading SMAPI..."); Console.Title = Constants.ConsoleTitle; Program.VerifyPath(Program.ModPath); + Program.VerifyPath(Program.CachePath); Program.VerifyPath(Constants.LogDir); if (!File.Exists(Program.GameExecutablePath)) { @@ -293,6 +297,8 @@ namespace StardewModdingAPI private static void LoadMods() { Program.Monitor.Log("Loading mods..."); + + ModAssemblyLoader modAssemblyLoader = new ModAssemblyLoader(Program.CachePath); foreach (string directory in Directory.GetDirectories(Program.ModPath)) { foreach (string manifestPath in Directory.GetFiles(directory, "manifest.json")) @@ -382,9 +388,11 @@ namespace StardewModdingAPI } } - // load DLL & hook up mod + // load assembly + Assembly modAssembly; try { + // get assembly path string assemblyPath = Path.Combine(directory, manifest.EntryDll); if (!File.Exists(assemblyPath)) { @@ -392,36 +400,47 @@ namespace StardewModdingAPI continue; } - Assembly modAssembly = Assembly.UnsafeLoadFrom(assemblyPath); - if (modAssembly.DefinedTypes.Count(x => x.BaseType == typeof(Mod)) > 0) + // read assembly + modAssembly = modAssemblyLoader.ProcessAssembly(assemblyPath); + if (modAssembly.DefinedTypes.Count(x => x.BaseType == typeof(Mod)) == 0) { - TypeInfo modEntryType = modAssembly.DefinedTypes.First(x => x.BaseType == typeof(Mod)); - Mod modEntry = (Mod)modAssembly.CreateInstance(modEntryType.ToString()); - if (modEntry != null) - { - // track mod - Program.ModRegistry.Add(manifest, modAssembly); - - // hook up mod - modEntry.Manifest = manifest; - modEntry.Helper = helper; - modEntry.Monitor = new Monitor(manifest.Name, Program.LogFile) { ShowTraceInConsole = Program.DeveloperMode }; - modEntry.PathOnDisk = directory; - Program.Monitor.Log($"Loaded mod: {modEntry.Manifest.Name} by {modEntry.Manifest.Author}, v{modEntry.Manifest.Version} | {modEntry.Manifest.Description}", LogLevel.Info); - Program.ModsLoaded += 1; - modEntry.Entry(); // deprecated since 1.0 - modEntry.Entry((ModHelper)modEntry.Helper); // deprecated since 1.1 - modEntry.Entry(modEntry.Helper); // deprecated since 1.1 - - // raise deprecation warning for old Entry() method - if (Program.DeprecationManager.IsVirtualMethodImplemented(modEntryType, typeof(Mod), nameof(Mod.Entry), new[] { typeof(object[]) })) - Program.DeprecationManager.Warn(manifest.Name, $"an old version of {nameof(Mod)}.{nameof(Mod.Entry)}", "1.0", DeprecationLevel.Notice); - if (Program.DeprecationManager.IsVirtualMethodImplemented(modEntryType, typeof(Mod), nameof(Mod.Entry), new[] { typeof(ModHelper) })) - Program.DeprecationManager.Warn(manifest.Name, $"an old version of {nameof(Mod)}.{nameof(Mod.Entry)}", "1.1", DeprecationLevel.Notice); - } - } - else Program.Monitor.Log($"{errorPrefix}: the mod DLL does not contain an implementation of the 'Mod' class.", LogLevel.Error); + continue; + } + } + catch (Exception ex) + { + Program.Monitor.Log($"{errorPrefix}: an error occurred while optimising the target DLL.\n{ex}", LogLevel.Error); + continue; + } + + // hook up mod + try + { + TypeInfo modEntryType = modAssembly.DefinedTypes.First(x => x.BaseType == typeof(Mod)); + Mod modEntry = (Mod)modAssembly.CreateInstance(modEntryType.ToString()); + if (modEntry != null) + { + // track mod + Program.ModRegistry.Add(manifest, modAssembly); + + // hook up mod + modEntry.Manifest = manifest; + modEntry.Helper = helper; + modEntry.Monitor = new Monitor(manifest.Name, Program.LogFile) { ShowTraceInConsole = Program.DeveloperMode }; + modEntry.PathOnDisk = directory; + Program.Monitor.Log($"Loaded mod: {modEntry.Manifest.Name} by {modEntry.Manifest.Author}, v{modEntry.Manifest.Version} | {modEntry.Manifest.Description}", LogLevel.Info); + Program.ModsLoaded += 1; + modEntry.Entry(); // deprecated since 1.0 + modEntry.Entry((ModHelper)modEntry.Helper); // deprecated since 1.1 + modEntry.Entry(modEntry.Helper); // deprecated since 1.1 + + // raise deprecation warning for old Entry() method + if (Program.DeprecationManager.IsVirtualMethodImplemented(modEntryType, typeof(Mod), nameof(Mod.Entry), new[] { typeof(object[]) })) + Program.DeprecationManager.Warn(manifest.Name, $"an old version of {nameof(Mod)}.{nameof(Mod.Entry)}", "1.0", DeprecationLevel.Notice); + if (Program.DeprecationManager.IsVirtualMethodImplemented(modEntryType, typeof(Mod), nameof(Mod.Entry), new[] { typeof(ModHelper) })) + Program.DeprecationManager.Warn(manifest.Name, $"an old version of {nameof(Mod)}.{nameof(Mod.Entry)}", "1.1", DeprecationLevel.Notice); + } } catch (Exception ex) { -- cgit From 08d5ee293ffc001dff3e866bd45954ef306e81ac Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 22 Nov 2016 00:03:14 -0500 Subject: simplify manifest.json path check --- src/StardewModdingAPI/Program.cs | 223 +++++++++++++++++++-------------------- 1 file changed, 111 insertions(+), 112 deletions(-) (limited to 'src/StardewModdingAPI/Program.cs') diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs index 12b6cad4..255ad365 100644 --- a/src/StardewModdingAPI/Program.cs +++ b/src/StardewModdingAPI/Program.cs @@ -301,152 +301,151 @@ namespace StardewModdingAPI ModAssemblyLoader modAssemblyLoader = new ModAssemblyLoader(Program.CachePath); foreach (string directory in Directory.GetDirectories(Program.ModPath)) { - foreach (string manifestPath in Directory.GetFiles(directory, "manifest.json")) + // check for cancellation + if (Program.CancellationTokenSource.IsCancellationRequested) { - // check for cancellation - if (Program.CancellationTokenSource.IsCancellationRequested) - { - Program.Monitor.Log("Shutdown requested; interrupting mod loading.", LogLevel.Error); - return; - } + Program.Monitor.Log("Shutdown requested; interrupting mod loading.", LogLevel.Error); + return; + } - IModHelper helper = new ModHelper(directory); - string errorPrefix = $"Couldn't load mod for manifest '{manifestPath}'"; + // get helper + IModHelper helper = new ModHelper(directory); - // read manifest - Manifest manifest; - try + // get manifest path + string manifestPath = Path.Combine(directory, "manifest.json"); + string errorPrefix = $"Couldn't load mod for manifest '{manifestPath}'"; + Manifest manifest; + try + { + // read manifest text + string json = File.ReadAllText(manifestPath); + if (string.IsNullOrEmpty(json)) { - // read manifest text - string json = File.ReadAllText(manifestPath); - if (string.IsNullOrEmpty(json)) - { - Program.Monitor.Log($"{errorPrefix}: manifest is empty.", LogLevel.Error); - continue; - } - - // deserialise manifest - manifest = helper.ReadJsonFile("manifest.json"); - if (manifest == null) - { - Program.Monitor.Log($"{errorPrefix}: the manifest file does not exist.", LogLevel.Error); - continue; - } - if (string.IsNullOrEmpty(manifest.EntryDll)) - { - Program.Monitor.Log($"{errorPrefix}: manifest doesn't specify an entry DLL.", LogLevel.Error); - continue; - } + Program.Monitor.Log($"{errorPrefix}: manifest is empty.", LogLevel.Error); + continue; + } - // log deprecated fields - if (manifest.UsedAuthourField) - Program.DeprecationManager.Warn(manifest.Name, $"{nameof(Manifest)}.{nameof(Manifest.Authour)}", "1.0", DeprecationLevel.Notice); + // deserialise manifest + manifest = helper.ReadJsonFile("manifest.json"); + if (manifest == null) + { + Program.Monitor.Log($"{errorPrefix}: the manifest file does not exist.", LogLevel.Error); + continue; } - catch (Exception ex) + if (string.IsNullOrEmpty(manifest.EntryDll)) { - Program.Monitor.Log($"{errorPrefix}: manifest parsing failed.\n{ex.GetLogSummary()}", LogLevel.Error); + Program.Monitor.Log($"{errorPrefix}: manifest doesn't specify an entry DLL.", LogLevel.Error); continue; } - // validate version - if (!string.IsNullOrWhiteSpace(manifest.MinimumApiVersion)) + // log deprecated fields + if (manifest.UsedAuthourField) + Program.DeprecationManager.Warn(manifest.Name, $"{nameof(Manifest)}.{nameof(Manifest.Authour)}", "1.0", DeprecationLevel.Notice); + } + catch (Exception ex) + { + Program.Monitor.Log($"{errorPrefix}: manifest parsing failed.\n{ex.GetLogSummary()}", LogLevel.Error); + continue; + } + + // validate version + if (!string.IsNullOrWhiteSpace(manifest.MinimumApiVersion)) + { + try { - try + Version minVersion = new Version(manifest.MinimumApiVersion); + if (minVersion.IsNewerThan(Constants.Version)) { - Version minVersion = new Version(manifest.MinimumApiVersion); - if (minVersion.IsNewerThan(Constants.Version)) - { - Program.Monitor.Log($"{errorPrefix}: this mod requires SMAPI {minVersion} or later. Please update SMAPI to the latest version to use this mod.", LogLevel.Error); - continue; - } - } - catch (FormatException ex) when (ex.Message.Contains("not a semantic version")) - { - Program.Monitor.Log($"{errorPrefix}: the mod specified an invalid minimum SMAPI version '{manifest.MinimumApiVersion}'. This should be a semantic version number like {Constants.Version}.", LogLevel.Error); + Program.Monitor.Log($"{errorPrefix}: this mod requires SMAPI {minVersion} or later. Please update SMAPI to the latest version to use this mod.", LogLevel.Error); continue; } } - - // create per-save directory - if (manifest.PerSaveConfigs) + catch (FormatException ex) when (ex.Message.Contains("not a semantic version")) { - Program.DeprecationManager.Warn(manifest.Name, $"{nameof(Manifest)}.{nameof(Manifest.PerSaveConfigs)}", "1.0", DeprecationLevel.Notice); - try - { - string psDir = Path.Combine(directory, "psconfigs"); - Directory.CreateDirectory(psDir); - if (!Directory.Exists(psDir)) - { - Program.Monitor.Log($"{errorPrefix}: couldn't create the per-save configuration directory ('psconfigs') requested by this mod. The failure reason is unknown.", LogLevel.Error); - continue; - } - } - catch (Exception ex) - { - Program.Monitor.Log($"{errorPrefix}: couldm't create the per-save configuration directory ('psconfigs') requested by this mod.\n{ex.GetLogSummary()}", LogLevel.Error); - continue; - } + Program.Monitor.Log($"{errorPrefix}: the mod specified an invalid minimum SMAPI version '{manifest.MinimumApiVersion}'. This should be a semantic version number like {Constants.Version}.", LogLevel.Error); + continue; } + } - // load assembly - Assembly modAssembly; + // create per-save directory + if (manifest.PerSaveConfigs) + { + Program.DeprecationManager.Warn(manifest.Name, $"{nameof(Manifest)}.{nameof(Manifest.PerSaveConfigs)}", "1.0", DeprecationLevel.Notice); try { - // get assembly path - string assemblyPath = Path.Combine(directory, manifest.EntryDll); - if (!File.Exists(assemblyPath)) + string psDir = Path.Combine(directory, "psconfigs"); + Directory.CreateDirectory(psDir); + if (!Directory.Exists(psDir)) { - Program.Monitor.Log($"{errorPrefix}: target DLL '{assemblyPath}' does not exist.", LogLevel.Error); - continue; - } - - // read assembly - modAssembly = modAssemblyLoader.ProcessAssembly(assemblyPath); - if (modAssembly.DefinedTypes.Count(x => x.BaseType == typeof(Mod)) == 0) - { - Program.Monitor.Log($"{errorPrefix}: the mod DLL does not contain an implementation of the 'Mod' class.", LogLevel.Error); + Program.Monitor.Log($"{errorPrefix}: couldn't create the per-save configuration directory ('psconfigs') requested by this mod. The failure reason is unknown.", LogLevel.Error); continue; } } catch (Exception ex) { - Program.Monitor.Log($"{errorPrefix}: an error occurred while optimising the target DLL.\n{ex}", LogLevel.Error); + Program.Monitor.Log($"{errorPrefix}: couldm't create the per-save configuration directory ('psconfigs') requested by this mod.\n{ex.GetLogSummary()}", LogLevel.Error); continue; } + } - // hook up mod - try + // load assembly + Assembly modAssembly; + try + { + // get assembly path + string assemblyPath = Path.Combine(directory, manifest.EntryDll); + if (!File.Exists(assemblyPath)) { - TypeInfo modEntryType = modAssembly.DefinedTypes.First(x => x.BaseType == typeof(Mod)); - Mod modEntry = (Mod)modAssembly.CreateInstance(modEntryType.ToString()); - if (modEntry != null) - { - // track mod - Program.ModRegistry.Add(manifest, modAssembly); - - // hook up mod - modEntry.Manifest = manifest; - modEntry.Helper = helper; - modEntry.Monitor = new Monitor(manifest.Name, Program.LogFile) { ShowTraceInConsole = Program.DeveloperMode }; - modEntry.PathOnDisk = directory; - Program.Monitor.Log($"Loaded mod: {modEntry.Manifest.Name} by {modEntry.Manifest.Author}, v{modEntry.Manifest.Version} | {modEntry.Manifest.Description}", LogLevel.Info); - Program.ModsLoaded += 1; - modEntry.Entry(); // deprecated since 1.0 - modEntry.Entry((ModHelper)modEntry.Helper); // deprecated since 1.1 - modEntry.Entry(modEntry.Helper); // deprecated since 1.1 - - // raise deprecation warning for old Entry() method - if (Program.DeprecationManager.IsVirtualMethodImplemented(modEntryType, typeof(Mod), nameof(Mod.Entry), new[] { typeof(object[]) })) - Program.DeprecationManager.Warn(manifest.Name, $"an old version of {nameof(Mod)}.{nameof(Mod.Entry)}", "1.0", DeprecationLevel.Notice); - if (Program.DeprecationManager.IsVirtualMethodImplemented(modEntryType, typeof(Mod), nameof(Mod.Entry), new[] { typeof(ModHelper) })) - Program.DeprecationManager.Warn(manifest.Name, $"an old version of {nameof(Mod)}.{nameof(Mod.Entry)}", "1.1", DeprecationLevel.Notice); - } + Program.Monitor.Log($"{errorPrefix}: target DLL '{assemblyPath}' does not exist.", LogLevel.Error); + continue; } - catch (Exception ex) + + // read assembly + modAssembly = modAssemblyLoader.ProcessAssembly(assemblyPath); + if (modAssembly.DefinedTypes.Count(x => x.BaseType == typeof(Mod)) == 0) + { + Program.Monitor.Log($"{errorPrefix}: the mod DLL does not contain an implementation of the 'Mod' class.", LogLevel.Error); + continue; + } + } + catch (Exception ex) + { + Program.Monitor.Log($"{errorPrefix}: an error occurred while optimising the target DLL.\n{ex}", LogLevel.Error); + continue; + } + + // hook up mod + try + { + TypeInfo modEntryType = modAssembly.DefinedTypes.First(x => x.BaseType == typeof(Mod)); + Mod modEntry = (Mod)modAssembly.CreateInstance(modEntryType.ToString()); + if (modEntry != null) { - Program.Monitor.Log($"{errorPrefix}: an error occurred while loading the target DLL.\n{ex.GetLogSummary()}", LogLevel.Error); + // track mod + Program.ModRegistry.Add(manifest, modAssembly); + + // hook up mod + modEntry.Manifest = manifest; + modEntry.Helper = helper; + modEntry.Monitor = new Monitor(manifest.Name, Program.LogFile) { ShowTraceInConsole = Program.DeveloperMode }; + modEntry.PathOnDisk = directory; + Program.Monitor.Log($"Loaded mod: {modEntry.Manifest.Name} by {modEntry.Manifest.Author}, v{modEntry.Manifest.Version} | {modEntry.Manifest.Description}", LogLevel.Info); + Program.ModsLoaded += 1; + modEntry.Entry(); // deprecated since 1.0 + modEntry.Entry((ModHelper)modEntry.Helper); // deprecated since 1.1 + modEntry.Entry(modEntry.Helper); // deprecated since 1.1 + + // raise deprecation warning for old Entry() method + if (Program.DeprecationManager.IsVirtualMethodImplemented(modEntryType, typeof(Mod), nameof(Mod.Entry), new[] { typeof(object[]) })) + Program.DeprecationManager.Warn(manifest.Name, $"an old version of {nameof(Mod)}.{nameof(Mod.Entry)}", "1.0", DeprecationLevel.Notice); + if (Program.DeprecationManager.IsVirtualMethodImplemented(modEntryType, typeof(Mod), nameof(Mod.Entry), new[] { typeof(ModHelper) })) + Program.DeprecationManager.Warn(manifest.Name, $"an old version of {nameof(Mod)}.{nameof(Mod.Entry)}", "1.1", DeprecationLevel.Notice); } } + catch (Exception ex) + { + Program.Monitor.Log($"{errorPrefix}: an error occurred while loading the target DLL.\n{ex.GetLogSummary()}", LogLevel.Error); + } } // print result -- cgit From e9fee3f6fe18927192b1dd676cd420507af2e389 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 22 Nov 2016 00:36:48 -0500 Subject: preprocess all mod assemblies for compatibility with multi-assembly mods (#166) --- src/StardewModdingAPI/Program.cs | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'src/StardewModdingAPI/Program.cs') diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs index 255ad365..f8920896 100644 --- a/src/StardewModdingAPI/Program.cs +++ b/src/StardewModdingAPI/Program.cs @@ -301,6 +301,10 @@ namespace StardewModdingAPI ModAssemblyLoader modAssemblyLoader = new ModAssemblyLoader(Program.CachePath); foreach (string directory in Directory.GetDirectories(Program.ModPath)) { + // ignore internal directory + if (new DirectoryInfo(directory).Name == ".cache") + continue; + // check for cancellation if (Program.CancellationTokenSource.IsCancellationRequested) { @@ -388,20 +392,32 @@ namespace StardewModdingAPI } } + // preprocess mod assemblies + { + bool succeeded = true; + foreach (string assemblyPath in Directory.GetFiles(directory, "*.dll")) + { + try + { + modAssemblyLoader.ProcessAssembly(assemblyPath); + } + catch (Exception ex) + { + Program.Monitor.Log($"{errorPrefix}: an error occurred while preprocessing '{assemblyPath}'.\n{ex}", LogLevel.Error); + succeeded = false; + break; + } + } + if (!succeeded) + continue; + } + // load assembly Assembly modAssembly; try { - // get assembly path string assemblyPath = Path.Combine(directory, manifest.EntryDll); - if (!File.Exists(assemblyPath)) - { - Program.Monitor.Log($"{errorPrefix}: target DLL '{assemblyPath}' does not exist.", LogLevel.Error); - continue; - } - - // read assembly - modAssembly = modAssemblyLoader.ProcessAssembly(assemblyPath); + modAssembly = modAssemblyLoader.LoadCachedAssembly(assemblyPath); if (modAssembly.DefinedTypes.Count(x => x.BaseType == typeof(Mod)) == 0) { Program.Monitor.Log($"{errorPrefix}: the mod DLL does not contain an implementation of the 'Mod' class.", LogLevel.Error); -- cgit From 7bea3c2ba00789a38ae71035548c2c6b5c298d5b Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 26 Nov 2016 16:00:02 -0500 Subject: add log entry when preprocessing an assembly (#166) --- src/StardewModdingAPI/Program.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/StardewModdingAPI/Program.cs') diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs index f8920896..e364ef03 100644 --- a/src/StardewModdingAPI/Program.cs +++ b/src/StardewModdingAPI/Program.cs @@ -298,7 +298,7 @@ namespace StardewModdingAPI { Program.Monitor.Log("Loading mods..."); - ModAssemblyLoader modAssemblyLoader = new ModAssemblyLoader(Program.CachePath); + ModAssemblyLoader modAssemblyLoader = new ModAssemblyLoader(Program.CachePath, Program.Monitor); foreach (string directory in Directory.GetDirectories(Program.ModPath)) { // ignore internal directory @@ -403,7 +403,7 @@ namespace StardewModdingAPI } catch (Exception ex) { - Program.Monitor.Log($"{errorPrefix}: an error occurred while preprocessing '{assemblyPath}'.\n{ex}", LogLevel.Error); + Program.Monitor.Log($"{errorPrefix}: an error occurred while preprocessing '{Path.GetFileName(assemblyPath)}'.\n{ex.GetLogSummary()}", LogLevel.Error); succeeded = false; break; } @@ -426,7 +426,7 @@ namespace StardewModdingAPI } catch (Exception ex) { - Program.Monitor.Log($"{errorPrefix}: an error occurred while optimising the target DLL.\n{ex}", LogLevel.Error); + Program.Monitor.Log($"{errorPrefix}: an error occurred while optimising the target DLL.\n{ex.GetLogSummary()}", LogLevel.Error); continue; } -- cgit From 1de8dc1b0f58991f9d15fa343e849bd6a2023ecc Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 26 Nov 2016 16:07:21 -0500 Subject: pass target platform to assembly rewriter for later use (#166) --- src/StardewModdingAPI/Program.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/StardewModdingAPI/Program.cs') diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs index e364ef03..eba89981 100644 --- a/src/StardewModdingAPI/Program.cs +++ b/src/StardewModdingAPI/Program.cs @@ -23,13 +23,17 @@ namespace StardewModdingAPI /********* ** Properties *********/ - /// The full path to the Stardew Valley executable. + /// The target game platform. + private static readonly Platform TargetPlatform = #if SMAPI_FOR_WINDOWS - private static readonly string GameExecutablePath = Path.Combine(Constants.ExecutionPath, "Stardew Valley.exe"); + Platform.Windows; #else - private static readonly string GameExecutablePath = Path.Combine(Constants.ExecutionPath, "StardewValley.exe"); + Platform.Mono; #endif + /// The full path to the Stardew Valley executable. + private static readonly string GameExecutablePath = Path.Combine(Constants.ExecutionPath, Program.TargetPlatform == Platform.Windows ? "Stardew Valley.exe" : "StardewValley.exe"); + /// The full path to the folder containing mods. private static readonly string ModPath = Path.Combine(Constants.ExecutionPath, "Mods"); @@ -298,7 +302,7 @@ namespace StardewModdingAPI { Program.Monitor.Log("Loading mods..."); - ModAssemblyLoader modAssemblyLoader = new ModAssemblyLoader(Program.CachePath, Program.Monitor); + ModAssemblyLoader modAssemblyLoader = new ModAssemblyLoader(Program.CachePath, Program.TargetPlatform, Program.Monitor); foreach (string directory in Directory.GetDirectories(Program.ModPath)) { // ignore internal directory -- cgit From f7b8879011873fa8f7a3d5dd7db27254bfc90469 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 27 Nov 2016 15:56:47 -0500 Subject: supplement assembly resolution for Mono (#166) --- src/StardewModdingAPI/Program.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/StardewModdingAPI/Program.cs') diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs index eba89981..bed4cafc 100644 --- a/src/StardewModdingAPI/Program.cs +++ b/src/StardewModdingAPI/Program.cs @@ -303,6 +303,8 @@ namespace StardewModdingAPI Program.Monitor.Log("Loading mods..."); ModAssemblyLoader modAssemblyLoader = new ModAssemblyLoader(Program.CachePath, Program.TargetPlatform, Program.Monitor); + AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => modAssemblyLoader.ResolveAssembly(e.Name); // supplement Mono's assembly resolution which doesn't handle assembly rewrites very well + foreach (string directory in Directory.GetDirectories(Program.ModPath)) { // ignore internal directory @@ -391,7 +393,7 @@ namespace StardewModdingAPI } catch (Exception ex) { - Program.Monitor.Log($"{errorPrefix}: couldm't create the per-save configuration directory ('psconfigs') requested by this mod.\n{ex.GetLogSummary()}", LogLevel.Error); + Program.Monitor.Log($"{errorPrefix}: couldn't create the per-save configuration directory ('psconfigs') requested by this mod.\n{ex.GetLogSummary()}", LogLevel.Error); continue; } } -- cgit From 5470e95bf59e5e3bae249ead6909163390fb2af3 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 29 Nov 2016 14:02:59 -0500 Subject: add separate project to support upcoming IL rewriting (#166) --- src/StardewModdingAPI/Program.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/StardewModdingAPI/Program.cs') diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs index bed4cafc..f0686039 100644 --- a/src/StardewModdingAPI/Program.cs +++ b/src/StardewModdingAPI/Program.cs @@ -9,6 +9,7 @@ using System.Windows.Forms; #endif using Microsoft.Xna.Framework.Graphics; using Newtonsoft.Json; +using StardewModdingAPI.AssemblyRewriters; using StardewModdingAPI.Events; using StardewModdingAPI.Framework; using StardewModdingAPI.Inheritance; -- cgit