mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
WIP probably going to go with WebView2 instead
This commit is contained in:
parent
f2c6241742
commit
95feacc209
@ -11,57 +11,6 @@ namespace Wabbajack.CLI.Browser;
|
||||
|
||||
public static class BrowserExtensions
|
||||
{
|
||||
public static async Task WaitForReady(this WebView browser)
|
||||
{
|
||||
while (!browser.IsInitialized)
|
||||
{
|
||||
await Task.Delay(250);
|
||||
}
|
||||
|
||||
while (browser.BrowserObject == null)
|
||||
{
|
||||
await Task.Delay(250);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task NavigateTo(this WebView browser, Uri location)
|
||||
{
|
||||
browser.Navigate(location.ToString());
|
||||
await browser.WaitForIdle();
|
||||
}
|
||||
|
||||
public static async Task WaitForIdle(this WebView browser)
|
||||
{
|
||||
while (browser.IsBusy)
|
||||
{
|
||||
await Task.Delay(250);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<Cookie[]> Cookies(this WebView view, string domainEnding, CancellationToken token)
|
||||
{
|
||||
var results = CefCookieManager.GetGlobalManager(null)!;
|
||||
var cookies = await results.GetCookiesAsync(c => c.Domain.EndsWith(domainEnding), token)!;
|
||||
return cookies.Select(c => new Cookie
|
||||
{
|
||||
Domain = c.Domain,
|
||||
Name = c.Name,
|
||||
Path = c.Path,
|
||||
Value = c.Value
|
||||
}).ToArray();
|
||||
}
|
||||
|
||||
public static async Task EvaluateJavaScript(this WebView view, string js)
|
||||
{
|
||||
view.GetMainFrame().ExecuteJavaScript(js, "", 0);
|
||||
}
|
||||
|
||||
public static async Task<HtmlDocument> GetDom(this WebView view, CancellationToken token)
|
||||
{
|
||||
var source = await view.GetMainFrame().GetSourceAsync(token);
|
||||
var doc = new HtmlDocument();
|
||||
doc.LoadHtml(source);
|
||||
return doc;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia;
|
||||
@ -7,7 +8,9 @@ using Avalonia.ReactiveUI;
|
||||
using Avalonia.Threading;
|
||||
using CefNet;
|
||||
using CefNet.Avalonia;
|
||||
using HtmlAgilityPack;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Wabbajack.DTOs.Logins;
|
||||
|
||||
namespace Wabbajack.CLI.Browser
|
||||
{
|
||||
@ -66,5 +69,72 @@ namespace Wabbajack.CLI.Browser
|
||||
_mainWindowViewModel = vm;
|
||||
_browser = browser;
|
||||
}
|
||||
|
||||
public string Instructions
|
||||
{
|
||||
set
|
||||
{
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
_mainWindowViewModel.Instructions = value;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public async Task WaitForReady()
|
||||
{
|
||||
while (!_browser.IsInitialized)
|
||||
{
|
||||
await Task.Delay(250);
|
||||
}
|
||||
|
||||
while (_browser.BrowserObject == null)
|
||||
{
|
||||
await Task.Delay(250);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task NavigateTo(Uri location)
|
||||
{
|
||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
_browser.Navigate(location.ToString());
|
||||
});
|
||||
await WaitForIdle();
|
||||
}
|
||||
|
||||
public async Task WaitForIdle()
|
||||
{
|
||||
while (_browser.IsBusy)
|
||||
{
|
||||
await Task.Delay(250);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Cookie[]> Cookies(string domainEnding, CancellationToken token)
|
||||
{
|
||||
var results = CefCookieManager.GetGlobalManager(null)!;
|
||||
var cookies = await results.GetCookiesAsync(c => c.Domain.EndsWith(domainEnding), token)!;
|
||||
return cookies.Select(c => new Cookie
|
||||
{
|
||||
Domain = c.Domain,
|
||||
Name = c.Name,
|
||||
Path = c.Path,
|
||||
Value = c.Value
|
||||
}).ToArray();
|
||||
}
|
||||
|
||||
public async Task EvaluateJavaScript(string js)
|
||||
{
|
||||
_browser.GetMainFrame().ExecuteJavaScript(js, "", 0);
|
||||
}
|
||||
|
||||
public async Task<HtmlDocument> GetDom(CancellationToken token)
|
||||
{
|
||||
var source = await _browser.GetMainFrame().GetSourceAsync(token);
|
||||
var doc = new HtmlDocument();
|
||||
doc.LoadHtml(source);
|
||||
return doc;
|
||||
}
|
||||
}
|
||||
}
|
@ -97,6 +97,6 @@ internal class Program
|
||||
reg.Register<VfsIndexFolder>(VfsIndexFolder.MakeCommand);
|
||||
reg.Register<NexusLogin>(NexusLogin.MakeCommand);
|
||||
|
||||
return await service!.Run(args);
|
||||
return await service.Run(args);
|
||||
}
|
||||
}
|
@ -1,9 +1,14 @@
|
||||
using System;
|
||||
using System.CommandLine;
|
||||
using System.CommandLine.Invocation;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Fizzler.Systems.HtmlAgilityPack;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Wabbajack.CLI.Browser;
|
||||
using Wabbajack.DTOs.Logins;
|
||||
using Wabbajack.Services.OSIntegrated;
|
||||
|
||||
namespace Wabbajack.CLI.Verbs;
|
||||
|
||||
@ -11,11 +16,13 @@ public class NexusLogin : AVerb
|
||||
{
|
||||
private readonly ILogger<NexusLogin> _logger;
|
||||
private readonly BrowserHost _host;
|
||||
private readonly EncryptedJsonTokenProvider<NexusApiState> _tokenProvider;
|
||||
|
||||
public NexusLogin(ILogger<NexusLogin> logger, BrowserHost host)
|
||||
public NexusLogin(ILogger<NexusLogin> logger, BrowserHost host, EncryptedJsonTokenProvider<NexusApiState> tokenProvider)
|
||||
{
|
||||
_logger = logger;
|
||||
_host = host;
|
||||
_tokenProvider = tokenProvider;
|
||||
}
|
||||
|
||||
public static Command MakeCommand()
|
||||
@ -29,6 +36,79 @@ public class NexusLogin : AVerb
|
||||
{
|
||||
var browser = await _host.CreateBrowser();
|
||||
|
||||
token.ThrowIfCancellationRequested();
|
||||
|
||||
browser.Instructions = "Please log into the Nexus";
|
||||
|
||||
await browser.WaitForReady();
|
||||
|
||||
await browser.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"));
|
||||
|
||||
|
||||
Cookie[] cookies = { };
|
||||
while (true)
|
||||
{
|
||||
cookies = await browser.Cookies("nexusmods.com", token);
|
||||
if (cookies.Any(c => c.Name == "member_id"))
|
||||
break;
|
||||
|
||||
token.ThrowIfCancellationRequested();
|
||||
await Task.Delay(500, token);
|
||||
}
|
||||
|
||||
browser.Instructions = "Getting API Key...";
|
||||
|
||||
await browser.NavigateTo(new Uri("https://www.nexusmods.com/users/myaccount?tab=api"));
|
||||
|
||||
var key = "";
|
||||
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
key = (await browser.GetDom(token))
|
||||
.DocumentNode
|
||||
.QuerySelectorAll("input[value=wabbajack]")
|
||||
.SelectMany(p => p.ParentNode.ParentNode.QuerySelectorAll("textarea.application-key"))
|
||||
.Select(node => node.InnerHtml)
|
||||
.FirstOrDefault() ?? "";
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
break;
|
||||
|
||||
try
|
||||
{
|
||||
await browser.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;"
|
||||
);
|
||||
browser.Instructions = "Generating API Key, Please Wait...";
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
token.ThrowIfCancellationRequested();
|
||||
await Task.Delay(500, token);
|
||||
}
|
||||
|
||||
browser.Instructions = "Success, saving information...";
|
||||
await _tokenProvider.SetToken(new NexusApiState
|
||||
{
|
||||
Cookies = cookies,
|
||||
ApiKey = key
|
||||
});
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.40" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.2-mauipre.1.22054.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.2-mauipre.1.22054.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.2-mauipre.1.22054.8" />
|
||||
|
@ -113,7 +113,7 @@ public static class ServiceExtensions
|
||||
service.AddSingleton<WriteOnlyClient>();
|
||||
|
||||
// Token Providers
|
||||
service.AddAllSingleton<ITokenProvider<NexusApiState>, NexusApiTokenProvider>();
|
||||
service.AddAllSingleton<ITokenProvider<NexusApiState>, EncryptedJsonTokenProvider<NexusApiState>, NexusApiTokenProvider>();
|
||||
service
|
||||
.AddAllSingleton<ITokenProvider<LoversLabLoginState>, EncryptedJsonTokenProvider<LoversLabLoginState>,
|
||||
LoversLabTokenProvider>();
|
||||
|
Loading…
Reference in New Issue
Block a user