Exemple #1
0
        public void ScanDlls()
        {
            string pathDir = Path.Combine(ksp.Mods(), "Example-0.1.0");

            Directory.CreateDirectory(pathDir);
            string infoJsonDir = Path.Combine(pathDir, "info.json");

            Assert.IsFalse(ksp.Registry.IsInstalled("Example"), "Example should start uninstalled");

            File.WriteAllText(infoJsonDir, @"{""name"":""Example"",""version"":""0.1.0"",""title"":""SomeTitle"",""author"":""someAuthor"",""contact"":""*****@*****.**"",""homepage"":""http://example.com"",""description"":""someDescription"",""dependencies"":[]}");

            ksp.ScanGameData();

            Assert.IsTrue(ksp.Registry.IsInstalled("Example"), "Example installed");

            AbstractVersion version = ksp.Registry.InstalledVersion("Example");

            Assert.IsInstanceOf <AutodetectedVersion>(version, "DLL detected as a DLL, not full mod");

            // Now let's do the same with different case.
            pathDir = Path.Combine(ksp.Mods(), "NewMod-0.1.0");
            Directory.CreateDirectory(pathDir);
            infoJsonDir = Path.Combine(pathDir, "info.json");
            File.WriteAllText(infoJsonDir, @"{""name"":""NewMod"",""version"":""0.1.0"",""title"":""SomeTitle"",""author"":""someAuthor"",""contact"":""*****@*****.**"",""homepage"":""http://example.com"",""description"":""someDescription"",""dependencies"":[]}");

            Assert.IsFalse(ksp.Registry.IsInstalled("NewMod"));

            ksp.ScanGameData();

            Assert.IsTrue(ksp.Registry.IsInstalled("NewMod"));
        }
Exemple #2
0
        /// <summary>
        /// <see cref = "IRegistryQuerier.Installed" />
        /// </summary>
        public Dictionary <string, AbstractVersion> Installed(bool withProvides = true)
        {
            var installed = new Dictionary <string, AbstractVersion>();

            // Index our Preexisting Modules, because we like them as much as any other mod
            // unlike CKAN staff who hates their dlls!
            foreach (var preexisting in installed_preexisting_modules)
            {
                AbstractVersion modVersion = preexisting.Value.modInfo.version;
                if (modVersion != null)
                {
                    installed[preexisting.Key] = modVersion;
                }
            }

            // Index our provides list, so users can see virtual packages
            if (withProvides)
            {
                foreach (var provided in Provided())
                {
                    installed[provided.Key] = provided.Value;
                }
            }

            // Index our installed modules (which may overwrite the installed DLLs and provides)
            foreach (var modinfo in installed_modules)
            {
                installed[modinfo.Key] = modinfo.Value.Module.modVersion;
            }

            return(installed);
        }
Exemple #3
0
        public bool isSatisfiedBy(string name, AbstractVersion modVersion)
        {
            if (name != modName)
            {
                return(isOptional);
            }
            var  calculatedMaxVersion = calculateMaxVersion();
            bool ret = (minVersion == null || modVersion >= minVersion) && (calculatedMaxVersion == null || modVersion <= calculatedMaxVersion);

            return(isConflict ? !ret : ret);
        }
Exemple #4
0
        //=========================================================================== Construction

        /// <summary>
        /// Initializes a new instance of the <see cref="VersionNumber"/> class.
        /// </summary>
        /// <param name="major">The major verion number.</param>
        /// <param name="minor">The minor version number.</param>
        /// <param name="status">The version status.</param>
        public VersionNumber(int major, int minor, VersionStatus status)
        {
            if (major < 0 || minor < 0)
            {
                throw new ArgumentException("Major or minor must be greater than or equal zero");
            }

            _abstractVersion = AbstractVersion.Defined;
            _major           = major;
            _minor           = minor;
            _status          = status;
        }
