Merge pull request #487 from wabbajack-tools/beth-net-better-login

Better Bethesda.NET login
This commit is contained in:
Timothy Baldridge 2020-02-07 06:46:41 -07:00 committed by GitHub
commit 268b7335c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 265 additions and 30 deletions

View File

@ -6,6 +6,7 @@
* Adding `matchAll=<archive-name>` to a *mods's* `meta.ini` file will result in unconditional patching for all unmatching files or BSAs in
that mod (issue #465)
* Added support for non-premium Nexus downloads via manual downloading through the in-app browser.
* Downloads from Bethesda.NET are now supported. Can login via SkyrimSE or Fallout 4.
=======

View File

@ -87,6 +87,8 @@ namespace Wabbajack.Common
}
}
public bool IsInstalled => GameLocation() != null;
public string MainExecutable { get; internal set; }
public string GameLocation()

View File

@ -7,16 +7,18 @@ import frida
import sys
from subprocess import Popen, PIPE
import psutil, time, json
from pathlib import Path
known_headers = {}
shutdown = False
def on_message(message, data):
msg_type, msg_data = message["payload"]
if msg_type == "header":
header, value = msg_data.split(": ");
header, value = msg_data.split(": ")
if header not in known_headers:
known_headers[header] = value;
known_headers[header] = value
if msg_type == "data":
try:
data = json.loads(msg_data)
@ -25,6 +27,7 @@ def on_message(message, data):
except:
return
def main(target_process):
session = frida.attach(target_process)
@ -65,17 +68,35 @@ def main(target_process):
script.on('message', on_message)
script.load()
while not shutdown:
time.sleep(0.5);
while not shutdown and psutil.pid_exists(target_process):
time.sleep(0.5)
session.detach()
sys.exit(1)
def wait_for_game(name):
def wait_for_game(started, name):
no_exe = 0
parent_path = Path(started).parent
while True:
time.sleep(1);
found = False
time.sleep(1)
for proc in psutil.process_iter():
try:
if Path(proc.exe()).parent == parent_path:
no_exe = 0
found = True
except:
pass
if proc.name() == name:
return proc.pid;
return proc.pid
if not found:
print("Not Found " + str(no_exe))
no_exe += 1
if no_exe == 3:
sys.exit(1)
def shutdown_and_print(data):
global shutdown
@ -85,19 +106,18 @@ def shutdown_and_print(data):
for proc in psutil.process_iter():
if proc.pid == pid:
proc.kill();
proc.kill()
break
shutdown = True;
shutdown = True
if __name__ == '__main__':
start = """C:\Steam\steamapps\common\Skyrim Special Edition\SkyrimSE.exe"""
wait_for = "SkyrimSE.exe"
if len(sys.argv) == 3:
start = sys.argv[1];
start = sys.argv[1]
wait_for = sys.argv[2]
target_process = Popen([start])
pid = wait_for_game(wait_for);
pid = wait_for_game(start, wait_for)
main(pid)

View File

