예제 #1
0
        public void SetCurrentInstanceByPath(string path)
        {
            var matchingGames = knownGames
                                .Where(g => g.GameInFolder(new DirectoryInfo(path)))
                                .ToList();

            switch (matchingGames.Count)
            {
            case 0:
                throw new NotKSPDirKraken(path);

            case 1:
                GameInstance ksp = new GameInstance(
                    matchingGames.First(), path, "custom", User);
                if (ksp.Valid)
                {
                    CurrentInstance = ksp;
                }
                else
                {
                    throw new NotKSPDirKraken(ksp.GameDir());
                }
                break;

            default:
                // TODO: Prompt user to choose
                break;
            }
        }
        private string[] rowItems(GameInstance instance, bool includeGame, bool includePlayTime)
        {
            var list = new List <string>
            {
                !instance.Valid
                    ? string.Format(Properties.Resources.ManageGameInstancesNameColumnInvalid, instance.Name)
                    : !(_manager.CurrentInstance?.Equals(instance) ?? false) && instance.IsMaybeLocked
                        ? string.Format(Properties.Resources.ManageGameInstancesNameColumnLocked, instance.Name)
                        : instance.Name
            };

            if (includeGame)
            {
                list.Add(instance.game.ShortName);
            }

            list.Add(FormatVersion(instance.Version()));

            if (includePlayTime)
            {
                list.Add(instance.playTime?.ToString() ?? "");
            }

            list.Add(instance.GameDir().Replace('/', Path.DirectorySeparatorChar));
            return(list.ToArray());
        }
예제 #3
0
        /// <summary>
        /// Clones an existing KSP installation.
        /// </summary>
        /// <param name="existingInstance">The KSP instance to clone.</param>
        /// <param name="newName">The name for the new instance.</param>
        /// <param name="newPath">The path where the new instance should be located.</param>
        /// <exception cref="InstanceNameTakenKraken">Thrown if the instance name is already in use.</exception>
        /// <exception cref="NotKSPDirKraken">Thrown by AddInstance() if created instance is not valid, e.g. if something went wrong with copying.</exception>
        /// <exception cref="DirectoryNotFoundKraken">Thrown by CopyDirectory() if directory doesn't exist. Should never be thrown here.</exception>
        /// <exception cref="PathErrorKraken">Thrown by CopyDirectory() if the target folder already exists and is not empty.</exception>
        /// <exception cref="IOException">Thrown by CopyDirectory() if something goes wrong during the process.</exception>
        public void CloneInstance(GameInstance existingInstance, string newName, string newPath)
        {
            if (HasInstance(newName))
            {
                throw new InstanceNameTakenKraken(newName);
            }
            if (!existingInstance.Valid)
            {
                throw new NotKSPDirKraken(existingInstance.GameDir(), "The specified instance is not a valid KSP instance.");
            }

            log.Debug("Copying directory.");
            Utilities.CopyDirectory(existingInstance.GameDir(), newPath, true);

            // Add the new instance to the config
            GameInstance new_instance = new GameInstance(existingInstance.game, newPath, newName, User);

            AddInstance(new_instance);
        }
예제 #4
0
 private static string FindDownloadsPath(GameInstance gameInst)
 {
     foreach (string p in downloadPaths)
     {
         if (!string.IsNullOrEmpty(p) && Directory.Exists(p))
         {
             return(p);
         }
     }
     return(gameInst.GameDir());
 }
예제 #5
0
 /// <summary>
 /// Adds a KSP instance to config.
 /// Returns the resulting KSP object.
 /// </summary>
 public GameInstance AddInstance(GameInstance ksp_instance)
 {
     if (ksp_instance.Valid)
     {
         string name = ksp_instance.Name;
         instances.Add(name, ksp_instance);
         Configuration.SetRegistryToInstances(instances);
     }
     else
     {
         throw new NotKSPDirKraken(ksp_instance.GameDir());
     }
     return(ksp_instance);
 }