Exemple #5
0
        /// <summary>
        /// Returns the specified CkanModule with the version specified,
        /// or null if it does not exist.
        /// <see cref = "IRegistryQuerier.GetModuleByVersion" />
        /// </summary>
        public CfanModule GetModuleByVersion(string ident, AbstractVersion version)
        {
            log.DebugFormat("Trying to find {0} version {1}", ident, version);

            if (!available_modules.ContainsKey(ident))
            {
                return(null);
            }

            AvailableModule available = available_modules[ident];

            return(available.ByVersion(new ModVersion(version.ToString())));
        }
Exemple #6
0
        /// <summary>
        ///     Install our mod from the filename supplied.
        ///     If no file is supplied, we will check the cache or throw FileNotFoundKraken.
        ///     Does *not* resolve dependencies; this actually does the heavy listing.
        ///     Does *not* save the registry.
        ///     Do *not* call this directly, use InstallList() instead.
        ///
        /// Propagates a BadMetadataKraken if our install metadata is bad.
        /// Propagates a FileExistsKraken if we were going to overwrite a file.
        /// Throws a FileNotFoundKraken if we can't find the downloaded module.
        ///
        /// </summary>
        //
        // TODO: The name of this and InstallModule() need to be made more distinctive.

        private void Install(CfanModule module, string filename = null)
        {
            CheckMetapackageInstallationKraken(module);

            AbstractVersion version = registry_manager.registry.InstalledVersion(module.identifier);

            // TODO: This really should be handled by higher-up code.
            if (version != null)
            {
                User.RaiseMessage("    {0} {1} already installed, skipped", module.identifier, version);
                return;
            }

            // Find our in the cache if we don't already have it.
            filename = filename ?? Cache.GetCachedZip(module.download, true);

            // If we *still* don't have a file, then kraken bitterly.
            if (filename == null)
            {
                throw new FileNotFoundKraken(
                          null,
                          String.Format("Trying to install {0}, but it's not downloaded or download is corrupted", module)
                          );
            }

            // We'll need our registry to record which files we've installed.
            Registry registry = registry_manager.registry;

            using (var transaction = CkanTransaction.CreateTransactionScope())
            {
                // Install all the things!
                IEnumerable <string> files = InstallModule(module, filename);

                // Register our module and its files.
                registry.RegisterModule(module, files, ksp);

                // Finish our transaction, but *don't* save the registry; we may be in an
                // intermediate, inconsistent state.
                // This is fine from a transaction standpoint, as we may not have an enclosing
                // transaction, and if we do, they can always roll us back.
                transaction.Complete();
            }

            // Fire our callback that we've installed a module, if we have one.
            if (onReportModInstalled != null)
            {
                onReportModInstalled(module);
            }
        }
Exemple #7
0
        public CfanModuleIdAndVersion(string stringWithIdentifierEqualsVersion)
        {
            Match match = Regex.Match(stringWithIdentifierEqualsVersion,
                                      @"^(?<mod>[a-zA-Z0-9_-][a-zA-Z0-9_ -\.]+[a-zA-Z0-9_-]*)(?<version>=\d+\.\d+\.?\d*)?$");

            if (!match.Success)
            {
                throw new ModuleAndVersionStringInvalidKraken(stringWithIdentifierEqualsVersion);
            }

            identifier = match.Groups["mod"].Value;
            if (match.Groups["version"].Success)
            {
                version = new ModVersion(match.Groups["version"].Value.TrimStart('='));
            }
        }
Exemple #8
0
        /// <summary>
        /// Returns the path to a cached copy of a module if it exists, or downloads
        /// and returns the downloaded copy otherwise.
        ///
        /// If no filename is provided, the module's standard name will be used.
        /// Chcecks provided cache first.
        /// </summary>
        public static string CachedOrDownload(string identifier, AbstractVersion version, Uri url, NetFileCache cache, string filename = null)
        {
            if (filename == null)
            {
                filename = CfanModule.createStandardFileName(identifier, version.ToString());
            }

            string full_path = cache.GetCachedZip(url);

            if (full_path == null)
            {
                return(Download(url, filename, cache));
            }

            log.DebugFormat("Using {0} (cached)", filename);
            return(full_path);
        }
