public async Task <int> UninstallMultipleMods(List <InstalledMod> mods, bool skipPreventRemoveCheck = true, IProgress <ProgressReport> progress = null) { if (mods.Count == 0) { return(0); } int uninstalledCount = 0; mods = mods.OrderBy((e) => e.usedBy.Count).ToList(); progress?.Report(new ProgressReport($"Uninstalling { mods.Count } mods...", 0f)); for (int i = 0; i < mods.Count; i++) { InstalledMod m = mods[i]; if (await UninstallMod(m, skipPreventRemoveCheck, ProgressReport.Partial(progress, i * (1f / mods.Count), 1f / mods.Count))) { uninstalledCount++; } } progress?.Report(new ProgressReport($"{ mods.Count } of { uninstalledCount } mods were uninstalled successfully.", 0f)); return(uninstalledCount); }
public Task <bool> UninstallMod(InstalledMod mod, bool skipPreventRemoveCheck = false, IProgress <ProgressReport> progess = null) { return(Task.Run(() => { progess?.Report(new ProgressReport($"Preparing to uninstall { mod } ...", 0.1f)); if (!skipPreventRemoveCheck && mod.usedBy.Count > 0) { progess?.Report(new ProgressReport($"Could not uninstall mod: other mods are depending on it.", 1f)); return false; } if (!skipPreventRemoveCheck && mod.preventRemoval) { progess?.Report(new ProgressReport($"Could not uninstall mod: the removal of this mod was prevented.", 1f)); return false; } for (int f = 0; f < mod.affectedFiles.Count; f++) { string file = Path.Combine(BeatSaberDirectory, mod.affectedFiles[f]); progess?.Report(new ProgressReport($"Removing { mod.Name } ... { file }", (float)(f + 1) / mod.affectedFiles.Count * 0.9f)); if (File.Exists(file)) { File.Delete(file); } DirectoryExtensions.DeleteEmptyParentDirectories(Path.GetDirectoryName(file)); } foreach (string uses in mod.uses) { InstalledMod usesMod = GetInstalledMod(uses); usesMod?.usedBy.Remove(mod.Name); } progess?.Report(new ProgressReport($"Mod { mod.ToString() } was uninstalled successfully.", 1f)); InstalledMods.Remove(mod); SaveConfig(); return true; })); }
public Task <InstalledMod> UpdateMod(InstalledMod currentModVersion, Mod newModVersion, IProgress <ProgressReport> progress = null) { return(Task.Run(async() => { if (currentModVersion >= newModVersion) { progress?.Report(new ProgressReport($"Update skipped: a newer or equal version was already installed.", 1f)); return currentModVersion; } progress?.Report(new ProgressReport($"Removing old version: { currentModVersion.Version } ...", 0.1f)); if (await UninstallMod(currentModVersion, true, ProgressReport.Partial(progress, 0.1f, 0.4f))) { InstalledMod newInstalledVersion = await InstallMod(newModVersion, ProgressReport.Partial(progress, 0.5f, 0.5f)); if (newInstalledVersion != null) { newInstalledVersion.usedBy = currentModVersion.usedBy; newInstalledVersion.uses = currentModVersion.uses; newInstalledVersion.preventRemoval = currentModVersion.preventRemoval; progress?.Report(new ProgressReport($"Update succeeded: { currentModVersion } -> { newModVersion }", 1f)); return newInstalledVersion; } else { progress?.Report(new ProgressReport($"Update failed: Could not install new version.", 1f)); return null; } } else { progress?.Report(new ProgressReport($"Update failed: Could not remove old version.", 1f)); return null; } })); }
public async Task UninstallAllMods(bool showIPAConsole = false, IProgress <ProgressReport> progress = null) { progress?.Report(new ProgressReport("Unpatching...", 0.1f)); await RunIPA(revert : true, wait : showIPAConsole, shown : showIPAConsole); List <InstalledMod> toRemove = config.installedMods.OrderBy((e) => e.usedBy.Count).ToList(); for (int m = 0; m < toRemove.Count; m++) { InstalledMod mod = toRemove[m]; progress?.Report(new ProgressReport($"Removing { mod }...", 0.25f + (float)(m + 1) / toRemove.Count * 0.7f)); await UninstallMod(mod, true); } config.installedMods.Clear(); SaveConfig(); progress?.Report(new ProgressReport($"Done removing { toRemove.Count } mods.", 1f)); }
public Mod GetModFromLocal(InstalledMod mod) { return(AllMods.FirstOrDefault((e) => e.Version == mod.Version && string.Compare(e.Name, mod.Name, StringComparison.OrdinalIgnoreCase) == 0)); }
/*public Task<bool> DownloadMod(Mod mod, string archiveDestination, IProgress<ProgressReport> progress = null) * { * }*/ public Task <InstalledMod> InstallMod(Mod mod, IProgress <ProgressReport> progress = null) { return(Task.Run(async() => { progress?.Report(new ProgressReport($"Starting to install { mod } ...", 0.1f)); if (!mod.IsInformationKnown) { mod = beatMods.GetModFromId(mod.Id); if (mod == null) { progress?.Report(new ProgressReport($"Install failed: mod with id { mod.Id } could not be found.", 1f)); return null; } } if (IsInstalledAnyVersion(mod)) { progress?.Report(new ProgressReport($"Install skipped: another version of this mod was already installed.", 1f)); return GetInstalledModIgnoreVersion(mod); } // Every mod should require BSIPA if (string.Compare(mod.Name, Mod.BSIPA, StringComparison.OrdinalIgnoreCase) != 0 && !mod.dependencies.Any((e) => string.Compare(e.Name, Mod.BSIPA, StringComparison.OrdinalIgnoreCase) == 0)) { Mod bsipa = beatMods.GetMostRecentModWithName(Mod.BSIPA, BeatSaberVersion); if (bsipa == null) { progress?.Report(new ProgressReport($"Install failed: BSIPA (required) could not be found as a dependency.", 1f)); return null; } mod.dependencies.Add(bsipa); } Mod.Download md = mod.GetBestDownloadFor(config.beatSaberType); if (string.IsNullOrEmpty(md.DownloadUrl)) { progress?.Report(new ProgressReport($"Install failed: there was no compatible plugin file available for { config.beatSaberType }", 1f)); return null; } string zipDownloadLocation = Path.Combine(ModArchivesDownloadLocation, mod.GetArchiveName()); new FileInfo(zipDownloadLocation).Directory.Create(); DownloadZip: if (!File.Exists(zipDownloadLocation)) { if (beatMods.IsOffline) { progress?.Report(new ProgressReport($"Install failed: mod { mod } is not offline available.", 1f)); return null; } using (WebClient wc = new WebClient()) { wc.DownloadProgressChanged += (sender, e) => progress?.Report(new ProgressReport($"Downloading { mod } ...", 0.1f + e.ProgressPercentage / 100f * 0.3f)); await wc.DownloadFileTaskAsync(md.DownloadUrl, zipDownloadLocation); } } InstalledMod localMod = new InstalledMod(mod, BeatSaberType); try { using (FileStream fs = new FileStream(zipDownloadLocation, FileMode.Open)) using (ZipArchive archive = new ZipArchive(fs)) { Progress <float> extractProgress = new Progress <float>((i) => progress?.Report(new ProgressReport($"Extracting { mod.ToString() } ...", 0.4f + i * 0.3f))); localMod.affectedFiles = archive.ExtractToDirectory(BeatSaberDirectory, true, false, extractProgress); } } catch (InvalidDataException) { File.Delete(zipDownloadLocation); goto DownloadZip; } for (int d = 0; d < mod.dependencies.Count; d++) { Mod dependency = mod.dependencies[d]; if (dependency.IsInformationKnown) // Install the most recent that is compatible with the game's version { Mod mostRecentCompatible = beatMods.GetMostRecentModWithName(dependency.Name, BeatSaberVersion); if (mostRecentCompatible != null) { dependency = mostRecentCompatible; } } progress?.Report(new ProgressReport($"Installing dependencies: { dependency.ToString() } ...", 0.7f + (float)(d + 1) / mod.dependencies.Count * 0.3f)); InstalledMod installedDependency = await InstallMod(dependency); if (!localMod.uses.Contains(installedDependency.Name)) { localMod.uses.Add(installedDependency.Name); } if (installedDependency != null) { if (!installedDependency.usedBy.Contains(localMod.Name)) { installedDependency.usedBy.Add(localMod.Name); } } else { progress?.Report(new ProgressReport($"Could not install dependency: { dependency.ToString() }, skipped.", 0.7f + (float)(d + 1) / mod.dependencies.Count * 0.3f)); } } if (RemoveModArchivesAfterInstall) { progress?.Report(new ProgressReport($"Removing archive...", 0.95f)); File.Delete(zipDownloadLocation); } else { if (!beatMods.OfflineMods.Contains(mod)) { beatMods.OfflineMods.Add(mod); } } if (string.Compare(mod.Name, Mod.BSIPA, StringComparison.OrdinalIgnoreCase) == 0) { progress?.Report(new ProgressReport($"Patching Beat Saber...", 1f)); await RunIPA(); } progress?.Report(new ProgressReport($"Mod { mod.ToString() } was installed successfully.", 1f)); InstalledMods.Add(localMod); SaveConfig(); return localMod; })); }