Exemplo n.º 1
0
        /// <summary>
        /// We don't want to make the installer index all the archives, that's just a waste of time, so instead
        /// we'll pass just enough information to VFS to let it know about the files we have.
        /// </summary>
        private void PrimeVFS()
        {
            HashedArchives.Do(a => VFS.AddKnown(new VirtualFile()
            {
                Paths = new string[] { a.Value },
                Hash  = a.Key
            }));
            VFS.RefreshIndexes();


            ModList.Directives
            .OfType <FromArchive>()
            .Do(f =>
            {
                var updated_path = new string[f.ArchiveHashPath.Length];
                f.ArchiveHashPath.CopyTo(updated_path, 0);
                updated_path[0] = VFS.HashIndex[updated_path[0]].Where(e => e.IsConcrete).First().FullPath;
                VFS.AddKnown(new VirtualFile()
                {
                    Paths = updated_path
                });
            });

            VFS.BackfillMissing();
        }
Exemplo n.º 2
0
        public void Install()
        {
            Directory.CreateDirectory(Outputfolder);
            Directory.CreateDirectory(DownloadFolder);

            HashArchives();
            DownloadArchives();
            HashArchives();

            var missing = ModList.Archives.Where(a => !HashedArchives.ContainsKey(a.Hash)).ToList();

            if (missing.Count > 0)
            {
                foreach (var a in missing)
                {
                    Info("Unable to download {0}", a.Name);
                }
                Error("Cannot continue, was unable to download one or more archives");
            }
            BuildFolderStructure();
            InstallArchives();
            InstallIncludedFiles();
            BuildBSAs();

            Info("Installation complete! You may exit the program.");
        }
Exemplo n.º 3
0
        public async Task DownloadArchives()
        {
            var missing = ModList.Archives.Where(a => !HashedArchives.ContainsKey(a.Hash)).ToList();

            Info($"Missing {missing.Count} archives");

            Info("Getting Nexus API Key, if a browser appears, please accept");

            var dispatchers = missing.Select(m => m.State.GetDownloader())
                              .Distinct()
                              .ToList();

            await Task.WhenAll(dispatchers.Select(d => d.Prepare()));

            var nexusDownloader = dispatchers.OfType <NexusDownloader>().FirstOrDefault();

            if (nexusDownloader != null && !await nexusDownloader.HaveEnoughAPICalls(missing))
            {
                throw new Exception($"Not enough Nexus API calls to download this list, please try again after midnight GMT when your API limits reset");
            }

            var validationData = new ValidateModlist();
            await validationData.LoadListsFromGithub();

            foreach (var archive in missing.Where(archive => !archive.State.IsWhitelisted(validationData.ServerWhitelist)))
            {
                throw new Exception($"File {archive.State.PrimaryKeyString} failed validation");
            }

            await DownloadMissingArchives(missing);
        }
Exemplo n.º 4
0
        private void DownloadArchives()
        {
            var missing = ModList.Archives.Where(a => !HashedArchives.ContainsKey(a.Hash)).ToList();

            Info("Missing {0} archives", missing.Count);

            Info("Getting Nexus API Key, if a browser appears, please accept");
            NexusAPIKey = NexusAPI.GetNexusAPIKey();

            DownloadMissingArchives(missing);
        }
Exemplo n.º 5
0
        public async Task HashArchives()
        {
            var hashResults = await DownloadFolder.EnumerateFiles()
                              .Where(e => e.Extension != Consts.HashFileExtension)
                              .PMap(Queue, async e => (await e.FileHashCachedAsync(), e));

            HashedArchives.SetTo(hashResults
                                 .OrderByDescending(e => e.Item2.LastModified)
                                 .GroupBy(e => e.Item1)
                                 .Select(e => e.First())
                                 .Select(e => new KeyValuePair <Hash, AbsolutePath>(e.Item1, e.Item2)));
        }