예제 #6
0
        public void IsGameDir()
        {
            var game = new KerbalSpaceProgram();

            // Our test data directory should be good.
            Assert.IsTrue(game.GameInFolder(new DirectoryInfo(TestData.good_ksp_dir())));

            // As should our copied folder.
            Assert.IsTrue(game.GameInFolder(new DirectoryInfo(ksp_dir)));

            // And the one from our KSP instance.
            Assert.IsTrue(game.GameInFolder(new DirectoryInfo(ksp.GameDir())));

            // All these ones should be bad.
            foreach (string dir in TestData.bad_ksp_dirs())
            {
                Assert.IsFalse(game.GameInFolder(new DirectoryInfo(dir)));
            }
        }
        /// <summary>
        /// Initialize the compatible game versions dialog
        /// </summary>
        /// <param name="inst">Game instance</param>
        /// <param name="centerScreen">true to center the dialog on the screen, false to center on the parent</param>
        public CompatibleGameVersionsDialog(GameInstance inst, bool centerScreen)
        {
            this._inst = inst;
            InitializeComponent();

            if (centerScreen)
            {
                StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            }

            List <GameVersion> compatibleVersions = inst.GetCompatibleVersions();

            GameVersionLabel.Text  = inst.Version()?.ToString() ?? Properties.Resources.CompatibleGameVersionsDialogNone;
            GameLocationLabel.Text = inst.GameDir().Replace('/', Path.DirectorySeparatorChar);
            List <GameVersion> knownVersions                = inst.game.KnownVersions;
            List <GameVersion> majorVersionsList            = CreateMajorVersionsList(knownVersions);
            List <GameVersion> compatibleVersionsLeftOthers = new List <GameVersion>(compatibleVersions);

            compatibleVersionsLeftOthers.RemoveAll((el) => knownVersions.Contains(el) || majorVersionsList.Contains(el));

            SortAndAddVersionsToList(compatibleVersionsLeftOthers, compatibleVersions);
            SortAndAddVersionsToList(majorVersionsList, compatibleVersions);
            SortAndAddVersionsToList(knownVersions, compatibleVersions);
        }
