Esempio n. 1
0
 public void TestSetup()
 {
     WorkQueue.Init((x, y, z) => { }, (min, max) => { });
     validate = new ValidateModlist();
     validate.LoadAuthorPermissionsFromString(permissions);
     validate.LoadServerWhitelist(server_whitelist);
 }
Esempio n. 2
0
        public override async Task <JobResult> Execute(DBContext db, SqlService sql, AppSettings settings)
        {
            Utils.Log("Starting Modlist Validation");
            var modlists = await ModlistMetadata.LoadFromGithub();

            using (var queue = new WorkQueue())
            {
                var whitelists = new ValidateModlist(queue);
                await whitelists.LoadListsFromGithub();

                foreach (var list in modlists)
                {
                    try
                    {
                        await ValidateList(db, list, queue, whitelists);
                    }
                    catch (Exception ex)
                    {
                        Utils.Log(ex.ToString());
                    }
                }
            }

            return(JobResult.Success());
        }
Esempio n. 3
0
        private async Task <bool> IsValid(SqlService sql, ValidateModlist whitelists, Archive archive)
        {
            try
            {
                if (!archive.State.IsWhitelisted(whitelists.ServerWhitelist))
                {
                    return(false);
                }

                try
                {
                    if (archive.State is NexusDownloader.State state)
                    {
                        if (await ValidateNexusFast(sql, state))
                        {
                            return(true);
                        }
                    }
                    else if (archive.State is GoogleDriveDownloader.State)
                    {
                        // Disabled for now
                        return(true);
                    }
                    else if (archive.State is HTTPDownloader.State hstate &&
                             hstate.Url.StartsWith("https://wabbajack"))
                    {
                        return(true);
                    }
                    else
                    {
                        if (await archive.State.Verify(archive))
                        {
                            return(true);
                        }
                    }
                }
                catch (Exception)
                {
                    // ignored
                }

                Utils.Log($"{archive.State.PrimaryKeyString} is broken, looking for upgrade: {archive.Name}");
                var result = await ClientAPI.GetModUpgrade(archive.Hash);

                if (result != null)
                {
                    Utils.Log($"{archive.State.PrimaryKeyString} is broken, upgraded to {result.State.PrimaryKeyString} {result.Name}");
                    return(true);
                }

                Utils.Log($"{archive.State.PrimaryKeyString} is broken, no alternative found");
                return(false);
            }
Esempio n. 4
0
        /// <summary>
        /// Runs the Validation of a Modlist
        /// </summary>
        /// <param name="opts"></param>
        /// <returns>
        /// <para>
        /// <c>-1</c> bad Input
        /// <c>0</c> valid modlist
        /// <c>1</c> broken modlist
        /// </para>
        /// </returns>
        protected override async Task <int> Run()
        {
            if (!File.Exists(Input))
            {
                Console.WriteLine($"The file {Input} does not exist!");
                return(-1);
            }


            if (!Input.EndsWith(Consts.ModListExtension))
            {
                Console.WriteLine($"The file {Input} does not end with {Consts.ModListExtension}!");
                return(-1);
            }

            ModList modlist;

            try
            {
                modlist = AInstaller.LoadFromFile(Input);
            }
            catch (Exception e)
            {
                Console.WriteLine($"Error while loading the Modlist!\n{e}");
                return(1);
            }

            if (modlist == null)
            {
                Console.WriteLine($"The Modlist could not be loaded!");
                return(1);
            }


            var queue = new WorkQueue();

            try
            {
                ValidateModlist.RunValidation(queue, modlist).RunSynchronously();
            }
            catch (Exception e)
            {
                Console.WriteLine($"Error during Validation!\n{e}");
                return(1);
            }

            Console.WriteLine("The Modlist passed the Validation");
            return(0);
        }
Esempio n. 5
0
        private async Task ValidateList(SqlService sql, ModlistMetadata list, WorkQueue queue, ValidateModlist whitelists)
        {
            var modlistPath = Consts.ModListDownloadFolder.Combine(list.Links.MachineURL + Consts.ModListExtension);

            if (list.NeedsDownload(modlistPath))
            {
                modlistPath.Delete();

                var state = DownloadDispatcher.ResolveArchive(list.Links.Download);
                Utils.Log($"Downloading {list.Links.MachineURL} - {list.Title}");
                await state.Download(modlistPath);
            }
            else
            {
                Utils.Log($"No changes detected from downloaded modlist");
            }


            Utils.Log($"Loading {modlistPath}");

            var installer = AInstaller.LoadFromFile(modlistPath);

            Utils.Log($"{installer.Archives.Count} archives to validate");

            await DownloadDispatcher.PrepareAll(installer.Archives.Select(a => a.State));


            var validated = (await installer.Archives
                             .PMap(queue, async archive =>
            {
                var isValid = await IsValid(sql, whitelists, archive);

                return(new DetailedStatusItem {
                    IsFailing = !isValid, Archive = archive
                });
            }))
                            .ToList();


            var status = new DetailedStatus
            {
                Name             = list.Title,
                Archives         = validated.OrderBy(v => v.Archive.Name).ToList(),
                DownloadMetaData = list.DownloadMetadata,
                HasFailures      = validated.Any(v => v.IsFailing)
            };

            var dto = new ModListStatus
            {
                Id      = list.Links.MachineURL,
                Summary = new ModListSummary
                {
                    Name       = status.Name,
                    MachineURL = list.Links?.MachineURL ?? status.Name,
                    Checked    = status.Checked,
                    Failed     = status.Archives.Count(a => a.IsFailing),
                    Passed     = status.Archives.Count(a => !a.IsFailing),
                },
                DetailedStatus = status,
                Metadata       = list
            };

            Utils.Log(
                $"Writing Update for {dto.Summary.Name} - {dto.Summary.Failed} failed - {dto.Summary.Passed} passed");
            await sql.UpdateModListStatus(dto);

            Utils.Log(
                $"Done updating {dto.Summary.Name}");
        }
Esempio n. 6
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);
        }