Exemplo n.º 6
0
        public void Install()
        {
            Directory.CreateDirectory(Outputfolder);
            Directory.CreateDirectory(DownloadFolder);

            if (ModList.Directives.OfType <RemappedInlineFile>().FirstOrDefault() != null ||
                ModList.Directives.OfType <CleanedESM>().FirstOrDefault() != null)
            {
                MessageBox.Show(
                    "In order to do a proper install Wabbajack needs to know where your game folder resides. This is most likely " +
                    "somewhere in one of your Steam folders. Please select this folder on the next screen." +
                    "Note: This is not the install location where Mod Organizer 2 will be installed. ",
                    "Select your Game Folder", MessageBoxButton.OK);
                if (!LocateGameFolder())
                {
                    Info("Stopping installation because game folder was not selected");
                    return;
                }
            }

            HashArchives();
            DownloadArchives();
            HashArchives();

            var missing = ModList.Archives.Where(a => !HashedArchives.ContainsKey(a.Hash)).ToList();

            if (missing.Count > 0)
            {
                foreach (var a in missing)
                {
                    Info("Unable to download {0}", a.Name);
                }
                if (IgnoreMissingFiles)
                {
                    Info("Missing some archives, but continuing anyways at the request of the user");
                }
                else
                {
                    Error("Cannot continue, was unable to download one or more archives");
                }
            }

            PrimeVFS();

            BuildFolderStructure();
            InstallArchives();
            InstallIncludedFiles();
            BuildBSAs();

            Info("Installation complete! You may exit the program.");
            AskToEndorse();
        }
Exemplo n.º 7
0
        public async Task DownloadArchives()
        {
            var missing = ModList.Archives.Where(a => !HashedArchives.ContainsKey(a.Hash)).ToList();
            Info($"Missing {missing.Count} archives");

            Info("Getting Nexus API Key, if a browser appears, please accept");

            var dispatchers = missing.Select(m => m.State.GetDownloader()).Distinct();

            await Task.WhenAll(dispatchers.Select(d => d.Prepare()));

            await DownloadMissingArchives(missing);
        }
Exemplo n.º 8
0
        private void InstallArchives()
        {
            Info("Installing Archives");
            Info("Grouping Install Files");
            var grouped = ModList.Directives
                          .OfType <FromArchive>()
                          .GroupBy(e => e.ArchiveHashPath[0])
                          .ToDictionary(k => k.Key);
            var archives = ModList.Archives
                           .Select(a => new { Archive = a, AbsolutePath = HashedArchives.GetOrDefault(a.Hash) })
                           .Where(a => a.AbsolutePath != null)
                           .ToList();

            Info("Installing Archives");
            archives.PMap(a => InstallArchive(a.Archive, a.AbsolutePath, grouped[a.Archive.Hash]));
        }
Exemplo n.º 9
0
        public async Task InstallArchives()
        {
            Info("Installing Archives");
            Info("Grouping Install Files");
            var grouped = ModList.Directives
                          .OfType <FromArchive>()
                          .GroupBy(e => e.ArchiveHashPath.BaseHash)
                          .ToDictionary(k => k.Key);
            var archives = ModList.Archives
                           .Select(a => new { Archive = a, AbsolutePath = HashedArchives.GetOrDefault(a.Hash) })
                           .Where(a => a.AbsolutePath != null)
                           .ToList();

            Info("Installing Archives");
            await archives.PMap(Queue, UpdateTracker, a => InstallArchive(Queue, a.Archive, a.AbsolutePath, grouped[a.Archive.Hash]));
        }
Exemplo n.º 10
0
 private async Task InstallIncludedDownloadMetas()
 {
     await ModList.Archives
     .PMap(Queue, UpdateTracker, async archive =>
     {
         if (HashedArchives.TryGetValue(archive.Hash, out var paths))
         {
             var metaPath = paths.WithExtension(Consts.MetaFileExtension);
             if (!metaPath.Exists && !(archive.State is GameFileSourceDownloader.State))
             {
                 Status($"Writing {metaPath.FileName}");
                 var meta = AddInstalled(archive.State.GetMetaIni()).ToArray();
                 await metaPath.WriteAllLinesAsync(meta);
             }
         }
     });
 }
