public void Compile() { Info($"Indexing {MO2Folder}"); VFS.AddRoot(MO2Folder); Info($"Indexing {GamePath}"); VFS.AddRoot(GamePath); var mo2_files = Directory.EnumerateFiles(MO2Folder, "*", SearchOption.AllDirectories) .Where(p => p.FileExists()) .Select(p => new RawSourceFile(VFS.Lookup(p)) { Path = p.RelativeTo(MO2Folder) }); var game_files = Directory.EnumerateFiles(GamePath, "*", SearchOption.AllDirectories) .Where(p => p.FileExists()) .Select(p => new RawSourceFile(VFS.Lookup(p)) { Path = Path.Combine(Consts.GameFolderFilesDir, p.RelativeTo(GamePath)) }); var loot_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "LOOT"); Info($"Indexing {loot_path}"); VFS.AddRoot(loot_path); var loot_files = Directory.EnumerateFiles(loot_path, "userlist.yaml", SearchOption.AllDirectories) .Where(p => p.FileExists()) .Select(p => new RawSourceFile(VFS.Lookup(p)) { Path = Path.Combine(Consts.LOOTFolderFilesDir, p.RelativeTo(loot_path)) }); Info($"Indexing Archives"); IndexedArchives = Directory.EnumerateFiles(MO2DownloadsFolder) .Where(f => Consts.SupportedArchives.Contains(Path.GetExtension(f))) .Where(f => File.Exists(f + ".meta")) .Select(f => new IndexedArchive() { File = VFS.Lookup(f), Name = Path.GetFileName(f), IniData = (f + ".meta").LoadIniFile(), Meta = File.ReadAllText(f + ".meta") }) .ToList(); Info($"Indexing Files"); IndexedFiles = IndexedArchives.PMap(f => { Status($"Finding files in {Path.GetFileName(f.File.FullPath)}"); return(VFS.FilesInArchive(f.File)); }) .SelectMany(fs => fs) .OrderByDescending(f => f.TopLevelArchive.LastModified) .GroupBy(f => f.Hash) .ToDictionary(f => f.Key, f => f.AsEnumerable()); Info("Searching for mod files"); AllFiles = mo2_files.Concat(game_files) .Concat(loot_files) .ToList(); Info("Found {0} files to build into mod list", AllFiles.Count); ExtraFiles = new ConcurrentBag <Directive>(); ModInis = Directory.EnumerateDirectories(Path.Combine(MO2Folder, "mods")) .Select(f => { var mod_name = Path.GetFileName(f); var meta_path = Path.Combine(f, "meta.ini"); if (File.Exists(meta_path)) { return(mod_name, meta_path.LoadIniFile()); } return(null, null); }) .Where(f => f.Item2 != null) .ToDictionary(f => f.Item1, f => f.Item2); var stack = MakeStack(); Info("Running Compilation Stack"); var results = AllFiles.PMap(f => RunStack(stack, f)).ToList(); // Add the extra files that were generated by the stack Info($"Adding {ExtraFiles.Count} that were generated by the stack"); results = results.Concat(ExtraFiles).ToList(); var nomatch = results.OfType <NoMatch>(); Info("No match for {0} files", nomatch.Count()); foreach (var file in nomatch) { Info(" {0}", file.To); } if (nomatch.Count() > 0) { if (IgnoreMissingFiles) { Info("Continuing even though files were missing at the request of the user."); } else { Info("Exiting due to no way to compile these files"); return; } } InstallDirectives = results.Where(i => !(i is IgnoredDirectly)).ToList(); Info("Getting nexus api_key please click authorize if a browser window appears"); NexusKey = NexusAPI.GetNexusAPIKey(); User = NexusAPI.GetUserStatus(NexusKey); if (!User.is_premium) { Info($"User {User.name} is not a premium Nexus user, cannot continue"); } GatherArchives(); BuildPatches(); ModList = new ModList() { Archives = SelectedArchives, Directives = InstallDirectives, Name = MO2Profile }; GenerateReport(); PatchExecutable(); ResetMembers(); ShowReport(); Info("Done Building Modpack"); }