From 1d68ade508cec6c0f821d0a5b1b1e518c71b72a3 Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Wed, 25 Mar 2020 17:15:19 -0600 Subject: [PATCH] Only 36 errors left --- Wabbajack.Common/Paths.cs | 12 +++++ Wabbajack.Lib/AInstaller.cs | 32 ++++++------ .../CompilationSteps/IgnoreDisabledMods.cs | 7 ++- Wabbajack.Lib/FileUploader/AuthorAPI.cs | 4 +- Wabbajack.Lib/MO2Compiler.cs | 51 ++++++++++--------- 5 files changed, 59 insertions(+), 47 deletions(-) diff --git a/Wabbajack.Common/Paths.cs b/Wabbajack.Common/Paths.cs index 34fe3215..0d798569 100644 --- a/Wabbajack.Common/Paths.cs +++ b/Wabbajack.Common/Paths.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; @@ -307,6 +308,17 @@ namespace Wabbajack.Common await using var dest = destFile.Create(); await src.CopyToAsync(dest); } + + public IEnumerable EnumerateDirectories(bool recursive = true) + { + return Directory.EnumerateDirectories(_path, "*", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly) + .Select(p => (AbsolutePath)p); + } + + public async Task WriteAllLinesAsync(params string[] strings) + { + await WriteAllTextAsync(string.Join("\n",strings)); + } } public struct RelativePath : IPath, IEquatable diff --git a/Wabbajack.Lib/AInstaller.cs b/Wabbajack.Lib/AInstaller.cs index 58f3ccaa..aa4a55e8 100644 --- a/Wabbajack.Lib/AInstaller.cs +++ b/Wabbajack.Lib/AInstaller.cs @@ -335,38 +335,39 @@ namespace Wabbajack.Lib var indexed = ModList.Directives.ToDictionary(d => d.To); UpdateTracker.NextStep("Looking for files to delete"); - await Directory.EnumerateFiles(OutputFolder, "*", DirectoryEnumerationOptions.Recursive) + await OutputFolder.EnumerateFiles() .PMap(Queue, UpdateTracker, f => { var relative_to = f.RelativeTo(OutputFolder); Utils.Status($"Checking if ModList file {relative_to}"); - if (indexed.ContainsKey(relative_to) || f.IsInPath(DownloadFolder)) + if (indexed.ContainsKey(relative_to) || f.InFolder(DownloadFolder)) return; Utils.Log($"Deleting {relative_to} it's not part of this ModList"); - File.Delete(f); + f.Delete(); }); Utils.Log("Cleaning empty folders"); var expectedFolders = indexed.Keys + .Select(f => f.RelativeTo(OutputFolder)) // We ignore the last part of the path, so we need a dummy file name - .Append(Path.Combine(DownloadFolder, "_")) + .Append(DownloadFolder.Combine("_")) .SelectMany(path => { // Get all the folders and all the folder parents // so for foo\bar\baz\qux.txt this emits ["foo", "foo\\bar", "foo\\bar\\baz"] - var split = path.Split('\\'); + var split = ((string)path.RelativeTo(OutputFolder)).Split('\\'); return Enumerable.Range(1, split.Length - 1).Select(t => string.Join("\\", split.Take(t))); }) .Distinct() - .Select(p => Path.Combine(OutputFolder, p)) + .Select(p => OutputFolder.Combine(p)) .ToHashSet(); try { - Directory.EnumerateDirectories(OutputFolder, DirectoryEnumerationOptions.Recursive) + OutputFolder.EnumerateDirectories(true) .Where(p => !expectedFolders.Contains(p)) - .OrderByDescending(p => p.Length) + .OrderByDescending(p => p.Size) .Do(Utils.DeleteDirectory); } catch (Exception) @@ -376,19 +377,18 @@ namespace Wabbajack.Lib } UpdateTracker.NextStep("Looking for unmodified files"); - (await indexed.Values.PMap(Queue, UpdateTracker, d => + (await indexed.Values.PMap(Queue, UpdateTracker, async d => { // Bit backwards, but we want to return null for // all files we *want* installed. We return the files // to remove from the install list. Status($"Optimizing {d.To}"); - var path = Path.Combine(OutputFolder, d.To); - if (!File.Exists(path)) return null; + var path = OutputFolder.Combine(d.To); + if (!path.Exists) return null; - var fi = new FileInfo(path); - if (fi.Length != d.Size) return null; + if (path.Size != d.Size) return null; - return path.FileHash() == d.Hash ? d : null; + return await path.FileHashAsync() == d.Hash ? d : null; })) .Where(d => d != null) .Do(d => indexed.Remove(d.To)); @@ -396,8 +396,8 @@ namespace Wabbajack.Lib UpdateTracker.NextStep("Updating ModList"); Utils.Log($"Optimized {ModList.Directives.Count} directives to {indexed.Count} required"); var requiredArchives = indexed.Values.OfType() - .GroupBy(d => d.ArchiveHashPath[0]) - .Select(d => Hash.FromBase64(d.Key)) + .GroupBy(d => d.ArchiveHashPath.BaseHash) + .Select(d => d.Key) .ToHashSet(); ModList.Archives = ModList.Archives.Where(a => requiredArchives.Contains(a.Hash)).ToList(); diff --git a/Wabbajack.Lib/CompilationSteps/IgnoreDisabledMods.cs b/Wabbajack.Lib/CompilationSteps/IgnoreDisabledMods.cs index e2512b83..79b93495 100644 --- a/Wabbajack.Lib/CompilationSteps/IgnoreDisabledMods.cs +++ b/Wabbajack.Lib/CompilationSteps/IgnoreDisabledMods.cs @@ -9,7 +9,7 @@ namespace Wabbajack.Lib.CompilationSteps { public class IgnoreDisabledMods : ACompilationStep { - private readonly IEnumerable _allEnabledMods; + private readonly IEnumerable _allEnabledMods; private readonly MO2Compiler _mo2Compiler; public IgnoreDisabledMods(ACompiler compiler) : base(compiler) @@ -20,15 +20,14 @@ namespace Wabbajack.Lib.CompilationSteps _allEnabledMods = _mo2Compiler.SelectedProfiles .SelectMany(p => _mo2Compiler.MO2Folder.Combine("profiles", p, "modlist.txt").ReadAllLines()) .Where(line => line.StartsWith("+") || line.EndsWith("_separator")) - .Select(line => line.Substring(1)) + .Select(line => line.Substring(1).RelativeTo(_mo2Compiler.MO2ModsFolder)) .Concat(alwaysEnabled) - .Select(line => Path.Combine((string)Consts.MO2ModFolderName, line) + "\\") .ToList(); } public override async ValueTask Run(RawSourceFile source) { - if (!source.Path.StartsWith(Consts.MO2ModFolderName) || _allEnabledMods.Any(mod => source.Path.StartsWith(mod))) + if (!_allEnabledMods.Any(mod => source.AbsolutePath.InFolder(mod))) return null; var r = source.EvolveTo(); r.Reason = "Disabled Mod"; diff --git a/Wabbajack.Lib/FileUploader/AuthorAPI.cs b/Wabbajack.Lib/FileUploader/AuthorAPI.cs index eee2dad6..bb901b68 100644 --- a/Wabbajack.Lib/FileUploader/AuthorAPI.cs +++ b/Wabbajack.Lib/FileUploader/AuthorAPI.cs @@ -34,12 +34,12 @@ namespace Wabbajack.Lib.FileUploader var tcs = new TaskCompletionSource(); Task.Run(async () => { - var client = GetAuthorizedClient(); + var client = await GetAuthorizedClient(); var fsize = filename.Size; var hash_task = filename.FileHashAsync(); - var response = await client.PutAsync(UploadURL+$"/{filename.FileName.ToString()}/start", new StringContent("")); + var response = await client.PutAsync($"{UploadURL}/{filename.FileName.ToString()}/start", new StringContent("")); if (!response.IsSuccessStatusCode) { tcs.SetException(new Exception($"Start Error: {response.StatusCode} {response.ReasonPhrase}")); diff --git a/Wabbajack.Lib/MO2Compiler.cs b/Wabbajack.Lib/MO2Compiler.cs index 59aeee34..cdf6252b 100644 --- a/Wabbajack.Lib/MO2Compiler.cs +++ b/Wabbajack.Lib/MO2Compiler.cs @@ -30,6 +30,8 @@ namespace Wabbajack.Lib public AbsolutePath MO2Folder; + public AbsolutePath MO2ModsFolder => MO2Folder.Combine(Consts.MO2ModFolderName); + public string MO2Profile { get; } public Dictionary ModMetas { get; set; } @@ -80,7 +82,7 @@ namespace Wabbajack.Lib internal UserStatus User { get; private set; } public ConcurrentBag ExtraFiles { get; private set; } - public Dictionary ModInis { get; private set; } + public Dictionary ModInis { get; private set; } public HashSet SelectedProfiles { get; set; } = new HashSet(); @@ -250,14 +252,15 @@ namespace Wabbajack.Lib if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Loading INIs"); - ModInis = Directory.EnumerateDirectories(Path.Combine(MO2Folder, Consts.MO2ModFolderName)) + ModInis = MO2Folder.Combine(Consts.MO2ModFolderName) + .EnumerateDirectories() .Select(f => { - var modName = Path.GetFileName(f); - var metaPath = Path.Combine(f, "meta.ini"); - if (File.Exists(metaPath)) + var modName = f.FileName; + var metaPath = f.Combine("meta.ini"); + if (metaPath.Exists) return (mod_name: modName, metaPath.LoadIniFile()); - return (null, null); + return default; }) .Where(f => f.Item2 != null) .ToDictionary(f => f.Item1, f => f.Item2); @@ -308,8 +311,8 @@ namespace Wabbajack.Lib Name = ModListName ?? MO2Profile, Author = ModListAuthor ?? "", Description = ModListDescription ?? "", - Readme = ModListReadme ?? "", - Image = ModListImage ?? "", + Readme = (string)ModListReadme, + Image = ModListImage.FileName, Website = ModListWebsite != null ? new Uri(ModListWebsite) : null }; @@ -356,17 +359,17 @@ namespace Wabbajack.Lib private async Task InferMetas() { - async Task HasInvalidMeta(string filename) + async Task HasInvalidMeta(AbsolutePath filename) { - string metaname = filename + Consts.MetaFileExtension; - if (!File.Exists(metaname)) return true; - return (AbstractDownloadState) await DownloadDispatcher.ResolveArchive(metaname.LoadIniFile()) == null; + var metaname = filename.WithExtension(Consts.MetaFileExtension); + if (metaname.Exists) return true; + return await DownloadDispatcher.ResolveArchive(metaname.LoadIniFile()) == null; } - var to_find = (await Directory.EnumerateFiles(MO2DownloadsFolder) - .Where(f => !f.EndsWith(Consts.MetaFileExtension) && !f.EndsWith(Consts.HashFileExtension)) - .PMap(Queue, async f => await HasInvalidMeta(f) ? f : null)) - .Where(f => f != null) + var to_find = (await MO2DownloadsFolder.EnumerateFiles() + .Where(f => f.Extension != Consts.MetaFileExtension && f.Extension !=Consts.HashFileExtension) + .PMap(Queue, async f => await HasInvalidMeta(f) ? f : default)) + .Where(f => f.Exists) .ToList(); if (to_find.Count == 0) return; @@ -375,7 +378,7 @@ namespace Wabbajack.Lib await to_find.PMap(Queue, async f => { - var vf = VFS.Index.ByFullPath[f]; + var vf = VFS.Index.ByRootPath[f]; var client = new Common.Http.Client(); using var response = await client.GetAsync( @@ -383,17 +386,15 @@ namespace Wabbajack.Lib if (!response.IsSuccessStatusCode) { - File.WriteAllLines(vf.FullPath + Consts.MetaFileExtension, new [] - { - "[General]", - "unknownArchive=true" - }); + await vf.AbsoluteName.WithExtension(Consts.MetaFileExtension).WriteAllLinesAsync( + "[General]", + "unknownArchive=true"); return; } - var ini_data = await response.Content.ReadAsStringAsync(); - Utils.Log($"Inferred .meta for {Path.GetFileName(vf.FullPath)}, writing to disk"); - File.WriteAllText(vf.FullPath + Consts.MetaFileExtension, ini_data); + var iniData = await response.Content.ReadAsStringAsync(); + Utils.Log($"Inferred .meta for {vf.FullPath.FileName}, writing to disk"); + await vf.AbsoluteName.WithExtension(Consts.MetaFileExtension).WriteAllTextAsync(iniData); }); }