Exemplo n.º 11
0
        /// <summary>
        ///     We don't want to make the installer index all the archives, that's just a waste of time, so instead
        ///     we'll pass just enough information to VFS to let it know about the files we have.
        /// </summary>
        public async Task PrimeVFS()
        {
            VFS.AddKnown(HashedArchives.Select(a => new KnownFile
            {
                Paths = new[] { a.Value },
                Hash  = a.Key
            }));


            VFS.AddKnown(
                ModList.Directives
                .OfType <FromArchive>()
                .Select(f => new KnownFile {
                Paths = f.ArchiveHashPath
            }));

            await VFS.BackfillMissing();
        }
Exemplo n.º 12
0
        public async Task HashArchives()
        {
            Utils.Log("Looking for files to hash");
            var toHash = DownloadFolder.EnumerateFiles()
                         .Concat(Game.GameLocation().EnumerateFiles())
                         .ToList();

            Utils.Log($"Found {toHash.Count} files to hash");

            var hashResults = await
                              toHash
                              .PMap(Queue, UpdateTracker, async e => (await e.FileHashCachedAsync(), e));

            HashedArchives.SetTo(hashResults
                                 .OrderByDescending(e => e.Item2.LastModified)
                                 .GroupBy(e => e.Item1)
                                 .Select(e => e.First())
                                 .Select(e => new KeyValuePair <Hash, AbsolutePath>(e.Item1, e.Item2)));
        }
Exemplo n.º 13
0
        private void DownloadArchives()
        {
            var missing = ModList.Archives.Where(a => !HashedArchives.ContainsKey(a.Hash)).ToList();

            Info("Missing {0} archives", missing.Count);

            Info("Getting Nexus API Key, if a browser appears, please accept");
            NexusAPIKey = NexusAPI.GetNexusAPIKey();

            var user_status = NexusAPI.GetUserStatus(NexusAPIKey);

            if (!user_status.is_premium)
            {
                Info($"Automated installs with Wabbajack requires a premium nexus account. {user_status.name} is not a premium account");
                return;
            }

            DownloadMissingArchives(missing);
            return;
        }
Exemplo n.º 14
0
        public async Task DownloadArchives()
        {
            var missing = ModList.Archives.Where(a => !HashedArchives.ContainsKey(a.Hash)).ToList();

            Info($"Missing {missing.Count} archives");

            Info("Getting Nexus API Key, if a browser appears, please accept");

            var dispatchers = missing.Select(m => m.State.GetDownloader()).Distinct();

            await Task.WhenAll(dispatchers.Select(d => d.Prepare()));

            var nexusDownloader = dispatchers.OfType <NexusDownloader>().FirstOrDefault();

            if (nexusDownloader != null && !await nexusDownloader.HaveEnoughAPICalls(missing))
            {
                throw new Exception($"Not enough Nexus API calls to download this list, please try again after midnight GMT when your API limits reset");
            }

            await DownloadMissingArchives(missing);
        }
