diff --git a/Wabbajack.Common/Utils.cs b/Wabbajack.Common/Utils.cs
index 697bc6b3..937f932a 100644
--- a/Wabbajack.Common/Utils.cs
+++ b/Wabbajack.Common/Utils.cs
@@ -129,5 +129,59 @@ namespace Wabbajack.Common
}
}
+ public static List
PMap(this IEnumerable coll, Func f)
+ {
+ var tasks = coll.Select(i =>
+ {
+ TaskCompletionSource tc = new TaskCompletionSource
();
+ WorkQueue.QueueTask(() =>
+ {
+ try
+ {
+ tc.SetResult(f(i));
+ }
+ catch (Exception ex)
+ {
+ tc.SetException(ex);
+ }
+ });
+ return tc.Task;
+ }).ToList();
+
+ return tasks.Select(t =>
+ {
+ t.Wait();
+ return t.Result;
+ }).ToList();
+ }
+
+ public static void PMap(this IEnumerable coll, Action f)
+ {
+ var tasks = coll.Select(i =>
+ {
+ TaskCompletionSource tc = new TaskCompletionSource();
+ WorkQueue.QueueTask(() =>
+ {
+ try
+ {
+ f(i);
+ tc.SetResult(true);
+ }
+ catch (Exception ex)
+ {
+ tc.SetException(ex);
+ }
+ });
+ return tc.Task;
+ }).ToList();
+
+ tasks.Select(t =>
+ {
+ t.Wait();
+ return t.Result;
+ }).ToList();
+ return;
+ }
+
}
}
diff --git a/Wabbajack.Common/Wabbajack.Common.csproj b/Wabbajack.Common/Wabbajack.Common.csproj
index 095b9fc2..86d1b20f 100644
--- a/Wabbajack.Common/Wabbajack.Common.csproj
+++ b/Wabbajack.Common/Wabbajack.Common.csproj
@@ -60,6 +60,7 @@
+
diff --git a/Wabbajack.Common/WorkQueue.cs b/Wabbajack.Common/WorkQueue.cs
new file mode 100644
index 00000000..3ed1155d
--- /dev/null
+++ b/Wabbajack.Common/WorkQueue.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Wabbajack.Common
+{
+ public class WorkQueue
+ {
+ private static BlockingCollection Queue = new BlockingCollection();
+
+ [ThreadStatic]
+ private static int CpuId;
+
+ public static void Init(Action report_function)
+ {
+ ReportFunction = report_function;
+ ThreadCount = Environment.ProcessorCount;
+ StartThreads();
+ }
+
+ private static void StartThreads()
+ {
+ Threads = Enumerable.Range(0, ThreadCount)
+ .Select(idx =>
+ {
+ var thread = new Thread(() => ThreadBody(idx));
+ thread.Priority = ThreadPriority.BelowNormal;
+ thread.IsBackground = true;
+ thread.Name = String.Format("Wabbajack_Worker_{0}", idx);
+ thread.Start();
+ return thread;
+ }).ToList();
+ }
+
+ private static void ThreadBody(int idx)
+ {
+ CpuId = idx;
+
+ while(true)
+ {
+ Report("Waiting", 0);
+ var f = Queue.Take();
+ f();
+ }
+
+ }
+ public static void Report(string msg, int progress)
+ {
+ ReportFunction(CpuId, msg, progress);
+ }
+
+ public static void QueueTask(Action a)
+ {
+ Queue.Add(a);
+ }
+
+ public static Action ReportFunction { get; private set; }
+ public static int ThreadCount { get; private set; }
+ public static List Threads { get; private set; }
+ }
+}
diff --git a/Wabbajack.sln b/Wabbajack.sln
index ddc035ba..97d8040c 100644
--- a/Wabbajack.sln
+++ b/Wabbajack.sln
@@ -3,24 +3,20 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29102.190
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wabbajack", "Wabbajack\Wabbajack.csproj", "{1649CAB3-6F8E-4F2E-844C-931BD4B61233}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wabbajack.Common", "Wabbajack.Common\Wabbajack.Common.csproj", "{B3F3FB6E-B9EB-4F49-9875-D78578BC7AE5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BSA.Tools", "BSA.Tools\BSA.Tools.csproj", "{B6389807-EA59-4633-B42B-A85F52FEC135}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SevenZipExtractor", "SevenZipExtractor\SevenZipExtractor.csproj", "{8AA97F58-5044-4BBA-B8D9-A74B6947A660}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wabbajack", "Wabbajack\Wabbajack.csproj", "{33602679-8484-40C7-A10C-774DFF5D8314}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {1649CAB3-6F8E-4F2E-844C-931BD4B61233}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1649CAB3-6F8E-4F2E-844C-931BD4B61233}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1649CAB3-6F8E-4F2E-844C-931BD4B61233}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1649CAB3-6F8E-4F2E-844C-931BD4B61233}.Release|Any CPU.Build.0 = Release|Any CPU
{B3F3FB6E-B9EB-4F49-9875-D78578BC7AE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B3F3FB6E-B9EB-4F49-9875-D78578BC7AE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B3F3FB6E-B9EB-4F49-9875-D78578BC7AE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -33,6 +29,10 @@ Global
{8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Release|Any CPU.Build.0 = Release|Any CPU
+ {33602679-8484-40C7-A10C-774DFF5D8314}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {33602679-8484-40C7-A10C-774DFF5D8314}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {33602679-8484-40C7-A10C-774DFF5D8314}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {33602679-8484-40C7-A10C-774DFF5D8314}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Wabbajack/App.xaml b/Wabbajack/App.xaml
new file mode 100644
index 00000000..9f16f10f
--- /dev/null
+++ b/Wabbajack/App.xaml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/Wabbajack/App.xaml.cs b/Wabbajack/App.xaml.cs
new file mode 100644
index 00000000..90cf0503
--- /dev/null
+++ b/Wabbajack/App.xaml.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace Wabbajack
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : Application
+ {
+ }
+}
diff --git a/Wabbajack/AppState.cs b/Wabbajack/AppState.cs
new file mode 100644
index 00000000..f99e4510
--- /dev/null
+++ b/Wabbajack/AppState.cs
@@ -0,0 +1,102 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+using System.Windows.Threading;
+using Wabbajack.Common;
+
+namespace Wabbajack
+{
+ internal class AppState
+ {
+ public class CPUStatus
+ {
+ public int Progress { get; internal set; }
+ public string Msg { get; internal set; }
+ public int ID { get; internal set; }
+ }
+
+ public volatile bool Dirty;
+
+ private Dispatcher dispatcher;
+
+ public ObservableCollection Log { get; }
+ public ObservableCollection Status { get; }
+
+
+ public String Mode { get; set; }
+
+ private List InternalStatus { get; }
+ public string LogFile { get; private set; }
+
+ public AppState(Dispatcher d, String mode)
+ {
+ LogFile = Assembly.GetExecutingAssembly().Location + ".log";
+
+ if (LogFile.FileExists())
+ File.Delete(LogFile);
+
+ Mode = mode;
+ Dirty = false;
+ dispatcher = d;
+ Log = new ObservableCollection();
+ Status = new ObservableCollection();
+ InternalStatus = new List();
+
+ var th = new Thread(() => UpdateLoop());
+ th.Priority = ThreadPriority.BelowNormal;
+ th.IsBackground = true;
+ th.Start();
+ }
+
+ private void UpdateLoop()
+ {
+ while (true)
+ {
+ if (Dirty)
+ {
+ lock (InternalStatus)
+ {
+ var data = InternalStatus.ToArray();
+ dispatcher.Invoke(() =>
+ {
+ for (int idx = 0; idx < data.Length; idx += 1)
+ {
+ if (idx >= Status.Count)
+ Status.Add(data[idx]);
+ else if (Status[idx] != data[idx])
+ Status[idx] = data[idx];
+ }
+ });
+ Dirty = false;
+ }
+ }
+ Thread.Sleep(250);
+ }
+ }
+
+ public void LogMsg(string msg)
+ {
+ dispatcher.Invoke(() => Log.Add(msg));
+ lock (dispatcher) {
+ File.AppendAllText(LogFile, msg + "\r\n");
+ }
+ }
+
+ public void SetProgress(int id, string msg, int progress)
+ {
+ lock (InternalStatus)
+ {
+ Dirty = true;
+ while (id >= InternalStatus.Count)
+ {
+ InternalStatus.Add(new CPUStatus());
+ }
+
+ InternalStatus[id] = new CPUStatus() { ID = id, Msg = msg, Progress = progress };
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Wabbajack/AutoScrollBehavior.cs b/Wabbajack/AutoScrollBehavior.cs
new file mode 100644
index 00000000..1c46151f
--- /dev/null
+++ b/Wabbajack/AutoScrollBehavior.cs
@@ -0,0 +1,117 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Wabbajack
+{
+ class AutoScrollBehavior
+ {
+ static readonly Dictionary Associations =
+ new Dictionary();
+
+ public static bool GetScrollOnNewItem(DependencyObject obj)
+ {
+ return (bool)obj.GetValue(ScrollOnNewItemProperty);
+ }
+
+ public static void SetScrollOnNewItem(DependencyObject obj, bool value)
+ {
+ obj.SetValue(ScrollOnNewItemProperty, value);
+ }
+
+ public static readonly DependencyProperty ScrollOnNewItemProperty =
+ DependencyProperty.RegisterAttached(
+ "ScrollOnNewItem",
+ typeof(bool),
+ typeof(AutoScrollBehavior),
+ new UIPropertyMetadata(false, OnScrollOnNewItemChanged));
+
+ public static void OnScrollOnNewItemChanged(
+ DependencyObject d,
+ DependencyPropertyChangedEventArgs e)
+ {
+ var listBox = d as ListBox;
+ if (listBox == null) return;
+ bool oldValue = (bool)e.OldValue, newValue = (bool)e.NewValue;
+ if (newValue == oldValue) return;
+ if (newValue)
+ {
+ listBox.Loaded += ListBox_Loaded;
+ listBox.Unloaded += ListBox_Unloaded;
+ var itemsSourcePropertyDescriptor = TypeDescriptor.GetProperties(listBox)["ItemsSource"];
+ itemsSourcePropertyDescriptor.AddValueChanged(listBox, ListBox_ItemsSourceChanged);
+ }
+ else
+ {
+ listBox.Loaded -= ListBox_Loaded;
+ listBox.Unloaded -= ListBox_Unloaded;
+ if (Associations.ContainsKey(listBox))
+ Associations[listBox].Dispose();
+ var itemsSourcePropertyDescriptor = TypeDescriptor.GetProperties(listBox)["ItemsSource"];
+ itemsSourcePropertyDescriptor.RemoveValueChanged(listBox, ListBox_ItemsSourceChanged);
+ }
+ }
+
+ private static void ListBox_ItemsSourceChanged(object sender, EventArgs e)
+ {
+ var listBox = (ListBox)sender;
+ if (Associations.ContainsKey(listBox))
+ Associations[listBox].Dispose();
+ Associations[listBox] = new Capture(listBox);
+ }
+
+ static void ListBox_Unloaded(object sender, RoutedEventArgs e)
+ {
+ var listBox = (ListBox)sender;
+ if (Associations.ContainsKey(listBox))
+ Associations[listBox].Dispose();
+ listBox.Unloaded -= ListBox_Unloaded;
+ }
+
+ static void ListBox_Loaded(object sender, RoutedEventArgs e)
+ {
+ var listBox = (ListBox)sender;
+ var incc = listBox.Items as INotifyCollectionChanged;
+ if (incc == null) return;
+ listBox.Loaded -= ListBox_Loaded;
+ Associations[listBox] = new Capture(listBox);
+ }
+
+ class Capture : IDisposable
+ {
+ private readonly ListBox listBox;
+ private readonly INotifyCollectionChanged incc;
+
+ public Capture(ListBox listBox)
+ {
+ this.listBox = listBox;
+ incc = listBox.ItemsSource as INotifyCollectionChanged;
+ if (incc != null)
+ {
+ incc.CollectionChanged += incc_CollectionChanged;
+ }
+ }
+
+ void incc_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ if (e.Action == NotifyCollectionChangedAction.Add)
+ {
+ listBox.ScrollIntoView(e.NewItems[0]);
+ listBox.SelectedItem = e.NewItems[0];
+ }
+ }
+
+ public void Dispose()
+ {
+ if (incc != null)
+ incc.CollectionChanged -= incc_CollectionChanged;
+ }
+ }
+ }
+}
diff --git a/Wabbajack/Compiler.cs b/Wabbajack/Compiler.cs
index 3c30c2d4..c22bf6c9 100644
--- a/Wabbajack/Compiler.cs
+++ b/Wabbajack/Compiler.cs
@@ -1,5 +1,4 @@
-using Murmur;
-using Newtonsoft.Json;
+using Newtonsoft.Json;
using SevenZipExtractor;
using System;
using System.Collections.Generic;
@@ -24,31 +23,15 @@ namespace Wabbajack
public dynamic MO2Ini { get; }
public string GamePath { get; }
- public string MO2DownloadsFolder {
+ public string MO2DownloadsFolder
+ {
get
{
return Path.Combine(MO2Folder, "downloads");
}
}
- internal void PatchExecutable()
- {
- var data = JsonConvert.SerializeObject(InstallDirectives).BZip2String();
- var executable = Assembly.GetExecutingAssembly().Location;
- var out_path = Path.Combine(Path.GetDirectoryName(executable), "out.exe");
- File.Copy(executable, out_path, true);
- using(var os = File.OpenWrite(out_path))
- using(var bw = new BinaryWriter(os))
- {
- long orig_pos = os.Length;
- os.Position = os.Length;
- bw.Write(data.LongLength);
- bw.Write(data);
- bw.Write(orig_pos);
- bw.Write(Encoding.ASCII.GetBytes(Consts.ModPackMagic));
- }
- }
public string MO2Profile;
@@ -61,7 +44,6 @@ namespace Wabbajack
}
public Action Log_Fn { get; }
- public Action Progress_Function { get; }
public List InstallDirectives { get; private set; }
public List SelectedArchives { get; private set; }
public List AllFiles { get; private set; }
@@ -75,6 +57,14 @@ namespace Wabbajack
Log_Fn(msg);
}
+ public void Status(string msg, params object[] args)
+ {
+ if (args.Length > 0)
+ msg = String.Format(msg, args);
+ WorkQueue.Report(msg, 0);
+ }
+
+
private void Error(string msg, params object[] args)
{
if (args.Length > 0)
@@ -83,24 +73,21 @@ namespace Wabbajack
throw new Exception(msg);
}
- public Compiler(string mo2_folder, Action log_fn, Action progress_function)
+ public Compiler(string mo2_folder, Action log_fn)
{
MO2Folder = mo2_folder;
Log_Fn = log_fn;
- Progress_Function = progress_function;
MO2Ini = Path.Combine(MO2Folder, "ModOrganizer.ini").LoadIniFile();
GamePath = ((string)MO2Ini.General.gamePath).Replace("\\\\", "\\");
}
-
+
public void LoadArchives()
{
IndexedArchives = Directory.EnumerateFiles(MO2DownloadsFolder)
.Where(file => SupportedArchives.Contains(Path.GetExtension(file)))
- .AsParallel()
- .Select(file => LoadArchive(file))
- .ToList();
+ .PMap(file => LoadArchive(file));
}
private IndexedArchive LoadArchive(string file)
@@ -109,6 +96,7 @@ namespace Wabbajack
if (metaname.FileExists() && new FileInfo(metaname).LastWriteTime >= new FileInfo(file).LastWriteTime)
{
+ Status("Loading Archive Index for {0}", Path.GetFileName(file));
var info = metaname.FromJSON();
info.Name = Path.GetFileName(file);
info.AbsolutePath = file;
@@ -125,6 +113,7 @@ namespace Wabbajack
using (var ar = new ArchiveFile(file))
{
+ Status("Indexing {0}", Path.GetFileName(file));
var streams = new Dictionary();
ar.Extract(entry => {
if (entry.IsFolder) return null;
@@ -170,7 +159,8 @@ namespace Wabbajack
var stack = MakeStack();
- var results = AllFiles.AsParallel().Select(f => RunStack(stack, f)).ToList();
+ Info("Running Compilation Stack");
+ var results = AllFiles.PMap(f => RunStack(stack, f)).ToList();
var nomatch = results.OfType();
Info("No match for {0} files", nomatch.Count());
@@ -181,9 +171,9 @@ namespace Wabbajack
GatherArchives();
BuildPatches();
-
- results.ToJSON("out.json");
-
+ PatchExecutable();
+
+ Info("Done Building Modpack");
}
@@ -198,13 +188,13 @@ namespace Wabbajack
Info("Patching building patches from {0} archives", groups.Count);
var absolute_paths = AllFiles.ToDictionary(e => e.Path, e => e.AbsolutePath);
- Parallel.ForEach(groups, group => BuildArchivePatches(group.Key, group, absolute_paths));
+ groups.PMap(group => BuildArchivePatches(group.Key, group, absolute_paths));
if (InstallDirectives.OfType().FirstOrDefault(f => f.Patch == null) != null)
{
Error("Missing patches after generation, this should not happen");
}
-
+
}
private void BuildArchivePatches(string archive_sha, IEnumerable group, Dictionary absolute_paths)
@@ -212,22 +202,23 @@ namespace Wabbajack
var archive = IndexedArchives.First(a => a.Hash == archive_sha);
var paths = group.Select(g => g.From).ToHashSet();
var streams = new Dictionary();
- Info("Etracting Patch Files from {0}", archive.Name);
+ Status("Etracting Patch Files from {0}", archive.Name);
// First we fetch the source files from the input archive
using (var a = new ArchiveFile(archive.AbsolutePath))
{
a.Extract(entry =>
{
- if (!paths.Contains(entry.FileName)) return null;
+ if (!paths.Contains(entry.FileName)) return null;
- var result = new MemoryStream();
- streams.Add(entry.FileName, result);
- return result;
+ var result = new MemoryStream();
+ streams.Add(entry.FileName, result);
+ return result;
}, false);
}
var extracted = streams.ToDictionary(k => k.Key, v => v.Value.ToArray());
// Now Create the patches
+ Status("Building Patches for {0}", archive.Name);
Parallel.ForEach(group, entry =>
{
Info("Patching {0}", entry.To);
@@ -259,7 +250,7 @@ namespace Wabbajack
private Archive ResolveArchive(string sha, Dictionary archives)
{
- if(archives.TryGetValue(sha, out var found))
+ if (archives.TryGetValue(sha, out var found))
{
if (found.IniData == null)
Error("No download metadata found for {0}, please use MO2 to query info or add a .meta file and try again.", found.Name);
@@ -271,10 +262,12 @@ namespace Wabbajack
if (general.modID != null && general.fileID != null && general.gameName != null)
{
- result = new NexusMod() {
+ result = new NexusMod()
+ {
GameName = general.gameName,
FileID = general.fileID,
- ModID = general.modID};
+ ModID = general.modID
+ };
}
else if (general.directURL != null)
{
@@ -302,6 +295,7 @@ namespace Wabbajack
private Directive RunStack(IEnumerable> stack, RawSourceFile source)
{
+ Status("Compiling {0}", source.Path);
return (from f in stack
let result = f(source)
where result != null
@@ -475,7 +469,7 @@ namespace Wabbajack
var result = source.EvolveTo();
result.Reason = "No Match in Stack";
return result;
- };
+ };
}
private Func DirectMatch()
@@ -488,7 +482,6 @@ namespace Wabbajack
return source =>
{
- Info("Hashing {0}", source.Path);
if (indexed.TryGetValue(source.Hash, out var found))
{
var result = source.EvolveTo();
@@ -518,5 +511,24 @@ namespace Wabbajack
return null;
};
}
+
+ internal void PatchExecutable()
+ {
+ var data = JsonConvert.SerializeObject(InstallDirectives).BZip2String();
+ var executable = Assembly.GetExecutingAssembly().Location;
+ var out_path = Path.Combine(Path.GetDirectoryName(executable), MO2Profile + ".exe");
+ Info("Patching Executable {0}", Path.GetFileName(out_path));
+ File.Copy(executable, out_path, true);
+ using (var os = File.OpenWrite(out_path))
+ using (var bw = new BinaryWriter(os))
+ {
+ long orig_pos = os.Length;
+ os.Position = os.Length;
+ bw.Write(data.LongLength);
+ bw.Write(data);
+ bw.Write(orig_pos);
+ bw.Write(Encoding.ASCII.GetBytes(Consts.ModPackMagic));
+ }
+ }
}
}
diff --git a/Wabbajack/MainWindow.xaml b/Wabbajack/MainWindow.xaml
new file mode 100644
index 00000000..960a2936
--- /dev/null
+++ b/Wabbajack/MainWindow.xaml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Wabbajack/MainWindow.xaml.cs b/Wabbajack/MainWindow.xaml.cs
new file mode 100644
index 00000000..2a1e2153
--- /dev/null
+++ b/Wabbajack/MainWindow.xaml.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using Wabbajack.Common;
+
+namespace Wabbajack
+{
+ ///
+ /// Interaction logic for MainWindow.xaml
+ ///
+ public partial class MainWindow : Window
+ {
+ public MainWindow()
+ {
+ InitializeComponent();
+ var context = new AppState(Dispatcher, "Building");
+ WorkQueue.Init((id, msg, progress) => context.SetProgress(id, msg, progress));
+
+ var compiler = new Compiler("c:\\Mod Organizer 2", msg => context.LogMsg(msg));
+ new Thread(() =>
+ {
+ compiler.LoadArchives();
+ compiler.MO2Profile = "Lexy's Legacy of The Dragonborn Special Edition";
+ compiler.Compile();
+ }).Start();
+
+
+ this.DataContext = context;
+
+ }
+ }
+}
diff --git a/Wabbajack/Program.cs b/Wabbajack/Program.cs
deleted file mode 100644
index 06f2e4f4..00000000
--- a/Wabbajack/Program.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using Wabbajack.Common;
-
-namespace Wabbajack
-{
- class Program
- {
- static void Main(string[] args)
- {
- var modpack = CheckForModPack();
- if (modpack != null)
- {
- Console.WriteLine(modpack);
- Thread.Sleep(10000);
- return;
- }
-
- var compiler = new Compiler("c:\\Mod Organizer 2", msg => Console.WriteLine(msg), (msg, id, prog) => Console.WriteLine(msg));
- compiler.LoadArchives();
- compiler.MO2Profile = "Lexy's Legacy of The Dragonborn Special Edition";
- compiler.Compile();
- compiler.PatchExecutable();
-
- }
-
- private static string CheckForModPack()
- {
- using (var s = File.OpenRead(Assembly.GetExecutingAssembly().Location))
- {
- var magic_bytes = Encoding.ASCII.GetBytes(Consts.ModPackMagic);
- s.Position = s.Length - magic_bytes.Length;
- using (var br = new BinaryReader(s))
- {
- var bytes = br.ReadBytes(magic_bytes.Length);
- var magic = Encoding.ASCII.GetString(bytes);
- if (magic != Consts.ModPackMagic)
- {
- return null;
- }
-
- s.Position = s.Length - magic_bytes.Length - 8;
- var start_pos = br.ReadInt64();
- s.Position = start_pos;
- long length = br.ReadInt64();
-
- return br.ReadBytes((int)length).BZip2String();
-
- }
- }
- }
- }
-}
diff --git a/Wabbajack/Properties/AssemblyInfo.cs b/Wabbajack/Properties/AssemblyInfo.cs
index 702339de..72bb216a 100644
--- a/Wabbajack/Properties/AssemblyInfo.cs
+++ b/Wabbajack/Properties/AssemblyInfo.cs
@@ -1,6 +1,8 @@
using System.Reflection;
+using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using System.Windows;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
@@ -19,8 +21,25 @@ using System.Runtime.InteropServices;
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("1649cab3-6f8e-4f2e-844c-931bd4b61233")]
+//In order to begin building localizable applications, set
+//CultureYouAreCodingWith in your .csproj file
+//inside a . For example, if you are using US english
+//in your source files, set the to en-US. Then uncomment
+//the NeutralResourceLanguage attribute below. Update the "en-US" in
+//the line below to match the UICulture setting in the project file.
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
+
// Version information for an assembly consists of the following four values:
//
diff --git a/Wabbajack/Properties/Resources.Designer.cs b/Wabbajack/Properties/Resources.Designer.cs
index ab5f14c9..0827b61c 100644
--- a/Wabbajack/Properties/Resources.Designer.cs
+++ b/Wabbajack/Properties/Resources.Designer.cs
@@ -8,10 +8,10 @@
//
//------------------------------------------------------------------------------
-namespace Wabbajack.Properties {
- using System;
-
-
+namespace Wabbajack.Properties
+{
+
+
///
/// A strongly-typed resource class, for looking up localized strings, etc.
///
@@ -19,54 +19,53 @@ namespace Wabbajack.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class Resources {
-
+ internal class Resources
+ {
+
private static global::System.Resources.ResourceManager resourceMan;
-
+
private static global::System.Globalization.CultureInfo resourceCulture;
-
+
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Resources() {
+ internal Resources()
+ {
}
-
+
///
/// Returns the cached ResourceManager instance used by this class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager {
- get {
- if (object.ReferenceEquals(resourceMan, null)) {
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Wabbajack.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
-
+
///
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture {
- get {
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
return resourceCulture;
}
- set {
+ set
+ {
resourceCulture = value;
}
}
-
- ///
- /// Looks up a localized string similar to .
- ///
- internal static string ModPack {
- get {
- return ResourceManager.GetString("ModPack", resourceCulture);
- }
- }
}
}
diff --git a/Wabbajack/Properties/Resources.resx b/Wabbajack/Properties/Resources.resx
index c1567b33..af7dbebb 100644
--- a/Wabbajack/Properties/Resources.resx
+++ b/Wabbajack/Properties/Resources.resx
@@ -46,7 +46,7 @@
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
@@ -60,7 +60,6 @@
: and then encoded with base64 encoding.
-->
-
@@ -69,10 +68,9 @@
-
+
-
@@ -87,10 +85,9 @@
-
+
-
@@ -112,12 +109,9 @@
2.0
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
-
\ No newline at end of file
diff --git a/Wabbajack/Properties/Settings.Designer.cs b/Wabbajack/Properties/Settings.Designer.cs
new file mode 100644
index 00000000..776cd400
--- /dev/null
+++ b/Wabbajack/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Wabbajack.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/Wabbajack/Properties/Settings.settings b/Wabbajack/Properties/Settings.settings
new file mode 100644
index 00000000..033d7a5e
--- /dev/null
+++ b/Wabbajack/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Wabbajack/Wabbajack.csproj b/Wabbajack/Wabbajack.csproj
index 5a4f2e42..8da3b5f9 100644
--- a/Wabbajack/Wabbajack.csproj
+++ b/Wabbajack/Wabbajack.csproj
@@ -5,12 +5,14 @@
Debug
AnyCPU
- {1649CAB3-6F8E-4F2E-844C-931BD4B61233}
- Exe
+ {33602679-8484-40C7-A10C-774DFF5D8314}
+ WinExe
Wabbajack
Wabbajack
v4.7.2
512
+ {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 4
true
true
@@ -39,39 +41,77 @@
..\packages\Costura.Fody.4.0.0\lib\net40\Costura.dll
-
- ..\packages\murmurhash.1.0.3\lib\net45\MurmurHash.dll
-
..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll
+
+
+
-
-
-
+
+ 4.0
+
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ App.xaml
+ Code
+
+
+
-
-
+
+ MainWindow.xaml
+ Code
+
+
+
+
+ Code
+
True
True
Resources.resx
+
+ True
+ Settings.settings
+ True
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
-
-
-
-
+
+ {b6389807-ea59-4633-b42b-a85f52fec135}
+ BSA.Tools
+
{8aa97f58-5044-4bba-b8d9-a74b6947a660}
SevenZipExtractor
@@ -81,19 +121,13 @@
Wabbajack.Common
-
-
- ResXFileCodeGenerator
- Resources.Designer.cs
-
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
+
-
\ No newline at end of file
diff --git a/Wabbajack/packages.config b/Wabbajack/packages.config
index b65cc07a..d3422849 100644
--- a/Wabbajack/packages.config
+++ b/Wabbajack/packages.config
@@ -2,6 +2,5 @@
-
\ No newline at end of file