Esempio n. 1
0
File: KSP.cs Progetto: yixi435/CKAN
 public string Ships()
 {
     return(KSPPathUtils.NormalizePath(
                Path.Combine(GameDir(), "Ships")
                ));
 }
Esempio n. 2
0
File: KSP.cs Progetto: yixi435/CKAN
 public string ShipsSph()
 {
     return(KSPPathUtils.NormalizePath(
                Path.Combine(Ships(), "SPH")
                ));
 }
Esempio n. 3
0
File: KSP.cs Progetto: yixi435/CKAN
 public string InstallHistoryDir()
 {
     return(KSPPathUtils.NormalizePath(
                Path.Combine(CkanDir(), "history")
                ));
 }
Esempio n. 4
0
File: KSP.cs Progetto: yixi435/CKAN
 public string Missions()
 {
     return(KSPPathUtils.NormalizePath(
                Path.Combine(GameDir(), "Missions")
                ));
 }
Esempio n. 5
0
File: KSP.cs Progetto: yixi435/CKAN
 public string GameData()
 {
     return(KSPPathUtils.NormalizePath(
                Path.Combine(GameDir(), "GameData")
                ));
 }
Esempio n. 6
0
File: KSP.cs Progetto: yixi435/CKAN
 public string DownloadCacheDir()
 {
     return(KSPPathUtils.NormalizePath(
                Path.Combine(CkanDir(), "downloads")
                ));
 }
Esempio n. 7
0
 /// <summary>
 /// Returns path relative to this KSP's GameDir.
 /// </summary>
 public string ToRelativeGameDir(string path)
 {
     return(KSPPathUtils.ToRelative(path, GameDir()));
 }
Esempio n. 8
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, KSP ksp)
        {
            string installDir;
            bool   makeDirs;
            var    files = new List <InstallableFile>();

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

            if (install_to == "GameData" || install_to.StartsWith("GameData/"))
            {
                // The installation path can be either "GameData" or a sub-directory of "GameData"
                // but it cannot contain updirs
                if (install_to.Contains("/../") || install_to.EndsWith("/.."))
                {
                    throw new BadInstallLocationKraken("Invalid installation path: " + install_to);
                }

                string subDir = install_to.Substring("GameData".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 = ksp == null ? null : (KSPPathUtils.NormalizePath(ksp.GameData() + "/" + subDir));
                makeDirs   = true;
            }
            else if (install_to.StartsWith("Ships"))
            {
                // Don't allow directory creation in ships directory
                makeDirs = false;

                switch (install_to)
                {
                case "Ships":
                    installDir = ksp?.Ships();
                    break;

                case "Ships/VAB":
                    installDir = ksp?.ShipsVab();
                    break;

                case "Ships/SPH":
                    installDir = ksp?.ShipsSph();
                    break;

                case "Ships/@thumbs":
                    installDir = ksp?.ShipsThumbs();
                    break;

                case "Ships/@thumbs/VAB":
                    installDir = ksp?.ShipsThumbsVAB();
                    break;

                case "Ships/@thumbs/SPH":
                    installDir = ksp?.ShipsThumbsSPH();
                    break;

                default:
                    throw new BadInstallLocationKraken("Unknown install_to " + install_to);
                }
            }
            else
            {
                switch (install_to)
                {
                case "Tutorial":
                    installDir = ksp?.Tutorial();
                    makeDirs   = true;
                    break;

                case "Scenarios":
                    installDir = ksp?.Scenarios();
                    makeDirs   = true;
                    break;

                case "Missions":
                    installDir = ksp?.Missions();
                    makeDirs   = true;
                    break;

                case "GameRoot":
                    installDir = ksp?.GameDir();
                    makeDirs   = false;
                    break;

                default:
                    throw new BadInstallLocationKraken("Unknown install_to " + install_to);
                }
            }

            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     = makeDirs,
                    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(
                        entry.Name, installDir, @as);
                }

                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);
        }
Esempio n. 9
0
 public string Scenarios()
 {
     return(KSPPathUtils.NormalizePath(
                Path.Combine(GameDir(), "saves", "scenarios")
                ));
 }
Esempio n. 10
0
 public string TempDir()
 {
     return(KSPPathUtils.NormalizePath(
                Path.Combine(CkanDir(), "temp")
                ));
 }