Exemplo n.º 15
0
        protected override async Task <bool> _Begin(CancellationToken cancel)
        {
            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            var metric = Metrics.Send("begin_install", ModList.Name);

            MessageBox.Show(
                "Vortex Support is still experimental and may produce unexpected results. " +
                "If anything fails go to the special vortex support channels on the discord. @erri120#2285 " +
                "for support.", "Warning",
                MessageBoxButton.OK);

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            ConfigureProcessor(10, await RecommendQueueSize());
            Directory.CreateDirectory(DownloadFolder);

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Hashing Archives");
            await HashArchives();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Downloading Missing Archives");
            await DownloadArchives();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Hashing Remaining Archives");
            await HashArchives();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            var missing = ModList.Archives.Where(a => !HashedArchives.ContainsKey(a.Hash)).ToList();

            if (missing.Count > 0)
            {
                foreach (var a in missing)
                {
                    Info($"Unable to download {a.Name}");
                }
                if (IgnoreMissingFiles)
                {
                    Info("Missing some archives, but continuing anyways at the request of the user");
                }
                else
                {
                    Error("Cannot continue, was unable to download one or more archives");
                }
            }

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Priming VFS");
            await PrimeVFS();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Building Folder Structure");
            BuildFolderStructure();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Installing Archives");
            await InstallArchives();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Installing Included files");
            await InstallIncludedFiles();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Installing Manual files");
            await InstallManualGameFiles();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Installing SteamWorkshopItems");
            await InstallSteamWorkshopItems();

            //InstallIncludedDownloadMetas();
            var metric2 = Metrics.Send("finish_install", ModList.Name);

            UpdateTracker.NextStep("Installation complete! You may exit the program.");
            return(true);
        }
Exemplo n.º 16
0
        protected override async Task <bool> _Begin(CancellationToken cancel)
        {
            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            await Metrics.Send(Metrics.BeginInstall, ModList.Name);

            Utils.Log("Configuring Processor");

            FileExtractor2.FavorPerfOverRAM = FavorPerfOverRam;

            if (GameFolder == null)
            {
                GameFolder = Game.TryGetGameLocation();
            }

            if (GameFolder == null)
            {
                var otherGame = Game.CommonlyConfusedWith.Where(g => g.MetaData().IsInstalled).Select(g => g.MetaData()).FirstOrDefault();
                if (otherGame != null)
                {
                    await Utils.Log(new CriticalFailureIntervention(
                                        $"In order to do a proper install Wabbajack needs to know where your {Game.HumanFriendlyGameName} folder resides. However this game doesn't seem to be installed, we did however find a installed " +
                                        $"copy of {otherGame.HumanFriendlyGameName}, did you install the wrong game?",
                                        $"Could not locate {Game.HumanFriendlyGameName}"))
                    .Task;
                }
                else
                {
                    await Utils.Log(new CriticalFailureIntervention(
                                        $"In order to do a proper install Wabbajack needs to know where your {Game.HumanFriendlyGameName} folder resides. However this game doesn't seem to be installed",
                                        $"Could not locate {Game.HumanFriendlyGameName}"))
                    .Task;
                }

                Utils.Log("Exiting because we couldn't find the game folder.");
                return(false);
            }

            Utils.Log($"Install Folder: {OutputFolder}");
            Utils.Log($"Downloads Folder: {DownloadFolder}");
            Utils.Log($"Game Folder: {GameFolder.Value}");
            Utils.Log($"Wabbajack Folder: {AbsolutePath.EntryPoint}");


            var watcher = new DiskSpaceWatcher(cancel, new[] { OutputFolder, DownloadFolder, GameFolder.Value, AbsolutePath.EntryPoint }, (long)2 << 31,
                                               drive =>
                    {
                    Utils.Log($"Aborting due to low space on {drive.Name}");
                    Abort();
                });
            var watcherTask = watcher.Start();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Validating Game ESMs");
            await ValidateGameESMs();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Creating Output Folders");

            OutputFolder.CreateDirectory();
            DownloadFolder.CreateDirectory();

            if (OutputFolder.Combine(Consts.MO2ModFolderName).IsDirectory&& WarnOnOverwrite)
            {
                if ((await Utils.Log(new ConfirmUpdateOfExistingInstall {
                    ModListName = ModList.Name, OutputFolder = OutputFolder
                }).Task) == ConfirmUpdateOfExistingInstall.Choice.Abort)
                {
                    Utils.Log("Exiting installation at the request of the user, existing mods folder found.");
                    return(false);
                }
            }

            // Reduce to one thread if downloads on HDD, else use specified. Hashing on HDD has no benefit with more threads.
            if (new PhysicalDisk(DownloadFolder.DriveInfo().Name).MediaType == PhysicalDisk.MediaTypes.HDD && ReduceHDDThreads)
            {
                DesiredThreads.OnNext(1);
            }
            else
            {
                DesiredThreads.OnNext(DiskThreads);
            }

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Optimizing ModList");
            await OptimizeModlist();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Hashing Archives");
            await HashArchives();

            // Set to download thread count.
            DesiredThreads.OnNext(DownloadThreads);

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Downloading Missing Archives");
            await DownloadArchives();

            // Reduce to one thread if downloads on HDD, else use specified. Hashing on HDD has no benefit with more threads.
            if (new PhysicalDisk(DownloadFolder.DriveInfo().Name).MediaType == PhysicalDisk.MediaTypes.HDD && ReduceHDDThreads)
            {
                DesiredThreads.OnNext(1);
            }
            else
            {
                DesiredThreads.OnNext(DiskThreads);
            }

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Hashing Remaining Archives");
            await HashArchives();

            var missing = ModList.Archives.Where(a => !HashedArchives.ContainsKey(a.Hash)).ToList();

            if (missing.Count > 0)
            {
                foreach (var a in missing)
                {
                    Info($"Unable to download {a.Name} ({a.State.PrimaryKeyString})");
                }
                if (IgnoreMissingFiles)
                {
                    Info("Missing some archives, but continuing anyways at the request of the user");
                }
                else
                {
                    Error("Cannot continue, was unable to download one or more archives");
                }
            }

            // Reduce to two threads if output on HDD, else use specified. Installing files seems to have a slight benefit with two threads.
            if (new PhysicalDisk(OutputFolder.DriveInfo().Name).MediaType == PhysicalDisk.MediaTypes.HDD && ReduceHDDThreads)
            {
                DesiredThreads.OnNext(2);
            }
            else
            {
                DesiredThreads.OnNext(DiskThreads);
            }

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Extracting Modlist contents");
            await ExtractModlist();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Priming VFS");
            await PrimeVFS();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Building Folder Structure");
            BuildFolderStructure();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Installing Archives");
            await InstallArchives();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Installing Included files");
            await InstallIncludedFiles();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Installing Archive Metas");
            await InstallIncludedDownloadMetas();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Building BSAs");
            await BuildBSAs();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Generating Merges");
            await zEditIntegration.GenerateMerges(this);

            UpdateTracker.NextStep("Set MO2 into portable");
            await ForcePortable();

            UpdateTracker.NextStep("Create Empty Output Mods");
            CreateOutputMods();

            UpdateTracker.NextStep("Updating System-specific ini settings");
            SetScreenSizeInPrefs();

            UpdateTracker.NextStep("Compacting files");
            await CompactFiles();

            UpdateTracker.NextStep("Installation complete! You may exit the program.");
            await ExtractedModlistFolder !.DisposeAsync();
            await Metrics.Send(Metrics.FinishInstall, ModList.Name);

            return(true);
        }
