From b79830ad54a78628127465d69af78b2e7a869460 Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Wed, 9 Dec 2020 14:46:08 -0700 Subject: [PATCH 1/2] Added purge-archive verb --- Wabbajack.CLI/OptionsDefinition.cs | 3 +- Wabbajack.CLI/Verbs/PurgeArchive.cs | 65 ++++++++++++++++++++++++++ Wabbajack.Common/Paths/AbsolutePath.cs | 2 +- 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 Wabbajack.CLI/Verbs/PurgeArchive.cs diff --git a/Wabbajack.CLI/OptionsDefinition.cs b/Wabbajack.CLI/OptionsDefinition.cs index 3eba22bd..cb61728d 100644 --- a/Wabbajack.CLI/OptionsDefinition.cs +++ b/Wabbajack.CLI/OptionsDefinition.cs @@ -34,7 +34,8 @@ namespace Wabbajack.CLI typeof(ExportServerGameFiles), typeof(HashGamefiles), typeof(Backup), - typeof(Restore) + typeof(Restore), + typeof(PurgeArchive) }; } } diff --git a/Wabbajack.CLI/Verbs/PurgeArchive.cs b/Wabbajack.CLI/Verbs/PurgeArchive.cs new file mode 100644 index 00000000..e005dbaf --- /dev/null +++ b/Wabbajack.CLI/Verbs/PurgeArchive.cs @@ -0,0 +1,65 @@ +using System.IO.Compression; +using System.Linq; +using System.Threading.Tasks; +using CommandLine; +using Wabbajack.Common; +using Wabbajack.Lib; + +namespace Wabbajack.CLI.Verbs +{ + [Verb("purge-archive", HelpText = "Purges an archive and all directives from a .wabbajack file")] + public class PurgeArchive : AVerb + { + [Option('i', "input", Required = true, HelpText = "Input .wabbajack file")] + public string Input { get; set; } = ""; + private AbsolutePath _Input => (AbsolutePath)Input; + + [Option('o', "output", Required = true, HelpText = "Output .wabbajack file")] + public string Output { get; set; } = ""; + private AbsolutePath _Output => (AbsolutePath)Output; + + [Option('h', "hash", Required = true, HelpText = "Hash to purge")] + public string ArchiveHash { get; set; } = ""; + private Hash _Hash => Hash.Interpret(ArchiveHash); + + protected override async Task Run() + { + Utils.Log("Copying .wabbajack file"); + await _Input.CopyToAsync(_Output); + + Utils.Log("Loading modlist"); + + await using var fs = await _Output.OpenWrite(); + using var ar = new ZipArchive(fs, ZipArchiveMode.Update); + ModList modlist; + await using (var entry = ar.Entries.First(e => e.Name == "modlist").Open()) + { + modlist = entry.FromJson(); + } + + Utils.Log("Purging archives"); + modlist.Archives = modlist.Archives.Where(a => a.Hash != _Hash).ToList(); + modlist.Directives = modlist.Directives.Select(d => + { + if (d is FromArchive a) + { + if (a.ArchiveHashPath.BaseHash == _Hash) return (false, d); + } + return (true, d); + }).Where(d => d.Item1) + .Select(d => d.d) + .ToList(); + + Utils.Log("Writing modlist"); + + await using (var entry = ar.Entries.First(e => e.Name == "modlist").Open()) + { + entry.SetLength(0); + entry.Position = 0; + modlist.ToJson(entry); + } + + return ExitCode.Ok; + } + } +} diff --git a/Wabbajack.Common/Paths/AbsolutePath.cs b/Wabbajack.Common/Paths/AbsolutePath.cs index e7f4a5c6..26d8a27e 100644 --- a/Wabbajack.Common/Paths/AbsolutePath.cs +++ b/Wabbajack.Common/Paths/AbsolutePath.cs @@ -95,7 +95,7 @@ namespace Wabbajack.Common public ValueTask OpenWrite() { var path = _path; - return CircuitBreaker.WithAutoRetryAsync(async () => File.OpenWrite(path)); + return CircuitBreaker.WithAutoRetryAsync(async () => File.Open(path, FileMode.OpenOrCreate, FileAccess.ReadWrite)); } public async Task WriteAllTextAsync(string text) From aa591bafa7c4ec7600152b0d4b6e173f921c527d Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Tue, 15 Dec 2020 17:09:59 -0700 Subject: [PATCH 2/2] Add TES4RU support back in --- Wabbajack.Lib/Downloaders/AbstractIPS4Downloader.cs | 11 +++++++++++ Wabbajack.Test/DownloaderTests.cs | 4 +--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Wabbajack.Lib/Downloaders/AbstractIPS4Downloader.cs b/Wabbajack.Lib/Downloaders/AbstractIPS4Downloader.cs index 4ad33f64..8c87bfe4 100644 --- a/Wabbajack.Lib/Downloaders/AbstractIPS4Downloader.cs +++ b/Wabbajack.Lib/Downloaders/AbstractIPS4Downloader.cs @@ -68,6 +68,16 @@ namespace Wabbajack.Lib.Downloaders IsAttachment = true }; } + + + if (url.PathAndQuery.StartsWith("/files/download/") && long.TryParse(url.PathAndQuery.Split("/").Last(), out var fileId)) + { + return new TState + { + FullURL = url.ToString(), + IsAttachment = true + }; + } if (!url.PathAndQuery.StartsWith("/files/file/")) { @@ -76,6 +86,7 @@ namespace Wabbajack.Lib.Downloaders absolute = false; } + var id = HttpUtility.ParseQueryString(url.Query)["r"]; var file = absolute ? url.AbsolutePath.Split('/').Last(s => s != "") diff --git a/Wabbajack.Test/DownloaderTests.cs b/Wabbajack.Test/DownloaderTests.cs index 0bd46741..a418dcce 100644 --- a/Wabbajack.Test/DownloaderTests.cs +++ b/Wabbajack.Test/DownloaderTests.cs @@ -407,13 +407,12 @@ namespace Wabbajack.Test Assert.Equal("Cheese for Everyone!", await filename.Path.ReadAllTextAsync()); } - /* Site is down [Fact] public async Task TESAllDownloader() { await DownloadDispatcher.GetInstance().Prepare(); const string ini = "[General]\n" + - "directURL=https://tesall.ru/files/getdownload/594545-wabbajack-test-file/"; + "directURL=https://tesall.ru/files/download/594545"; var state = (AbstractDownloadState)await DownloadDispatcher.ResolveArchive(ini.LoadIniString()); @@ -431,7 +430,6 @@ namespace Wabbajack.Test Assert.Equal("Cheese for Everyone!", await filename.Path.ReadAllTextAsync()); } - */ /* WAITING FOR APPROVAL BY MODERATOR [Fact]