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)); }
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)); }
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)); }
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")); }
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)); }
/// <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); } }
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(); }
/// <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()); }
public bool IsCompatibleKSP(FactorioVersion kspVersion) { ModDependency baseGame = BaseGameDependency; return(baseGame == null || baseGame.isSatisfiedBy("base", kspVersion)); }
/// <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; } } }
public Dependency(Manifest parent, ModDependency depend) : this(parent, depend.packageId) { displayName = depend.displayName; downloadUrl = depend.downloadUrl; steamWorkshopUrl = depend.steamWorkshopUrl; }
public SourceSync(Manifest parent, ModDependency depend) : base(parent, depend) { }
public AbstractVersion HighestCompatibleKSP() { ModDependency baseGame = BaseGameDependency; return(baseGame != null ? new FactorioVersion(baseGame.calculateMaxVersion().ToString()) : null); }
/// <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)); }
public FactorioVersion getMinFactorioVersion() { ModDependency baseGame = BaseGameDependency; return(baseGame?.minVersion != null ? new FactorioVersion(baseGame.minVersion.ToString()) : null); }
protected LoadOrder(Manifest parent, ModDependency _depend) : base(parent, _depend) { }
/// <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); }
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; } } } }
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))); }