Exemple #9
0
        public int RunCommand(CKAN.KSP ksp, object raw_options)
        {
            UpgradeOptions options = (UpgradeOptions)raw_options;

            if (options.ckan_file != null)
            {
                options.modules.Add(LoadCkanFromFile(ksp, options.ckan_file).identifier);
            }

            if (options.modules.Count == 0 && !options.upgrade_all)
            {
                // What? No files specified?
                User.RaiseMessage("Usage: cfan upgrade Mod [Mod2, ...]");
                User.RaiseMessage("  or   cfan upgrade --all");
                User.RaiseMessage("  or   cfan upgrade ckan");
                return(Exit.BADOPT);
            }

            if (!options.upgrade_all && options.modules[0] == "cfan")
            {
                User.RaiseMessage("Querying the latest CFAN version");
                AutoUpdate.Instance.FetchLatestReleaseInfo();
                var latestVersion  = AutoUpdate.Instance.LatestVersion;
                var currentVersion = new ModVersion(Meta.Version());

                if (latestVersion.IsGreaterThan(currentVersion))
                {
                    User.RaiseMessage("New CFAN version available - " + latestVersion);
                    var releaseNotes = AutoUpdate.Instance.ReleaseNotes;
                    User.RaiseMessage(releaseNotes);
                    User.RaiseMessage("\n");

                    if (User.RaiseYesNoDialog("Proceed with install?"))
                    {
                        User.RaiseMessage("Upgrading CFAN, please wait..");
                        AutoUpdate.Instance.StartUpdateProcess(false);
                    }
                }
                else
                {
                    User.RaiseMessage("You already have the latest version.");
                }

                return(Exit.OK);
            }

            User.RaiseMessage("\nUpgrading modules...\n");

            try
            {
                if (options.upgrade_all)
                {
                    var installed  = new Dictionary <string, AbstractVersion>(ksp.Registry.Installed(true));
                    var to_upgrade = new List <CfanModule>();

                    foreach (KeyValuePair <string, AbstractVersion> mod in installed)
                    {
                        AbstractVersion current_version = mod.Value;

                        if ((current_version is ProvidedVersion) || (current_version is AutodetectedVersion))
                        {
                            continue;
                        }
                        try
                        {
                            // Check if upgrades are available
                            CfanModule latest = ksp.Registry.LatestAvailable(mod.Key, ksp.Version());

                            // This may be an unindexed mod. If so,
                            // skip rather than crash. See KSP-CKAN/CKAN#841.
                            if (latest == null)
                            {
                                continue;
                            }

                            if (latest.modVersion.IsGreaterThan(mod.Value))
                            {
                                // Upgradable
                                log.InfoFormat("New version {0} found for {1}",
                                               latest.modVersion, latest.identifier);
                                to_upgrade.Add(latest);
                            }
                        }
                        catch (ModuleNotFoundKraken)
                        {
                            log.InfoFormat("{0} is installed, but no longer in the registry",
                                           mod.Key);
                        }
                    }

                    ModuleInstaller.GetInstance(ksp, User).Upgrade(to_upgrade, new NetAsyncModulesDownloader(User, ksp.tryGetFactorioAuthData()));
                }
                else
                {
                    // TODO: These instances all need to go.
                    ModuleInstaller.GetInstance(ksp, User).Upgrade(options.modules, new NetAsyncModulesDownloader(User, ksp.tryGetFactorioAuthData()));
                }
            }
            catch (ModuleNotFoundKraken kraken)
            {
                User.RaiseMessage("Module {0} not found", kraken.module);
                return(Exit.ERROR);
            }
            User.RaiseMessage("\nDone!\n");

            return(Exit.OK);
        }
Exemple #10
0
 /// <summary>
 /// Returns the path to a cached copy of a module if it exists, or downloads
 /// and returns the downloaded copy otherwise.
 ///
 /// If no filename is provided, the module's standard name will be used.
 /// Chcecks the CKAN cache first.
 /// </summary>
 public string CachedOrDownload(string identifier, AbstractVersion version, Uri url, string filename = null)
 {
     return(CachedOrDownload(identifier, version, url, Cache, filename));
 }
