private async Task UpdateModAsyncInner(Mod oldMod, ModRelease newestRelease, string token, IProgress <double> progress, CancellationToken cancellationToken) { FileInfo modFile = await ModWebsite.UpdateReleaseAsync(newestRelease, GlobalCredentials.Instance.Username, token, progress, cancellationToken); Mod newMod; if (App.Instance.Settings.AlwaysUpdateZipped || (oldMod is ZippedMod)) { newMod = new ZippedMod(oldMod.Name, newestRelease.Version, newestRelease.FactorioVersion, modFile, InstalledMods, InstalledModpacks); } else { DirectoryInfo modDirectory = await Task.Run(() => { progress.Report(2); DirectoryInfo modsDirectory = App.Instance.Settings.GetModDirectory(newestRelease.FactorioVersion); ZipFile.ExtractToDirectory(modFile.FullName, modsDirectory.FullName); modFile.Delete(); return(new DirectoryInfo(Path.Combine(modsDirectory.FullName, modFile.NameWithoutExtension()))); }); newMod = new ExtractedMod(oldMod.Name, newestRelease.Version, newestRelease.FactorioVersion, modDirectory, InstalledMods, InstalledModpacks); } InstalledMods.Add(newMod); if (oldMod.Update(newMod)) { InstalledModpacks.ExchangeMods(oldMod, newMod); } ModpackTemplateList.Instance.Update(InstalledModpacks); ModpackTemplateList.Instance.Save(); }
public static void AddMod(IInstalledMod mod) { SyncContext.Send(state => InstalledMods.Add(mod), null); }
/// <summary> /// Installs a mod into the game. /// </summary> public async Task <bool> Install(Mod m) { string mPath = Mod.InstallPath + m.Slug; string mBackupPath = Mod.BackupPath + m.Slug; if (!Directory.Exists(mBackupPath)) { Directory.CreateDirectory(mBackupPath); } Console.WriteLine("Install Mod"); // Before installing get the list of affected ice files and make sure no installed // mod uses the same files if (!ModCollision(m)) { m.ContentsMD5 = new Dictionary <string, string>(); foreach (var f in Directory.GetFiles(mPath)) { var fileName = Path.GetFileName(f); string from = mPath + "\\" + fileName; string destin = settings.PSO2Dir + "\\" + fileName; string backup = mBackupPath + "\\" + fileName; if (!File.Exists(from)) { MessageBox.Show("Mod file(s) are not found. please reinstall mod.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return(false); } if (!File.Exists(destin)) { // backup target no match continue; } //Console.WriteLine ("Backup FROM: " + settings.PSO2Dir + "\\" + fileName + " TO: " + mBackupPath + "\\" + fileName); //Console.WriteLine ("Replace FROM: " + mPath + "\\" + fileName + " TO: " + settings.PSO2Dir + "\\" + fileName); if (!Mod.modSettingsFiles.Contains(fileName)) { var BackupTask = new Helpers.FileCopy(destin, backup); var ApplyModTask = new Helpers.FileCopy(from, destin); // This is done here because some mods will have dynamic/setup content so we create // the md5 hash over the file we copy on the pso2 dir m.ContentsMD5.Add(fileName, Helpers.CheckMD5(destin)); Console.WriteLine("Backup Task"); await Task.Run(() => BackupTask.StartCopy()); Console.WriteLine("Apply Mod Task"); await Task.Run(() => ApplyModTask.StartCopy()); } } InstalledMods.Add(m); AvailableMods.Remove(m); UpdateSettings(); } else { MessageBox.Show("Another installed mod is using the same files this mod will try to overwrite. Installation cancelled", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return(false); } return(true); }
private async Task DownloadSelectedModRelease() { string token; if (GlobalCredentials.Instance.LogIn(Window, out token)) { var progressWindow = new ProgressWindow { Owner = Window }; var progressViewModel = (ProgressViewModel)progressWindow.ViewModel; progressViewModel.ActionName = App.Instance.GetLocalizedResourceString("DownloadingAction"); progressViewModel.ProgressDescription = string.Format(App.Instance.GetLocalizedResourceString("DownloadingDescription"), selectedRelease.FileName); progressViewModel.CanCancel = true; var cancellationSource = new CancellationTokenSource(); progressViewModel.CancelRequested += (sender, e) => cancellationSource.Cancel(); var progress = new Progress <double>(p => progressViewModel.Progress = p); Mod newMod; try { Task closeWindowTask = null; try { Task <Mod> downloadTask = ModWebsite.DownloadReleaseAsync(selectedRelease, GlobalCredentials.Instance.Username, token, progress, cancellationSource.Token, InstalledMods, MainViewModel.Instance.Modpacks); closeWindowTask = downloadTask.ContinueWith(t => progressWindow.Dispatcher.Invoke(progressWindow.Close)); progressWindow.ShowDialog(); newMod = await downloadTask; } finally { if (closeWindowTask != null) { await closeWindowTask; } } } catch (HttpRequestException) { MessageBox.Show(Window, App.Instance.GetLocalizedMessage("InternetConnection", MessageType.Error), App.Instance.GetLocalizedMessageTitle("InternetConnection", MessageType.Error), MessageBoxButton.OK, MessageBoxImage.Error); return; } if (!cancellationSource.IsCancellationRequested) { if (newMod != null) { InstalledMods.Add(newMod); } UpdateSelectedReleases(); } } }
/*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; })); }
private async Task UpdateSelectedModRelease() { string token; if (GlobalCredentials.Instance.LogIn(Window, out token)) { ModRelease newestRelease = GetNewestRelease(ExtendedInfo, SelectedRelease); Mod mod = InstalledMods.FindByFactorioVersion(SelectedMod.Name, newestRelease.FactorioVersion); var zippedMod = mod as ZippedMod; var extractedMod = mod as ExtractedMod; var cancellationSource = new CancellationTokenSource(); var progressWindow = new ProgressWindow { Owner = Window }; var progressViewModel = (ProgressViewModel)progressWindow.ViewModel; progressViewModel.ActionName = App.Instance.GetLocalizedResourceString("UpdatingAction"); progressViewModel.ProgressDescription = string.Format(App.Instance.GetLocalizedResourceString("DownloadingDescription"), newestRelease.FileName); progressViewModel.CanCancel = true; progressViewModel.CancelRequested += (sender, e) => cancellationSource.Cancel(); IProgress <double> progress = new Progress <double>(p => { if (p > 1) { progressViewModel.ProgressDescription = App.Instance.GetLocalizedResourceString("ExtractingDescription"); progressViewModel.IsIndeterminate = true; progressViewModel.CanCancel = false; } else { progressViewModel.Progress = p; } }); try { Task closeWindowTask = null; try { Task downloadTask = ModWebsite.UpdateReleaseAsync(newestRelease, GlobalCredentials.Instance.Username, token, progress, cancellationSource.Token); if (extractedMod != null) { downloadTask = downloadTask.ContinueWith(t => { progress.Report(2); FileInfo modFile = ((Task <FileInfo>)t).Result; DirectoryInfo modDirectory = App.Instance.Settings.GetModDirectory(newestRelease.FactorioVersion); ZipFile.ExtractToDirectory(modFile.FullName, modDirectory.FullName); modFile.Delete(); return(new DirectoryInfo(Path.Combine(modDirectory.FullName, modFile.NameWithoutExtension()))); }, TaskContinuationOptions.NotOnFaulted | TaskContinuationOptions.NotOnCanceled); } closeWindowTask = downloadTask.ContinueWith(t => progressWindow.Dispatcher.Invoke(progressWindow.Close)); progressWindow.ShowDialog(); if (zippedMod != null) { FileInfo newModFile = await(Task <FileInfo>) downloadTask; if (zippedMod.FactorioVersion == newestRelease.FactorioVersion) { zippedMod.Update(newModFile, newestRelease.Version); } else { var newMod = new ZippedMod(zippedMod.Name, newestRelease.Version, newestRelease.FactorioVersion, newModFile, InstalledMods, MainViewModel.Instance.Modpacks); InstalledMods.Add(newMod); foreach (var modpack in MainViewModel.Instance.Modpacks) { ModReference reference; if (modpack.Contains(zippedMod, out reference)) { modpack.Mods.Remove(reference); modpack.Mods.Add(new ModReference(newMod, modpack)); } } zippedMod.File.Delete(); InstalledMods.Remove(extractedMod); } } if (extractedMod != null) { DirectoryInfo newModDirectory = await(Task <DirectoryInfo>) downloadTask; if (extractedMod.FactorioVersion == newestRelease.FactorioVersion) { extractedMod.Update(newModDirectory, newestRelease.Version); } else { var newMod = new ExtractedMod(extractedMod.Name, newestRelease.Version, newestRelease.FactorioVersion, newModDirectory, InstalledMods, MainViewModel.Instance.Modpacks); InstalledMods.Add(newMod); foreach (var modpack in MainViewModel.Instance.Modpacks) { ModReference reference; if (modpack.Contains(extractedMod, out reference)) { modpack.Mods.Remove(reference); modpack.Mods.Add(new ModReference(newMod, modpack)); } } extractedMod.Directory.Delete(true); InstalledMods.Remove(extractedMod); ModpackTemplateList.Instance.Update(MainViewModel.Instance.Modpacks); ModpackTemplateList.Instance.Save(); } } } finally { if (closeWindowTask != null) { await closeWindowTask; } } } catch (HttpRequestException) { MessageBox.Show(Window, App.Instance.GetLocalizedMessage("InternetConnection", MessageType.Error), App.Instance.GetLocalizedMessageTitle("InternetConnection", MessageType.Error), MessageBoxButton.OK, MessageBoxImage.Error); return; } SelectedRelease = null; foreach (var release in SelectedReleases) { release.IsInstalled = InstalledMods.Contains(selectedMod.Name, release.Version); release.IsVersionInstalled = !release.IsInstalled && InstalledMods.ContainsByFactorioVersion(selectedMod.Name, release.FactorioVersion); } } }