UserInterventionHandlers cancellation tokens. Removed dispatcher

This commit is contained in:
Justin Swanson 2019-12-08 13:46:30 -06:00
parent fb996a702a
commit f8f0490047
5 changed files with 79 additions and 86 deletions

View File

@ -5,6 +5,7 @@ using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using Wabbajack.Common;
@ -42,7 +43,7 @@ namespace Wabbajack.Lib.Downloaders
_authedClient = GetAuthedClient().Result ?? throw new Exception("not logged into LL, TODO");
}
public static async Task<Helpers.Cookie[]> GetAndCacheLoversLabCookies(BaseCefBrowser browser, Action<string> updateStatus)
public static async Task<Helpers.Cookie[]> GetAndCacheLoversLabCookies(BaseCefBrowser browser, Action<string> updateStatus, CancellationToken cancel)
{
updateStatus("Please Log Into Lovers Lab");
browser.Address = "https://www.loverslab.com/login";
@ -56,17 +57,19 @@ namespace Wabbajack.Lib.Downloaders
}
catch (Exception ex)
{
Utils.Error(ex);
}
return false;
}
var cookies = new Helpers.Cookie[0];
while (true)
{
cancel.ThrowIfCancellationRequested();
await CleanAds();
cookies = (await Helpers.GetCookies("loverslab.com"));
if (cookies.FirstOrDefault(c => c.Name == "ips4_member_id") != null)
break;
await Task.Delay(500);
await Task.Delay(500, cancel);
}
cookies.ToEcryptedJson("loverslabcookies");

View File

@ -23,6 +23,7 @@ using Xilium.CefGlue.Common;
using Xilium.CefGlue.Common.Handlers;
using Xilium.CefGlue.WPF;
using static Wabbajack.Lib.NexusApi.NexusApiUtils;
using System.Threading;
namespace Wabbajack.Lib.NexusApi
{
@ -109,41 +110,47 @@ namespace Wabbajack.Lib.NexusApi
}
}
public static async Task<string> SetupNexusLogin(BaseCefBrowser browser, Action<string> updateStatus)
public static async Task<string> SetupNexusLogin(BaseCefBrowser browser, Action<string> updateStatus, CancellationToken cancel)
{
updateStatus("Please Log Into the Nexus");
browser.Address = "https://users.nexusmods.com/auth/continue?client_id=nexus&redirect_uri=https://www.nexusmods.com/oauth/callback&response_type=code&referrer=//www.nexusmods.com";
while (true)
{
var cookies = (await Helpers.GetCookies("nexusmods.com"));
if (cookies.FirstOrDefault(c => c.Name == "member_id") != null)
var cookies = await Helpers.GetCookies("nexusmods.com");
if (cookies.Any(c => c.Name == "member_id"))
break;
await Task.Delay(500);
cancel.ThrowIfCancellationRequested();
await Task.Delay(500, cancel);
}
// open a web socket to receive the api key
var guid = Guid.NewGuid();
var _websocket = new WebSocket("wss://sso.nexusmods.com")
using (var websocket = new WebSocket("wss://sso.nexusmods.com")
{
SslConfiguration =
{
EnabledSslProtocols = SslProtocols.Tls12
}
};
})
{
updateStatus("Please Authorize Wabbajack to Download Mods");
var api_key = new TaskCompletionSource<string>();
websocket.OnMessage += (sender, msg) => { api_key.SetResult(msg.Data); };
updateStatus("Please Authorize Wabbajack to Download Mods");
var api_key = new TaskCompletionSource<string>();
_websocket.OnMessage += (sender, msg) => { api_key.SetResult(msg.Data); };
websocket.Connect();
websocket.Send("{\"id\": \"" + guid + "\", \"appid\": \"" + Consts.AppName + "\"}");
await Task.Delay(1000, cancel);
_websocket.Connect();
_websocket.Send("{\"id\": \"" + guid + "\", \"appid\": \"" + Consts.AppName + "\"}");
await Task.Delay(1000);
// open a web browser to get user permission
browser.Address = $"https://www.nexusmods.com/sso?id={guid}&application={Consts.AppName}";
return await api_key.Task;
// open a web browser to get user permission
browser.Address = $"https://www.nexusmods.com/sso?id={guid}&application={Consts.AppName}";
using (cancel.Register(() =>
{
api_key.SetCanceled();
}))
{
return await api_key.Task;
}
}
}
public UserStatus GetUserStatus()

View File

