mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Added libCef, hooked it into a WPF window. Made NexusAPI raise a message. Implemented encrypted caching routines.
This commit is contained in:
parent
ceebe0b745
commit
a8a344d4be
@ -17,6 +17,7 @@ using ICSharpCode.SharpZipLib.BZip2;
|
||||
using IniParser;
|
||||
using Newtonsoft.Json;
|
||||
using ReactiveUI;
|
||||
using Syroot.Windows.IO;
|
||||
using Wabbajack.Common.StatusFeed;
|
||||
using Wabbajack.Common.StatusFeed.Errors;
|
||||
using YamlDotNet.Serialization;
|
||||
@ -899,5 +900,28 @@ namespace Wabbajack.Common
|
||||
}
|
||||
p.WaitForExit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a file to JSON but in an encrypted format in the user's app local directory.
|
||||
/// The data will be encrypted so that it can only be read by this machine and this user.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="data"></param>
|
||||
public static void ToEcryptedJson<T>(this T data, string key)
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes(data.ToJSON());
|
||||
var encoded = ProtectedData.Protect(bytes, Encoding.UTF8.GetBytes(key), DataProtectionScope.LocalMachine);
|
||||
var path = Path.Combine(KnownFolders.LocalAppData.Path, "Wabbajack", key);
|
||||
File.WriteAllBytes(path, encoded);
|
||||
}
|
||||
|
||||
public static T FromEncryptedJson<T>(string key)
|
||||
{
|
||||
var path = Path.Combine(KnownFolders.LocalAppData.Path, "Wabbajack", key);
|
||||
var bytes = File.ReadAllBytes(path);
|
||||
var decoded = ProtectedData.Unprotect(bytes, Encoding.UTF8.GetBytes(key), DataProtectionScope.LocalMachine);
|
||||
return Encoding.UTF8.GetString(decoded).FromJSONString<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,12 +75,16 @@
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Syroot.KnownFolders">
|
||||
<HintPath>..\..\..\Users\tbald\.nuget\packages\syroot.windows.io.knownfolders\1.2.1\lib\net452\Syroot.KnownFolders.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.Security" />
|
||||
<Reference Include="System.ServiceModel" />
|
||||
<Reference Include="System.Transactions" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
@ -169,6 +173,9 @@
|
||||
<PackageReference Include="ReactiveUI">
|
||||
<Version>10.5.30</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Syroot.Windows.IO.KnownFolders">
|
||||
<Version>1.2.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Data.HashFunction.xxHash">
|
||||
<Version>2.0.0</Version>
|
||||
</PackageReference>
|
||||
|
33
Wabbajack.Lib/LibCefHelpers/Init.cs
Normal file
33
Wabbajack.Lib/LibCefHelpers/Init.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Alphaleonis.Win32.Filesystem;
|
||||
using Wabbajack.Common;
|
||||
|
||||
namespace Wabbajack.Lib.LibCefHelpers
|
||||
{
|
||||
public static class Helpers
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// We bundle the cef libs inside the .exe, we need to extract them before loading any wpf code that requires them
|
||||
/// </summary>
|
||||
public static void ExtractLibs()
|
||||
{
|
||||
if (File.Exists("cefglue.7z") && File.Exists("libcef.dll")) return;
|
||||
|
||||
using (var fs = File.OpenWrite("cefglue.7z"))
|
||||
using (var rs = Assembly.GetExecutingAssembly().GetManifestResourceStream("Wabbajack.Lib.LibCefHelpers.cefglue.7z"))
|
||||
{
|
||||
rs.CopyTo(fs);
|
||||
Utils.Log("Extracting libCef files");
|
||||
}
|
||||
using (var wq = new WorkQueue(1))
|
||||
FileExtractor.ExtractAll(wq, "cefglue.7z", ".");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
BIN
Wabbajack.Lib/LibCefHelpers/cefglue.7z
Normal file
BIN
Wabbajack.Lib/LibCefHelpers/cefglue.7z
Normal file
Binary file not shown.
@ -72,19 +72,12 @@ namespace Wabbajack.Lib.NexusApi
|
||||
Directory.CreateDirectory(cacheFolder);
|
||||
}
|
||||
|
||||
var cacheFile = Path.Combine(cacheFolder, _additionalEntropy);
|
||||
if (File.Exists(cacheFile))
|
||||
try
|
||||
{
|
||||
return Utils.FromEncryptedJson<string>("nexusapikey");
|
||||
}
|
||||
catch (CryptographicException)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Encoding.UTF8.GetString(
|
||||
ProtectedData.Unprotect(File.ReadAllBytes(cacheFile),
|
||||
Encoding.UTF8.GetBytes(_additionalEntropy), DataProtectionScope.CurrentUser));
|
||||
}
|
||||
catch (CryptographicException)
|
||||
{
|
||||
File.Delete(cacheFile);
|
||||
}
|
||||
}
|
||||
|
||||
var env_key = Environment.GetEnvironmentVariable("NEXUSAPIKEY");
|
||||
@ -93,35 +86,36 @@ namespace Wabbajack.Lib.NexusApi
|
||||
return env_key;
|
||||
}
|
||||
|
||||
// open a web socket to receive the api key
|
||||
var guid = Guid.NewGuid();
|
||||
var _websocket = new WebSocket("wss://sso.nexusmods.com")
|
||||
{
|
||||
SslConfiguration =
|
||||
{
|
||||
EnabledSslProtocols = SslProtocols.Tls12
|
||||
}
|
||||
};
|
||||
|
||||
var api_key = new TaskCompletionSource<string>();
|
||||
_websocket.OnMessage += (sender, msg) => { api_key.SetResult(msg.Data); };
|
||||
|
||||
_websocket.Connect();
|
||||
_websocket.Send("{\"id\": \"" + guid + "\", \"appid\": \"" + Consts.AppName + "\"}");
|
||||
|
||||
// open a web browser to get user permission
|
||||
Process.Start($"https://www.nexusmods.com/sso?id={guid}&application=" + Consts.AppName);
|
||||
|
||||
// get the api key from the socket and cache it
|
||||
api_key.Task.Wait();
|
||||
var result = api_key.Task.Result;
|
||||
File.WriteAllBytes(cacheFile, ProtectedData.Protect(Encoding.UTF8.GetBytes(result),
|
||||
Encoding.UTF8.GetBytes(_additionalEntropy), DataProtectionScope.CurrentUser));
|
||||
|
||||
var result = Utils.Log(new RequestNexusAuthorization()).Task.Result;
|
||||
result.ToEcryptedJson("nexusapikey");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> SetupNexusLogin(Action<Uri> browserNavigate)
|
||||
{
|
||||
// open a web socket to receive the api key
|
||||
var guid = Guid.NewGuid();
|
||||
var _websocket = new WebSocket("wss://sso.nexusmods.com")
|
||||
{
|
||||
SslConfiguration =
|
||||
{
|
||||
EnabledSslProtocols = SslProtocols.Tls12
|
||||
}
|
||||
};
|
||||
|
||||
var api_key = new TaskCompletionSource<string>();
|
||||
_websocket.OnMessage += (sender, msg) => { api_key.SetResult(msg.Data); };
|
||||
|
||||
_websocket.Connect();
|
||||
_websocket.Send("{\"id\": \"" + guid + "\", \"appid\": \"" + Consts.AppName + "\"}");
|
||||
|
||||
// open a web browser to get user permission
|
||||
browserNavigate(new Uri($"https://www.nexusmods.com/sso?id={guid}&application=" + Consts.AppName));
|
||||
|
||||
return await api_key.Task;
|
||||
}
|
||||
|
||||
public UserStatus GetUserStatus()
|
||||
{
|
||||
var url = "https://api.nexusmods.com/v1/users/validate.json";
|
||||
|
27
Wabbajack.Lib/NexusApi/RequestNexusAuthorization.cs
Normal file
27
Wabbajack.Lib/NexusApi/RequestNexusAuthorization.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Wabbajack.Common.StatusFeed;
|
||||
|
||||
namespace Wabbajack.Lib.NexusApi
|
||||
{
|
||||
public class RequestNexusAuthorization : AStatusMessage, IUserIntervention
|
||||
{
|
||||
public override string ShortDescription => "Getting User's Nexus API Key";
|
||||
public override string ExtendedDescription { get; }
|
||||
|
||||
private readonly TaskCompletionSource<string> _source = new TaskCompletionSource<string>();
|
||||
public Task<string> Task => _source.Task;
|
||||
|
||||
public void Resume(string apikey)
|
||||
{
|
||||
_source.SetResult(apikey);
|
||||
}
|
||||
public void Cancel()
|
||||
{
|
||||
_source.SetCanceled();
|
||||
}
|
||||
}
|
||||
}
|
@ -117,6 +117,7 @@
|
||||
<Compile Include="CompilationSteps\PatchStockESMs.cs" />
|
||||
<Compile Include="CompilationSteps\Serialization.cs" />
|
||||
<Compile Include="Downloaders\SteamWorkshopDownloader.cs" />
|
||||
<Compile Include="LibCefHelpers\Init.cs" />
|
||||
<Compile Include="MO2Compiler.cs" />
|
||||
<Compile Include="Data.cs" />
|
||||
<Compile Include="Downloaders\AbstractDownloadState.cs" />
|
||||
@ -138,6 +139,7 @@
|
||||
<Compile Include="NexusApi\Dtos.cs" />
|
||||
<Compile Include="NexusApi\NexusApi.cs" />
|
||||
<Compile Include="NexusApi\NexusApiUtils.cs" />
|
||||
<Compile Include="NexusApi\RequestNexusAuthorization.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ReportBuilder.cs" />
|
||||
<Compile Include="StatusMessages\ConfirmUpdateOfExistingInstall.cs" />
|
||||
@ -156,6 +158,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<EmbeddedResource Include="LibCefHelpers\cefglue.7z" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(SolutionDir)\Compression.BSA\Compression.BSA.csproj">
|
||||
@ -181,6 +184,9 @@
|
||||
<PackageReference Include="AlphaFS">
|
||||
<Version>2.2.6</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="CefGlue.Wpf">
|
||||
<Version>75.1.28</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Ceras">
|
||||
<Version>4.1.7</Version>
|
||||
</PackageReference>
|
||||
|
@ -4,6 +4,7 @@ using System.Reflection;
|
||||
using System.Windows;
|
||||
using MahApps.Metro;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Lib.LibCefHelpers;
|
||||
|
||||
namespace Wabbajack
|
||||
{
|
||||
@ -14,7 +15,7 @@ namespace Wabbajack
|
||||
{
|
||||
public App()
|
||||
{
|
||||
// Initialization in MainWindow ctor
|
||||
Helpers.ExtractLibs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ namespace Wabbajack
|
||||
public readonly Lazy<InstallerVM> Installer;
|
||||
public readonly Lazy<ModListGalleryVM> Gallery;
|
||||
public readonly ModeSelectionVM ModeSelectionVM;
|
||||
public readonly WebBrowserVM WebBrowserVM;
|
||||
|
||||
public MainWindowVM(MainWindow mainWindow, MainSettings settings)
|
||||
{
|
||||
@ -42,6 +43,7 @@ namespace Wabbajack
|
||||
Compiler = new Lazy<CompilerVM>(() => new CompilerVM(this));
|
||||
Gallery = new Lazy<ModListGalleryVM>(() => new ModListGalleryVM(this));
|
||||
ModeSelectionVM = new ModeSelectionVM(this);
|
||||
WebBrowserVM = new WebBrowserVM();
|
||||
|
||||
// Set up logging
|
||||
Utils.LogMessages
|
||||
@ -67,7 +69,8 @@ namespace Wabbajack
|
||||
else
|
||||
{
|
||||
// Start on mode selection
|
||||
ActivePane = ModeSelectionVM;
|
||||
//ActivePane = ModeSelectionVM;
|
||||
ActivePane = WebBrowserVM;
|
||||
}
|
||||
}
|
||||
|
||||
|
28
Wabbajack/View Models/WebBrowserVM.cs
Normal file
28
Wabbajack/View Models/WebBrowserVM.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using Wabbajack.Lib;
|
||||
using Xilium.CefGlue.Common;
|
||||
using Xilium.CefGlue.WPF;
|
||||
|
||||
namespace Wabbajack
|
||||
{
|
||||
public class WebBrowserVM : ViewModel
|
||||
{
|
||||
[Reactive]
|
||||
public string Address { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string Instructions { get; set; }
|
||||
|
||||
public BaseCefBrowser Browser { get; internal set; }
|
||||
|
||||
public WebBrowserVM()
|
||||
{
|
||||
Instructions = "Wabbajack Web Browser";
|
||||
}
|
||||
}
|
||||
}
|
@ -33,6 +33,9 @@
|
||||
<DataTemplate DataType="{x:Type local:ModListGalleryVM}">
|
||||
<local:ModListGalleryView />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type local:WebBrowserVM}">
|
||||
<local:WebBrowserView />
|
||||
</DataTemplate>
|
||||
</ContentPresenter.Resources>
|
||||
</ContentPresenter>
|
||||
</mahapps:MetroWindow>
|
||||
|
70
Wabbajack/Views/WebBrowserView.xaml
Normal file
70
Wabbajack/Views/WebBrowserView.xaml
Normal file
@ -0,0 +1,70 @@
|
||||
<UserControl x:Class="Wabbajack.WebBrowserView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
|
||||
xmlns:wabbajack="clr-namespace:Wabbajack"
|
||||
xmlns:wpf="clr-namespace:Xilium.CefGlue.WPF;assembly=Xilium.CefGlue.WPF"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<Color x:Key="TextBackgroundFill">#92000000</Color>
|
||||
<SolidColorBrush x:Key="TextBackgroundFillBrush" Color="{StaticResource TextBackgroundFill}" />
|
||||
<Color x:Key="TextBackgroundHoverFill">#DF000000</Color>
|
||||
<Style x:Key="BackgroundBlurStyle" TargetType="TextBlock">
|
||||
<Setter Property="Background" Value="{StaticResource TextBackgroundFillBrush}" />
|
||||
<Setter Property="Foreground" Value="Transparent" />
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="True">
|
||||
<DataTrigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<ColorAnimation
|
||||
Storyboard.TargetProperty="(TextBlock.Background).(SolidColorBrush.Color)"
|
||||
To="{StaticResource TextBackgroundHoverFill}"
|
||||
Duration="0:0:0.06" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.EnterActions>
|
||||
<DataTrigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<ColorAnimation
|
||||
Storyboard.TargetProperty="(TextBlock.Background).(SolidColorBrush.Color)"
|
||||
To="{StaticResource TextBackgroundFill}"
|
||||
Duration="0:0:0.06" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.ExitActions>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="47" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<wabbajack:TopProgressView
|
||||
Title="{Binding Instructions}"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
ShadowMargin="False" />
|
||||
<Button
|
||||
x:Name="BackButton"
|
||||
Grid.Row="0"
|
||||
Width="30"
|
||||
Height="30"
|
||||
Margin="7,5,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Command="{Binding BackCommand}"
|
||||
Style="{StaticResource IconCircleButtonStyle}"
|
||||
ToolTip="Back to main menu">
|
||||
<iconPacks:PackIconMaterial Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Kind="ArrowLeft" />
|
||||
</Button>
|
||||
<wpf:WpfCefBrowser Grid.Row="1" Address="http://www.wabbajack.org" Name="Browser"></wpf:WpfCefBrowser>
|
||||
</Grid>
|
||||
</UserControl>
|
29
Wabbajack/Views/WebBrowserView.xaml.cs
Normal file
29
Wabbajack/Views/WebBrowserView.xaml.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Wabbajack
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for WebBrowser.xaml
|
||||
/// </summary>
|
||||
public partial class WebBrowserView : UserControl
|
||||
{
|
||||
public WebBrowserView()
|
||||
{
|
||||
InitializeComponent();
|
||||
((WebBrowserVM)DataContext).Browser = Browser;
|
||||
}
|
||||
}
|
||||
}
|
@ -162,6 +162,10 @@
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<Reference Include="Xilium.CefGlue.WPF, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\Users\tbald\.nuget\packages\cefglue.wpf\75.1.28\lib\net472\x64\Xilium.CefGlue.WPF.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml">
|
||||
@ -169,6 +173,7 @@
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Compile Include="Converters\EqualsToBoolConverter.cs" />
|
||||
<Compile Include="View Models\WebBrowserVM.cs" />
|
||||
<Compile Include="Views\Installers\MO2InstallerConfigView.xaml.cs">
|
||||
<DependentUpon>MO2InstallerConfigView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@ -247,6 +252,9 @@
|
||||
<Compile Include="Views\Installers\VortexInstallerConfigView.xaml.cs">
|
||||
<DependentUpon>VortexInstallerConfigView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\WebBrowserView.xaml.cs">
|
||||
<DependentUpon>WebBrowserView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Page Include="Views\Installers\MO2InstallerConfigView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
@ -333,6 +341,10 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\WebBrowserView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
|
Loading…
Reference in New Issue
Block a user