public GUIMod(Module mod, IRegistryQuerier registry, KSPVersion current_ksp_version) { 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 = !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); Version 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() : "-"; LatestVersion = latest_version != null ? latest_version.ToString() : "-"; KSPversion = ksp_version != null ? ksp_version.ToString() : "-"; Abstract = mod.@abstract; Homepage = mod.resources != null && mod.resources.homepage != null ? (object) mod.resources.homepage : "N/A"; Identifier = mod.identifier; }
private void AddMod(IEnumerable<RelationshipDescriptor> relations, Dictionary<string, List<string>> chooseAble, string identifier, IRegistryQuerier registry) { if (relations == null) return; foreach (RelationshipDescriptor mod in relations) { try { // if the mod is available for the current KSP version _and_ // the mod is not installed _and_ // the mod is not already in the install list if ( registry.LatestAvailable(mod.name, CurrentInstance.Version()) != null && !registry.IsInstalled(mod.name) && !toInstall.Contains(mod.name)) { // add it to the list of chooseAble mods we display to the user if (!chooseAble.ContainsKey(mod.name)) { chooseAble.Add(mod.name, new List<string>()); } chooseAble[mod.name].Add(identifier); } } // XXX - Don't ignore all krakens! Those things are important! catch (Kraken) { } } }
public GUIMod(CkanModule mod, IRegistryQuerier registry, KspVersionCriteria current_ksp_version) { 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 = !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); Version 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; 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.name.Split(' '). Where(s => s.Length > 0).Select(s => s[0]).ToArray()); UpdateIsCached(); }
public GUIMod(CkanModule mod, IRegistryQuerier registry, KSPVersion current_ksp_version) { 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 = !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); Version 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 homepage provided use that, otherwise use the kerbalstuff 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.kerbalstuff != null) { Homepage = mod.resources.kerbalstuff.ToString(); } else if (mod.resources.repository != null) { Homepage = mod.resources.repository.ToString(); } } 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.name.Split(' '). Where(s => s.Length > 0).Select(s => s[0]).ToArray()); if (Main.Instance != null) { IsCached = Main.Instance.CurrentInstance.Cache.IsMaybeCachedZip(mod.download); } }
private IEnumerable <ListViewItem> getRecSugRows( IEnumerable <CkanModule> sourceModules, IRegistryQuerier registry, HashSet <CkanModule> toInstall ) { Dictionary <CkanModule, List <string> > dependersIndex = getDependersIndex(sourceModules, registry, toInstall); foreach (CkanModule mod in sourceModules.Where(m => m.recommends != null)) { foreach (RelationshipDescriptor rel in mod.recommends) { List <CkanModule> providers = rel.LatestAvailableWithProvides( registry, CurrentInstance.VersionCriteria() ); foreach (CkanModule provider in providers) { List <string> dependers; if (!registry.IsInstalled(provider.identifier) && !toInstall.Any(m => m.identifier == provider.identifier) && dependersIndex.TryGetValue(provider, out dependers) && CanInstall(registry, CurrentInstance.VersionCriteria(), RelationshipResolver.DependsOnlyOpts(), toInstall.ToList().Concat(new List <CkanModule>() { provider }).ToList())) { dependersIndex.Remove(provider); yield return(getRecSugItem( provider, string.Join(", ", dependers), RecommendationsGroup, providers.Count <= 1 || provider.identifier == (rel as ModuleRelationshipDescriptor)?.name )); } } } } foreach (CkanModule mod in sourceModules.Where(m => m.suggests != null)) { foreach (RelationshipDescriptor rel in mod.suggests) { List <CkanModule> providers = rel.LatestAvailableWithProvides( registry, CurrentInstance.VersionCriteria() ); foreach (CkanModule provider in providers) { List <string> dependers; if (!registry.IsInstalled(provider.identifier) && !toInstall.Any(m => m.identifier == provider.identifier) && dependersIndex.TryGetValue(provider, out dependers) && CanInstall(registry, CurrentInstance.VersionCriteria(), RelationshipResolver.DependsOnlyOpts(), toInstall.ToList().Concat(new List <CkanModule>() { provider }).ToList())) { dependersIndex.Remove(provider); yield return(getRecSugItem( provider, string.Join(", ", dependers), SuggestionsGroup, false )); } } } } }
/// <summary> /// Check if a mod is autodetected. /// </summary> /// <returns><c>true</c>, if autodetected<c>false</c> otherwise.</returns> public static bool IsAutodetected(this IRegistryQuerier querier, string identifier) { return(querier.IsInstalled(identifier) && querier.InstalledVersion(identifier) is UnmanagedModuleVersion); }
/// <summary> /// Resolve a relationship stanza (a list of relationships). /// This will add modules to be installed, if required. /// May recurse back to Resolve for those new modules. /// /// If `soft_resolve` is true, we warn rather than throw exceptions on mods we cannot find. /// If `soft_resolve` is false (default), we throw a ModuleNotFoundKraken if we can't find a dependency. /// /// Throws a TooManyModsProvideKraken if we have too many choices and /// options.without_toomanyprovides_kraken is not set. /// /// See RelationshipResolverOptions for further adjustments that can be made. /// /// </summary> private void ResolveStanza(IEnumerable <RelationshipDescriptor> stanza, SelectionReason reason, RelationshipResolverOptions options, bool soft_resolve = false, IEnumerable <RelationshipDescriptor> old_stanza = null) { if (stanza == null) { return; } foreach (var descriptor in stanza) { string dep_name = descriptor.name; log.DebugFormat("Considering {0}", dep_name); // If we already have this dependency covered, skip. // If it's already installed, skip. if (modlist.ContainsKey(dep_name)) { var module = modlist[dep_name]; if (descriptor.version_within_bounds(module.version)) { continue; } //TODO Ideally we could check here if it can be replaced by the version we want. if (options.procede_with_inconsistencies) { conflicts.Add(new KeyValuePair <CkanModule, CkanModule>(module, reason.Parent)); conflicts.Add(new KeyValuePair <CkanModule, CkanModule>(reason.Parent, module)); continue; } throw new InconsistentKraken( string.Format( "{0} requires a version {1}. However a incompatible version, {2}, is in the resolver", dep_name, descriptor.RequiredVersion, module.version)); } if (registry.IsInstalled(dep_name)) { if (descriptor.version_within_bounds(registry.InstalledVersion(dep_name))) { continue; } var module = registry.InstalledModule(dep_name).Module; //TODO Ideally we could check here if it can be replaced by the version we want. if (options.procede_with_inconsistencies) { conflicts.Add(new KeyValuePair <CkanModule, CkanModule>(module, reason.Parent)); conflicts.Add(new KeyValuePair <CkanModule, CkanModule>(reason.Parent, module)); continue; } throw new InconsistentKraken( string.Format( "{0} requires a version {1}. However a incompatible version, {2}, is already installed", dep_name, descriptor.RequiredVersion, registry.InstalledVersion(dep_name))); } var descriptor1 = descriptor; List <CkanModule> candidates = registry.LatestAvailableWithProvides(dep_name, kspversion, descriptor) .Where(mod => descriptor1.version_within_bounds(mod.version) && MightBeInstallable(mod)).ToList(); if (candidates.Count == 0) { if (!soft_resolve) { log.ErrorFormat("Dependency on {0} found but it is not listed in the index, or not available for your version of KSP.", dep_name); throw new ModuleNotFoundKraken(dep_name); } log.InfoFormat("{0} is recommended/suggested but it is not listed in the index, or not available for your version of KSP.", dep_name); continue; } if (candidates.Count > 1) { // Oh no, too many to pick from! // TODO: It would be great if instead we picked the one with the // most recommendations. if (options.without_toomanyprovides_kraken) { continue; } // If we've got a parent stanza that has a relationship on a mod that provides what // we need, then select that. if (old_stanza != null) { List <CkanModule> provide = candidates.Where(can => old_stanza.Where(relation => can.identifier == relation.name).Any()).ToList(); if (!provide.Any() || provide.Count() > 1) { //We still have either nothing, or too my to pick from //Just throw the TMP now throw new TooManyModsProvideKraken(dep_name, candidates); } candidates[0] = provide.First(); } else { throw new TooManyModsProvideKraken(dep_name, candidates); } } CkanModule candidate = candidates[0]; // Finally, check our candidate against everything which might object // to it being installed; that's all the mods which are fixed in our // list thus far, as well as everything on the system. var fixed_mods = new HashSet <CkanModule>(modlist.Values); fixed_mods.UnionWith(installed_modules); var conflicting_mod = fixed_mods.FirstOrDefault(mod => mod.ConflictsWith(candidate)); if (conflicting_mod == null) { // Okay, looks like we want this one. Adding. Add(candidate, reason); Resolve(candidate, options, stanza); } else if (soft_resolve) { log.InfoFormat("{0} would cause conflicts, excluding it from consideration", candidate); } else { if (options.procede_with_inconsistencies) { Add(candidate, reason); conflicts.Add(new KeyValuePair <CkanModule, CkanModule>(conflicting_mod, candidate)); conflicts.Add(new KeyValuePair <CkanModule, CkanModule>(candidate, conflicting_mod)); } else { throw new InconsistentKraken(string.Format("{0} conflicts with {1}, can't install both.", conflicting_mod, candidate)); } } } }
/// <summary> /// Is the mod installed and does it have a newer version compatible with version /// We can't update AD mods /// </summary> public static bool HasUpdate(this IRegistryQuerier querier, string identifier, FactorioVersion version) { CfanModule newest_version; try { newest_version = querier.LatestAvailable(identifier, version); } catch (ModuleNotFoundKraken) { return(false); } if (newest_version == null) { return(false); } return(!new List <string>(querier.InstalledPreexistingModules).Contains(identifier) && querier.IsInstalled(identifier, false) && newest_version.modVersion.IsGreaterThan(querier.InstalledVersion(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(); }
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); } }