Exemplo n.º 17
0
        protected override async Task <bool> _Begin(CancellationToken cancel)
        {
            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            var metric = Metrics.Send(Metrics.BeginInstall, ModList.Name);
            var result = await Utils.Log(new YesNoIntervention(
                                             "Vortex Support is still experimental and may produce unexpected results. " +
                                             "If anything fails please go to the special Vortex support channels on the Wabbajack Discord and contact @erri120#2285 " +
                                             "for support.", "Continue with experimental feature?")).Task;

            if (result == ConfirmationIntervention.Choice.Abort)
            {
                Utils.Log("Exiting at request of user");
                return(false);
            }

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            ConfigureProcessor(10, ConstructDynamicNumThreads(await RecommendQueueSize()));
            Directory.CreateDirectory(DownloadFolder);

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Hashing Archives");
            await HashArchives();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Downloading Missing Archives");
            await DownloadArchives();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Hashing Remaining Archives");
            await HashArchives();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            var missing = ModList.Archives.Where(a => !HashedArchives.ContainsKey(a.Hash)).ToList();

            if (missing.Count > 0)
            {
                foreach (var a in missing)
                {
                    Info($"Unable to download {a.Name}");
                }
                if (IgnoreMissingFiles)
                {
                    Info("Missing some archives, but continuing anyways at the request of the user");
                }
                else
                {
                    Error("Cannot continue, was unable to download one or more archives");
                }
            }

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Priming VFS");
            await PrimeVFS();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Building Folder Structure");
            BuildFolderStructure();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Installing Archives");
            await InstallArchives();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Installing Included files");
            await InstallIncludedFiles();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Installing Manual files");
            await InstallManualGameFiles();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Installing SteamWorkshopItems");
            await InstallSteamWorkshopItems();

            //InstallIncludedDownloadMetas();
            var metric2 = Metrics.Send(Metrics.FinishInstall, ModList.Name);

            UpdateTracker.NextStep("Installation complete! You may exit the program.");
            return(true);
        }
