Ejemplo n.º 1
0
        /// <summary>Get the possible game paths to update.</summary>
        /// <param name="toolkit">The mod toolkit.</param>
        /// <param name="context">The installer context.</param>
        private IEnumerable <DirectoryInfo> DetectGameFolders(ModToolkit toolkit, InstallerContext context)
        {
            HashSet <string> foundPaths = new HashSet <string>();

            // 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))
                    {
                        foundPaths.Add(curPath.FullName);
                        yield return(curPath);

                        break;
                    }

                    curPath = curPath.Parent;
                }
            }

            // game paths detected by toolkit
            foreach (DirectoryInfo dir in toolkit.GetGameFolders())
            {
                if (foundPaths.Add(dir.FullName))
                {
                    yield return(dir);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>Interactively locate the game install path to update.</summary>
        /// <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(ModToolkit toolkit, InstallerContext context, string specifiedPath)
        {
            // use specified path
            if (specifiedPath != null)
            {
                var dir = new DirectoryInfo(specifiedPath);
                if (!dir.Exists)
                {
                    this.PrintError($"You specified --game-path \"{specifiedPath}\", but that folder doesn't exist.");
                    return(null);
                }
                if (!context.LooksLikeGameFolder(dir))
                {
                    this.PrintError($"You specified --game-path \"{specifiedPath}\", but that folder doesn't contain the Stardew Valley executable.");
                    return(null);
                }
                return(dir);
            }

            // 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())
            {
                // only one path
                if (defaultPaths.Length == 1)
                {
                    return(defaultPaths.First());
                }

                // let user choose path
                Console.WriteLine();
                this.PrintInfo("Found multiple copies of the game:");
                for (int i = 0; i < defaultPaths.Length; i++)
                {
                    this.PrintInfo($"[{i + 1}] {defaultPaths[i].FullName}");
                }
                Console.WriteLine();

                string[] validOptions = Enumerable.Range(1, defaultPaths.Length).Select(p => p.ToString(CultureInfo.InvariantCulture)).ToArray();
                string   choice       = this.InteractivelyChoose("Where do you want to add/remove SMAPI? Type the number next to your choice, then press enter.", validOptions);
                int      index        = int.Parse(choice, CultureInfo.InvariantCulture) - 1;
                return(defaultPaths[index]);
            }

            // ask user
            this.PrintInfo("Oops, couldn't find the game automatically.");
            while (true)
            {
                // get path from user
                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))
                {
                    this.PrintInfo("   You must specify a directory path to continue.");
                    continue;
                }

                // normalize path
                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");
                    path = Path.Combine(home, path.Substring(2));
                }

                // get directory
                if (File.Exists(path))
                {
                    path = Path.GetDirectoryName(path);
                }
                DirectoryInfo directory = new DirectoryInfo(path);

                // validate path
                if (!directory.Exists)
                {
                    this.PrintInfo("   That directory doesn't seem to exist.");
                    continue;
                }
                if (!context.LooksLikeGameFolder(directory))
                {
                    this.PrintInfo("   That directory doesn't contain a Stardew Valley executable.");
                    continue;
                }

                // looks OK
                this.PrintInfo("   OK!");
                return(directory);
            }
        }
Ejemplo n.º 3
0
        /// <summary>Interactively locate the game install path to update.</summary>
        /// <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(ModToolkit toolkit, InstallerContext context, string specifiedPath)
        {
            // use specified path
            if (specifiedPath != null)
            {
                var dir = new DirectoryInfo(specifiedPath);
                if (!dir.Exists)
                {
                    this.PrintError($"You specified --game-path \"{specifiedPath}\", but that folder doesn't exist.");
                    return(null);
                }
                if (!context.LooksLikeGameFolder(dir))
                {
                    this.PrintError($"You specified --game-path \"{specifiedPath}\", but that folder doesn't contain the Secrets of Grindea executable.");
                    return(null);
                }
                return(dir);
            }

            // let user choose detected path
            DirectoryInfo[] defaultPaths = this.DetectGameFolders(toolkit, context).ToArray();
            if (defaultPaths.Any())
            {
                this.PrintInfo("Where do you want to add or remove SoGMAPI?");
                Console.WriteLine();
                for (int i = 0; i < defaultPaths.Length; i++)
                {
                    this.PrintInfo($"[{i + 1}] {defaultPaths[i].FullName}");
                }
                this.PrintInfo($"[{defaultPaths.Length + 1}] Enter a custom game path.");
                Console.WriteLine();

                string[] validOptions = Enumerable.Range(1, defaultPaths.Length + 1).Select(p => p.ToString(CultureInfo.InvariantCulture)).ToArray();
                string   choice       = this.InteractivelyChoose("Type the number next to your choice, then press enter.", validOptions);
                int      index        = int.Parse(choice, CultureInfo.InvariantCulture) - 1;

                if (index < defaultPaths.Length)
                {
                    return(defaultPaths[index]);
                }
            }
            else
            {
                this.PrintInfo("Oops, couldn't find the game automatically.");
            }

            // let user enter manual path
            while (true)
            {
                // get path from user
                Console.WriteLine();
                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))
                {
                    this.PrintWarning("You must specify a directory path to continue.");
                    continue;
                }

                // normalize path
                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/macOS, spaces in paths may be escaped if copied from the command line
                if (path.StartsWith("~/"))
                {
                    string home = Environment.GetEnvironmentVariable("HOME") ?? Environment.GetEnvironmentVariable("USERPROFILE");
                    path = Path.Combine(home, path.Substring(2));
                }

                // get directory
                if (File.Exists(path))
                {
                    path = Path.GetDirectoryName(path);
                }
                DirectoryInfo directory = new DirectoryInfo(path);

                // validate path
                if (!directory.Exists)
                {
                    this.PrintWarning("That directory doesn't seem to exist.");
                    continue;
                }
                if (!context.LooksLikeGameFolder(directory))
                {
                    this.PrintWarning("That directory doesn't contain a Secrets of Grindea executable.");
                    continue;
                }

                // looks OK
                this.PrintInfo("   OK!");
                return(directory);
            }
        }