From c8c6b3897cd080ef3261f5642d31d8a51971981b Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 2 Sep 2021 19:31:22 -0400 Subject: update versions for Stardew Valley 1.5.5 and remove 1.5.4-specific checks --- src/SMAPI.Installer/InteractiveInstaller.cs | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'src/SMAPI.Installer') diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs index 9f49137f..79c3b891 100644 --- a/src/SMAPI.Installer/InteractiveInstaller.cs +++ b/src/SMAPI.Installer/InteractiveInstaller.cs @@ -277,18 +277,6 @@ namespace StardewModdingApi.Installer /********* ** Step 4: validate assumptions *********/ - // not 64-bit on Windows - if (context.Platform == Platform.Windows) - { - FileInfo linuxExecutable = new FileInfo(Path.Combine(paths.GamePath, "StardewValley.exe")); - if (linuxExecutable.Exists && this.Is64Bit(linuxExecutable.FullName)) - { - this.PrintError("Oops! The detected game install path seems to be unofficial 64-bit mode, which is no longer supported. You can update to Stardew Valley 1.5.5 or later instead. See https://stardewvalleywiki.com/Modding:Migrate_to_64-bit_on_Windows for more info."); - Console.ReadLine(); - return; - } - } - // executable exists if (!File.Exists(paths.ExecutablePath)) { @@ -297,14 +285,6 @@ namespace StardewModdingApi.Installer return; } - // not Stardew Valley 1.5.5+ - if (File.Exists(Path.Combine(paths.GamePath, "Stardew Valley.dll"))) - { - this.PrintError("Oops! The detected game install path seems to be Stardew Valley 1.5.5 or later, but this version of SMAPI is only compatible up to Stardew Valley 1.5.4. Please check for a newer version of SMAPI: https://smapi.io."); - Console.ReadLine(); - return; - } - // game folder doesn't contain paths beyond the max limit { string[] tooLongPaths = PathUtilities.GetTooLongPaths(Path.Combine(paths.GamePath, "Mods")).ToArray(); -- cgit From 727d75ae728ba6cc8fc070524264c454aac8404f Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 12 Aug 2021 21:26:10 -0400 Subject: update to .NET 5 and official 64-bit --- build/common.targets | 25 ++++-- build/prepare-install-package.targets | 66 +++++--------- docs/release-notes.md | 14 +++ docs/technical/mod-package.md | 1 + docs/technical/web.md | 2 +- src/SMAPI.Installer/Framework/InstallerContext.cs | 45 ---------- src/SMAPI.Installer/Framework/InstallerPaths.cs | 44 +++++----- src/SMAPI.Installer/InteractiveInstaller.cs | 81 ++++++----------- src/SMAPI.Installer/SMAPI.Installer.csproj | 2 +- src/SMAPI.Installer/assets/System.Numerics.dll | Bin 54272 -> 0 bytes .../assets/System.Runtime.Caching.dll | Bin 71168 -> 0 bytes src/SMAPI.Installer/assets/unix-install.sh | 18 +--- src/SMAPI.Installer/assets/unix-launcher.sh | 96 +++++---------------- .../SMAPI.ModBuildConfig.Analyzer.Tests.csproj | 13 +-- .../SMAPI.ModBuildConfig.Analyzer.csproj | 3 +- .../SMAPI.ModBuildConfig.csproj | 16 ++-- src/SMAPI.ModBuildConfig/build/smapi.targets | 8 +- .../SMAPI.Mods.ConsoleCommands.csproj | 4 +- .../SMAPI.Mods.ErrorHandler.csproj | 4 +- .../SMAPI.Mods.SaveBackup.csproj | 4 +- src/SMAPI.Tests/SMAPI.Tests.csproj | 5 +- .../SMAPI.Toolkit.CoreInterfaces.csproj | 2 +- src/SMAPI.Toolkit/Framework/Constants.cs | 9 ++ .../Framework/GameScanning/GameScanner.cs | 5 +- .../Framework/LowLevelEnvironmentUtility.cs | 9 -- src/SMAPI.Toolkit/SMAPI.Toolkit.csproj | 6 +- src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs | 7 -- src/SMAPI.Toolkit/Utilities/PathUtilities.cs | 15 ++-- src/SMAPI/Framework/Logging/LogManager.cs | 2 +- .../Framework/Reflection/InterfaceProxyFactory.cs | 2 +- src/SMAPI/Framework/SCore.cs | 9 +- src/SMAPI/Metadata/InstructionMetadata.cs | 2 +- src/SMAPI/SMAPI.csproj | 14 +-- 33 files changed, 192 insertions(+), 341 deletions(-) delete mode 100644 src/SMAPI.Installer/assets/System.Numerics.dll delete mode 100644 src/SMAPI.Installer/assets/System.Runtime.Caching.dll create mode 100644 src/SMAPI.Toolkit/Framework/Constants.cs (limited to 'src/SMAPI.Installer') diff --git a/build/common.targets b/build/common.targets index 02142351..a74002a6 100644 --- a/build/common.targets +++ b/build/common.targets @@ -7,7 +7,7 @@ $(AssemblySearchPaths);{GAC} - $(DefineConstants);SMAPI_FOR_WINDOWS;SMAPI_FOR_XNA + $(DefineConstants);SMAPI_FOR_WINDOWS @@ -27,20 +27,31 @@ - + + + + + + + + + - - - + + + + + + @@ -54,13 +65,13 @@ - + - + diff --git a/build/prepare-install-package.targets b/build/prepare-install-package.targets index 601f6496..bc1716a3 100644 --- a/build/prepare-install-package.targets +++ b/build/prepare-install-package.targets @@ -14,7 +14,7 @@ $(SolutionDir)\..\bin $(BuildRootPath)\SMAPI\bin\$(Configuration) - $(BuildRootPath)\SMAPI.Toolkit\bin\$(Configuration)\net452 + $(BuildRootPath)\SMAPI.Toolkit\bin\$(Configuration)\net5.0 $(BuildRootPath)\SMAPI.Mods.ConsoleCommands\bin\$(Configuration) $(BuildRootPath)\SMAPI.Mods.ErrorHandler\bin\$(Configuration) $(BuildRootPath)\SMAPI.Mods.SaveBackup\bin\$(Configuration) @@ -35,12 +35,17 @@ - - - + + + + + + - + + + @@ -61,11 +66,16 @@ - - + + + + + + + @@ -78,63 +88,33 @@ - - - - - - + + + - + - + - - - - - - - - - - - - - - - - + - diff --git a/docs/release-notes.md b/docs/release-notes.md index efda7267..43370409 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -3,8 +3,22 @@ # Release notes ## Upcoming release * For players: + * Updated for Stardew Valley 1.5.5. * Added `set_farm_type` [console command](https://stardewvalleywiki.com/Modding:Console_commands#Console_commands) to change the current farm type. +* For mod authors: + * Migrated to 64-bit MonoGame and .NET 5 on all platforms (see [migration guide for mod authors](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5)). + +**Update note for players with older systems:** +The game now has two branches: the _main branch_ which you'll get by default, and an optional +_compatibility branch_ for [older systems](https://www.stardewvalley.net/compatibility/). The two +branches have identical content, but use [different technologies](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5#Stardew_Valley_compatibility_branch). + +Unfortunately **SMAPI only supports the main branch of the game**. There are formidable difficulties +across all mods in supporting all three variations, the [Steam hardware stats](https://store.steampowered.com/hwsurvey) +show that 99.69% of players have 64-bit, and 32-bit imposes significant restrictions on what mods +can do. + * For the web UI: * Updated the JSON validator/schema for Content Patcher 1.24.0. diff --git a/docs/technical/mod-package.md b/docs/technical/mod-package.md index 7eefc7a4..a3ce8761 100644 --- a/docs/technical/mod-package.md +++ b/docs/technical/mod-package.md @@ -366,6 +366,7 @@ when you compile it. ## Release notes ## Upcoming release +* Updated for Stardew Valley 1.5.5 and SMAPI 3.13.0. **The older versions are no longer supported.** * Improved analyzer performance by enabling parallel execution. ## 3.3.0 diff --git a/docs/technical/web.md b/docs/technical/web.md index 50237bfe..f0d43fb1 100644 --- a/docs/technical/web.md +++ b/docs/technical/web.md @@ -367,7 +367,7 @@ accordingly. Initial setup: 1. Create an Azure Blob storage account for uploaded files. -2. Create an Azure App Services environment running the latest .NET Core on Linux or Windows. +2. Create an Azure App Services environment running the latest .NET on Linux or Windows. 3. Add these application settings in the new App Services environment: property name | description diff --git a/src/SMAPI.Installer/Framework/InstallerContext.cs b/src/SMAPI.Installer/Framework/InstallerContext.cs index 88e57760..95df32ca 100644 --- a/src/SMAPI.Installer/Framework/InstallerContext.cs +++ b/src/SMAPI.Installer/Framework/InstallerContext.cs @@ -1,6 +1,4 @@ -using System; using System.IO; -using Microsoft.Win32; using StardewModdingAPI.Toolkit; using StardewModdingAPI.Toolkit.Framework.GameScanning; using StardewModdingAPI.Toolkit.Utilities; @@ -13,9 +11,6 @@ namespace StardewModdingAPI.Installer.Framework /********* ** Fields *********/ - /// The value that represents Windows 7. - private readonly Version Windows7Version = new Version(6, 1); - /// The underlying toolkit game scanner. private readonly GameScanner GameScanner = new GameScanner(); @@ -29,9 +24,6 @@ namespace StardewModdingAPI.Installer.Framework /// The human-readable OS name and version. public string PlatformName { get; } - /// The name of the Stardew Valley executable. - public string ExecutableName { get; } - /// Whether the installer is running on Windows. public bool IsWindows => this.Platform == Platform.Windows; @@ -47,7 +39,6 @@ namespace StardewModdingAPI.Installer.Framework { this.Platform = EnvironmentUtility.DetectPlatform(); this.PlatformName = EnvironmentUtility.GetFriendlyPlatformName(this.Platform); - this.ExecutableName = EnvironmentUtility.GetExecutableName(this.Platform); } /// Get the installer's version number. @@ -57,42 +48,6 @@ namespace StardewModdingAPI.Installer.Framework return new SemanticVersion(raw); } - /// Get whether the current system has .NET Framework 4.5 or later installed. This only applies on Windows. - /// The current platform is not Windows. - public bool HasNetFramework45() - { - switch (this.Platform) - { - case Platform.Windows: - using (RegistryKey versionKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full")) - return versionKey?.GetValue("Release") != null; // .NET Framework 4.5+ - - default: - throw new NotSupportedException("The installed .NET Framework version can only be checked on Windows."); - } - } - - /// Get whether the current system has XNA Framework installed. This only applies on Windows. - /// The current platform is not Windows. - public bool HasXna() - { - switch (this.Platform) - { - case Platform.Windows: - using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\XNA\Framework")) - return key != null; // XNA Framework 4.0+ - - default: - throw new NotSupportedException("The installed XNA Framework version can only be checked on Windows."); - } - } - - /// Whether the current OS supports newer versions of .NET Framework. - public bool CanInstallLatestNetFramework() - { - return Environment.OSVersion.Version >= this.Windows7Version; // Windows 7+ - } - /// Get whether a folder seems to contain the game files. /// The folder to check. public bool LooksLikeGameFolder(DirectoryInfo dir) diff --git a/src/SMAPI.Installer/Framework/InstallerPaths.cs b/src/SMAPI.Installer/Framework/InstallerPaths.cs index 6ba5fa5f..0976eceb 100644 --- a/src/SMAPI.Installer/Framework/InstallerPaths.cs +++ b/src/SMAPI.Installer/Framework/InstallerPaths.cs @@ -1,4 +1,5 @@ using System.IO; +using StardewModdingAPI.Toolkit.Framework; namespace StardewModdingAPI.Installer.Framework { @@ -44,17 +45,20 @@ namespace StardewModdingAPI.Installer.Framework /// The full path to the user's config overrides file. public string ApiUserConfigPath { get; } - /// The full path to the installed game executable file. - public string ExecutablePath { get; private set; } + /// The full path to the installed game DLL. + public string GameDllPath { get; } - /// The full path to the vanilla game launcher on Linux/macOS. - public string UnixLauncherPath { get; } + /// The full path to the installed SMAPI executable file. + public string UnixSmapiExecutablePath { get; } - /// The full path to the installed SMAPI launcher on Linux/macOS before it's renamed. - public string UnixSmapiLauncherPath { get; } + /// The full path to the vanilla game launch script on Linux/macOS. + public string VanillaLaunchScriptPath { get; } - /// The full path to the vanilla game launcher on Linux/macOS after SMAPI is installed. - public string UnixBackupLauncherPath { get; } + /// The full path to the installed SMAPI launch script on Linux/macOS before it's renamed. + public string NewLaunchScriptPath { get; } + + /// The full path to the backed up game launch script on Linux/macOS after SMAPI is installed. + public string BackupLaunchScriptPath { get; } /********* @@ -63,28 +67,24 @@ namespace StardewModdingAPI.Installer.Framework /// Construct an instance. /// The directory path containing the files to copy into the game folder. /// The directory path for the installed game. - /// The name of the game's executable file for the current platform. - public InstallerPaths(DirectoryInfo bundleDir, DirectoryInfo gameDir, string gameExecutableName) + public InstallerPaths(DirectoryInfo bundleDir, DirectoryInfo gameDir) { + // base paths this.BundleDir = bundleDir; this.GameDir = gameDir; this.ModsDir = new DirectoryInfo(Path.Combine(gameDir.FullName, "Mods")); + this.GameDllPath = Path.Combine(gameDir.FullName, Constants.GameDllName); - this.BundleApiUserConfigPath = Path.Combine(bundleDir.FullName, "smapi-internal", "config.user.json"); + // launch scripts + this.VanillaLaunchScriptPath = Path.Combine(gameDir.FullName, "StardewValley"); + this.NewLaunchScriptPath = Path.Combine(gameDir.FullName, "unix-launcher.sh"); + this.BackupLaunchScriptPath = Path.Combine(gameDir.FullName, "StardewValley-original"); + this.UnixSmapiExecutablePath = Path.Combine(gameDir.FullName, "StardewModdingAPI"); - this.ExecutablePath = Path.Combine(gameDir.FullName, gameExecutableName); - this.UnixLauncherPath = Path.Combine(gameDir.FullName, "StardewValley"); - this.UnixSmapiLauncherPath = Path.Combine(gameDir.FullName, "StardewModdingAPI"); - this.UnixBackupLauncherPath = Path.Combine(gameDir.FullName, "StardewValley-original"); + // internal files + this.BundleApiUserConfigPath = Path.Combine(bundleDir.FullName, "smapi-internal", "config.user.json"); this.ApiConfigPath = Path.Combine(gameDir.FullName, "smapi-internal", "config.json"); this.ApiUserConfigPath = Path.Combine(gameDir.FullName, "smapi-internal", "config.user.json"); } - - /// Override the filename for the . - /// the file name. - public void SetExecutableFileName(string filename) - { - this.ExecutablePath = Path.Combine(this.GamePath, filename); - } } } diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs index 79c3b891..34285cf7 100644 --- a/src/SMAPI.Installer/InteractiveInstaller.cs +++ b/src/SMAPI.Installer/InteractiveInstaller.cs @@ -41,12 +41,13 @@ namespace StardewModdingApi.Installer // current files yield return GetInstallPath("libgdiplus.dylib"); // Linux/macOS only yield return GetInstallPath("StardewModdingAPI"); // Linux/macOS only + yield return GetInstallPath("StardewModdingAPI.dll"); yield return GetInstallPath("StardewModdingAPI.exe"); yield return GetInstallPath("StardewModdingAPI.exe.config"); yield return GetInstallPath("StardewModdingAPI.exe.mdb"); // Linux/macOS only yield return GetInstallPath("StardewModdingAPI.pdb"); // Windows only + yield return GetInstallPath("StardewModdingAPI.runtimeconfig.json"); yield return GetInstallPath("StardewModdingAPI.xml"); - yield return GetInstallPath("StardewModdingAPI-x64.exe"); // not normally added to game folder, but may be mistakenly added by a manual install yield return GetInstallPath("smapi-internal"); yield return GetInstallPath("steam_appid.txt"); @@ -70,9 +71,7 @@ namespace StardewModdingApi.Installer yield return GetInstallPath("StardewModdingAPI.Toolkit.CoreInterfaces.dll"); // moved in 2.8 yield return GetInstallPath("StardewModdingAPI.Toolkit.CoreInterfaces.pdb"); // moved in 2.8 yield return GetInstallPath("StardewModdingAPI.Toolkit.CoreInterfaces.xml"); // moved in 2.8 - yield return GetInstallPath("System.Numerics.dll"); // moved in 2.8 - yield return GetInstallPath("System.Runtime.Caching.dll"); // moved in 2.8 - yield return GetInstallPath("System.ValueTuple.dll"); // moved in 2.8 + yield return GetInstallPath("StardewModdingAPI-x64.exe"); // 3.13 if (modsDir.Exists) { @@ -149,30 +148,6 @@ namespace StardewModdingApi.Installer } #endif - /**** - ** Check Windows dependencies - ****/ - if (context.IsWindows) - { - // .NET Framework 4.5+ - if (!context.HasNetFramework45()) - { - this.PrintError(context.CanInstallLatestNetFramework() - ? "Please install the latest version of .NET Framework before installing SMAPI." - : "Please install .NET Framework 4.5 before installing SMAPI." - ); - this.PrintError("See the download page at https://www.microsoft.com/net/download/framework for details."); - Console.ReadLine(); - return; - } - if (!context.HasXna()) - { - this.PrintError("You don't seem to have XNA Framework installed. Please run the game at least once before installing SMAPI, so it can perform its first-time setup."); - Console.ReadLine(); - return; - } - } - /**** ** read command-line arguments ****/ @@ -270,7 +245,7 @@ namespace StardewModdingApi.Installer // get folders DirectoryInfo bundleDir = new DirectoryInfo(this.BundlePath); - paths = new InstallerPaths(bundleDir, installDir, context.ExecutableName); + paths = new InstallerPaths(bundleDir, installDir); } @@ -278,7 +253,7 @@ namespace StardewModdingApi.Installer ** Step 4: validate assumptions *********/ // executable exists - if (!File.Exists(paths.ExecutablePath)) + if (!File.Exists(paths.GameDllPath)) { this.PrintError("The detected game install path doesn't contain a Stardew Valley executable."); Console.ReadLine(); @@ -367,11 +342,11 @@ namespace StardewModdingApi.Installer ** Always uninstall old files ****/ // restore game launcher - if (context.IsUnix && File.Exists(paths.UnixBackupLauncherPath)) + if (context.IsUnix && File.Exists(paths.BackupLaunchScriptPath)) { this.PrintDebug("Removing SMAPI launcher..."); - this.InteractivelyDelete(paths.UnixLauncherPath); - File.Move(paths.UnixBackupLauncherPath, paths.UnixLauncherPath); + this.InteractivelyDelete(paths.VanillaLaunchScriptPath); + File.Move(paths.BackupLaunchScriptPath, paths.VanillaLaunchScriptPath); } // remove old files @@ -419,28 +394,31 @@ namespace StardewModdingApi.Installer this.PrintDebug("Safely replacing game launcher..."); // back up & remove current launcher - if (File.Exists(paths.UnixLauncherPath)) + if (File.Exists(paths.VanillaLaunchScriptPath)) { - if (!File.Exists(paths.UnixBackupLauncherPath)) - File.Move(paths.UnixLauncherPath, paths.UnixBackupLauncherPath); + if (!File.Exists(paths.BackupLaunchScriptPath)) + File.Move(paths.VanillaLaunchScriptPath, paths.BackupLaunchScriptPath); else - this.InteractivelyDelete(paths.UnixLauncherPath); + this.InteractivelyDelete(paths.VanillaLaunchScriptPath); } // add new launcher - File.Move(paths.UnixSmapiLauncherPath, paths.UnixLauncherPath); + File.Move(paths.NewLaunchScriptPath, paths.VanillaLaunchScriptPath); - // mark file executable + // mark files executable // (MSBuild doesn't keep permission flags for files zipped in a build task.) - new Process + foreach (string path in new[] { paths.VanillaLaunchScriptPath, paths.UnixSmapiExecutablePath }) { - StartInfo = new ProcessStartInfo + new Process { - FileName = "chmod", - Arguments = $"755 \"{paths.UnixLauncherPath}\"", - CreateNoWindow = true - } - }.Start(); + StartInfo = new ProcessStartInfo + { + FileName = "chmod", + Arguments = $"755 \"{path}\"", + CreateNoWindow = true + } + }.Start(); + } } // create mods directory (if needed) @@ -507,7 +485,7 @@ namespace StardewModdingApi.Installer /********* - ** Step 6: final instructions + ** Step 7: final instructions *********/ if (context.IsWindows) { @@ -536,13 +514,6 @@ namespace StardewModdingApi.Installer /********* ** Private methods *********/ - /// Get whether an executable is 64-bit. - /// The absolute path to the executable file. - private bool Is64Bit(string executablePath) - { - return LowLevelEnvironmentUtility.Is64BitAssembly(executablePath); - } - /// Get the display text for a color scheme. /// The color scheme. private string GetDisplayText(MonitorColorScheme scheme) @@ -705,7 +676,7 @@ namespace StardewModdingApi.Installer { // get path from user Console.WriteLine(); - this.PrintInfo($"Type the file path to the game directory (the one containing '{context.ExecutableName}'), then press enter."); + this.PrintInfo($"Type the file path to the game directory (the one containing '{Constants.GameDllName}'), then press enter."); string path = Console.ReadLine()?.Trim(); if (string.IsNullOrWhiteSpace(path)) { diff --git a/src/SMAPI.Installer/SMAPI.Installer.csproj b/src/SMAPI.Installer/SMAPI.Installer.csproj index c47f3e6e..e3e01467 100644 --- a/src/SMAPI.Installer/SMAPI.Installer.csproj +++ b/src/SMAPI.Installer/SMAPI.Installer.csproj @@ -2,7 +2,7 @@ StardewModdingAPI.Installer The SMAPI installer for players. - net452 + net5.0 Exe false diff --git a/src/SMAPI.Installer/assets/System.Numerics.dll b/src/SMAPI.Installer/assets/System.Numerics.dll deleted file mode 100644 index fed0f92c..00000000 Binary files a/src/SMAPI.Installer/assets/System.Numerics.dll and /dev/null differ diff --git a/src/SMAPI.Installer/assets/System.Runtime.Caching.dll b/src/SMAPI.Installer/assets/System.Runtime.Caching.dll deleted file mode 100644 index a062391d..00000000 Binary files a/src/SMAPI.Installer/assets/System.Runtime.Caching.dll and /dev/null differ diff --git a/src/SMAPI.Installer/assets/unix-install.sh b/src/SMAPI.Installer/assets/unix-install.sh index 311c5469..a830a22d 100644 --- a/src/SMAPI.Installer/assets/unix-install.sh +++ b/src/SMAPI.Installer/assets/unix-install.sh @@ -1,24 +1,10 @@ #!/bin/bash -# Run the SMAPI installer through Mono on Linux or macOS. # Move to script's directory cd "`dirname "$0"`" -# get cross-distro version of POSIX command -COMMAND="" -if command -v command >/dev/null 2>&1; then - COMMAND="command -v" -elif type type >/dev/null 2>&1; then - COMMAND="type" -fi - # if $TERM is not set to xterm, mono will bail out when attempting to write to the console. export TERM=xterm -# validate Mono & run installer -if $COMMAND mono >/dev/null 2>&1; then - mono internal/unix-install.exe -else - echo "Oops! Looks like Mono isn't installed. Please install Mono from https://mono-project.com, reboot, and run this installer again." - read -fi +# run installer +./internal/unix-install diff --git a/src/SMAPI.Installer/assets/unix-launcher.sh b/src/SMAPI.Installer/assets/unix-launcher.sh index d309f750..21bed803 100644 --- a/src/SMAPI.Installer/assets/unix-launcher.sh +++ b/src/SMAPI.Installer/assets/unix-launcher.sh @@ -1,34 +1,17 @@ #!/usr/bin/env bash -# MonoKickstart Shell Script -# Written by Ethan "flibitijibibo" Lee -# Modified for SMAPI by various contributors # Move to script's directory cd "$(dirname "$0")" || exit $? -# Get the system architecture -UNAME=$(uname) -ARCH=$(uname -m) +# validate script is being run from the game folder +if [ ! -f "Stardew Valley.dll" ]; then + echo "Oops! SMAPI must be placed in the Stardew Valley game folder.\nSee instructions: https://stardewvalleywiki.com/Modding:Player_Guide"; + read + exit 1 +fi -# MonoKickstart picks the right libfolder, so just execute the right binary. +# macOS if [ "$UNAME" == "Darwin" ]; then - # ... Except on OSX. - export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:./osx/ - - # El Capitan is a total idiot and wipes this variable out, making the - # Steam overlay disappear. This sidesteps "System Integrity Protection" - # and resets the variable with Valve's own variable (they provided this - # fix by the way, thanks Valve!). Note that you will need to update your - # launch configuration to the script location, NOT just the app location - # (i.e. Kick.app/Contents/MacOS/Kick, not just Kick.app). - # -flibit - if [ "$STEAM_DYLD_INSERT_LIBRARIES" != "" ] && [ "$DYLD_INSERT_LIBRARIES" == "" ]; then - export DYLD_INSERT_LIBRARIES="$STEAM_DYLD_INSERT_LIBRARIES" - fi - - # this was here before - ln -sf mcs.bin.osx mcs - # fix "DllNotFoundException: libgdiplus.dylib" errors when loading images in SMAPI if [ -f libgdiplus.dylib ]; then rm libgdiplus.dylib @@ -37,52 +20,13 @@ if [ "$UNAME" == "Darwin" ]; then ln -s /Library/Frameworks/Mono.framework/Versions/Current/lib/libgdiplus.dylib libgdiplus.dylib fi - # create bin file - # Note: don't overwrite if it's identical, to avoid resetting permission flags - if [ ! -x StardewModdingAPI.bin.osx ] || ! cmp StardewValley.bin.osx StardewModdingAPI.bin.osx >/dev/null 2>&1; then - cp -p StardewValley.bin.osx StardewModdingAPI.bin.osx - fi - - # Make sure we're running in Terminal (so the user can see errors/warnings/update alerts). - # Previously we would just use `open -a Terminal` to launch the .bin.osx file, but that - # doesn't let us set environment variables. - if [ ! -t 1 ]; then # https://stackoverflow.com/q/911168/262123 - # sanity check to make sure we don't have an infinite loop of opening windows - SKIP_TERMINAL=false - for argument in "$@"; do - if [ "$argument" == "--no-reopen-terminal" ]; then - SKIP_TERMINAL=true - break - fi - done - - # reopen in Terminal if needed - # https://stackoverflow.com/a/29511052/262123 - if [ "$SKIP_TERMINAL" == "false" ]; then - echo "Reopening in the Terminal app..." - echo "\"$0\" $@ --no-reopen-terminal" > /tmp/open-smapi-terminal.sh - chmod +x /tmp/open-smapi-terminal.sh - cat /tmp/open-smapi-terminal.sh - open -W -a Terminal /tmp/open-smapi-terminal.sh - rm /tmp/open-smapi-terminal.sh - exit 0 - fi - fi + # launch smapi + open -a Terminal ./StardewModdingAPI "$@" - # launch SMAPI - LC_ALL="C" ./StardewModdingAPI.bin.osx "$@" +# Linux else # choose binary file to launch - LAUNCH_FILE="" - if [ "$ARCH" == "x86_64" ]; then - ln -sf mcs.bin.x86_64 mcs - cp StardewValley.bin.x86_64 StardewModdingAPI.bin.x86_64 - LAUNCH_FILE="./StardewModdingAPI.bin.x86_64" - else - ln -sf mcs.bin.x86 mcs - cp StardewValley.bin.x86 StardewModdingAPI.bin.x86 - LAUNCH_FILE="./StardewModdingAPI.bin.x86" - fi + LAUNCH_FILE="./StardewModdingAPI" export LAUNCH_FILE # select terminal (prefer xterm for best compatibility, then known supported terminals) @@ -105,44 +49,44 @@ else terminal|termite) # consumes only one argument after -e # options containing space characters are unsupported - exec $TERMINAL_NAME -e "env TERM=xterm LC_ALL=\"C\" $LAUNCH_FILE $@" + exec $TERMINAL_NAME -e "env TERM=xterm $LAUNCH_FILE $@" ;; xterm|konsole|alacritty) # consumes all arguments after -e - exec $TERMINAL_NAME -e env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@" + exec $TERMINAL_NAME -e env TERM=xterm $LAUNCH_FILE "$@" ;; terminator|xfce4-terminal|mate-terminal) # consumes all arguments after -x - exec $TERMINAL_NAME -x env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@" + exec $TERMINAL_NAME -x env TERM=xterm $LAUNCH_FILE "$@" ;; gnome-terminal) # consumes all arguments after -- - exec $TERMINAL_NAME -- env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@" + exec $TERMINAL_NAME -- env TERM=xterm $LAUNCH_FILE "$@" ;; kitty) # consumes all trailing arguments - exec $TERMINAL_NAME env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@" + exec $TERMINAL_NAME env TERM=xterm $LAUNCH_FILE "$@" ;; *) # If we don't know the terminal, just try to run it in the current shell. # If THAT fails, launch with no output. - env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@" + env TERM=xterm $LAUNCH_FILE "$@" if [ $? -eq 127 ]; then - exec LC_ALL="C" $LAUNCH_FILE --no-terminal "$@" + exec $LAUNCH_FILE --no-terminal "$@" fi esac ## terminal isn't executable; fallback to current shell or no terminal else echo "The '$TERMINAL_NAME' terminal isn't executable. SMAPI might be running in a sandbox or the system might be misconfigured? Falling back to current shell." - env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@" + env TERM=xterm $LAUNCH_FILE "$@" if [ $? -eq 127 ]; then - exec LC_ALL="C" $LAUNCH_FILE --no-terminal "$@" + exec $LAUNCH_FILE --no-terminal "$@" fi fi fi diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj b/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj index dc3d8320..264932e4 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj @@ -1,18 +1,14 @@  - - netcoreapp2.0 + net5.0 latest - - + + - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + @@ -20,5 +16,4 @@ - diff --git a/src/SMAPI.ModBuildConfig.Analyzer/SMAPI.ModBuildConfig.Analyzer.csproj b/src/SMAPI.ModBuildConfig.Analyzer/SMAPI.ModBuildConfig.Analyzer.csproj index 0d109b83..3fadc37a 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer/SMAPI.ModBuildConfig.Analyzer.csproj +++ b/src/SMAPI.ModBuildConfig.Analyzer/SMAPI.ModBuildConfig.Analyzer.csproj @@ -9,8 +9,7 @@ - - + diff --git a/src/SMAPI.ModBuildConfig/SMAPI.ModBuildConfig.csproj b/src/SMAPI.ModBuildConfig/SMAPI.ModBuildConfig.csproj index 93769650..33356413 100644 --- a/src/SMAPI.ModBuildConfig/SMAPI.ModBuildConfig.csproj +++ b/src/SMAPI.ModBuildConfig/SMAPI.ModBuildConfig.csproj @@ -2,28 +2,28 @@ StardewModdingAPI.ModBuildConfig - net452 + netstandard2.0 latest true Pathoschild.Stardew.ModBuildConfig Build package for SMAPI mods - 3.3.0 + 3.4.0 Pathoschild - Automates the build configuration for crossplatform Stardew Valley SMAPI mods. For SMAPI 3.0 or later. + Automates the build configuration for crossplatform Stardew Valley SMAPI mods. For SMAPI 3.13.0 or later. MIT images/icon.png https://smapi.io/package/readme false + + + true - - - - - + + diff --git a/src/SMAPI.ModBuildConfig/build/smapi.targets b/src/SMAPI.ModBuildConfig/build/smapi.targets index be10481b..a3cd6c45 100644 --- a/src/SMAPI.ModBuildConfig/build/smapi.targets +++ b/src/SMAPI.ModBuildConfig/build/smapi.targets @@ -45,13 +45,13 @@ **********************************************--> - + - + @@ -68,8 +68,8 @@ - - + + diff --git a/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj b/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj index fa192073..65d54599 100644 --- a/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj +++ b/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj @@ -2,7 +2,7 @@ ConsoleCommands StardewModdingAPI.Mods.ConsoleCommands - net452 + net5.0 false @@ -13,7 +13,7 @@ - + diff --git a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj index 7ba6025b..2ad19df7 100644 --- a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj +++ b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj @@ -2,7 +2,7 @@ ErrorHandler StardewModdingAPI.Mods.ErrorHandler - net452 + net5.0 false @@ -14,7 +14,7 @@ - + diff --git a/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj b/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj index 079beb08..f8908c7d 100644 --- a/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj +++ b/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj @@ -2,7 +2,7 @@ SaveBackup StardewModdingAPI.Mods.SaveBackup - net452 + net5.0 false @@ -13,7 +13,7 @@ - + diff --git a/src/SMAPI.Tests/SMAPI.Tests.csproj b/src/SMAPI.Tests/SMAPI.Tests.csproj index 8f7bfab4..e19105ff 100644 --- a/src/SMAPI.Tests/SMAPI.Tests.csproj +++ b/src/SMAPI.Tests/SMAPI.Tests.csproj @@ -2,7 +2,7 @@ SMAPI.Tests SMAPI.Tests - net452 + net5.0 false latest @@ -16,6 +16,7 @@ + @@ -23,7 +24,7 @@ - $(GamePath)\$(GameExecutableName).exe + $(GamePath)\$(GameExecutableName).dll True diff --git a/src/SMAPI.Toolkit.CoreInterfaces/SMAPI.Toolkit.CoreInterfaces.csproj b/src/SMAPI.Toolkit.CoreInterfaces/SMAPI.Toolkit.CoreInterfaces.csproj index 0e1e40b2..4c92b4db 100644 --- a/src/SMAPI.Toolkit.CoreInterfaces/SMAPI.Toolkit.CoreInterfaces.csproj +++ b/src/SMAPI.Toolkit.CoreInterfaces/SMAPI.Toolkit.CoreInterfaces.csproj @@ -2,7 +2,7 @@ StardewModdingAPI Provides toolkit interfaces which are available to SMAPI mods. - net452;netstandard2.0 + net5.0; netstandard2.0 true diff --git a/src/SMAPI.Toolkit/Framework/Constants.cs b/src/SMAPI.Toolkit/Framework/Constants.cs new file mode 100644 index 00000000..55f26582 --- /dev/null +++ b/src/SMAPI.Toolkit/Framework/Constants.cs @@ -0,0 +1,9 @@ +namespace StardewModdingAPI.Toolkit.Framework +{ + /// Contains the SMAPI installer's constants and assumptions. + internal static class Constants + { + /// The name of the game's main DLL, used to detect game folders. + public const string GameDllName = "Stardew Valley.dll"; + } +} diff --git a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs index c90fc1d3..7553c07f 100644 --- a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs +++ b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs @@ -56,10 +56,7 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning { return dir.Exists - && ( - dir.EnumerateFiles("StardewValley.exe").Any() - || dir.EnumerateFiles("Stardew Valley.exe").Any() - ); + && dir.EnumerateFiles("Stardew Valley.dll").Any(); } diff --git a/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs b/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs index 2636aae0..8b6eb5fb 100644 --- a/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs +++ b/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs @@ -80,15 +80,6 @@ namespace StardewModdingAPI.Toolkit.Framework return name; } - /// Get the name of the Stardew Valley executable. - /// The current platform. - public static string GetExecutableName(string platform) - { - return platform == nameof(Platform.Windows) - ? "Stardew Valley.exe" - : "StardewValley.exe"; - } - /// Get whether an executable is 64-bit. /// The absolute path to the assembly file. public static bool Is64BitAssembly(string path) diff --git a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj index 3d87c169..ec27bf79 100644 --- a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj +++ b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj @@ -2,7 +2,7 @@ StardewModdingAPI.Toolkit A library which encapsulates mod-handling logic for mod managers and tools. Not intended for use by mods. - net452;netstandard2.0 + net5.0; netstandard2.0 true @@ -12,8 +12,8 @@ - - + + diff --git a/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs b/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs index 6de79a85..7536337a 100644 --- a/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs +++ b/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs @@ -40,13 +40,6 @@ namespace StardewModdingAPI.Toolkit.Utilities return LowLevelEnvironmentUtility.GetFriendlyPlatformName(platform.ToString()); } - /// Get the name of the Stardew Valley executable. - /// The current platform. - public static string GetExecutableName(Platform platform) - { - return LowLevelEnvironmentUtility.GetExecutableName(platform.ToString()); - } - /// Get whether an executable is 64-bit. /// The absolute path to the assembly file. public static bool Is64BitAssembly(string path) diff --git a/src/SMAPI.Toolkit/Utilities/PathUtilities.cs b/src/SMAPI.Toolkit/Utilities/PathUtilities.cs index 020ebc6d..c17bb354 100644 --- a/src/SMAPI.Toolkit/Utilities/PathUtilities.cs +++ b/src/SMAPI.Toolkit/Utilities/PathUtilities.cs @@ -88,14 +88,18 @@ namespace StardewModdingAPI.Toolkit.Utilities /// Get a directory or file path relative to a given source path. If no relative path is possible (e.g. the paths are on different drives), an absolute path is returned. /// The source folder path. /// The target folder or file path. - /// - /// - /// NOTE: this is a heuristic implementation that works in the cases SMAPI needs it for, but it doesn't handle all edge cases (e.g. case-sensitivity on Linux, or traversing between UNC paths on Windows). This should be replaced with the more comprehensive Path.GetRelativePath if the game ever migrates to .NET Core. - /// - /// [Pure] public static string GetRelativePath(string sourceDir, string targetPath) { +#if NET5_0 + return Path.GetRelativePath(sourceDir, targetPath); +#else + // NOTE: + // this is a heuristic implementation that works in the cases SMAPI needs it for, but it + // doesn't handle all edge cases (e.g. case-sensitivity on Linux, or traversing between + // UNC paths on Windows). SMAPI and mods will use the more robust .NET 5 version anyway + // though, this is only for compatibility with the mod build package. + // convert to URIs Uri from = new Uri(sourceDir.TrimEnd(PathUtilities.PossiblePathSeparators) + "/"); Uri to = new Uri(targetPath.TrimEnd(PathUtilities.PossiblePathSeparators) + "/"); @@ -123,6 +127,7 @@ namespace StardewModdingAPI.Toolkit.Utilities } return relative; +#endif } /// Get whether a path is relative and doesn't try to climb out of its containing folder (e.g. doesn't contain ../). diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index 2e25a94a..abcb2f64 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -290,7 +290,7 @@ namespace StardewModdingAPI.Framework.Logging /// The custom SMAPI settings. public void LogIntro(string modsPath, IDictionary customSettings) { - // log platform & patches + // log platform this.Monitor.Log($"SMAPI {Constants.ApiVersion} with Stardew Valley {Constants.GameVersion} on {EnvironmentUtility.GetFriendlyPlatformName(Constants.Platform)}", LogLevel.Info); // log basic info diff --git a/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs b/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs index 8d1b6034..5acba569 100644 --- a/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs +++ b/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs @@ -24,7 +24,7 @@ namespace StardewModdingAPI.Framework.Reflection /// Construct an instance. public InterfaceProxyFactory() { - AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName($"StardewModdingAPI.Proxies, Version={this.GetType().Assembly.GetName().Version}, Culture=neutral"), AssemblyBuilderAccess.Run); + AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName($"StardewModdingAPI.Proxies, Version={this.GetType().Assembly.GetName().Version}, Culture=neutral"), AssemblyBuilderAccess.Run); this.ModuleBuilder = assemblyBuilder.DefineDynamicModule("StardewModdingAPI.Proxies"); } diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index b049e868..95a7ace6 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -16,7 +16,6 @@ using Microsoft.Xna.Framework; #if SMAPI_FOR_WINDOWS using Microsoft.Win32; #endif -using Microsoft.Xna.Framework; using Newtonsoft.Json; using StardewModdingAPI.Enums; using StardewModdingAPI.Events; @@ -1298,9 +1297,6 @@ namespace StardewModdingAPI.Framework { // create client string url = this.Settings.WebApiBaseUrl; -#if !SMAPI_FOR_WINDOWS - url = url.Replace("https://", "http://"); // workaround for OpenSSL issues with the game's bundled Mono on Linux/macOS -#endif WebApiClient client = new WebApiClient(url, Constants.ApiVersion); this.Monitor.Log("Checking for updates..."); @@ -1695,9 +1691,8 @@ namespace StardewModdingAPI.Framework catch (Exception ex) { errorReasonPhrase = "its DLL couldn't be loaded."; - // re-enable in Stardew Valley 1.5.5 - //if (ex is BadImageFormatException && !EnvironmentUtility.Is64BitAssembly(assemblyPath)) - // errorReasonPhrase = "it needs to be updated for 64-bit mode."; + if (ex is BadImageFormatException && !EnvironmentUtility.Is64BitAssembly(assemblyPath)) + errorReasonPhrase = "it needs to be updated for 64-bit mode."; errorDetails = $"Error: {ex.GetLogSummary()}"; failReason = ModFailReason.LoadFailed; diff --git a/src/SMAPI/Metadata/InstructionMetadata.cs b/src/SMAPI/Metadata/InstructionMetadata.cs index 368306a1..232e54ce 100644 --- a/src/SMAPI/Metadata/InstructionMetadata.cs +++ b/src/SMAPI/Metadata/InstructionMetadata.cs @@ -48,7 +48,7 @@ namespace StardewModdingAPI.Metadata // rewrite for Stardew Valley 1.5.5 if (platformChanged) yield return new MethodParentRewriter(typeof(SpriteBatch), typeof(SpriteBatchFacade)); - //yield return new ArchitectureAssemblyRewriter(); + yield return new ArchitectureAssemblyRewriter(); // detect Harmony & rewrite for SMAPI 3.12 (Harmony 1.x => 2.0 update) yield return new HarmonyRewriter(); diff --git a/src/SMAPI/SMAPI.csproj b/src/SMAPI/SMAPI.csproj index e5cc8da6..a04dd1b6 100644 --- a/src/SMAPI/SMAPI.csproj +++ b/src/SMAPI/SMAPI.csproj @@ -3,13 +3,16 @@ StardewModdingAPI StardewModdingAPI The modding API for Stardew Valley. - net452 - x86 + net5.0 + x64 Exe true false true icon.ico + + + true @@ -19,15 +22,16 @@ - + + + - + - -- cgit From ce80c68135b08fea7caaa9581b3c4eba61c3ec65 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Mon, 16 Aug 2021 19:43:55 -0400 Subject: fix segfault on Linux/macOS after .NET 5 update Harmony doesn't seem to support tiered compilation on Linux/macOS, but the vanilla game disables that too anyway. The bundled runtimeconfig files match the ones used by the vanilla game. Thanks to 0x0ade for identifying the cause! --- build/prepare-install-package.targets | 3 ++- src/SMAPI.Installer/assets/runtimeconfig.unix.json | 14 ++++++++++++++ src/SMAPI.Installer/assets/runtimeconfig.windows.json | 12 ++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/SMAPI.Installer/assets/runtimeconfig.unix.json create mode 100644 src/SMAPI.Installer/assets/runtimeconfig.windows.json (limited to 'src/SMAPI.Installer') diff --git a/build/prepare-install-package.targets b/build/prepare-install-package.targets index bc1716a3..21b02b87 100644 --- a/build/prepare-install-package.targets +++ b/build/prepare-install-package.targets @@ -36,13 +36,14 @@ + - + diff --git a/src/SMAPI.Installer/assets/runtimeconfig.unix.json b/src/SMAPI.Installer/assets/runtimeconfig.unix.json new file mode 100644 index 00000000..8a01ceb1 --- /dev/null +++ b/src/SMAPI.Installer/assets/runtimeconfig.unix.json @@ -0,0 +1,14 @@ +{ + "runtimeOptions": { + "tfm": "net5.0", + "includedFrameworks": [ + { + "name": "Microsoft.NETCore.App", + "version": "5.0.7" + } + ], + "configProperties": { + "System.Runtime.TieredCompilation": false + } + } +} diff --git a/src/SMAPI.Installer/assets/runtimeconfig.windows.json b/src/SMAPI.Installer/assets/runtimeconfig.windows.json new file mode 100644 index 00000000..b693d809 --- /dev/null +++ b/src/SMAPI.Installer/assets/runtimeconfig.windows.json @@ -0,0 +1,12 @@ +{ + "runtimeOptions": { + "tfm": "net5.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "5.0.0" + }, + "configProperties": { + "System.Runtime.TieredCompilation": false + } + } +} -- cgit From f6479ea2b61ebcc4eda434d7d5cb664534a99801 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 17 Aug 2021 16:42:04 -0400 Subject: restructure installer for .NET 5 changes --- build/prepare-install-package.targets | 14 +++++++------- src/SMAPI.Installer/Program.cs | 3 +-- src/SMAPI.Installer/assets/README.txt | 2 +- src/SMAPI.Installer/assets/unix-install.sh | 2 +- src/SMAPI.Installer/assets/windows-install.bat | 2 +- 5 files changed, 11 insertions(+), 12 deletions(-) (limited to 'src/SMAPI.Installer') diff --git a/build/prepare-install-package.targets b/build/prepare-install-package.targets index 21b02b87..dd28266d 100644 --- a/build/prepare-install-package.targets +++ b/build/prepare-install-package.targets @@ -36,11 +36,11 @@ - - - - - + + + + + @@ -99,12 +99,12 @@ - + - + diff --git a/src/SMAPI.Installer/Program.cs b/src/SMAPI.Installer/Program.cs index d9c31dd6..45cfea75 100644 --- a/src/SMAPI.Installer/Program.cs +++ b/src/SMAPI.Installer/Program.cs @@ -31,8 +31,7 @@ namespace StardewModdingApi.Installer public static void Main(string[] args) { // find install bundle - PlatformID platform = Environment.OSVersion.Platform; - FileInfo zipFile = new FileInfo(Path.Combine(Program.InstallerPath, $"{(platform == PlatformID.Win32NT ? "windows" : "unix")}-install.dat")); + FileInfo zipFile = new FileInfo(Path.Combine(Program.InstallerPath, "install.dat")); if (!zipFile.Exists) { Console.WriteLine($"Oops! Some of the installer files are missing; try re-downloading the installer. (Missing file: {zipFile.FullName})"); diff --git a/src/SMAPI.Installer/assets/README.txt b/src/SMAPI.Installer/assets/README.txt index c3a7e271..5c20529a 100644 --- a/src/SMAPI.Installer/assets/README.txt +++ b/src/SMAPI.Installer/assets/README.txt @@ -24,7 +24,7 @@ Manual install THIS IS NOT RECOMMENDED FOR MOST PLAYERS. See instructions above instead. If you really want to install SMAPI manually, here's how. -1. Unzip "internal/windows-install.dat" (on Windows) or "internal/unix-install.dat" (on +1. Unzip "internal/windows/install.dat" (on Windows) or "internal/unix/install.dat" (on Linux/macOS). You can change '.dat' to '.zip', it's just a normal zip file renamed to prevent confusion. 2. Copy the files from the folder you just unzipped into your game folder. The diff --git a/src/SMAPI.Installer/assets/unix-install.sh b/src/SMAPI.Installer/assets/unix-install.sh index a830a22d..f5de7b16 100644 --- a/src/SMAPI.Installer/assets/unix-install.sh +++ b/src/SMAPI.Installer/assets/unix-install.sh @@ -7,4 +7,4 @@ cd "`dirname "$0"`" export TERM=xterm # run installer -./internal/unix-install +./internal/unix/install diff --git a/src/SMAPI.Installer/assets/windows-install.bat b/src/SMAPI.Installer/assets/windows-install.bat index 2cd98554..3ca13528 100644 --- a/src/SMAPI.Installer/assets/windows-install.bat +++ b/src/SMAPI.Installer/assets/windows-install.bat @@ -4,5 +4,5 @@ if not errorlevel 1 ( echo Oops! It looks like you're running the installer from inside a zip file. Make sure you unzip the download first. pause ) else ( - start /WAIT /B internal\windows-install.exe + start /WAIT /B internal\windows\install.exe ) -- cgit From 7c5c63d6846d93f772dfda37f394b5f501f49f25 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 17 Aug 2021 20:11:30 -0400 Subject: fix SMAPI not working on macOS, improve installer validation --- build/prepare-install-package.targets | 2 -- src/SMAPI.Installer/assets/unix-install.sh | 10 ++++--- src/SMAPI.Installer/assets/unix-launcher.sh | 36 ++++++++++++++++++++++++-- src/SMAPI.Installer/assets/windows-install.bat | 29 +++++++++++++++++---- 4 files changed, 65 insertions(+), 12 deletions(-) (limited to 'src/SMAPI.Installer') diff --git a/build/prepare-install-package.targets b/build/prepare-install-package.targets index dd28266d..ef5624ad 100644 --- a/build/prepare-install-package.targets +++ b/build/prepare-install-package.targets @@ -38,8 +38,6 @@ - - diff --git a/src/SMAPI.Installer/assets/unix-install.sh b/src/SMAPI.Installer/assets/unix-install.sh index f5de7b16..07df4e6c 100644 --- a/src/SMAPI.Installer/assets/unix-install.sh +++ b/src/SMAPI.Installer/assets/unix-install.sh @@ -3,8 +3,12 @@ # Move to script's directory cd "`dirname "$0"`" -# if $TERM is not set to xterm, mono will bail out when attempting to write to the console. -export TERM=xterm +# make sure .NET 5 is installed +if ! command -v dotnet >/dev/null 2>&1; then + echo "Oops! You must have .NET 5 installed to use SMAPI: https://dotnet.microsoft.com/download"; + read + exit 1 +fi # run installer -./internal/unix/install +dotnet internal/unix/SMAPI.Installer.dll diff --git a/src/SMAPI.Installer/assets/unix-launcher.sh b/src/SMAPI.Installer/assets/unix-launcher.sh index 21bed803..0e700b61 100644 --- a/src/SMAPI.Installer/assets/unix-launcher.sh +++ b/src/SMAPI.Installer/assets/unix-launcher.sh @@ -10,7 +10,15 @@ if [ ! -f "Stardew Valley.dll" ]; then exit 1 fi +# make sure .NET 5 is installed +if ! command -v dotnet >/dev/null 2>&1; then + echo "Oops! You must have .NET 5 installed to use SMAPI: https://dotnet.microsoft.com/download"; + read + exit 1 +fi + # macOS +UNAME=$(uname) if [ "$UNAME" == "Darwin" ]; then # fix "DllNotFoundException: libgdiplus.dylib" errors when loading images in SMAPI if [ -f libgdiplus.dylib ]; then @@ -20,8 +28,32 @@ if [ "$UNAME" == "Darwin" ]; then ln -s /Library/Frameworks/Mono.framework/Versions/Current/lib/libgdiplus.dylib libgdiplus.dylib fi - # launch smapi - open -a Terminal ./StardewModdingAPI "$@" + # Make sure we're running in Terminal (so the user can see errors/warnings/update alerts). + if [ ! -t 1 ]; then # https://stackoverflow.com/q/911168/262123 + # sanity check to make sure we don't have an infinite loop of opening windows + SKIP_TERMINAL=false + for argument in "$@"; do + if [ "$argument" == "--no-reopen-terminal" ]; then + SKIP_TERMINAL=true + break + fi + done + + # reopen in Terminal if needed + # https://stackoverflow.com/a/29511052/262123 + if [ "$SKIP_TERMINAL" == "false" ]; then + echo "Reopening in the Terminal app..." + echo "\"$0\" $@ --no-reopen-terminal" > /tmp/open-smapi-terminal.sh + chmod +x /tmp/open-smapi-terminal.sh + cat /tmp/open-smapi-terminal.sh + open -W -a Terminal /tmp/open-smapi-terminal.sh + rm /tmp/open-smapi-terminal.sh + exit 0 + fi + fi + + # launch SMAPI + dotnet StardewModdingAPI.dll "$@" # Linux else diff --git a/src/SMAPI.Installer/assets/windows-install.bat b/src/SMAPI.Installer/assets/windows-install.bat index 3ca13528..8623f321 100644 --- a/src/SMAPI.Installer/assets/windows-install.bat +++ b/src/SMAPI.Installer/assets/windows-install.bat @@ -1,8 +1,27 @@ @echo off + +REM make sure we're not running within a zip folder echo "%~dp0" | findstr /C:"%TEMP%" 1>nul -if not errorlevel 1 ( - echo Oops! It looks like you're running the installer from inside a zip file. Make sure you unzip the download first. - pause -) else ( - start /WAIT /B internal\windows\install.exe +if %ERRORLEVEL% EQU 0 ( + echo "Oops! It looks like you're running the installer from inside a zip file. Make sure you unzip the download first." + pause + exit ) + +REM make sure .NET 5 is installed +WHERE dotnet /q +if %ERRORLEVEL% NEQ 0 ( + echo "Oops! You must have .NET 5 (desktop x64) installed to use SMAPI: https://dotnet.microsoft.com/download/dotnet/5.0/runtime" + pause + exit +) + +REM make sure an antivirus hasn't deleted the installer DLL +if not exist internal\windows\SMAPI.Installer.dll ( + echo "Oops! SMAPI can't find its 'internal\windows\SMAPI.Installer.dll' file. Your antivirus might have deleted the file." + pause + exit +) + +REM start installer +dotnet internal\windows\SMAPI.Installer.dll -- cgit From 0f508c755aa679dc63b78507c54b5530d5b972d3 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 17 Aug 2021 21:41:23 -0400 Subject: reorganize install script This fixes an issue where Steam messes with the PATH, so dotnet isn't available until the terminal window is opened. --- src/SMAPI.Installer/assets/unix-launcher.sh | 70 ++++++++++++++++++----------- 1 file changed, 44 insertions(+), 26 deletions(-) (limited to 'src/SMAPI.Installer') diff --git a/src/SMAPI.Installer/assets/unix-launcher.sh b/src/SMAPI.Installer/assets/unix-launcher.sh index 0e700b61..7e892fca 100644 --- a/src/SMAPI.Installer/assets/unix-launcher.sh +++ b/src/SMAPI.Installer/assets/unix-launcher.sh @@ -1,34 +1,19 @@ #!/usr/bin/env bash -# Move to script's directory +########## +## Initial setup +########## +# move to script's directory cd "$(dirname "$0")" || exit $? -# validate script is being run from the game folder -if [ ! -f "Stardew Valley.dll" ]; then - echo "Oops! SMAPI must be placed in the Stardew Valley game folder.\nSee instructions: https://stardewvalleywiki.com/Modding:Player_Guide"; - read - exit 1 -fi - -# make sure .NET 5 is installed -if ! command -v dotnet >/dev/null 2>&1; then - echo "Oops! You must have .NET 5 installed to use SMAPI: https://dotnet.microsoft.com/download"; - read - exit 1 -fi -# macOS -UNAME=$(uname) -if [ "$UNAME" == "Darwin" ]; then - # fix "DllNotFoundException: libgdiplus.dylib" errors when loading images in SMAPI - if [ -f libgdiplus.dylib ]; then - rm libgdiplus.dylib - fi - if [ -f /Library/Frameworks/Mono.framework/Versions/Current/lib/libgdiplus.dylib ]; then - ln -s /Library/Frameworks/Mono.framework/Versions/Current/lib/libgdiplus.dylib libgdiplus.dylib - fi - - # Make sure we're running in Terminal (so the user can see errors/warnings/update alerts). +########## +## Open terminal if needed +########## +# on macOS, make sure we're running in a Terminal +# Besides letting the player see errors/warnings/alerts in the console, this is also needed because +# Steam messes with the PATH. +if [ "$(uname)" == "Darwin" ]; then if [ ! -t 1 ]; then # https://stackoverflow.com/q/911168/262123 # sanity check to make sure we don't have an infinite loop of opening windows SKIP_TERMINAL=false @@ -51,6 +36,39 @@ if [ "$UNAME" == "Darwin" ]; then exit 0 fi fi +fi + + +########## +## Validate assumptions +########## +# script must be run from the game folder +if [ ! -f "Stardew Valley.dll" ]; then + echo "Oops! SMAPI must be placed in the Stardew Valley game folder.\nSee instructions: https://stardewvalleywiki.com/Modding:Player_Guide"; + read + exit 1 +fi + +# .NET 5 must be installed +if ! command -v dotnet >/dev/null 2>&1; then + echo "Oops! You must have .NET 5 installed to use SMAPI: https://dotnet.microsoft.com/download"; + read + exit 1 +fi + + +########## +## Launch SMAPI +########## +# macOS +if [ "$(uname)" == "Darwin" ]; then + # fix "DllNotFoundException: libgdiplus.dylib" errors when loading images in SMAPI + if [ -f libgdiplus.dylib ]; then + rm libgdiplus.dylib + fi + if [ -f /Library/Frameworks/Mono.framework/Versions/Current/lib/libgdiplus.dylib ]; then + ln -s /Library/Frameworks/Mono.framework/Versions/Current/lib/libgdiplus.dylib libgdiplus.dylib + fi # launch SMAPI dotnet StardewModdingAPI.dll "$@" -- cgit From 33c7a0392cc9f39f885f50774e980a0bf3643fd6 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 17 Aug 2021 23:25:09 -0400 Subject: remove libgdiplus workaround on macOS This is no longer needed after the .NET 5 migration. --- src/SMAPI.Installer/InteractiveInstaller.cs | 4 ++-- src/SMAPI.Installer/assets/unix-launcher.sh | 9 --------- src/SMAPI/Framework/ContentManagers/ModContentManager.cs | 3 --- 3 files changed, 2 insertions(+), 14 deletions(-) (limited to 'src/SMAPI.Installer') diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs index 34285cf7..896017d3 100644 --- a/src/SMAPI.Installer/InteractiveInstaller.cs +++ b/src/SMAPI.Installer/InteractiveInstaller.cs @@ -39,7 +39,6 @@ namespace StardewModdingApi.Installer string GetInstallPath(string path) => Path.Combine(installDir.FullName, path); // current files - yield return GetInstallPath("libgdiplus.dylib"); // Linux/macOS only yield return GetInstallPath("StardewModdingAPI"); // Linux/macOS only yield return GetInstallPath("StardewModdingAPI.dll"); yield return GetInstallPath("StardewModdingAPI.exe"); @@ -52,6 +51,7 @@ namespace StardewModdingApi.Installer yield return GetInstallPath("steam_appid.txt"); // obsolete + yield return GetInstallPath("libgdiplus.dylib"); // before 3.13 (macOS only) yield return GetInstallPath(Path.Combine("Mods", ".cache")); // 1.3-1.4 yield return GetInstallPath(Path.Combine("Mods", "TrainerMod")); // *–2.0 (renamed to ConsoleCommands) yield return GetInstallPath("Mono.Cecil.Rocks.dll"); // 1.3–1.8 @@ -71,7 +71,7 @@ namespace StardewModdingApi.Installer yield return GetInstallPath("StardewModdingAPI.Toolkit.CoreInterfaces.dll"); // moved in 2.8 yield return GetInstallPath("StardewModdingAPI.Toolkit.CoreInterfaces.pdb"); // moved in 2.8 yield return GetInstallPath("StardewModdingAPI.Toolkit.CoreInterfaces.xml"); // moved in 2.8 - yield return GetInstallPath("StardewModdingAPI-x64.exe"); // 3.13 + yield return GetInstallPath("StardewModdingAPI-x64.exe"); // before 3.13 if (modsDir.Exists) { diff --git a/src/SMAPI.Installer/assets/unix-launcher.sh b/src/SMAPI.Installer/assets/unix-launcher.sh index 7e892fca..58f7a5ae 100644 --- a/src/SMAPI.Installer/assets/unix-launcher.sh +++ b/src/SMAPI.Installer/assets/unix-launcher.sh @@ -62,15 +62,6 @@ fi ########## # macOS if [ "$(uname)" == "Darwin" ]; then - # fix "DllNotFoundException: libgdiplus.dylib" errors when loading images in SMAPI - if [ -f libgdiplus.dylib ]; then - rm libgdiplus.dylib - fi - if [ -f /Library/Frameworks/Mono.framework/Versions/Current/lib/libgdiplus.dylib ]; then - ln -s /Library/Frameworks/Mono.framework/Versions/Current/lib/libgdiplus.dylib libgdiplus.dylib - fi - - # launch SMAPI dotnet StardewModdingAPI.dll "$@" # Linux diff --git a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs index d24ffb81..bf0b54b9 100644 --- a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs @@ -7,7 +7,6 @@ using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI.Framework.Exceptions; using StardewModdingAPI.Framework.Reflection; -using StardewModdingAPI.Internal; using StardewModdingAPI.Toolkit.Serialization; using StardewModdingAPI.Toolkit.Utilities; using StardewValley; @@ -177,8 +176,6 @@ namespace StardewModdingAPI.Framework.ContentManagers } catch (Exception ex) when (!(ex is SContentLoadException)) { - if (ex.GetInnermostException() is DllNotFoundException dllEx && dllEx.Message == "libgdiplus.dylib") - throw GetContentError("couldn't find libgdiplus, which is needed to load mod images. Make sure Mono is installed and you're running the game through the normal launcher."); throw new SContentLoadException($"The content manager failed loading content asset '{assetName}' from {this.Name}.", ex); } -- cgit From 89c98223ebf6bfeee5ef587ab748995e09dd4310 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 18 Aug 2021 23:55:43 -0400 Subject: remove path-too-long exception handling The path length limit no longer applies in .NET 5. --- src/SMAPI.Installer/InteractiveInstaller.cs | 11 ----------- src/SMAPI.Toolkit/Utilities/PathUtilities.cs | 28 ---------------------------- src/SMAPI/Framework/Logging/LogManager.cs | 19 +------------------ 3 files changed, 1 insertion(+), 57 deletions(-) (limited to 'src/SMAPI.Installer') diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs index 896017d3..714a959b 100644 --- a/src/SMAPI.Installer/InteractiveInstaller.cs +++ b/src/SMAPI.Installer/InteractiveInstaller.cs @@ -259,17 +259,6 @@ namespace StardewModdingApi.Installer Console.ReadLine(); return; } - - // game folder doesn't contain paths beyond the max limit - { - string[] tooLongPaths = PathUtilities.GetTooLongPaths(Path.Combine(paths.GamePath, "Mods")).ToArray(); - if (tooLongPaths.Any()) - { - this.PrintError($"SMAPI can't install to the detected game folder, because some of its files exceed the maximum {context.Platform} path length.\nIf you need help fixing this error, see https://smapi.io/help\n\nAffected paths:\n {string.Join("\n ", tooLongPaths)}"); - Console.ReadLine(); - return; - } - } Console.Clear(); diff --git a/src/SMAPI.Toolkit/Utilities/PathUtilities.cs b/src/SMAPI.Toolkit/Utilities/PathUtilities.cs index 1d378042..2e9e5eac 100644 --- a/src/SMAPI.Toolkit/Utilities/PathUtilities.cs +++ b/src/SMAPI.Toolkit/Utilities/PathUtilities.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Diagnostics.Contracts; using System.IO; using System.Linq; @@ -150,32 +149,5 @@ namespace StardewModdingAPI.Toolkit.Utilities { return !Regex.IsMatch(str, "[^a-z0-9_.-]", RegexOptions.IgnoreCase); } - - /// Get the paths which exceed the OS length limit. - /// The root path to search. - internal static IEnumerable GetTooLongPaths(string rootPath) - { - if (!Directory.Exists(rootPath)) - return new string[0]; - - return Directory - .EnumerateFileSystemEntries(rootPath, "*.*", SearchOption.AllDirectories) - .Where(PathUtilities.IsPathTooLong); - } - - /// Get whether a file or directory path exceeds the OS path length limit. - /// The path to test. - internal static bool IsPathTooLong(string path) - { - try - { - _ = Path.GetFullPath(path); - return false; - } - catch (PathTooLongException) - { - return true; - } - } } } diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index dbcf8934..5a291d0a 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -250,24 +250,7 @@ namespace StardewModdingAPI.Framework.Logging /// The exception details. public void LogFatalLaunchError(Exception exception) { - switch (exception) - { - // path too long exception - case PathTooLongException _: - { - string[] affectedPaths = PathUtilities.GetTooLongPaths(Constants.ModsPath).ToArray(); - string message = affectedPaths.Any() - ? $"SMAPI can't launch because some of your mod files exceed the maximum path length on {Constants.Platform}.\nIf you need help fixing this error, see https://smapi.io/help\n\nAffected paths:\n {string.Join("\n ", affectedPaths)}" - : $"The game failed to launch: {exception.GetLogSummary()}"; - this.MonitorForGame.Log(message, LogLevel.Error); - } - break; - - // generic exception - default: - this.MonitorForGame.Log($"The game failed to launch: {exception.GetLogSummary()}", LogLevel.Error); - break; - } + this.MonitorForGame.Log($"The game failed to launch: {exception.GetLogSummary()}", LogLevel.Error); } /**** -- cgit 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/SMAPI.Installer') 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 From b791e854c1f2117f0cc218485ec767a493a3d847 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 23 Sep 2021 23:11:54 -0400 Subject: fix installer precheck errors showing quotes, tweak readability --- src/SMAPI.Installer/assets/windows-install.bat | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/SMAPI.Installer') diff --git a/src/SMAPI.Installer/assets/windows-install.bat b/src/SMAPI.Installer/assets/windows-install.bat index 8623f321..00a2c6fb 100644 --- a/src/SMAPI.Installer/assets/windows-install.bat +++ b/src/SMAPI.Installer/assets/windows-install.bat @@ -3,7 +3,8 @@ REM make sure we're not running within a zip folder echo "%~dp0" | findstr /C:"%TEMP%" 1>nul if %ERRORLEVEL% EQU 0 ( - echo "Oops! It looks like you're running the installer from inside a zip file. Make sure you unzip the download first." + echo Oops! It looks like you're running the installer from inside a zip file. Make sure you unzip the download first. + echo. pause exit ) @@ -11,14 +12,17 @@ if %ERRORLEVEL% EQU 0 ( REM make sure .NET 5 is installed WHERE dotnet /q if %ERRORLEVEL% NEQ 0 ( - echo "Oops! You must have .NET 5 (desktop x64) installed to use SMAPI: https://dotnet.microsoft.com/download/dotnet/5.0/runtime" + echo Oops! You must have .NET 5 ^(desktop x64^) installed to use SMAPI: https://dotnet.microsoft.com/download/dotnet/5.0/runtime + echo. pause exit ) REM make sure an antivirus hasn't deleted the installer DLL if not exist internal\windows\SMAPI.Installer.dll ( - echo "Oops! SMAPI can't find its 'internal\windows\SMAPI.Installer.dll' file. Your antivirus might have deleted the file." + echo Oops! SMAPI is missing one of its files. Your antivirus might have deleted it. + echo Missing file: %installerDir%internal\windows\SMAPI.Installer.dll + echo. pause exit ) -- cgit From 32ccc8e87294fae4caaf7878ee852ab89b9cfdfd Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 23 Sep 2021 23:12:43 -0400 Subject: fix installer file precheck failing for some users --- src/SMAPI.Installer/assets/windows-install.bat | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/SMAPI.Installer') diff --git a/src/SMAPI.Installer/assets/windows-install.bat b/src/SMAPI.Installer/assets/windows-install.bat index 00a2c6fb..bd6da962 100644 --- a/src/SMAPI.Installer/assets/windows-install.bat +++ b/src/SMAPI.Installer/assets/windows-install.bat @@ -1,7 +1,9 @@ @echo off +SET installerDir=%~dp0 + REM make sure we're not running within a zip folder -echo "%~dp0" | findstr /C:"%TEMP%" 1>nul +echo %installerDir% | findstr /C:"%TEMP%" 1>nul if %ERRORLEVEL% EQU 0 ( echo Oops! It looks like you're running the installer from inside a zip file. Make sure you unzip the download first. echo. @@ -19,7 +21,7 @@ if %ERRORLEVEL% NEQ 0 ( ) REM make sure an antivirus hasn't deleted the installer DLL -if not exist internal\windows\SMAPI.Installer.dll ( +if not exist "%installerDir%internal\windows\SMAPI.Installer.dll" ( echo Oops! SMAPI is missing one of its files. Your antivirus might have deleted it. echo Missing file: %installerDir%internal\windows\SMAPI.Installer.dll echo. -- cgit From 51c6ef9443c9d53448d39a97afde8a0fd23eec46 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 23 Sep 2021 23:13:17 -0400 Subject: fix .NET 5 precheck passing if player has .NET Core installed --- src/SMAPI.Installer/assets/windows-install.bat | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/SMAPI.Installer') diff --git a/src/SMAPI.Installer/assets/windows-install.bat b/src/SMAPI.Installer/assets/windows-install.bat index bd6da962..cb96fc19 100644 --- a/src/SMAPI.Installer/assets/windows-install.bat +++ b/src/SMAPI.Installer/assets/windows-install.bat @@ -19,6 +19,13 @@ if %ERRORLEVEL% NEQ 0 ( pause exit ) +dotnet --info | findstr /C:"Microsoft.WindowsDesktop.App 5." 1>nul +if %ERRORLEVEL% NEQ 0 ( + echo Oops! You must have .NET 5 ^(desktop x64^) installed to use SMAPI: https://dotnet.microsoft.com/download/dotnet/5.0/runtime + echo. + pause + exit +) REM make sure an antivirus hasn't deleted the installer DLL if not exist "%installerDir%internal\windows\SMAPI.Installer.dll" ( -- cgit From cb378a1c558dc2c5de9f2ab1ae9ba38b17d2ac7c Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 23 Sep 2021 23:25:51 -0400 Subject: keep installer window open if it crashes --- docs/release-notes.md | 1 + src/SMAPI.Installer/assets/windows-install.bat | 9 +++++++++ 2 files changed, 10 insertions(+) (limited to 'src/SMAPI.Installer') diff --git a/docs/release-notes.md b/docs/release-notes.md index d6e22af4..f8c1b495 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -6,6 +6,7 @@ * Updated for Stardew Valley 1.5.5. * Updated compatibility list. * Added `set_farm_type` [console command](https://stardewvalleywiki.com/Modding:Console_commands#Console_commands) to change the current farm type. + * Fixed installer window closing immediately if the installer crashed. * For mod authors: * Migrated to 64-bit MonoGame and .NET 5 on all platforms (see [migration guide for mod authors](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5)). diff --git a/src/SMAPI.Installer/assets/windows-install.bat b/src/SMAPI.Installer/assets/windows-install.bat index cb96fc19..2e0be906 100644 --- a/src/SMAPI.Installer/assets/windows-install.bat +++ b/src/SMAPI.Installer/assets/windows-install.bat @@ -38,3 +38,12 @@ if not exist "%installerDir%internal\windows\SMAPI.Installer.dll" ( REM start installer dotnet internal\windows\SMAPI.Installer.dll + +REM keep window open if it failed +if %ERRORLEVEL% NEQ 0 ( + echo. + echo Oops! The SMAPI installer seems to have failed. The error details may be shown above. + echo. + pause + exit +) -- cgit