Exemplo n.º 18
0
        protected override async Task <bool> _Begin(CancellationToken cancel)
        {
            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            var metric = Metrics.Send(Metrics.BeginInstall, ModList.Name);

            Utils.Log("Configuring Processor");

            Queue.SetActiveThreadsObservable(ConstructDynamicNumThreads(await RecommendQueueSize()));

            if (GameFolder == null)
            {
                GameFolder = Game.TryGetGameLocation();
            }

            if (GameFolder == null)
            {
                var otherGame = Game.CommonlyConfusedWith.Where(g => g.MetaData().IsInstalled).Select(g => g.MetaData()).FirstOrDefault();
                if (otherGame != null)
                {
                    await Utils.Log(new CriticalFailureIntervention(
                                        $"In order to do a proper install Wabbajack needs to know where your {Game.HumanFriendlyGameName} folder resides. However this game doesn't seem to be installed, we did however find a installed " +
                                        $"copy of {otherGame.HumanFriendlyGameName}, did you install the wrong game?",
                                        $"Could not locate {Game.HumanFriendlyGameName}"))
                    .Task;
                }
                else
                {
                    await Utils.Log(new CriticalFailureIntervention(
                                        $"In order to do a proper install Wabbajack needs to know where your {Game.HumanFriendlyGameName} folder resides. However this game doesn't seem to be installed",
                                        $"Could not locate {Game.HumanFriendlyGameName}"))
                    .Task;
                }

                Utils.Log("Exiting because we couldn't find the game folder.");
                return(false);
            }

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Validating Game ESMs");
            ValidateGameESMs();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Validating Modlist");
            await ValidateModlist.RunValidation(ModList);

            OutputFolder.CreateDirectory();
            DownloadFolder.CreateDirectory();

            if (OutputFolder.Combine(Consts.MO2ModFolderName).IsDirectory&& WarnOnOverwrite)
            {
                if ((await Utils.Log(new ConfirmUpdateOfExistingInstall {
                    ModListName = ModList.Name, OutputFolder = OutputFolder
                }).Task) == ConfirmUpdateOfExistingInstall.Choice.Abort)
                {
                    Utils.Log("Exiting installation at the request of the user, existing mods folder found.");
                    return(false);
                }
            }

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Optimizing ModList");
            await OptimizeModlist();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Hashing Archives");
            await HashArchives();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Downloading Missing Archives");
            await DownloadArchives();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Hashing Remaining Archives");
            await HashArchives();

            var missing = ModList.Archives.Where(a => !HashedArchives.ContainsKey(a.Hash)).ToList();

            if (missing.Count > 0)
            {
                foreach (var a in missing)
                {
                    Info($"Unable to download {a.Name}");
                }
                if (IgnoreMissingFiles)
                {
                    Info("Missing some archives, but continuing anyways at the request of the user");
                }
                else
                {
                    Error("Cannot continue, was unable to download one or more archives");
                }
            }

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Priming VFS");
            await PrimeVFS();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Building Folder Structure");
            BuildFolderStructure();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Installing Archives");
            await InstallArchives();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Installing Included files");
            await InstallIncludedFiles();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Installing Archive Metas");
            await InstallIncludedDownloadMetas();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Building BSAs");
            await BuildBSAs();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Generating Merges");
            await zEditIntegration.GenerateMerges(this);

            UpdateTracker.NextStep("Set MO2 into portable");
            await ForcePortable();

            UpdateTracker.NextStep("Create Empty Output Mods");
            CreateOutputMods();

            UpdateTracker.NextStep("Updating System-specific ini settings");
            SetScreenSizeInPrefs();

            UpdateTracker.NextStep("Installation complete! You may exit the program.");
            var metric2 = Metrics.Send(Metrics.FinishInstall, ModList.Name);

            return(true);
        }