@ -51,7 +51,7 @@ namespace Wabbajack
Gallery = new Lazy<ModListGalleryVM>(() => new ModListGalleryVM(this));
ModeSelectionVM = new ModeSelectionVM(this);
WebBrowserVM = new WebBrowserVM();
UserInterventionHandlers = new UserInterventionHandlers {MainWindow = this, ViewDispatcher = mainWindow.Dispatcher};
UserInterventionHandlers = new UserInterventionHandlers(this);
// Set up logging
Utils.LogMessages
@ -67,7 +67,10 @@ namespace Wabbajack
Utils.LogMessages
.OfType<IUserIntervention>()
.Subscribe(msg => UserInterventionHandlers.Handle(msg));
.ObserveOnGuiThread()
.SelectTask(msg => UserInterventionHandlers.Handle(msg))
.Subscribe()
.DisposeWith(CompositeDisposable);
if (IsStartingFromModlist(out var path))
{

View File

@ -2,10 +2,12 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using ReactiveUI;
using Wabbajack.Common;
using Wabbajack.Common.StatusFeed;
using Wabbajack.Lib.Downloaders;
using Wabbajack.Lib.NexusApi;
@ -15,73 +17,44 @@ namespace Wabbajack
{
public class UserInterventionHandlers
{
public Dispatcher ViewDispatcher { get; set; }
public MainWindowVM MainWindow { get; set; }
internal void Handle(RequestLoversLabLogin msg)
public MainWindowVM MainWindow { get; }
public UserInterventionHandlers(MainWindowVM mvm)
{
ViewDispatcher.InvokeAsync(async () =>
{
var oldPane = MainWindow.ActivePane;
var vm = new WebBrowserVM();
MainWindow.ActivePane = vm;
try
{
vm.BackCommand = ReactiveCommand.Create(() =>
{
MainWindow.ActivePane = oldPane;
msg.Cancel();
});
}
catch (Exception e)
{ }
try
{
var data = await LoversLabDownloader.GetAndCacheLoversLabCookies(vm.Browser, m => vm.Instructions = m);
msg.Resume(data);
}
catch (Exception ex)
{
msg.Cancel();
}
MainWindow.ActivePane = oldPane;
});
MainWindow = mvm;
}
internal void Handle(RequestNexusAuthorization msg)
private async Task WrapBrowserJob(IUserIntervention intervention, Func<WebBrowserVM, CancellationTokenSource, Task> toDo)
{
ViewDispatcher.InvokeAsync(async () =>
CancellationTokenSource cancel = new CancellationTokenSource();
var oldPane = MainWindow.ActivePane;
var vm = new WebBrowserVM();
MainWindow.ActivePane = vm;
vm.BackCommand = ReactiveCommand.Create(() =>
{
var oldPane = MainWindow.ActivePane;
var vm = new WebBrowserVM();
MainWindow.ActivePane = vm;
try
{
vm.BackCommand = ReactiveCommand.Create(() =>
{
MainWindow.ActivePane = oldPane;
msg.Cancel();
});
}
catch (Exception e)
{ }
try
{
var key = await NexusApiClient.SetupNexusLogin(vm.Browser, m => vm.Instructions = m);
msg.Resume(key);
}
catch (Exception ex)
{
msg.Cancel();
}
cancel.Cancel();
MainWindow.ActivePane = oldPane;
intervention.Cancel();
});
try
{
await toDo(vm, cancel);
}
catch (TaskCanceledException)
{
intervention.Cancel();
}
catch (Exception ex)
{
Utils.Error(ex);
intervention.Cancel();
}
MainWindow.ActivePane = oldPane;
}
internal void Handle(ConfirmUpdateOfExistingInstall msg)
public void Handle(ConfirmUpdateOfExistingInstall msg)
{
var result = MessageBox.Show(msg.ExtendedDescription, msg.ShortDescription, MessageBoxButton.OKCancel);
if (result == MessageBoxResult.OK)
@ -90,7 +63,7 @@ namespace Wabbajack
msg.Cancel();
}
public void Handle(IUserIntervention msg)
public async Task Handle(IUserIntervention msg)
{
switch (msg)
{
@ -98,10 +71,18 @@ namespace Wabbajack
Handle(c);
break;
case RequestNexusAuthorization c:
Handle(c);
await WrapBrowserJob(msg, async (vm, cancel) =>
{
var key = await NexusApiClient.SetupNexusLogin(vm.Browser, m => vm.Instructions = m, cancel.Token);
c.Resume(key);
});
break;
case RequestLoversLabLogin c:
Handle(c);
await WrapBrowserJob(msg, async (vm, cancel) =>
{
var data = await LoversLabDownloader.GetAndCacheLoversLabCookies(vm.Browser, m => vm.Instructions = m, cancel.Token);
c.Resume(data);
});
break;
default:
throw new NotImplementedException($"No handler for {msg}");

View File

@ -6,7 +6,6 @@ using System.Threading.Tasks;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Wabbajack.Lib;
using Xilium.CefGlue.Common;
using Xilium.CefGlue.WPF;
namespace Wabbajack
@ -16,13 +15,13 @@ namespace Wabbajack
[Reactive]
public string Instructions { get; set; }
public WpfCefBrowser Browser { get; }
public WpfCefBrowser Browser { get; } = new WpfCefBrowser();
[Reactive]
public IReactiveCommand BackCommand { get; set; }
public WebBrowserVM(string url = "http://www.wabbajack.org")
{
Browser = new WpfCefBrowser();
Browser.Address = url;
Instructions = "Wabbajack Web Browser";
}