Logs and exceptions as classes

This commit is contained in:
Timothy Baldridge 2019-12-03 21:12:08 -07:00
parent fa9431b001
commit 9adfa89fca
33 changed files with 400 additions and 48 deletions

View File

@ -31,7 +31,7 @@ namespace Compression.BSA.Test
public static void Setup(TestContext testContext)
{
Queue = new WorkQueue();
Utils.LogMessages.Subscribe(f => testContext.WriteLine(f));
Utils.LogMessages.Subscribe(f => testContext.WriteLine(f.ShortDescription));
if (!Directory.Exists(_stagingFolder))
Directory.CreateDirectory(_stagingFolder);

View File

@ -6,6 +6,8 @@ using Alphaleonis.Win32.Filesystem;
using Compression.BSA;
using ICSharpCode.SharpZipLib.GZip;
using OMODFramework;
using Wabbajack.Common.StatusFeed;
using Wabbajack.Common.StatusFeed.Errors;
namespace Wabbajack.Common
{
@ -40,11 +42,11 @@ namespace Wabbajack.Common
else if (source.EndsWith(".omod"))
ExtractAllWithOMOD(source, dest);
else
ExtractAllWith7Zip(source, dest);
ExtractAllWith7Zip(queue, source, dest);
}
catch (Exception ex)
{
Utils.Log($"Error while extracting {source}");
queue.Log($"Error while extracting {source}");
throw ex;
}
}
@ -88,14 +90,14 @@ namespace Wabbajack.Common
}
catch (Exception ex)
{
Utils.Log($"While Extracting {source}");
queue.Log($"While Extracting {source}");
throw ex;
}
}
private static void ExtractAllWith7Zip(string source, string dest)
private static void ExtractAllWith7Zip(WorkQueue queue, string source, string dest)
{
Utils.Log($"Extracting {Path.GetFileName(source)}");
queue.Log(new GenericInfo($"Extracting {Path.GetFileName(source)}", $"The contents of {source} are being extracted to {dest} using 7zip.exe"));
var info = new ProcessStartInfo
{
@ -143,11 +145,11 @@ namespace Wabbajack.Common
}
p.WaitForExit();
if (p.ExitCode != 0)
if (p.ExitCode == 0)
{
Utils.Log(p.StandardOutput.ReadToEnd());
Utils.Log($"Extraction error extracting {source}");
return;
}
queue.Log(new _7zipReturnError(p.ExitCode, source, dest, p.StandardOutput.ReadToEnd()));
}
/// <summary>
@ -161,4 +163,4 @@ namespace Wabbajack.Common
return Consts.SupportedArchives.Contains(v) || Consts.SupportedBSAs.Contains(v);
}
}
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wabbajack.Common.StatusFeed
{
public abstract class AErrorMessage : Exception, IError
{
public DateTime Timestamp { get; } = DateTime.Now;
public abstract string ShortDescription { get; }
public abstract string ExtendedDescription { get; }
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wabbajack.Common.StatusFeed
{
public abstract class AStatusMessage : IStatusMessage
{
public DateTime Timestamp { get; } = DateTime.Now;
public abstract string ShortDescription { get; }
public abstract string ExtendedDescription { get; }
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wabbajack.Common.StatusFeed.Errors
{
public class _7zipReturnError : AStatusMessage, IError
{
private string _destination;
private string _filename;
private int _code;
private string _7zip_output;
public override string ShortDescription => $"7Zip returned an error while executing";
public override string ExtendedDescription =>
$@"7Zip.exe should always return 0 when it finishes executing. While extracting {_filename} 7Zip encountered some error and
instead returned {_code} which indicates there was an error. The archive might be corrupt or in a format that 7Zip cannot handle. Please verify the file is valid and that you
haven't run out of disk space in the {_destination} folder.
7Zip Output:
{_7zip_output}";
public _7zipReturnError(int code, string filename, string destination, string output)
{
_code = code;
_filename = filename;
_destination = destination;
_7zip_output = output;
}
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wabbajack.Common.StatusFeed.Errors
{
class FileExtractionError : AStatusMessage, IError
{
private string _filename;
private string _destination;
public override string ShortDescription { get; }
public override string ExtendedDescription { get; }
public FileExtractionError(string filename, string destination)
{
_filename = filename;
_destination = destination;
}
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wabbajack.Common.StatusFeed.Errors
{
public class UnconvertedError : AErrorMessage
{
private string _msg;
public UnconvertedError(string msg)
{
_msg = msg;
}
public override string ShortDescription { get => _msg; }
public override string ExtendedDescription { get; } = "";
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wabbajack.Common.StatusFeed
{
public class GenericInfo : AStatusMessage, IInfo
{
public override string ShortDescription { get; }
public override string ExtendedDescription { get;}
public GenericInfo(string short_description, string long_description = "")
{
ShortDescription = short_description;
ExtendedDescription = long_description;
}
public override string ToString()
{
return ShortDescription;
}
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wabbajack.Common.StatusFeed
{
public interface IError : IStatusMessage
{
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wabbajack.Common.StatusFeed
{
public interface IInfo : IStatusMessage
{
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wabbajack.Common.StatusFeed
{
public interface IStatusMessage
{
DateTime Timestamp { get; }
string ShortDescription { get; }
string ExtendedDescription { get; }
}
}

View File

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wabbajack.Common.StatusFeed
{
/// <summary>
/// Defines a message that requires user interaction. The user must perform some action
/// or make a choice.
/// </summary>
public interface IUserIntervention<T> : IStatusMessage
{
/// <summary>
/// The user didn't make a choice, so this action should be aborted
/// </summary>
void Cancel();
/// <summary>
/// The user has provided the required information.
/// </summary>
/// <param name="result"></param>
void Resume(T result);
}
/// <summary>
/// Defines a message that requires user interaction. The user must perform some action
/// or make a choice.
/// </summary>
public interface IUserIntervention : IStatusMessage
{
/// <summary>
/// The user didn't make a choice, so this action should be aborted
/// </summary>
void Cancel();
/// <summary>
/// Resume without any further information
/// </summary>
void Resume();
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Reactive.Subjects;
using Wabbajack.Common.StatusFeed;
namespace Wabbajack.Common
{

View File

@ -16,6 +16,8 @@ using Ceras;
using ICSharpCode.SharpZipLib.BZip2;
using IniParser;
using Newtonsoft.Json;
using ReactiveUI;
using Wabbajack.Common.StatusFeed;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
using Directory = System.IO.Directory;
@ -44,10 +46,8 @@ namespace Wabbajack.Common
File.Delete(LogFile);
}
private static readonly Subject<string> LoggerSubj = new Subject<string>();
public static IObservable<string> LogMessages => LoggerSubj;
private static readonly Subject<(string Message, int Progress)> StatusSubj = new Subject<(string Message, int Progress)>();
public static IObservable<(string Message, int Progress)> StatusUpdates => StatusSubj;
private static readonly Subject<IStatusMessage> LoggerSubj = new Subject<IStatusMessage>();
public static IObservable<IStatusMessage> LogMessages => LoggerSubj;
private static readonly string[] Suffix = {"B", "KB", "MB", "GB", "TB", "PB", "EB"}; // Longs run out around EB
@ -55,15 +55,30 @@ namespace Wabbajack.Common
private static DateTime _startTime;
public static void Log(string msg)
{
Log(new GenericInfo(msg));
}
public static T Log<T>(T msg) where T : IStatusMessage
{
lock (_lock)
{
msg = $"{(DateTime.Now - _startTime).TotalSeconds:0.##} - {msg}";
File.AppendAllText(LogFile, msg + "\r\n");
}
LoggerSubj.OnNext(msg);
return msg;
}
public static void Error(AErrorMessage err)
{
lock (_lock)
{
File.AppendAllText(LogFile, err.ShortDescription + "\r\n");
}
LoggerSubj.OnNext(err);
throw err;
}
public static void LogToFile(string msg)
@ -80,8 +95,6 @@ namespace Wabbajack.Common
{
if (WorkQueue.CurrentQueue != null)
WorkQueue.CurrentQueue.Report(msg, progress);
else
StatusSubj.OnNext((msg, progress));
}
/// <summary>
@ -673,10 +686,11 @@ namespace Wabbajack.Common
return false;
}
/*
public static void Warning(string s)
{
Log($"WARNING: {s}");
}
}*/
public static TV GetOrDefault<TK, TV>(this Dictionary<TK, TV> dict, TK key)
{
@ -713,11 +727,12 @@ namespace Wabbajack.Common
return tv.ToJSON().FromJSONString<T>();
}
/*
public static void Error(string msg)
{
Log(msg);
throw new Exception(msg);
}
}*/
public static Stream GetEmbeddedResourceStream(string name)
{
@ -743,7 +758,6 @@ namespace Wabbajack.Common
.Build();
return d.Deserialize<T>(new StringReader(s));
}
public static void LogStatus(string s)
{
Status(s);

View File

@ -104,6 +104,16 @@
<Compile Include="GOGHandler.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SplittingStream.cs" />
<Compile Include="StatusFeed\AErrorMessage.cs" />
<Compile Include="StatusFeed\AStatusMessage.cs" />
<Compile Include="StatusFeed\Errors\7zipReturnError.cs" />
<Compile Include="StatusFeed\Errors\FileExtractionError.cs" />
<Compile Include="StatusFeed\Errors\UnconvertedError.cs" />
<Compile Include="StatusFeed\GenericInfo.cs" />
<Compile Include="StatusFeed\IError.cs" />
<Compile Include="StatusFeed\IInfo.cs" />
<Compile Include="StatusFeed\IStatusMessage.cs" />
<Compile Include="StatusFeed\IUserIntervention.cs" />
<Compile Include="StatusFileStream.cs" />
<Compile Include="StatusUpdate.cs" />
<Compile Include="SteamHandler.cs" />

View File

@ -5,6 +5,7 @@ using System.Linq;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Threading;
using Wabbajack.Common.StatusFeed;
namespace Wabbajack.Common
{
@ -21,6 +22,9 @@ namespace Wabbajack.Common
private static readonly Subject<CPUStatus> _Status = new Subject<CPUStatus>();
public IObservable<CPUStatus> Status => _Status;
private static readonly Subject<IStatusMessage> _messages = new Subject<IStatusMessage>();
public IObservable<IStatusMessage> Messages => _messages;
public static List<Thread> Threads { get; private set; }
public WorkQueue(int threadCount = 0)
@ -28,6 +32,16 @@ namespace Wabbajack.Common
StartThreads(threadCount == 0 ? Environment.ProcessorCount : threadCount);
}
public void Log(IStatusMessage msg)
{
_messages.OnNext(msg);
}
public void Log(string msg)
{
_messages.OnNext(new GenericInfo(msg));
}
private void StartThreads(int threadCount)
{
ThreadCount = threadCount;

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Alphaleonis.Win32.Filesystem;
using Wabbajack.Common.StatusFeed;
namespace Wabbajack.Lib.CompilationSteps.CompilationErrors
{
public class InvalidGameESMError : AErrorMessage
{
private readonly string _hash;
private readonly string _path;
private readonly CleanedESM _esm;
private string _gameFileName => Path.GetFileName(_esm.To);
public override string ShortDescription
{
get =>
$"Game file {_gameFileName} has a hash of {_hash} which does not match the expected value of {_esm.SourceESMHash}";
}
public override string ExtendedDescription
{
get =>
$@"This modlist is setup to perform automatic cleaning of the stock game file {_gameFileName} in order to perform this cleaning Wabbajack must first verify that the
source file is in the correct state. It seems that the file in your game directory has a hash of {_hash} instead of the expect hash of {_esm.SourceESMHash}. This could be caused by
the modlist expecting a different of the game than you currently have installed, or perhaps you have already cleaned the file. You could attempt to fix this error by re-installing
the game, and then attempting to re-install this modlist. Also verify that the version of the game you have installed matches the version expected by this modlist.";
}
public InvalidGameESMError(CleanedESM esm, string hash, string path)
{
_hash = hash;
_path = path;
_esm = esm;
}
}
}

View File

@ -5,6 +5,7 @@ using Alphaleonis.Win32.Filesystem;
using Compression.BSA;
using Newtonsoft.Json;
using Wabbajack.Common;
using Wabbajack.Common.StatusFeed.Errors;
namespace Wabbajack.Lib.CompilationSteps
{
@ -72,7 +73,7 @@ namespace Wabbajack.Lib.CompilationSteps
foreach (var match in matches)
{
if (match is IgnoredDirectly)
Utils.Error($"File required for BSA {source.Path} creation doesn't exist: {match.To}");
Utils.Error(new UnconvertedError($"File required for BSA {source.Path} creation doesn't exist: {match.To}"));
_mo2Compiler.ExtraFiles.Add(match);
}
@ -100,4 +101,4 @@ namespace Wabbajack.Lib.CompilationSteps
}
}
}
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.Linq;
using Wabbajack.Common;
using Wabbajack.Common.StatusFeed.Errors;
using Wabbajack.Lib.NexusApi;
using Wabbajack.Lib.Validation;
@ -45,12 +46,12 @@ namespace Wabbajack.Lib.Downloaders
var status = client.GetUserStatus();
if (!client.IsAuthenticated)
{
Utils.Error($"Authenticating for the Nexus failed. A nexus account is required to automatically download mods.");
Utils.Error(new UnconvertedError($"Authenticating for the Nexus failed. A nexus account is required to automatically download mods."));
return;
}
if (status.is_premium) return;
Utils.Error($"Automated installs with Wabbajack requires a premium nexus account. {client.Username} is not a premium account.");
Utils.Error(new UnconvertedError($"Automated installs with Wabbajack requires a premium nexus account. {client.Username} is not a premium account."));
}
public class State : AbstractDownloadState

View File

@ -4,8 +4,10 @@ using System.Linq;
using System.Text;
using System.Windows;
using Wabbajack.Common;
using Wabbajack.Lib.CompilationSteps.CompilationErrors;
using Wabbajack.Lib.Downloaders;
using Wabbajack.Lib.NexusApi;
using Wabbajack.Lib.StatusMessages;
using Wabbajack.Lib.Validation;
using Directory = Alphaleonis.Win32.Filesystem.Directory;
using File = Alphaleonis.Win32.Filesystem.File;
@ -57,12 +59,7 @@ namespace Wabbajack.Lib
if (Directory.Exists(Path.Combine(OutputFolder, "mods")) && WarnOnOverwrite)
{
if (MessageBox.Show(
"There already appears to be a Mod Organizer 2 install in this folder, are you sure you wish to continue" +
" with installation? If you do, you may render both your existing install and the new modlist inoperable.",
"Existing MO2 installation in install folder",
MessageBoxButton.YesNo,
MessageBoxImage.Exclamation) == MessageBoxResult.No)
if (Utils.Log(new ConfirmUpdateOfExistingInstall { ModListName = ModList.Name, OutputFolder = OutputFolder}).Task.Result == ConfirmUpdateOfExistingInstall.Choice.Abort)
{
Utils.Log("Existing installation at the request of the user, existing mods folder found.");
return false;
@ -141,7 +138,7 @@ namespace Wabbajack.Lib
var hash = gameFile.FileHash();
if (hash != esm.SourceESMHash)
{
Utils.Error("Game ESM hash doesn't match, is the ESM already cleaned? Please verify your local game files.");
Utils.Error(new InvalidGameESMError(esm, hash, gameFile));
}
}
}

View File

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wabbajack.Common.StatusFeed;
namespace Wabbajack.Lib.StatusMessages
{
public class ConfirmUpdateOfExistingInstall : AStatusMessage, IUserIntervention
{
public enum Choice
{
Continue,
Abort
}
public string OutputFolder { get; set; }
public string ModListName { get; set; }
public override string ShortDescription { get; } = "Do you want to overwrite existing files?";
private TaskCompletionSource<Choice> _source = new TaskCompletionSource<Choice>();
public Task<Choice> Task => _source.Task;
public override string ExtendedDescription
{
get =>
$@"There appears to be a modlist already installed in the output folder. If you continue with the install,
Any files that exist in {OutputFolder} will be changed to match the files found in the {ModListName} modlist. This means that save games will be removed, custom settings
will be reverted. Are you sure you wish to continue?";
}
public void Cancel()
{
_source.SetResult(Choice.Abort);
}
public void Resume()
{
_source.SetResult(Choice.Continue);
}
}
}

View File

@ -77,11 +77,6 @@ namespace Wabbajack.Lib.Validation
/// <returns></returns>
public Permissions FilePermissions(NexusDownloader.State mod)
{
if (mod.Author == null || mod.GameName == null || mod.ModID == null || mod.FileID == null)
{
Utils.Error($"Error: Null data for {mod.Author} {mod.GameName} {mod.ModID} {mod.FileID}");
}
var author_permissions = AuthorPermissions.GetOrDefault(mod.Author)?.Permissions;
var game_permissions = AuthorPermissions.GetOrDefault(mod.Author)?.Games.GetOrDefault(mod.GameName)?.Permissions;
var mod_permissions = AuthorPermissions.GetOrDefault(mod.Author)?.Games.GetOrDefault(mod.GameName)?.Mods.GetOrDefault(mod.ModID)

View File

@ -82,6 +82,7 @@
<Compile Include="AInstaller.cs" />
<Compile Include="CerasConfig.cs" />
<Compile Include="CompilationSteps\ACompilationStep.cs" />
<Compile Include="CompilationSteps\CompilationErrors\InvalidGameESMError.cs" />
<Compile Include="CompilationSteps\DeconstructBSAs.cs" />
<Compile Include="CompilationSteps\DirectMatch.cs" />
<Compile Include="CompilationSteps\DropAll.cs" />
@ -133,6 +134,7 @@
<Compile Include="NexusApi\NexusApiUtils.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ReportBuilder.cs" />
<Compile Include="StatusMessages\ConfirmUpdateOfExistingInstall.cs" />
<Compile Include="UI\UIUtils.cs" />
<Compile Include="Validation\DTOs.cs" />
<Compile Include="Validation\ValidateModlist.cs" />
@ -216,5 +218,6 @@
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -60,7 +60,7 @@ namespace Wabbajack.Lib
merges.Where(m => m.Count() > 1)
.Do(m =>
{
Utils.Warning(
Utils.Log(
$"WARNING, you have two patches named {m.Key.name}\\{m.Key.filename} in your zEdit profiles. We'll pick one at random, this probably isn't what you want.");
});

View File

@ -17,7 +17,7 @@ namespace Wabbajack.Test.ListValidation
[ClassInitialize]
public static void SetupNexus(TestContext context)
{
Utils.LogMessages.Subscribe(context.WriteLine);
Utils.LogMessages.Subscribe(m => context.WriteLine(m.ToString()));
var api = new NexusApiClient();
api.ClearUpdatedModsInCache();
}
@ -27,7 +27,7 @@ namespace Wabbajack.Test.ListValidation
public void Setup()
{
Directory.CreateDirectory(Consts.ModListDownloadFolder);
Utils.LogMessages.Subscribe(s => TestContext.WriteLine(s));
Utils.LogMessages.Subscribe(s => TestContext.WriteLine(s.ToString()));
Queue = new WorkQueue();
}

View File

@ -18,7 +18,7 @@ namespace Wabbajack.Test
utils = new TestUtils();
utils.Game = Game.SkyrimSpecialEdition;
Utils.LogMessages.Subscribe(f => TestContext.WriteLine(f));
Utils.LogMessages.Subscribe(f => TestContext.WriteLine(f.ShortDescription));
}

View File

@ -22,7 +22,7 @@ namespace Wabbajack.Test
Game = Game.DarkestDungeon
};
Utils.LogMessages.Subscribe(f => TestContext.WriteLine(f));
Utils.LogMessages.Subscribe(f => TestContext.WriteLine(f.ShortDescription));
}
[TestCleanup]

View File

@ -30,7 +30,7 @@ namespace Wabbajack.Test
utils = new TestUtils();
utils.Game = Game.SkyrimSpecialEdition;
Utils.LogMessages.Subscribe(f => TestContext.WriteLine(f));
Utils.LogMessages.Subscribe(f => TestContext.WriteLine(f.ToString()));
if (!Directory.Exists(DOWNLOAD_FOLDER))
Directory.CreateDirectory(DOWNLOAD_FOLDER);

View File

@ -22,7 +22,7 @@ namespace Wabbajack.VirtualFileSystem.Test
[TestInitialize]
public void Setup()
{
Utils.LogMessages.Subscribe(f => TestContext.WriteLine(f));
Utils.LogMessages.Subscribe(f => TestContext.WriteLine(f.ShortDescription));
if (Directory.Exists(VFS_TEST_DIR))
Utils.DeleteDirectory(VFS_TEST_DIR);
Directory.CreateDirectory(VFS_TEST_DIR);

View File

@ -8,6 +8,7 @@ using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Windows.Media.Imaging;
using Wabbajack.Common;
using Wabbajack.Common.StatusFeed;
using Wabbajack.Lib;
namespace Wabbajack
@ -39,7 +40,7 @@ namespace Wabbajack
public ObservableCollectionExtended<CPUStatus> StatusList { get; } = new ObservableCollectionExtended<CPUStatus>();
public ObservableCollectionExtended<string> Log => MWVM.Log;
public ObservableCollectionExtended<IStatusMessage> Log => MWVM.Log;
public IReactiveCommand BackCommand { get; }

View File

@ -17,6 +17,7 @@ using ReactiveUI.Fody.Helpers;
using System.Windows.Media;
using DynamicData;
using DynamicData.Binding;
using Wabbajack.Common.StatusFeed;
namespace Wabbajack
{
@ -77,7 +78,7 @@ namespace Wabbajack
public float PercentCompleted => _percentCompleted.Value;
public ObservableCollectionExtended<CPUStatus> StatusList { get; } = new ObservableCollectionExtended<CPUStatus>();
public ObservableCollectionExtended<string> Log => MWVM.Log;
public ObservableCollectionExtended<IStatusMessage> Log => MWVM.Log;
private readonly ObservableAsPropertyHelper<ModlistInstallationSettings> _CurrentSettings;
public ModlistInstallationSettings CurrentSettings => _CurrentSettings.Value;

View File

@ -6,8 +6,11 @@ using System;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Windows;
using Wabbajack.Common;
using Wabbajack.Common.StatusFeed;
using Wabbajack.Lib;
using Wabbajack.Lib.StatusMessages;
namespace Wabbajack
{
@ -24,7 +27,7 @@ namespace Wabbajack
[Reactive]
public ViewModel ActivePane { get; set; }
public ObservableCollectionExtended<string> Log { get; } = new ObservableCollectionExtended<string>();
public ObservableCollectionExtended<IStatusMessage> Log { get; } = new ObservableCollectionExtended<IStatusMessage>();
public readonly Lazy<CompilerVM> Compiler;
public readonly Lazy<InstallerVM> Installer;
@ -52,6 +55,10 @@ namespace Wabbajack
.Subscribe()
.DisposeWith(CompositeDisposable);
Utils.LogMessages
.OfType<ConfirmUpdateOfExistingInstall>()
.Subscribe(msg => ConfirmUpdate(msg));
if (IsStartingFromModlist(out var path))
{
Installer.Value.ModListPath.TargetPath = path;
@ -64,6 +71,15 @@ namespace Wabbajack
}
}
private void ConfirmUpdate(ConfirmUpdateOfExistingInstall msg)
{
var result = MessageBox.Show(msg.ExtendedDescription, msg.ShortDescription, MessageBoxButton.OKCancel);
if (result == MessageBoxResult.OK)
msg.Resume();
else
msg.Cancel();
}
private static bool IsStartingFromModlist(out string modlistPath)
{
string[] args = Environment.GetCommandLineArgs();

View File

@ -29,7 +29,7 @@
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" TextWrapping="WrapWithOverflow" />
<TextBlock Text="{Binding ShortDescription}" TextWrapping="WrapWithOverflow" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>