Exemplo n.º 19
0
        protected override async Task <bool> _Begin(CancellationToken cancel)
        {
            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            var metric = Metrics.Send(Metrics.BeginInstall, ModList.Name);

            ConfigureProcessor(20, ConstructDynamicNumThreads(await RecommendQueueSize()));
            var game = ModList.GameType.MetaData();

            if (GameFolder == null)
            {
                GameFolder = game.GameLocation();
            }

            if (GameFolder == null)
            {
                await Utils.Log(new CriticalFailureIntervention(
                                    $"In order to do a proper install Wabbajack needs to know where your {game.MO2Name} folder resides. We tried looking the " +
                                    "game location up in the Windows Registry but were unable to find it, please make sure you launch the game once before running this installer. ",
                                    "Could not find game location")).Task;

                Utils.Log("Exiting because we couldn't find the game folder.");
                return(false);
            }

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Validating Game ESMs");
            ValidateGameESMs();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Validating Modlist");
            await ValidateModlist.RunValidation(Queue, ModList);

            Directory.CreateDirectory(OutputFolder);
            Directory.CreateDirectory(DownloadFolder);

            if (Directory.Exists(Path.Combine(OutputFolder, "mods")) && WarnOnOverwrite)
            {
                if ((await Utils.Log(new ConfirmUpdateOfExistingInstall {
                    ModListName = ModList.Name, OutputFolder = OutputFolder
                }).Task) == ConfirmUpdateOfExistingInstall.Choice.Abort)
                {
                    Utils.Log("Exiting installation at the request of the user, existing mods folder found.");
                    return(false);
                }
            }

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Optimizing ModList");
            await OptimizeModlist();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Hashing Archives");
            await HashArchives();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Downloading Missing Archives");
            await DownloadArchives();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Hashing Remaining Archives");
            await HashArchives();

            var missing = ModList.Archives.Where(a => !HashedArchives.ContainsKey(a.Hash)).ToList();

            if (missing.Count > 0)
            {
                foreach (var a in missing)
                {
                    Info($"Unable to download {a.Name}");
                }
                if (IgnoreMissingFiles)
                {
                    Info("Missing some archives, but continuing anyways at the request of the user");
                }
                else
                {
                    Error("Cannot continue, was unable to download one or more archives");
                }
            }

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Priming VFS");
            await PrimeVFS();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Building Folder Structure");
            BuildFolderStructure();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Installing Archives");
            await InstallArchives();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Installing Included files");
            await InstallIncludedFiles();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Installing Archive Metas");
            await InstallIncludedDownloadMetas();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Building BSAs");
            await BuildBSAs();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Generating Merges");
            await zEditIntegration.GenerateMerges(this);

            UpdateTracker.NextStep("Set MO2 into portable");
            ForcePortable();

            UpdateTracker.NextStep("Create Empty Output Mods");
            CreateOutputMods();

            UpdateTracker.NextStep("Updating System-specific ini settings");
            SetScreenSizeInPrefs();

            UpdateTracker.NextStep("Installation complete! You may exit the program.");
            var metric2 = Metrics.Send(Metrics.FinishInstall, ModList.Name);

            return(true);
        }