From b048a240f815cf8139f1f29cc8d8e07801f049a6 Mon Sep 17 00:00:00 2001 From: Timothy Baldridge <tbaldridge@gmail.com> Date: Tue, 28 Apr 2020 16:46:50 -0600 Subject: [PATCH 1/3] Fixes the popups from MediaFire --- Wabbajack.Lib/WebAutomation/CefSharpWrapper.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Wabbajack.Lib/WebAutomation/CefSharpWrapper.cs b/Wabbajack.Lib/WebAutomation/CefSharpWrapper.cs index 48e73d50..d2b39217 100644 --- a/Wabbajack.Lib/WebAutomation/CefSharpWrapper.cs +++ b/Wabbajack.Lib/WebAutomation/CefSharpWrapper.cs @@ -18,6 +18,9 @@ namespace Wabbajack.Lib.WebAutomation public CefSharpWrapper(IWebBrowser browser) { _browser = browser; + + _browser.DownloadHandler = new DownloadHandler(this); + _browser.LifeSpanHandler = new PopupBlocker(this); } public Task NavigateTo(Uri uri) @@ -33,11 +36,9 @@ namespace Wabbajack.Lib.WebAutomation tcs.SetResult(true); } }; - _browser.LoadingStateChanged += handler; _browser.Load(uri.ToString()); - _browser.DownloadHandler = new DownloadHandler(this); - _browser.LifeSpanHandler = new PopupBlocker(this); + return tcs.Task; } @@ -80,7 +81,7 @@ namespace Wabbajack.Lib.WebAutomation IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser? newBrowser) { // Block popups - newBrowser = null; + newBrowser = chromiumWebBrowser; return true; } @@ -90,7 +91,7 @@ namespace Wabbajack.Lib.WebAutomation public bool DoClose(IWebBrowser chromiumWebBrowser, IBrowser browser) { - return true; + return false; } public void OnBeforeClose(IWebBrowser chromiumWebBrowser, IBrowser browser) From 3b34af90deea0be9b0c6ea1d35b1a0d3e2bb952e Mon Sep 17 00:00:00 2001 From: Justin Swanson <justin.c.swanson@gmail.com> Date: Tue, 28 Apr 2020 17:52:20 -0500 Subject: [PATCH 2/3] Standardized the "warmup" functionality into one place --- .../StoreHandlers/StoreHandler.cs | 8 ++- Wabbajack.Common/Util/TempFolder.cs | 5 +- Wabbajack/App.xaml.cs | 10 ---- Wabbajack/Views/MainWindow.xaml.cs | 54 ++++++++++++------- 4 files changed, 47 insertions(+), 30 deletions(-) diff --git a/Wabbajack.Common/StoreHandlers/StoreHandler.cs b/Wabbajack.Common/StoreHandlers/StoreHandler.cs index dd1220c5..295c2225 100644 --- a/Wabbajack.Common/StoreHandlers/StoreHandler.cs +++ b/Wabbajack.Common/StoreHandlers/StoreHandler.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace Wabbajack.Common.StoreHandlers { @@ -13,7 +14,7 @@ namespace Wabbajack.Common.StoreHandlers public class StoreHandler { - private static readonly Lazy<StoreHandler> _instance = new Lazy<StoreHandler>(() => new StoreHandler(), true); + private static readonly Lazy<StoreHandler> _instance = new Lazy<StoreHandler>(() => new StoreHandler(), isThreadSafe: true); public static StoreHandler Instance => _instance.Value; private static readonly Lazy<SteamHandler> _steamHandler = new Lazy<SteamHandler>(() => new SteamHandler()); @@ -72,6 +73,11 @@ namespace Wabbajack.Common.StoreHandlers { return StoreGames.FirstOrDefault(g => g.Game == game)?.Path; } + + public static void Warmup() + { + Task.Run(() => _instance.Value).FireAndForget(); + } } public abstract class AStoreGame diff --git a/Wabbajack.Common/Util/TempFolder.cs b/Wabbajack.Common/Util/TempFolder.cs index 9ce128d3..70862216 100644 --- a/Wabbajack.Common/Util/TempFolder.cs +++ b/Wabbajack.Common/Util/TempFolder.cs @@ -18,7 +18,10 @@ namespace Wabbajack.Common _cleanTask = Task.Run(() => "tmp_files".RelativeTo(AbsolutePath.EntryPoint).DeleteDirectory()); } - public static void Init() + /// <summary> + /// Starts the initialization in a background task + /// </summary> + public static void Warmup() { // Nothing to do, as work is done in static ctor } diff --git a/Wabbajack/App.xaml.cs b/Wabbajack/App.xaml.cs index b2986871..7d8a7492 100644 --- a/Wabbajack/App.xaml.cs +++ b/Wabbajack/App.xaml.cs @@ -1,15 +1,6 @@ using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using System.Linq; -using System.Threading.Tasks; using System.Windows; -using System.Windows.Interop; -using System.Windows.Media; using Wabbajack.Common; -using Wabbajack.Common.StoreHandlers; -using Wabbajack.Util; namespace Wabbajack { @@ -23,7 +14,6 @@ namespace Wabbajack CLIOld.ParseOptions(Environment.GetCommandLineArgs()); if (CLIArguments.Help) CLIOld.DisplayHelpText(); - var storeHandler = new StoreHandler(); } } } diff --git a/Wabbajack/Views/MainWindow.xaml.cs b/Wabbajack/Views/MainWindow.xaml.cs index c6572535..8c48ffec 100644 --- a/Wabbajack/Views/MainWindow.xaml.cs +++ b/Wabbajack/Views/MainWindow.xaml.cs @@ -6,6 +6,7 @@ using System.Windows; using MahApps.Metro.Controls; using Newtonsoft.Json; using Wabbajack.Common; +using Wabbajack.Common.StoreHandlers; using Wabbajack.Lib.LibCefHelpers; using Wabbajack.Util; using Application = System.Windows.Application; @@ -23,8 +24,6 @@ namespace Wabbajack public MainWindow() { - TempFolder.Init(); - Helpers.Init(); // Wire any unhandled crashing exceptions to log before exiting AppDomain.CurrentDomain.UnhandledException += (sender, e) => { @@ -44,22 +43,7 @@ namespace Wabbajack Utils.Log( $"System settings - ({p.SystemMemorySize.ToFileSizeString()} RAM), Display: {p.ScreenWidth} x {p.ScreenHeight} ({p.VideoMemorySize.ToFileSizeString()} VRAM - VideoMemorySizeMb={p.EnbLEVRAMSize})"); - // Run logic to associate wabbajack lists with this app in the background - Task.Run(async () => - { - var appPath = System.Reflection.Assembly.GetExecutingAssembly().Location; - try - { - if (!ModListAssociationManager.IsAssociated() || ModListAssociationManager.NeedsUpdating(appPath)) - { - ModListAssociationManager.Associate(appPath); - } - } - catch (Exception e) - { - Utils.Log($"ExtensionManager had an exception:\n{e}"); - } - }).FireAndForget(); + Warmup(); // Load settings if (CLIArguments.NoSettings || !MainSettings.TryLoadTypicalSettings(out var settings)) @@ -100,6 +84,40 @@ namespace Wabbajack _settings = settings; } + /// <summary> + /// Starts some background initialization tasks spinning so they're already prepped when actually needed + /// </summary> + private void Warmup() + { + TempFolder.Warmup(); + // ToDo + // Currently this is a blocking call. Perhaps upgrade to be run in a background task. + // Would first need to ensure users of CEF properly await the background initialization before use + Helpers.Init(); + StoreHandler.Warmup(); + + Task.Run(AssociateListsWithWabbajack).FireAndForget(); + } + + /// <summary> + /// Run logic to associate wabbajack lists with this app in the background + /// </summary> + private void AssociateListsWithWabbajack() + { + var appPath = System.Reflection.Assembly.GetExecutingAssembly().Location; + try + { + if (!ModListAssociationManager.IsAssociated() || ModListAssociationManager.NeedsUpdating(appPath)) + { + ModListAssociationManager.Associate(appPath); + } + } + catch (Exception e) + { + Utils.Log($"ExtensionManager had an exception:\n{e}"); + } + } + private void RunWhenLoaded(Action a) { if (IsLoaded) From 64540e2cab6de1fafc5abca3cc506d6b14d7c94b Mon Sep 17 00:00:00 2001 From: Timothy Baldridge <tbaldridge@gmail.com> Date: Wed, 29 Apr 2020 06:26:44 -0600 Subject: [PATCH 3/3] Bunch of small server-side fixes, LZ4 compression speed, and better list validation --- Compression.BSA/BSABuilder.cs | 2 +- Wabbajack.App.Test/Wabbajack.App.Test.csproj | 2 +- .../Wabbajack.BuildServer.Test.csproj | 2 +- .../ValidateNonNexusArchives.cs | 15 +- .../Controllers/Heartbeat.cs | 5 +- .../Controllers/ListValidation.cs | 178 ++++++++++++------ .../Controllers/ModlistUpdater.cs | 5 +- .../Wabbajack.BuildServer.csproj | 4 +- Wabbajack.Common/Wabbajack.Common.csproj | 2 +- Wabbajack.Lib/Downloaders/MEGADownloader.cs | 13 +- Wabbajack.Lib/Wabbajack.Lib.csproj | 6 +- Wabbajack.Test/Wabbajack.Test.csproj | 2 +- Wabbajack/Wabbajack.csproj | 8 +- 13 files changed, 165 insertions(+), 79 deletions(-) diff --git a/Compression.BSA/BSABuilder.cs b/Compression.BSA/BSABuilder.cs index 04246c72..dcaa2b49 100644 --- a/Compression.BSA/BSABuilder.cs +++ b/Compression.BSA/BSABuilder.cs @@ -280,7 +280,7 @@ namespace Compression.BSA case VersionType.SSE: { var r = new MemoryStream(); - await using (var w = LZ4Stream.Encode(r, new LZ4EncoderSettings {CompressionLevel = LZ4Level.L12_MAX}, true)) + await using (var w = LZ4Stream.Encode(r, new LZ4EncoderSettings {CompressionLevel = LZ4Level.L08_HC}, true)) { await _srcData.CopyToWithStatusAsync(_srcData.Length, w, $"Compressing {_path}"); } diff --git a/Wabbajack.App.Test/Wabbajack.App.Test.csproj b/Wabbajack.App.Test/Wabbajack.App.Test.csproj index fe0caef1..c3720f5f 100644 --- a/Wabbajack.App.Test/Wabbajack.App.Test.csproj +++ b/Wabbajack.App.Test/Wabbajack.App.Test.csproj @@ -7,7 +7,7 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.0" /> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" /> <PackageReference Include="xunit" Version="2.4.1" /> <PackageReference Include="xunit.runner.console" Version="2.4.1" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" /> diff --git a/Wabbajack.BuildServer.Test/Wabbajack.BuildServer.Test.csproj b/Wabbajack.BuildServer.Test/Wabbajack.BuildServer.Test.csproj index fe3d65bd..af882a93 100644 --- a/Wabbajack.BuildServer.Test/Wabbajack.BuildServer.Test.csproj +++ b/Wabbajack.BuildServer.Test/Wabbajack.BuildServer.Test.csproj @@ -7,7 +7,7 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.0" /> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" /> <PackageReference Include="xunit" Version="2.4.1" /> <PackageReference Include="Xunit.Priority" Version="1.1.6" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" /> diff --git a/Wabbajack.BuildServer/BackendServices/ValidateNonNexusArchives.cs b/Wabbajack.BuildServer/BackendServices/ValidateNonNexusArchives.cs index 4d79c299..c144a9e0 100644 --- a/Wabbajack.BuildServer/BackendServices/ValidateNonNexusArchives.cs +++ b/Wabbajack.BuildServer/BackendServices/ValidateNonNexusArchives.cs @@ -1,6 +1,8 @@ using System; using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; +using Wabbajack.BuildServer.Controllers; using Wabbajack.BuildServer.Model.Models; using Wabbajack.Common; using Wabbajack.Lib.Downloaders; @@ -24,7 +26,18 @@ namespace Wabbajack.BuildServer.BackendServices { try { - var isValid = await archive.State.Verify(archive); + bool isValid; + switch (archive.State) + { + case GoogleDriveDownloader.State _: + case ManualDownloader.State _: + case HTTPDownloader.State s when new Uri(s.Url).Host.StartsWith("wabbajackpush"): + isValid = true; + break; + default: + isValid = await archive.State.Verify(archive); + break; + } return (Archive: archive, IsValid: isValid); } catch (Exception ex) diff --git a/Wabbajack.BuildServer/Controllers/Heartbeat.cs b/Wabbajack.BuildServer/Controllers/Heartbeat.cs index 6e97518a..b79f2d48 100644 --- a/Wabbajack.BuildServer/Controllers/Heartbeat.cs +++ b/Wabbajack.BuildServer/Controllers/Heartbeat.cs @@ -44,7 +44,8 @@ namespace Wabbajack.BuildServer.Controllers return Ok(new HeartbeatResult { Uptime = DateTime.Now - _startTime, - LastNexusUpdate = DateTime.Now - GetNexusUpdatesJob.LastNexusSync + LastNexusUpdate = DateTime.Now - GetNexusUpdatesJob.LastNexusSync, + LastListValidation = DateTime.UtcNow - ListValidation.SummariesLastChecked }); } @@ -53,6 +54,8 @@ namespace Wabbajack.BuildServer.Controllers { public TimeSpan Uptime { get; set; } public TimeSpan LastNexusUpdate { get; set; } + + public TimeSpan LastListValidation { get; set; } } [HttpGet("only-authenticated")] diff --git a/Wabbajack.BuildServer/Controllers/ListValidation.cs b/Wabbajack.BuildServer/Controllers/ListValidation.cs index 48f66f2b..8722d6fa 100644 --- a/Wabbajack.BuildServer/Controllers/ListValidation.cs +++ b/Wabbajack.BuildServer/Controllers/ListValidation.cs @@ -17,6 +17,7 @@ using Wabbajack.Common; using Wabbajack.Lib; using Wabbajack.Lib.Downloaders; using Wabbajack.Lib.ModListRegistry; +using Wabbajack.Lib.NexusApi; namespace Wabbajack.BuildServer.Controllers { @@ -24,7 +25,7 @@ namespace Wabbajack.BuildServer.Controllers [Route("/lists")] public class ListValidation : AControllerBase<ListValidation> { - enum ArchiveStatus + public enum ArchiveStatus { Valid, InValid, @@ -37,6 +38,8 @@ namespace Wabbajack.BuildServer.Controllers _updater = new ModlistUpdater(null, sql, settings); _settings = settings; Cache = cache; + _nexusClient = NexusApiClient.Get(); + } public static IMemoryCache Cache { get; set; } @@ -44,76 +47,97 @@ namespace Wabbajack.BuildServer.Controllers public static void ResetCache() { - Cache?.Remove(ModListSummariesKey); + SummariesLastChecked = DateTime.UnixEpoch; + ModListSummaries = null; } + private static IEnumerable<(ModListSummary Summary, DetailedStatus Detailed)> ModListSummaries = null; + public static DateTime SummariesLastChecked = DateTime.UnixEpoch; + private static AsyncLock UpdateLock = new AsyncLock(); public async Task<IEnumerable<(ModListSummary Summary, DetailedStatus Detailed)>> GetSummaries() { - - if (Cache.TryGetValue(ModListSummariesKey, out object result)) + static bool TimesUp() { - return (IEnumerable<(ModListSummary Summary, DetailedStatus Detailed)>)result; + return DateTime.UtcNow - SummariesLastChecked > TimeSpan.FromMinutes(5); + } + + if (ModListSummaries != null && !TimesUp()) + { + return ModListSummaries; } - - var data = await SQL.GetValidationData(); - - using var queue = new WorkQueue(); - - var results = await data.ModLists.PMap(queue, async list => + var task = Task.Run(async () => { - var (metadata, modList) = list; - var archives = await modList.Archives.PMap(queue, async archive => + using var _ = await UpdateLock.WaitAsync(); + if (ModListSummaries != null && !TimesUp()) { - var (_, result) = ValidateArchive(data, archive); - if (result == ArchiveStatus.InValid) + return ModListSummaries; + } + SummariesLastChecked = DateTime.UtcNow; + + + var data = await SQL.GetValidationData(); + + using var queue = new WorkQueue(); + + var results = await data.ModLists.PMap(queue, async list => + { + var (metadata, modList) = list; + var archives = await modList.Archives.PMap(queue, async archive => { - var fixResult = await TryToFix(data, archive); - - return fixResult; + var (_, result) = await ValidateArchive(data, archive); + if (result != ArchiveStatus.InValid) return (archive, result); - } + return await TryToFix(data, archive); - return (archive, result); + }); + + var failedCount = archives.Count(f => f.Item2 == ArchiveStatus.InValid); + var passCount = archives.Count(f => + f.Item2 == ArchiveStatus.Valid || f.Item2 == ArchiveStatus.Updated); + var updatingCount = archives.Count(f => f.Item2 == ArchiveStatus.Updating); + + var summary = new ModListSummary + { + Checked = DateTime.UtcNow, + Failed = failedCount, + Passed = passCount, + Updating = updatingCount, + MachineURL = metadata.Links.MachineURL, + Name = metadata.Title, + }; + + var detailed = new DetailedStatus + { + Name = metadata.Title, + Checked = DateTime.UtcNow, + DownloadMetaData = metadata.DownloadMetadata, + HasFailures = failedCount > 0, + MachineName = metadata.Links.MachineURL, + Archives = archives.Select(a => new DetailedStatusItem + { + Archive = a.Item1, + IsFailing = a.Item2 == ArchiveStatus.InValid || a.Item2 == ArchiveStatus.Updating + }).ToList() + }; + + return (summary, detailed); }); - var failedCount = archives.Count(f => f.Item2 == ArchiveStatus.InValid); - var passCount = archives.Count(f => f.Item2 == ArchiveStatus.Valid || f.Item2 == ArchiveStatus.Updated); - var updatingCount = archives.Count(f => f.Item2 == ArchiveStatus.Updating); - var summary = new ModListSummary - { - Checked = DateTime.UtcNow, - Failed = failedCount, - Passed = passCount, - Updating = updatingCount, - MachineURL = metadata.Links.MachineURL, - Name = metadata.Title, - }; - - var detailed = new DetailedStatus - { - Name = metadata.Title, - Checked = DateTime.UtcNow, - DownloadMetaData = metadata.DownloadMetadata, - HasFailures = failedCount > 0, - MachineName = metadata.Links.MachineURL, - Archives = archives.Select(a => new DetailedStatusItem - { - Archive = a.Item1, IsFailing = a.Item2 == ArchiveStatus.InValid || a.Item2 == ArchiveStatus.Updating - }).ToList() - }; - - return (summary, detailed); + var cacheOptions = new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(1)); + Cache.Set(ModListSummariesKey, results, cacheOptions); + + ModListSummaries = results; + return results; }); - - - var cacheOptions = new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(1)); - Cache.Set(ModListSummariesKey, results, cacheOptions); - return results; + var data = ModListSummaries; + if (data == null) + return await task; + return data; } - private static (Archive archive, ArchiveStatus) ValidateArchive(SqlService.ValidationData data, Archive archive) + private async Task<(Archive archive, ArchiveStatus)> ValidateArchive(SqlService.ValidationData data, Archive archive) { switch (archive.State) { @@ -123,8 +147,10 @@ namespace Wabbajack.BuildServer.Controllers case NexusDownloader.State nexusState when data.NexusFiles.Contains(( nexusState.Game.MetaData().NexusGameId, nexusState.ModID, nexusState.FileID)): return (archive, ArchiveStatus.Valid); - case NexusDownloader.State _: - return (archive, ArchiveStatus.InValid); + case NexusDownloader.State ns: + return (archive, await FastNexusModStats(ns)); + case HTTPDownloader.State s when new Uri(s.Url).Host.StartsWith("wabbajackpush"): + return (archive, ArchiveStatus.Valid); case ManualDownloader.State _: return (archive, ArchiveStatus.Valid); default: @@ -140,6 +166,47 @@ namespace Wabbajack.BuildServer.Controllers } } + private async Task<ArchiveStatus> FastNexusModStats(NexusDownloader.State ns) + { + + var mod = await SQL.GetNexusModInfoString(ns.Game, ns.ModID); + var files = await SQL.GetModFiles(ns.Game, ns.ModID); + + if (mod == null) + { + Utils.Log($"Found missing Nexus mod info {ns.Game} {ns.ModID}"); + mod = await (await _nexusClient).GetModInfo(ns.Game, ns.ModID, false); + try + { + await SQL.AddNexusModInfo(ns.Game, ns.ModID, mod.updated_time, mod); + } + catch (Exception _) + { + // Could be a PK constraint failure + } + } + + if (files == null) + { + Utils.Log($"Found missing Nexus mod file infos {ns.Game} {ns.ModID}"); + files = await (await _nexusClient).GetModFiles(ns.Game, ns.ModID, false); + + try + { + await SQL.AddNexusModFiles(ns.Game, ns.ModID, mod.updated_time, files); + } + catch (Exception _) + { + // Could be a PK constraint failure + } + } + + if (mod.available && files.files.Any(f => !string.IsNullOrEmpty(f.category_name) && f.file_id == ns.FileID)) + return ArchiveStatus.Valid; + return ArchiveStatus.InValid; + + } + private static AsyncLock _findPatchLock = new AsyncLock(); private async Task<(Archive, ArchiveStatus)> TryToFix(SqlService.ValidationData data, Archive archive) { @@ -219,6 +286,7 @@ namespace Wabbajack.BuildServer.Controllers private AppSettings _settings; private ModlistUpdater _updater; + private Task<NexusApiClient> _nexusClient; [HttpGet] [Route("status/{Name}.html")] diff --git a/Wabbajack.BuildServer/Controllers/ModlistUpdater.cs b/Wabbajack.BuildServer/Controllers/ModlistUpdater.cs index f6216adb..af3dbd01 100644 --- a/Wabbajack.BuildServer/Controllers/ModlistUpdater.cs +++ b/Wabbajack.BuildServer/Controllers/ModlistUpdater.cs @@ -88,14 +88,12 @@ namespace Wabbajack.BuildServer.Controllers public async Task<IActionResult> GetAlternative(string xxHash) { var startingHash = Hash.FromHex(xxHash); - Utils.Log($"Alternative requested for {startingHash}"); await Metric("requested_upgrade", startingHash.ToString()); var archive = await SQL.GetStateByHash(startingHash); if (archive == null) { - Utils.Log($"No original state for {startingHash}"); return NotFound("Original state not found"); } @@ -120,7 +118,6 @@ namespace Wabbajack.BuildServer.Controllers } - Utils.Log($"Found {newArchive.State.PrimaryKeyString} {newArchive.Name} as an alternative to {startingHash}"); if (newArchive.Hash == Hash.Empty) { await SQL.EnqueueJob(new Job @@ -138,6 +135,7 @@ namespace Wabbajack.BuildServer.Controllers } } }); + Utils.Log($"Enqueued Index and Upgrade for {startingHash} -> {newArchive.State.PrimaryKeyString}"); return Accepted("Enqueued for Processing"); } @@ -155,6 +153,7 @@ namespace Wabbajack.BuildServer.Controllers DestPK = newArchive.State.PrimaryKeyString } }); + Utils.Log($"Enqueued Upgrade for {startingHash} -> {newArchive.State.PrimaryKeyString}"); } return Ok(newArchive.ToJson()); } diff --git a/Wabbajack.BuildServer/Wabbajack.BuildServer.csproj b/Wabbajack.BuildServer/Wabbajack.BuildServer.csproj index c0f5b361..bb7a9a6b 100644 --- a/Wabbajack.BuildServer/Wabbajack.BuildServer.csproj +++ b/Wabbajack.BuildServer/Wabbajack.BuildServer.csproj @@ -18,7 +18,7 @@ <ItemGroup> <PackageReference Include="CsvHelper" Version="15.0.5" /> <PackageReference Include="Dapper" Version="2.0.35" /> - <PackageReference Include="FluentFTP" Version="32.3.3" /> + <PackageReference Include="FluentFTP" Version="32.4.0" /> <PackageReference Include="graphiql" Version="2.0.0" /> <PackageReference Include="GraphQL" Version="3.0.0-preview-1352" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Core" Version="2.2.0" /> @@ -28,7 +28,7 @@ <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" /> <PackageReference Include="Microsoft.OpenApi" Version="1.1.4" /> <PackageReference Include="Nettle" Version="1.3.0" /> - <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.2" /> + <PackageReference Include="Swashbuckle.AspNetCore" Version="5.4.0" /> <PackageReference Include="System.Data.SqlClient" Version="4.8.1" /> </ItemGroup> diff --git a/Wabbajack.Common/Wabbajack.Common.csproj b/Wabbajack.Common/Wabbajack.Common.csproj index 82b17462..ac2bc5e4 100644 --- a/Wabbajack.Common/Wabbajack.Common.csproj +++ b/Wabbajack.Common/Wabbajack.Common.csproj @@ -32,7 +32,7 @@ <PackageReference Include="Microsoft.Win32.Registry" Version="4.7.0" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Octodiff" Version="1.2.1" /> - <PackageReference Include="ReactiveUI" Version="11.3.1" /> + <PackageReference Include="ReactiveUI" Version="11.3.8" /> <PackageReference Include="SharpZipLib" Version="1.2.0" /> <PackageReference Include="System.Data.HashFunction.xxHash" Version="2.0.0" /> <PackageReference Include="System.Net.Http" Version="4.3.4" /> diff --git a/Wabbajack.Lib/Downloaders/MEGADownloader.cs b/Wabbajack.Lib/Downloaders/MEGADownloader.cs index ecf60c8e..ed0fbd7e 100644 --- a/Wabbajack.Lib/Downloaders/MEGADownloader.cs +++ b/Wabbajack.Lib/Downloaders/MEGADownloader.cs @@ -96,27 +96,30 @@ namespace Wabbajack.Lib.Downloaders private static MegaApiClient MegaApiClient => DownloadDispatcher.GetInstance<MegaDownloader>().MegaApiClient; - private static void MegaLogin() + private static AsyncLock _loginLock = new AsyncLock(); + private static async Task MegaLogin() { + using var _ = await _loginLock.WaitAsync(); + if (MegaApiClient.IsLoggedIn) return; if (!Utils.HaveEncryptedJson(DataName)) { Utils.Status("Logging into MEGA (as anonymous)"); - MegaApiClient.LoginAnonymous(); + await MegaApiClient.LoginAnonymousAsync(); } else { Utils.Status("Logging into MEGA with saved credentials."); var authInfo = Utils.FromEncryptedJson<MegaApiClient.AuthInfos>(DataName); - MegaApiClient.Login(authInfo); + await MegaApiClient.LoginAsync(authInfo); } } public override async Task<bool> Download(Archive a, AbsolutePath destination) { - MegaLogin(); + await MegaLogin(); var fileLink = new Uri(Url); Utils.Status($"Downloading MEGA file: {a.Name}"); @@ -126,7 +129,7 @@ namespace Wabbajack.Lib.Downloaders public override async Task<bool> Verify(Archive a) { - MegaLogin(); + await MegaLogin(); var fileLink = new Uri(Url); try diff --git a/Wabbajack.Lib/Wabbajack.Lib.csproj b/Wabbajack.Lib/Wabbajack.Lib.csproj index 989e4aa2..f13f5686 100644 --- a/Wabbajack.Lib/Wabbajack.Lib.csproj +++ b/Wabbajack.Lib/Wabbajack.Lib.csproj @@ -35,10 +35,10 @@ <Version>2.1.0</Version> </PackageReference> <PackageReference Include="ReactiveUI"> - <Version>11.3.1</Version> + <Version>11.3.8</Version> </PackageReference> <PackageReference Include="ReactiveUI.Fody"> - <Version>11.3.1</Version> + <Version>11.3.8</Version> </PackageReference> <PackageReference Include="SharpCompress"> <Version>0.25.0</Version> @@ -65,7 +65,7 @@ <Version>1.0.0</Version> </PackageReference> <PackageReference Include="YoutubeExplode"> - <Version>5.0.1</Version> + <Version>5.0.2</Version> </PackageReference> </ItemGroup> <ItemGroup> diff --git a/Wabbajack.Test/Wabbajack.Test.csproj b/Wabbajack.Test/Wabbajack.Test.csproj index c5ad8b23..c81e88e4 100644 --- a/Wabbajack.Test/Wabbajack.Test.csproj +++ b/Wabbajack.Test/Wabbajack.Test.csproj @@ -27,7 +27,7 @@ <ItemGroup> <PackageReference Include="CefSharp.Common" Version="79.1.360" /> <PackageReference Include="CefSharp.OffScreen" Version="79.1.360" /> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.0" /> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" /> <PackageReference Include="xunit" Version="2.4.1" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" /> <PackageReference Include="coverlet.collector" Version="1.2.1" /> diff --git a/Wabbajack/Wabbajack.csproj b/Wabbajack/Wabbajack.csproj index c5935f64..323218e7 100644 --- a/Wabbajack/Wabbajack.csproj +++ b/Wabbajack/Wabbajack.csproj @@ -57,7 +57,7 @@ <ItemGroup> <PackageReference Include="CefSharp.Wpf" Version="79.1.360" /> - <PackageReference Include="DynamicData" Version="6.14.10" /> + <PackageReference Include="DynamicData" Version="6.14.14" /> <PackageReference Include="Extended.Wpf.Toolkit" Version="3.8.1" /> <PackageReference Include="Fody" Version="6.1.1"> <PrivateAssets>all</PrivateAssets> @@ -72,9 +72,9 @@ <PackageReference Include="MahApps.Metro.IconPacks" Version="4.0.0" /> <PackageReference Include="PInvoke.Gdi32" Version="0.6.6" /> <PackageReference Include="PInvoke.User32" Version="0.6.6" /> - <PackageReference Include="ReactiveUI" Version="11.3.1" /> - <PackageReference Include="ReactiveUI.Fody" Version="11.3.1" /> - <PackageReference Include="ReactiveUI.WPF" Version="11.3.1" /> + <PackageReference Include="ReactiveUI" Version="11.3.8" /> + <PackageReference Include="ReactiveUI.Fody" Version="11.3.8" /> + <PackageReference Include="ReactiveUI.WPF" Version="11.3.8" /> <PackageReference Include="SharpDX.DXGI" Version="4.2.0" /> <PackageReference Include="WindowsAPICodePack-Shell" Version="1.1.1" /> <PackageReference Include="WPFThemes.DarkBlend" Version="1.0.8" />