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 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; }; }
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(); }
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)); }
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)); }
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 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); } }
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; }; }
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);
private static void ExtractAllWithInno(string source, string dest) { Utils.Log($"Extracting {Path.GetFileName(source)}"); var info = new ProcessStartInfo { FileName = @"Extractors\innounp.exe", Arguments = $"-x -y -b -d\"{dest}\" \"{source}\"", RedirectStandardError = true, RedirectStandardInput = true, RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; var p = new Process { StartInfo = info }; p.Start(); ChildProcessTracker.AddProcess(p); try { p.PriorityClass = ProcessPriorityClass.BelowNormal; } catch (Exception e) { Utils.Error(e, "Error while setting process priority level for innounp.exe"); } var name = Path.GetFileName(source); try { while (!p.HasExited) { var line = p.StandardOutput.ReadLine(); if (line == null) { break; } if (line.Length <= 4 || line[3] != '%') { continue; } int.TryParse(line.Substring(0, 3), out var percentInt); Utils.Status($"Extracting {name} - {line.Trim()}", Percent.FactoryPutInRange(percentInt / 100d)); } } catch (Exception e) { Utils.Error(e, "Error while reading StandardOutput for innounp.exe"); } p.WaitForExitAndWarn(TimeSpan.FromSeconds(30), $"Extracting {name}"); if (p.ExitCode == 0) { return; } Utils.Log(p.StandardOutput.ReadToEnd()); Utils.Log($"Extraction error extracting {source}"); }
private static void ExtractAllWith7Zip(string source, string dest) { Utils.Log(new GenericInfo($"Extracting {Path.GetFileName(source)}", $"The contents of {source} are being extracted to {dest} using 7zip.exe")); var info = new ProcessStartInfo { FileName = @"Extractors\7z.exe", Arguments = $"x -bsp1 -y -o\"{dest}\" \"{source}\" -mmt=off", RedirectStandardError = true, RedirectStandardInput = true, RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; var p = new Process { StartInfo = info }; p.Start(); ChildProcessTracker.AddProcess(p); try { p.PriorityClass = ProcessPriorityClass.BelowNormal; } catch (Exception) { } var name = Path.GetFileName(source); try { while (!p.HasExited) { var line = p.StandardOutput.ReadLine(); if (line == null) { break; } if (line.Length <= 4 || line[3] != '%') { continue; } int.TryParse(line.Substring(0, 3), out var percentInt); Utils.Status($"Extracting {name} - {line.Trim()}", Percent.FactoryPutInRange(percentInt / 100d)); } } catch (Exception) { } p.WaitForExitAndWarn(TimeSpan.FromSeconds(30), $"Extracting {name}"); if (p.ExitCode == 0) { Utils.Status($"Extracting {name} - 100%", Percent.One, alsoLog: true); return; } Utils.Error(new _7zipReturnError(p.ExitCode, source, dest, p.StandardOutput.ReadToEnd())); }