Esempio n. 11
0
        /// <summary>
        /// Given a stanza and 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>
        internal static List <InstallableFile> FindInstallableFiles(ModuleInstallDescriptor stanza, ZipFile zipfile, KSP ksp)
        {
            string installDir;
            bool   makeDirs;
            var    files = new List <InstallableFile> ();

            // Normalize the path before doing everything else
            // TODO: This really should happen in the ModuleInstallDescriptor itself.
            stanza.install_to = KSPPathUtils.NormalizePath(stanza.install_to);

            // Convert our stanza to a standard `file` type. This is a no-op if it's
            // already the basic type.

            stanza = stanza.ConvertFindToFile(zipfile);

            if (stanza.install_to == "GameData" || stanza.install_to.StartsWith("GameData/"))
            {
                // The installation path can be either "GameData" or a sub-directory of "GameData"
                // but it cannot contain updirs
                if (stanza.install_to.Contains("/../") || stanza.install_to.EndsWith("/.."))
                {
                    throw new BadInstallLocationKraken("Invalid installation path: " + stanza.install_to);
                }

                string subDir = stanza.install_to.Substring("GameData".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 = ksp == null ? null : (KSPPathUtils.NormalizePath(ksp.GameData() + "/" + subDir));
                makeDirs   = true;
            }
            else if (stanza.install_to.StartsWith("Ships"))
            {
                // Don't allow directory creation in ships directory
                makeDirs = false;

                switch (stanza.install_to)
                {
                case "Ships":
                    installDir = ksp == null ? null : ksp.Ships();
                    break;

                case "Ships/VAB":
                    installDir = ksp == null ? null : ksp.ShipsVab();
                    break;

                case "Ships/SPH":
                    installDir = ksp == null ? null : ksp.ShipsSph();
                    break;

                case "Ships/@thumbs":
                    installDir = ksp == null ? null : ksp.ShipsThumbs();
                    break;

                case "Ships/@thumbs/VAB":
                    installDir = ksp == null ? null : ksp.ShipsThumbsVAB();
                    break;

                case "Ships/@thumbs/SPH":
                    installDir = ksp == null ? null : ksp.ShipsThumbsSPH();
                    break;

                default:
                    throw new BadInstallLocationKraken("Unknown install_to " + stanza.install_to);
                }
            }
            else
            {
                switch (stanza.install_to)
                {
                case "Tutorial":
                    installDir = ksp == null ? null : ksp.Tutorial();
                    makeDirs   = true;
                    break;

                case "Scenarios":
                    installDir = ksp == null ? null : ksp.Scenarios();
                    makeDirs   = true;
                    break;

                case "GameRoot":
                    installDir = ksp == null ? null : ksp.GameDir();
                    makeDirs   = false;
                    break;

                default:
                    throw new BadInstallLocationKraken("Unknown install_to " + stanza.install_to);
                }
            }

            // 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 things not prescribed by our install stanza.
                if (!stanza.IsWanted(entry.Name))
                {
                    continue;
                }

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

                // If we have a place to install it, fill that in...
                if (installDir != null)
                {
                    // Get the full name of the file.
                    string outputName = entry.Name;

                    // Update our file info with the install location
                    file_info.destination = TransformOutputName(stanza.file, outputName, installDir);
                }

                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 in {0} to install!", stanza.file));
            }

            return(files);
        }
Esempio n. 12
0
        private void DeSerialisationFixes(StreamingContext context)
        {
            // Our context is our KSP install.
            KSP ksp = (KSP)context.Context;


            // Older registries didn't have the installed_files list, so we create one
            // if absent.

            if (installed_files == null)
            {
                log.Warn("Older registry format detected, adding installed files manifest...");
                ReindexInstalled();
            }

            // If we have no registry version at all, then we're from the pre-release period.
            // We would check for a null here, but ints *can't* be null.
            if (registry_version == 0)
            {
                log.Warn("Older registry format detected, normalising paths...");

                var normalised_installed_files = new Dictionary <string, string>();

                foreach (KeyValuePair <string, string> tuple in installed_files)
                {
                    string path = KSPPathUtils.NormalizePath(tuple.Key);

                    if (Path.IsPathRooted(path))
                    {
                        path = ksp.ToRelativeGameDir(path);
                        normalised_installed_files[path] = tuple.Value;
                    }
                    else
                    {
                        // Already relative.
                        normalised_installed_files[path] = tuple.Value;
                    }
                }

                installed_files = normalised_installed_files;

                // Now update all our module file manifests.

                foreach (InstalledModule module in installed_modules.Values)
                {
                    module.Renormalise(ksp);
                }

                // Our installed dlls have contained relative paths since forever,
                // and the next `ckan scan` will fix them anyway. (We can't scan here,
                // because that needs a registry, and we chicken-egg.)

                log.Warn("Registry upgrade complete");
            }

            // Fix control lock, which previously was indexed with an invalid identifier.
            if (registry_version < 2)
            {
                InstalledModule control_lock_entry;
                const string    old_ident = "001ControlLock";
                const string    new_ident = "ControlLock";

                if (installed_modules.TryGetValue("001ControlLock", out control_lock_entry))
                {
                    if (ksp == null)
                    {
                        throw new Kraken("Internal bug: No KSP instance provided on registry deserialisation");
                    }

                    log.WarnFormat("Older registry detected. Reindexing {0} as {1}. This may take a moment.", old_ident, new_ident);

                    // Remove old record.
                    installed_modules.Remove(old_ident);

                    // Extract the old module metadata
                    CkanModule control_lock_mod = control_lock_entry.Module;

                    // Change to the correct ident.
                    control_lock_mod.identifier = new_ident;

                    // Prepare to re-index.
                    var new_control_lock_installed = new InstalledModule(
                        ksp,
                        control_lock_mod,
                        control_lock_entry.Files
                        );

                    // Re-insert into registry.
                    installed_modules[new_control_lock_installed.identifier] = new_control_lock_installed;

                    // Re-index files.
                    ReindexInstalled();
                }
            }

            // If we spot a default repo with the old .zip URL, flip it to the new .tar.gz URL
            // Any other repo we leave *as-is*, even if it's the github meta-repo, as it's been
            // custom-added by our user.

            Repository default_repo;
            var        oldDefaultRepo = new Uri("https://github.com/KSP-CKAN/CKAN-meta/archive/master.zip");

            if (repositories != null && repositories.TryGetValue(Repository.default_ckan_repo_name, out default_repo) && default_repo.uri == oldDefaultRepo)
            {
                log.InfoFormat("Updating default metadata URL from {0} to {1}", oldDefaultRepo, Repository.default_ckan_repo_uri);
                repositories["default"].uri = Repository.default_ckan_repo_uri;
            }

            registry_version = LATEST_REGISTRY_VERSION;
        }
