/// <summary> /// Initialize a GUIMod based on just an identifier /// </summary> /// <param name="identifier">The id of the module to represent</param> /// <param name="registry">CKAN registry object for current game instance</param> /// <param name="current_ksp_version">Current game version</param> /// <param name="incompatible">If true, mark this module as incompatible</param> public GUIMod(string identifier, IRegistryQuerier registry, KspVersionCriteria current_ksp_version, bool incompatible = false) { Identifier = identifier; IsIncompatible = incompatible; IsAutodetected = registry.IsAutodetected(identifier); DownloadCount = registry.DownloadCount(identifier); ModuleVersion latest_version = null; try { latest_version = registry.LatestAvailable(identifier, current_ksp_version)?.version; } catch (ModuleNotFoundKraken) { } // 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. CkanModule latest_available_for_any_ksp = null; try { latest_available_for_any_ksp = registry.LatestAvailable(identifier, null); } catch { } // If there's known information for this mod in any form, calculate the highest compatible // KSP. if (latest_available_for_any_ksp != null) { KSPCompatibility = registry.LatestCompatibleKSP(identifier)?.ToYalovString() ?? "Unknown"; KSPCompatibilityLong = $"{KSPCompatibility} (using mod version {latest_available_for_any_ksp.version})"; } 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.version.ToString(); } else { LatestVersion = "-"; } // If we have a homepage provided, use that; otherwise use the spacedock page, curse page or the github repo so that users have somewhere to get more info than just the abstract. Homepage = "N/A"; }
/// <summary> /// Initialize a GUIMod based on just an identifier /// </summary> /// <param name="identifier">The id of the module to represent</param> /// <param name="registry">CKAN registry object for current game instance</param> /// <param name="current_ksp_version">Current game version</param> /// <param name="incompatible">If true, mark this module as incompatible</param> public GUIMod(string identifier, IRegistryQuerier registry, KspVersionCriteria current_ksp_version, bool?incompatible = null) { Identifier = identifier; IsAutodetected = registry.IsAutodetected(identifier); DownloadCount = registry.DownloadCount(identifier); if (IsAutodetected) { IsInstalled = true; } ModuleVersion latest_version = null; try { LatestCompatibleMod = registry.LatestAvailable(identifier, current_ksp_version); latest_version = LatestCompatibleMod?.version; } catch (ModuleNotFoundKraken) { } IsIncompatible = incompatible ?? LatestCompatibleMod == null; // 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. CkanModule latest_available_for_any_ksp = null; try { latest_available_for_any_ksp = registry.LatestAvailable(identifier, null); } catch { } // If there's known information for this mod in any form, calculate the highest compatible // KSP. if (latest_available_for_any_ksp != null) { KSPCompatibilityVersion = registry.LatestCompatibleKSP(identifier); KSPCompatibility = KSPCompatibilityVersion?.ToYalovString() ?? Properties.Resources.GUIModUnknown; KSPCompatibilityLong = string.Format(Properties.Resources.GUIModKSPCompatibilityLong, KSPCompatibility, latest_available_for_any_ksp.version); } if (latest_version != null) { LatestVersion = latest_version.ToString(); } else if (latest_available_for_any_ksp != null) { LatestVersion = latest_available_for_any_ksp.version.ToString(); } else { LatestVersion = "-"; } SearchableIdentifier = CkanModule.nonAlphaNums.Replace(Identifier, ""); }
public IEnumerable <Metadata> Transform(Metadata metadata, TransformOptions opts) { Log.Debug("Fixing version strings (if required)..."); var json = metadata.Json(); JToken epoch; if (json.TryGetValue("x_netkan_epoch", out epoch)) { Log.InfoFormat("Executing epoch transformation with {0}", metadata.Kref); Log.DebugFormat("Input metadata:{0}{1}", Environment.NewLine, json); uint epochNumber; if (uint.TryParse(epoch.ToString(), out epochNumber)) { //Implicit if zero. No need to add if (epochNumber != 0) { json["version"] = epochNumber + ":" + json["version"]; } Log.DebugFormat("Transformed metadata:{0}{1}", Environment.NewLine, json); } else { throw new BadMetadataKraken(null, "Invalid epoch: " + epoch + " In " + json["identifier"]); } } JToken allowOOO; if (json.TryGetValue("x_netkan_allow_out_of_order", out allowOOO) && (bool)allowOOO) { Log.Debug("Out of order versions enabled in netkan, skipping OOO check"); } else if (opts.HighestVersion != null) { // Ensure we are greater or equal to the previous max ModuleVersion startV = new ModuleVersion((string)json["version"]); ModuleVersion currentV = startV; while (currentV < opts.HighestVersion) { Log.DebugFormat("Auto-epoching out of order version: {0} < {1}", currentV, opts.HighestVersion); // Increment epoch if too small currentV = currentV.IncrementEpoch(); } if (!opts.HighestVersion.EpochEquals(currentV) && startV < opts.HighestVersion && opts.HighestVersion < currentV) { // New file, tell the Indexer to be careful opts.Staged = true; opts.StagingReason = $"Auto-epoching out of order version: {startV} < {opts.HighestVersion} < {currentV}"; } json["version"] = currentV.ToString(); } yield return(new Metadata(json)); }
public static string StandardName(string identifier, ModuleVersion version) { // Versions can contain ALL SORTS OF WACKY THINGS! Colons, friggin newlines, // slashes, and heaven knows what use mod authors try to smoosh into them. // We'll reduce this down to "friendly" characters, replacing everything else with // dashes. This doesn't change look-ups, as we use the hash prefix for that. string version_string = Regex.Replace(version.ToString(), "[^A-Za-z0-9_.-]", "-"); return(identifier + "-" + version_string + ".zip"); }
public static JToken ToSpecVersionJson(this ModuleVersion specVersion) { if (specVersion.IsEqualTo(new ModuleVersion("v1.0"))) { return(1); } else { return(specVersion.ToString()); } }
private void addVersionBox(int l, int t, int r, int b, Func<string> title, Func<ConsoleColor> color, bool doubleLine, List<CkanModule> releases) { AddObject(new ConsoleFrame( l, t, r, b, title, color, doubleLine )); if (releases != null && releases.Count > 0) { ModuleVersion minMod = null, maxMod = null; KspVersion minKsp = null, maxKsp = null; Registry.GetMinMaxVersions(releases, out minMod, out maxMod, out minKsp, out maxKsp); AddObject(new ConsoleLabel( l + 2, t + 1, r - 2, () => minMod == maxMod ? $"{ModuleInstaller.WithAndWithoutEpoch(minMod?.ToString() ?? "???")}" : $"{ModuleInstaller.WithAndWithoutEpoch(minMod?.ToString() ?? "???")} - {ModuleInstaller.WithAndWithoutEpoch(maxMod?.ToString() ?? "???")}", null, color )); AddObject(new ConsoleLabel( l + 2, t + 2, r - 2, () => "Compatible with:", null, () => ConsoleTheme.Current.DimLabelFg )); AddObject(new ConsoleLabel( l + 4, t + 3, r - 2, () => KspVersionRange.VersionSpan(minKsp, maxKsp), null, color )); } }
public GithubRelease(GithubRef reference, JToken json) { PreRelease = (bool)json["prerelease"]; Tag = new ModuleVersion((string)json["tag_name"]); Author = (string)json["author"]["login"]; PublishedAt = (DateTime?)json["published_at"]; Assets = reference.UseSourceArchive ? new List <GithubReleaseAsset> { new GithubReleaseAsset( Tag.ToString(), new Uri((string)json["zipball_url"]), PublishedAt) } : ((JArray)json["assets"]) .Where(asset => reference.Filter.IsMatch((string)asset["name"])) .Select(asset => new GithubReleaseAsset( (string)asset["name"], new Uri((string)asset["browser_download_url"]), (DateTime?)asset["updated_at"])) .ToList(); }
public IEnumerable <GithubRelease> GetAllReleases(GithubRef reference) { const int perPage = 10; for (int page = 1; true; ++page) { var json = Call($"repos/{reference.Repository}/releases?per_page={perPage}&page={page}"); Log.Debug("Parsing JSON..."); var releases = JArray.Parse(json); // Finding the most recent *stable* release means filtering // out on pre-releases. foreach (var release in releases) { // First, check for prerelease status... if (reference.UsePrerelease == (bool)release["prerelease"]) { var version = new ModuleVersion((string)release["tag_name"]); var author = (string)release["author"]["login"]; List <GithubReleaseAsset> allAssets; if (reference.UseSourceArchive) { Log.Debug("Using GitHub source archive"); Uri download = new Uri((string)release["zipball_url"]); DateTime?updated = (DateTime)release["published_at"]; allAssets = new List <GithubReleaseAsset> { new GithubReleaseAsset(version.ToString(), download, updated) }; } else { allAssets = new List <GithubReleaseAsset>(); var assets = (JArray)release["assets"]; foreach (var asset in assets.Where(asset => reference.Filter.IsMatch((string)asset["name"]))) { Log.DebugFormat("Using GitHub asset: {0}", asset["name"]); Uri download = new Uri((string)asset["browser_download_url"]); DateTime?updated = (DateTime)asset["updated_at"]; allAssets.Add(new GithubReleaseAsset( (string)asset["name"], download, updated ) ); } } if (allAssets.Any()) { yield return(new GithubRelease(author, version, allAssets)); } } } if (releases.Count < perPage) { // That's all folks! break; } } }
public GUIMod(CkanModule mod, IRegistryQuerier registry, KspVersionCriteria current_ksp_version, bool incompatible = false) { IsCKAN = mod is CkanModule; //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 = incompatible || !mod.IsCompatibleKSP(current_ksp_version); IsAutodetected = registry.IsAutodetected(mod.identifier); Authors = mod.author == null ? "N/A" : String.Join(",", mod.author); var installed_version = registry.InstalledVersion(mod.identifier); ModuleVersion latest_version = null; var ksp_version = mod.ksp_version; try { var latest_available = registry.LatestAvailable(mod.identifier, current_ksp_version); if (latest_available != null) { latest_version = latest_available.version; } } 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. CkanModule 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 = (CkanModule)mod; } } // If there's known information for this mod in any form, calculate the highest compatible // KSP. if (latest_available_for_any_ksp != null) { KSPCompatibility = KSPCompatibilityLong = latest_available_for_any_ksp.HighestCompatibleKSP(); // 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 || !latest_available_for_any_ksp.version.IsEqualTo(installed_version)) { KSPCompatibilityLong = string.Format("{0} (using mod version {1})", KSPCompatibility, latest_available_for_any_ksp.version); } } 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.version.ToString(); } else { LatestVersion = "-"; } KSPversion = ksp_version != null?ksp_version.ToString() : "-"; Abstract = mod.@abstract; // If we have a homepage provided, use that; otherwise use the spacedock page, curse page or the github repo so that users have somewhere to get more info than just the abstract. Homepage = "N/A"; if (mod.resources != null) { if (mod.resources.homepage != null) { Homepage = mod.resources.homepage.ToString(); } else if (mod.resources.spacedock != null) { Homepage = mod.resources.spacedock.ToString(); } else if (mod.resources.curse != null) { Homepage = mod.resources.curse.ToString(); } else if (mod.resources.repository != null) { Homepage = mod.resources.repository.ToString(); } } Identifier = mod.identifier; DownloadSize = (mod.download_size == 0) ? "N/A" : CkanModule.FmtSize(mod.download_size); Abbrevation = new string(mod.name.Split(' '). Where(s => s.Length > 0).Select(s => s[0]).ToArray()); UpdateIsCached(); }
/// <summary> /// Initialize a GUIMod based on just an identifier /// </summary> /// <param name="identifier">The id of the module to represent</param> /// <param name="registry">CKAN registry object for current game instance</param> /// <param name="current_ksp_version">Current game version</param> /// <param name="incompatible">If true, mark this module as incompatible</param> public GUIMod(string identifier, IRegistryQuerier registry, KspVersionCriteria current_ksp_version, bool incompatible = false) { Identifier = identifier; IsIncompatible = incompatible; IsAutodetected = registry.IsAutodetected(identifier); DownloadCount = registry.DownloadCount(identifier); if (registry.IsAutodetected(identifier)) { IsInstalled = true; } ModuleVersion latest_version = null; try { LatestCompatibleMod = registry.LatestAvailable(identifier, current_ksp_version); latest_version = LatestCompatibleMod?.version; } catch (ModuleNotFoundKraken) { } // 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. CkanModule latest_available_for_any_ksp = null; try { latest_available_for_any_ksp = registry.LatestAvailable(identifier, null); } catch { } // If there's known information for this mod in any form, calculate the highest compatible // KSP. if (latest_available_for_any_ksp != null) { KSPCompatibility = registry.LatestCompatibleKSP(identifier)?.ToYalovString() ?? Properties.Resources.GUIModUnknown; KSPCompatibilityLong = string.Format(Properties.Resources.GUIModKSPCompatibilityLong, KSPCompatibility, latest_available_for_any_ksp.version); } else { // No idea what this mod is, sorry! KSPCompatibility = KSPCompatibilityLong = Properties.Resources.GUIModUnknown; } if (latest_version != null) { LatestVersion = latest_version.ToString(); } else if (latest_available_for_any_ksp != null) { LatestVersion = latest_available_for_any_ksp.version.ToString(); } else { LatestVersion = "-"; } // If we have a homepage provided, use that; otherwise use the spacedock page, curse page or the github repo so that users have somewhere to get more info than just the abstract. Homepage = Properties.Resources.GUIModNSlashA; SearchableIdentifier = CkanModule.nonAlphaNums.Replace(Identifier, ""); }
public GUIMod(CkanModule mod, IRegistryQuerier registry, KspVersionCriteria current_ksp_version, bool incompatible = false) { IsCKAN = mod is CkanModule; //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 = incompatible || !mod.IsCompatibleKSP(current_ksp_version); IsAutodetected = registry.IsAutodetected(mod.identifier); Authors = mod.author == null ? "N/A" : String.Join(",", mod.author); var installed_version = registry.InstalledVersion(mod.identifier); ModuleVersion latest_version = null; var ksp_version = mod.ksp_version; try { var latest_available = registry.LatestAvailable(mod.identifier, current_ksp_version); if (latest_available != null) { latest_version = latest_available.version; } } 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. CkanModule 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 = (CkanModule)mod; } } // If there's known information for this mod in any form, calculate the highest compatible // KSP. if (latest_available_for_any_ksp != null) { if (!VersionMaxWasGenerated) { VersionMaxWasGenerated = true; List <KspVersion> versions = new KspBuildMap(new Win32Registry()).KnownVersions; // should be sorted VersionsMax = new Dictionary <string, KspVersion>(); VersionsMax[""] = versions.Last(); foreach (var v in versions) { VersionsMax[v.Major.ToString()] = v; // add or replace VersionsMax[v.Major + "." + v.Minor] = v; } } const int Undefined = -1; KspVersion ksp_ver = registry.LatestCompatibleKSP(mod.identifier); string ver = ksp_ver?.ToString(); int major = ksp_ver.Major, minor = ksp_ver.Minor, patch = ksp_ver.Patch; KspVersion value; if (major == Undefined //|| (major >= UptoNines(VersionsMax[""].Major)) // 9.99.99 || (major > VersionsMax[""].Major) || // 2.0.0 (major == VersionsMax[""].Major && VersionsMax.TryGetValue(major.ToString(), out value) && minor >= UptoNines(value.Minor)) // 1.99.99 ? ) { KSPCompatibility = "any"; } else if (minor != Undefined && VersionsMax.TryGetValue(major + "." + minor, out value) && (patch == Undefined || patch >= UptoNines(value.Patch)) ) { KSPCompatibility = major + "." + minor + "." + UptoNines(value.Patch); } else { KSPCompatibility = ver; } // KSPCompatibility += " | " + major + "." + minor + "." + patch; // for testing // 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 || !latest_available_for_any_ksp.version.IsEqualTo(installed_version)) { KSPCompatibilityLong = string.Format("{0} (using mod version {1})", KSPCompatibility, latest_available_for_any_ksp.version); // ver, latest_available_for_any_ksp.version); // true values in the right tab } else { KSPCompatibilityLong = KSPCompatibility; // KSPCompatibilityLong = ver; // true values in the right tab } } 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.version.ToString(); } else { LatestVersion = "-"; } KSPversion = ksp_version != null?ksp_version.ToString() : "-"; Abstract = mod.@abstract; // If we have a homepage provided, use that; otherwise use the spacedock page, curse page or the github repo so that users have somewhere to get more info than just the abstract. Homepage = "N/A"; if (mod.resources != null) { if (mod.resources.homepage != null) { Homepage = mod.resources.homepage.ToString(); } else if (mod.resources.spacedock != null) { Homepage = mod.resources.spacedock.ToString(); } else if (mod.resources.curse != null) { Homepage = mod.resources.curse.ToString(); } else if (mod.resources.repository != null) { Homepage = mod.resources.repository.ToString(); } } Identifier = mod.identifier; DownloadSize = (mod.download_size == 0) ? "N/A" : CkanModule.FmtSize(mod.download_size); Abbrevation = new string(mod.name.Split(' '). Where(s => s.Length > 0).Select(s => s[0]).ToArray()); UpdateIsCached(); }
/// <summary> /// Returns a version string shorn of any leading epoch as delimited by a single colon /// </summary> /// <param name="version">A version that might contain an epoch</param> public static string StripEpoch(ModuleVersion version) { return(StripEpoch(version.ToString())); }