Example #1
0
        public void VersionWithinBounds_vs_AutoDetectedMod(string version)
        {
            string modName       = "someModName";
            var    modDependency = new ModDependency($"{modName}>=5.6.0");
            var    autodetected  = new AutodetectedVersion("1.0");

            Assert.False(modDependency.isSatisfiedBy(modName, autodetected));
        }
Example #2
0
        public void VersionWithinBounds_MinMax_vs_AutoDetectedMod(string min, string max)
        {
            string modName       = "someModName";
            var    modDependency = new ModDependency($"{modName}>={min}<={max}");
            var    autodetected  = new AutodetectedVersion("0.0.1");

            Assert.False(modDependency.isSatisfiedBy(modName, autodetected));
        }
Example #3
0
        public void VersionWithinBounds_MinMax(string min, string max, string compareTo, bool expected)
        {
            string modName       = "someModName";
            var    modDependency = new ModDependency($"{modName}>={min}<={max}");
            var    version       = new ModVersion(compareTo);

            Assert.AreEqual(expected, modDependency.isSatisfiedBy(modName, version));
        }
Example #4
0
        public void NormalizeFactorioVersion()
        {
            var jsonString = @"{""tags"":[{""id"":21,""name"":""storage"",""title"":""Storage"",""description"":"""",""type"":""t""}],""ratings_count"":0,""game_versions"":[""0.13""],""license_url"":""https://opensource.org/licenses/MIT"",""latest_release"":{""id"":11169,""version"":""0.1.0"",""game_version"":""0.13"",""released_at"":""2017-12-18T08:51:02.518735Z"",""download_url"":""/api/downloads/data/mods/168/Warehousing_0.1.0.zip"",""info_json"":{""description"":""Store all the things! Warehousing provides high capacity storage buildings, including logistic network versions."",""author"":""Anoyomouse"",""name"":""Warehousing"",""dependencies"":[""base >= 0.15.0""],""contact"":""PM on the Factorio Forums"",""version"":""0.1.0"",""factorio_version"":""0.16"",""homepage"":""https://forums.factorio.com/17295"",""title"":""Warehousing Mod""},""file_name"":""Warehousing_0.1.0.zip"",""file_size"":609499,""downloads_count"":2381,""factorio_version"":""0.16""},""summary"":""Store all the things! Warehousing provides high capacity storage buildings, including logistic network versions."",""id"":168,""license_name"":""MIT"",""created_at"":""2016-06-30 14:31:27.945831+00:00"",""name"":""Warehousing"",""github_path"":""Anoyomouse/Warehousing"",""updated_at"":""2017-12-18 08:51:02.892619+00:00"",""first_media_file"":{""id"":302,""width"":686,""height"":489,""size"":816769,""urls"":{""original"":""https://mods-data.factorio.com/pub_data/media_files/jEL61ah7Nqxg.png"",""thumb"":""https://mods-data.factorio.com/pub_data/media_files/jEL61ah7Nqxg.thumb.png""}},""license_flags"":599,""title"":""Warehousing Mod"",""current_user_rating"":null,""downloads_count"":88876,""owner"":""anoyomouse"",""homepage"":""https://forums.factorio.com/17295""}";
            var modJson    = JsonConvert.DeserializeObject <ModJson>(jsonString);
            FactorioComDownloader  downloader = new FactorioComDownloader();
            IEnumerable <CfanJson> mods       = downloader.generateCfanJsons(new NullUser(), modJson);
            CfanJson      cfanJson            = mods.First();
            ModDependency factorioDependency  = cfanJson.modInfo.dependencies.First(p => p.modName == "base");

            Assert.IsTrue(factorioDependency.maxVersion > new ModVersion("0.16.0"));
        }
Example #5
0
        protected static ModDependency createLegacyDependency(ModDependency dependency)
        {
            var minVersion = dependency.minVersion;
            var maxVersion = dependency.maxVersion;

            if (minVersion != null && maxVersion != null)
            {
                // old CFAN versions didn't support setting both minVersion and maxVersion
                minVersion = null;
            }
            return(new ModDependency(minVersion, maxVersion, dependency.modName, dependency.isOptional));
        }
Example #6
0
        /// <summary>
        /// <see cref = "IRegistryQuerier.LatestAvailable" />
        /// </summary>

        // TODO: Consider making this internal, because practically everything should
        // be calling LatestAvailableWithProvides()
        public CfanModule LatestAvailable(
            string module,
            FactorioVersion ksp_version,
            ModDependency relationship_descriptor = null)
        {
            log.DebugFormat("Finding latest available for {0}", module);

            // TODO: Check user's stability tolerance (stable, unstable, testing, etc)

            try
            {
                return(available_modules[module].Latest(ksp_version, relationship_descriptor, factorioAuthData != null));
            }
            catch (KeyNotFoundException)
            {
                throw new ModuleNotFoundKraken(module);
            }
        }
Example #7
0
        protected void fixBaseGameVersionRequirement(ModInfoJson modInfoJson)
        {
            // cfan does not allow empty base game version requirement for versions above 0.13
            var baseGameRequirement = modInfoJson.dependencies.FirstOrDefault(p => p.modName == "base");

            if (String.IsNullOrEmpty(modInfoJson.factorio_version))
            {
                throw new Exception("Mod " + modInfoJson.name + " has empty factorio_version field.");
            }
            ModVersion minVersion        = ModVersion.minWithTheSameMinor(new ModVersion(modInfoJson.factorio_version));
            ModVersion maxVersion        = ModVersion.maxWithTheSameMinor(new ModVersion(modInfoJson.factorio_version));
            var        newBaseDependency = new ModDependency(minVersion, maxVersion, "base", false);

            // add new or substitute existing base dependency
            var newDependencies = modInfoJson.dependencies.Where(p => p != baseGameRequirement).ToList();

            newDependencies.Add(newBaseDependency);
            modInfoJson.dependencies = newDependencies.ToArray();
        }
Example #8
0
        /// <summary>
        /// Formats a RelationshipDescriptor into a user-readable string:
        /// Name, version: x, min: x, max: x
        /// </summary>
        private static string RelationshipToPrintableString(ModDependency dep)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append(dep.modName);
            if (dep.isOptional)
            {
                sb.Append(" (only if installed)");
            }
            if (dep.isConflict)
            {
                sb.Append(" (conflict)");
            }
            if (dep.minVersion != null)
            {
                sb.Append(", min: " + dep.minVersion);
            }
            if (dep.maxVersion != null)
            {
                sb.Append(", max: " + dep.maxVersion);
            }
            return(sb.ToString());
        }
Example #9
0
        public bool IsCompatibleKSP(FactorioVersion kspVersion)
        {
            ModDependency baseGame = BaseGameDependency;

            return(baseGame == null || baseGame.isSatisfiedBy("base", kspVersion));
        }
Example #10
0
        /// <summary>
        /// Return the most recent release of a module with a optional ksp version to target and a RelationshipDescriptor to satisfy.
        /// </summary>
        /// <param name="ksp_version">If not null only consider mods which match this ksp version.</param>
        /// <param name="relationship">If not null only consider mods which satisfy the RelationshipDescriptor.</param>
        /// <returns></returns>
        public CfanModule Latest(FactorioVersion ksp_version = null, ModDependency relationship = null, bool hasFactorioAuth = false)
        {
            IDictionary <ModVersion, CfanJson> module_version = this.module_version;

            if (!hasFactorioAuth)
            {
                module_version = module_version.Where(p => !CfanJson.requiresFactorioComAuthorization(p.Value)).ToDictionary(p => p.Key, p => p.Value);
            }

            var      available_versions = new List <ModVersion>(module_version.Keys);
            CfanJson module;

            log.DebugFormat("Our dictionary has {0} keys", module_version.Keys.Count);
            log.DebugFormat("Choosing between {0} available versions", available_versions.Count);

            // Uh oh, nothing available. Maybe this existed once, but not any longer.
            if (available_versions.Count == 0)
            {
                return(null);
            }

            // No restrictions? Great, we can just pick the first one!
            if (ksp_version == null && relationship == null)
            {
                module = module_version[available_versions.First()];

                log.DebugFormat("No KSP version restriction, {0} is most recent", module.modInfo.version);
                return(new CfanModule(module));
            }

            // If there's no relationship to satisfy, we can just pick the first that is
            // compatible with our version of KSP.
            if (relationship == null)
            {
                // Time to check if there's anything that we can satisfy.
                var version =
                    available_versions.FirstOrDefault(v => new CfanModule(module_version[v]).IsCompatibleKSP(ksp_version));
                if (version != null)
                {
                    return(new CfanModule(module_version[version]));
                }

                log.DebugFormat("No version of {0} is compatible with KSP {1}",
                                module_version[available_versions[0]].modInfo.name, ksp_version);

                return(null);
            }

            // If we're here, then we have a relationship to satisfy, so things get more complex.
            if (ksp_version == null)
            {
                var version = available_versions.FirstOrDefault(p => relationship.isSatisfiedBy(identifier, p));
                return(version == null ? null : new CfanModule(module_version[version]));
            }
            else
            {
                var version = available_versions.FirstOrDefault(v =>
                                                                relationship.isSatisfiedBy(identifier, v) &&
                                                                new CfanModule(module_version[v]).IsCompatibleKSP(ksp_version));
                return(version == null ? null : new CfanModule(module_version[version]));
            }
        }
 public Incompatible(Manifest parent, ModDependency depend) : base(parent, depend)
 {
 }
        private void AddDependency(Dictionary <Version, Dictionary <string, ModDependencyInfo> > dict, ModDependency dependency, Version factorioVersion)
        {
            var subDict = GetSubDict(dict, factorioVersion);

            ModDependencyInfo info;

            if (!subDict.TryGetValue(dependency.ModName, out info))
            {
                info = new ModDependencyInfo(dependency.ModName, factorioVersion, dependency.ModVersion, dependency.IsOptional);
                subDict.Add(dependency.ModName, info);
            }
            else
            {
                if (dependency.HasVersionRestriction)
                {
                    if ((info.Version == null) || (dependency.ModVersion > info.Version))
                    {
                        info.Version = dependency.ModVersion;
                    }
                }

                if (!dependency.IsOptional)
                {
                    info.IsOptional = false;
                }
            }
        }
Example #13
0
 public Dependency(Manifest parent, ModDependency depend) : this(parent, depend.packageId)
 {
     displayName      = depend.displayName;
     downloadUrl      = depend.downloadUrl;
     steamWorkshopUrl = depend.steamWorkshopUrl;
 }
Example #14
0
 public SourceSync(Manifest parent, ModDependency depend) : base(parent, depend)
 {
 }
Example #15
0
        public AbstractVersion HighestCompatibleKSP()
        {
            ModDependency baseGame = BaseGameDependency;

            return(baseGame != null ? new FactorioVersion(baseGame.calculateMaxVersion().ToString()) : null);
        }
Example #16
0
 /// <summary>
 /// <see cref = "IRegistryQuerier.LatestAvailableWithProvides" />
 /// </summary>
 public List <CfanModule> LatestAvailableWithProvides(string module, FactorioVersion ksp_version, ModDependency relationship_descriptor = null)
 {
     // This public interface calculates a cache of modules which
     // are compatible with the current version of KSP, and then
     // calls the private version below for heavy lifting.
     return(LatestAvailableWithProvides(module, ksp_version,
                                        available_modules.Values.Select(pair => pair.Latest(ksp_version)).Where(mod => mod != null).ToArray(),
                                        relationship_descriptor));
 }
Example #17
0
        public FactorioVersion getMinFactorioVersion()
        {
            ModDependency baseGame = BaseGameDependency;

            return(baseGame?.minVersion != null ? new FactorioVersion(baseGame.minVersion.ToString()) : null);
        }
Example #18
0
 protected LoadOrder(Manifest parent, ModDependency _depend) : base(parent, _depend)
 {
 }
Example #19
0
        /// <summary>
        /// Returns the latest version of a module that can be installed for
        /// the given KSP version. This is a *private* method that assumes
        /// the `available_for_current_version` list has been correctly
        /// calculated. Not for direct public consumption. ;)
        /// </summary>
        private List <CfanModule> LatestAvailableWithProvides(string module, FactorioVersion ksp_version,
                                                              IEnumerable <CfanModule> available_for_current_version, ModDependency relationship_descriptor = null)
        {
            log.DebugFormat("Finding latest available with provides for {0}", module);

            // TODO: Check user's stability tolerance (stable, unstable, testing, etc)

            var modules = new List <CfanModule>();

            try
            {
                // If we can find the module requested for our KSP, use that.
                CfanModule mod = LatestAvailable(module, ksp_version, relationship_descriptor);
                if (mod != null)
                {
                    modules.Add(mod);
                }
            }
            catch (ModuleNotFoundKraken)
            {
                // It's cool if we can't find it, though.
            }

            // Walk through all our available modules, and see if anything
            // provides what we need.

            // Get our candidate module. We can assume this is non-null, as
            // if it *is* null then available_for_current_version is corrupted,
            // and something is terribly wrong.
            foreach (CfanModule candidate in available_for_current_version)
            {
                // Find everything this module provides (for our version of KSP)
                List <string> provides = candidate.providesNames.ToList();

                // If the module has provides, and any of them are what we're looking
                // for, the add it to our list.
                if (provides != null && provides.Any(provided => provided == module))
                {
                    modules.Add(candidate);
                }
            }
            return(modules);
        }
Example #20
0
        private async Task AddDependency(Dictionary <string, Dictionary <Version, ModDependencyInfo> > dict, Dictionary <string, ExtendedModInfo> infos, ModDependency dependency, Version factorioVersion)
        {
            var modInfo = await GetModInfoAsync(infos, dependency.ModName);

            if ((modInfo != null) && dependency.IsPresent(modInfo, factorioVersion, out var release))
            {
                var subDict = GetSubDict(dict, dependency.ModName);

                ModDependencyInfo info;
                if (!subDict.TryGetValue(release.Version, out info))
                {
                    info = new ModDependencyInfo(release, dependency.ModName, factorioVersion, dependency.IsOptional);
                    subDict.Add(release.Version, info);
                }
                else
                {
                    if (!dependency.IsOptional)
                    {
                        info.IsOptional = false;
                    }
                }
            }
        }
Example #21
0
        public void VersionWithinBounds_ExactFalse(string modDependencyString, string modName, string versionName, bool expected)
        {
            var modDependency = new ModDependency(modDependencyString);

            Assert.AreEqual(expected, modDependency.isSatisfiedBy(modName, new ModVersion(versionName)));
        }