mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
commit
1ab9302a6c
@ -115,79 +115,22 @@ csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||
# Wrapping preferences
|
||||
csharp_preserve_single_line_statements = true
|
||||
csharp_preserve_single_line_blocks = true
|
||||
|
||||
###############################
|
||||
# C# Async Rules #
|
||||
###############################
|
||||
# CS4014: Task not awaited
|
||||
dotnet_diagnostic.CS4014.severity = error
|
||||
|
||||
# CS1998: Async function does not contain await
|
||||
dotnet_diagnostic.CS1998.severity = silent
|
||||
|
||||
###############################
|
||||
# C# Nullability #
|
||||
# Other #
|
||||
###############################
|
||||
# CS8602: Dereference of a possibly null reference.
|
||||
dotnet_diagnostic.CS8602.severity = error
|
||||
|
||||
# CS8600: Converting null literal or possible null value to non-nullable type.
|
||||
dotnet_diagnostic.CS8600.severity = error
|
||||
# CS1591: Missing XML comment for publicly visible type or member
|
||||
dotnet_diagnostic.CS1591.severity = silent
|
||||
|
||||
# CS8619: Nullability of reference types in value doesn't match target type.
|
||||
dotnet_diagnostic.CS8619.severity = error
|
||||
|
||||
# CS8603: Possible null reference return.
|
||||
dotnet_diagnostic.CS8603.severity = error
|
||||
|
||||
# CS8625: Cannot convert null literal to non-nullable reference type.
|
||||
dotnet_diagnostic.CS8625.severity = error
|
||||
|
||||
# CS8653: A default expression introduces a null value for a type parameter.
|
||||
dotnet_diagnostic.CS8653.severity = silent
|
||||
|
||||
# CS8601: Possible null reference assignment.
|
||||
dotnet_diagnostic.CS8601.severity = error
|
||||
|
||||
# CS8604: Possible null reference argument.
|
||||
dotnet_diagnostic.CS8604.severity = error
|
||||
|
||||
# CS8622: Nullability of reference types in type of parameter doesn't match the target delegate.
|
||||
dotnet_diagnostic.CS8622.severity = error
|
||||
|
||||
# CS8610: Nullability of reference types in type of parameter doesn't match overridden member.
|
||||
dotnet_diagnostic.CS8610.severity = error
|
||||
|
||||
# CS8618: Non-nullable field is uninitialized. Consider declaring as nullable.
|
||||
dotnet_diagnostic.CS8618.severity = error
|
||||
|
||||
# CS8629: Nullable value type may be null.
|
||||
dotnet_diagnostic.CS8629.severity = error
|
||||
|
||||
# CS8620: Argument cannot be used for parameter due to differences in the nullability of reference types.
|
||||
dotnet_diagnostic.CS8620.severity = error
|
||||
|
||||
# CS8614: Nullability of reference types in type of parameter doesn't match implicitly implemented member.
|
||||
dotnet_diagnostic.CS8614.severity = error
|
||||
|
||||
# CS8617: Nullability of reference types in type of parameter doesn't match implemented member.
|
||||
dotnet_diagnostic.CS8617.severity = error
|
||||
|
||||
# CS8611: Nullability of reference types in type of parameter doesn't match partial method declaration.
|
||||
dotnet_diagnostic.CS8611.severity = error
|
||||
|
||||
# CS8597: Thrown value may be null.
|
||||
dotnet_diagnostic.CS8597.severity = error
|
||||
|
||||
# CS8609: Nullability of reference types in return type doesn't match overridden member.
|
||||
dotnet_diagnostic.CS8609.severity = error
|
||||
|
||||
# CS8714: The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'notnull' constraint.
|
||||
dotnet_diagnostic.CS8714.severity = error
|
||||
|
||||
# CS8605: Unboxing a possibly null value.
|
||||
dotnet_diagnostic.CS8605.severity = error
|
||||
|
||||
# CS8613: Nullability of reference types in return type doesn't match implicitly implemented member.
|
||||
dotnet_diagnostic.CS8613.severity = error
|
||||
|
||||
# CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
|
||||
dotnet_diagnostic.CS8632.severity = error
|
||||
dotnet_diagnostic.CS1701.severity = silent
|
||||
dotnet_diagnostic.CS1702.severity = silent
|
||||
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -366,3 +366,9 @@ MigrationBackup/
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
/.idea
|
||||
|
||||
Compression.BSA/Compression.BSA.xml
|
||||
|
||||
Wabbajack.Common/Wabbajack.Common.xml
|
||||
|
||||
Wabbajack.VirtualFileSystem/Wabbajack.VirtualFileSystem.xml
|
||||
|
@ -93,10 +93,11 @@ namespace Compression.BSA.Test
|
||||
_tempDir.CreateDirectory();
|
||||
|
||||
TestContext.WriteLine($"Reading {bsa}");
|
||||
var tempFile = ((RelativePath)"tmp.bsa").RelativeToEntryPoint();
|
||||
await using var tempFolder = await TempFolder.Create();
|
||||
var tempFile = tempFolder.Dir.Combine("test.bsa");
|
||||
var size = bsa.Size;
|
||||
|
||||
await using var a = await BSADispatch.OpenRead(bsa);
|
||||
var a = await BSADispatch.OpenRead(bsa);
|
||||
await a.Files.PMap(Queue, async file =>
|
||||
{
|
||||
var absName = _tempDir.Combine(file.Path);
|
||||
@ -132,7 +133,7 @@ namespace Compression.BSA.Test
|
||||
}
|
||||
|
||||
TestContext.WriteLine($"Verifying {bsa}");
|
||||
await using var b = await BSADispatch.OpenRead(tempFile);
|
||||
var b = await BSADispatch.OpenRead(tempFile);
|
||||
TestContext.WriteLine($"Performing A/B tests on {bsa}");
|
||||
Assert.Equal(a.State.ToJson(), b.State.ToJson());
|
||||
|
||||
|
@ -19,7 +19,7 @@ namespace Compression.BSA
|
||||
if (fourcc == TES3Reader.TES3_MAGIC)
|
||||
return await TES3Reader.Load(filename);
|
||||
if (fourcc == "BSA\0")
|
||||
return await BSAReader.Load(filename);
|
||||
return await BSAReader.LoadWithRetry(filename);
|
||||
if (fourcc == "BTDX")
|
||||
return await BA2Reader.Load(filename);
|
||||
throw new InvalidDataException("Filename is not a .bsa or .ba2, magic " + fourcc);
|
||||
|
@ -50,7 +50,7 @@ namespace Compression.BSA
|
||||
Miscellaneous = 0x100
|
||||
}
|
||||
|
||||
public class BSAReader : IAsyncDisposable, IBSAReader
|
||||
public class BSAReader : IBSAReader
|
||||
{
|
||||
internal uint _archiveFlags;
|
||||
internal uint _fileCount;
|
||||
@ -60,8 +60,6 @@ namespace Compression.BSA
|
||||
internal uint _folderRecordOffset;
|
||||
private List<FolderRecord> _folders;
|
||||
internal string _magic;
|
||||
private BinaryReader _rdr;
|
||||
private Stream _stream;
|
||||
internal uint _totalFileNameLength;
|
||||
internal uint _totalFolderNameLength;
|
||||
internal uint _version;
|
||||
@ -79,15 +77,21 @@ namespace Compression.BSA
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static async ValueTask<BSAReader> Load(AbsolutePath filename)
|
||||
public static async ValueTask<BSAReader> LoadWithRetry(AbsolutePath filename)
|
||||
{
|
||||
using var stream = await filename.OpenRead();
|
||||
using var br = new BinaryReader(stream);
|
||||
var bsa = new BSAReader {_rdr = br, _stream = stream, _fileName = filename};
|
||||
await bsa.LoadHeaders();
|
||||
bsa._rdr = null;
|
||||
bsa._stream = null;
|
||||
var bsa = new BSAReader { _fileName = filename };
|
||||
bsa.LoadHeaders(br);
|
||||
return bsa;
|
||||
}
|
||||
|
||||
public static BSAReader Load(AbsolutePath filename)
|
||||
{
|
||||
using var stream = File.Open(filename.ToString(), FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var br = new BinaryReader(stream);
|
||||
var bsa = new BSAReader { _fileName = filename };
|
||||
bsa.LoadHeaders(br);
|
||||
return bsa;
|
||||
}
|
||||
|
||||
@ -107,7 +111,7 @@ namespace Compression.BSA
|
||||
|
||||
public ArchiveFlags ArchiveFlags => (ArchiveFlags) _archiveFlags;
|
||||
|
||||
public FileFlags FileFlags => (FileFlags) _archiveFlags;
|
||||
public FileFlags FileFlags => (FileFlags)_fileFlags;
|
||||
|
||||
|
||||
public bool HasFolderNames => (_archiveFlags & 0x1) > 0;
|
||||
@ -127,42 +131,38 @@ namespace Compression.BSA
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
private void LoadHeaders(BinaryReader rdr)
|
||||
{
|
||||
}
|
||||
|
||||
private async ValueTask LoadHeaders()
|
||||
{
|
||||
var fourcc = Encoding.ASCII.GetString(_rdr.ReadBytes(4));
|
||||
var fourcc = Encoding.ASCII.GetString(rdr.ReadBytes(4));
|
||||
|
||||
if (fourcc != "BSA\0")
|
||||
throw new InvalidDataException("Archive is not a BSA");
|
||||
|
||||
_magic = fourcc;
|
||||
_version = _rdr.ReadUInt32();
|
||||
_folderRecordOffset = _rdr.ReadUInt32();
|
||||
_archiveFlags = _rdr.ReadUInt32();
|
||||
_folderCount = _rdr.ReadUInt32();
|
||||
_fileCount = _rdr.ReadUInt32();
|
||||
_totalFolderNameLength = _rdr.ReadUInt32();
|
||||
_totalFileNameLength = _rdr.ReadUInt32();
|
||||
_fileFlags = _rdr.ReadUInt32();
|
||||
_version = rdr.ReadUInt32();
|
||||
_folderRecordOffset = rdr.ReadUInt32();
|
||||
_archiveFlags = rdr.ReadUInt32();
|
||||
_folderCount = rdr.ReadUInt32();
|
||||
_fileCount = rdr.ReadUInt32();
|
||||
_totalFolderNameLength = rdr.ReadUInt32();
|
||||
_totalFileNameLength = rdr.ReadUInt32();
|
||||
_fileFlags = rdr.ReadUInt32();
|
||||
|
||||
LoadFolderRecords();
|
||||
LoadFolderRecords(rdr);
|
||||
}
|
||||
|
||||
private void LoadFolderRecords()
|
||||
private void LoadFolderRecords(BinaryReader rdr)
|
||||
{
|
||||
_folders = new List<FolderRecord>();
|
||||
for (var idx = 0; idx < _folderCount; idx += 1)
|
||||
_folders.Add(new FolderRecord(this, _rdr));
|
||||
_folders.Add(new FolderRecord(this, rdr));
|
||||
|
||||
foreach (var folder in _folders)
|
||||
folder.LoadFileRecordBlock(this, _rdr);
|
||||
folder.LoadFileRecordBlock(this, rdr);
|
||||
|
||||
foreach (var folder in _folders)
|
||||
foreach (var file in folder._files)
|
||||
file.LoadFileRecord(this, folder, file, _rdr);
|
||||
file.LoadFileRecord(this, folder, file, rdr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Platforms>x64</Platforms>
|
||||
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Platforms>x64</Platforms>
|
||||
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
|
||||
<Version>3.0</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DocumentationFile>Compression.BSA.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Genbox.AlphaFS" Version="2.2.2.1" />
|
||||
|
@ -6,7 +6,7 @@ using Wabbajack.Common;
|
||||
|
||||
namespace Compression.BSA
|
||||
{
|
||||
public interface IBSAReader : IAsyncDisposable
|
||||
public interface IBSAReader
|
||||
{
|
||||
/// <summary>
|
||||
/// The files defined by the archive
|
||||
|
5
Directory.Build.props
Normal file
5
Directory.Build.props
Normal file
@ -0,0 +1,5 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<WarningsAsErrors>nullable</WarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
</Project>
|
@ -14,7 +14,7 @@ namespace Wabbajack.CLI.Verbs
|
||||
|
||||
protected override async Task<ExitCode> Run()
|
||||
{
|
||||
await using var bsa = await BSADispatch.OpenRead(Input.RelativeTo(AbsolutePath.GetCurrentDirectory()));
|
||||
var bsa = await BSADispatch.OpenRead(Input.RelativeTo(AbsolutePath.GetCurrentDirectory()));
|
||||
bsa.Dump(Console.WriteLine);
|
||||
return ExitCode.Ok;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Wabbajack.Common;
|
||||
|
||||
namespace Wabbajack
|
||||
{
|
||||
@ -12,9 +13,15 @@ namespace Wabbajack
|
||||
await task.ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
when (onException != null)
|
||||
{
|
||||
onException(ex);
|
||||
if (onException == null)
|
||||
{
|
||||
Utils.Error(ex);
|
||||
}
|
||||
else
|
||||
{
|
||||
onException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@ -52,7 +53,7 @@ namespace Wabbajack.Common
|
||||
|
||||
public static void ToJson<T>(this T obj, Stream stream)
|
||||
{
|
||||
using var tw = new StreamWriter(stream, Encoding.UTF8, leaveOpen: true);
|
||||
using var tw = new StreamWriter(stream, Encoding.UTF8, bufferSize: 1024, leaveOpen: true);
|
||||
using var writer = new JsonTextWriter(tw);
|
||||
var ser = JsonSerializer.Create(JsonSettings);
|
||||
ser.Serialize(writer, obj);
|
||||
@ -81,7 +82,7 @@ namespace Wabbajack.Common
|
||||
|
||||
public static T FromJson<T>(this Stream stream, bool genericReader = false)
|
||||
{
|
||||
using var tr = new StreamReader(stream, Encoding.UTF8, leaveOpen: true);
|
||||
using var tr = new StreamReader(stream, Encoding.UTF8, bufferSize: 1024, detectEncodingFromByteOrderMarks: false, leaveOpen: true);
|
||||
using var reader = new JsonTextReader(tr);
|
||||
var ser = JsonSerializer.Create(genericReader ? GenericJsonSettings : JsonSettings);
|
||||
var result = ser.Deserialize<T>(reader);
|
||||
@ -244,14 +245,12 @@ namespace Wabbajack.Common
|
||||
|
||||
public class IPathConverter : JsonConverter<IPath>
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, IPath value, JsonSerializer serializer)
|
||||
public override void WriteJson(JsonWriter writer, [AllowNull] IPath value, JsonSerializer serializer)
|
||||
{
|
||||
writer.WriteValue(Enum.GetName(typeof(Game), value));
|
||||
}
|
||||
|
||||
public override IPath ReadJson(JsonReader reader, Type objectType, IPath existingValue,
|
||||
bool hasExistingValue,
|
||||
JsonSerializer serializer)
|
||||
public override IPath ReadJson(JsonReader reader, Type objectType, [AllowNull] IPath existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
// Backwards compatibility support
|
||||
var str = reader.Value?.ToString();
|
||||
@ -260,7 +259,6 @@ namespace Wabbajack.Common
|
||||
if (Path.IsPathRooted(str))
|
||||
return (AbsolutePath)str;
|
||||
return (RelativePath)str;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -439,7 +439,8 @@ namespace Wabbajack.Common
|
||||
/// <param name="coll"></param>
|
||||
/// <param name="func"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<TOut> Keep<TIn, TOut>(this IEnumerable<TIn> coll, Func<TIn, TOut> func) where TOut : IComparable<TOut>
|
||||
public static IEnumerable<TOut> Keep<TIn, TOut>(this IEnumerable<TIn> coll, Func<TIn, TOut> func)
|
||||
where TOut : struct, IComparable<TOut>
|
||||
{
|
||||
return coll.Select(func).Where(v => v.CompareTo(default) != 0);
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Platforms>x64</Platforms>
|
||||
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
|
||||
<Nullable>enable</Nullable>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<PackageVersion>2.0.9.1</PackageVersion>
|
||||
<PackageVersion>3.0</PackageVersion>
|
||||
<Title>Wabbajack Common Lib</Title>
|
||||
<Authors>Wabbajack Team</Authors>
|
||||
<Copyright>2020</Copyright>
|
||||
@ -14,6 +14,11 @@
|
||||
<PackageLicenseUrl>https://raw.githubusercontent.com/wabbajack-tools/wabbajack/master/LICENSE.txt</PackageLicenseUrl>
|
||||
<PackageIconUrl>https://www.wabbajack.org/favicon.ico</PackageIconUrl>
|
||||
<RepositoryUrl>https://github.com/wabbajack-tools/wabbajack</RepositoryUrl>
|
||||
<Version>3.0</Version>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DocumentationFile>Wabbajack.Common.xml</DocumentationFile>
|
||||
<NoWarn></NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="7z.dll.gz" />
|
||||
|
@ -18,20 +18,20 @@ namespace Wabbajack.Lib.AuthorApi
|
||||
return new Client(client);
|
||||
}
|
||||
|
||||
private Client(Common.Http.Client client)
|
||||
private Client(Wabbajack.Lib.Http.Client client)
|
||||
{
|
||||
_client = client;
|
||||
}
|
||||
|
||||
public static async Task<Common.Http.Client> GetAuthorizedClient(string? apiKey = null)
|
||||
public static async Task<Wabbajack.Lib.Http.Client> GetAuthorizedClient(string? apiKey = null)
|
||||
{
|
||||
var client = new Common.Http.Client();
|
||||
var client = new Wabbajack.Lib.Http.Client();
|
||||
client.Headers.Add(("X-API-KEY", await GetAPIKey(apiKey)));
|
||||
return client;
|
||||
}
|
||||
|
||||
public static string? ApiKeyOverride = null;
|
||||
private Common.Http.Client _client;
|
||||
private Wabbajack.Lib.Http.Client _client;
|
||||
|
||||
public static async ValueTask<string> GetAPIKey(string? apiKey = null)
|
||||
{
|
||||
|
@ -45,9 +45,9 @@ using Wabbajack.Lib.Downloaders;
|
||||
|
||||
public class ClientAPI
|
||||
{
|
||||
public static async Task<Common.Http.Client> GetClient()
|
||||
public static async Task<Wabbajack.Lib.Http.Client> GetClient()
|
||||
{
|
||||
var client = new Common.Http.Client();
|
||||
var client = new Wabbajack.Lib.Http.Client();
|
||||
client.Headers.Add((Consts.MetricsKeyHeader, await Metrics.GetMetricsKey()));
|
||||
return client;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ namespace Wabbajack.Lib.CompilationSteps
|
||||
|
||||
public DeconstructBSAs(ACompiler compiler) : base(compiler)
|
||||
{
|
||||
_mo2Compiler = (MO2Compiler) compiler;
|
||||
_mo2Compiler = (MO2Compiler)compiler;
|
||||
_includeDirectly = _mo2Compiler.ModInis.Where(kv =>
|
||||
{
|
||||
var general = kv.Value.General;
|
||||
@ -60,10 +60,10 @@ namespace Wabbajack.Lib.CompilationSteps
|
||||
if (_includeDirectly.Any(path => source.Path.StartsWith(path)))
|
||||
defaultInclude = true;
|
||||
|
||||
if (source.AbsolutePath.Size >= (long) 2 << 31)
|
||||
if (source.AbsolutePath.Size >= (long)2 << 31)
|
||||
{
|
||||
await using var bsa = await BSADispatch.OpenRead(source.AbsolutePath);
|
||||
if (bsa.State is BSAStateObject)
|
||||
var bsaTest = await BSADispatch.OpenRead(source.AbsolutePath);
|
||||
if (bsaTest.State is BSAStateObject)
|
||||
{
|
||||
Utils.Error(
|
||||
$"BSA {source.AbsolutePath.FileName} is over 2GB in size, very few programs (Including Wabbajack) can create BSA files this large without causing CTD issues." +
|
||||
@ -83,7 +83,7 @@ namespace Wabbajack.Lib.CompilationSteps
|
||||
{
|
||||
_cleanup = await source.File.Context.Stage(source.File.Children);
|
||||
}
|
||||
|
||||
|
||||
var matches = await sourceFiles.PMap(_mo2Compiler.Queue, e => _mo2Compiler.RunStack(stack, new RawSourceFile(e, Consts.BSACreationDir.Combine((RelativePath)id, (RelativePath)e.Name))));
|
||||
|
||||
|
||||
@ -95,16 +95,14 @@ namespace Wabbajack.Lib.CompilationSteps
|
||||
}
|
||||
|
||||
CreateBSA directive;
|
||||
await using (var bsa = await BSADispatch.OpenRead(source.AbsolutePath))
|
||||
var bsa = await BSADispatch.OpenRead(source.AbsolutePath);
|
||||
directive = new CreateBSA(
|
||||
state: bsa.State,
|
||||
items: bsa.Files.Select(f => f.State).ToList())
|
||||
{
|
||||
directive = new CreateBSA(
|
||||
state: bsa.State,
|
||||
items: bsa.Files.Select(f => f.State).ToList())
|
||||
{
|
||||
To = source.Path,
|
||||
TempID = (RelativePath)id,
|
||||
};
|
||||
}
|
||||
To = source.Path,
|
||||
TempID = (RelativePath)id,
|
||||
};
|
||||
|
||||
if (_cleanup != null)
|
||||
await _cleanup();
|
||||
|
@ -26,7 +26,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
|
||||
// ToDo
|
||||
// Remove null assignment. Either add nullability to type, or figure way to prepare it safely
|
||||
public Common.Http.Client AuthedClient { get; private set; } = null!;
|
||||
public Wabbajack.Lib.Http.Client AuthedClient { get; private set; } = null!;
|
||||
|
||||
public ReactiveCommand<Unit, Unit> TriggerLogin { get; }
|
||||
public ReactiveCommand<Unit, Unit> ClearLogin { get; }
|
||||
@ -57,8 +57,8 @@ namespace Wabbajack.Lib.Downloaders
|
||||
TriggerLogin = ReactiveCommand.CreateFromTask(
|
||||
execute: () => Utils.CatchAndLog(async () => await Utils.Log(new RequestSiteLogin(this)).Task),
|
||||
canExecute: IsLoggedIn.Select(b => !b).ObserveOnGuiThread());
|
||||
ClearLogin = ReactiveCommand.Create(
|
||||
execute: () => Utils.CatchAndLog(() => Utils.DeleteEncryptedJson(_encryptedKeyName)),
|
||||
ClearLogin = ReactiveCommand.CreateFromTask(
|
||||
execute: () => Utils.CatchAndLog(async () => await Utils.DeleteEncryptedJson(_encryptedKeyName)),
|
||||
canExecute: IsLoggedIn.ObserveOnGuiThread());
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
return cookies;
|
||||
}
|
||||
|
||||
public async Task<Common.Http.Client> GetAuthedClient()
|
||||
public async Task<Wabbajack.Lib.Http.Client> GetAuthedClient()
|
||||
{
|
||||
Helpers.Cookie[] cookies;
|
||||
try
|
||||
|
@ -43,7 +43,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
public BethesdaNetDownloader()
|
||||
{
|
||||
TriggerLogin = ReactiveCommand.CreateFromTask(() => Utils.CatchAndLog(RequestLoginAndCache), IsLoggedIn.Select(b => !b).ObserveOn(RxApp.MainThreadScheduler));
|
||||
ClearLogin = ReactiveCommand.Create(() => Utils.CatchAndLog(() =>Utils.DeleteEncryptedJson(DataName)), IsLoggedIn.ObserveOn(RxApp.MainThreadScheduler));
|
||||
ClearLogin = ReactiveCommand.CreateFromTask(() => Utils.CatchAndLog(async () => await Utils.DeleteEncryptedJson(DataName)), IsLoggedIn.ObserveOn(RxApp.MainThreadScheduler));
|
||||
}
|
||||
|
||||
private static async Task RequestLoginAndCache()
|
||||
@ -216,13 +216,13 @@ namespace Wabbajack.Lib.Downloaders
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<(Common.Http.Client, CDPTree, CollectedBNetInfo)> ResolveDownloadInfo()
|
||||
private async Task<(Wabbajack.Lib.Http.Client, CDPTree, CollectedBNetInfo)> ResolveDownloadInfo()
|
||||
{
|
||||
var info = new CollectedBNetInfo();
|
||||
|
||||
var login_info = await Utils.FromEncryptedJson<BethesdaNetData>(DataName);
|
||||
|
||||
var client = new Common.Http.Client();
|
||||
var client = new Wabbajack.Lib.Http.Client();
|
||||
|
||||
client.Headers.Add(("User-Agent", "bnet"));
|
||||
foreach (var header in login_info.headers.Where(h => h.Key.ToLower().StartsWith("x-")))
|
||||
|
@ -59,7 +59,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
private async Task<HTTPDownloader.State> ToHttpState()
|
||||
{
|
||||
var initialURL = $"https://drive.google.com/uc?id={Id}&export=download";
|
||||
var client = new Common.Http.Client();
|
||||
var client = new Wabbajack.Lib.Http.Client();
|
||||
using var response = await client.GetAsync(initialURL);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
throw new HttpException((int)response.StatusCode, response.ReasonPhrase);
|
||||
|
@ -54,7 +54,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
public List<string> Headers { get; } = new List<string>();
|
||||
|
||||
[JsonIgnore]
|
||||
public Common.Http.Client? Client { get; set; }
|
||||
public Wabbajack.Lib.Http.Client? Client { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public override object[] PrimaryKey => new object[] { Url };
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Reactive;
|
||||
using System.Security;
|
||||
using System.Threading.Tasks;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Wabbajack.Lib.Downloaders
|
||||
@ -39,6 +40,6 @@ namespace Wabbajack.Lib.Downloaders
|
||||
|
||||
public interface INeedsLoginCredentials : INeedsLogin
|
||||
{
|
||||
LoginReturnMessage LoginWithCredentials(string username, SecureString password, string? mfa);
|
||||
Task<LoginReturnMessage> LoginWithCredentials(string username, SecureString password, string? mfa);
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
}
|
||||
}
|
||||
|
||||
public LoginReturnMessage LoginWithCredentials(string username, SecureString password, string? mfa)
|
||||
public async Task<LoginReturnMessage> LoginWithCredentials(string username, SecureString password, string? mfa)
|
||||
{
|
||||
MegaApiClient.AuthInfos authInfos;
|
||||
|
||||
@ -57,7 +57,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
MegaApiClient.Logout();
|
||||
}
|
||||
catch (NotSupportedException ex)
|
||||
catch (NotSupportedException)
|
||||
{
|
||||
// Not logged in, so ignore
|
||||
}
|
||||
@ -101,7 +101,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
if (MegaApiClient.IsLoggedIn)
|
||||
{
|
||||
var infos = MEGAAuthInfos.ToMEGAAuthInfos(authInfos);
|
||||
infos.ToEcryptedJson(DataName);
|
||||
await infos.ToEcryptedJson(DataName);
|
||||
}
|
||||
|
||||
return new LoginReturnMessage("Logged in successfully, you can now close this window.",
|
||||
@ -115,7 +115,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
TriggerLogin = ReactiveCommand.Create(() => { },
|
||||
IsLoggedIn.Select(b => !b).ObserveOnGuiThread());
|
||||
|
||||
ClearLogin = ReactiveCommand.Create(() => Utils.CatchAndLog(() => Utils.DeleteEncryptedJson(DataName)),
|
||||
ClearLogin = ReactiveCommand.CreateFromTask(() => Utils.CatchAndLog(async () => await Utils.DeleteEncryptedJson(DataName)),
|
||||
IsLoggedIn.ObserveOnGuiThread());
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
|
||||
private async Task<HTTPDownloader.State?> Resolve()
|
||||
{
|
||||
var client = new Common.Http.Client();
|
||||
var client = new Wabbajack.Lib.Http.Client();
|
||||
var body = await client.GetHtmlAsync(Url);
|
||||
var node = body.DocumentNode.DescendantsAndSelf().First(d => d.HasClass("input") && d.HasClass("popsok") &&
|
||||
d.GetAttributeValue("aria-label", "") == "Download file");
|
||||
|
@ -46,8 +46,8 @@ namespace Wabbajack.Lib.Downloaders
|
||||
TriggerLogin = ReactiveCommand.CreateFromTask(
|
||||
execute: () => Utils.CatchAndLog(NexusApiClient.RequestAndCacheAPIKey),
|
||||
canExecute: IsLoggedIn.Select(b => !b).ObserveOnGuiThread());
|
||||
ClearLogin = ReactiveCommand.Create(
|
||||
execute: () => Utils.CatchAndLog(() => Utils.DeleteEncryptedJson("nexusapikey")),
|
||||
ClearLogin = ReactiveCommand.CreateFromTask(
|
||||
execute: () => Utils.CatchAndLog(async () => await Utils.DeleteEncryptedJson("nexusapikey")),
|
||||
canExecute: IsLoggedIn.ObserveOnGuiThread());
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ namespace Wabbajack.Lib.Downloaders.UrlDownloaders
|
||||
var state = YouTubeDownloader.UriToState(uri) as YouTubeDownloader.State;
|
||||
if (state == null) return null;
|
||||
|
||||
var client = new YoutubeClient(Common.Http.ClientFactory.Client);
|
||||
var client = new YoutubeClient(Wabbajack.Lib.Http.ClientFactory.Client);
|
||||
var video = await client.Videos.GetAsync(state.Key);
|
||||
|
||||
var desc = video.Description;
|
||||
|
@ -59,7 +59,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
var definition = await GetDefinition();
|
||||
await using var fs = await destination.Create();
|
||||
using var mmfile = MemoryMappedFile.CreateFromFile(fs, null, definition.Size, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, false);
|
||||
var client = new Common.Http.Client();
|
||||
var client = new Wabbajack.Lib.Http.Client();
|
||||
using var queue = new WorkQueue();
|
||||
await definition.Parts.PMap(queue, async part =>
|
||||
{
|
||||
@ -81,7 +81,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
|
||||
private async Task<CDNFileDefinition> GetDefinition()
|
||||
{
|
||||
var client = new Common.Http.Client();
|
||||
var client = new Wabbajack.Lib.Http.Client();
|
||||
using var data = await client.GetAsync(Url + "/definition.json.gz");
|
||||
await using var gz = new GZipStream(await data.Content.ReadAsStreamAsync(), CompressionMode.Decompress);
|
||||
return gz.FromJson<CDNFileDefinition>();
|
||||
|
@ -61,7 +61,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
|
||||
public override async Task<bool> Verify(Archive archive)
|
||||
{
|
||||
var client = new Common.Http.Client();
|
||||
var client = new Wabbajack.Lib.Http.Client();
|
||||
var result = await client.GetAsync(Url, errorsAsExceptions: false);
|
||||
return result.IsSuccessStatusCode;
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
using var queue = new WorkQueue();
|
||||
await using var folder = await TempFolder.Create();
|
||||
folder.Dir.Combine("tracks").CreateDirectory();
|
||||
var client = new YoutubeClient(Common.Http.ClientFactory.Client);
|
||||
var client = new YoutubeClient(Wabbajack.Lib.Http.ClientFactory.Client);
|
||||
var meta = await client.Videos.GetAsync(Key);
|
||||
var video = await client.Videos.Streams.GetManifestAsync(Key);
|
||||
var stream = video.Streams.OfType<AudioOnlyStreamInfo>().Where(f => f.AudioCodec.StartsWith("mp4a")).OrderByDescending(a => a.Bitrate)
|
||||
@ -210,7 +210,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
try
|
||||
{
|
||||
var client = new YoutubeClient(Common.Http.ClientFactory.Client);
|
||||
var client = new YoutubeClient(Wabbajack.Lib.Http.ClientFactory.Client);
|
||||
var video = await client.Videos.GetAsync(Key);
|
||||
return true;
|
||||
}
|
||||
|
@ -29,9 +29,9 @@ namespace Wabbajack.Lib.FileUploader
|
||||
return apiKey ?? (await Consts.LocalAppDataPath.Combine(Consts.AuthorAPIKeyFile).ReadAllTextAsync()).Trim();
|
||||
}
|
||||
|
||||
public static async Task<Common.Http.Client> GetAuthorizedClient(string? apiKey = null)
|
||||
public static async Task<Wabbajack.Lib.Http.Client> GetAuthorizedClient(string? apiKey = null)
|
||||
{
|
||||
var client = new Common.Http.Client();
|
||||
var client = new Wabbajack.Lib.Http.Client();
|
||||
client.Headers.Add(("X-API-KEY", await GetAPIKey(apiKey)));
|
||||
return client;
|
||||
}
|
||||
|
@ -6,9 +6,10 @@ using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using HtmlAgilityPack;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Exceptions;
|
||||
|
||||
namespace Wabbajack.Common.Http
|
||||
namespace Wabbajack.Lib.Http
|
||||
{
|
||||
public class Client
|
||||
{
|
@ -1,7 +1,8 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using SysHttp = System.Net.Http;
|
||||
namespace Wabbajack.Common.Http
|
||||
|
||||
namespace Wabbajack.Lib.Http
|
||||
{
|
||||
public static class ClientFactory
|
||||
{
|
@ -18,9 +18,9 @@ namespace Wabbajack.Lib.LibCefHelpers
|
||||
{
|
||||
public static class Helpers
|
||||
{
|
||||
public static Common.Http.Client GetClient(IEnumerable<Cookie> cookies, string referer)
|
||||
public static Wabbajack.Lib.Http.Client GetClient(IEnumerable<Cookie> cookies, string referer)
|
||||
{
|
||||
var client = new Common.Http.Client();
|
||||
var client = new Wabbajack.Lib.Http.Client();
|
||||
client.Headers.Add(("Referrer", referer));
|
||||
client.Cookies.AddRange(cookies.Select(cookie => new System.Net.Cookie(cookie.Name, cookie.Value, cookie.Path, cookie.Domain)));
|
||||
return client;
|
||||
|
@ -521,7 +521,7 @@ namespace Wabbajack.Lib
|
||||
var bsaId = (RelativePath)((string)to).Split('\\')[1];
|
||||
var bsa = InstallDirectives.OfType<CreateBSA>().First(b => b.TempID == bsaId);
|
||||
|
||||
await using var a = await BSADispatch.OpenRead(MO2Folder.Combine(bsa.To));
|
||||
var a = await BSADispatch.OpenRead(MO2Folder.Combine(bsa.To));
|
||||
var find = (RelativePath)Path.Combine(((string)to).Split('\\').Skip(2).ToArray());
|
||||
var file = a.Files.First(e => e.Path == find);
|
||||
var returnStream = new TempStream();
|
||||
|
@ -7,9 +7,10 @@ using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Win32;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Exceptions;
|
||||
|
||||
namespace Wabbajack.Common
|
||||
namespace Wabbajack.Lib
|
||||
{
|
||||
public class Metrics
|
||||
{
|
@ -62,7 +62,7 @@ namespace Wabbajack.Lib.ModListRegistry
|
||||
|
||||
public static async Task<List<ModlistMetadata>> LoadFromGithub()
|
||||
{
|
||||
var client = new Common.Http.Client();
|
||||
var client = new Wabbajack.Lib.Http.Client();
|
||||
Utils.Log("Loading ModLists from GitHub");
|
||||
var metadataResult = client.GetStringAsync(Consts.ModlistMetadataURL);
|
||||
var summaryResult = client.GetStringAsync(Consts.ModlistSummaryURL);
|
||||
|
@ -11,7 +11,6 @@ using Wabbajack.Common;
|
||||
using Wabbajack.Lib.Downloaders;
|
||||
using System.Threading;
|
||||
using Wabbajack.Common.Exceptions;
|
||||
using Wabbajack.Common.Http;
|
||||
using Wabbajack.Lib.WebAutomation;
|
||||
|
||||
namespace Wabbajack.Lib.NexusApi
|
||||
@ -20,7 +19,7 @@ namespace Wabbajack.Lib.NexusApi
|
||||
{
|
||||
private static readonly string API_KEY_CACHE_FILE = "nexus.key_cache";
|
||||
|
||||
public Common.Http.Client HttpClient { get; } = new Common.Http.Client();
|
||||
public Wabbajack.Lib.Http.Client HttpClient { get; } = new Wabbajack.Lib.Http.Client();
|
||||
|
||||
#region Authentication
|
||||
|
||||
@ -255,7 +254,7 @@ namespace Wabbajack.Lib.NexusApi
|
||||
return new NexusApiClient(apiKey);
|
||||
}
|
||||
|
||||
public async Task<T> Get<T>(string url, Client? client = null)
|
||||
public async Task<T> Get<T>(string url, Wabbajack.Lib.Http.Client? client = null)
|
||||
{
|
||||
client ??= HttpClient;
|
||||
int retries = 0;
|
||||
|
@ -46,7 +46,7 @@ namespace Wabbajack.Lib.NexusApi
|
||||
|
||||
private static async Task<IEnumerable<UpdateRecord>> GetFeed(Uri uri)
|
||||
{
|
||||
var client = new Common.Http.Client();
|
||||
var client = new Wabbajack.Lib.Http.Client();
|
||||
var data = await client.GetStringAsync(uri);
|
||||
var reader = XmlReader.Create(new StringReader(data));
|
||||
var results = SyndicationFeed.Load(reader);
|
||||
|
@ -12,8 +12,8 @@ namespace Wabbajack.Lib
|
||||
public override string ShortDescription { get; } = string.Empty;
|
||||
public override string ExtendedDescription { get; } = string.Empty;
|
||||
|
||||
private TaskCompletionSource<(Uri, Common.Http.Client)> _tcs = new TaskCompletionSource<(Uri, Common.Http.Client)>();
|
||||
public Task<(Uri, Common.Http.Client)> Task => _tcs.Task;
|
||||
private TaskCompletionSource<(Uri, Wabbajack.Lib.Http.Client)> _tcs = new TaskCompletionSource<(Uri, Wabbajack.Lib.Http.Client)>();
|
||||
public Task<(Uri, Wabbajack.Lib.Http.Client)> Task => _tcs.Task;
|
||||
|
||||
private ManuallyDownloadFile(ManualDownloader.State state)
|
||||
{
|
||||
@ -30,7 +30,7 @@ namespace Wabbajack.Lib
|
||||
_tcs.SetCanceled();
|
||||
}
|
||||
|
||||
public void Resume(Uri s, Common.Http.Client client)
|
||||
public void Resume(Uri s, Wabbajack.Lib.Http.Client client)
|
||||
{
|
||||
_tcs.SetResult((s, client));
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ namespace Wabbajack.Lib.Validation
|
||||
|
||||
public async Task LoadListsFromGithub()
|
||||
{
|
||||
var client = new Common.Http.Client();
|
||||
var client = new Wabbajack.Lib.Http.Client();
|
||||
|
||||
Utils.Log("Loading server whitelist");
|
||||
using (var response = await client.GetAsync(Consts.ServerWhitelistURL))
|
||||
|
@ -7,7 +7,6 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Http;
|
||||
using Wabbajack.Common.StatusFeed;
|
||||
using Wabbajack.Lib;
|
||||
using Wabbajack.Lib.Downloaders;
|
||||
@ -145,10 +144,10 @@ namespace Wabbajack.BuildServer.Test
|
||||
[Collection("ServerTests")]
|
||||
public class ABuildServerSystemTest : XunitContextBase, IClassFixture<SingletonAdaptor<BuildServerFixture>>
|
||||
{
|
||||
protected readonly Client _client;
|
||||
protected readonly Wabbajack.Lib.Http.Client _client;
|
||||
private readonly IDisposable _unsubMsgs;
|
||||
private readonly IDisposable _unsubErr;
|
||||
protected Client _authedClient;
|
||||
protected Wabbajack.Lib.Http.Client _authedClient;
|
||||
protected WorkQueue _queue;
|
||||
private Random _random;
|
||||
|
||||
@ -159,8 +158,8 @@ namespace Wabbajack.BuildServer.Test
|
||||
_unsubMsgs = Utils.LogMessages.OfType<IInfo>().Subscribe(onNext: msg => XunitContext.WriteLine(msg.ShortDescription));
|
||||
_unsubErr = Utils.LogMessages.OfType<IUserIntervention>().Subscribe(msg =>
|
||||
XunitContext.WriteLine("ERROR: User intervention required: " + msg.ShortDescription));
|
||||
_client = new Client();
|
||||
_authedClient = new Client();
|
||||
_client = new Wabbajack.Lib.Http.Client();
|
||||
_authedClient = new Wabbajack.Lib.Http.Client();
|
||||
Fixture = fixture.Deref();
|
||||
_authedClient.Headers.Add(("x-api-key", Fixture.APIKey));
|
||||
AuthorAPI.ApiKeyOverride = Fixture.APIKey;
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Dapper;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Lib;
|
||||
using Wabbajack.Server.DataLayer;
|
||||
using Wabbajack.Server.DTOs;
|
||||
using Xunit;
|
||||
|
@ -49,7 +49,7 @@ namespace Wabbajack.Server.Services
|
||||
};
|
||||
if (url == null) return;
|
||||
|
||||
var client = new Common.Http.Client();
|
||||
var client = new Wabbajack.Lib.Http.Client();
|
||||
await client.PostAsync(url, new StringContent(message.ToJson(true), Encoding.UTF8, "application/json"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -13,7 +13,7 @@ namespace Wabbajack.VirtualFileSystem
|
||||
private IAsyncDisposable _disposable;
|
||||
private AbsolutePath _tempFolder;
|
||||
|
||||
public ExtractedFiles(Dictionary<RelativePath, IExtractedFile> files, IAsyncDisposable disposeOther)
|
||||
public ExtractedFiles(Dictionary<RelativePath, IExtractedFile> files, IAsyncDisposable disposeOther = null)
|
||||
{
|
||||
_files = files;
|
||||
_disposable = disposeOther;
|
||||
|
@ -114,9 +114,9 @@ namespace Wabbajack.VirtualFileSystem
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var arch = await BSADispatch.OpenRead(source);
|
||||
var arch = await BSADispatch.OpenRead(source);
|
||||
var files = arch.Files.ToDictionary(f => f.Path, f => (IExtractedFile)new ExtractedBSAFile(f));
|
||||
return new ExtractedFiles(files, arch);
|
||||
return new ExtractedFiles(files);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -1,9 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<Platforms>x64</Platforms>
|
||||
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Platforms>x64</Platforms>
|
||||
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DocumentationFile>Wabbajack.VirtualFileSystem.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Compression.BSA\Compression.BSA.csproj" />
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Net.Mail;
|
||||
using System.Reactive.Linq;
|
||||
using System.Security;
|
||||
using System.Threading.Tasks;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using Wabbajack.Common;
|
||||
@ -21,6 +22,9 @@ namespace Wabbajack
|
||||
[Reactive]
|
||||
public LoginReturnMessage ReturnMessage { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public bool LoggingIn { get; private set; }
|
||||
|
||||
private readonly ObservableAsPropertyHelper<bool> _loginEnabled;
|
||||
public bool LoginEnabled => _loginEnabled.Value;
|
||||
|
||||
@ -35,6 +39,12 @@ namespace Wabbajack
|
||||
|
||||
_loginEnabled = this.WhenAny(x => x.Username)
|
||||
.Select(IsValidAddress)
|
||||
.CombineLatest(
|
||||
this.WhenAny(x => x.LoggingIn),
|
||||
(valid, loggingIn) =>
|
||||
{
|
||||
return valid && !loggingIn;
|
||||
})
|
||||
.ToGuiProperty(this,
|
||||
nameof(LoginEnabled));
|
||||
|
||||
@ -43,17 +53,19 @@ namespace Wabbajack
|
||||
.ToGuiProperty(this, nameof(MFAVisible));
|
||||
}
|
||||
|
||||
public void Login(SecureString password)
|
||||
public async Task Login(SecureString password)
|
||||
{
|
||||
try
|
||||
{
|
||||
LoggingIn = true;
|
||||
|
||||
if (password == null || password.Length == 0)
|
||||
{
|
||||
ReturnMessage = new LoginReturnMessage("You need to input a password!", LoginReturnCode.BadInput);
|
||||
return;
|
||||
}
|
||||
|
||||
ReturnMessage = _downloader.LoginWithCredentials(Username, password, string.IsNullOrWhiteSpace(MFAKey) ? null : MFAKey);
|
||||
ReturnMessage = await _downloader.LoginWithCredentials(Username, password, string.IsNullOrWhiteSpace(MFAKey) ? null : MFAKey);
|
||||
password.Clear();
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -61,6 +73,10 @@ namespace Wabbajack
|
||||
Utils.Error(e, "Exception while trying to login");
|
||||
ReturnMessage = new LoginReturnMessage($"Unhandled exception: {e.Message}", LoginReturnCode.InternalError);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LoggingIn = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsValidAddress(string s)
|
||||
|
@ -84,7 +84,7 @@ namespace Wabbajack
|
||||
{
|
||||
if (Login.IconUri == null) return;
|
||||
|
||||
using var img = await new Common.Http.Client().GetAsync(Login.IconUri, errorsAsExceptions:false);
|
||||
using var img = await new Wabbajack.Lib.Http.Client().GetAsync(Login.IconUri, errorsAsExceptions:false);
|
||||
if (!img.IsSuccessStatusCode) return;
|
||||
|
||||
var icoData = new MemoryStream(await img.Content.ReadAsByteArrayAsync());
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using MahApps.Metro.Controls;
|
||||
using ReactiveUI;
|
||||
using Wabbajack.Lib.Downloaders;
|
||||
|
||||
@ -35,9 +36,9 @@ namespace Wabbajack
|
||||
});
|
||||
}
|
||||
|
||||
private void LoginButton_OnClick(object sender, RoutedEventArgs e)
|
||||
private async void LoginButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ViewModel.Login(Password.SecurePassword);
|
||||
ViewModel.Login(Password.SecurePassword).FireAndForget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user