From c0d50a8216daadf827a44920204b065448224f63 Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Wed, 3 Feb 2021 20:48:30 -0700 Subject: [PATCH] Version 2.4.2.0 --- CHANGELOG.md | 9 ++- Wabbajack.Benchmark/WorkQueueBenchmarks.cs | 53 +++++++++++++++++ Wabbajack.Common/Logging.cs | 5 ++ Wabbajack.Lib/ABatchProcessor.cs | 7 ++- .../Downloaders/AbstractIPS4Downloader.cs | 8 ++- .../Downloaders/LoversLabDownloader.cs | 2 +- Wabbajack.Lib/Http/ClientFactory.cs | 7 ++- Wabbajack.Lib/Metrics.cs | 8 +++ Wabbajack.Lib/NexusApi/NexusApi.cs | 15 ++++- .../ModListValidationTests.cs | 6 +- .../ApiKeyAuthorizationHandler.cs | 11 ++-- Wabbajack.Server/Controllers/AuthoredFiles.cs | 10 +++- Wabbajack.Server/DataLayer/ModLists.cs | 10 ++++ Wabbajack.Server/Services/DiscordFrontend.cs | 35 +++++++---- .../Services/ModListDownloader.cs | 59 ++++++++----------- Wabbajack.Server/Services/QuickSync.cs | 11 ++++ Wabbajack.Test/MetricsTests.cs | 24 ++++++++ Wabbajack.sln | 10 ++++ .../View Models/Compilers/MO2CompilerVM.cs | 3 +- .../View Models/UserInterventionHandlers.cs | 2 +- 20 files changed, 229 insertions(+), 66 deletions(-) create mode 100644 Wabbajack.Benchmark/WorkQueueBenchmarks.cs create mode 100644 Wabbajack.Test/MetricsTests.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c7c7e58..225b300a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ ### Changelog -#### Version - 2.4.1.2 - 1/29/2020 +#### Version - 2.4.2.0 - 2/3/2020 +* Rework the Nexus Manual Downloading process now with less jank +* Manual Nexus Downloading now explains why it's so painful, and how to fix it (get Premium) +* Manual Nexus Downloading no longer opens a ton of CEF processes +* Manual Nexus Downloading no longer prompts users to download files that don't exist +* Disabled CloudFlare DDOS mitigation for LoversLab downloading, the site is back to normal now + +#### Version - 2.4.1.2 - 1/30/2020 * Don't install .meta files for files sourced from the game folder * Fix bug MO2 archive name detection in .meta files (rare bug with FO4VR and other like games) * Catch exceptions when ECS downloads manifest data diff --git a/Wabbajack.Benchmark/WorkQueueBenchmarks.cs b/Wabbajack.Benchmark/WorkQueueBenchmarks.cs new file mode 100644 index 00000000..9136131c --- /dev/null +++ b/Wabbajack.Benchmark/WorkQueueBenchmarks.cs @@ -0,0 +1,53 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using BenchmarkDotNet.Attributes; +using Wabbajack.Common; + +namespace Wabbajack.Benchmark +{ + public class WorkQueueBenchmarks + { + private int[] _itms; + private WorkQueue _queue; + private TempFile _file; + private Random _rdm; + + [Params(2, 4, 8, 16, 32, 64, 128, 256)] + public int Threads { get; set; } + + [GlobalSetup] + public async Task Setup() + { + _rdm = new Random((int)DateTime.Now.ToFileTimeUtc()); + _itms = Enumerable.Range(0, Threads * 10).ToArray(); + _queue = new WorkQueue(Threads); + + _file = new TempFile(); + await using var f = await _file.Path.Create(); + var data = new byte[1024 * 1024 * 10]; // 1GB + + _rdm.NextBytes(data); + await f.WriteAsync(data); + } + + [GlobalCleanup] + public async Task Cleanup() + { + _queue.Dispose(); + await _file.DisposeAsync(); + } + + /* [Benchmark] + public async Task SleepTask() + { + await _itms.PMap(_queue, async f => await Task.Delay(1)); + }*/ + + [Benchmark] + public async Task FileHashTask() + { + await _itms.PMap(_queue, async f => await _file.Path.FileHashAsync()); + } + } +} diff --git a/Wabbajack.Common/Logging.cs b/Wabbajack.Common/Logging.cs index 383a0fe7..206b67fa 100644 --- a/Wabbajack.Common/Logging.cs +++ b/Wabbajack.Common/Logging.cs @@ -167,5 +167,10 @@ namespace Wabbajack.Common Utils.Error(ex); } } + + public static void ErrorMetric(Exception exception) + { + throw new NotImplementedException(); + } } } diff --git a/Wabbajack.Lib/ABatchProcessor.cs b/Wabbajack.Lib/ABatchProcessor.cs index a049316a..0131c827 100644 --- a/Wabbajack.Lib/ABatchProcessor.cs +++ b/Wabbajack.Lib/ABatchProcessor.cs @@ -168,13 +168,18 @@ namespace Wabbajack.Lib Utils.Log("Starting Installer Task"); return Task.Run(async () => - { + { try { Utils.Log("Installation has Started"); _isRunning.OnNext(true); return await _Begin(_cancel.Token); } + catch (Exception ex) + { + var _ = Metrics.Error(this.GetType(), ex); + throw; + } finally { Utils.Log("Vacuuming databases"); diff --git a/Wabbajack.Lib/Downloaders/AbstractIPS4Downloader.cs b/Wabbajack.Lib/Downloaders/AbstractIPS4Downloader.cs index f46e5a5d..ba83827c 100644 --- a/Wabbajack.Lib/Downloaders/AbstractIPS4Downloader.cs +++ b/Wabbajack.Lib/Downloaders/AbstractIPS4Downloader.cs @@ -32,7 +32,7 @@ namespace Wabbajack.Lib.Downloaders { private DateTime LastRequestTime = default; - protected long RequestsPerMinute = 20; + protected long RequestsPerMinute = 60; private TimeSpan RequestDelay => TimeSpan.FromMinutes(1) / RequestsPerMinute; protected AbstractIPS4Downloader(Uri loginUri, string encryptedKeyName, string cookieDomain, string loginCookie = "ips4_member_id") @@ -182,7 +182,8 @@ namespace Wabbajack.Lib.Downloaders public override async Task Download(Archive a, AbsolutePath destination) { - await ((IWaitForWindowDownloader)Downloader).WaitForNextRequestWindow(); + if (Downloader.IsCloudFlareProtected) + await ((IWaitForWindowDownloader)Downloader).WaitForNextRequestWindow(); return await ResolveDownloadStream(a, destination, false); } @@ -312,7 +313,8 @@ namespace Wabbajack.Lib.Downloaders public override async Task Verify(Archive a, CancellationToken? token) { - await ((IWaitForWindowDownloader)Downloader).WaitForNextRequestWindow(); + if (Downloader.IsCloudFlareProtected) + await ((IWaitForWindowDownloader)Downloader).WaitForNextRequestWindow(); await using var tp = new TempFile(); var isValid = await ResolveDownloadStream(a, tp.Path, true, token: token); return isValid; diff --git a/Wabbajack.Lib/Downloaders/LoversLabDownloader.cs b/Wabbajack.Lib/Downloaders/LoversLabDownloader.cs index 251f7689..771fc650 100644 --- a/Wabbajack.Lib/Downloaders/LoversLabDownloader.cs +++ b/Wabbajack.Lib/Downloaders/LoversLabDownloader.cs @@ -21,7 +21,7 @@ namespace Wabbajack.Lib.Downloaders public LoversLabDownloader() : base(new Uri("https://www.loverslab.com/login"), "loverslabcookies", "loverslab.com") { - IsCloudFlareProtected = true; + IsCloudFlareProtected = false; } protected override async Task WhileWaiting(IWebDriver browser) { diff --git a/Wabbajack.Lib/Http/ClientFactory.cs b/Wabbajack.Lib/Http/ClientFactory.cs index 0ec211bb..71fb5aea 100644 --- a/Wabbajack.Lib/Http/ClientFactory.cs +++ b/Wabbajack.Lib/Http/ClientFactory.cs @@ -1,5 +1,8 @@ using System; using System.Net; +using System.Net.Security; +using System.Security.Authentication; +using Wabbajack.Common; using SysHttp = System.Net.Http; namespace Wabbajack.Lib.Http @@ -18,8 +21,10 @@ namespace Wabbajack.Lib.Http CookieContainer = Cookies, MaxConnectionsPerServer = 20, PooledConnectionLifetime = TimeSpan.FromMilliseconds(100), - PooledConnectionIdleTimeout = TimeSpan.FromMilliseconds(100) + PooledConnectionIdleTimeout = TimeSpan.FromMilliseconds(100), + }; + Utils.Log($"Configuring with SSL {_socketsHandler.SslOptions.EnabledSslProtocols}"); Client = new SysHttp.HttpClient(_socketsHandler); } } diff --git a/Wabbajack.Lib/Metrics.cs b/Wabbajack.Lib/Metrics.cs index a51ed1f3..3faafc59 100644 --- a/Wabbajack.Lib/Metrics.cs +++ b/Wabbajack.Lib/Metrics.cs @@ -1,5 +1,7 @@ using System; +using System.Text.Encodings.Web; using System.Threading.Tasks; +using System.Web; using Microsoft.Win32; using Wabbajack.Common; @@ -78,5 +80,11 @@ namespace Wabbajack.Lib client.Headers.Add((Consts.MetricsKeyHeader, key)); await client.GetAsync($"{Consts.WabbajackBuildServerUri}metrics/{action}/{value}"); } + + public static async Task Error(Type type, Exception exception) + { + await Send("Exception", type.Name + "|" + exception.Message); + await Send("ExceptionData" + type.Name + "|" + Consts.CurrentMinimumWabbajackVersion, HttpUtility.UrlEncode($"{exception.Message}\n{exception.StackTrace}")); + } } } diff --git a/Wabbajack.Lib/NexusApi/NexusApi.cs b/Wabbajack.Lib/NexusApi/NexusApi.cs index 5f3986b8..98701f35 100644 --- a/Wabbajack.Lib/NexusApi/NexusApi.cs +++ b/Wabbajack.Lib/NexusApi/NexusApi.cs @@ -19,6 +19,10 @@ namespace Wabbajack.Lib.NexusApi public class NexusApiClient : ViewModel, INexusApi { private static readonly string API_KEY_CACHE_FILE = "nexus.key_cache"; + /// + /// Forces the client to do manual downloading via CEF (for testing) + /// + private static bool ManualTestingMode = true; public Http.Client HttpClient { get; } = new(); @@ -301,15 +305,18 @@ namespace Wabbajack.Lib.NexusApi return await Get(builder.ToString(), HttpClient.WithHeader((Consts.MetricsKeyHeader, await Metrics.GetMetricsKey()))); } + + private static AsyncLock ManualDownloadLock = new(); public async Task GetNexusDownloadLink(NexusDownloader.State archive) { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; var info = await GetModInfo(archive.Game, archive.ModID); - if (!info.available) + var fileInfo = await GetModFiles(archive.Game, archive.ModID); + if (!info.available || !fileInfo.files.Any(f => f.file_id == archive.FileID && f.category_name != null)) throw new Exception("Mod unavailable"); - - if (await IsPremium()) + + if (await IsPremium() && !ManualTestingMode) { if (HourlyRemaining <= 0 && DailyRemaining <= 0) { @@ -323,6 +330,8 @@ namespace Wabbajack.Lib.NexusApi try { + using var _ = await ManualDownloadLock.WaitAsync(); + await Task.Delay(1000); Utils.Log($"Requesting manual download for {archive.Name} {archive.PrimaryKeyString}"); return (await Utils.Log(await ManuallyDownloadNexusFile.Create(archive)).Task).ToString(); } diff --git a/Wabbajack.Server.Test/ModListValidationTests.cs b/Wabbajack.Server.Test/ModListValidationTests.cs index f2759bcc..1234856a 100644 --- a/Wabbajack.Server.Test/ModListValidationTests.cs +++ b/Wabbajack.Server.Test/ModListValidationTests.cs @@ -40,7 +40,7 @@ namespace Wabbajack.BuildServer.Test Consts.ModlistMetadataURL = modlist.ToString(); var sql = Fixture.GetService(); var downloader = Fixture.GetService(); - await downloader.CheckForNewLists(); + await downloader.Execute(); foreach (var list in ModListMetaData) { @@ -48,7 +48,7 @@ namespace Wabbajack.BuildServer.Test } // Nothing has changed so we shouldn't be downloading anything this time - Assert.Equal(0, await downloader.CheckForNewLists()); + Assert.Equal(0, await downloader.Execute()); } @@ -161,7 +161,7 @@ namespace Wabbajack.BuildServer.Test { var downloader = Fixture.GetService(); - await downloader.CheckForNewLists(); + await downloader.Execute(); if (runNonNexus) { diff --git a/Wabbajack.Server/ApiKeyAuthorizationHandler.cs b/Wabbajack.Server/ApiKeyAuthorizationHandler.cs index 1ab4932a..e55700a5 100644 --- a/Wabbajack.Server/ApiKeyAuthorizationHandler.cs +++ b/Wabbajack.Server/ApiKeyAuthorizationHandler.cs @@ -29,6 +29,7 @@ namespace Wabbajack.BuildServer { private const string ProblemDetailsContentType = "application/problem+json"; private readonly SqlService _sql; + private static ConcurrentHashSet _knownKeys = new(); private const string ApiKeyHeaderName = "X-Api-Key"; public ApiKeyAuthenticationHandler( @@ -44,7 +45,8 @@ namespace Wabbajack.BuildServer protected override async Task HandleAuthenticateAsync() { var metricsKey = Request.Headers[Consts.MetricsKeyHeader].FirstOrDefault(); - await LogRequest(metricsKey); + // Never needed this, disabled for now + //await LogRequest(metricsKey); if (metricsKey != default) { if (await _sql.IsTarKey(metricsKey)) @@ -82,15 +84,16 @@ namespace Wabbajack.BuildServer return AuthenticateResult.Success(ticket); } - if (!await _sql.ValidMetricsKey(metricsKey)) + if (!_knownKeys.Contains(metricsKey) && !await _sql.ValidMetricsKey(metricsKey)) { return AuthenticateResult.Fail("Invalid Metrics Key"); } else { - var claims = new List(); + _knownKeys.Add(metricsKey); + + var claims = new List {new(ClaimTypes.Role, "User")}; - claims.Add(new Claim(ClaimTypes.Role, "User")); var identity = new ClaimsIdentity(claims, Options.AuthenticationType); var identities = new List {identity}; diff --git a/Wabbajack.Server/Controllers/AuthoredFiles.cs b/Wabbajack.Server/Controllers/AuthoredFiles.cs index 0f99e791..e6783c1e 100644 --- a/Wabbajack.Server/Controllers/AuthoredFiles.cs +++ b/Wabbajack.Server/Controllers/AuthoredFiles.cs @@ -27,14 +27,16 @@ namespace Wabbajack.BuildServer.Controllers private ILogger _logger; private AppSettings _settings; private CDNMirrorList _mirrorList; + private DiscordWebHook _discord; - public AuthoredFiles(ILogger logger, SqlService sql, AppSettings settings, CDNMirrorList mirrorList) + public AuthoredFiles(ILogger logger, SqlService sql, AppSettings settings, CDNMirrorList mirrorList, DiscordWebHook discord) { _sql = sql; _logger = logger; _settings = settings; _mirrorList = mirrorList; + _discord = discord; } [HttpPut] @@ -77,6 +79,9 @@ namespace Wabbajack.BuildServer.Controllers _logger.Log(LogLevel.Information, $"Creating File upload {definition.OriginalFileName}"); definition = await _sql.CreateAuthoredFile(definition, user); + + await _discord.Send(Channel.Ham, + new DiscordMessage() {Content = $"{user} has started uploading {definition.OriginalFileName} ({definition.Size.ToFileSizeString()})"}); return Ok(definition.ServerAssignedUniqueId); } @@ -101,6 +106,9 @@ namespace Wabbajack.BuildServer.Controllers ms.Position = 0; await UploadAsync(ms, $"{definition.MungedName}/definition.json.gz"); + await _discord.Send(Channel.Ham, + new DiscordMessage {Content = $"{user} has finished uploading {definition.OriginalFileName} ({definition.Size.ToFileSizeString()})"}); + return Ok($"https://{_settings.BunnyCDN_StorageZone}.b-cdn.net/{definition.MungedName}"); } diff --git a/Wabbajack.Server/DataLayer/ModLists.cs b/Wabbajack.Server/DataLayer/ModLists.cs index 43f23acd..23215f93 100644 --- a/Wabbajack.Server/DataLayer/ModLists.cs +++ b/Wabbajack.Server/DataLayer/ModLists.cs @@ -100,5 +100,15 @@ namespace Wabbajack.Server.DataLayer Hash = t.Item2 }).ToList(); } + + public async Task PurgeList(string machineURL) + { + await using var conn = await Open(); + var ret1 = await conn.ExecuteAsync(@" delete from dbo.ModListArchives where MachineURL = @machineURL", + new {machineURL}); + var ret2 = await conn.ExecuteAsync(@" delete from dbo.ModLists where MachineURL = @machineURL", + new {machineURL}); + return ret1 + ret2; + } } } diff --git a/Wabbajack.Server/Services/DiscordFrontend.cs b/Wabbajack.Server/Services/DiscordFrontend.cs index d324debb..6f81afa8 100644 --- a/Wabbajack.Server/Services/DiscordFrontend.cs +++ b/Wabbajack.Server/Services/DiscordFrontend.cs @@ -58,23 +58,34 @@ namespace Wabbajack.Server.Services } await PurgeNexusCache(arg, parts[2]); } - else if (parts[1] == "cyberpunk") + else if (parts[1] == "quick-sync") { - var random = new Random(); - var releaseDate = new DateTime(2020, 12, 10, 0, 0, 0, DateTimeKind.Utc); - var r = releaseDate - DateTime.UtcNow; - if (r < TimeSpan.Zero) + var options = await _quickSync.Report(); + if (parts.Length != 3) { - await ReplyTo(arg, "It's out, what are you doing here?"); + var optionsStr = string.Join(", ", options.Select(o => o.Key.Name)); + await ReplyTo(arg, $"Can't expect me to quicksync the whole damn world! Try: {optionsStr}"); } else { - var msgs = (await "cyberpunk_message.txt".RelativeTo(AbsolutePath.EntryPoint) - .ReadAllLinesAsync()).ToArray(); - var msg = msgs[random.Next(0, msgs.Length)]; - var fullmsg = String.Format(msg, - $"{r.Days} days, {r.Hours} hours, {r.Minutes} minutes, {r.Seconds} seconds"); - await ReplyTo(arg, fullmsg); + foreach (var pair in options.Where(o => o.Key.Name == parts[2])) + { + await _quickSync.Notify(pair.Key); + await ReplyTo(arg, $"Notified {pair.Key}"); + } + } + } + else if (parts[1] == "purge-list") + { + if (parts.Length != 3) + { + await ReplyTo(arg, $"Yeah, I'm not gonna purge the whole server..."); + } + else + { + var deleted = await _sql.PurgeList(parts[2]); + await _quickSync.Notify(); + await ReplyTo(arg, $"Purged all traces of #{parts[2]} from the server, triggered list downloading. {deleted} records removed"); } } } diff --git a/Wabbajack.Server/Services/ModListDownloader.cs b/Wabbajack.Server/Services/ModListDownloader.cs index a3815bba..eb253d32 100644 --- a/Wabbajack.Server/Services/ModListDownloader.cs +++ b/Wabbajack.Server/Services/ModListDownloader.cs @@ -16,15 +16,14 @@ using Wabbajack.Server.DTOs; namespace Wabbajack.Server.Services { - public class ModListDownloader + public class ModListDownloader : AbstractService { - private ILogger _logger; - private AppSettings _settings; private ArchiveMaintainer _maintainer; private SqlService _sql; private DiscordWebHook _discord; - public ModListDownloader(ILogger logger, AppSettings settings, ArchiveMaintainer maintainer, SqlService sql, DiscordWebHook discord) + public ModListDownloader(ILogger logger, AppSettings settings, ArchiveMaintainer maintainer, SqlService sql, DiscordWebHook discord, QuickSync quickSync) + : base(logger, settings, quickSync, TimeSpan.FromMinutes(1)) { _logger = logger; _settings = settings; @@ -33,32 +32,8 @@ namespace Wabbajack.Server.Services _discord = discord; } - public void Start() - { - if (_settings.RunBackEndJobs) - { - Task.Run(async () => - { - while (true) - { - try - { - _logger.Log(LogLevel.Information, "Checking for updated mod lists"); - await CheckForNewLists(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error checking list"); - } - await Task.Delay(TimeSpan.FromMinutes(5)); - - } - }); - } - } - - public async Task CheckForNewLists() + public override async Task Execute() { int downloaded = 0; var lists = (await ModlistMetadata.LoadFromGithub()) @@ -68,6 +43,7 @@ namespace Wabbajack.Server.Services { try { + ReportStarting(list.Links.MachineURL); if (await _sql.HaveIndexedModlist(list.Links.MachineURL, list.DownloadMetadata.Hash)) continue; @@ -76,7 +52,10 @@ namespace Wabbajack.Server.Services { _logger.Log(LogLevel.Information, $"Downloading {list.Links.MachineURL}"); await _discord.Send(Channel.Ham, - new DiscordMessage {Content = $"Downloading {list.Links.MachineURL} - {list.DownloadMetadata.Hash}"}); + new DiscordMessage + { + Content = $"Downloading {list.Links.MachineURL} - {list.DownloadMetadata.Hash}" + }); var tf = new TempFile(); var state = DownloadDispatcher.ResolveArchive(list.Links.Download); if (state == null) @@ -110,7 +89,10 @@ namespace Wabbajack.Server.Services { _logger.LogWarning($"Bad Modlist {list.Links.MachineURL}"); await _discord.Send(Channel.Ham, - new DiscordMessage {Content = $"Bad Modlist {list.Links.MachineURL} - {list.DownloadMetadata.Hash}"}); + new DiscordMessage + { + Content = $"Bad Modlist {list.Links.MachineURL} - {list.DownloadMetadata.Hash}" + }); continue; } @@ -122,7 +104,10 @@ namespace Wabbajack.Server.Services { _logger.LogWarning($"Bad Modlist {list.Links.MachineURL}"); await _discord.Send(Channel.Ham, - new DiscordMessage {Content = $"Bad Modlist {list.Links.MachineURL} - {list.DownloadMetadata.Hash}"}); + new DiscordMessage + { + Content = $"Bad Modlist {list.Links.MachineURL} - {list.DownloadMetadata.Hash}" + }); continue; } } @@ -133,7 +118,15 @@ namespace Wabbajack.Server.Services { _logger.LogError(ex, $"Error downloading modlist {list.Links.MachineURL}"); await _discord.Send(Channel.Ham, - new DiscordMessage {Content = $"Error downloading modlist {list.Links.MachineURL} - {list.DownloadMetadata.Hash}"}); + new DiscordMessage + { + Content = + $"Error downloading modlist {list.Links.MachineURL} - {list.DownloadMetadata.Hash}" + }); + } + finally + { + ReportEnding(list.Links.MachineURL); } } _logger.Log(LogLevel.Information, $"Done checking modlists. Downloaded {downloaded} new lists"); diff --git a/Wabbajack.Server/Services/QuickSync.cs b/Wabbajack.Server/Services/QuickSync.cs index 954f1058..e6de56ea 100644 --- a/Wabbajack.Server/Services/QuickSync.cs +++ b/Wabbajack.Server/Services/QuickSync.cs @@ -67,5 +67,16 @@ namespace Wabbajack.Server.Services ct.Cancel(); } } + + public async Task Notify(Type t) + { + _logger.LogInformation($"Quicksync {t.Name}"); + // Needs debugging + using var _ = await _lock.WaitAsync(); + if (_syncs.TryGetValue(t, out var ct)) + { + ct.Cancel(); + } + } } } diff --git a/Wabbajack.Test/MetricsTests.cs b/Wabbajack.Test/MetricsTests.cs new file mode 100644 index 00000000..8d8b0a68 --- /dev/null +++ b/Wabbajack.Test/MetricsTests.cs @@ -0,0 +1,24 @@ +using System; +using System.Threading.Tasks; +using Wabbajack.Lib; +using Xunit; + +namespace Wabbajack.Test +{ + public class MetricsTests + { + [Fact] + public async Task CanSendExceptions() + { + try + { + throw new Exception("Test Exception"); + } + catch (Exception ex) + { + await Metrics.Error(this.GetType(), ex); + } + } + + } +} diff --git a/Wabbajack.sln b/Wabbajack.sln index bcd18b18..f8bfa0aa 100644 --- a/Wabbajack.sln +++ b/Wabbajack.sln @@ -44,6 +44,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wabbajack.Server", "Wabbaja EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wabbajack.Server.Test", "Wabbajack.Server.Test\Wabbajack.Server.Test.csproj", "{9DEC8DC8-B6E0-469B-9571-C4BAC0776D07}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wabbajack.Benchmark", "Wabbajack.Benchmark\Wabbajack.Benchmark.csproj", "{DDB89C1F-FFA8-4CC2-B202-2DF13FCBC6C7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -165,6 +167,14 @@ Global {9DEC8DC8-B6E0-469B-9571-C4BAC0776D07}.Release|Any CPU.Build.0 = Release|Any CPU {9DEC8DC8-B6E0-469B-9571-C4BAC0776D07}.Release|x64.ActiveCfg = Release|Any CPU {9DEC8DC8-B6E0-469B-9571-C4BAC0776D07}.Release|x64.Build.0 = Release|Any CPU + {DDB89C1F-FFA8-4CC2-B202-2DF13FCBC6C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DDB89C1F-FFA8-4CC2-B202-2DF13FCBC6C7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DDB89C1F-FFA8-4CC2-B202-2DF13FCBC6C7}.Debug|x64.ActiveCfg = Debug|Any CPU + {DDB89C1F-FFA8-4CC2-B202-2DF13FCBC6C7}.Debug|x64.Build.0 = Debug|Any CPU + {DDB89C1F-FFA8-4CC2-B202-2DF13FCBC6C7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DDB89C1F-FFA8-4CC2-B202-2DF13FCBC6C7}.Release|Any CPU.Build.0 = Release|Any CPU + {DDB89C1F-FFA8-4CC2-B202-2DF13FCBC6C7}.Release|x64.ActiveCfg = Release|Any CPU + {DDB89C1F-FFA8-4CC2-B202-2DF13FCBC6C7}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Wabbajack/View Models/Compilers/MO2CompilerVM.cs b/Wabbajack/View Models/Compilers/MO2CompilerVM.cs index b8255f75..19279473 100644 --- a/Wabbajack/View Models/Compilers/MO2CompilerVM.cs +++ b/Wabbajack/View Models/Compilers/MO2CompilerVM.cs @@ -230,8 +230,7 @@ namespace Wabbajack ModlistIsNSFW = ModlistSettings.IsNSFW }; } - using (ActiveCompilation = compiler -) + using (ActiveCompilation = compiler) { Parent.MWVM.Settings.Performance.SetProcessorSettings(ActiveCompilation); var success = await ActiveCompilation.Begin(); diff --git a/Wabbajack/View Models/UserInterventionHandlers.cs b/Wabbajack/View Models/UserInterventionHandlers.cs index c06113fd..64ab01fd 100644 --- a/Wabbajack/View Models/UserInterventionHandlers.cs +++ b/Wabbajack/View Models/UserInterventionHandlers.cs @@ -139,7 +139,7 @@ namespace Wabbajack }; await vm.Driver.WaitForInitialized(); IWebDriver browser = new CefSharpWrapper(vm.Browser); - vm.Instructions = $"Please Download {state.Name} - {state.ModID} - {state.FileID}"; + vm.Instructions = $"Click the highlighted file (get a NexusMods.com Premium account to automate this)"; browser.DownloadHandler = uri => { manuallyDownloadNexusFile.Resume(uri);