예제 #8
0
        /// <summary>
        /// User is done. Start cloning or faking, depending on the clicked radio button.
        /// Close the window if everything went right.
        /// </summary>
        private async void buttonOK_Click(object sender, EventArgs e)
        {
            string newName = textBoxNewName.Text;
            string newPath = textBoxNewPath.Text;

            // Do some basic checks.
            if (String.IsNullOrWhiteSpace(newName))
            {
                user.RaiseError(Properties.Resources.CloneFakeKspDialogEnterName);
                return;
            }
            if (String.IsNullOrWhiteSpace(newPath))
            {
                user.RaiseError(Properties.Resources.CloneFakeKspDialogEnterPath);
                return;
            }

            // Show progress bar and deactivate controls.
            progressBar.Style = ProgressBarStyle.Marquee;
            progressBar.Show();
            foreach (Control ctrl in this.Controls)
            {
                ctrl.Enabled = false;
            }

            // Clone the specified instance.
            // Done in a new task to not block the GUI thread.
            if (radioButtonClone.Checked)
            {
                user.RaiseMessage(Properties.Resources.CloneFakeKspDialogCloningInstance);

                try
                {
                    await Task.Run(() =>
                    {
                        GameInstance sourceInstance = manager.Instances.Values
                                                      .FirstOrDefault(i => i.GameDir() == textBoxClonePath.Text);
                        GameInstance instanceToClone = new GameInstance(
                            sourceInstance.game,
                            textBoxClonePath.Text,
                            "irrelevant",
                            user
                            );

                        if (instanceToClone.Valid)
                        {
                            manager.CloneInstance(instanceToClone, newName, newPath);
                        }
                        else
                        {
                            throw new NotKSPDirKraken(instanceToClone.GameDir());
                        }
                    });
                }
                catch (InstanceNameTakenKraken)
                {
                    user.RaiseError(Properties.Resources.CloneFakeKspDialogNameAlreadyUsed);
                    reactivateDialog();
                    return;
                }
                catch (NotKSPDirKraken kraken)
                {
                    user.RaiseError(string.Format(Properties.Resources.CloneFakeKspDialogInstanceNotValid, kraken.path));
                    reactivateDialog();
                    return;
                }
                catch (PathErrorKraken kraken)
                {
                    user.RaiseError(string.Format(Properties.Resources.CloneFakeKspDialogDestinationNotEmpty, kraken.path));
                    reactivateDialog();
                    return;
                }
                catch (IOException ex)
                {
                    user.RaiseError(string.Format(Properties.Resources.CloneFakeKspDialogCloneFailed, ex.Message));
                    reactivateDialog();
                    return;
                }
                catch (Exception ex)
                {
                    user.RaiseError(string.Format(Properties.Resources.CloneFakeKspDialogCloneFailed, ex.Message));
                    reactivateDialog();
                    return;
                }

                if (checkBoxSetAsDefault.Checked)
                {
                    manager.SetAutoStart(newName);
                }

                if (checkBoxSwitchInstance.Checked)
                {
                    manager.SetCurrentInstance(newName);
                }

                user.RaiseMessage(Properties.Resources.CloneFakeKspDialogSuccessfulClone);

                DialogResult = DialogResult.OK;
                this.Close();
            }

            // Create a new dummy instance.
            // Also in a separate task.
            else if (radioButtonFake.Checked)
            {
                GameVersion GameVersion = GameVersion.Parse(comboBoxGameVersion.Text);

                Dictionary <DLC.IDlcDetector, GameVersion> dlcs = new Dictionary <DLC.IDlcDetector, GameVersion>();
                if (!String.IsNullOrWhiteSpace(textBoxMHDlcVersion.Text) && textBoxMHDlcVersion.Text.ToLower() != "none")
                {
                    if (GameVersion.TryParse(textBoxMHDlcVersion.Text, out GameVersion ver))
                    {
                        dlcs.Add(new DLC.MakingHistoryDlcDetector(), ver);
                    }
                    else
                    {
                        user.RaiseError(Properties.Resources.CloneFakeKspDialogDlcVersionMalformatted, "Making History");
                        reactivateDialog();
                        return;
                    }
                }
                if (!String.IsNullOrWhiteSpace(textBoxBGDlcVersion.Text) && textBoxBGDlcVersion.Text.ToLower() != "none")
                {
                    if (GameVersion.TryParse(textBoxBGDlcVersion.Text, out GameVersion ver))
                    {
                        dlcs.Add(new DLC.BreakingGroundDlcDetector(), ver);
                    }
                    else
                    {
                        user.RaiseError(Properties.Resources.CloneFakeKspDialogDlcVersionMalformatted, "Breaking Ground");
                        reactivateDialog();
                        return;
                    }
                }

                user.RaiseMessage(Properties.Resources.CloneFakeKspDialogCreatingInstance);

                try
                {
                    await Task.Run(() =>
                    {
                        manager.FakeInstance(new KerbalSpaceProgram(), newName, newPath, GameVersion, dlcs);
                    });
                }
                catch (InstanceNameTakenKraken)
                {
                    user.RaiseError(Properties.Resources.CloneFakeKspDialogNameAlreadyUsed);
                    reactivateDialog();
                    return;
                }
                catch (BadInstallLocationKraken)
                {
                    user.RaiseError(Properties.Resources.CloneFakeKspDialogDestinationNotEmpty, newPath);
                    reactivateDialog();
                    return;
                }
                catch (Exception ex)
                {
                    user.RaiseError(string.Format(Properties.Resources.CloneFakeKspDialogFakeFailed, ex.Message));
                    reactivateDialog();
                    return;
                }

                if (checkBoxSetAsDefault.Checked)
                {
                    manager.SetAutoStart(newName);
                }

                if (checkBoxSwitchInstance.Checked)
                {
                    manager.SetCurrentInstance(newName);
                }

                user.RaiseMessage(Properties.Resources.CloneFakeKspDialogSuccessfulCreate);

                DialogResult = DialogResult.OK;
                this.Close();
            }
        }
