diff options
Diffstat (limited to 'src/SMAPI.Installer/InteractiveInstaller.cs')
-rw-r--r-- | src/SMAPI.Installer/InteractiveInstaller.cs | 124 |
1 files changed, 43 insertions, 81 deletions
diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs index d0ef0b8d..035ec382 100644 --- a/src/SMAPI.Installer/InteractiveInstaller.cs +++ b/src/SMAPI.Installer/InteractiveInstaller.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; -using Microsoft.Win32; +using System.Reflection; using StardewModdingApi.Installer.Enums; using StardewModdingAPI.Installer.Framework; using StardewModdingAPI.Internal.ConsoleWriting; @@ -25,12 +25,8 @@ namespace StardewModdingApi.Installer /// <summary>The absolute path to the directory containing the files to copy into the game folder.</summary> private readonly string BundlePath; - /// <summary>The <see cref="Environment.OSVersion"/> value that represents Windows 7.</summary> - private readonly Version Windows7Version = new Version(6, 1); - /// <summary>The mod IDs which the installer should allow as bundled mods.</summary> - private readonly string[] BundledModIDs = new[] - { + private readonly string[] BundledModIDs = { "SMAPI.SaveBackup", "SMAPI.ConsoleCommands" }; @@ -129,22 +125,22 @@ namespace StardewModdingApi.Installer ** Get basic info & set window title ****/ ModToolkit toolkit = new ModToolkit(); - Platform platform = EnvironmentUtility.DetectPlatform(); - Console.Title = $"SMAPI {this.GetDisplayVersion(this.GetType().Assembly.GetName().Version)} installer on {platform} {EnvironmentUtility.GetFriendlyPlatformName(platform)}"; + var context = new InstallerContext(); + Console.Title = $"SMAPI {context.GetInstallerVersion()} installer on {context.Platform} {context.PlatformName}"; Console.WriteLine(); /**** ** Check if correct installer ****/ #if SMAPI_FOR_WINDOWS - if (platform == Platform.Linux || platform == Platform.Mac) + if (context.IsUnix) { - this.PrintError($"This is the installer for Windows. Run the 'install on {platform}.{(platform == Platform.Linux ? "sh" : "command")}' file instead."); + this.PrintError($"This is the installer for Windows. Run the 'install on {context.Platform}.{(context.Platform == Platform.Mac ? "command" : "sh")}' file instead."); Console.ReadLine(); return; } #else - if (platform == Platform.Windows) + if (context.IsWindows) { this.PrintError($"This is the installer for Linux/Mac. Run the 'install on Windows.exe' file instead."); Console.ReadLine(); @@ -155,20 +151,20 @@ namespace StardewModdingApi.Installer /**** ** Check Windows dependencies ****/ - if (platform == Platform.Windows) + if (context.IsWindows) { // .NET Framework 4.5+ - if (!this.HasNetFramework45(platform)) + if (!context.HasNetFramework45()) { - this.PrintError(Environment.OSVersion.Version >= this.Windows7Version - ? "Please install the latest version of .NET Framework before installing SMAPI." // Windows 7+ - : "Please install .NET Framework 4.5 before installing SMAPI." // Windows Vista or earlier + 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 (!this.HasXna(platform)) + 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(); @@ -202,7 +198,7 @@ namespace StardewModdingApi.Installer ** Step 2: choose a theme (can't auto-detect on Linux/Mac) *********/ MonitorColorScheme scheme = MonitorColorScheme.AutoDetect; - if (platform == Platform.Linux || platform == Platform.Mac) + if (context.IsUnix) { /**** ** print header @@ -215,8 +211,8 @@ namespace StardewModdingApi.Installer ** show theme selector ****/ // get theme writers - var lightBackgroundWriter = new ColorfulConsoleWriter(platform, ColorfulConsoleWriter.GetDefaultColorSchemeConfig(MonitorColorScheme.LightBackground)); - var darkBackgroundWriter = new ColorfulConsoleWriter(platform, ColorfulConsoleWriter.GetDefaultColorSchemeConfig(MonitorColorScheme.DarkBackground)); + var lightBackgroundWriter = new ColorfulConsoleWriter(context.Platform, ColorfulConsoleWriter.GetDefaultColorSchemeConfig(MonitorColorScheme.LightBackground)); + var darkBackgroundWriter = new ColorfulConsoleWriter(context.Platform, ColorfulConsoleWriter.GetDefaultColorSchemeConfig(MonitorColorScheme.DarkBackground)); // print question this.PrintPlain("Which text looks more readable?"); @@ -264,7 +260,7 @@ namespace StardewModdingApi.Installer ****/ // get game path this.PrintInfo("Where is your game folder?"); - DirectoryInfo installDir = this.InteractivelyGetInstallPath(platform, toolkit, gamePathArg); + DirectoryInfo installDir = this.InteractivelyGetInstallPath(toolkit, context, gamePathArg); if (installDir == null) { this.PrintError("Failed finding your game path."); @@ -274,7 +270,7 @@ namespace StardewModdingApi.Installer // get folders DirectoryInfo bundleDir = new DirectoryInfo(this.BundlePath); - paths = new InstallerPaths(bundleDir, installDir, EnvironmentUtility.GetExecutableName(platform)); + paths = new InstallerPaths(bundleDir, installDir, context.ExecutableName); } Console.Clear(); @@ -359,7 +355,7 @@ namespace StardewModdingApi.Installer ** Always uninstall old files ****/ // restore game launcher - if (platform.IsMono() && File.Exists(paths.UnixBackupLauncherPath)) + if (context.IsUnix && File.Exists(paths.UnixBackupLauncherPath)) { this.PrintDebug("Removing SMAPI launcher..."); this.InteractivelyDelete(paths.UnixLauncherPath); @@ -406,7 +402,7 @@ namespace StardewModdingApi.Installer } // replace mod launcher (if possible) - if (platform.IsMono()) + if (context.IsUnix) { this.PrintDebug("Safely replacing game launcher..."); @@ -504,7 +500,7 @@ namespace StardewModdingApi.Installer /********* ** Step 7: final instructions *********/ - if (platform == Platform.Windows) + if (context.IsWindows) { if (action == ScriptAction.Install) { @@ -531,16 +527,6 @@ namespace StardewModdingApi.Installer /********* ** Private methods *********/ - /// <summary>Get the display text for an assembly version.</summary> - /// <param name="version">The assembly version.</param> - private string GetDisplayVersion(Version version) - { - string str = $"{version.Major}.{version.Minor}"; - if (version.Build != 0) - str += $".{version.Build}"; - return str; - } - /// <summary>Get the display text for a color scheme.</summary> /// <param name="scheme">The color scheme.</param> private string GetDisplayText(MonitorColorScheme scheme) @@ -582,38 +568,6 @@ namespace StardewModdingApi.Installer /// <param name="text">The text to print.</param> private void PrintSuccess(string text) => this.ConsoleWriter.WriteLine(text, ConsoleLogLevel.Success); - /// <summary>Get whether the current system has .NET Framework 4.5 or later installed. This only applies on Windows.</summary> - /// <param name="platform">The current platform.</param> - /// <exception cref="NotSupportedException">The current platform is not Windows.</exception> - private bool HasNetFramework45(Platform platform) - { - switch (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."); - } - } - - /// <summary>Get whether the current system has XNA Framework installed. This only applies on Windows.</summary> - /// <param name="platform">The current platform.</param> - /// <exception cref="NotSupportedException">The current platform is not Windows.</exception> - private bool HasXna(Platform platform) - { - switch (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."); - } - } - /// <summary>Interactively delete a file or folder path, and block until deletion completes.</summary> /// <param name="path">The file or folder path.</param> private void InteractivelyDelete(string path) @@ -687,15 +641,12 @@ namespace StardewModdingApi.Installer } /// <summary>Interactively locate the game install path to update.</summary> - /// <param name="platform">The current platform.</param> /// <param name="toolkit">The mod toolkit.</param> + /// <param name="context">The installer context.</param> /// <param name="specifiedPath">The path specified as a command-line argument (if any), which should override automatic path detection.</param> - private DirectoryInfo InteractivelyGetInstallPath(Platform platform, ModToolkit toolkit, string specifiedPath) + private DirectoryInfo InteractivelyGetInstallPath(ModToolkit toolkit, InstallerContext context, string specifiedPath) { - // get executable name - string executableFilename = EnvironmentUtility.GetExecutableName(platform); - - // validate specified path + // use specified path if (specifiedPath != null) { var dir = new DirectoryInfo(specifiedPath); @@ -704,7 +655,7 @@ namespace StardewModdingApi.Installer this.PrintError($"You specified --game-path \"{specifiedPath}\", but that folder doesn't exist."); return null; } - if (!dir.EnumerateFiles(executableFilename).Any()) + if (!context.LooksLikeGameFolder(dir)) { this.PrintError($"You specified --game-path \"{specifiedPath}\", but that folder doesn't contain the Stardew Valley executable."); return null; @@ -712,7 +663,19 @@ namespace StardewModdingApi.Installer return dir; } - // get installed paths + // use game folder which contains the installer, if any + { + DirectoryInfo curPath = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory; + while (curPath?.Parent != null) // must be in a folder (not at the root) + { + if (context.LooksLikeGameFolder(curPath)) + return curPath; + + curPath = curPath.Parent; + } + } + + // use an installed path DirectoryInfo[] defaultPaths = toolkit.GetGameFolders().ToArray(); if (defaultPaths.Any()) { @@ -738,7 +701,7 @@ namespace StardewModdingApi.Installer while (true) { // get path from user - this.PrintInfo($"Type the file path to the game directory (the one containing '{executableFilename}'), then press enter."); + this.PrintInfo($"Type the file path to the game directory (the one containing '{context.ExecutableName}'), then press enter."); string path = Console.ReadLine()?.Trim(); if (string.IsNullOrWhiteSpace(path)) { @@ -747,10 +710,9 @@ namespace StardewModdingApi.Installer } // normalize path - if (platform == Platform.Windows) - path = path.Replace("\"", ""); // in Windows, quotes are used to escape spaces and aren't part of the file path - if (platform == Platform.Linux || platform == Platform.Mac) - path = path.Replace("\\ ", " "); // in Linux/Mac, spaces in paths may be escaped if copied from the command line + path = context.IsWindows + ? path.Replace("\"", "") // in Windows, quotes are used to escape spaces and aren't part of the file path + : path.Replace("\\ ", " "); // in Linux/Mac, spaces in paths may be escaped if copied from the command line if (path.StartsWith("~/")) { string home = Environment.GetEnvironmentVariable("HOME") ?? Environment.GetEnvironmentVariable("USERPROFILE"); @@ -768,7 +730,7 @@ namespace StardewModdingApi.Installer this.PrintInfo(" That directory doesn't seem to exist."); continue; } - if (!directory.EnumerateFiles(executableFilename).Any()) + if (!context.LooksLikeGameFolder(directory)) { this.PrintInfo(" That directory doesn't contain a Stardew Valley executable."); continue; |