Esempio n. 13
0
 public string CkanDir()
 {
     return(KSPPathUtils.NormalizePath(
                Path.Combine(GameDir(), "CKAN")
                ));
 }
Esempio n. 14
0
File: KSP.cs Progetto: yixi435/CKAN
 public string ShipsThumbsVAB()
 {
     return(KSPPathUtils.NormalizePath(
                Path.Combine(ShipsThumbs(), "VAB")
                ));
 }
Esempio n. 15
0
 /// <summary>
 /// Given a path relative to this KSP's GameDir, returns the
 /// absolute path on the system.
 /// </summary>
 public string ToAbsoluteGameDir(string path)
 {
     return(KSPPathUtils.ToAbsolute(path, GameDir()));
 }
Esempio n. 16
0
File: KSP.cs Progetto: yixi435/CKAN
 public string Tutorial()
 {
     return(KSPPathUtils.NormalizePath(
                Path.Combine(GameDir(), "saves", "training")
                ));
 }
Esempio n. 17
0
 /// <summary>
 /// Compare two install stanzas
 /// </summary>
 /// <param name="other">The other stanza for comparison</param>
 /// <returns>
 /// True if they're equivalent, false if they're different.
 /// IEquatable<> uses this for more efficient comparisons.
 /// </returns>
 public bool Equals(ModuleInstallDescriptor otherStanza)
 {
     if (otherStanza == null)
     {
         // Not even the right type!
         return(false);
     }
     if (KSPPathUtils.NormalizePath(file) != KSPPathUtils.NormalizePath(otherStanza.file))
     {
         return(false);
     }
     if (KSPPathUtils.NormalizePath(find) != KSPPathUtils.NormalizePath(otherStanza.find))
     {
         return(false);
     }
     if (find_regexp != otherStanza.find_regexp)
     {
         return(false);
     }
     if (KSPPathUtils.NormalizePath(install_to) != KSPPathUtils.NormalizePath(otherStanza.install_to))
     {
         return(false);
     }
     if (@as != otherStanza.@as)
     {
         return(false);
     }
     if ((filter == null) != (otherStanza.filter == null))
     {
         return(false);
     }
     if (filter != null &&
         !filter.SequenceEqual(otherStanza.filter))
     {
         return(false);
     }
     if ((filter_regexp == null) != (otherStanza.filter_regexp == null))
     {
         return(false);
     }
     if (filter_regexp != null &&
         !filter_regexp.SequenceEqual(otherStanza.filter_regexp))
     {
         return(false);
     }
     if (find_matches_files != otherStanza.find_matches_files)
     {
         return(false);
     }
     if ((include_only == null) != (otherStanza.include_only == null))
     {
         return(false);
     }
     if (include_only != null &&
         !include_only.SequenceEqual(otherStanza.include_only))
     {
         return(false);
     }
     if ((include_only_regexp == null) != (otherStanza.include_only_regexp == null))
     {
         return(false);
     }
     if (include_only_regexp != null &&
         !include_only_regexp.SequenceEqual(otherStanza.include_only_regexp))
     {
         return(false);
     }
     return(true);
 }