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 --- 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 +++++---------------- 8 files changed, 71 insertions(+), 215 deletions(-) delete mode 100644 src/SMAPI.Installer/assets/System.Numerics.dll delete mode 100644 src/SMAPI.Installer/assets/System.Runtime.Caching.dll (limited to 'src/SMAPI.Installer') 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 -- cgit