@ -63,13 +63,14 @@ namespace Wabbajack.Lib.Downloaders
await Utils.Log(new RequestBethesdaNetLogin()).Task;
}
public static async Task<BethesdaNetData> Login()
public static async Task<BethesdaNetData> Login(Game game)
{
var game = Path.Combine(Game.SkyrimSpecialEdition.MetaData().GameLocation(), "SkyrimSE.exe");
var metadata = game.MetaData();
var gamePath = Path.Combine(metadata.GameLocation(), metadata.MainExecutable);
var info = new ProcessStartInfo
{
FileName = @"Downloaders\BethesdaNet\bethnetlogin.exe",
Arguments = $"\"{game}\" SkyrimSE.exe",
Arguments = $"\"{gamePath}\" {metadata.MainExecutable}",
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
@ -87,10 +88,17 @@ namespace Wabbajack.Lib.Downloaders
last_line = line;
}
try
{
var result = last_line.FromJSONString<BethesdaNetData>();
result.ToEcryptedJson(DataName);
return result;
}
catch (Exception _)
{
return null;
}
}
public AbstractDownloadState GetDownloaderState(string url)
{

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 KiB

View File

@ -0,0 +1,64 @@
using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Threading.Tasks;
using CefSharp;
using CefSharp.Wpf;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Wabbajack.Common;
using Wabbajack.Lib;
using Wabbajack.Lib.Downloaders;
using Wabbajack.Lib.WebAutomation;
namespace Wabbajack
{
public class BethesdaNetLoginVM : ViewModel, IBackNavigatingVM
{
[Reactive]
public string Instructions { get; set; }
[Reactive]
public ViewModel NavigateBackTarget { get; set; }
[Reactive]
public ReactiveCommand<Unit, Unit> BackCommand { get; set; }
public ReactiveCommand<Unit, Unit> LoginViaSkyrimSE { get; }
public ReactiveCommand<Unit, Unit> LoginViaFallout4 { get; }
private Subject<bool> LoggingIn = new Subject<bool>();
private BethesdaNetLoginVM()
{
Instructions = "Login to Bethesda.NET in-game...";
LoginViaSkyrimSE = ReactiveCommand.CreateFromTask(async () =>
{
LoggingIn.OnNext(true);
Instructions = "Starting Skyrim Special Edition...";
await BethesdaNetDownloader.Login(Game.SkyrimSpecialEdition);
LoggingIn.OnNext(false);
await BackCommand.Execute();
}, Game.SkyrimSpecialEdition.MetaData().IsInstalled
? LoggingIn.Select(e => !e).StartWith(true)
: Observable.Return(false));
LoginViaFallout4 = ReactiveCommand.CreateFromTask(async () =>
{
LoggingIn.OnNext(true);
Instructions = "Starting Fallout 4...";
await BethesdaNetDownloader.Login(Game.Fallout4);
LoggingIn.OnNext(false);
await BackCommand.Execute();
}, Game.Fallout4.MetaData().IsInstalled
? LoggingIn.Select(e => !e).StartWith(true)
: Observable.Return(false));
}
public static async Task<BethesdaNetLoginVM> GetNew()
{
// Make sure libraries are extracted first
return new BethesdaNetLoginVM();
}
}
}

View File

@ -55,6 +55,21 @@ namespace Wabbajack
MainWindow.NavigateTo(oldPane);
}
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)
{
switch (msg)
@ -71,8 +86,7 @@ namespace Wabbajack
await WrapBrowserJob(msg, (vm, cancel) => HandleManualNexusDownload(vm, cancel, c));
break;
case RequestBethesdaNetLogin c:
var data = await BethesdaNetDownloader.Login();
c.Resume(data);
await WrapBethesdaNetLogin(c);
break;
case AbstractNeedsLoginDownloader.RequestSiteLogin c:
await WrapBrowserJob(msg, async (vm, cancel) =>

View File

@ -0,0 +1,105 @@
<UserControl x:Class="Wabbajack.BethesdaNetLoginView"
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"
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>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="100"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock TextWrapping="Wrap" Margin = "10" Grid.Row="0" Grid.ColumnSpan="2" FontSize="20" Text="Login with your game of choice. Clicking the button will launch the game. Once at the main menu, load the `Mods` menu. The game will close once you've logged into Bethesda.NET"></TextBlock>
<Button Grid.Row="1" Grid.Column="0" Command="{Binding LoginViaSkyrimSE}">
<Image Source="../../Resources/GameGridIcons/SkyrimSpecialEdition.png">
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5" />
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Button>
<Button Grid.Row="1" Grid.Column="1" Command="{Binding LoginViaFallout4}">
<Image Source="../../Resources/GameGridIcons/Fallout4.png">
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5" />
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Button>
</Grid>
</Grid>
</UserControl>

View File

@ -0,0 +1,13 @@
using System.Windows.Controls;
namespace Wabbajack
{
public partial class BethesdaNetLoginView : UserControl
{
public BethesdaNetLoginView()
{
InitializeComponent();
}
}
}

View File

@ -37,6 +37,9 @@
<DataTemplate DataType="{x:Type local:WebBrowserVM}">
<local:WebBrowserView />
</DataTemplate>
<DataTemplate DataType="{x:Type local:BethesdaNetLoginVM}">
<local:BethesdaNetLoginView />
</DataTemplate>
<DataTemplate DataType="{x:Type local:SettingsVM}">
<local:SettingsView ViewModel="{Binding}" />
</DataTemplate>

View File

@ -39,6 +39,8 @@
<ItemGroup>
<None Remove="Readme.md" />
<None Remove="Resources\GameGridIcons\Fallout4.png" />
<None Remove="Resources\GameGridIcons\SkyrimSpecialEdition.png" />
<None Remove="Resources\MO2Button.png" />
<None Remove="Resources\VortexButton.png" />
<None Remove="Resources\Wabba_Ded.png" />
@ -78,11 +80,14 @@
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\GameGridIcons\Fallout4.png" />
<Resource Include="Resources\GameGridIcons\SkyrimSpecialEdition.png" />
<Resource Include="Resources\MO2Button.png" />
<Resource Include="Resources\VortexButton.png" />
<Resource Include="Resources\Wabba_Ded.png" />
<Resource Include="Resources\Wabba_Mouth.png" />
<Resource Include="Resources\Wabba_Mouth_No_Text.png" />
</ItemGroup>
<ItemGroup>