Exemple #11
0
        /// <summary>
        /// Updates the supplied registry from the URL given.
        /// This does not *save* the registry. For that, you probably want Repo.Update
        /// </summary>
        internal static void UpdateRegistry(Uri repo, Registry registry, KSP ksp, IUser user, Boolean clear = true)
        {
            log.InfoFormat("Downloading {0}", repo);

            string repo_file = String.Empty;

            try
            {
                repo_file = Net.Download(repo);
            }
            catch (System.Net.WebException e)
            {
                user.RaiseError($"Couldn't download {repo}.", e);
                return;
            }

            // Clear our list of known modules.
            var old_available = registry.available_modules;

            if (clear)
            {
                registry.ClearAvailable();
            }

            // Check the filetype.
            FileType type = FileIdentifier.IdentifyFile(repo_file);

            switch (type)
            {
            case FileType.TarGz:
                UpdateRegistryFromTarGz(repo_file, registry);
                break;

            case FileType.Zip:
                UpdateRegistryFromZip(repo_file, registry);
                break;

            default:
                break;
            }

            List <CfanModule> metadataChanges = new List <CfanModule>();

            foreach (var identifierModulePair in old_available)
            {
                var identifier = identifierModulePair.Key;

                if (registry.IsInstalled(identifier))
                {
                    AbstractVersion abstractVersion  = registry.InstalledVersion(identifier);
                    var             installedVersion = new ModVersion(abstractVersion.ToString());

                    if (!(registry.available_modules.ContainsKey(identifier)))
                    {
                        log.InfoFormat("UpdateRegistry, module {0}, version {1} not in repository ({2})", identifier, installedVersion, repo);
                        continue;
                    }

                    if (!registry.available_modules[identifier].module_version.ContainsKey(installedVersion))
                    {
                        continue;
                    }

                    // if the mod is installed and the metadata is different we have to reinstall it
                    CfanModule metadata = new CfanModule(registry.available_modules[identifier].module_version[installedVersion]);

                    if (!old_available.ContainsKey(identifier) ||
                        !old_available[identifier].module_version.ContainsKey(installedVersion))
                    {
                        continue;
                    }

                    CfanModule oldMetadata = new CfanModule(old_available[identifier].module_version[installedVersion]);

                    bool same = metadata.kind == oldMetadata.kind;

                    if (!same)
                    {
                        metadataChanges.Add(new CfanModule(registry.available_modules[identifier].module_version[installedVersion]));
                    }
                }
            }

            if (metadataChanges.Any())
            {
                string mods = "";
                for (int i = 0; i < metadataChanges.Count; i++)
                {
                    mods += metadataChanges[i].identifier + " "
                            + metadataChanges[i].modVersion.ToString() + ((i < metadataChanges.Count - 1) ? ", " : "");
                }

                if (user.RaiseYesNoDialog(String.Format(
                                              @"The following mods have had their metadata changed since last update - {0}.
It is advisable that you reinstall them in order to preserve consistency with the repository. Do you wish to reinstall now?", mods)))
                {
                    ModuleInstaller installer = ModuleInstaller.GetInstance(ksp, new NullUser());
                    installer.Upgrade(metadataChanges, new NetAsyncModulesDownloader(new NullUser(), ksp.tryGetFactorioAuthData()));
                }
            }

            // Remove our downloaded meta-data now we've processed it.
            // Seems weird to do this as part of a transaction, but Net.Download uses them, so let's be consistent.
            file_transaction.Delete(repo_file);
        }
Exemple #12
0
		//=========================================================================== Construction

        /// <summary>
        /// Initializes a new instance of the <see cref="VersionNumber"/> class.
        /// </summary>
        /// <param name="major">The major verion number.</param>
        /// <param name="minor">The minor version number.</param>
		/// <param name="status">The version status.</param>
		public VersionNumber(int major, int minor, VersionStatus status)
		{
			if (major < 0 || minor < 0)
				throw new ArgumentException("Major or minor must be greater than or equal zero");

			_abstractVersion = AbstractVersion.Defined;
			_major = major;
			_minor = minor;
			_status = status;
		}
Exemple #13
0
		private VersionNumber(AbstractVersion abstractVersion)
		{
			_abstractVersion = abstractVersion;
			_major = -1;
			_minor = -1 - (int)abstractVersion;
		}
Exemple #14
0
        public int RunCommand(CKAN.KSP ksp, object raw_options)
        {
            ListOptions options = (ListOptions)raw_options;

            IRegistryQuerier registry = RegistryManager.Instance(ksp).registry;


            ExportFileType?exportFileType = null;

            if (!string.IsNullOrWhiteSpace(options.export))
            {
                exportFileType = GetExportFileType(options.export);

                if (exportFileType == null)
                {
                    user.RaiseError("Unknown export format: {0}", options.export);
                }
            }

            if (!(options.porcelain) && exportFileType == null)
            {
                user.RaiseMessage("\nFactorio found at {0}\n", ksp.GameDir());
                user.RaiseMessage("Factorio Version: {0}\n", ksp.Version());

                user.RaiseMessage("Installed Modules:\n");
            }

            if (exportFileType == null)
            {
                var installed = new SortedDictionary <string, AbstractVersion>(registry.Installed());

                foreach (KeyValuePair <string, AbstractVersion> mod in installed)
                {
                    AbstractVersion current_version = mod.Value;

                    string bullet = "*";

                    if (current_version is ProvidedVersion)
                    {
                        // Skip virtuals for now.
                        continue;
                    }
                    else if (current_version is AutodetectedVersion)
                    {
                        // Autodetected dll
                        bullet = "-";
                    }
                    else
                    {
                        try
                        {
                            // Check if upgrades are available, and show appropriately.
                            CfanModule latest = registry.LatestAvailable(mod.Key, ksp.Version());

                            log.InfoFormat("Latest {0} is {1}", mod.Key, latest);

                            if (latest == null)
                            {
                                // Not compatible!
                                bullet = "X";
                            }
                            else if (latest.modVersion.Equals(current_version))
                            {
                                // Up to date
                                bullet = "-";
                            }
                            else if (latest.modVersion.IsGreaterThan(mod.Value))
                            {
                                // Upgradable
                                bullet = "^";
                            }
                        }
                        catch (ModuleNotFoundKraken)
                        {
                            log.InfoFormat("{0} is installed, but no longer in the registry", mod.Key);
                            bullet = "?";
                        }
                    }

                    user.RaiseMessage("{0} {1} {2}", bullet, mod.Key, mod.Value);
                }
            }
            else
            {
                var stream = Console.OpenStandardOutput();
                new Exporter(exportFileType.Value).Export(registry, stream);
                stream.Flush();
            }

            if (!(options.porcelain) && exportFileType == null)
            {
                user.RaiseMessage("\nLegend: -: Up to date. X: Incompatible. ^: Upgradable. ?: Unknown ");
            }

            return(Exit.OK);
        }
Exemple #15
0
 private VersionNumber(AbstractVersion abstractVersion)
 {
     _abstractVersion = abstractVersion;
     _major           = -1;
     _minor           = -1 - (int)abstractVersion;
 }
Exemple #16
0
 public CfanModuleIdAndVersion(string identifier, AbstractVersion version)
 {
     this.identifier = identifier;
     this.version    = version;
 }
Exemple #17
0
        public GUIMod(CfanModule mod, IRegistryQuerier registry, FactorioVersion current_ksp_version)
        {
            IsCKAN = mod is CfanModule;
            //Currently anything which could alter these causes a full reload of the modlist
            // If this is ever changed these could be moved into the properties
            Mod              = mod;
            IsInstalled      = registry.IsInstalled(mod.identifier, false);
            IsInstallChecked = IsInstalled;
            HasUpdate        = registry.HasUpdate(mod.identifier, current_ksp_version);
            IsIncompatible   = !mod.IsCompatibleKSP(current_ksp_version);
            IsAutodetected   = registry.IsAutodetected(mod.identifier);
            Authors          = mod.authors == null ? "N/A" : String.Join(",", mod.authors);

            var             installed_version = registry.InstalledVersion(mod.identifier);
            AbstractVersion latest_version    = null;
            var             ksp_version       = mod.getMinFactorioVersion();

            CfanModule latest_available = null;

            try
            {
                latest_available = registry.LatestAvailable(mod.identifier, current_ksp_version);
                if (latest_available != null)
                {
                    latest_version = latest_available.modVersion;
                }
            }
            catch (ModuleNotFoundKraken)
            {
                latest_version = installed_version;
            }

            InstalledVersion = installed_version != null?installed_version.ToString() : "-";

            // Let's try to find the compatibility for this mod. If it's not in the registry at
            // all (because it's a DarkKAN mod) then this might fail.

            CfanModule latest_available_for_any_ksp = null;

            try
            {
                latest_available_for_any_ksp = registry.LatestAvailable(mod.identifier, null);
            }
            catch
            {
                // If we can't find the mod in the CKAN, but we've a CkanModule installed, then
                // use that.
                if (IsCKAN)
                {
                    latest_available_for_any_ksp = (CfanModule)mod;
                }
            }

            var showInfoFrom = latest_available ?? latest_available_for_any_ksp;

            // If there's known information for this mod in any form, calculate the highest compatible
            // KSP.
            if (showInfoFrom != null)
            {
                string minVersion = showInfoFrom.getMinFactorioVersion()?.ToString();
                string maxVersion = showInfoFrom.HighestCompatibleKSP()?.ToString();
                if (maxVersion != null && ModVersion.isMaxWithTheSameMinor(new ModVersion(maxVersion)))
                {
                    maxVersion = maxVersion.Replace(int.MaxValue.ToString(), "x");
                }

                if (minVersion != null && maxVersion != null)
                {
                    KSPCompatibility = minVersion.ToString() + " - " + maxVersion.ToString();
                }
                else if (minVersion != null)
                {
                    KSPCompatibility = " >= " + minVersion.ToString();
                }
                else if (maxVersion != null)
                {
                    KSPCompatibility = " <= " + maxVersion.ToString();
                }
                else
                {
                    KSPCompatibility = "any";
                }
                KSPCompatibilityLong = KSPCompatibility;

                // If the mod we have installed is *not* the mod we have installed, or we don't know
                // what we have installed, indicate that an upgrade would be needed.
                if (installed_version == null || !showInfoFrom.modVersion.Equals(installed_version))
                {
                    KSPCompatibilityLong = string.Format("{0} (using mod version {1})",
                                                         KSPCompatibility, showInfoFrom.modVersion);
                }
            }
            else
            {
                // No idea what this mod is, sorry!
                KSPCompatibility = KSPCompatibilityLong = "unknown";
            }

            if (latest_version != null)
            {
                LatestVersion = latest_version.ToString();
            }
            else if (latest_available_for_any_ksp != null)
            {
                LatestVersion = latest_available_for_any_ksp.modVersion.ToString();
            }
            else
            {
                LatestVersion = "-";
            }

            KSPversion = ksp_version != null?ksp_version.ToString() : "-";

            Abstract = mod.@abstract;

            // If we have homepage provided use that, otherwise use the spacedock page or the github repo so that users have somewhere to get more info than just the abstract.

            Homepage = "N/A";
            if (!string.IsNullOrEmpty(mod.homepage))
            {
                Homepage = mod.homepage;
            }

            Identifier = mod.identifier;

            if (mod.download_size == 0)
            {
                DownloadSize = "N/A";
            }
            else if (mod.download_size / 1024.0 < 1)
            {
                DownloadSize = "1<KB";
            }
            else
            {
                DownloadSize = mod.download_size / 1024 + "";
            }

            Abbrevation = new string(mod.title.Split(' ').
                                     Where(s => s.Length > 0).Select(s => s[0]).ToArray());

            if (Main.Instance != null)
            {
                IsCached = Main.Instance.CurrentInstance.Cache.IsMaybeCachedZip(mod.download);
            }
        }