diff --git a/Wabbajack.CLI/OptionsDefinition.cs b/Wabbajack.CLI/OptionsDefinition.cs index ec4695e9..c398b133 100644 --- a/Wabbajack.CLI/OptionsDefinition.cs +++ b/Wabbajack.CLI/OptionsDefinition.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Markdig.Syntax.Inlines; using Wabbajack.CLI.Verbs; @@ -6,42 +7,8 @@ namespace Wabbajack.CLI { public class OptionsDefinition { - public static readonly Type[] AllOptions = { - typeof(OptionsDefinition), - typeof(Encrypt), - typeof(Decrypt), - typeof(Validate), - typeof(DownloadUrl), - typeof(UpdateModlists), - typeof(UpdateNexusCache), - typeof(ChangeDownload), - typeof(ServerLog), - typeof(MyFiles), - typeof(DeleteFile), - typeof(Changelog), - typeof(FindSimilar), - typeof(BSADump), - typeof(MigrateGameFolderFiles), - typeof(HashFile), - typeof(InlinedFileReport), - typeof(ExtractBSA), - typeof(PurgeNexusCache), - typeof(ForceHealing), - typeof(HashVariants), - typeof(ParseMeta), - typeof(NoPatch), - typeof(NexusPermissions), - typeof(ExportServerGameFiles), - typeof(HashGamefiles), - typeof(Backup), - typeof(Restore), - typeof(PurgeArchive), - typeof(AllKnownDownloadStates), - typeof(VerifyAllDownloads), - typeof(HashBenchmark), - typeof(StressTestURL), - typeof(MirrorFolder), - typeof(DownloadFromMeta) - }; + public static Type[] AllOptions => + typeof(OptionsDefinition).Assembly.GetTypes().Where(t => t.IsAssignableTo(typeof(AVerb))).ToArray(); + } } diff --git a/Wabbajack.CLI/Properties/launchSettings.json b/Wabbajack.CLI/Properties/launchSettings.json index fa6e610c..37532044 100644 --- a/Wabbajack.CLI/Properties/launchSettings.json +++ b/Wabbajack.CLI/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "Wabbajack.CLI": { "commandName": "Project", - "commandLineArgs": "download-from-meta -m \"c:\\tmp\\test (2).meta\" -o c:\\tmp\\out.7z" + "commandLineArgs": "upload-mod-to-cdn -m \"Generated Files\" -f \"Sanitarium Generated Files\" -r \"C:\\Modding\\Sanitarium\"" } } } \ No newline at end of file diff --git a/Wabbajack.CLI/Verbs/UploadModToCDN.cs b/Wabbajack.CLI/Verbs/UploadModToCDN.cs new file mode 100644 index 00000000..ab441096 --- /dev/null +++ b/Wabbajack.CLI/Verbs/UploadModToCDN.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using CommandLine; +using Wabbajack.Common; +using Wabbajack.Lib.AuthorApi; +using Wabbajack.VirtualFileSystem; + +namespace Wabbajack.CLI.Verbs +{ + [Verb("upload-mod-to-cdn", HelpText = "Compresses and uploads one or more folders in MO2 onto the CDN and updates the MO2's downloads folder to match.")] + public class UploadModToCDN : AVerb + { + [Option('m', "mods", Required = true, HelpText = @"ModOrganizer2 mod names to export")] + public IEnumerable Mods { get; set; } = Array.Empty(); + + [Option('f', "filename", Required = true, HelpText = @"Human friendly filename for the created download")] + public string Filename { get; set; } = ""; + + [Option('r', "root", Required = true, HelpText = @"The root MO2 folder")] + public string _MO2Path { get; set; } = ""; + + public AbsolutePath MO2Path => (AbsolutePath)_MO2Path; + protected override async Task Run() + { + var ini = MO2Path.Combine(Consts.ModOrganizer2Ini).LoadIniFile(); + var downloadsFolder = (AbsolutePath)(ini.Settings.download_directory ?? MO2Path.Combine("downloads")); + var fileFixed = downloadsFolder.Combine(Filename).ReplaceExtension(new Extension(".7z")); + + var folders = Mods.Select(m => MO2Path.Combine("mods", m)).ToArray(); + + Utils.Log("Compressing files"); + await FileExtractor2.CompressFiles(fileFixed, folders, Utils.Log); + Utils.Log($"Final Size: {fileFixed.Size.ToFileSizeString()}"); + + Utils.Log("Uploading to CDN"); + var queue = new WorkQueue(); + var url = await (await Client.Create()).UploadFile(queue, fileFixed,(s, p) => Utils.Log($"{p} - {s}")); + Utils.Log("Updating Meta"); + await fileFixed.WithExtension(new Extension(Consts.MetaFileExtension)).WriteAllLinesAsync( + "[General]", + "installed=true", + $"directURL={url}"); + + return ExitCode.Ok; + } + } +} diff --git a/Wabbajack.VirtualFileSystem/FileExtractor2/FileExtractor.cs b/Wabbajack.VirtualFileSystem/FileExtractor2/FileExtractor.cs index 9762660b..7bdcff92 100644 --- a/Wabbajack.VirtualFileSystem/FileExtractor2/FileExtractor.cs +++ b/Wabbajack.VirtualFileSystem/FileExtractor2/FileExtractor.cs @@ -51,6 +51,7 @@ namespace Wabbajack.VirtualFileSystem public static bool FavorPerfOverRAM { get; set; } + public static async Task> GatheringExtract(WorkQueue queue, IStreamFactory sFn, Predicate shouldExtract, Func> mapfn, AbsolutePath? tempFolder = null, @@ -280,5 +281,30 @@ namespace Wabbajack.VirtualFileSystem return 0; }); } + + + /// + /// Compresses all the files with 7zip + /// + /// + /// + public static async Task CompressFiles(AbsolutePath to, AbsolutePath[] filesAndFolders, Action status) + { + var args = new List() {"a", to, "-mx9"}; + args.AddRange(filesAndFolders.Cast()); + var process = new ProcessHelper + { + Path = @"Extractors\7z.exe".RelativeTo(AbsolutePath.EntryPoint), + Arguments = args, + ThrowOnNonZeroExitCode = true + }; + + using var _ = process.Output.Where(o => o.Type == ProcessHelper.StreamType.Output) + .Subscribe(l => status(l.Line)); + + await process.Start(); + return; + + } } }