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();
        }
Example #2
0
 public static void AddMod(IInstalledMod mod)
 {
     SyncContext.Send(state => InstalledMods.Add(mod), null);
 }
Example #3
0
        /// <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;
            }));
        }
Example #6
0
        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);
                }
            }
        }