Esempio n. 7
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);
        }
 public ContentRightsManagementTests()
 {
     queue    = new WorkQueue();
     validate = new ValidateModlist();
     validate.LoadServerWhitelist(server_whitelist);
 }
Esempio n. 9
0
        protected override async Task <bool> _Begin(CancellationToken cancel)
        {
            if (cancel.IsCancellationRequested)
            {
                return(false);
            }

            Info($"Starting Vortex compilation for {GameName} at {GamePath} with staging folder at {StagingFolder} and downloads folder at {DownloadsFolder}.");

            ConfigureProcessor(12, ConstructDynamicNumThreads(await RecommendQueueSize()));
            UpdateTracker.Reset();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Parsing deployment file");
            ParseDeploymentFile();

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Creating metas for archives");
            await CreateMetaFiles();

            Utils.Log($"VFS File Location: {VFSCacheName}");

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            await VFS.IntegrateFromFile(VFSCacheName);

            var roots = new List <string> {
                StagingFolder, GamePath, DownloadsFolder
            };

            AddExternalFolder(ref roots);

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Indexing folders");
            await VFS.AddRoots(roots);

            await VFS.WriteToFile(VFSCacheName);

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Cleaning output folder");
            if (Directory.Exists(ModListOutputFolder))
            {
                Utils.DeleteDirectory(ModListOutputFolder);
            }

            Directory.CreateDirectory(ModListOutputFolder);

            UpdateTracker.NextStep("Finding Install Files");
            var vortexStagingFiles = Directory.EnumerateFiles(StagingFolder, "*", SearchOption.AllDirectories)
                                     .Where(p => p.FileExists() && p != StagingMarkerName && !p.Contains(Consts.ManualGameFilesDir))
                                     .Select(p => new RawSourceFile(VFS.Index.ByRootPath[p], p.RelativeTo(StagingFolder)));

            var vortexDownloads = Directory.EnumerateFiles(DownloadsFolder, "*", SearchOption.AllDirectories)
                                  .Where(p => p.FileExists() && p != DownloadMarkerName)
                                  .Select(p => new RawSourceFile(VFS.Index.ByRootPath[p], p.RelativeTo(DownloadsFolder)));

            var gameFiles = Directory.EnumerateFiles(GamePath, "*", SearchOption.AllDirectories)
                            .Where(p => p.FileExists())
                            .Select(p => new RawSourceFile(VFS.Index.ByRootPath[p], Path.Combine(Consts.GameFolderFilesDir, p.RelativeTo(GamePath))));

            Info("Indexing Archives");
            IndexedArchives = Directory.EnumerateFiles(DownloadsFolder)
                              .Where(f => File.Exists(f + Consts.MetaFileExtension))
                              .Select(f => new IndexedArchive
            {
                File    = VFS.Index.ByRootPath[f],
                Name    = Path.GetFileName(f),
                IniData = (f + Consts.MetaFileExtension).LoadIniFile(),
                Meta    = File.ReadAllText(f + Consts.MetaFileExtension)
            })
                              .ToList();

            Info("Indexing Files");
            IndexedFiles = IndexedArchives.SelectMany(f => f.File.ThisAndAllChildren)
                           .OrderBy(f => f.NestingFactor)
                           .GroupBy(f => f.Hash)
                           .ToDictionary(f => f.Key, f => f.AsEnumerable());

            AllFiles = vortexStagingFiles.Concat(vortexDownloads)
                       .Concat(gameFiles)
                       .DistinctBy(f => f.Path)
                       .ToList();

            Info($"Found {AllFiles.Count} files to build into mod list");

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }
            UpdateTracker.NextStep("Verifying destinations");
            var duplicates = AllFiles.GroupBy(f => f.Path)
                             .Where(fs => fs.Count() > 1)
                             .Select(fs =>
            {
                Utils.Log($"Duplicate files installed to {fs.Key} from : {string.Join(", ", fs.Select(f => f.AbsolutePath))}");
                return(fs);
            }).ToList();

            if (duplicates.Count > 0)
            {
                Error($"Found {duplicates.Count} duplicates, exiting");
            }

            for (var i = 0; i < AllFiles.Count; i++)
            {
                var f = AllFiles[i];
                if (!f.Path.StartsWith(Consts.GameFolderFilesDir) || !IndexedFiles.ContainsKey(f.Hash))
                {
                    continue;
                }

                if (!IndexedFiles.TryGetValue(f.Hash, out var value))
                {
                    continue;
                }

                var element = value.ElementAt(0);

                if (!f.Path.Contains(element.Name))
                {
                    continue;
                }

                IndexedArchive targetArchive = null;
                IndexedArchives.Where(a => a.File.ThisAndAllChildren.Contains(element)).Do(a => targetArchive = a);

                if (targetArchive == null)
                {
                    continue;
                }

                if (targetArchive.IniData?.General?.tag == null || targetArchive.IniData?.General?.tag != Consts.WABBAJACK_VORTEX_MANUAL)
                {
                    continue;
                }

                #if DEBUG
                Utils.Log($"Double hash for: {f.AbsolutePath}");
                #endif

                var replace     = f;
                var name        = replace.File.Name;
                var archiveName = targetArchive.Name;
                var elementPath = element.FullPath.Substring(element.FullPath.LastIndexOf('|') + 1);
                var gameToFile  = name.Substring(GamePath.Length + 1).Replace(elementPath, "");
                if (gameToFile.EndsWith("\\"))
                {
                    gameToFile = gameToFile.Substring(0, gameToFile.Length - 1);
                }
                //replace.Path = replace.Path.Replace(Consts.GameFolderFilesDir, Consts.ManualGameFilesDir);
                replace.Path = Path.Combine(Consts.ManualGameFilesDir, archiveName, gameToFile, elementPath);
                //replace.Path = Path.Combine(Consts.ManualGameFilesDir, element.FullPath.Substring(DownloadsFolder.Length + 1).Replace('|', '\\'));
                AllFiles.RemoveAt(i);
                AllFiles.Insert(i, replace);
                //AllFiles.Replace(f, replace);
            }

            var stack = MakeStack();

            Info("Running Compilation Stack");
            var results = await AllFiles.PMap(Queue, f => RunStack(stack.Where(s => s != null), f));

            var noMatch = results.OfType <NoMatch>().ToList();
            PrintNoMatches(noMatch);
            if (CheckForNoMatchExit(noMatch))
            {
                return(false);
            }

            InstallDirectives = results.Where(i => !(i is IgnoredDirectly)).ToList();

            Info("Getting Nexus api_key, please click authorize if a browser window appears");

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

            ModList = new ModList
            {
                Name        = ModListName ?? "",
                Author      = ModListAuthor ?? "",
                Description = ModListDescription ?? "",
                Readme      = ModListReadme ?? "",
                Image       = ModListImage ?? "",
                Website     = ModListWebsite ?? "",
                Archives    = SelectedArchives.ToList(),
                ModManager  = ModManager.Vortex,
                Directives  = InstallDirectives,
                GameType    = Game
            };

            UpdateTracker.NextStep("Running Validation");
            await ValidateModlist.RunValidation(Queue, ModList);

            UpdateTracker.NextStep("Generating Report");
            GenerateManifest();

            UpdateTracker.NextStep("Exporting ModList");
            ExportModList();

            ResetMembers();

            UpdateTracker.NextStep("Done Building ModList");

            return(true);
        }