예제 #9
0
        /// <summary>
        /// Given an open zipfile, returns all files that would be installed
        /// for this stanza.
        ///
        /// If a KSP instance is provided, it will be used to generate output paths, otherwise these will be null.
        ///
        /// Throws a BadInstallLocationKraken if the install stanza targets an
        /// unknown install location (eg: not GameData, Ships, etc)
        ///
        /// Throws a BadMetadataKraken if the stanza resulted in no files being returned.
        /// </summary>
        /// <exception cref="BadInstallLocationKraken">Thrown when the installation path is not valid according to the spec.</exception>
        public List <InstallableFile> FindInstallableFiles(ZipFile zipfile, GameInstance ksp)
        {
            string installDir;
            var    files = new List <InstallableFile>();

            // Normalize the path before doing everything else
            string install_to = CKANPathUtils.NormalizePath(this.install_to);

            // The installation path cannot contain updirs
            if (install_to.Contains("/../") || install_to.EndsWith("/.."))
            {
                throw new BadInstallLocationKraken("Invalid installation path: " + install_to);
            }

            if (ksp == null)
            {
                installDir = null;
            }
            else if (install_to == ksp.game.PrimaryModDirectoryRelative ||
                     install_to.StartsWith($"{ksp.game.PrimaryModDirectoryRelative}/"))
            {
                // The installation path can be either "GameData" or a sub-directory of "GameData"
                string subDir = install_to.Substring(ksp.game.PrimaryModDirectoryRelative.Length); // remove "GameData"
                subDir = subDir.StartsWith("/") ? subDir.Substring(1) : subDir;                    // remove a "/" at the beginning, if present

                // Add the extracted subdirectory to the path of KSP's GameData
                installDir = CKANPathUtils.NormalizePath(ksp.game.PrimaryModDirectory(ksp) + "/" + subDir);
            }
            else
            {
                switch (install_to)
                {
                case "GameRoot":
                    installDir = ksp.GameDir();
                    break;

                default:
                    if (ksp.game.AllowInstallationIn(install_to, out string path))
                    {
                        installDir = ksp.ToAbsoluteGameDir(path);
                    }
                    else
                    {
                        throw new BadInstallLocationKraken("Unknown install_to " + install_to);
                    }
                    break;
                }
            }

            EnsurePattern();

            // `find` is supposed to match the "topmost" folder. Find it.
            var shortestMatch = find == null ? (int?)null
                : zipfile.Cast <ZipEntry>()
                                .Select(entry => inst_pattern.Match(entry.Name.Replace('\\', '/')))
                                .Where(match => match.Success)
                                .DefaultIfEmpty()
                                .Min(match => match?.Index);

            // O(N^2) solution, as we're walking the zipfile for each stanza.
            // Surely there's a better way, although this is fast enough we may not care.
            foreach (ZipEntry entry in zipfile)
            {
                // Skips dirs and things not prescribed by our install stanza.
                if (!IsWanted(entry.Name, shortestMatch))
                {
                    continue;
                }

                // Prepare our file info.
                InstallableFile file_info = new InstallableFile
                {
                    source      = entry,
                    makedir     = false,
                    destination = null
                };

                // If we have a place to install it, fill that in...
                if (installDir != null)
                {
                    // Get the full name of the file.
                    // Update our file info with the install location
                    file_info.destination = TransformOutputName(
                        ksp.game, entry.Name, installDir, @as);
                    file_info.makedir = AllowDirectoryCreation(
                        ksp.game,
                        ksp?.ToRelativeGameDir(file_info.destination)
                        ?? file_info.destination);
                }

                files.Add(file_info);
            }

            // If we have no files, then something is wrong! (KSP-CKAN/CKAN#93)
            if (files.Count == 0)
            {
                // We have null as the first argument here, because we don't know which module we're installing
                throw new BadMetadataKraken(null, String.Format("No files found matching {0} to install!", DescribeMatch()));
            }

            return(files);
        }