public static async Task ExtractAll(WorkQueue queue, AbsolutePath source, AbsolutePath dest) { try { if (Consts.SupportedBSAs.Contains(source.Extension)) { await ExtractAllWithBSA(queue, source, dest); } else if (source.Extension == Consts.OMOD) { ExtractAllWithOMOD(source, dest); } else if (source.Extension == Consts.EXE) { await ExtractAllExe(source, dest); } else { await ExtractAllWith7Zip(source, dest); } } catch (Exception ex) { Utils.ErrorThrow(ex, $"Error while extracting {source}"); } }
private static async Task ExtractAllWithBSA(WorkQueue queue, AbsolutePath source, AbsolutePath dest) { try { using var arch = BSADispatch.OpenRead(source); await arch.Files .PMap(queue, f => { Utils.Status($"Extracting {(string)f.Path}"); var outPath = f.Path.RelativeTo(dest); var parent = outPath.Parent; if (!parent.IsDirectory) { parent.CreateDirectory(); } using var fs = outPath.Create(); f.CopyDataTo(fs); }); } catch (Exception ex) { Utils.ErrorThrow(ex, $"While Extracting {source}"); } }
private static async Task <Dictionary <RelativePath, T> > GatheringExtractWithOMOD <T>(Stream archive, Predicate <RelativePath> shouldExtract, Func <RelativePath, IStreamFactory, ValueTask <T> > mapfn) { var tmpFile = new TempFile(); await tmpFile.Path.WriteAllAsync(archive); var dest = await TempFolder.Create(); Utils.Log($"Extracting {(string)tmpFile.Path}"); Framework.Settings.TempPath = (string)dest.Dir; Framework.Settings.CodeProgress = new OMODProgress(); var omod = new OMOD((string)tmpFile.Path); omod.GetDataFiles(); omod.GetPlugins(); var results = new Dictionary <RelativePath, T>(); foreach (var file in dest.Dir.EnumerateFiles()) { var path = file.RelativeTo(dest.Dir); if (!shouldExtract(path)) { continue; } var result = await mapfn(path, new NativeFileStreamFactory(file, path)); results.Add(path, result); } return(results); }
public static async Task <ExtractedFiles> ExtractAll(WorkQueue queue, AbsolutePath source, IEnumerable <RelativePath> OnlyFiles = null) { try { if (Consts.SupportedBSAs.Contains(source.Extension)) { return(await ExtractAllWithBSA(queue, source)); } else if (source.Extension == Consts.OMOD) { return(await ExtractAllWithOMOD(source)); } else if (source.Extension == Consts.EXE) { return(await ExtractAllExe(source)); } else { return(await ExtractAllWith7Zip(source, OnlyFiles)); } } catch (Exception ex) { Utils.ErrorThrow(ex, $"Error while extracting {source}"); throw new Exception(); } }
public void TestDiskSpeed() { using (var queue = new WorkQueue()) { var speed = Utils.TestDiskSpeed(queue, @".\"); } }
public MainWindow() { // Wire any unhandled crashing exceptions to log before exiting AppDomain.CurrentDomain.UnhandledException += (sender, e) => { // Don't do any special logging side effects Wabbajack.Common.Utils.Error(((Exception)e.ExceptionObject), "Uncaught error"); }; Wabbajack.Common.Utils.Log($"Wabbajack Build - {ThisAssembly.Git.Sha}"); // Run some init tasks in background Task.Run(async() => { await Helpers.Initialize(); var appPath = System.Reflection.Assembly.GetExecutingAssembly().Location; try { if (!ExtensionManager.IsAssociated() || ExtensionManager.NeedsUpdating(appPath)) { ExtensionManager.Associate(appPath); } } catch (Exception e) { Utils.Log($"ExtensionManager had an exception:\n{e}"); } }).FireAndForget(); // Load settings string[] args = Environment.GetCommandLineArgs(); if ((args.Length > 1 && args[1] == "nosettings") || !MainSettings.TryLoadTypicalSettings(out var settings)) { _settings = new MainSettings(); RunWhenLoaded(DefaultSettings); } else { _settings = settings; RunWhenLoaded(LoadSettings); } // Set datacontext _mwvm = new MainWindowVM(this, _settings); DataContext = _mwvm; // Bring window to the front if it isn't already this.Initialized += (s, e) => { this.Activate(); this.Topmost = true; this.Focus(); }; this.ContentRendered += (s, e) => { this.Topmost = false; }; }
public MainWindow() { // Wire any unhandled crashing exceptions to log before exiting AppDomain.CurrentDomain.UnhandledException += (sender, e) => { // Don't do any special logging side effects Utils.Error(((Exception)e.ExceptionObject), "Uncaught error"); }; Utils.Log($"Wabbajack Build - {ThisAssembly.Git.Sha}"); var p = SystemParametersConstructor.Create(); Utils.Log($"Detected Windows Version: {p.WindowsVersion}"); if (!(p.WindowsVersion.Major >= 6 && p.WindowsVersion.Minor >= 2)) { Utils.Log( $"You are not running a recent version of Windows (version 10 or greater), Wabbajack is not supported on OS versions older than Windows 10."); } Utils.Log( $"System settings - ({p.SystemMemorySize.ToFileSizeString()} RAM), Display: {p.ScreenWidth} x {p.ScreenHeight} ({p.VideoMemorySize.ToFileSizeString()} VRAM - VideoMemorySizeMb={p.EnbLEVRAMSize})"); Warmup(); var(settings, loadedSettings) = MainSettings.TryLoadTypicalSettings().AsTask().Result; // Load settings if (CLIArguments.NoSettings || !loadedSettings) { _settings = new MainSettings { Version = Consts.SettingsVersion }; RunWhenLoaded(DefaultSettings); } else { _settings = settings; RunWhenLoaded(LoadSettings); } // Set datacontext _mwvm = new MainWindowVM(this, _settings); DataContext = _mwvm; // Bring window to the front if it isn't already this.Initialized += (s, e) => { this.Activate(); this.Topmost = true; this.Focus(); }; this.ContentRendered += (s, e) => { this.Topmost = false; }; }
public MainWindow() { Helpers.Init(); // Wire any unhandled crashing exceptions to log before exiting AppDomain.CurrentDomain.UnhandledException += (sender, e) => { // Don't do any special logging side effects Utils.Error(((Exception)e.ExceptionObject), "Uncaught error"); }; Utils.Log($"Wabbajack Build - {ThisAssembly.Git.Sha}"); // Run logic to associate wabbajack lists with this app in the background Task.Run(async() => { var appPath = System.Reflection.Assembly.GetExecutingAssembly().Location; try { if (!ModListAssociationManager.IsAssociated() || ModListAssociationManager.NeedsUpdating(appPath)) { ModListAssociationManager.Associate(appPath); } } catch (Exception e) { Utils.Log($"ExtensionManager had an exception:\n{e}"); } }).FireAndForget(); // Load settings if (CLIArguments.NoSettings || !MainSettings.TryLoadTypicalSettings(out var settings)) { _settings = new MainSettings(); RunWhenLoaded(DefaultSettings); } else { _settings = settings; RunWhenLoaded(LoadSettings); } // Set datacontext _mwvm = new MainWindowVM(this, _settings); DataContext = _mwvm; // Bring window to the front if it isn't already this.Initialized += (s, e) => { this.Activate(); this.Topmost = true; this.Focus(); }; this.ContentRendered += (s, e) => { this.Topmost = false; }; }
public void TestHash() { const string data = "Cheese for Everyone!"; File.WriteAllText("test.data", data); Assert.AreEqual("eSIyd+KOG3s=", "test.data".FileHashCached(), "Hash is cached"); Assert.IsTrue(Utils.TryGetHashCache("test.data", out var fileHash), "New caching method is invoked"); Assert.AreEqual("eSIyd+KOG3s=", fileHash, "The correct hash value is cached"); Assert.AreNotEqual("eSIyd+KOG3s=", File.ReadAllText("test.data" + Consts.HashFileExtension), "We don't store the hash in plaintext"); }
private static void ExtractAllWithOMOD(AbsolutePath source, AbsolutePath dest) { Utils.Log($"Extracting {(string)source.FileName}"); Framework.Settings.TempPath = (string)dest; Framework.Settings.CodeProgress = new OMODProgress(); var omod = new OMOD((string)source); omod.GetDataFiles(); omod.GetPlugins(); }
private static async Task <ExtractedFiles> ExtractAllWithBSA(WorkQueue queue, AbsolutePath source) { try { await using var arch = BSADispatch.OpenRead(source); var files = arch.Files.ToDictionary(f => f.Path, f => (IExtractedFile) new ExtractedBSAFile(f)); return(new ExtractedFiles(files, arch)); } catch (Exception ex) { Utils.ErrorThrow(ex, $"While Extracting {source}"); throw new Exception(); } }
public static async Task <Dictionary <RelativePath, T> > GatheringExtract <T>(IStreamFactory sFn, Predicate <RelativePath> shouldExtract, Func <RelativePath, IStreamFactory, ValueTask <T> > mapfn) { if (sFn is NativeFileStreamFactory) { Utils.Log($"Extracting {sFn.Name}"); } await using var archive = await sFn.GetStream(); var sig = await ArchiveSigs.MatchesAsync(archive); archive.Position = 0; switch (sig) { case Definitions.FileType.RAR_OLD: case Definitions.FileType.RAR_NEW: case Definitions.FileType._7Z: case Definitions.FileType.ZIP: { if (sFn.Name.FileName.Extension == OMODExtension) { return(await GatheringExtractWithOMOD(archive, shouldExtract, mapfn)); } else { return(await GatheringExtractWith7Zip <T>(archive, (Definitions.FileType) sig, shouldExtract, mapfn)); } } case Definitions.FileType.BSA: case Definitions.FileType.BA2: return(await GatheringExtractWithBSA(sFn, (Definitions.FileType) sig, shouldExtract, mapfn)); case Definitions.FileType.TES3: if (sFn.Name.FileName.Extension == BSAExtension) { return(await GatheringExtractWithBSA(sFn, (Definitions.FileType) sig, shouldExtract, mapfn)); } else { throw new Exception($"Invalid file format {sFn.Name}"); } default: throw new Exception($"Invalid file format {sFn.Name}"); } }
private static async Task <ExtractedFiles> ExtractAllWithOMOD(AbsolutePath source) { var dest = await TempFolder.Create(); Utils.Log($"Extracting {(string)source.FileName}"); Framework.Settings.TempPath = (string)dest.Dir; Framework.Settings.CodeProgress = new OMODProgress(); var omod = new OMOD((string)source); omod.GetDataFiles(); omod.GetPlugins(); return(new ExtractedFiles(dest)); }
/// <summary> /// Run logic to associate wabbajack lists with this app in the background /// </summary> private void AssociateListsWithWabbajack() { var appPath = System.Reflection.Assembly.GetExecutingAssembly().Location; try { if (!ModListAssociationManager.IsAssociated() || ModListAssociationManager.NeedsUpdating(appPath)) { ModListAssociationManager.Associate(appPath); } } catch (Exception e) { Utils.Log($"ExtensionManager had an exception:\n{e}"); } }
private static async Task ExtractAllWith7Zip(AbsolutePath source, AbsolutePath dest) { Utils.Log(new GenericInfo($"Extracting {(string)source.FileName}", $"The contents of {(string)source.FileName} are being extracted to {(string)source.FileName} using 7zip.exe")); var process = new ProcessHelper { Path = @"Extractors\7z.exe".RelativeTo(AbsolutePath.EntryPoint), Arguments = new object[] { "x", "-bsp1", "-y", $"-o\"{dest}\"", source, "-mmt=off" } }; var result = process.Output.Where(d => d.Type == ProcessHelper.StreamType.Output) .ForEachAsync(p => { var(_, line) = p; if (line == null) { return; } if (line.Length <= 4 || line[3] != '%') { return; } int.TryParse(line.Substring(0, 3), out var percentInt); Utils.Status($"Extracting {(string)source.FileName} - {line.Trim()}", Percent.FactoryPutInRange(percentInt / 100d)); }); var exitCode = await process.Start(); if (exitCode != 0) { Utils.Error(new _7zipReturnError(exitCode, source, dest, "")); } else { Utils.Status($"Extracting {source.FileName} - done", Percent.One, alsoLog: true); } }
private static async Task <ExtractedFiles> ExtractAllExe(AbsolutePath source) { var isArchive = await TestWith7z(source); if (isArchive) { return(await ExtractAllWith7Zip(source, null)); } var dest = await TempFolder.Create(); Utils.Log($"Extracting {(string)source.FileName}"); var process = new ProcessHelper { Path = @"Extractors\innounp.exe".RelativeTo(AbsolutePath.EntryPoint), Arguments = new object[] { "-x", "-y", "-b", $"-d\"{dest.Dir}\"", source } }; var result = process.Output.Where(d => d.Type == ProcessHelper.StreamType.Output) .ForEachAsync(p => { var(_, line) = p; if (line == null) { return; } if (line.Length <= 4 || line[3] != '%') { return; } int.TryParse(line.Substring(0, 3), out var percentInt); Utils.Status($"Extracting {source.FileName} - {line.Trim()}", Percent.FactoryPutInRange(percentInt / 100d)); }); await process.Start(); return(new ExtractedFiles(dest)); }
public void Start() { _client.LoginAsync(TokenType.Bot, Utils.FromEncryptedJson <string>("discord-key").Result).Wait(); _client.StartAsync().Wait(); }
public static async Task <Dictionary <RelativePath, T> > GatheringExtract <T>(WorkQueue queue, IStreamFactory sFn, Predicate <RelativePath> shouldExtract, Func <RelativePath, IExtractedFile, ValueTask <T> > mapfn, AbsolutePath?tempFolder = null, HashSet <RelativePath> onlyFiles = null) { if (tempFolder == null) { tempFolder = TempFolder.BaseFolder; } if (sFn is NativeFileStreamFactory) { Utils.Log($"Extracting {sFn.Name}"); } await using var archive = await sFn.GetStream(); var sig = await ArchiveSigs.MatchesAsync(archive); archive.Position = 0; Dictionary <RelativePath, T> results = new Dictionary <RelativePath, T>(); switch (sig) { case Definitions.FileType.RAR_OLD: case Definitions.FileType.RAR_NEW: case Definitions.FileType._7Z: case Definitions.FileType.ZIP: { if (sFn.Name.FileName.Extension == OMODExtension) { results = await GatheringExtractWithOMOD(archive, shouldExtract, mapfn); } else { results = await GatheringExtractWith7Zip <T>(queue, sFn, (Definitions.FileType) sig, shouldExtract, mapfn, tempFolder.Value, onlyFiles); } break; } case Definitions.FileType.BSA: case Definitions.FileType.BA2: results = await GatheringExtractWithBSA(sFn, (Definitions.FileType) sig, shouldExtract, mapfn); break; case Definitions.FileType.TES3: if (sFn.Name.FileName.Extension == BSAExtension) { results = await GatheringExtractWithBSA(sFn, (Definitions.FileType) sig, shouldExtract, mapfn); } else { throw new Exception($"Invalid file format {sFn.Name}"); } break; default: throw new Exception($"Invalid file format {sFn.Name}"); } if (onlyFiles != null && onlyFiles.Count != results.Count) { throw new Exception( $"Sanity check error extracting {sFn.Name} - {results.Count} results, expected {onlyFiles.Count}"); } return(results); }
public void SetProgress(long inSize, long outSize) { Utils.Status("Extracting OMOD", Percent.FactoryPutInRange(inSize, _total)); }
public MainWindow() { try { // Wire any unhandled crashing exceptions to log before exiting AppDomain.CurrentDomain.UnhandledException += (sender, e) => { // Don't do any special logging side effects Utils.LogStraightToFile("Error."); Utils.LogStraightToFile(((Exception)e.ExceptionObject).ToString()); Environment.Exit(-1); }; Utils.Log($"Wabbajack Build - {ThisAssembly.Git.Sha}"); Utils.Log($"Running in {AbsolutePath.EntryPoint}"); var p = SystemParametersConstructor.Create(); Utils.Log($"Detected Windows Version: {p.WindowsVersion}"); if (!(p.WindowsVersion.Major >= 10 && p.WindowsVersion.Minor >= 0)) { Utils.Log( $"You are not running a recent version of Windows (version 10 or greater), Wabbajack is not supported on OS versions older than Windows 10."); } Utils.Log( $"System settings - ({p.SystemMemorySize.ToFileSizeString()} RAM) ({p.SystemPageSize.ToFileSizeString()} Page), Display: {p.ScreenWidth} x {p.ScreenHeight} ({p.VideoMemorySize.ToFileSizeString()} VRAM - VideoMemorySizeMb={p.EnbLEVRAMSize})"); if (p.SystemPageSize == 0) { Utils.Log("Pagefile is disabled! Consider increasing to 20000MB. A disabled pagefile can cause crashes and poor in-game performance."); } else if (p.SystemPageSize < 2e+10) { Utils.Log("Pagefile below recommended! Consider increasing to 20000MB. A suboptimal pagefile can cause crashes and poor in-game performance."); } Warmup(); var _ = LauncherUpdater.Run(); var(settings, loadedSettings) = MainSettings.TryLoadTypicalSettings().AsTask().Result; // Load settings if (CLIArguments.NoSettings || !loadedSettings) { _settings = new MainSettings { Version = Consts.SettingsVersion }; RunWhenLoaded(DefaultSettings); } else { _settings = settings; RunWhenLoaded(LoadSettings); } // Set datacontext _mwvm = new MainWindowVM(this, _settings); DataContext = _mwvm; // Bring window to the front if it isn't already this.Initialized += (s, e) => { this.Activate(); this.Topmost = true; this.Focus(); }; this.ContentRendered += (s, e) => { this.Topmost = false; }; } catch (Exception ex) { Utils.LogStraightToFile("Error"); Utils.LogStraightToFile(ex.ToString()); Environment.Exit(-1); } }
private static async Task <ExtractedFiles> ExtractAllWith7Zip(AbsolutePath source, IEnumerable <RelativePath> onlyFiles) { TempFile tmpFile = null; var dest = await TempFolder.Create(); Utils.Log(new GenericInfo($"Extracting {(string)source.FileName}", $"The contents of {(string)source.FileName} are being extracted to {(string)source.FileName} using 7zip.exe")); var process = new ProcessHelper { Path = @"Extractors\7z.exe".RelativeTo(AbsolutePath.EntryPoint), }; if (onlyFiles != null) { //It's stupid that we have to do this, but 7zip's file pattern matching isn't very fuzzy IEnumerable <string> AllVariants(string input) { yield return($"\"{input}\""); yield return($"\"\\{input}\""); } tmpFile = new TempFile(); await tmpFile.Path.WriteAllLinesAsync(onlyFiles.SelectMany(f => AllVariants((string)f)).ToArray()); process.Arguments = new object[] { "x", "-bsp1", "-y", $"-o\"{dest.Dir}\"", source, $"@\"{tmpFile.Path}\"", "-mmt=off" }; } else { process.Arguments = new object[] { "x", "-bsp1", "-y", $"-o\"{dest.Dir}\"", source, "-mmt=off" }; } var result = process.Output.Where(d => d.Type == ProcessHelper.StreamType.Output) .ForEachAsync(p => { var(_, line) = p; if (line == null) { return; } if (line.Length <= 4 || line[3] != '%') { return; } int.TryParse(line.Substring(0, 3), out var percentInt); Utils.Status($"Extracting {(string)source.FileName} - {line.Trim()}", Percent.FactoryPutInRange(percentInt / 100d)); }); var exitCode = await process.Start(); if (exitCode != 0) { Utils.Error(new _7zipReturnError(exitCode, source, dest.Dir, "")); } else { Utils.Status($"Extracting {source.FileName} - done", Percent.One, alsoLog: true); } tmpFile?.Dispose(); return(new ExtractedFiles(dest)); }
private static async Task <Dictionary <RelativePath, T> > GatheringExtractWith7Zip <T>(WorkQueue queue, IStreamFactory sf, Definitions.FileType sig, Predicate <RelativePath> shouldExtract, Func <RelativePath, IExtractedFile, ValueTask <T> > mapfn, AbsolutePath tempPath, HashSet <RelativePath> onlyFiles) { TempFile tmpFile = null; var dest = tempPath.Combine(Guid.NewGuid().ToString()); dest.CreateDirectory(); TempFile spoolFile = null; AbsolutePath source; try { if (sf.Name is AbsolutePath abs) { source = abs; } else { spoolFile = new TempFile(tempPath.Combine(Guid.NewGuid().ToString()) .WithExtension(source.Extension)); await using var s = await sf.GetStream(); await spoolFile.Path.WriteAllAsync(s); source = spoolFile.Path; } Utils.Log(new GenericInfo($"Extracting {(string)source.FileName}", $"The contents of {(string)source.FileName} are being extracted to {(string)source.FileName} using 7zip.exe")); var process = new ProcessHelper { Path = @"Extractors\7z.exe".RelativeTo(AbsolutePath.EntryPoint), }; if (onlyFiles != null) { //It's stupid that we have to do this, but 7zip's file pattern matching isn't very fuzzy IEnumerable <string> AllVariants(string input) { yield return($"\"{input}\""); yield return($"\"\\{input}\""); } tmpFile = new TempFile(); await tmpFile.Path.WriteAllLinesAsync(onlyFiles.SelectMany(f => AllVariants((string)f)).ToArray()); process.Arguments = new object[] { "x", "-bsp1", "-y", $"-o\"{dest}\"", source, $"@\"{tmpFile.Path}\"", "-mmt=off" }; } else { process.Arguments = new object[] { "x", "-bsp1", "-y", $"-o\"{dest}\"", source, "-mmt=off" }; } var result = process.Output.Where(d => d.Type == ProcessHelper.StreamType.Output) .ForEachAsync(p => { var(_, line) = p; if (line == null) { return; } if (line.Length <= 4 || line[3] != '%') { return; } int.TryParse(line.Substring(0, 3), out var percentInt); Utils.Status($"Extracting {(string)source.FileName} - {line.Trim()}", Percent.FactoryPutInRange(percentInt / 100d)); }); var exitCode = await process.Start(); if (exitCode != 0) { Utils.ErrorThrow(new _7zipReturnError(exitCode, source, dest, "")); } else { Utils.Status($"Extracting {source.FileName} - done", Percent.One, alsoLog: true); } var results = await dest.EnumerateFiles() .PMap(queue, async f => { var path = f.RelativeTo(dest); if (!shouldExtract(path)) { return(((RelativePath, T)) default);
public MainWindow() { Helpers.Init(); // Wire any unhandled crashing exceptions to log before exiting AppDomain.CurrentDomain.UnhandledException += (sender, e) => { // Don't do any special logging side effects Utils.Error(((Exception)e.ExceptionObject), "Uncaught error"); }; Utils.Log($"Wabbajack Build - {ThisAssembly.Git.Sha}"); var p = SystemParametersConstructor.Create(); Utils.Log($"Detected Windows Version: {p.WindowsVersion}"); if (!(p.WindowsVersion.Major >= 6 && p.WindowsVersion.Minor >= 2)) { Utils.Log( $"You are not running a recent version of Windows (version 10 or greater), Wabbajack is not supported on OS versions older than Windows 10."); } Utils.Log( $"System settings - ({p.SystemMemorySize.ToFileSizeString()} RAM), Display: {p.ScreenWidth} x {p.ScreenHeight} ({p.VideoMemorySize.ToFileSizeString()} VRAM - VideoMemorySizeMb={p.EnbLEVRAMSize})"); // Run logic to associate wabbajack lists with this app in the background Task.Run(async() => { var appPath = System.Reflection.Assembly.GetExecutingAssembly().Location; try { if (!ModListAssociationManager.IsAssociated() || ModListAssociationManager.NeedsUpdating(appPath)) { ModListAssociationManager.Associate(appPath); } } catch (Exception e) { Utils.Log($"ExtensionManager had an exception:\n{e}"); } }).FireAndForget(); // Load settings if (CLIArguments.NoSettings || !MainSettings.TryLoadTypicalSettings(out var settings)) { _settings = new MainSettings { Version = Consts.SettingsVersion }; RunWhenLoaded(DefaultSettings); } else { _settings = settings; RunWhenLoaded(LoadSettings); } // Set datacontext _mwvm = new MainWindowVM(this, _settings); DataContext = _mwvm; // Bring window to the front if it isn't already this.Initialized += (s, e) => { this.Activate(); this.Topmost = true; this.Focus(); }; this.ContentRendered += (s, e) => { this.Topmost = false; }; }