Esempio n. 10
0
        private static async Task ValidateList(DBContext db, ModlistMetadata list, WorkQueue queue, ValidateModlist whitelists)
        {
            var existing = await db.ModListStatus.FindOneAsync(l => l.Id == list.Links.MachineURL);

            var modlist_path = Path.Combine(Consts.ModListDownloadFolder, list.Links.MachineURL + Consts.ModListExtension);

            if (list.NeedsDownload(modlist_path))
            {
                if (File.Exists(modlist_path))
                {
                    File.Delete(modlist_path);
                }

                var state = DownloadDispatcher.ResolveArchive(list.Links.Download);
                Utils.Log($"Downloading {list.Links.MachineURL} - {list.Title}");
                await state.Download(modlist_path);
            }
            else
            {
                Utils.Log($"No changes detected from downloaded modlist");
            }


            Utils.Log($"Loading {modlist_path}");

            var installer = AInstaller.LoadFromFile(modlist_path);

            Utils.Log($"{installer.Archives.Count} archives to validate");

            DownloadDispatcher.PrepareAll(installer.Archives.Select(a => a.State));


            var validated = (await installer.Archives
                             .PMap(queue, async archive =>
            {
                bool is_failed;
                try
                {
                    is_failed = !(await archive.State.Verify(archive)) || !archive.State.IsWhitelisted(whitelists.ServerWhitelist);
                }
                catch (Exception)
                {
                    is_failed = false;
                }

                return(new DetailedStatusItem {
                    IsFailing = is_failed, Archive = archive
                });
            }))
                            .ToList();


            var status = new DetailedStatus
            {
                Name             = list.Title,
                Archives         = validated.OrderBy(v => v.Archive.Name).ToList(),
                DownloadMetaData = list.DownloadMetadata,
                HasFailures      = validated.Any(v => v.IsFailing)
            };

            var dto = new ModListStatus
            {
                Id      = list.Links.MachineURL,
                Summary = new ModlistSummary
                {
                    Name    = status.Name,
                    Checked = status.Checked,
                    Failed  = status.Archives.Count(a => a.IsFailing),
                    Passed  = status.Archives.Count(a => !a.IsFailing),
                },
                DetailedStatus = status,
                Metadata       = list
            };

            Utils.Log(
                $"Writing Update for {dto.Summary.Name} - {dto.Summary.Failed} failed - {dto.Summary.Passed} passed");
            await ModListStatus.Update(db, dto);

            Utils.Log(
                $"Done updating {dto.Summary.Name}");
        }
Esempio n. 11
0
 public ContentRightsManagementTests(ITestOutputHelper output) : base(output)
 {
     queue    = new WorkQueue();
     validate = new ValidateModlist();
     validate.LoadServerWhitelist(server_whitelist);
 }
Esempio n. 12
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");

            DesiredThreads.OnNext(DiskThreads);
            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("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} ({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");
                }
            }

            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);
        }