/// <summary> /// Generates a download progress report. /// </summary> /// <param name="index">Index of the file being downloaded</param> /// <param name="percent">The percent complete</param> /// <param name="bytesDownloaded">The bytes downloaded</param> /// <param name="bytesToDownload">The total amount of bytes we expect to download</param> private void FileProgressReport(int index, int percent, long bytesDownloaded, long bytesToDownload) { if (download_canceled) { return; } NetAsyncDownloaderDownloadPart download = downloads[index]; DateTime now = DateTime.Now; TimeSpan timeSpan = now - download.lastProgressUpdateTime; if (timeSpan.Seconds >= 3.0) { long bytesChange = bytesDownloaded - download.lastProgressUpdateSize; download.lastProgressUpdateSize = (int)bytesDownloaded; download.lastProgressUpdateTime = now; download.bytesPerSecond = (int)bytesChange / timeSpan.Seconds; } download.size = bytesToDownload; download.bytesLeft = download.size - bytesDownloaded; if (Progress != null) { Progress(download.target, download.bytesLeft, download.size); } int totalBytesPerSecond = 0; long totalBytesLeft = 0; long totalSize = 0; foreach (NetAsyncDownloaderDownloadPart t in downloads.ToList()) { if (t.bytesLeft > 0) { totalBytesPerSecond += t.bytesPerSecond; } totalBytesLeft += t.bytesLeft; totalSize += t.size; } foreach (Net.DownloadTarget t in queuedDownloads.ToList()) { totalBytesLeft += t.size; totalSize += t.size; } int totalPercentage = (int)(((totalSize - totalBytesLeft) * 100) / (totalSize)); if (!download_canceled) { // Math.Ceiling was added to avoid showing 0 MiB left when finishing User.RaiseProgress( String.Format("{0}/sec - downloading - {1} left", CkanModule.FmtSize(totalBytesPerSecond), CkanModule.FmtSize(totalBytesLeft)), totalPercentage); } }
private void PurgeAllMenuItem_Click(object sender, EventArgs e) { YesNoDialog deleteConfirmationDialog = new YesNoDialog(); string confirmationText = String.Format ( Properties.Resources.SettingsDialogDeleteConfirm, m_cacheFileCount, CkanModule.FmtSize(m_cacheSize) ); if (deleteConfirmationDialog.ShowYesNoDialog(confirmationText) == DialogResult.Yes) { // tell the cache object to nuke itself Main.Instance.Manager.Cache.RemoveAll(); // forcibly tell all mod rows to re-check cache state foreach (DataGridViewRow row in Main.Instance.ModList.Rows) { var mod = row.Tag as GUIMod; mod?.UpdateIsCached(); } // finally, clear the preview contents list Main.Instance.UpdateModContentsTree(null, true); UpdateCacheInfo(config.DownloadCacheDir); } }
/// <summary> /// Initialize a GUIMod based on a CkanModule /// </summary> /// <param name="mod">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(CkanModule mod, IRegistryQuerier registry, KspVersionCriteria current_ksp_version, bool incompatible = false) : this(mod.identifier, registry, current_ksp_version, incompatible) { Mod = mod; IsCKAN = mod is CkanModule; Name = mod.name.Trim(); Abstract = [email protected](); Abbrevation = new string(Name.Split(' ').Where(s => s.Length > 0).Select(s => s[0]).ToArray()); Authors = mod.author == null ? "N/A" : String.Join(",", mod.author); HasUpdate = registry.HasUpdate(mod.identifier, current_ksp_version); DownloadSize = mod.download_size == 0 ? "N/A" : CkanModule.FmtSize(mod.download_size); IsIncompatible = IsIncompatible || !mod.IsCompatibleKSP(current_ksp_version); if (mod.resources != null) { Homepage = mod.resources.homepage?.ToString() ?? mod.resources.spacedock?.ToString() ?? mod.resources.curse?.ToString() ?? mod.resources.repository?.ToString() ?? "N/A"; } UpdateIsCached(); }
protected string modNameAndStatus(CkanModule m) { return(m.IsMetapackage ? string.Format(Properties.Resources.MainChangesetMetapackage, m.name, m.version) : Main.Instance.Manager.Cache.IsMaybeCachedZip(m) ? string.Format(Properties.Resources.MainChangesetCached, m.name, m.version) : string.Format(Properties.Resources.MainChangesetHostSize, m.name, m.version, m.download.Host ?? "", CkanModule.FmtSize(m.download_size))); }
/// <summary> /// React to data received for a module, /// adds or updates a label and progress bar so user can see how each download is going /// </summary> /// <param name="module">The module that is being downloaded</param> /// <param name="remaining">Number of bytes left to download</param> /// <param name="total">Number of bytes in complete download</param> public void SetModuleProgress(CkanModule module, long remaining, long total) { Util.Invoke(this, () => { if (moduleBars.TryGetValue(module, out ProgressBar pb)) { // download_size is allowed to be 0 pb.Value = Math.Max(pb.Minimum, Math.Min(pb.Maximum, (int)(100 * (total - remaining) / total) )); } else { var rowTop = TopPanel.Height - padding; var newLb = new Label() { AutoSize = true, Location = new Point(2 * padding, rowTop), Size = new Size(labelWidth, progressHeight), Text = string.Format( Properties.Resources.MainChangesetHostSize, module.name, module.version, module.download.Host ?? "", CkanModule.FmtSize(module.download_size)), }; moduleLabels.Add(module, newLb); var newPb = new ProgressBar() { Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right, Location = new Point(labelWidth + 3 * padding, rowTop), Size = new Size(TopPanel.Width - labelWidth - 5 * padding, progressHeight), Minimum = 0, Maximum = 100, // download_size is allowed to be 0 Value = Math.Max(0, Math.Min(100, (int)(100 * (total - remaining) / total) )), Style = ProgressBarStyle.Continuous, }; moduleBars.Add(module, newPb); } progressTimer.Start(); }); }
private void UpdateCacheInfo() { m_cacheSize = 0; m_cacheFileCount = 0; var cachePath = Main.Instance.CurrentInstance.DownloadCacheDir(); var cacheDirectory = new DirectoryInfo(cachePath); foreach (var file in cacheDirectory.GetFiles()) { m_cacheFileCount++; m_cacheSize += file.Length; } CKANCacheLabel.Text = String.Format ( "There are currently {0} cached files using {1} in total", m_cacheFileCount, CkanModule.FmtSize(m_cacheSize) ); }
private void ClearCKANCacheButton_Click(object sender, EventArgs e) { YesNoDialog deleteConfirmationDialog = new YesNoDialog(); string confirmationText = String.Format ( "Do you really want to delete {0} cached files, freeing {1}?", m_cacheFileCount, CkanModule.FmtSize(m_cacheSize) ); if (deleteConfirmationDialog.ShowYesNoDialog(confirmationText) == System.Windows.Forms.DialogResult.Yes) { foreach (var file in Directory.GetFiles(Main.Instance.CurrentInstance.DownloadCacheDir())) { try { File.Delete(file); } catch (Exception) { } } // tell the cache object to nuke itself Main.Instance.CurrentInstance.Cache.Clear(); // forcibly tell all mod rows to re-check cache state foreach (DataGridViewRow row in Main.Instance.ModList.Rows) { var mod = row.Tag as GUIMod; mod?.UpdateIsCached(); } // finally, clear the preview contents list Main.Instance.UpdateModContentsTree(null, true); UpdateCacheInfo(); } }
private void UpdateCacheInfo(string newPath) { string failReason; if (newPath == winReg.DownloadCacheDir || Main.Instance.Manager.TrySetupCache(newPath, out failReason)) { Main.Instance.Manager.Cache.GetSizeInfo(out m_cacheFileCount, out m_cacheSize); CachePath.Text = winReg.DownloadCacheDir; CacheSummary.Text = $"{m_cacheFileCount} files, {CkanModule.FmtSize(m_cacheSize)}"; CacheSummary.ForeColor = SystemColors.ControlText; ClearCacheButton.Enabled = true; OpenCacheButton.Enabled = true; } else { CacheSummary.Text = $"Invalid path: {failReason}"; CacheSummary.ForeColor = Color.Red; ClearCacheButton.Enabled = false; OpenCacheButton.Enabled = false; } }
private ListViewItem getRecSugItem(CkanModule module, string descrip, ListViewGroup group, bool check) { ListViewItem item = new ListViewItem() { Tag = module, Checked = check, Group = group, Text = Manager.Cache.IsMaybeCachedZip(module) ? $"{module.name} {module.version} (cached)" : $"{module.name} {module.version} ({module.download.Host ?? ""}, {CkanModule.FmtSize(module.download_size)})" }; item.SubItems.Add(new ListViewItem.ListViewSubItem() { Text = descrip }); item.SubItems.Add(new ListViewItem.ListViewSubItem() { Text = module.@abstract }); return(item); }
public void UpdateChangesDialog(List <ModChange> changeset, BackgroundWorker installWorker) { changeSet = changeset; this.installWorker = installWorker; ChangesListView.Items.Clear(); if (changeset == null) { return; } // We're going to split our change-set into two parts: updated/removed mods, // and everything else (which right now is installing mods, but we may have // other types in the future). changeSet = new List <ModChange>(); changeSet.AddRange(changeset.Where(change => change.ChangeType == GUIModChangeType.Remove)); changeSet.AddRange(changeset.Where(change => change.ChangeType == GUIModChangeType.Update)); IEnumerable <ModChange> leftOver = changeset.Where(change => change.ChangeType != GUIModChangeType.Remove && change.ChangeType != GUIModChangeType.Update); // Now make our list more human-friendly (dependencies for a mod are listed directly // after it.) CreateSortedModList(leftOver); changeset = changeSet; foreach (var change in changeset) { if (change.ChangeType == GUIModChangeType.None) { continue; } CkanModule m = change.Mod.ToModule(); ListViewItem item = new ListViewItem() { Text = CurrentInstance.Cache.IsMaybeCachedZip(m) ? $"{m.name} {m.version} (cached)" : $"{m.name} {m.version} ({m.download.Host ?? ""}, {CkanModule.FmtSize(m.download_size)})" }; var sub_change_type = new ListViewItem.ListViewSubItem { Text = change.ChangeType.ToString() }; ListViewItem.ListViewSubItem description = new ListViewItem.ListViewSubItem(); description.Text = change.Reason.Reason.Trim(); if (change.ChangeType == GUIModChangeType.Update) { description.Text = String.Format("Update selected by user to version {0}.", change.Mod.LatestVersion); } if (change.ChangeType == GUIModChangeType.Install && change.Reason is SelectionReason.UserRequested) { description.Text = "New mod install selected by user."; } item.SubItems.Add(sub_change_type); item.SubItems.Add(description); ChangesListView.Items.Add(item); } }
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(); }
private void UpdateCacheInfo(string newPath) { string failReason; if (newPath == config.DownloadCacheDir || Main.Instance.Manager.TrySetupCache(newPath, out failReason)) { Main.Instance.Manager.Cache.GetSizeInfo(out m_cacheFileCount, out m_cacheSize); CachePath.Text = config.DownloadCacheDir; CacheSummary.Text = string.Format(Properties.Resources.SettingsDialogSummmary, m_cacheFileCount, CkanModule.FmtSize(m_cacheSize)); CacheSummary.ForeColor = SystemColors.ControlText; OpenCacheButton.Enabled = true; ClearCacheButton.Enabled = (m_cacheSize > 0); PurgeToLimitMenuItem.Enabled = (config.CacheSizeLimit.HasValue && m_cacheSize > config.CacheSizeLimit.Value); } else { CacheSummary.Text = string.Format(Properties.Resources.SettingsDialogSummaryInvalid, failReason); CacheSummary.ForeColor = Color.Red; OpenCacheButton.Enabled = false; ClearCacheButton.Enabled = false; } }
/// <summary> /// Initialize a GUIMod based on a CkanModule /// </summary> /// <param name="mod">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(CkanModule mod, IRegistryQuerier registry, KspVersionCriteria current_ksp_version, bool?incompatible = null) : this(mod.identifier, registry, current_ksp_version, incompatible) { Mod = mod; IsCKAN = mod is CkanModule; Name = mod.name.Trim(); Abstract = [email protected](); Description = mod.description?.Trim() ?? string.Empty; Abbrevation = new string(Name.Split(' ').Where(s => s.Length > 0).Select(s => s[0]).ToArray()); Authors = mod.author == null ? Properties.Resources.GUIModNSlashA : String.Join(",", mod.author); HasUpdate = registry.HasUpdate(mod.identifier, current_ksp_version); HasReplacement = registry.GetReplacement(mod, current_ksp_version) != null; DownloadSize = mod.download_size == 0 ? Properties.Resources.GUIModNSlashA : CkanModule.FmtSize(mod.download_size); // Get the Searchables. SearchableName = mod.SearchableName; SearchableAbstract = mod.SearchableAbstract; SearchableDescription = mod.SearchableDescription; SearchableAuthors = mod.SearchableAuthors; // If not set in GUIMod(identifier, ...) (because the mod is not known to the registry), // set based on the the data we have from the CkanModule. if (KSPCompatibilityVersion == null) { KSPCompatibilityVersion = mod.LatestCompatibleKSP(); KSPCompatibility = KSPCompatibilityVersion?.ToYalovString() ?? Properties.Resources.GUIModUnknown; KSPCompatibilityLong = string.Format( Properties.Resources.GUIModKSPCompatibilityLong, KSPCompatibility, mod.version ); } UpdateIsCached(); }
private void UpdateProvidedModsDialog(TooManyModsProvideKraken tooManyProvides, TaskCompletionSource <CkanModule> task) { toomany_source = task; ChooseProvidedModsLabel.Text = String.Format( Properties.Resources.MainInstallProvidedBy, tooManyProvides.requested ); ChooseProvidedModsListView.Items.Clear(); ChooseProvidedModsListView.ItemChecked += ChooseProvidedModsListView_ItemChecked; foreach (CkanModule module in tooManyProvides.modules) { ListViewItem item = new ListViewItem() { Tag = module, Checked = false, Text = Manager.Cache.IsMaybeCachedZip(module) ? string.Format(Properties.Resources.MainChangesetCached, module.name, module.version) : string.Format(Properties.Resources.MainChangesetHostSize, module.name, module.version, module.download.Host ?? "", CkanModule.FmtSize(module.download_size)) }; ListViewItem.ListViewSubItem description = new ListViewItem.ListViewSubItem() { Text = module.@abstract }; item.SubItems.Add(description); ChooseProvidedModsListView.Items.Add(item); } ChooseProvidedModsListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); ChooseProvidedModsContinueButton.Enabled = false; }
private ListViewItem getRecSugItem(NetModuleCache cache, CkanModule module, string descrip, ListViewGroup group, bool check) { return(new ListViewItem(new string[] { module.IsDLC?module.name : cache.IsMaybeCachedZip(module) ? string.Format(Properties.Resources.MainChangesetCached, module.name, module.version) : string.Format(Properties.Resources.MainChangesetHostSize, module.name, module.version, module.download?.Host ?? "", CkanModule.FmtSize(module.download_size)), descrip, module.@abstract }) { Tag = module, Checked = check, Group = group }); }
private ListViewItem getRecSugItem(CkanModule module, string descrip, ListViewGroup group, bool check) { ListViewItem item = new ListViewItem() { Tag = module, Checked = check, Group = group, Text = Manager.Cache.IsMaybeCachedZip(module) ? string.Format(Properties.Resources.MainChangesetCached, module.name, module.version) : string.Format(Properties.Resources.MainChangesetHostSize, module.name, module.version, module.download.Host ?? "", CkanModule.FmtSize(module.download_size)) }; item.SubItems.Add(new ListViewItem.ListViewSubItem() { Text = descrip }); item.SubItems.Add(new ListViewItem.ListViewSubItem() { Text = module.@abstract }); return(item); }
private void UpdateProvidedModsDialog(TooManyModsProvideKraken tooManyProvides, TaskCompletionSource <CkanModule> task) { toomany_source = task; ChooseProvidedModsLabel.Text = String.Format( "Module {0} is provided by more than one available module, please choose one of the following mods:", tooManyProvides.requested); ChooseProvidedModsListView.Items.Clear(); ChooseProvidedModsListView.ItemChecked += ChooseProvidedModsListView_ItemChecked; foreach (CkanModule module in tooManyProvides.modules) { ListViewItem item = new ListViewItem() { Tag = module, Checked = false, Text = Manager.Cache.IsMaybeCachedZip(module) ? $"{module.name} {module.version} (cached)" : $"{module.name} {module.version} ({module.download.Host ?? ""}, {CkanModule.FmtSize(module.download_size)})" }; ListViewItem.ListViewSubItem description = new ListViewItem.ListViewSubItem() { Text = module.@abstract }; item.SubItems.Add(description); ChooseProvidedModsListView.Items.Add(item); } ChooseProvidedModsListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); ChooseProvidedModsContinueButton.Enabled = false; }
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 a CkanModule /// </summary> /// <param name="mod">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(CkanModule mod, IRegistryQuerier registry, KspVersionCriteria current_ksp_version, bool?incompatible = null) : this(mod.identifier, registry, current_ksp_version, incompatible) { Mod = mod; IsCKAN = mod is CkanModule; Name = mod.name.Trim(); Abstract = [email protected](); Description = mod.description?.Trim() ?? string.Empty; Abbrevation = new string(Name.Split(' ').Where(s => s.Length > 0).Select(s => s[0]).ToArray()); Authors = mod.author == null ? Properties.Resources.GUIModNSlashA : String.Join(",", mod.author); HasUpdate = registry.HasUpdate(mod.identifier, current_ksp_version); HasReplacement = registry.GetReplacement(mod, current_ksp_version) != null; DownloadSize = mod.download_size == 0 ? Properties.Resources.GUIModNSlashA : CkanModule.FmtSize(mod.download_size); // Get the Searchables. SearchableName = mod.SearchableName; SearchableAbstract = mod.SearchableAbstract; SearchableDescription = mod.SearchableDescription; SearchableAuthors = mod.SearchableAuthors; UpdateIsCached(); }
private void UpdateCacheInfo(string newPath) { string failReason; if (updatingCache) { return; } if (newPath == config.DownloadCacheDir || Main.Instance.Manager.TrySetupCache(newPath, out failReason)) { updatingCache = true; Task.Factory.StartNew(() => { // This might take a little while if the cache is big Main.Instance.Manager.Cache.GetSizeInfo(out m_cacheFileCount, out m_cacheSize); Util.Invoke(this, () => { if (config.CacheSizeLimit.HasValue) { // Show setting in MB CacheLimit.Text = (config.CacheSizeLimit.Value / 1024 / 1024).ToString(); } CachePath.Text = config.DownloadCacheDir; CacheSummary.Text = string.Format(Properties.Resources.SettingsDialogSummmary, m_cacheFileCount, CkanModule.FmtSize(m_cacheSize)); CacheSummary.ForeColor = SystemColors.ControlText; OpenCacheButton.Enabled = true; ClearCacheButton.Enabled = (m_cacheSize > 0); PurgeToLimitMenuItem.Enabled = (config.CacheSizeLimit.HasValue && m_cacheSize > config.CacheSizeLimit.Value); updatingCache = false; }); }); } else { CacheSummary.Text = string.Format(Properties.Resources.SettingsDialogSummaryInvalid, failReason); CacheSummary.ForeColor = Color.Red; OpenCacheButton.Enabled = false; ClearCacheButton.Enabled = false; } }
public void LoadProviders(string requested, List <CkanModule> modules, NetModuleCache cache) { ChooseProvidedModsLabel.Text = String.Format( Properties.Resources.MainInstallProvidedBy, requested ); ChooseProvidedModsListView.Items.Clear(); ChooseProvidedModsListView.Items.AddRange(modules .Select(module => new ListViewItem(new string[] { cache.IsMaybeCachedZip(module) ? string.Format(Properties.Resources.MainChangesetCached, module.name, module.version) : string.Format(Properties.Resources.MainChangesetHostSize, module.name, module.version, module.download.Host ?? "", CkanModule.FmtSize(module.download_size)), module.@abstract }) { Tag = module, Checked = false }) .ToArray()); ChooseProvidedModsListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); ChooseProvidedModsContinueButton.Enabled = false; }
/// <summary> /// Installs all modules given a list of identifiers as a transaction. Resolves dependencies. /// This *will* save the registry at the end of operation. /// /// Propagates a BadMetadataKraken if our install metadata is bad. /// Propagates a FileExistsKraken if we were going to overwrite a file. /// Propagates a CancelledActionKraken if the user cancelled the install. /// </summary> public void InstallList(ICollection <CkanModule> modules, RelationshipResolverOptions options, IDownloader downloader = null) { // TODO: Break this up into smaller pieces! It's huge! var resolver = new RelationshipResolver(modules, options, registry_manager.registry, ksp.VersionCriteria()); var modsToInstall = resolver.ModList().ToList(); List <CkanModule> downloads = new List <CkanModule>(); // TODO: All this user-stuff should be happening in another method! // We should just be installing mods as a transaction. User.RaiseMessage("About to install...\r\n"); foreach (CkanModule module in modsToInstall) { if (!ksp.Cache.IsCachedZip(module)) { User.RaiseMessage(" * {0} {1} ({2}, {3})", module.name, module.version, module.download.Host, CkanModule.FmtSize(module.download_size) ); downloads.Add(module); } else { User.RaiseMessage(" * {0} {1} (cached)", module.name, module.version); } } bool ok = User.RaiseYesNoDialog("\r\nContinue?"); if (!ok) { throw new CancelledActionKraken("User declined install list"); } User.RaiseMessage(String.Empty); // Just to look tidy. if (downloads.Count > 0) { if (downloader == null) { downloader = new NetAsyncModulesDownloader(User); } downloader.DownloadModules(ksp.Cache, downloads); } // We're about to install all our mods; so begin our transaction. using (TransactionScope transaction = CkanTransaction.CreateTransactionScope()) { for (int i = 0; i < modsToInstall.Count; i++) { int percent_complete = (i * 100) / modsToInstall.Count; User.RaiseProgress(String.Format("Installing mod \"{0}\"", modsToInstall[i]), percent_complete); Install(modsToInstall[i]); } User.RaiseProgress("Updating registry", 70); registry_manager.Save(!options.without_enforce_consistency); User.RaiseProgress("Committing filesystem changes", 80); transaction.Complete(); } // We can scan GameData as a separate transaction. Installing the mods // leaves everything consistent, and this is just gravy. (And ScanGameData // acts as a Tx, anyway, so we don't need to provide our own.) User.RaiseProgress("Rescanning GameData", 90); if (!options.without_enforce_consistency) { ksp.ScanGameData(); } User.RaiseProgress("Done!\r\n", 100); }
private void UpdateRecommendedDialog(Dictionary <CkanModule, string> mods, bool suggested = false) { if (!suggested) { RecommendedDialogLabel.Text = "The following modules have been recommended by one or more of the chosen modules:"; RecommendedModsListView.Columns[1].Text = "Recommended by:"; RecommendedModsToggleCheckbox.Text = "(De-)select all recommended mods."; RecommendedModsToggleCheckbox.Checked = true; tabController.RenameTab("ChooseRecommendedModsTabPage", "Choose recommended mods"); } else { RecommendedDialogLabel.Text = "The following modules have been suggested by one or more of the chosen modules:"; RecommendedModsListView.Columns[1].Text = "Suggested by:"; RecommendedModsToggleCheckbox.Text = "(De-)select all suggested mods."; RecommendedModsToggleCheckbox.Checked = false; tabController.RenameTab("ChooseRecommendedModsTabPage", "Choose suggested mods"); } RecommendedModsListView.Items.Clear(); foreach (var pair in mods) { CkanModule module = pair.Key; ListViewItem item = new ListViewItem() { Tag = module, Checked = !suggested, Text = CurrentInstance.Cache.IsMaybeCachedZip(pair.Key) ? $"{pair.Key.name} {pair.Key.version} (cached)" : $"{pair.Key.name} {pair.Key.version} ({pair.Key.download.Host ?? ""}, {CkanModule.FmtSize(pair.Key.download_size)})" }; ListViewItem.ListViewSubItem recommendedBy = new ListViewItem.ListViewSubItem() { Text = pair.Value }; item.SubItems.Add(recommendedBy); ListViewItem.ListViewSubItem description = new ListViewItem.ListViewSubItem { Text = module.@abstract }; item.SubItems.Add(description); RecommendedModsListView.Items.Add(item); } }
public void UpdateChangesDialog(List <ModChange> changeset, BackgroundWorker installWorker) { changeSet = changeset; this.installWorker = installWorker; ChangesListView.Items.Clear(); if (changeset == null) { return; } // We're going to split our change-set into two parts: updated/removed mods, // and everything else (which right now is replacing and installing mods, but we may have // other types in the future). changeSet = new List <ModChange>(); changeSet.AddRange(changeset.Where(change => change.ChangeType == GUIModChangeType.Remove)); changeSet.AddRange(changeset.Where(change => change.ChangeType == GUIModChangeType.Update)); IEnumerable <ModChange> leftOver = changeset.Where(change => change.ChangeType != GUIModChangeType.Remove && change.ChangeType != GUIModChangeType.Update); // Now make our list more human-friendly (dependencies for a mod are listed directly // after it.) CreateSortedModList(leftOver); changeset = changeSet; foreach (var change in changeset) { if (change.ChangeType == GUIModChangeType.None) { continue; } CkanModule m = change.Mod; ListViewItem item = new ListViewItem() { Text = m.IsMetapackage ? string.Format(Properties.Resources.MainChangesetMetapackage, m.name, m.version) : Manager.Cache.IsMaybeCachedZip(m) ? string.Format(Properties.Resources.MainChangesetCached, m.name, m.version) : string.Format(Properties.Resources.MainChangesetHostSize, m.name, m.version, m.download.Host ?? "", CkanModule.FmtSize(m.download_size)), Tag = change.Mod }; var sub_change_type = new ListViewItem.ListViewSubItem { Text = change.ChangeType.ToString() }; ListViewItem.ListViewSubItem description = new ListViewItem.ListViewSubItem(); description.Text = change.Reason.Reason.Trim(); if (change.ChangeType == GUIModChangeType.Update) { description.Text = String.Format(Properties.Resources.MainChangesetUpdateSelected, change.Mod.version); } if (change.ChangeType == GUIModChangeType.Install && change.Reason is SelectionReason.UserRequested) { description.Text = Properties.Resources.MainChangesetNewInstall; } item.SubItems.Add(sub_change_type); item.SubItems.Add(description); ChangesListView.Items.Add(item); } }