diff --git a/Wabbajack.Common/Json.cs b/Wabbajack.Common/Json.cs index 4d2584c7..64b6e9ab 100644 --- a/Wabbajack.Common/Json.cs +++ b/Wabbajack.Common/Json.cs @@ -78,7 +78,10 @@ namespace Wabbajack.Common using var tr = new StreamReader(stream, Encoding.UTF8, leaveOpen: true); using var reader = new JsonTextReader(tr); var ser = JsonSerializer.Create(JsonSettings); - return ser.Deserialize<T>(reader); + var result = ser.Deserialize<T>(reader); + if (result == null) + throw new JsonException("Type deserialized into null"); + return result; } @@ -238,7 +241,7 @@ namespace Wabbajack.Common - public class JsonNameSerializationBinder : ISerializationBinder + public class JsonNameSerializationBinder : DefaultSerializationBinder { private static Dictionary<string, Type> _nameToType = new Dictionary<string, Type>(); private static Dictionary<Type, string> _typeToName = new Dictionary<Type, string>(); @@ -280,7 +283,7 @@ namespace Wabbajack.Common } - public Type BindToType(string? assemblyName, string typeName) + public override Type BindToType(string? assemblyName, string typeName) { if (typeName.EndsWith("[]")) { @@ -295,22 +298,17 @@ namespace Wabbajack.Common if (val != null) return val; - if (assemblyName != null) - { - var assembly = AppDomain.CurrentDomain.Load(assemblyName); - if (assembly != null) - { - var result = assembly.GetType(typeName); - if (result != null) return result; - } - } - - - throw new InvalidDataException($"No Binding name for {typeName}"); + return base.BindToType(assemblyName, typeName); } - public void BindToName(Type serializedType, out string? assemblyName, out string? typeName) + public override void BindToName(Type serializedType, out string? assemblyName, out string? typeName) { + if (serializedType.FullName?.StartsWith("System.") ?? false) + { + base.BindToName(serializedType, out assemblyName, out typeName); + return; + } + if (!_typeToName.ContainsKey(serializedType)) { throw new InvalidDataException($"No Binding name for {serializedType}"); diff --git a/Wabbajack.Common/Paths.cs b/Wabbajack.Common/Paths.cs index eb2617dd..d5fac5b3 100644 --- a/Wabbajack.Common/Paths.cs +++ b/Wabbajack.Common/Paths.cs @@ -145,13 +145,16 @@ namespace Wabbajack.Common } } + /// <summary> + /// Returns the full path the folder that contains Wabbajack.Common. This will almost always be + /// where all the binaries for the project reside. + /// </summary> + /// <exception cref="ArgumentException"></exception> public static AbsolutePath EntryPoint { get { - var location = Assembly.GetEntryAssembly()?.Location ?? null; - if (location == null) - location = Assembly.GetExecutingAssembly().Location ?? null; + var location = Assembly.GetExecutingAssembly().Location ?? null; if (location == null) throw new ArgumentException("Could not find entry point."); return ((AbsolutePath)location).Parent; diff --git a/Wabbajack.Common/ProcessHelper.cs b/Wabbajack.Common/ProcessHelper.cs index fb9f5251..8c81852d 100644 --- a/Wabbajack.Common/ProcessHelper.cs +++ b/Wabbajack.Common/ProcessHelper.cs @@ -16,24 +16,35 @@ namespace Wabbajack.Common Error, } - public string Path { get; set; } = string.Empty; + public AbsolutePath Path { get; set; } public IEnumerable<object> Arguments { get; set; } = Enumerable.Empty<object>(); public bool LogError { get; set; } = true; - public readonly Subject<(StreamType Type, string Line)> Output = new Subject<(StreamType Type, string)>(); - - + public readonly Subject<(StreamType Type, string Line)> Output = new Subject<(StreamType Type, string)>(); + + public bool ThrowOnNonZeroExitCode { get; set; } = false; + + public ProcessHelper() { } public async Task<int> Start() { + var args = Arguments.Select(arg => + { + return arg switch + { + AbsolutePath abs => $"\"{abs}\"", + RelativePath rel => $"\"{rel}\"", + _ => arg.ToString() + }; + }); var info = new ProcessStartInfo { FileName = (string)Path, - Arguments = string.Join(" ", Arguments), + Arguments = string.Join(" ", args), RedirectStandardError = true, RedirectStandardInput = true, RedirectStandardOutput = true, @@ -65,7 +76,7 @@ namespace Wabbajack.Common if (string.IsNullOrEmpty(data.Data)) return; Output.OnNext((StreamType.Error, data.Data)); if (LogError) - Utils.Log($"{AlphaPath.GetFileName(Path)} ({p.Id}) StdErr: {data.Data}"); + Utils.Log($"{Path.FileName} ({p.Id}) StdErr: {data.Data}"); }; p.ErrorDataReceived += ErrorEventHandler; @@ -92,6 +103,9 @@ namespace Wabbajack.Common p.Exited -= Exited; Output.OnCompleted(); + + if (result != 0 && ThrowOnNonZeroExitCode) + throw new Exception($"Error executing {Path} - Exit Code {result} - Check the log for more information"); return result; } diff --git a/Wabbajack.Common/Utils.cs b/Wabbajack.Common/Utils.cs index 4e108027..4f971802 100644 --- a/Wabbajack.Common/Utils.cs +++ b/Wabbajack.Common/Utils.cs @@ -517,7 +517,6 @@ namespace Wabbajack.Common return await Task.WhenAll(tasks); } - public static async Task<TR[]> PMap<TI, TR>(this IEnumerable<TI> coll, WorkQueue queue, Func<TI, Task<TR>> f) { @@ -956,7 +955,7 @@ namespace Wabbajack.Common { var process = new ProcessHelper { - Path = "cmd.exe", + Path = ((RelativePath)"cmd.exe").RelativeToSystemDirectory(), Arguments = new object[] {"/c", "del", "/f", "/q", "/s", $"\"{(string)path}\"", "&&", "rmdir", "/q", "/s", $"\"{(string)path}\""}, }; var result = process.Output.Where(d => d.Type == ProcessHelper.StreamType.Output) @@ -999,7 +998,7 @@ namespace Wabbajack.Common var encoded = ProtectedData.Protect(bytes, Encoding.UTF8.GetBytes(key), DataProtectionScope.LocalMachine); Consts.LocalAppDataPath.CreateDirectory(); - Consts.LocalAppDataPath.Combine(key).WriteAllBytes(bytes); + Consts.LocalAppDataPath.Combine(key).WriteAllBytes(encoded); } public static byte[] FromEncryptedData(string key) { diff --git a/Wabbajack.Lib/Downloaders/BethesdaNetDownloader.cs b/Wabbajack.Lib/Downloaders/BethesdaNetDownloader.cs index c05d4ed1..aae2c848 100644 --- a/Wabbajack.Lib/Downloaders/BethesdaNetDownloader.cs +++ b/Wabbajack.Lib/Downloaders/BethesdaNetDownloader.cs @@ -96,8 +96,9 @@ namespace Wabbajack.Lib.Downloaders result.ToEcryptedJson(DataName); return result; } - catch (Exception) + catch (Exception ex) { + Utils.Error(ex, "Could not save Bethesda.NET login info"); return null; } } @@ -363,6 +364,7 @@ namespace Wabbajack.Lib.Downloaders } + [JsonName("BethesdaNetData")] public class BethesdaNetData { public string body { get; set; } diff --git a/Wabbajack.Lib/Downloaders/YouTubeDownloader.cs b/Wabbajack.Lib/Downloaders/YouTubeDownloader.cs index c72184d0..713000bd 100644 --- a/Wabbajack.Lib/Downloaders/YouTubeDownloader.cs +++ b/Wabbajack.Lib/Downloaders/YouTubeDownloader.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO.Compression; using System.Linq; +using System.Reactive.Linq; using System.Threading; using System.Threading.Tasks; using System.Web; @@ -144,71 +145,46 @@ namespace Wabbajack.Lib.Downloaders } - private const string FFMpegPath = "Downloaders/Converters/ffmpeg.exe"; - private const string xWMAEncodePath = "Downloaders/Converters/xWMAEncode.exe"; - private async Task ExtractTrack(AbsolutePath source, AbsolutePath dest_folder, Track track) + private AbsolutePath FFMpegPath => "Downloaders/Converters/ffmpeg.exe".RelativeTo(AbsolutePath.EntryPoint); + private AbsolutePath xWMAEncodePath = "Downloaders/Converters/xWMAEncode.exe".RelativeTo(AbsolutePath.EntryPoint); + private Extension WAVExtension = new Extension(".wav"); + private Extension XWMExtension = new Extension(".xwm"); + private async Task ExtractTrack(AbsolutePath source, AbsolutePath destFolder, Track track) { - var info = new ProcessStartInfo + var process = new ProcessHelper { - FileName = FFMpegPath, - Arguments = - $"-threads 1 -i \"{source}\" -ss {track.Start} -t {track.End - track.Start} \"{dest_folder}\\{track.Name}.wav\"", - RedirectStandardError = true, - RedirectStandardInput = true, - RedirectStandardOutput = true, - UseShellExecute = false, - CreateNoWindow = true + Path = FFMpegPath, + Arguments = new object[] {"-threads", 1, "-i", source, "-ss", track.Start, "-t", track.End - track.Start, track.Name.RelativeTo(destFolder).WithExtension(WAVExtension)}, + ThrowOnNonZeroExitCode = true }; + + var ffmpegLogs = process.Output.Where(arg => arg.Type == ProcessHelper.StreamType.Output) + .ForEachAsync(val => + { + Utils.Status($"Extracting {track.Name} - {val.Line}"); + }); - var p = new Process {StartInfo = info}; - p.Start(); - ChildProcessTracker.AddProcess(p); - - var output = await p.StandardError.ReadToEndAsync(); - - try - { - p.PriorityClass = ProcessPriorityClass.BelowNormal; - } - catch (Exception e) - { - Utils.Error(e, "Error while setting process priority level for ffmpeg.exe"); - } - p.WaitForExit(); + await process.Start(); if (track.Format == Track.FormatEnum.WAV) return; - info = new ProcessStartInfo + process = new ProcessHelper() { - FileName = xWMAEncodePath, - Arguments = - $"-b 192000 \"{dest_folder}\\{track.Name}.wav\" \"{dest_folder}\\{track.Name}.xwm\"", - RedirectStandardError = true, - RedirectStandardInput = true, - RedirectStandardOutput = true, - UseShellExecute = false, - CreateNoWindow = true + Path = xWMAEncodePath, + Arguments = new object[] {"-b", 192000, track.Name.RelativeTo(destFolder).WithExtension(WAVExtension), track.Name.RelativeTo(destFolder).WithExtension(XWMExtension)}, + ThrowOnNonZeroExitCode = true }; - p = new Process {StartInfo = info}; + var xwmLogs = process.Output.Where(arg => arg.Type == ProcessHelper.StreamType.Output) + .ForEachAsync(val => + { + Utils.Status($"Encoding {track.Name} - {val.Line}"); + }); - p.Start(); - ChildProcessTracker.AddProcess(p); - - var output2 = await p.StandardError.ReadToEndAsync(); - - try - { - p.PriorityClass = ProcessPriorityClass.BelowNormal; - } - catch (Exception e) - { - Utils.Error(e, "Error while setting process priority level for ffmpeg.exe"); - } - p.WaitForExit(); + await process.Start(); - if (File.Exists($"{dest_folder}\\{track.Name}.wav")) - File.Delete($"{dest_folder}\\{track.Name}.wav"); + if (File.Exists($"{destFolder}\\{track.Name}.wav")) + File.Delete($"{destFolder}\\{track.Name}.wav"); } diff --git a/Wabbajack.VirtualFileSystem/FileExtractor.cs b/Wabbajack.VirtualFileSystem/FileExtractor.cs index 0ea6ff09..8f53f144 100644 --- a/Wabbajack.VirtualFileSystem/FileExtractor.cs +++ b/Wabbajack.VirtualFileSystem/FileExtractor.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics; using System.Linq; +using System.Reactive.Linq; using System.Threading.Tasks; using Alphaleonis.Win32.Filesystem; using Compression.BSA; @@ -25,9 +26,9 @@ namespace Wabbajack.VirtualFileSystem else if (source.Extension == Consts.OMOD) ExtractAllWithOMOD(source, dest); else if (source.Extension == Consts.EXE) - ExtractAllEXE(source, dest); + await ExtractAllExe(source, dest); else - ExtractAllWith7Zip(source, dest); + await ExtractAllWith7Zip(source, dest); } catch (Exception ex) { @@ -35,71 +36,40 @@ namespace Wabbajack.VirtualFileSystem } } - private static void ExtractAllEXE(AbsolutePath source, AbsolutePath dest) + private static async Task ExtractAllExe(AbsolutePath source, AbsolutePath dest) { - var isArchive = TestWith7z(source); + var isArchive = await TestWith7z(source); if (isArchive) { - ExtractAllWith7Zip(source, dest); + await ExtractAllWith7Zip(source, dest); return; } Utils.Log($"Extracting {(string)source.FileName}"); - var info = new ProcessStartInfo + var process = new ProcessHelper { - FileName = @"Extractors\innounp.exe", - Arguments = $"-x -y -b -d\"{(string)dest}\" \"{(string)source}\"", - RedirectStandardError = true, - RedirectStandardInput = true, - RedirectStandardOutput = true, - UseShellExecute = false, - CreateNoWindow = true + Path = @"Extractors\innounp.exe".RelativeTo(AbsolutePath.EntryPoint), + Arguments = new object[] {"-x", "-y", "-b", $"-d\"{dest}\"", source} }; - 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 = source.FileName; - try - { - while (!p.HasExited) + + var result = process.Output.Where(d => d.Type == ProcessHelper.StreamType.Output) + .ForEachAsync(p => { - var line = p.StandardOutput.ReadLine(); + var (_, line) = p; if (line == null) - break; + return; if (line.Length <= 4 || line[3] != '%') - continue; + return; int.TryParse(line.Substring(0, 3), out var percentInt); - Utils.Status($"Extracting {(string)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 {(string)name}"); - if (p.ExitCode == 0) - return; - - Utils.Log(p.StandardOutput.ReadToEnd()); - Utils.Log($"Extraction error extracting {source}"); - } + Utils.Status($"Extracting {source.FileName} - {line.Trim()}", Percent.FactoryPutInRange(percentInt / 100d)); + }); + await process.Start(); + } private class OMODProgress : ICodeProgress { @@ -159,60 +129,42 @@ namespace Wabbajack.VirtualFileSystem } } - private static void ExtractAllWith7Zip(AbsolutePath source, AbsolutePath dest) + 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 info = new ProcessStartInfo + + var process = new ProcessHelper { - FileName = @"Extractors\7z.exe", - Arguments = $"x -bsp1 -y -o\"{(string)dest}\" \"{(string)source}\" -mmt=off", - RedirectStandardError = true, - RedirectStandardInput = true, - RedirectStandardOutput = true, - UseShellExecute = false, - CreateNoWindow = true + Path = @"Extractors\7z.exe".RelativeTo(AbsolutePath.EntryPoint), + Arguments = new object[] {"x", "-bsp1", "-y", $"-o\"{dest}\"", source, "-mmt=off"} }; + - var p = new Process {StartInfo = info}; - - p.Start(); - ChildProcessTracker.AddProcess(p); - try - { - p.PriorityClass = ProcessPriorityClass.BelowNormal; - } - catch (Exception) - { - } - - var name = source.FileName; - try - { - while (!p.HasExited) + var result = process.Output.Where(d => d.Type == ProcessHelper.StreamType.Output) + .ForEachAsync(p => { - var line = p.StandardOutput.ReadLine(); + var (_, line) = p; if (line == null) - break; + return; - if (line.Length <= 4 || line[3] != '%') continue; + if (line.Length <= 4 || line[3] != '%') return; int.TryParse(line.Substring(0, 3), out var percentInt); - Utils.Status($"Extracting {(string)name} - {line.Trim()}", Percent.FactoryPutInRange(percentInt / 100d)); - } - } - catch (Exception) - { - } + Utils.Status($"Extracting {(string)source.FileName} - {line.Trim()}", Percent.FactoryPutInRange(percentInt / 100d)); + }); - p.WaitForExitAndWarn(TimeSpan.FromSeconds(30), $"Extracting {name}"); + var exitCode = await process.Start(); - if (p.ExitCode == 0) + + if (exitCode != 0) { - Utils.Status($"Extracting {name} - 100%", Percent.One, alsoLog: true); - return; + Utils.Error(new _7zipReturnError(exitCode, source, dest, "")); + } + else + { + Utils.Status($"Extracting {source.FileName} - done", Percent.One, alsoLog: true); } - Utils.Error(new _7zipReturnError(p.ExitCode, source, dest, p.StandardOutput.ReadToEnd())); } /// <summary> @@ -220,92 +172,35 @@ namespace Wabbajack.VirtualFileSystem /// </summary> /// <param name="v"></param> /// <returns></returns> - public static bool CanExtract(AbsolutePath v) + public static async Task<bool> CanExtract(AbsolutePath v) { var ext = v.Extension; if(ext != _exeExtension && !Consts.TestArchivesBeforeExtraction.Contains(ext)) return Consts.SupportedArchives.Contains(ext) || Consts.SupportedBSAs.Contains(ext); - var isArchive = TestWith7z(v); + var isArchive = await TestWith7z(v); if (isArchive) return true; - var info = new ProcessStartInfo + var process = new ProcessHelper { - FileName = @"Extractors\innounp.exe", - Arguments = $"-t \"{v}\" ", - RedirectStandardError = true, - RedirectStandardInput = true, - RedirectStandardOutput = true, - UseShellExecute = false, - CreateNoWindow = true + Path = @"Extractors\innounp.exe".RelativeTo(AbsolutePath.EntryPoint), + Arguments = new object[] {"-t", v}, }; - var p = new Process {StartInfo = info}; - - p.Start(); - ChildProcessTracker.AddProcess(p); - - var name = v.FileName; - while (!p.HasExited) - { - var line = p.StandardOutput.ReadLine(); - if (line == null) - break; - - if (line[0] != '#') - continue; - - Utils.Status($"Testing {(string)name} - {line.Trim()}"); - } - - p.WaitForExitAndWarn(TimeSpan.FromSeconds(30), $"Testing {name}"); - return p.ExitCode == 0; + return await process.Start() == 0; } - public static bool TestWith7z(AbsolutePath file) + public static async Task<bool> TestWith7z(AbsolutePath file) { - var testInfo = new ProcessStartInfo + var process = new ProcessHelper() { - FileName = @"Extractors\7z.exe", - Arguments = $"t \"{file}\"", - RedirectStandardError = true, - RedirectStandardInput = true, - RedirectStandardOutput = true, - UseShellExecute = false, - CreateNoWindow = true + Path = @"Extractors\7z.exe".RelativeTo(AbsolutePath.EntryPoint), + Arguments = new object[] {"t", file}, }; - var testP = new Process {StartInfo = testInfo}; - - testP.Start(); - ChildProcessTracker.AddProcess(testP); - try - { - testP.PriorityClass = ProcessPriorityClass.BelowNormal; - } - catch (Exception) - { - return false; - } - - try - { - while (!testP.HasExited) - { - var line = testP.StandardOutput.ReadLine(); - if (line == null) - break; - } - } - catch (Exception) - { - return false; - } - - testP.WaitForExitAndWarn(TimeSpan.FromSeconds(30), $"Can Extract Check {file}"); - return testP.ExitCode == 0; + return await process.Start() == 0; } private static Extension _exeExtension = new Extension(".exe"); diff --git a/Wabbajack.VirtualFileSystem/VirtualFile.cs b/Wabbajack.VirtualFileSystem/VirtualFile.cs index 2dac0afe..2c99b5bb 100644 --- a/Wabbajack.VirtualFileSystem/VirtualFile.cs +++ b/Wabbajack.VirtualFileSystem/VirtualFile.cs @@ -180,7 +180,7 @@ namespace Wabbajack.VirtualFileSystem if (context.UseExtendedHashes) self.ExtendedHashes = ExtendedHashes.FromFile(absPath); - if (FileExtractor.CanExtract(absPath)) + if (await FileExtractor.CanExtract(absPath)) { await using var tempFolder = Context.GetTemporaryFolder(); await FileExtractor.ExtractAll(context.Queue, absPath, tempFolder.FullName); diff --git a/Wabbajack/Views/Compilers/VortexCompilerConfigView.xaml b/Wabbajack/Views/Compilers/VortexCompilerConfigView.xaml deleted file mode 100644 index 56b3d9d9..00000000 --- a/Wabbajack/Views/Compilers/VortexCompilerConfigView.xaml +++ /dev/null @@ -1,147 +0,0 @@ -<UserControl - x:Class="Wabbajack.VortexCompilerConfigView" - xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" - xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:local="clr-namespace:Wabbajack" - xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - d:DesignHeight="450" - d:DesignWidth="800" - mc:Ignorable="d"> - <Grid> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="Auto" /> - <ColumnDefinition Width="20" /> - <ColumnDefinition Width="*" /> - <ColumnDefinition Width="30" /> - <ColumnDefinition Width="Auto" /> - <ColumnDefinition Width="20" /> - <ColumnDefinition Width="*" /> - </Grid.ColumnDefinitions> - <Grid.RowDefinitions> - <RowDefinition Height="40" /> - <RowDefinition Height="40" /> - <RowDefinition Height="40" /> - </Grid.RowDefinitions> - <TextBlock - Grid.Row="0" - Grid.Column="0" - HorizontalAlignment="Right" - VerticalAlignment="Center" - FontSize="14" - Text="Game" - TextAlignment="Center" - ToolTip="The game you wish to target" /> - <ComboBox - Grid.Row="0" - Grid.Column="2" - Height="30" - VerticalAlignment="Center" - VerticalContentAlignment="Center" - FontSize="14" - ItemsSource="{Binding GameOptions}" - SelectedValue="{Binding SelectedGame}" - ToolTip="The game you wish to target"> - <ComboBox.ItemTemplate> - <DataTemplate> - <TextBlock Margin="6,2" Text="{Binding DisplayName}" /> - </DataTemplate> - </ComboBox.ItemTemplate> - </ComboBox> - <TextBlock - Grid.Row="1" - Grid.Column="0" - HorizontalAlignment="Right" - VerticalAlignment="Center" - FontSize="14" - Text="Game Folder" - TextAlignment="Center" - ToolTip="The install folder for the game" /> - <local:FilePicker - Grid.Row="1" - Grid.Column="2" - Height="30" - VerticalAlignment="Center" - PickerVM="{Binding GameLocation}" - FontSize="14" - ToolTip="The install folder for the game" /> - <Grid - Grid.Row="2" - Grid.Column="2" - Height="28" - HorizontalAlignment="Left" - VerticalAlignment="Top"> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="Auto" /> - <ColumnDefinition Width="Auto" /> - </Grid.ColumnDefinitions> - <Button - Grid.Column="0" - Margin="0,0,5,0" - Background="Transparent" - Command="{Binding FindGameInSteamCommand}" - Style="{StaticResource CircleButtonStyle}" - ToolTip="Attempt to locate the game in Steam"> - <Image Margin="1" Source="../../Resources/Icons/steam.png" /> - </Button> - <Button - Grid.Column="1" - Background="Transparent" - Command="{Binding FindGameInGogCommand}" - Style="{StaticResource CircleButtonStyle}" - ToolTip="Attempt to locate game in GoG"> - <Image Margin="1" Source="../../Resources/Icons/gog.png" /> - </Button> - </Grid> - - <TextBlock - Grid.Row="0" - Grid.Column="4" - HorizontalAlignment="Right" - VerticalAlignment="Center" - FontSize="14" - Text="Download Location" - TextAlignment="Center" - ToolTip="The folder to download your mods" /> - <local:FilePicker - Grid.Row="0" - Grid.Column="6" - Height="30" - VerticalAlignment="Center" - PickerVM="{Binding DownloadsLocation}" - FontSize="14" - ToolTip="The folder to download your mods" /> - <TextBlock - Grid.Row="1" - Grid.Column="4" - HorizontalAlignment="Right" - VerticalAlignment="Center" - FontSize="14" - Text="Staging Location" - TextAlignment="Center" /> - <local:FilePicker - Grid.Row="1" - Grid.Column="6" - Height="30" - VerticalAlignment="Center" - PickerVM="{Binding StagingLocation}" - FontSize="14" /> - <TextBlock - Grid.Row="2" - Grid.Column="4" - HorizontalAlignment="Right" - VerticalAlignment="Center" - FontSize="14" - Text="Output Location" - TextAlignment="Center" - ToolTip="The folder to place the resulting modlist.wabbajack file" /> - <local:FilePicker - Grid.Row="2" - Grid.Column="6" - Height="30" - VerticalAlignment="Center" - PickerVM="{Binding Parent.OutputLocation}" - FontSize="14" - ToolTip="The folder to place the resulting modlist.wabbajack file" /> - </Grid> -</UserControl> diff --git a/Wabbajack/Views/Compilers/VortexCompilerConfigView.xaml.cs b/Wabbajack/Views/Compilers/VortexCompilerConfigView.xaml.cs deleted file mode 100644 index 3e59c494..00000000 --- a/Wabbajack/Views/Compilers/VortexCompilerConfigView.xaml.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Windows.Controls; - -namespace Wabbajack -{ - /// <summary> - /// Interaction logic for VortexCompilerConfigView.xaml - /// </summary> - public partial class VortexCompilerConfigView : UserControl - { - public VortexCompilerConfigView() - { - InitializeComponent(); - } - } -}