mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Can get a list of all appIds and depotids owned by the user
This commit is contained in:
parent
bf843f9289
commit
ac1f4a7427
@ -65,6 +65,7 @@ internal class Program
|
|||||||
services.AddSingleton<IVerb, ForceHeal>();
|
services.AddSingleton<IVerb, ForceHeal>();
|
||||||
services.AddSingleton<IVerb, MirrorFile>();
|
services.AddSingleton<IVerb, MirrorFile>();
|
||||||
services.AddSingleton<IVerb, SteamLogin>();
|
services.AddSingleton<IVerb, SteamLogin>();
|
||||||
|
services.AddSingleton<IVerb, SteamAppDumpInfo>();
|
||||||
|
|
||||||
services.AddSingleton<IUserInterventionHandler, UserInterventionHandler>();
|
services.AddSingleton<IUserInterventionHandler, UserInterventionHandler>();
|
||||||
}).Build();
|
}).Build();
|
||||||
|
57
Wabbajack.CLI/Verbs/SteamDumpAppInfo.cs
Normal file
57
Wabbajack.CLI/Verbs/SteamDumpAppInfo.cs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
using System;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Wabbajack.DTOs;
|
||||||
|
using Wabbajack.Networking.Http.Interfaces;
|
||||||
|
using Wabbajack.Networking.Steam;
|
||||||
|
|
||||||
|
namespace Wabbajack.CLI.Verbs;
|
||||||
|
|
||||||
|
public class SteamAppDumpInfo : IVerb
|
||||||
|
{
|
||||||
|
private readonly ILogger<SteamAppDumpInfo> _logger;
|
||||||
|
private readonly Client _client;
|
||||||
|
private readonly ITokenProvider<SteamLoginState> _token;
|
||||||
|
private readonly DepotDownloader _downloader;
|
||||||
|
|
||||||
|
public SteamAppDumpInfo(ILogger<SteamAppDumpInfo> logger, Client steamClient, ITokenProvider<SteamLoginState> token,
|
||||||
|
DepotDownloader downloader)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_client = steamClient;
|
||||||
|
_token = token;
|
||||||
|
_downloader = downloader;
|
||||||
|
}
|
||||||
|
public Command MakeCommand()
|
||||||
|
{
|
||||||
|
var command = new Command("steam-app-dump-info");
|
||||||
|
command.Description = "Dumps information to the console about the given app";
|
||||||
|
|
||||||
|
command.Add(new Option<string>(new[] {"-g", "-game", "-gameName"}, "Wabbajack game name"));
|
||||||
|
command.Handler = CommandHandler.Create(Run);
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> Run(string gameName)
|
||||||
|
{
|
||||||
|
if (!GameRegistry.TryGetByFuzzyName(gameName, out var game))
|
||||||
|
{
|
||||||
|
_logger.LogError("Can't find game {GameName} in game registry", gameName);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _client.Login();
|
||||||
|
|
||||||
|
if (!await _downloader.AccountHasAccess((uint) game.SteamIDs.First()))
|
||||||
|
{
|
||||||
|
_logger.LogError("Your account does not have access to this Steam App");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using SteamKit2;
|
using SteamKit2;
|
||||||
|
using SteamKit2.Internal;
|
||||||
using Wabbajack.DTOs.Interventions;
|
using Wabbajack.DTOs.Interventions;
|
||||||
using Wabbajack.Networking.Http.Interfaces;
|
using Wabbajack.Networking.Http.Interfaces;
|
||||||
using Wabbajack.Networking.Steam.UserInterventions;
|
using Wabbajack.Networking.Steam.UserInterventions;
|
||||||
@ -26,6 +28,16 @@ public class Client : IDisposable
|
|||||||
private bool _isLoggedIn;
|
private bool _isLoggedIn;
|
||||||
private bool _haveSigFile;
|
private bool _haveSigFile;
|
||||||
|
|
||||||
|
public TaskCompletionSource _licenseRequest = new();
|
||||||
|
private readonly SteamApps _steamApps;
|
||||||
|
|
||||||
|
public SteamApps.LicenseListCallback.License[] Licenses { get; private set; }
|
||||||
|
|
||||||
|
public ConcurrentDictionary<uint, ulong> PackageTokens { get; } = new();
|
||||||
|
|
||||||
|
public ConcurrentDictionary<uint, SteamApps.PICSProductInfoCallback.PICSProductInfo?> PackageInfos { get; } = new();
|
||||||
|
|
||||||
|
|
||||||
public Client(ILogger<Client> logger, HttpClient client, ITokenProvider<SteamLoginState> token,
|
public Client(ILogger<Client> logger, HttpClient client, ITokenProvider<SteamLoginState> token,
|
||||||
IUserInterventionHandler interventionHandler)
|
IUserInterventionHandler interventionHandler)
|
||||||
{
|
{
|
||||||
@ -47,6 +59,7 @@ public class Client : IDisposable
|
|||||||
_manager = new CallbackManager(_client);
|
_manager = new CallbackManager(_client);
|
||||||
|
|
||||||
_steamUser = _client.GetHandler<SteamUser>()!;
|
_steamUser = _client.GetHandler<SteamUser>()!;
|
||||||
|
_steamApps = _client.GetHandler<SteamApps>()!;
|
||||||
|
|
||||||
_manager.Subscribe<SteamClient.ConnectedCallback>( OnConnected );
|
_manager.Subscribe<SteamClient.ConnectedCallback>( OnConnected );
|
||||||
_manager.Subscribe<SteamClient.DisconnectedCallback>( OnDisconnected );
|
_manager.Subscribe<SteamClient.DisconnectedCallback>( OnDisconnected );
|
||||||
@ -54,6 +67,8 @@ public class Client : IDisposable
|
|||||||
_manager.Subscribe<SteamUser.LoggedOnCallback>( OnLoggedOn );
|
_manager.Subscribe<SteamUser.LoggedOnCallback>( OnLoggedOn );
|
||||||
_manager.Subscribe<SteamUser.LoggedOffCallback>( OnLoggedOff );
|
_manager.Subscribe<SteamUser.LoggedOffCallback>( OnLoggedOff );
|
||||||
|
|
||||||
|
_manager.Subscribe<SteamApps.LicenseListCallback>(OnLicenseList);
|
||||||
|
|
||||||
_manager.Subscribe<SteamUser.UpdateMachineAuthCallback>( OnUpdateMachineAuthCallback );
|
_manager.Subscribe<SteamUser.UpdateMachineAuthCallback>( OnUpdateMachineAuthCallback );
|
||||||
|
|
||||||
_isConnected = false;
|
_isConnected = false;
|
||||||
@ -74,6 +89,17 @@ public class Client : IDisposable
|
|||||||
.Start();
|
.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnLicenseList(SteamApps.LicenseListCallback obj)
|
||||||
|
{
|
||||||
|
if (obj.Result != EResult.OK)
|
||||||
|
{
|
||||||
|
_licenseRequest.TrySetException(new SteamException("While getting licenses", obj.Result, EResult.Invalid));
|
||||||
|
}
|
||||||
|
_logger.LogInformation("Got {LicenseCount} licenses from Steam", obj.LicenseList.Count);
|
||||||
|
Licenses = obj.LicenseList.ToArray();
|
||||||
|
_licenseRequest.TrySetResult();
|
||||||
|
}
|
||||||
|
|
||||||
private void OnUpdateMachineAuthCallback(SteamUser.UpdateMachineAuthCallback callback)
|
private void OnUpdateMachineAuthCallback(SteamUser.UpdateMachineAuthCallback callback)
|
||||||
{
|
{
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
@ -192,13 +218,14 @@ public class Client : IDisposable
|
|||||||
|
|
||||||
_isConnected = true;
|
_isConnected = true;
|
||||||
|
|
||||||
_steamUser.LogOn(new SteamUser.LogOnDetails()
|
_steamUser.LogOn(new SteamUser.LogOnDetails
|
||||||
{
|
{
|
||||||
Username = state.User,
|
Username = state.User,
|
||||||
Password = state.Password,
|
Password = state.Password,
|
||||||
AuthCode = _authCode,
|
AuthCode = _authCode,
|
||||||
TwoFactorCode = _twoFactorCode,
|
TwoFactorCode = _twoFactorCode,
|
||||||
SentryFileHash = sentryHash
|
SentryFileHash = sentryHash,
|
||||||
|
RequestSteam2Ticket = true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -218,12 +245,57 @@ public class Client : IDisposable
|
|||||||
_cancellationSource.Dispose();
|
_cancellationSource.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task Login(TaskCompletionSource? tcs = null)
|
public async Task Login(TaskCompletionSource? tcs = null)
|
||||||
{
|
{
|
||||||
_loginTask = tcs ?? new TaskCompletionSource();
|
_loginTask = tcs ?? new TaskCompletionSource();
|
||||||
_logger.LogInformation("Attempting login");
|
_logger.LogInformation("Attempting login");
|
||||||
_client.Connect();
|
_client.Connect();
|
||||||
|
|
||||||
return _loginTask.Task;
|
await _loginTask.Task;
|
||||||
|
await _licenseRequest.Task;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Dictionary<uint, SteamApps.PICSProductInfoCallback.PICSProductInfo?>> GetPackageInfos(IEnumerable<uint> packageIds)
|
||||||
|
{
|
||||||
|
var packages = packageIds.Where(id => !PackageInfos.ContainsKey(id)).ToList();
|
||||||
|
|
||||||
|
if (packages.Count > 0)
|
||||||
|
{
|
||||||
|
var packageRequests = new List<SteamApps.PICSRequest>();
|
||||||
|
|
||||||
|
foreach (var package in packages)
|
||||||
|
{
|
||||||
|
var request = new SteamApps.PICSRequest(package);
|
||||||
|
if (PackageTokens.TryGetValue(package, out var token))
|
||||||
|
{
|
||||||
|
request.AccessToken = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
packageRequests.Add(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogInformation("Requesting {Count} package infos", packageRequests.Count);
|
||||||
|
|
||||||
|
var results = await _steamApps.PICSGetProductInfo(new List<SteamApps.PICSRequest>(), packageRequests);
|
||||||
|
|
||||||
|
if (results.Failed)
|
||||||
|
throw new SteamException("Exception getting product info", EResult.Invalid, EResult.Invalid);
|
||||||
|
|
||||||
|
foreach (var packageInfo in results.Results!)
|
||||||
|
{
|
||||||
|
foreach (var package in packageInfo.Packages.Select(v => v.Value))
|
||||||
|
{
|
||||||
|
PackageInfos[package.ID] = package;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var package in packageInfo.UnknownPackages)
|
||||||
|
{
|
||||||
|
PackageInfos[package] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return packages.Distinct().ToDictionary(p => p, p => PackageInfos[p]);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
32
Wabbajack.Networking.Steam/DepotDownloader.cs
Normal file
32
Wabbajack.Networking.Steam/DepotDownloader.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace Wabbajack.Networking.Steam;
|
||||||
|
|
||||||
|
public class DepotDownloader
|
||||||
|
{
|
||||||
|
private readonly ILogger<DepotDownloader> _logger;
|
||||||
|
private readonly Client _steamClient;
|
||||||
|
|
||||||
|
public DepotDownloader(ILogger<DepotDownloader> logger, Client client)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_steamClient = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> AccountHasAccess(uint depotId)
|
||||||
|
{
|
||||||
|
var packages = _steamClient.Licenses.Select(l => l.PackageID);
|
||||||
|
var infos = await _steamClient.GetPackageInfos(packages);
|
||||||
|
|
||||||
|
foreach (var info in infos.Where(i => i.Value != null))
|
||||||
|
{
|
||||||
|
if (info.Value!.KeyValues["appids"].Children.Any(child => child.AsUnsignedInteger() == depotId))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (info.Value!.KeyValues["depotids"].Children.Any(child => child.AsUnsignedInteger() == depotId))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
13
Wabbajack.Networking.Steam/ServiceExtensions.cs
Normal file
13
Wabbajack.Networking.Steam/ServiceExtensions.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Wabbajack.Networking.Steam;
|
||||||
|
|
||||||
|
namespace Wabbajack.Networking.NexusApi;
|
||||||
|
|
||||||
|
public static class ServiceExtensions
|
||||||
|
{
|
||||||
|
public static void AddSteam(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddSingleton<Client>();
|
||||||
|
services.AddSingleton<DepotDownloader>();
|
||||||
|
}
|
||||||
|
}
|
@ -107,7 +107,7 @@ public static class ServiceExtensions
|
|||||||
service.AddSingleton<HttpClient>();
|
service.AddSingleton<HttpClient>();
|
||||||
service.AddAllSingleton<IHttpDownloader, SingleThreadedDownloader>();
|
service.AddAllSingleton<IHttpDownloader, SingleThreadedDownloader>();
|
||||||
|
|
||||||
service.AddSingleton<Wabbajack.Networking.Steam.Client>();
|
service.AddSteam();
|
||||||
|
|
||||||
service.AddSingleton<Client>();
|
service.AddSingleton<Client>();
|
||||||
service.AddSingleton<WriteOnlyClient>();
|
service.AddSingleton<WriteOnlyClient>();
|
||||||
|
Loading…
Reference in New Issue
Block a user