Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GOG file hashing #2407

Merged
merged 63 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
47595e6
Basic structure of the projects, can login via a test, and stay logge…
halgari Dec 11, 2024
669d794
Implemented the rest of the Steam flow for getting manifests. Introdu…
halgari Dec 11, 2024
f52f6a9
Boom, can stream files off of Steam
halgari Dec 11, 2024
c6d7703
Can download files, serialize manifests, all that good stuff
halgari Dec 12, 2024
49b3d9c
Fix the chunked stream so that it can use arbitrarily sized chunks
halgari Dec 12, 2024
c90d121
Delete the old Store project
halgari Dec 12, 2024
eb32afd
Disable the test that has to be run with human interaction
halgari Dec 12, 2024
ed8f39f
Few more comments and cleanup
halgari Dec 12, 2024
9d03f7b
WIP, can mostly log into GOG at this point
halgari Dec 12, 2024
5e944e6
Can log into GOG and get product info, the format for the files thems…
halgari Dec 13, 2024
d64c215
Update Abstractions/NexusMods.Abstractions.Steam/DTOs/ProductInfo.cs
halgari Dec 16, 2024
f734e43
Update src/Abstractions/NexusMods.Abstractions.Hashes/Crc32.cs
halgari Dec 16, 2024
b58d349
Update src/Networking/NexusMods.Networking.Steam/NexusMods.Networking…
halgari Dec 16, 2024
05e5f85
Update src/Networking/NexusMods.Networking.Steam/Session.cs
halgari Dec 16, 2024
0c20eb3
Update Abstractions/NexusMods.Abstractions.Steam/DTOs/Manifest.cs
halgari Dec 16, 2024
fd26dc2
Update src/Networking/NexusMods.Networking.Steam/ProductInfoParser.cs
halgari Dec 16, 2024
869a959
Update src/Abstractions/NexusMods.Abstractions.Hashes/MultiHasher.cs
halgari Dec 16, 2024
752486b
Update src/Networking/NexusMods.Networking.Steam/Session.cs
halgari Dec 16, 2024
3075e76
WIP getting access to files
halgari Dec 16, 2024
6815ce4
`sizeof(ulong)` vs `size(long)`
halgari Dec 16, 2024
f6e59ce
Update doc strings to better explain the value sizes
halgari Dec 16, 2024
6b7bc9a
Downloading and basic indexing of GOG data
halgari Dec 16, 2024
20d79bb
Can hash depots and export data, and it's not horrible performance
halgari Dec 17, 2024
782c74f
Update src/Networking/NexusMods.Networking.Steam/ManifestParser.cs
halgari Dec 17, 2024
62cbbfd
Export all OSes
halgari Dec 17, 2024
a5dd382
Update src/Abstractions/NexusMods.Abstractions.Hashes/HashJsonConvert…
halgari Dec 17, 2024
6cca217
Fix the .Steam project
halgari Dec 17, 2024
71c769a
Merge branch 'steam-login' of https://github.com/Nexus-Mods/NexusMods…
halgari Dec 17, 2024
f2b3e6b
fix compile errors introduced during code review
halgari Dec 17, 2024
d24b52b
Upgrade deps, fix several broken tests on `main`
halgari Dec 17, 2024
c63dc0b
Merge branch 'steam-login' into gog-login
halgari Dec 17, 2024
83046d2
Bit of code cleanup
halgari Dec 17, 2024
ae0585a
Merge branch 'main' into gog-login
halgari Dec 17, 2024
f244290
Add some doc strings
halgari Dec 17, 2024
2c8d116
Merge main
halgari Dec 17, 2024
5e0cfdf
Merge branch 'main' into gog-login
halgari Dec 18, 2024
a605fc5
Fix tests so we can get an idea of build sizes
halgari Dec 23, 2024
d0d9178
Merge main
halgari Dec 23, 2024
77bbcbb
try a change to fix builds on osx
halgari Jan 6, 2025
47b8c9d
include osx explicitly
halgari Jan 6, 2025
755a40f
More config changes
halgari Jan 6, 2025
867f225
Include ARM64 binaries
halgari Jan 7, 2025
5f1a5e5
Fix verify tests
halgari Jan 7, 2025
64a42ad
Missed a test file
halgari Jan 7, 2025
7e197b9
Merge branch 'main' into gog-login
halgari Jan 7, 2025
f495944
Switch around a few config things, just getting unblocked for now
halgari Jan 7, 2025
037c042
Fix the endianness of the hash converter
halgari Jan 7, 2025
1c92e0a
WIP switch over to actual oauth flow
halgari Jan 13, 2025
96aff76
WIP working login
halgari Jan 13, 2025
4ac6859
Today's work, need some feedback from GOG
halgari Jan 13, 2025
57aaaa7
WIP console progress
halgari Jan 14, 2025
de33238
Merge main
halgari Jan 14, 2025
1da7613
Finish integrating the gog login and clean up the indexing code a bit
halgari Jan 14, 2025
6b550f9
Bit of documentation
halgari Jan 14, 2025
a419511
Delete references to CEF/DotNetBrowser
halgari Jan 14, 2025
7581c73
Bit more cleanup
halgari Jan 14, 2025
cc7b492
Update src/Networking/NexusMods.Networking.GOG/Client.cs
halgari Jan 16, 2025
8d7b00c
Handle some PR feedback
halgari Jan 16, 2025
754f4bb
Merge remote-tracking branch 'origin/gog-login' into gog-login
halgari Jan 16, 2025
b5cf9db
Merge main
halgari Jan 16, 2025
d6ab723
Include the rest of the comments
halgari Jan 16, 2025
6b06c14
Bit more comments
halgari Jan 16, 2025
90019bc
Cleanup some code in SpectreRenderer.cs
halgari Jan 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Abstractions\NexusMods.Abstractions.Hashes\NexusMods.Abstractions.Hashes.csproj" />
<ProjectReference Include="..\..\src\Abstractions\NexusMods.Abstractions.Hashes\NexusMods.Abstractions.Hashes.csproj" />
</ItemGroup>
</Project>
4 changes: 3 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<PackageVersion Include="Avalonia.Labs.Panels" Version="11.2.0" />
<PackageVersion Include="Avalonia.Skia" Version="11.2.2" />
<PackageVersion Include="AvaloniaEdit.TextMate" Version="11.1.0" />
<PackageVersion Include="Jitbit.FastCache" Version="1.1.0" />
<PackageVersion Include="K4os.Compression.LZ4" Version="1.3.8" />
<PackageVersion Include="Bannerlord.ModuleManager" Version="6.0.246" />
<PackageVersion Include="BsDiff" Version="1.1.0" />
Expand Down Expand Up @@ -37,6 +38,7 @@
<PackageVersion Include="R3" Version="1.2.9" />
<PackageVersion Include="R3Extensions.Avalonia" Version="1.2.9" />
<PackageVersion Include="ReactiveUI" Version="20.1.63" />
<PackageVersion Include="SmartFormat" Version="3.5.1" />
<PackageVersion Include="Spectre.Console.Testing" Version="0.49.1" />
<PackageVersion Include="SteamKit2" Version="3.0.0" />
<PackageVersion Include="StrawberryShake.Server" Version="14.1.0" />
Expand Down Expand Up @@ -144,4 +146,4 @@
<PackageVersion Include="Splat.Microsoft.Extensions.Logging" Version="15.2.22" />
<PackageVersion Include="TransparentValueObjects" Version="1.0.2" />
</ItemGroup>
</Project>
</Project>
14 changes: 14 additions & 0 deletions NexusMods.App.sln
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Networking.Steam.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Abstractions.Hashes", "src\Abstractions\NexusMods.Abstractions.Hashes\NexusMods.Abstractions.Hashes.csproj", "{AF703852-D7B0-4BAD-8C75-B6046C6F0490}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Networking.GOG", "src\Networking\NexusMods.Networking.GOG\NexusMods.Networking.GOG.csproj", "{F7FD18A7-2F00-4EB6-84FC-15C57326FDEB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Abstractions.GOG", "src\Abstractions\NexusMods.Abstractions.GOG\NexusMods.Abstractions.GOG.csproj", "{03AC4F34-E69A-41E3-9F00-EE5A558D01B9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Abstractions.Logging", "src\Abstractions\NexusMods.Abstractions.Logging\NexusMods.Abstractions.Logging.csproj", "{9DE1C2AC-927A-4BC6-B2A1-7016902F8BAE}"
EndProject
Global
Expand Down Expand Up @@ -754,6 +758,14 @@ Global
{AF703852-D7B0-4BAD-8C75-B6046C6F0490}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF703852-D7B0-4BAD-8C75-B6046C6F0490}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AF703852-D7B0-4BAD-8C75-B6046C6F0490}.Release|Any CPU.Build.0 = Release|Any CPU
{F7FD18A7-2F00-4EB6-84FC-15C57326FDEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F7FD18A7-2F00-4EB6-84FC-15C57326FDEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F7FD18A7-2F00-4EB6-84FC-15C57326FDEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F7FD18A7-2F00-4EB6-84FC-15C57326FDEB}.Release|Any CPU.Build.0 = Release|Any CPU
{03AC4F34-E69A-41E3-9F00-EE5A558D01B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{03AC4F34-E69A-41E3-9F00-EE5A558D01B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{03AC4F34-E69A-41E3-9F00-EE5A558D01B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{03AC4F34-E69A-41E3-9F00-EE5A558D01B9}.Release|Any CPU.Build.0 = Release|Any CPU
{9DE1C2AC-927A-4BC6-B2A1-7016902F8BAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9DE1C2AC-927A-4BC6-B2A1-7016902F8BAE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9DE1C2AC-927A-4BC6-B2A1-7016902F8BAE}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -891,6 +903,8 @@ Global
{24457AAA-8954-4BD6-8EB5-168EAC6EFB1B} = {0CB73565-1207-4A56-A79F-6A8E9BBD795C}
{17023DB9-8E31-4397-B3E1-141149987865} = {897C4198-884F-448A-B0B0-C2A6D971EAE0}
{AF703852-D7B0-4BAD-8C75-B6046C6F0490} = {0CB73565-1207-4A56-A79F-6A8E9BBD795C}
{F7FD18A7-2F00-4EB6-84FC-15C57326FDEB} = {D7E9D8F5-8AC8-4ADA-B219-C549084AD84C}
{03AC4F34-E69A-41E3-9F00-EE5A558D01B9} = {0CB73565-1207-4A56-A79F-6A8E9BBD795C}
{9DE1C2AC-927A-4BC6-B2A1-7016902F8BAE} = {0CB73565-1207-4A56-A79F-6A8E9BBD795C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
Expand Down
1 change: 1 addition & 0 deletions NexusMods.App.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_INVOCATION_RPAR/@EntryValue">True</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">200</s:Int64>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=API/@EntryIndexedValue">API</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CDN/@EntryIndexedValue">CDN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DI/@EntryIndexedValue">DI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DTO/@EntryIndexedValue">DTO</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=EA/@EntryIndexedValue">EA</s:String>
Expand Down
61 changes: 61 additions & 0 deletions src/Abstractions/NexusMods.Abstractions.Cli/ProgressTask.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System.Diagnostics;
using NexusMods.ProxyConsole.Abstractions;
using NexusMods.ProxyConsole.Abstractions.Implementations;

namespace NexusMods.Abstractions.Cli;

/// <summary>
/// A wrapper for progress task communication
/// </summary>
public class ProgressTask : IAsyncDisposable
{
private readonly IRenderer _renderer;
private readonly Guid _taskId;
private double _progress = 0;
private readonly double? _maxValue;

internal ProgressTask(IRenderer renderer, Guid taskId, double? maxValue)
{
_renderer = renderer;
_taskId = taskId;
_maxValue = maxValue;
}

/// <summary>
/// Deletes the progress task
/// </summary>
public async ValueTask DisposeAsync()
{
await _renderer.RenderAsync(new DeleteProgressTask { TaskId = _taskId });
}

/// <summary>
/// Sets the progress of this task to the given value, in a range of 0 to 1
/// </summary>
public async Task SetProgress(double progress)
{
var increment = progress - _progress;
_progress = progress;
await _renderer.RenderAsync(new UpdateTask { TaskId = _taskId, IncrementProgressBy = increment });
}

/// <summary>
/// Increments the progress of this task by the given value, in a range of 0 to 1
/// </summary>
/// <param name="increment"></param>
public async Task IncrementProgress(double increment)
{
_progress += increment;
await _renderer.RenderAsync(new UpdateTask { TaskId = _taskId, IncrementProgressBy = increment });
}

/// <summary>
/// Increments the total "value" of this task by the given increment, the progress is then calculated as a percentage of the total value
/// </summary>
public async Task Increment(double increment)
{
Debug.Assert(_maxValue.HasValue);
var progress = (double)increment / _maxValue!.Value;
await IncrementProgress(progress);
}
}
44 changes: 44 additions & 0 deletions src/Abstractions/NexusMods.Abstractions.Cli/RendererExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,32 @@
{
await renderer.RenderAsync(Renderable.Text(text));
}

/// <summary>
/// Starts a progress bar box in the renderer that will be stopped when the returned disposable is disposed
/// </summary>
public static async Task<IAsyncDisposable> WithProgress(this IRenderer renderer)
{
await renderer.RenderAsync(new StartProgress());

return new DisposableProgress(renderer);
}

private class DisposableProgress(IRenderer renderer) : IAsyncDisposable
{
public async ValueTask DisposeAsync()
{
await renderer.RenderAsync(new StopProgress());
}
}


/// <summary>
/// Renders the text to the renderer with the given arguments and template
/// </summary>
/// <param name="renderer"></param>
/// <param name="text"></param>

Check warning on line 99 in src/Abstractions/NexusMods.Abstractions.Cli/RendererExtensions.cs

View workflow job for this annotation

GitHub Actions / build-windows / build-archive

XML comment has a param tag for 'text', but there is no parameter by that name
public static async ValueTask Text(this IRenderer renderer, string template, params object[] args)

Check warning on line 100 in src/Abstractions/NexusMods.Abstractions.Cli/RendererExtensions.cs

View workflow job for this annotation

GitHub Actions / build-windows / build-archive

Parameter 'template' has no matching param tag in the XML comment for 'RendererExtensions.Text(IRenderer, string, params object[])' (but other parameters do)
{
// Todo: implement custom conversion and formatting for the arguments
await renderer.RenderAsync(Renderable.Text(template, args.Select(a => a.ToString()!).ToArray()));
Expand Down Expand Up @@ -119,4 +138,29 @@
await renderer.Text(template, args);
await renderer.Text("Error: {0}", ex);
}

/// <summary>
/// Creates a new progress task with the given text, the task will be deleted when the returned disposable is disposed
/// </summary>
public static async ValueTask<ProgressTask> StartProgressTask(this IRenderer renderer, string text, double? maxValue = null)
{
var taskId = Guid.NewGuid();
await renderer.RenderAsync(new CreateProgressTask() { TaskId = taskId, Text = text });
return new ProgressTask(renderer, taskId, maxValue);
}

/// <summary>
/// Wraps the enumeration in a progress task that will update the progress bar as the items are enumerated
/// </summary>
public static async IAsyncEnumerable<T> WithProgress<T>(this T[] items, IRenderer renderer, string text)
{
var increment = 1.0 / items.Length;
await using var task = await renderer.StartProgressTask(text);

foreach (var item in items)
{
await task.IncrementProgress(increment);
yield return item;
}
}
}
72 changes: 72 additions & 0 deletions src/Abstractions/NexusMods.Abstractions.GOG/DTOs/Build.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System.Text.Json.Serialization;
using JetBrains.Annotations;
using NexusMods.Abstractions.GOG.JsonConverters;
using NexusMods.Abstractions.GOG.Values;

namespace NexusMods.Abstractions.GOG.DTOs;

/// <summary>
/// Information about a build, which is a collection of files and the chunks that make up those files. This may sound confusing, but the idea
/// is that "build" and to some extent "depot" are both metadata concepts. The Build is the information about what a collection of files are tagged
/// as (like Cyberpunk 1.5) and the depot is metadata about the actual files that are stored on the CDN. There is a 1:1 relationship between depots and
/// builds. The files in the depot are then stored in one of many CDNs, these CDN links are known as "SecureLinks". There may be many secure links (mirrors)
/// for a given depot and build.
/// </summary>
[UsedImplicitly]
public class Build
{
/// <summary>
/// The unique ID of the build.
/// </summary>
[JsonPropertyName("build_id")]
public required BuildId BuildId { get; init; }

/// <summary>
/// The product ID of the build.
/// </summary>
[JsonPropertyName("product_id")]
public required ProductId ProductId { get; init; }

/// <summary>
/// The OS of the build.
/// </summary>
[JsonPropertyName("os")]
public required string OS { get; init; }

/// <summary>
/// The version of the build.
/// </summary>
[JsonPropertyName("version_name")]
public required string VersionName { get; init; }

/// <summary>
/// Various tags for the build (not sure what these may contain).
/// </summary>
[JsonPropertyName("tags")]
public required string[] Tags { get; init; }

/// <summary>
/// True if the build is public, false if it is private.
/// </summary>
[JsonPropertyName("public")]
public bool Public { get; init; }

/// <summary>
/// The date the build was published.
/// </summary>
[JsonConverter(typeof(GOGDateTimeOffsetConverter))]
[JsonPropertyName("date_published")]
public DateTimeOffset DatePublished { get; init; }

/// <summary>
/// The generation of the build data (should be 2).
/// </summary>
[JsonPropertyName("generation")]
public int Generation { get; init; }

/// <summary>
/// A link to the build's details
/// </summary>
[JsonPropertyName("link")]
public required Uri? Link { get; init; }
}
68 changes: 68 additions & 0 deletions src/Abstractions/NexusMods.Abstractions.GOG/DTOs/BuildDetails.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System.Text.Json.Serialization;
using JetBrains.Annotations;
using NexusMods.Abstractions.GOG.Values;
using NexusMods.Paths;

namespace NexusMods.Abstractions.GOG.DTOs;

/// <summary>
/// Information about a build, which is a collection of depots.
/// </summary>
[UsedImplicitly]
public class BuildDetails
{
[JsonPropertyName("baseProductId")]
public required ProductId BaseProductId { get; init; }

[JsonPropertyName("buildId")]
public required BuildId BuildId { get; init; }

[JsonPropertyName("dependencies")]
public string[] Dependencies { get; init; } = [];

[JsonPropertyName("depots")]
public required BuildDetailsDepot[] Depots { get; init; }
}

/// <summary>
/// Details about a depot in a build.
/// </summary>
[UsedImplicitly]
public class BuildDetailsDepot
{
/// <summary>
/// The size of the depot when compressed.
/// </summary>
[JsonPropertyName("compressedSize")]
public required Size CompressedSize { get; init; }

/// <summary>
/// The languages supported by the depot.
/// </summary>
[JsonPropertyName("languages")]
public string[] Languages { get; init; } = [];

/// <summary>
/// The unique ID of the manifest for this depot.
/// </summary>
[JsonPropertyName("manifest")]
public required string Manifest { get; init; }

/// <summary>
/// The OS bitness (32, 64) supported by the depot.
/// </summary>
[JsonPropertyName("osBitness")]
public int[] OSBitness { get; init; } = [];

/// <summary>
/// The product ID of the depot.
/// </summary>
[JsonPropertyName("productId")]
public required ProductId ProductId { get; init; }

/// <summary>
/// The size of the depot when uncompressed.
/// </summary>
[JsonPropertyName("size")]
public required Size Size { get; init; }
}
Loading
Loading