mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Woot, we can log into the Nexus through 3.0 code
This commit is contained in:
parent
149dd9b07e
commit
9f87d91918
@ -15,6 +15,7 @@ using Wabbajack.DTOs;
|
||||
using Wabbajack.LoginManagers;
|
||||
using Wabbajack.Models;
|
||||
using Wabbajack.Services.OSIntegrated;
|
||||
using Wabbajack.UserIntervention;
|
||||
using Wabbajack.Util;
|
||||
|
||||
namespace Wabbajack
|
||||
@ -47,6 +48,9 @@ namespace Wabbajack
|
||||
RxApp.MainThreadScheduler = new DispatcherScheduler(Dispatcher.CurrentDispatcher);
|
||||
|
||||
services.AddOSIntegrated();
|
||||
|
||||
services.AddSingleton<CefService>();
|
||||
|
||||
services.AddTransient<MainWindow>();
|
||||
services.AddTransient<MainWindowVM>();
|
||||
services.AddSingleton<SystemParametersConstructor>();
|
||||
@ -60,6 +64,10 @@ namespace Wabbajack
|
||||
services.AddTransient<ModeSelectionVM>();
|
||||
services.AddTransient<ModListGalleryVM>();
|
||||
services.AddTransient<InstallerVM>();
|
||||
|
||||
services.AddTransient<WebBrowserVM>();
|
||||
|
||||
services.AddTransient<NexusLoginHandler>();
|
||||
|
||||
// Login Managers
|
||||
services.AddAllSingleton<INeedsLogin, NexusLoginManager>();
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using Wabbajack.Paths;
|
||||
using Wabbajack.Paths.IO;
|
||||
|
||||
namespace Wabbajack;
|
||||
|
||||
@ -9,6 +10,7 @@ public static class Consts
|
||||
public static Uri WabbajackBuildServerUri => new("https://build.wabbajack.org");
|
||||
public static Version CurrentMinimumWabbajackVersion { get; set; } = Version.Parse("2.3.0.0");
|
||||
public static bool UseNetworkWorkaroundMode { get; set; } = false;
|
||||
public static AbsolutePath CefCacheLocation { get; } = KnownFolders.WabbajackAppLocal.Combine("Cef");
|
||||
|
||||
public static byte SettingsVersion = 0;
|
||||
|
||||
|
@ -2,10 +2,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using ReactiveUI;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.DTOs.Interventions;
|
||||
using Wabbajack.Interventions;
|
||||
|
||||
namespace Wabbajack
|
||||
@ -18,6 +20,12 @@ namespace Wabbajack
|
||||
|
||||
private bool _handled;
|
||||
public bool Handled { get => _handled; set => this.RaiseAndSetIfChanged(ref _handled, value); }
|
||||
public CancellationToken Token { get; }
|
||||
public void SetException(Exception exception)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public abstract void Cancel();
|
||||
public ICommand CancelCommand { get; }
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Wabbajack.Interventions
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a message that requires user interaction. The user must perform some action
|
||||
/// or make a choice.
|
||||
/// </summary>
|
||||
public interface IUserIntervention : IReactiveObject
|
||||
{
|
||||
/// <summary>
|
||||
/// The user didn't make a choice, so this action should be aborted
|
||||
/// </summary>
|
||||
void Cancel();
|
||||
|
||||
/// <summary>
|
||||
/// Whether the interaction has been handled and no longer needs attention
|
||||
/// Note: This needs to be Reactive so that users can monitor its status
|
||||
/// </summary>
|
||||
bool Handled { get; }
|
||||
|
||||
}
|
||||
}
|
@ -11,7 +11,8 @@ public class NavigateToGlobal
|
||||
Installer,
|
||||
Settings,
|
||||
Compiler,
|
||||
ModListContents
|
||||
ModListContents,
|
||||
WebBrowser
|
||||
}
|
||||
|
||||
public ScreenType Screen { get; }
|
||||
|
@ -1,16 +1,28 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ReactiveUI;
|
||||
using Wabbajack.DTOs.Interventions;
|
||||
using Wabbajack.Networking.Http.Interfaces;
|
||||
|
||||
namespace Wabbajack.Messages;
|
||||
|
||||
public class NexusLogin
|
||||
public class NexusLogin : IUserIntervention
|
||||
{
|
||||
private TaskCompletionSource CompletionSource { get; }
|
||||
private readonly CancellationTokenSource _source;
|
||||
public TaskCompletionSource CompletionSource { get; }
|
||||
public CancellationToken Token => _source.Token;
|
||||
public void SetException(Exception exception)
|
||||
{
|
||||
CompletionSource.SetException(exception);
|
||||
_source.Cancel();
|
||||
}
|
||||
|
||||
public NexusLogin()
|
||||
{
|
||||
CompletionSource = new TaskCompletionSource();
|
||||
_source = new CancellationTokenSource();
|
||||
|
||||
}
|
||||
|
||||
public static Task Send()
|
||||
@ -19,4 +31,12 @@ public class NexusLogin
|
||||
MessageBus.Current.SendMessage(msg);
|
||||
return msg.CompletionSource.Task;
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
_source.Cancel();
|
||||
CompletionSource.TrySetCanceled();
|
||||
}
|
||||
|
||||
public bool Handled => CompletionSource.Task.IsCompleted;
|
||||
}
|
70
Wabbajack.App.Wpf/Models/CefService.cs
Normal file
70
Wabbajack.App.Wpf/Models/CefService.cs
Normal file
@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using CefSharp;
|
||||
using CefSharp.Wpf;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Wabbajack.Models;
|
||||
|
||||
public class CefService
|
||||
{
|
||||
private readonly ILogger<CefService> _logger;
|
||||
private bool Inited { get; set; } = false;
|
||||
|
||||
public Func<IBrowser, IFrame, string, IRequest, IResourceHandler>? SchemeHandler { get; set; }
|
||||
|
||||
public CefService(ILogger<CefService> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
Inited = false;
|
||||
Init();
|
||||
}
|
||||
|
||||
public IWebBrowser CreateBrowser()
|
||||
{
|
||||
return new ChromiumWebBrowser();
|
||||
}
|
||||
private void Init()
|
||||
{
|
||||
if (Inited || Cef.IsInitialized) return;
|
||||
Inited = true;
|
||||
var settings = new CefSettings
|
||||
{
|
||||
CachePath = Consts.CefCacheLocation.ToString(),
|
||||
JavascriptFlags = "--noexpose_wasm"
|
||||
};
|
||||
settings.RegisterScheme(new CefCustomScheme()
|
||||
{
|
||||
SchemeName = "wabbajack",
|
||||
SchemeHandlerFactory = new SchemeHandlerFactor(_logger, this)
|
||||
});
|
||||
|
||||
_logger.LogInformation("Initializing Cef");
|
||||
if (!Cef.Initialize(settings))
|
||||
{
|
||||
_logger.LogError("Cannot initialize CEF");
|
||||
}
|
||||
}
|
||||
|
||||
private class SchemeHandlerFactor : ISchemeHandlerFactory
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly CefService _service;
|
||||
|
||||
internal SchemeHandlerFactor(ILogger logger, CefService service)
|
||||
{
|
||||
_logger = logger;
|
||||
_service = service;
|
||||
}
|
||||
|
||||
public IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request)
|
||||
{
|
||||
_logger.LogInformation("Scheme handler Got: {Scheme} : {Url}", schemeName, request.Url);
|
||||
if (_service.SchemeHandler != null && schemeName == "wabbajack")
|
||||
{
|
||||
return _service.SchemeHandler!(browser, frame, schemeName, request);
|
||||
}
|
||||
return new ResourceHandler();
|
||||
}
|
||||
}
|
||||
}
|
@ -103,7 +103,7 @@ public class LoggerProvider : ILoggerProvider
|
||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception,
|
||||
Func<TState, Exception?, string> formatter)
|
||||
{
|
||||
Debug.WriteLine(formatter(state, exception));
|
||||
Debug.WriteLine($"{logLevel} - {formatter(state, exception)}");
|
||||
_provider._messages.OnNext(new LogMessage<TState>(DateTime.UtcNow, _provider.NextMessageId(), logLevel,
|
||||
eventId, state, exception, formatter));
|
||||
}
|
||||
|
111
Wabbajack.App.Wpf/UserIntervention/NexusLoginHandler.cs
Normal file
111
Wabbajack.App.Wpf/UserIntervention/NexusLoginHandler.cs
Normal file
@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ReactiveUI;
|
||||
using Wabbajack.DTOs.Logins;
|
||||
using Wabbajack.LibCefHelpers;
|
||||
using Wabbajack.Messages;
|
||||
using Wabbajack.Networking.Http.Interfaces;
|
||||
using Wabbajack.Services.OSIntegrated.TokenProviders;
|
||||
|
||||
namespace Wabbajack.UserIntervention;
|
||||
|
||||
public class NexusLoginHandler : WebUserInterventionBase
|
||||
{
|
||||
private readonly ITokenProvider<NexusApiState> _provider;
|
||||
|
||||
public NexusLoginHandler(ILogger<NexusLoginHandler> logger, WebBrowserVM browserVM, ITokenProvider<NexusApiState> provider) : base(logger, browserVM)
|
||||
{
|
||||
_provider = provider;
|
||||
}
|
||||
public async Task Begin()
|
||||
{
|
||||
try
|
||||
{
|
||||
Messages.NavigateTo.Send(Browser);
|
||||
UpdateStatus("Please log into the Nexus");
|
||||
await Driver.WaitForInitialized();
|
||||
|
||||
await NavigateTo(new Uri("https://users.nexusmods.com/auth/continue?client_id=nexus&redirect_uri=https://www.nexusmods.com/oauth/callback&response_type=code&referrer=//www.nexusmods.com"));
|
||||
|
||||
Helpers.Cookie[] cookies = {};
|
||||
while (true)
|
||||
{
|
||||
cookies = await Driver.GetCookies("nexusmods.com");
|
||||
if (cookies.Any(c => c.Name == "member_id"))
|
||||
break;
|
||||
Message.Token.ThrowIfCancellationRequested();
|
||||
await Task.Delay(500, Message.Token);
|
||||
}
|
||||
|
||||
|
||||
await NavigateTo(new Uri("https://www.nexusmods.com/users/myaccount?tab=api"));
|
||||
|
||||
UpdateStatus("Looking for API Key");
|
||||
|
||||
var key = "";
|
||||
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
key = await Driver.EvaluateJavaScript(
|
||||
"document.querySelector(\"input[value=wabbajack]\").parentElement.parentElement.querySelector(\"textarea.application-key\").innerHTML");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await Driver.EvaluateJavaScript(
|
||||
"var found = document.querySelector(\"input[value=wabbajack]\").parentElement.parentElement.querySelector(\"form button[type=submit]\");" +
|
||||
"found.onclick= function() {return true;};" +
|
||||
"found.class = \" \"; " +
|
||||
"found.click();" +
|
||||
"found.remove(); found = undefined;"
|
||||
);
|
||||
UpdateStatus("Generating API Key, Please Wait...");
|
||||
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
Message.Token.ThrowIfCancellationRequested();
|
||||
await Task.Delay(500, Message.Token);
|
||||
}
|
||||
|
||||
|
||||
await _provider.SetToken(new NexusApiState()
|
||||
{
|
||||
ApiKey = key,
|
||||
Cookies = cookies.Select(c => new Cookie()
|
||||
{
|
||||
Domain = c.Domain,
|
||||
Name = c.Name,
|
||||
Path = c.Path,
|
||||
Value = c.Value
|
||||
}).ToArray()
|
||||
});
|
||||
|
||||
((NexusLogin)Message).CompletionSource.SetResult();
|
||||
Messages.NavigateTo.Send(PrevPane);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, "While logging into Nexus Mods");
|
||||
Message.SetException(ex);
|
||||
Messages.NavigateTo.Send(PrevPane);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Wabbajack.DTOs.Interventions;
|
||||
using Wabbajack.Interventions;
|
||||
using Wabbajack.WebAutomation;
|
||||
|
||||
namespace Wabbajack.UserIntervention;
|
||||
|
||||
public class WebUserInterventionBase
|
||||
{
|
||||
protected readonly WebBrowserVM Browser;
|
||||
protected readonly ILogger Logger;
|
||||
protected IUserIntervention Message;
|
||||
protected ViewModel PrevPane;
|
||||
protected IWebDriver Driver;
|
||||
|
||||
public WebUserInterventionBase(ILogger logger, WebBrowserVM browser)
|
||||
{
|
||||
Logger = logger;
|
||||
Browser = browser;
|
||||
Driver = new CefSharpWrapper(logger, browser.Browser);
|
||||
}
|
||||
|
||||
public void Configure(ViewModel prevPane, IUserIntervention message)
|
||||
{
|
||||
Message = message;
|
||||
PrevPane = prevPane;
|
||||
}
|
||||
|
||||
protected void UpdateStatus(string status)
|
||||
{
|
||||
Browser.Instructions = status;
|
||||
}
|
||||
|
||||
protected async Task NavigateTo(Uri uri)
|
||||
{
|
||||
await Driver.NavigateTo(uri, Message.Token);
|
||||
}
|
||||
|
||||
}
|
@ -12,6 +12,7 @@ using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using DynamicData.Binding;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using Wabbajack.DTOs.Interventions;
|
||||
|
||||
namespace Wabbajack
|
||||
{
|
||||
|
@ -1,13 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ReactiveUI;
|
||||
using Wabbajack.Common;
|
||||
using System.Threading.Tasks;
|
||||
using Wabbajack.Installer;
|
||||
using Wabbajack;
|
||||
using Wabbajack.Interventions;
|
||||
using Wabbajack.DTOs.Interventions;
|
||||
|
||||
namespace Wabbajack
|
||||
{
|
||||
|
@ -13,6 +13,7 @@ using Wabbajack.Common;
|
||||
using Wabbajack.Installer;
|
||||
using Wabbajack;
|
||||
using Wabbajack.DTOs;
|
||||
using Wabbajack.DTOs.Interventions;
|
||||
using Wabbajack.Interventions;
|
||||
using Wabbajack.Util;
|
||||
|
||||
@ -194,7 +195,7 @@ namespace Wabbajack
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public IUserIntervention InterventionConverter(IUserIntervention intervention)
|
||||
{
|
||||
switch (intervention)
|
||||
|
@ -2,6 +2,7 @@
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
@ -16,10 +17,12 @@ using Wabbajack.Common;
|
||||
using Wabbajack.Downloaders.GameFile;
|
||||
using Wabbajack;
|
||||
using Wabbajack.Interventions;
|
||||
using Wabbajack.LoginManagers;
|
||||
using Wabbajack.Messages;
|
||||
using Wabbajack.Models;
|
||||
using Wabbajack.Networking.WabbajackClientApi;
|
||||
using Wabbajack.Paths;
|
||||
using Wabbajack.UserIntervention;
|
||||
using Wabbajack.View_Models;
|
||||
|
||||
namespace Wabbajack
|
||||
@ -44,12 +47,16 @@ namespace Wabbajack
|
||||
public readonly Lazy<SettingsVM> SettingsPane;
|
||||
public readonly ModListGalleryVM Gallery;
|
||||
public readonly ModeSelectionVM ModeSelectionVM;
|
||||
public readonly WebBrowserVM WebBrowserVM;
|
||||
public readonly Lazy<ModListContentsVM> ModListContentsVM;
|
||||
public readonly UserInterventionHandlers UserInterventionHandlers;
|
||||
private readonly Client _wjClient;
|
||||
private readonly ILogger<MainWindowVM> _logger;
|
||||
private readonly ResourceMonitor _resourceMonitor;
|
||||
|
||||
private List<ViewModel> PreviousPanes = new();
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
public ICommand CopyVersionCommand { get; }
|
||||
public ICommand ShowLoginManagerVM { get; }
|
||||
public ICommand OpenSettingsCommand { get; }
|
||||
@ -64,11 +71,12 @@ namespace Wabbajack
|
||||
|
||||
public MainWindowVM(ILogger<MainWindowVM> logger, MainSettings settings, Client wjClient,
|
||||
IServiceProvider serviceProvider, ModeSelectionVM modeSelectionVM, ModListGalleryVM modListGalleryVM, ResourceMonitor resourceMonitor,
|
||||
InstallerVM installer)
|
||||
InstallerVM installer, WebBrowserVM webBrowserVM)
|
||||
{
|
||||
_logger = logger;
|
||||
_wjClient = wjClient;
|
||||
_resourceMonitor = resourceMonitor;
|
||||
_serviceProvider = serviceProvider;
|
||||
ConverterRegistration.Register();
|
||||
Settings = settings;
|
||||
Installer = installer;
|
||||
@ -76,12 +84,25 @@ namespace Wabbajack
|
||||
SettingsPane = new Lazy<SettingsVM>(() => new SettingsVM(serviceProvider.GetRequiredService<ILogger<SettingsVM>>(), this, serviceProvider));
|
||||
Gallery = modListGalleryVM;
|
||||
ModeSelectionVM = modeSelectionVM;
|
||||
WebBrowserVM = webBrowserVM;
|
||||
ModListContentsVM = new Lazy<ModListContentsVM>(() => new ModListContentsVM(serviceProvider.GetRequiredService<ILogger<ModListContentsVM>>(), this));
|
||||
UserInterventionHandlers = new UserInterventionHandlers(serviceProvider.GetRequiredService<ILogger<UserInterventionHandlers>>(), this);
|
||||
|
||||
MessageBus.Current.Listen<NavigateToGlobal>()
|
||||
.Subscribe(m => HandleNavigateTo(m.Screen))
|
||||
.DisposeWith(CompositeDisposable);
|
||||
|
||||
MessageBus.Current.Listen<NavigateTo>()
|
||||
.Subscribe(m => HandleNavigateTo(m.ViewModel))
|
||||
.DisposeWith(CompositeDisposable);
|
||||
|
||||
MessageBus.Current.Listen<NavigateBack>()
|
||||
.Subscribe(HandleNavigateBack)
|
||||
.DisposeWith(CompositeDisposable);
|
||||
|
||||
MessageBus.Current.Listen<NexusLogin>()
|
||||
.Subscribe(m => HandleNexusLogin(m))
|
||||
.DisposeWith(CompositeDisposable);
|
||||
|
||||
_resourceMonitor.Updates
|
||||
.Select(r => string.Join(", ", r.Where(r => r.Throughput > 0)
|
||||
@ -169,6 +190,24 @@ namespace Wabbajack
|
||||
execute: () => NavigateToGlobal.Send(NavigateToGlobal.ScreenType.Settings));
|
||||
}
|
||||
|
||||
private void HandleNavigateTo(ViewModel objViewModel)
|
||||
{
|
||||
ActivePane = objViewModel;
|
||||
}
|
||||
|
||||
private void HandleNexusLogin(NexusLogin nexusLogin)
|
||||
{
|
||||
var handler = _serviceProvider.GetRequiredService<NexusLoginHandler>();
|
||||
handler.Configure(ActivePane, nexusLogin);
|
||||
handler.Begin().FireAndForget();
|
||||
}
|
||||
|
||||
private void HandleNavigateBack(NavigateBack navigateBack)
|
||||
{
|
||||
ActivePane = PreviousPanes.Last();
|
||||
PreviousPanes.RemoveAt(PreviousPanes.Count - 1);
|
||||
}
|
||||
|
||||
private void HandleNavigateTo(NavigateToGlobal.ScreenType s)
|
||||
{
|
||||
ActivePane = s switch
|
||||
@ -181,6 +220,7 @@ namespace Wabbajack
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private static bool IsStartingFromModlist(out AbsolutePath modlistPath)
|
||||
{
|
||||
/* TODO
|
||||
|
@ -2,9 +2,11 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack;
|
||||
using Wabbajack.DTOs.Interventions;
|
||||
using Wabbajack.Interventions;
|
||||
|
||||
namespace Wabbajack
|
||||
@ -16,6 +18,11 @@ namespace Wabbajack
|
||||
public MO2InstallerVM Installer { get; }
|
||||
|
||||
public bool Handled => ((IUserIntervention)Source).Handled;
|
||||
public CancellationToken Token { get; }
|
||||
public void SetException(Exception exception)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int CpuID => 0;
|
||||
|
||||
|
@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging;
|
||||
using ReactiveUI;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack;
|
||||
using Wabbajack.DTOs.Interventions;
|
||||
using Wabbajack.Interventions;
|
||||
using Wabbajack.Messages;
|
||||
|
||||
@ -23,12 +24,13 @@ namespace Wabbajack
|
||||
MainWindow = mvm;
|
||||
}
|
||||
|
||||
private async Task WrapBrowserJob(IUserIntervention intervention, Func<WebBrowserVM, CancellationTokenSource, Task> toDo)
|
||||
private async Task WrapBrowserJob(IUserIntervention intervention, WebBrowserVM vm, Func<WebBrowserVM, CancellationTokenSource, Task> toDo)
|
||||
{
|
||||
var wait = await _browserLock.WaitAsync();
|
||||
var cancel = new CancellationTokenSource();
|
||||
var oldPane = MainWindow.ActivePane;
|
||||
using var vm = await WebBrowserVM.GetNew(_logger);
|
||||
|
||||
// TODO: FIX using var vm = await WebBrowserVM.GetNew(_logger);
|
||||
NavigateTo.Send(vm);
|
||||
vm.BackCommand = ReactiveCommand.Create(() =>
|
||||
{
|
||||
|
@ -13,19 +13,22 @@ using ReactiveUI;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using Wabbajack;
|
||||
using Wabbajack.LibCefHelpers;
|
||||
using Wabbajack.Messages;
|
||||
using Wabbajack.Models;
|
||||
using Wabbajack.WebAutomation;
|
||||
|
||||
namespace Wabbajack
|
||||
{
|
||||
public class WebBrowserVM : ViewModel, IBackNavigatingVM, IDisposable
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly ILogger<WebBrowserVM> _logger;
|
||||
private readonly CefService _cefService;
|
||||
|
||||
[Reactive]
|
||||
public string Instructions { get; set; }
|
||||
|
||||
public IWebBrowser Browser { get; } = new ChromiumWebBrowser();
|
||||
public CefSharpWrapper Driver => new(_logger, Browser);
|
||||
public IWebBrowser Browser { get; }
|
||||
public CefSharpWrapper Driver { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public ViewModel NavigateBackTarget { get; set; }
|
||||
@ -36,17 +39,17 @@ namespace Wabbajack
|
||||
public Subject<bool> IsBackEnabledSubject { get; } = new Subject<bool>();
|
||||
public IObservable<bool> IsBackEnabled { get; }
|
||||
|
||||
private WebBrowserVM(ILogger logger, string url = "http://www.wabbajack.org")
|
||||
public WebBrowserVM(ILogger<WebBrowserVM> logger, CefService cefService)
|
||||
{
|
||||
// CefService is required so that Cef is initalized
|
||||
_logger = logger;
|
||||
IsBackEnabled = IsBackEnabledSubject.StartWith(true);
|
||||
_cefService = cefService;
|
||||
Instructions = "Wabbajack Web Browser";
|
||||
}
|
||||
|
||||
BackCommand = ReactiveCommand.Create(NavigateBack.Send);
|
||||
Browser = cefService.CreateBrowser();
|
||||
Driver = new CefSharpWrapper(_logger, Browser);
|
||||
|
||||
public static async Task<WebBrowserVM> GetNew(ILogger logger, string url = "http://www.wabbajack.org")
|
||||
{
|
||||
// Make sure libraries are extracted first
|
||||
return new WebBrowserVM(logger, url);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
|
@ -35,6 +35,7 @@ namespace Wabbajack.WebAutomation
|
||||
_browser.LoadingStateChanged -= handler;
|
||||
tcs.SetResult(true);
|
||||
};
|
||||
|
||||
_browser.LoadingStateChanged += handler;
|
||||
_browser.Load(uri.ToString());
|
||||
token?.Register(() => tcs.TrySetCanceled());
|
||||
|
@ -14,6 +14,7 @@ namespace Wabbajack.WebAutomation
|
||||
Task NavigateTo(Uri uri, CancellationToken? token = null);
|
||||
Task<string> EvaluateJavaScript(string text);
|
||||
Task<Helpers.Cookie[]> GetCookies(string domainPrefix);
|
||||
public Action<Uri>? DownloadHandler { get; set; }
|
||||
public Action<Uri>? DownloadHandler { get; set; }
|
||||
public Task WaitForInitialized();
|
||||
}
|
||||
}
|
||||
|
@ -102,6 +102,11 @@ public class ForceHeal : IVerb
|
||||
|
||||
var ini = meta.LoadIniFile();
|
||||
var state = await _downloadDispatcher.ResolveArchive(ini["General"].ToDictionary(d => d.KeyName, d => d.Value));
|
||||
if (state == null)
|
||||
{
|
||||
_logger.LogError("Cannot resolve state from meta for {File}", file);
|
||||
throw new Exception($"Cannot resolve state from meta for {file}");
|
||||
}
|
||||
|
||||
_logger.LogInformation("Hashing {File}", file.FileName);
|
||||
var hash = await _fileHashCache.FileHashCachedAsync(file, CancellationToken.None);
|
||||
|
@ -1,3 +1,6 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Wabbajack.DTOs.Interventions;
|
||||
|
||||
/// <summary>
|
||||
@ -15,4 +18,11 @@ public interface IUserIntervention
|
||||
/// Whether the interaction has been handled and no longer needs attention
|
||||
/// </summary>
|
||||
bool Handled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Token that can be used to trigger cancellation when Cancel() is called.
|
||||
/// </summary>
|
||||
public CancellationToken Token { get; }
|
||||
|
||||
void SetException(Exception exception);
|
||||
}
|
@ -8,4 +8,5 @@ public abstract class GithubAuthTokenProvider : ITokenProvider<string>
|
||||
public abstract ValueTask<string> Get();
|
||||
public abstract ValueTask SetToken(string val);
|
||||
public abstract ValueTask<bool> Delete();
|
||||
public abstract bool HaveToken();
|
||||
}
|
Loading…
Reference in New Issue
Block a user