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 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;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
@ -7,7 +8,9 @@ using Avalonia.ReactiveUI;
|
|||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using CefNet;
|
using CefNet;
|
||||||
using CefNet.Avalonia;
|
using CefNet.Avalonia;
|
||||||
|
using HtmlAgilityPack;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Wabbajack.DTOs.Logins;
|
||||||
|
|
||||||
namespace Wabbajack.CLI.Browser
|
namespace Wabbajack.CLI.Browser
|
||||||
{
|
{
|
||||||
@ -66,5 +69,72 @@ namespace Wabbajack.CLI.Browser
|
|||||||
_mainWindowViewModel = vm;
|
_mainWindowViewModel = vm;
|
||||||
_browser = browser;
|
_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<VfsIndexFolder>(VfsIndexFolder.MakeCommand);
|
||||||
reg.Register<NexusLogin>(NexusLogin.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;
|
||||||
using System.CommandLine.Invocation;
|
using System.CommandLine.Invocation;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Fizzler.Systems.HtmlAgilityPack;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Wabbajack.CLI.Browser;
|
using Wabbajack.CLI.Browser;
|
||||||
|
using Wabbajack.DTOs.Logins;
|
||||||
|
using Wabbajack.Services.OSIntegrated;
|
||||||
|
|
||||||
namespace Wabbajack.CLI.Verbs;
|
namespace Wabbajack.CLI.Verbs;
|
||||||
|
|
||||||
@ -11,11 +16,13 @@ public class NexusLogin : AVerb
|
|||||||
{
|
{
|
||||||
private readonly ILogger<NexusLogin> _logger;
|
private readonly ILogger<NexusLogin> _logger;
|
||||||
private readonly BrowserHost _host;
|
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;
|
_logger = logger;
|
||||||
_host = host;
|
_host = host;
|
||||||
|
_tokenProvider = tokenProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Command MakeCommand()
|
public static Command MakeCommand()
|
||||||
@ -29,6 +36,79 @@ public class NexusLogin : AVerb
|
|||||||
{
|
{
|
||||||
var browser = await _host.CreateBrowser();
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<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" 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.DependencyInjection.Abstractions" Version="6.0.2-mauipre.1.22054.8" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" 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>();
|
service.AddSingleton<WriteOnlyClient>();
|
||||||
|
|
||||||
// Token Providers
|
// Token Providers
|
||||||
service.AddAllSingleton<ITokenProvider<NexusApiState>, NexusApiTokenProvider>();
|
service.AddAllSingleton<ITokenProvider<NexusApiState>, EncryptedJsonTokenProvider<NexusApiState>, NexusApiTokenProvider>();
|
||||||
service
|
service
|
||||||
.AddAllSingleton<ITokenProvider<LoversLabLoginState>, EncryptedJsonTokenProvider<LoversLabLoginState>,
|
.AddAllSingleton<ITokenProvider<LoversLabLoginState>, EncryptedJsonTokenProvider<LoversLabLoginState>,
|
||||||
LoversLabTokenProvider>();
|
LoversLabTokenProvider>();
|
||||||
|
Loading…
Reference in New Issue
Block a user