wabbajack/Wabbajack/View Models/UserInterventionHandlers.cs

184 lines
7.3 KiB
C#
Raw Normal View History

2019-12-08 17:00:22 +00:00
using System;
using System.Collections.Generic;
using System.Linq;
2020-02-11 00:30:38 +00:00
using System.Net.Http;
2019-12-08 17:00:22 +00:00
using System.Text;
using System.Threading;
2019-12-08 17:00:22 +00:00
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
2020-02-06 05:30:31 +00:00
using CefSharp;
2019-12-08 17:00:22 +00:00
using ReactiveUI;
using Wabbajack.Common;
using Wabbajack.Lib;
2019-12-08 17:00:22 +00:00
using Wabbajack.Lib.Downloaders;
2020-02-11 00:30:38 +00:00
using Wabbajack.Lib.LibCefHelpers;
2019-12-08 17:00:22 +00:00
using Wabbajack.Lib.NexusApi;
using Wabbajack.Lib.WebAutomation;
2019-12-08 17:00:22 +00:00
namespace Wabbajack
{
public class UserInterventionHandlers
{
public MainWindowVM MainWindow { get; }
2019-12-08 17:00:22 +00:00
public UserInterventionHandlers(MainWindowVM mvm)
{
MainWindow = mvm;
2019-12-08 17:00:22 +00:00
}
private async Task WrapBrowserJob(IUserIntervention intervention, Func<WebBrowserVM, CancellationTokenSource, Task> toDo)
2019-12-08 17:00:22 +00:00
{
2020-02-11 00:30:38 +00:00
var cancel = new CancellationTokenSource();
var oldPane = MainWindow.ActivePane;
var vm = await WebBrowserVM.GetNew();
MainWindow.NavigateTo(vm);
vm.BackCommand = ReactiveCommand.Create(() =>
2019-12-08 17:00:22 +00:00
{
cancel.Cancel();
MainWindow.NavigateTo(oldPane);
intervention.Cancel();
2019-12-08 17:00:22 +00:00
});
try
{
await toDo(vm, cancel);
}
catch (TaskCanceledException)
{
intervention.Cancel();
}
catch (Exception ex)
{
Utils.Error(ex);
intervention.Cancel();
}
MainWindow.NavigateTo(oldPane);
2019-12-08 17:00:22 +00:00
}
private async Task WrapBethesdaNetLogin(IUserIntervention intervention)
{
CancellationTokenSource cancel = new CancellationTokenSource();
var oldPane = MainWindow.ActivePane;
var vm = await BethesdaNetLoginVM.GetNew();
MainWindow.NavigateTo(vm);
vm.BackCommand = ReactiveCommand.Create(() =>
{
cancel.Cancel();
MainWindow.NavigateTo(oldPane);
intervention.Cancel();
});
}
public async Task Handle(IUserIntervention msg)
2019-12-08 17:00:22 +00:00
{
switch (msg)
{
case RequestNexusAuthorization c:
await WrapBrowserJob(msg, async (vm, cancel) =>
{
await vm.Driver.WaitForInitialized();
var key = await NexusApiClient.SetupNexusLogin(new CefSharpWrapper(vm.Browser), m => vm.Instructions = m, cancel.Token);
c.Resume(key);
});
2019-12-08 17:00:22 +00:00
break;
2020-02-06 05:30:31 +00:00
case ManuallyDownloadNexusFile c:
await WrapBrowserJob(msg, (vm, cancel) => HandleManualNexusDownload(vm, cancel, c));
break;
2020-02-11 00:30:38 +00:00
case ManuallyDownloadFile c:
await WrapBrowserJob(msg, (vm, cancel) => HandleManualDownload(vm, cancel, c));
break;
case RequestBethesdaNetLogin c:
await WrapBethesdaNetLogin(c);
break;
case AbstractNeedsLoginDownloader.RequestSiteLogin c:
await WrapBrowserJob(msg, async (vm, cancel) =>
{
await vm.Driver.WaitForInitialized();
var data = await c.Downloader.GetAndCacheCookies(new CefSharpWrapper(vm.Browser), m => vm.Instructions = m, cancel.Token);
c.Resume(data);
});
2019-12-08 17:00:22 +00:00
break;
case CriticalFailureIntervention c:
MessageBox.Show(c.ExtendedDescription, c.ShortDescription, MessageBoxButton.OK,
MessageBoxImage.Error);
c.Cancel();
break;
case ConfirmationIntervention c:
break;
2019-12-08 17:00:22 +00:00
default:
throw new NotImplementedException($"No handler for {msg}");
}
}
2019-12-20 20:51:10 +00:00
2020-02-11 00:30:38 +00:00
private async Task HandleManualDownload(WebBrowserVM vm, CancellationTokenSource cancel, ManuallyDownloadFile manuallyDownloadFile)
{
var browser = new CefSharpWrapper(vm.Browser);
vm.Instructions = $"Please locate and download {manuallyDownloadFile.State.Url}";
var result = new TaskCompletionSource<Uri>();
browser.DownloadHandler = uri =>
{
//var client = Helpers.GetClient(browser.GetCookies("").Result, browser.Location);
result.SetResult(uri);
};
await vm.Driver.WaitForInitialized();
await browser.NavigateTo(new Uri(manuallyDownloadFile.State.Url));
while (!cancel.IsCancellationRequested)
{
if (result.Task.IsCompleted)
{
var cookies = await Helpers.GetCookies();
var referer = browser.Location;
var client = Helpers.GetClient(cookies, referer);
manuallyDownloadFile.Resume(result.Task.Result, client);
break;
}
await Task.Delay(100);
}
}
2020-02-06 05:30:31 +00:00
private async Task HandleManualNexusDownload(WebBrowserVM vm, CancellationTokenSource cancel, ManuallyDownloadNexusFile manuallyDownloadNexusFile)
{
var state = manuallyDownloadNexusFile.State;
2020-02-11 00:30:38 +00:00
var game = GameRegistry.GetByFuzzyName(state.GameName);
2020-02-06 05:30:31 +00:00
var hrefs = new[]
{
$"/Core/Libs/Common/Widgets/DownloadPopUp?id={state.FileID}&game_id={game.NexusGameId}",
$"https://www.nexusmods.com/{game.NexusName}/mods/{state.ModID}?tab=files&file_id={state.FileID}",
$"/Core/Libs/Common/Widgets/ModRequirementsPopUp?id={state.FileID}&game_id={game.NexusGameId}"
};
await vm.Driver.WaitForInitialized();
IWebDriver browser = new CefSharpWrapper(vm.Browser);
vm.Instructions = $"Please Download {state.Name} - {state.ModID} - {state.FileID}";
2020-02-06 05:30:31 +00:00
browser.DownloadHandler = uri =>
{
manuallyDownloadNexusFile.Resume(uri);
2020-02-11 00:30:38 +00:00
browser.DownloadHandler = null;
2020-02-06 05:30:31 +00:00
};
await browser.NavigateTo(NexusApiClient.ManualDownloadUrl(manuallyDownloadNexusFile.State));
var buttin_href = $"/Core/Libs/Common/Widgets/DownloadPopUp?id={manuallyDownloadNexusFile.State.FileID}&game_id={Game.SkyrimSpecialEdition}";
2019-12-20 20:51:10 +00:00
2020-02-06 05:30:31 +00:00
while (!cancel.IsCancellationRequested && !manuallyDownloadNexusFile.Task.IsCompleted) {
await browser.EvaluateJavaScript(
@"Array.from(document.getElementsByClassName('accordion')).forEach(e => Array.from(e.children).forEach(c => c.style=''))");
foreach (var href in hrefs)
{
const string style = "border-thickness: thick; border-color: #ff0000;border-width: medium;border-style: dashed;background-color: teal;padding: 7px";
await browser.EvaluateJavaScript($"Array.from(document.querySelectorAll('.accordion a[href=\"{href}\"]')).forEach(e => {{e.scrollIntoView({{behavior: 'smooth', block: 'center', inline: 'nearest'}}); e.setAttribute('style', '{style}');}});");
}
await Task.Delay(250);
}
}
2019-12-08 17:00:22 +00:00
}
}