From 294f2a311ea2cfb590529522c0afae8e5a4f44fd Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 19 Aug 2021 00:40:12 -0400 Subject: fix error resolving native DLLs like libSkiaSharp --- src/SMAPI.Installer/InteractiveInstaller.cs | 8 ++++++++ src/SMAPI.Toolkit/Utilities/FileUtilities.cs | 13 +++++++++++++ src/SMAPI/Program.cs | 16 ++++++++++++++++ 3 files changed, 37 insertions(+) (limited to 'src') diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs index 714a959b..d8c27a2d 100644 --- a/src/SMAPI.Installer/InteractiveInstaller.cs +++ b/src/SMAPI.Installer/InteractiveInstaller.cs @@ -410,6 +410,14 @@ namespace StardewModdingApi.Installer } } + // copy the game's deps.json file + // (This is needed to resolve native DLLs like libSkiaSharp.) + File.Copy( + sourceFileName: Path.Combine(paths.GamePath, "Stardew Valley.deps.json"), + destFileName: Path.Combine(paths.GamePath, "StardewModdingAPI.deps.json"), + overwrite: true + ); + // create mods directory (if needed) if (!paths.ModsDir.Exists) { diff --git a/src/SMAPI.Toolkit/Utilities/FileUtilities.cs b/src/SMAPI.Toolkit/Utilities/FileUtilities.cs index 7856fdb1..a6bf5929 100644 --- a/src/SMAPI.Toolkit/Utilities/FileUtilities.cs +++ b/src/SMAPI.Toolkit/Utilities/FileUtilities.cs @@ -1,4 +1,6 @@ +using System; using System.IO; +using System.Security.Cryptography; using System.Threading; namespace StardewModdingAPI.Toolkit.Utilities @@ -42,5 +44,16 @@ namespace StardewModdingAPI.Toolkit.Utilities if (entry.Exists) throw new IOException($"Timed out trying to delete {entry.FullName}"); } + + /// Get the MD5 hash for a file. + /// The absolute file path. + public static string GetFileHash(string absolutePath) + { + using FileStream stream = File.OpenRead(absolutePath); + using MD5 md5 = MD5.Create(); + + byte[] hash = md5.ComputeHash(stream); + return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); + } } } diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index 0417697b..67ff8322 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -5,6 +5,7 @@ using System.Reflection; using System.Threading; using StardewModdingAPI.Framework; using StardewModdingAPI.Toolkit.Serialization.Models; +using StardewModdingAPI.Toolkit.Utilities; namespace StardewModdingAPI { @@ -33,6 +34,7 @@ namespace StardewModdingAPI Program.AssertGamePresent(); Program.AssertGameVersion(); Program.AssertSmapiVersions(); + Program.AssertDepsJson(); Program.Start(args); } catch (BadImageFormatException ex) when (ex.FileName == EarlyConstants.GameAssemblyName) @@ -130,6 +132,20 @@ namespace StardewModdingAPI } } + /// Assert that SMAPI's StardewModdingAPI.deps.json matches Stardew Valley.deps.json, fixing it if necessary. + /// This is needed to resolve native DLLs like libSkiaSharp. + private static void AssertDepsJson() + { + string sourcePath = Path.Combine(Constants.ExecutionPath, "Stardew Valley.deps.json"); + string targetPath = Path.Combine(Constants.ExecutionPath, "StardewModdingAPI.deps.json"); + + if (!File.Exists(targetPath) || FileUtilities.GetFileHash(sourcePath) != FileUtilities.GetFileHash(targetPath)) + { + File.Copy(sourcePath, targetPath, overwrite: true); + Program.PrintErrorAndExit($"The '{Path.GetFileName(targetPath)}' file didn't match the game's version. SMAPI fixed it automatically, but you must restart SMAPI for the change to take effect."); + } + } + /// Initialize SMAPI and launch the game. /// The command-line arguments. /// This method is separate from because that can't contain any references to assemblies loaded by (e.g. via ), or Mono will incorrectly show an assembly resolution error before assembly resolution is set up. -- cgit