diff --git a/DeveLanCacheUI_SteamDepotFinder.ConsoleApp/DeveLanCacheUI_SteamDepotFinder.ConsoleApp.csproj b/DeveLanCacheUI_SteamDepotFinder.ConsoleApp/DeveLanCacheUI_SteamDepotFinder.ConsoleApp.csproj index b0f0af5..48d01e1 100644 --- a/DeveLanCacheUI_SteamDepotFinder.ConsoleApp/DeveLanCacheUI_SteamDepotFinder.ConsoleApp.csproj +++ b/DeveLanCacheUI_SteamDepotFinder.ConsoleApp/DeveLanCacheUI_SteamDepotFinder.ConsoleApp.csproj @@ -9,6 +9,7 @@ + diff --git a/DeveLanCacheUI_SteamDepotFinder.ConsoleApp/Program.cs b/DeveLanCacheUI_SteamDepotFinder.ConsoleApp/Program.cs index 4ef9d75..2505934 100644 --- a/DeveLanCacheUI_SteamDepotFinder.ConsoleApp/Program.cs +++ b/DeveLanCacheUI_SteamDepotFinder.ConsoleApp/Program.cs @@ -1,32 +1,36 @@ -namespace DeveLanCacheUI_SteamDepotFinder.ConsoleApp +using DeveLanCacheUI_SteamDepotFinder.NewVersion; +using DeveLanCacheUI_SteamDepotFinder.NewVersion.Steam; +using Microsoft.Extensions.Logging; + +namespace DeveLanCacheUI_SteamDepotFinder.ConsoleApp { - public static class Program + public class Program { public static async Task Main(string[] args) { Console.WriteLine($"DeveLanCacheUI_SteamDepotFinder version: {typeof(Program).Assembly.GetName().Version}"); - Console.WriteLine("Finding Depots..."); + using var loggerFactory = LoggerFactory.Create(builder => + { + builder + .AddFilter("Microsoft", LogLevel.Warning) + .AddFilter("System", LogLevel.Warning) + .AddFilter("DeveLanCacheUI_SteamDepotFinder", LogLevel.Information) + .AddConsole(); + }); + + var logger = loggerFactory.CreateLogger(); + logger.LogInformation("Starting processing..."); + + var steamSession = new Steam3Session(loggerFactory.CreateLogger()); + steamSession.LoginToSteam(); + var appInfoHandler = new AppInfoHandler(steamSession, loggerFactory.CreateLogger()); + + var steamDepotObtainer = new SteamDepotObtainer(steamSession, appInfoHandler, loggerFactory.CreateLogger()); + + await steamDepotObtainer.GoObtainDepotsAndWriteToFile(); - int retries = 0; - while (true) - { - try - { - var qrCodeLoginner = new QrCodeDingLogin(); - await qrCodeLoginner.GoLogin(); - break; - } - catch (TimeoutException ex) - { - Console.WriteLine("Timeout, retrying..."); - retries++; - } - - } - - Console.WriteLine($"Application completed with {retries} retries"); //For some reason threads remain running Environment.Exit(0); diff --git a/DeveLanCacheUI_SteamDepotFinder/DeveLanCacheUI_SteamDepotFinder.csproj b/DeveLanCacheUI_SteamDepotFinder/DeveLanCacheUI_SteamDepotFinder.csproj index 64ad33c..f18fdfa 100644 --- a/DeveLanCacheUI_SteamDepotFinder/DeveLanCacheUI_SteamDepotFinder.csproj +++ b/DeveLanCacheUI_SteamDepotFinder/DeveLanCacheUI_SteamDepotFinder.csproj @@ -8,6 +8,7 @@ + diff --git a/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/AppInfoHandler.cs b/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/AppInfoHandler.cs new file mode 100644 index 0000000..31b795f --- /dev/null +++ b/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/AppInfoHandler.cs @@ -0,0 +1,209 @@ +using DeveLanCacheUI_SteamDepotFinder.Steam; +using Microsoft.Extensions.Logging; +using SteamKit2; + +namespace DeveLanCacheUI_SteamDepotFinder.NewVersion.Steam +{ + /// + /// Responsible for retrieving application metadata from Steam + /// + /// Adapted from : https://github.com/tpill90/steam-lancache-prefill/blob/master/SteamPrefill/Handlers/AppInfoHandler.cs + /// + public class AppInfoHandler : ISteamAppObtainerService + { + private readonly Steam3Session _steam3Session; + private readonly ILogger _logger; + + public AppInfoHandler(Steam3Session steam3Session, ILogger logger) + { + _steam3Session = steam3Session; + _logger = logger; + } + + private Dictionary _cachedAppNames = new Dictionary(); + + public App? GetSteamAppById(uint? steamAppId) + { + if (steamAppId != null && _cachedAppNames.TryGetValue(steamAppId.Value, out var app)) + { + return app; + } + return null; + } + + //TODO comment + public async Task> EnsureAppsAreLoaded() + { + _logger.LogInformation("Retrieving all known AppIds"); + + using var steamAppsApi = _steam3Session.Configuration.GetAsyncWebAPIInterface("ISteamApps"); + var response = await steamAppsApi.CallAsync(HttpMethod.Get, "GetAppList", 2); + + var apiApps = response["apps"].Children.Select(app => + new App() + { + appid = app["appid"].AsUnsignedInteger(), + name = app["name"].AsString() ?? "Unknown" + } + ).ToList(); + + _cachedAppNames = apiApps.DistinctBy(t => t.appid).ToDictionary(t => t.appid, t => t); + + _logger.LogInformation("Retrieved {appCount} apps", apiApps.Count); + return apiApps; + } + + public async Task> RetrieveAllAppIds2() + { + return _cachedAppNames.Values.ToList(); + } + + /// + /// Retrieves the latest AppInfo for multiple apps at the same time. One large request containing multiple apps is significantly faster + /// than multiple individual requests, as it seems that there is a minimum threshold for how quickly steam will return results. + /// + /// The list of App Ids to retrieve info for + public async Task> BulkLoadAppInfoAsync(List appIdsToLoad) + { + if (!appIdsToLoad.Any()) + { + return new List(); + } + + // Some apps will require an additional "access token" in order to retrieve their app metadata + var accessTokensResponse = await _steam3Session.SteamAppsApi.PICSGetAccessTokens(appIdsToLoad, new List()).ToTask(); + var appTokens = accessTokensResponse.AppTokens; + + // Build out the requests + var requests = new List(); + foreach (var appId in appIdsToLoad) + { + var request = new SteamApps.PICSRequest(appId); + if (appTokens.ContainsKey(appId)) + { + request.AccessToken = appTokens[appId]; + } + requests.Add(request); + } + + // Finally request the metadata from steam + var resultSet = await _steam3Session.SteamAppsApi.PICSGetProductInfo(requests, new List()).ToTask(); + + var appInfos = resultSet.Results.SelectMany(e => e.Apps).ToList(); + + var toReturn = new List(); + + foreach (var a in appInfos) + { + var depots = a.Value.KeyValues["depots"]; + + var updatedApp = new App() + { + appid = a.Value.KeyValues["appid"].AsUnsignedInteger(), + name = a.Value.KeyValues["common"]?["name"]?.AsString() ?? "Unknown" + }; + + _cachedAppNames[updatedApp.appid] = updatedApp; + + foreach (var dep in depots.Children) + { + if (uint.TryParse(dep.Name, out var depotUint) && dep.Value == null) + { + if (dep.Children.Any(t => t.Name == "depotfromapp")) + { + var depfromappString = dep.Children.First(t => t.Name == "depotfromapp").AsString(); + + //Some apps have some strange characters in the depot id's: https://steamdb.info/app/1106980/depots/ + var depfromappStringNumberified = new string(depfromappString?.Where(t => char.IsDigit(t)).ToArray()); + var worked2 = uint.TryParse(depfromappStringNumberified, out var depfromapp); + + //Assume that if depfromapp == 0, it's a redistributable that we've already obtained elsewhere + //Example: https://steamdb.info/app/2203540/depots/ + if (worked2 && depfromapp != 0) + { + //var worked3 = SteamApi.SteamAppDict.TryGetValue(depfromapp, out var appNameThing2); + //string appName2 = worked3 ? appNameThing2!.name : "unknown"; + + //var outputString = ToOutputStringSanitized(depfromappStringNumberified, appName2, dep.Name); + + var csv = new SteamDepotEnricherCSVModel() + { + SteamAppId = depfromapp, + SteamAppName = "", + SteamDepotId = depotUint + }; + + toReturn.Add(csv); + } + } + else + { + var csv = new SteamDepotEnricherCSVModel() + { + SteamAppId = a.Key, + SteamAppName = a.Value.KeyValues["common"]?["name"]?.AsString() ?? "", + SteamDepotId = depotUint + }; + + toReturn.Add(csv); + } + } + } + } + + //This cleans all callbacks. If we don't do this loading all apps takes around 7gb and never cleans up + _steam3Session.CallbackManager.RunWaitAllCallbacks(timeout: TimeSpan.FromMilliseconds(0)); + + //// Handling unknown apps + //List unknownAppIds = resultSet.Results.SelectMany(e => e.UnknownApps).ToList(); + //foreach (var unknownAppId in unknownAppIds) + //{ + // LoadedAppInfos.TryAdd(unknownAppId, new AppInfo(unknownAppId, "Unknown")); + //} + + var toReturn2 = toReturn + .GroupBy(p => new { p.SteamAppId, p.SteamDepotId }) + .Select(g => g.First()) + .ToList(); + + return toReturn2; + } + + ///// + ///// Steam stores all DLCs for a game as separate "apps", so they must be loaded after the game's AppInfo has been retrieved, + ///// and the list of DLC AppIds are known. + ///// + ///// Once the DLC apps are loaded, the final combined depot list (both the app + dlc apps) will be built. + ///// + //private async Task FetchDlcAppInfoAsync() + //{ + // var dlcAppIds = LoadedAppInfos.Values.SelectMany(e => e.DlcAppIds).ToList(); + // var containingAppIds = LoadedAppInfos.Values.Where(e => e.Type == AppType.Game) + // .SelectMany(e => e.Depots) + // .Select(e => e.ContainingAppId) + // .ToList(); + + // var idsToLoad = containingAppIds.Union(dlcAppIds).ToList(); + // await BulkLoadAppInfoAsync(idsToLoad); + + // // Builds out the list of all depots for each game, including depots from all related DLCs + // // DLCs are stored as separate "apps", so their info comes back separately. + // foreach (var app in LoadedAppInfos.Values.Where(e => e.Type == AppType.Game)) + // { + // foreach (var dlcAppId in app.DlcAppIds) + // { + // var dlcApp = GetAppInfo(dlcAppId); + // var dlcDepots = dlcApp.Depots; + // app.Depots.AddRange(dlcDepots); + + // // Clear out the dlc app's depots so that they dont get duplicates added + // dlcDepots.Clear(); + // } + + // var distinctDepots = app.Depots.DistinctBy(e => e.DepotId).ToList(); + // app.Depots.Clear(); + // app.Depots.AddRange(distinctDepots); + // } + //} + } +} \ No newline at end of file diff --git a/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/DepotInformationThing.cs b/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/DepotInformationThing.cs new file mode 100644 index 0000000..44746c8 --- /dev/null +++ b/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/DepotInformationThing.cs @@ -0,0 +1,12 @@ +using static SteamKit2.Internal.CContentBuilder_CommitAppBuild_Request; + +namespace DeveLanCacheUI_SteamDepotFinder.NewVersion.Steam +{ + public record DepotInformationThing(uint AppId, string? AppName, uint DepotId) + { + public string ToCsvString() + { + return $"{AppId};{AppName?.Replace(";", ":") ?? ""};{DepotId}"; + } + } +} \ No newline at end of file diff --git a/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/Exceptions/SteamConnectionException.cs b/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/Exceptions/SteamConnectionException.cs new file mode 100644 index 0000000..9982077 --- /dev/null +++ b/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/Exceptions/SteamConnectionException.cs @@ -0,0 +1,22 @@ +using System.Runtime.Serialization; + +namespace DeveLanCacheUI_SteamDepotFinder.NewVersion.Steam.Exceptions +{ + public class SteamConnectionException : Exception + { + public SteamConnectionException() + { + + } + + public SteamConnectionException(string message) : base(message) + { + + } + + public SteamConnectionException(string message, Exception inner) : base(message, inner) + { + + } + } +} \ No newline at end of file diff --git a/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/Exceptions/SteamLoginException.cs b/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/Exceptions/SteamLoginException.cs new file mode 100644 index 0000000..331a9bc --- /dev/null +++ b/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/Exceptions/SteamLoginException.cs @@ -0,0 +1,20 @@ +namespace DeveLanCacheUI_SteamDepotFinder.NewVersion.Steam.Exceptions +{ + public class SteamLoginException : Exception + { + public SteamLoginException() + { + + } + + public SteamLoginException(string message) : base(message) + { + + } + + public SteamLoginException(string message, Exception inner) : base(message, inner) + { + + } + } +} \ No newline at end of file diff --git a/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/ISteamAppObtainerService.cs b/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/ISteamAppObtainerService.cs new file mode 100644 index 0000000..8ba0770 --- /dev/null +++ b/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/ISteamAppObtainerService.cs @@ -0,0 +1,9 @@ +using DeveLanCacheUI_SteamDepotFinder.Steam; + +namespace DeveLanCacheUI_SteamDepotFinder.NewVersion.Steam +{ + public interface ISteamAppObtainerService + { + App? GetSteamAppById(uint? steamAppId); + } +} diff --git a/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/Steam3Session.cs b/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/Steam3Session.cs new file mode 100644 index 0000000..367838c --- /dev/null +++ b/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/Steam3Session.cs @@ -0,0 +1,197 @@ +using DeveLanCacheUI_SteamDepotFinder.NewVersion.Steam.Exceptions; +using Microsoft.Extensions.Logging; +using SteamKit2; +using SteamKit2.CDN; +using System.Diagnostics.CodeAnalysis; + +namespace DeveLanCacheUI_SteamDepotFinder.NewVersion.Steam +{ + /// + /// Taken and adapted from: + /// https://github.com/tpill90/steam-lancache-prefill/blob/master/SteamPrefill/Handlers/Steam/Steam3Session.cs + /// + public sealed class Steam3Session : IDisposable + { + private readonly ILogger _logger; + + #region Member fields + + // Steam services + private readonly SteamClient _steamClient; + private readonly SteamUser _steamUser; + public readonly SteamApps SteamAppsApi; + public readonly SteamConfiguration Configuration; + public readonly Client CdnClient; + public readonly CallbackManager CallbackManager; + + public bool LoggedInToSteam { get; private set; } + + #endregion + + public Steam3Session(ILogger logger) + { + _logger = logger; + + _steamClient = new SteamClient(SteamConfiguration.Create(e => e.WithConnectionTimeout(TimeSpan.FromSeconds(120)))); + Configuration = _steamClient.Configuration; + _steamUser = _steamClient.GetHandler(); + SteamAppsApi = _steamClient.GetHandler(); + + CallbackManager = new CallbackManager(_steamClient); + + // This callback is triggered when SteamKit2 makes a successful connection + CallbackManager.Subscribe(e => + { + _isConnecting = false; + _disconnected = false; + }); + // If a connection attempt fails in anyway, SteamKit2 notifies of the failure with a "disconnect" + CallbackManager.Subscribe(e => + { + _isConnecting = false; + _disconnected = true; + }); + + CallbackManager.Subscribe(loggedOn => + { + _loggedOnCallbackResult = loggedOn; + }); + + CdnClient = new Client(_steamClient); + } + + public void LoginToSteam() + { + _logger.LogInformation("Starting Steam login!"); + + int retryCount = 0; + bool logonSuccess = false; + while (!logonSuccess) + { + CallbackManager.RunWaitAllCallbacks(timeout: TimeSpan.FromMilliseconds(50)); + + _logger.LogInformation("Connecting to Steam..."); + ConnectToSteam(); + + var logonResult = AttemptSteamLogin(); + logonSuccess = HandleLogonResult(logonResult); + + retryCount++; + if (retryCount == 5) + { + throw new SteamLoginException("Unable to login to Steam! Try again in a few moments..."); + } + } + + LoggedInToSteam = true; + _logger.LogInformation("Steam session initialization complete!"); + } + + #region Connecting to Steam + + // Used to busy wait until the connection attempt finishes in either a success or failure + private bool _isConnecting; + + /// + /// Attempts to establish a connection to the Steam network. + /// Retries if necessary until successful connection is established + /// + /// Throws if unable to connect to Steam + private void ConnectToSteam() + { + var timeoutAfter = DateTime.Now.AddSeconds(30); + + // Busy waiting until the client has a successful connection established + while (!_steamClient.IsConnected) + { + _isConnecting = true; + _steamClient.Connect(); + + // Busy waiting until SteamKit2 either succeeds/fails the connection attempt + while (_isConnecting) + { + CallbackManager.RunWaitAllCallbacks(timeout: TimeSpan.FromMilliseconds(50)); + if (DateTime.Now > timeoutAfter) + { + throw new SteamConnectionException("Timeout connecting to Steam... Try again in a few moments"); + } + } + } + _logger.LogInformation("Connected to Steam!"); + } + + #endregion + + #region Logging into Steam + + private SteamUser.LoggedOnCallback _loggedOnCallbackResult; + private SteamUser.LoggedOnCallback AttemptSteamLogin() + { + var timeoutAfter = DateTime.Now.AddSeconds(30); + // Need to reset this global result value, as it will be populated once the logon callback completes + _loggedOnCallbackResult = null; + + _steamUser.LogOnAnonymous(); + + // Busy waiting for the callback to complete, then we can return the callback value synchronously + while (_loggedOnCallbackResult == null) + { + CallbackManager.RunWaitAllCallbacks(timeout: TimeSpan.FromMilliseconds(50)); + if (DateTime.Now > timeoutAfter) + { + throw new SteamLoginException("Timeout logging into Steam... Try again in a few moments"); + } + } + return _loggedOnCallbackResult; + } + + [SuppressMessage("", "VSTHRD002:Synchronously waiting on tasks may cause deadlocks.", Justification = "Its not possible for this callback method to be async, must block synchronously")] + private bool HandleLogonResult(SteamUser.LoggedOnCallback logonResult) + { + var loggedOn = logonResult; + + if (loggedOn.Result == EResult.ServiceUnavailable) + { + throw new SteamLoginException($"Unable to login to Steam : Service is unavailable"); + } + if (loggedOn.Result != EResult.OK) + { + throw new SteamLoginException($"Unable to login to Steam. An unknown error occurred : {loggedOn.Result}"); + } + + _logger.LogInformation($"Logged in anonymously to Steam"); + + return true; + } + + private bool _disconnected = true; + public void Disconnect() + { + if (_disconnected) + { + _logger.LogInformation("Already disconnected from Steam"); + return; + } + + _disconnected = false; + _steamClient.Disconnect(); + + _logger.LogInformation("Disconnecting from Steam.."); + while (!_disconnected) + { + CallbackManager.RunWaitAllCallbacks(TimeSpan.FromMilliseconds(100)); + } + _logger.LogInformation("Disconnected from Steam!"); + LoggedInToSteam = false; + } + + #endregion + + public void Dispose() + { + _logger.LogInformation($"Disposing {nameof(Steam3Session)}..."); + Disconnect(); + CdnClient.Dispose(); + } + } +} \ No newline at end of file diff --git a/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/SteamDepotEnricherCSVModel.cs b/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/SteamDepotEnricherCSVModel.cs new file mode 100644 index 0000000..9132c40 --- /dev/null +++ b/DeveLanCacheUI_SteamDepotFinder/NewVersion/Steam/SteamDepotEnricherCSVModel.cs @@ -0,0 +1,9 @@ +namespace DeveLanCacheUI_SteamDepotFinder.NewVersion.Steam +{ + public class SteamDepotEnricherCSVModel + { + public required uint SteamAppId { get; init; } + public required string SteamAppName { get; init; } + public required uint SteamDepotId { get; init; } + } +} diff --git a/DeveLanCacheUI_SteamDepotFinder/NewVersion/SteamDepotObtainer.cs b/DeveLanCacheUI_SteamDepotFinder/NewVersion/SteamDepotObtainer.cs new file mode 100644 index 0000000..e335327 --- /dev/null +++ b/DeveLanCacheUI_SteamDepotFinder/NewVersion/SteamDepotObtainer.cs @@ -0,0 +1,76 @@ +using DeveLanCacheUI_SteamDepotFinder.NewVersion.Steam; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DeveLanCacheUI_SteamDepotFinder.NewVersion +{ + public class SteamDepotObtainer + { + private readonly Steam3Session _steam3Session; + private readonly AppInfoHandler _appInfoHandler; + private readonly ILogger _logger; + + public SteamDepotObtainer(Steam3Session steam3Session, AppInfoHandler appInfoHandler, ILogger logger) + { + _steam3Session = steam3Session; + _appInfoHandler = appInfoHandler; + _logger = logger; + } + + public async Task GoObtainDepotsAndWriteToFile() + { + _logger.LogInformation("Ensuring apps are loaded..."); + await _appInfoHandler.EnsureAppsAreLoaded(); + _logger.LogInformation("Ensuring apps are loaded completed"); + + var picsChangesResult = await _steam3Session.SteamAppsApi.PICSGetChangesSince().ToTask(); + var currentChangeNumber = picsChangesResult.CurrentChangeNumber; + var _currentChangeNumber = currentChangeNumber; + var changedApps = (await _appInfoHandler.RetrieveAllAppIds2()).Select(t => t.appid).ToList(); + + _logger.LogInformation($"Changelist 0 -> {_currentChangeNumber} ({changedApps.Count} apps)"); + + _logger.LogInformation($"Processing everything in bulk..."); + + var superList = new List(); + + for (var i = 0; i < changedApps.Count; i += 1000) + { + _logger.LogInformation($"Processing {i} -> {i + 1000} / {changedApps.Count}"); + + var currentBatch = changedApps.Skip(i).Take(1000).ToList(); + var appInfos = await _appInfoHandler.BulkLoadAppInfoAsync(currentBatch); + + foreach (var depot in appInfos) + { + superList.Add(new DepotInformationThing(depot.SteamAppId, string.IsNullOrWhiteSpace(depot.SteamAppName) ? "unknown" : depot.SteamAppName, depot.SteamDepotId)); + } + } + + _logger.LogInformation("Obtaining depots completed, total depots: " + superList.Count); + + _logger.LogInformation("Filtering duplicate depots..."); + + var superListFiltered = superList.DistinctBy(t => new { t.DepotId, t.AppId }).OrderBy(t => t.AppId).ThenBy(t => t.DepotId).ThenBy(t => t.AppName).ToList(); + + _logger.LogInformation("Filtering duplicate depots completed, total depots: " + superListFiltered.Count); + + _logger.LogInformation("Writing depots to file..."); + + var sb = new StringBuilder(); + foreach (var depot in superListFiltered) + { + sb.AppendLine(depot.ToCsvString()); + } + + var depots = sb.ToString(); + Directory.CreateDirectory("output"); + var outputPath = Path.Combine("output", "app-depot-output-cleaned.csv"); + File.WriteAllText(outputPath, depots); + } + } +} diff --git a/DeveLanCacheUI_SteamDepotFinder/QrCodeDingLogin.cs b/DeveLanCacheUI_SteamDepotFinder/QrCodeDingLogin.cs index de34439..98cf773 100644 --- a/DeveLanCacheUI_SteamDepotFinder/QrCodeDingLogin.cs +++ b/DeveLanCacheUI_SteamDepotFinder/QrCodeDingLogin.cs @@ -1,389 +1,389 @@ -using DeveLanCacheUI_SteamDepotFinder.Steam; -using QRCoder; -using SteamKit2; -using SteamKit2.Authentication; -using static SteamKit2.SteamApps; +//using DeveLanCacheUI_SteamDepotFinder.Steam; +//using QRCoder; +//using SteamKit2; +//using SteamKit2.Authentication; +//using static SteamKit2.SteamApps; -namespace DeveLanCacheUI_SteamDepotFinder -{ - public class QrCodeDingLogin - { - private readonly SteamClient steamClient; - private readonly CallbackManager manager; - private bool isRunning; - private readonly SteamUser? steamUser; +//namespace DeveLanCacheUI_SteamDepotFinder +//{ +// public class QrCodeDingLogin +// { +// private readonly SteamClient steamClient; +// private readonly CallbackManager manager; +// private bool isRunning; +// private readonly SteamUser? steamUser; - private const string TokenFilePath = "token.txt"; +// private const string TokenFilePath = "token.txt"; - //AppId;AppName;DepotId - string outputFolder = "output"; - string outputFilePath = "output/app-depot-output.csv"; - string outputFilePathCleaned = "output/app-depot-output-cleaned.csv"; - string lastProcessedStoreFile = "lastprocessed.txt"; - uint? lastProcessedTemp = null; +// //AppId;AppName;DepotId +// string outputFolder = "output"; +// string outputFilePath = "output/app-depot-output.csv"; +// string outputFilePathCleaned = "output/app-depot-output-cleaned.csv"; +// string lastProcessedStoreFile = "lastprocessed.txt"; +// uint? lastProcessedTemp = null; - int deniedCount = 0; - int processedCount = 0; - private bool loggedOn; +// int deniedCount = 0; +// int processedCount = 0; +// private bool loggedOn; - public QrCodeDingLogin() - { - if (!Directory.Exists(outputFolder)) - { - Directory.CreateDirectory(outputFolder); - } +// public QrCodeDingLogin() +// { +// if (!Directory.Exists(outputFolder)) +// { +// Directory.CreateDirectory(outputFolder); +// } - // create our steamclient instance - steamClient = new SteamClient(); +// // create our steamclient instance +// steamClient = new SteamClient(); - // create the callback manager which will route callbacks to function calls - manager = new CallbackManager(steamClient); +// // create the callback manager which will route callbacks to function calls +// manager = new CallbackManager(steamClient); - // get the steamuser handler, which is used for logging on after successfully connecting - steamUser = steamClient.GetHandler(); +// // get the steamuser handler, which is used for logging on after successfully connecting +// steamUser = steamClient.GetHandler(); - // register a few callbacks we're interested in - // these are registered upon creation to a callback manager, which will then route the callbacks - // to the functions specified - manager.Subscribe(OnConnected); - manager.Subscribe(OnDisconnected); +// // register a few callbacks we're interested in +// // these are registered upon creation to a callback manager, which will then route the callbacks +// // to the functions specified +// manager.Subscribe(OnConnected); +// manager.Subscribe(OnDisconnected); - manager.Subscribe(OnLoggedOn); - manager.Subscribe(OnLoggedOff); +// manager.Subscribe(OnLoggedOn); +// manager.Subscribe(OnLoggedOff); - manager.Subscribe(PicsCallback); +// manager.Subscribe(PicsCallback); - manager.Subscribe(OnPICSTokens); - } +// manager.Subscribe(OnPICSTokens); +// } - public async Task GoLogin() - { - uint? lastAppIdProcessed = null; - if (File.Exists(lastProcessedStoreFile)) - { - var lastAppProcessed = File.ReadAllText(lastProcessedStoreFile).Trim(); - if (!string.IsNullOrWhiteSpace(lastAppProcessed)) - { - lastAppIdProcessed = uint.Parse(lastAppProcessed); - } - } +// public async Task GoLogin() +// { +// uint? lastAppIdProcessed = null; +// if (File.Exists(lastProcessedStoreFile)) +// { +// var lastAppProcessed = File.ReadAllText(lastProcessedStoreFile).Trim(); +// if (!string.IsNullOrWhiteSpace(lastAppProcessed)) +// { +// lastAppIdProcessed = uint.Parse(lastAppProcessed); +// } +// } - Console.WriteLine($"Starting processing from app: {lastAppIdProcessed}"); +// Console.WriteLine($"Starting processing from app: {lastAppIdProcessed}"); - isRunning = true; +// isRunning = true; - Console.WriteLine("Connecting to Steam..."); +// Console.WriteLine("Connecting to Steam..."); - // initiate the connection - steamClient.Connect(); +// // initiate the connection +// steamClient.Connect(); - while (!loggedOn) - { - manager.RunWaitCallbacks(TimeSpan.FromSeconds(1)); - } +// while (!loggedOn) +// { +// manager.RunWaitCallbacks(TimeSpan.FromSeconds(1)); +// } - int i = 0; - int setSize = 1000; +// int i = 0; +// int setSize = 1000; - var allSteamApps = SteamApi.SteamApiData.applist.apps; +// var allSteamApps = SteamApi.SteamApiData.applist.apps; - if (lastAppIdProcessed != null) - { - var allSteamAppsToProcess = allSteamApps.TakeWhile(t => t.appid != lastAppIdProcessed).ToList(); - i = allSteamAppsToProcess.Count + 1; - } +// if (lastAppIdProcessed != null) +// { +// var allSteamAppsToProcess = allSteamApps.TakeWhile(t => t.appid != lastAppIdProcessed).ToList(); +// i = allSteamAppsToProcess.Count + 1; +// } - processedCount = i; +// processedCount = i; - DateTime lastUpdate = DateTime.Now; +// DateTime lastUpdate = DateTime.Now; - // create our callback handling loop - while (isRunning) - { - // in order for the callbacks to get routed, they need to be handled by the manager - manager.RunWaitCallbacks(TimeSpan.FromSeconds(1)); +// // create our callback handling loop +// while (isRunning) +// { +// // in order for the callbacks to get routed, they need to be handled by the manager +// manager.RunWaitCallbacks(TimeSpan.FromSeconds(1)); - //We need to wait untill all stuff has processed asyncly - if (processedCount + deniedCount == i) - { - if (lastProcessedTemp != -1) - { - File.WriteAllText(lastProcessedStoreFile, lastProcessedTemp.ToString()); - } +// //We need to wait untill all stuff has processed asyncly +// if (processedCount + deniedCount == i) +// { +// if (lastProcessedTemp != -1) +// { +// File.WriteAllText(lastProcessedStoreFile, lastProcessedTemp.ToString()); +// } - Console.WriteLine($"Progress: {i}/{allSteamApps.Length} {Math.Round(i / (double)allSteamApps.Length * 100.0, 2)}%"); +// Console.WriteLine($"Progress: {i}/{allSteamApps.Length} {Math.Round(i / (double)allSteamApps.Length * 100.0, 2)}%"); - if (i == allSteamApps.Length) - { - break; - } +// if (i == allSteamApps.Length) +// { +// break; +// } - var steamApps = steamClient.GetHandler(); +// var steamApps = steamClient.GetHandler(); - var set = allSteamApps.Skip(i).Take(setSize).ToList(); - var appsToGet = set.Select(t => t.appid).ToList(); +// var set = allSteamApps.Skip(i).Take(setSize).ToList(); +// var appsToGet = set.Select(t => t.appid).ToList(); - lastProcessedTemp = set.Last().appid; +// lastProcessedTemp = set.Last().appid; - lastUpdate = DateTime.Now; - await steamApps.PICSGetAccessTokens(appsToGet, new List()); - i += set.Count; - } - else if (lastUpdate.AddSeconds(60) < DateTime.Now) - { - Console.WriteLine("No update within 60 seconds. Killing everything and retrying...."); - DisconnectAndWaitForDisconnectedMax30Seconds(); - throw new TimeoutException("no response, please retry"); - } - } +// lastUpdate = DateTime.Now; +// await steamApps.PICSGetAccessTokens(appsToGet, new List()); +// i += set.Count; +// } +// else if (lastUpdate.AddSeconds(60) < DateTime.Now) +// { +// Console.WriteLine("No update within 60 seconds. Killing everything and retrying...."); +// DisconnectAndWaitForDisconnectedMax30Seconds(); +// throw new TimeoutException("no response, please retry"); +// } +// } - DisconnectAndWaitForDisconnectedMax30Seconds(); +// DisconnectAndWaitForDisconnectedMax30Seconds(); - Console.WriteLine("Cleaning up everything..."); +// Console.WriteLine("Cleaning up everything..."); - var allLines = File.ReadAllLines(outputFilePath); - Console.WriteLine($"Total lines: {allLines.Length}"); - var allLinesDistinct = allLines.Distinct().ToList(); - Console.WriteLine($"Duplicate lines removed (E.g. SteamWorks redist stuff): {allLines.Length - allLinesDistinct.Count}"); +// var allLines = File.ReadAllLines(outputFilePath); +// Console.WriteLine($"Total lines: {allLines.Length}"); +// var allLinesDistinct = allLines.Distinct().ToList(); +// Console.WriteLine($"Duplicate lines removed (E.g. SteamWorks redist stuff): {allLines.Length - allLinesDistinct.Count}"); - var selectified = allLinesDistinct.Select(t => - { - var splitted = t.Split(';'); - var canParseAppId = int.TryParse(splitted[0], out var appId); - var canParseDepotId = int.TryParse(splitted[1], out var depotId); - return new { Original = t, AppId = canParseAppId ? appId : 0, DepotId = canParseDepotId ? depotId : 0 }; - }).ToList(); +// var selectified = allLinesDistinct.Select(t => +// { +// var splitted = t.Split(';'); +// var canParseAppId = int.TryParse(splitted[0], out var appId); +// var canParseDepotId = int.TryParse(splitted[1], out var depotId); +// return new { Original = t, AppId = canParseAppId ? appId : 0, DepotId = canParseDepotId ? depotId : 0 }; +// }).ToList(); - Console.WriteLine("Sorting..."); +// Console.WriteLine("Sorting..."); - var selectifiedSorted = selectified.OrderBy(t => t.AppId).ThenBy(t => t.DepotId).Select(t => t.Original).ToList(); +// var selectifiedSorted = selectified.OrderBy(t => t.AppId).ThenBy(t => t.DepotId).Select(t => t.Original).ToList(); - Console.WriteLine($"Writing output to: {outputFilePathCleaned}"); - File.WriteAllLines(outputFilePathCleaned, selectifiedSorted); +// Console.WriteLine($"Writing output to: {outputFilePathCleaned}"); +// File.WriteAllLines(outputFilePathCleaned, selectifiedSorted); - Console.WriteLine("App exitted"); - } +// Console.WriteLine("App exitted"); +// } - private void DisconnectAndWaitForDisconnectedMax30Seconds() - { - Console.WriteLine("Disconnecting..."); - steamClient.Disconnect(); +// private void DisconnectAndWaitForDisconnectedMax30Seconds() +// { +// Console.WriteLine("Disconnecting..."); +// steamClient.Disconnect(); - for (int y = 0; y < 30; y++) - { - if (isRunning == false) - { - break; - } - Console.WriteLine($"Waiting for SteamClient to Disconnect... {y}"); +// for (int y = 0; y < 30; y++) +// { +// if (isRunning == false) +// { +// break; +// } +// Console.WriteLine($"Waiting for SteamClient to Disconnect... {y}"); - // in order for the callbacks to get routed, they need to be handled by the manager - manager.RunWaitCallbacks(TimeSpan.FromSeconds(1)); - } - } +// // in order for the callbacks to get routed, they need to be handled by the manager +// manager.RunWaitCallbacks(TimeSpan.FromSeconds(1)); +// } +// } - async void OnConnected(SteamClient.ConnectedCallback callback) - { - //TokenStore? token = null; +// async void OnConnected(SteamClient.ConnectedCallback callback) +// { +// //TokenStore? token = null; - //var envToken = Environment.GetEnvironmentVariable("STEAMTOKEN"); - - //if (envToken != null) - //{ - // token = JsonSerializer.Deserialize(envToken); - //} - //else if (File.Exists(TokenFilePath)) - //{ - // var tokenStoreSerialized = File.ReadAllText(TokenFilePath); - // token = JsonSerializer.Deserialize(tokenStoreSerialized); - //} +// //var envToken = Environment.GetEnvironmentVariable("STEAMTOKEN"); + +// //if (envToken != null) +// //{ +// // token = JsonSerializer.Deserialize(envToken); +// //} +// //else if (File.Exists(TokenFilePath)) +// //{ +// // var tokenStoreSerialized = File.ReadAllText(TokenFilePath); +// // token = JsonSerializer.Deserialize(tokenStoreSerialized); +// //} - steamUser.LogOnAnonymous(); +// steamUser.LogOnAnonymous(); - //if (token != null) - //{ - // // Logon to Steam with the access token we have received - // steamUser.LogOn(new SteamUser.LogOnDetails - // { - // Username = token.AccountName, - // AccessToken = token.RefreshToken, - // }); - //} - //else - //{ +// //if (token != null) +// //{ +// // // Logon to Steam with the access token we have received +// // steamUser.LogOn(new SteamUser.LogOnDetails +// // { +// // Username = token.AccountName, +// // AccessToken = token.RefreshToken, +// // }); +// //} +// //else +// //{ - // // Start an authentication session by requesting a link - // var authSession = await steamClient.Authentication.BeginAuthSessionViaQRAsync(new AuthSessionDetails()); +// // // Start an authentication session by requesting a link +// // var authSession = await steamClient.Authentication.BeginAuthSessionViaQRAsync(new AuthSessionDetails()); - // // Steam will periodically refresh the challenge url, this callback allows you to draw a new qr code - // authSession.ChallengeURLChanged = () => - // { - // Console.WriteLine(); - // Console.WriteLine("Steam has refreshed the challenge url"); - - // DrawQRCode(authSession); - // }; - - // // Draw current qr right away - // DrawQRCode(authSession); - - // // Starting polling Steam for authentication response - // // This response is later used to logon to Steam after connecting - // var pollResponse = await authSession.PollingWaitForResultAsync(); - - // Console.WriteLine($"Logging in as '{pollResponse.AccountName}'..."); - - // // Logon to Steam with the access token we have received - // steamUser.LogOn(new SteamUser.LogOnDetails - // { - // Username = pollResponse.AccountName, - // AccessToken = pollResponse.RefreshToken, - // }); - - // var tokenStore = new TokenStore() { AccountName = pollResponse.AccountName, RefreshToken = pollResponse.RefreshToken }; - // var tokenStoreSerialized = JsonSerializer.Serialize(tokenStore, new JsonSerializerOptions() { WriteIndented = true }); - // File.WriteAllText(TokenFilePath, tokenStoreSerialized); - //} - } - - void OnDisconnected(SteamClient.DisconnectedCallback callback) - { - Console.WriteLine("Disconnected from Steam"); - - isRunning = false; - } - - async void OnLoggedOn(SteamUser.LoggedOnCallback callback) - { - if (callback.Result != EResult.OK) - { - Console.WriteLine("Unable to logon to Steam: {0} / {1}", callback.Result, callback.ExtendedResult); - - isRunning = false; - return; - } - - Console.WriteLine("Successfully logged on!"); - loggedOn = true; - - - // at this point, we'd be able to perform actions on Steam - - - // for this sample we'll just log off - //steamUser.LogOff(); - } - - void OnLoggedOff(SteamUser.LoggedOffCallback callback) - { - Console.WriteLine("Logged off of Steam: {0}", callback.Result); - } - - - void OnPICSTokens(PICSTokensCallback callback) - { - - foreach (var denied in callback.AppTokensDenied) - { - var theApp = SteamApi.SteamAppDict[denied]; - var outputString = ToOutputStringSanitized(theApp.appid.ToString(), theApp.name, "denied"); - //Console.WriteLine(outputString); - File.AppendAllLines(outputFilePath, new List() { outputString }); - - deniedCount++; - } - - var allPicsRequests = callback.AppTokens.Select(t => new PICSRequest(t.Key, t.Value)).ToList(); - - - var steamApps = steamClient.GetHandler(); - steamApps.PICSGetProductInfo(allPicsRequests, new List(), false); - } - - private void PicsCallback(PICSProductInfoCallback callback) - { - foreach (var a in callback.Apps) - { - var depots = a.Value.KeyValues["depots"]; - - foreach (var dep in depots.Children) - { - if (uint.TryParse(dep.Name, out var _) && dep.Value == null) - { - var worked = SteamApi.SteamAppDict.TryGetValue(a.Key, out var appNameThing); +// // // Steam will periodically refresh the challenge url, this callback allows you to draw a new qr code +// // authSession.ChallengeURLChanged = () => +// // { +// // Console.WriteLine(); +// // Console.WriteLine("Steam has refreshed the challenge url"); + +// // DrawQRCode(authSession); +// // }; + +// // // Draw current qr right away +// // DrawQRCode(authSession); + +// // // Starting polling Steam for authentication response +// // // This response is later used to logon to Steam after connecting +// // var pollResponse = await authSession.PollingWaitForResultAsync(); + +// // Console.WriteLine($"Logging in as '{pollResponse.AccountName}'..."); + +// // // Logon to Steam with the access token we have received +// // steamUser.LogOn(new SteamUser.LogOnDetails +// // { +// // Username = pollResponse.AccountName, +// // AccessToken = pollResponse.RefreshToken, +// // }); + +// // var tokenStore = new TokenStore() { AccountName = pollResponse.AccountName, RefreshToken = pollResponse.RefreshToken }; +// // var tokenStoreSerialized = JsonSerializer.Serialize(tokenStore, new JsonSerializerOptions() { WriteIndented = true }); +// // File.WriteAllText(TokenFilePath, tokenStoreSerialized); +// //} +// } + +// void OnDisconnected(SteamClient.DisconnectedCallback callback) +// { +// Console.WriteLine("Disconnected from Steam"); + +// isRunning = false; +// } + +// async void OnLoggedOn(SteamUser.LoggedOnCallback callback) +// { +// if (callback.Result != EResult.OK) +// { +// Console.WriteLine("Unable to logon to Steam: {0} / {1}", callback.Result, callback.ExtendedResult); + +// isRunning = false; +// return; +// } + +// Console.WriteLine("Successfully logged on!"); +// loggedOn = true; + + +// // at this point, we'd be able to perform actions on Steam + + +// // for this sample we'll just log off +// //steamUser.LogOff(); +// } + +// void OnLoggedOff(SteamUser.LoggedOffCallback callback) +// { +// Console.WriteLine("Logged off of Steam: {0}", callback.Result); +// } + + +// void OnPICSTokens(PICSTokensCallback callback) +// { + +// foreach (var denied in callback.AppTokensDenied) +// { +// var theApp = SteamApi.SteamAppDict[denied]; +// var outputString = ToOutputStringSanitized(theApp.appid.ToString(), theApp.name, "denied"); +// //Console.WriteLine(outputString); +// File.AppendAllLines(outputFilePath, new List() { outputString }); + +// deniedCount++; +// } + +// var allPicsRequests = callback.AppTokens.Select(t => new PICSRequest(t.Key, t.Value)).ToList(); + + +// var steamApps = steamClient.GetHandler(); +// steamApps.PICSGetProductInfo(allPicsRequests, new List(), false); +// } + +// private void PicsCallback(PICSProductInfoCallback callback) +// { +// foreach (var a in callback.Apps) +// { +// var depots = a.Value.KeyValues["depots"]; + +// foreach (var dep in depots.Children) +// { +// if (uint.TryParse(dep.Name, out var _) && dep.Value == null) +// { +// var worked = SteamApi.SteamAppDict.TryGetValue(a.Key, out var appNameThing); - string appName = worked ? appNameThing!.name : "unknown"; - - if (dep.Children.Any(t => t.Name == "depotfromapp")) - { - var depfromappString = dep.Children.First(t => t.Name == "depotfromapp").AsString(); - - //Some apps have some strange characters in the depot id's: https://steamdb.info/app/1106980/depots/ - var depfromappStringNumberified = new string(depfromappString?.Where(t => char.IsDigit(t)).ToArray()); - var worked2 = uint.TryParse(depfromappStringNumberified, out var depfromapp); - - //Assume that if depfromapp == 0, it's a redistributable that we've already obtained elsewhere - //Example: https://steamdb.info/app/2203540/depots/ - if (worked2 && depfromapp != 0) - { - var worked3 = SteamApi.SteamAppDict.TryGetValue(depfromapp, out var appNameThing2); - string appName2 = worked3 ? appNameThing2!.name : "unknown"; - - var outputString = ToOutputStringSanitized(depfromappStringNumberified, appName2, dep.Name); - //Console.WriteLine(outputString); - File.AppendAllLines(outputFilePath, new List() { outputString }); - } - } - else - { - var outputString = ToOutputStringSanitized(a.Key.ToString(), appName, dep.Name); - //Console.WriteLine(outputString); - File.AppendAllLines(outputFilePath, new List() { outputString }); - } - } - } - - processedCount++; - } - } - - public string ToOutputStringSanitized(string appId, string appName, string depotId) - { - if (appId == "0") - { +// string appName = worked ? appNameThing!.name : "unknown"; + +// if (dep.Children.Any(t => t.Name == "depotfromapp")) +// { +// var depfromappString = dep.Children.First(t => t.Name == "depotfromapp").AsString(); + +// //Some apps have some strange characters in the depot id's: https://steamdb.info/app/1106980/depots/ +// var depfromappStringNumberified = new string(depfromappString?.Where(t => char.IsDigit(t)).ToArray()); +// var worked2 = uint.TryParse(depfromappStringNumberified, out var depfromapp); + +// //Assume that if depfromapp == 0, it's a redistributable that we've already obtained elsewhere +// //Example: https://steamdb.info/app/2203540/depots/ +// if (worked2 && depfromapp != 0) +// { +// var worked3 = SteamApi.SteamAppDict.TryGetValue(depfromapp, out var appNameThing2); +// string appName2 = worked3 ? appNameThing2!.name : "unknown"; + +// var outputString = ToOutputStringSanitized(depfromappStringNumberified, appName2, dep.Name); +// //Console.WriteLine(outputString); +// File.AppendAllLines(outputFilePath, new List() { outputString }); +// } +// } +// else +// { +// var outputString = ToOutputStringSanitized(a.Key.ToString(), appName, dep.Name); +// //Console.WriteLine(outputString); +// File.AppendAllLines(outputFilePath, new List() { outputString }); +// } +// } +// } + +// processedCount++; +// } +// } + +// public string ToOutputStringSanitized(string appId, string appName, string depotId) +// { +// if (appId == "0") +// { - } - - appId = appId ?? ""; - appName = appName ?? ""; - depotId = depotId ?? ""; +// } + +// appId = appId ?? ""; +// appName = appName ?? ""; +// depotId = depotId ?? ""; - return $"{appId.Replace(";", ":")};{appName.Replace(";", ":")};{depotId.Replace(";", ":")}"; - } +// return $"{appId.Replace(";", ":")};{appName.Replace(";", ":")};{depotId.Replace(";", ":")}"; +// } - void DrawQRCode(QrAuthSession authSession) - { - Console.WriteLine($"Challenge URL: {authSession.ChallengeURL}"); - Console.WriteLine(); - - // Encode the link as a QR code - var qrGenerator = new QRCodeGenerator(); - var qrCodeData = qrGenerator.CreateQrCode(authSession.ChallengeURL, QRCodeGenerator.ECCLevel.L); - var qrCode = new AsciiQRCode(qrCodeData); - var qrCodeAsAsciiArt = qrCode.GetGraphic(1, drawQuietZones: false); - - Console.WriteLine("Use the Steam Mobile App to sign in via QR code:"); - Console.WriteLine(qrCodeAsAsciiArt); - } - } -} +// void DrawQRCode(QrAuthSession authSession) +// { +// Console.WriteLine($"Challenge URL: {authSession.ChallengeURL}"); +// Console.WriteLine(); + +// // Encode the link as a QR code +// var qrGenerator = new QRCodeGenerator(); +// var qrCodeData = qrGenerator.CreateQrCode(authSession.ChallengeURL, QRCodeGenerator.ECCLevel.L); +// var qrCode = new AsciiQRCode(qrCodeData); +// var qrCodeAsAsciiArt = qrCode.GetGraphic(1, drawQuietZones: false); + +// Console.WriteLine("Use the Steam Mobile App to sign in via QR code:"); +// Console.WriteLine(qrCodeAsAsciiArt); +// } +// } +//} diff --git a/DeveLanCacheUI_SteamDepotFinder/Steam/SteamApi.cs b/DeveLanCacheUI_SteamDepotFinder/Steam/SteamApi.cs index d80ccc9..666f06c 100644 --- a/DeveLanCacheUI_SteamDepotFinder/Steam/SteamApi.cs +++ b/DeveLanCacheUI_SteamDepotFinder/Steam/SteamApi.cs @@ -1,63 +1,72 @@ -using System.Text.Json; - -namespace DeveLanCacheUI_SteamDepotFinder.Steam -{ - public static class SteamApi - { - private static readonly Lazy> _steamAppDict = new Lazy>(() => - { - //.ToDictionary(t => t.appid, t => t) - //Previously we had the code mentioned above but this sometimes resulted in a duplicate appid (still weird but whatever this should solve it) - - var allSteamApps = SteamApiData.applist.apps; - - var outputDict = new Dictionary(); - - foreach (var app in allSteamApps) - { - if (outputDict.ContainsKey(app.appid)) - { - Console.WriteLine($"Found duplicate appid: {app.appid} with name: {app.name}"); - } - else - { - outputDict.Add(app.appid, app); - } - } - - return outputDict; - }); - private static readonly Lazy _steamApiData = new Lazy(LoadSteamApiData); - - public static SteamApiData SteamApiData => _steamApiData.Value; - public static Dictionary SteamAppDict => _steamAppDict.Value; - - private static SteamApiData LoadSteamApiData() - { - var subDir = "Steam"; - string path = Path.Combine(subDir, "SteamData.json"); - if (File.Exists(path)) - { - Console.WriteLine($"Found {path} so reading apps from that file."); - var json = File.ReadAllText(path); - return JsonSerializer.Deserialize(json); - } - else - { - Console.WriteLine($"Could not find {path}, so obtaining new SteamApi Data..."); - using var c = new HttpClient(); - var result = c.GetAsync("https://api.steampowered.com/ISteamApps/GetAppList/v2/").Result; - var resultString = result.Content.ReadAsStringAsync().Result; - Console.WriteLine($"Writing result to file. First 1000 chars: {resultString.Substring(0, 1000)}"); - - if (!Directory.Exists(subDir)) - { - Directory.CreateDirectory(subDir); - } - - File.WriteAllText(path, resultString); - return JsonSerializer.Deserialize(resultString); - } - } - } -} +//using System.Text.Json; + +//namespace DeveLanCacheUI_SteamDepotFinder.Steam +//{ + +// public static class SteamApi +// { +// private static readonly Lazy> _steamAppDict = new Lazy>(() => +// { +// //.ToDictionary(t => t.appid, t => t) +// //Previously we had the code mentioned above but this sometimes resulted in a duplicate appid (still weird but whatever this should solve it) + +// var allSteamApps = SteamApiData.applist.apps; + +// var outputDict = new Dictionary(); + +// foreach (var app in allSteamApps) +// { +// if (outputDict.ContainsKey(app.appid)) +// { +// var theDuplicate = outputDict[app.appid]; +// if (theDuplicate.name != app.name) +// { +// Console.WriteLine($"Found duplicate appid: {app.appid} with name: {app.name} and duplicate name: {theDuplicate.name}"); +// } +// else +// { +// Console.WriteLine($"Found duplicate appid: {app.appid} with name: {app.name}"); +// } +// } +// else +// { +// outputDict.Add(app.appid, app); +// } +// } + +// return outputDict; +// }); +// private static readonly Lazy _steamApiData = new Lazy(LoadSteamApiData); + +// public static SteamApiData SteamApiData => _steamApiData.Value; +// public static Dictionary SteamAppDict => _steamAppDict.Value; + +// private static SteamApiData LoadSteamApiData() +// { +// var subDir = "Steam"; +// string path = Path.Combine(subDir, "SteamData.json"); +// if (File.Exists(path)) +// { +// Console.WriteLine($"Found {path} so reading apps from that file."); +// var json = File.ReadAllText(path); +// return JsonSerializer.Deserialize(json); +// } +// else +// { +// Console.WriteLine($"Could not find {path}, so obtaining new SteamApi Data..."); +// using var c = new HttpClient(); +// var result = c.GetAsync("https://api.steampowered.com/ISteamApps/GetAppList/v2/").Result; +// var resultString = result.Content.ReadAsStringAsync().Result; +// Console.WriteLine($"Writing result to file. First 1000 chars: {resultString.Substring(0, 1000)}"); + +// if (!Directory.Exists(subDir)) +// { +// Directory.CreateDirectory(subDir); +// } + +// File.WriteAllText(path, resultString); +// return JsonSerializer.Deserialize(resultString); +// } +// } +// } +//} diff --git a/DeveLanCacheUI_SteamDepotFinder/Steam/SteamApiData.cs b/DeveLanCacheUI_SteamDepotFinder/Steam/SteamApiData.cs index cef2a0b..51a7c65 100644 --- a/DeveLanCacheUI_SteamDepotFinder/Steam/SteamApiData.cs +++ b/DeveLanCacheUI_SteamDepotFinder/Steam/SteamApiData.cs @@ -1,14 +1,14 @@ namespace DeveLanCacheUI_SteamDepotFinder.Steam { - public class SteamApiData - { - public Applist applist { get; set; } - } + //public class SteamApiData + //{ + // public Applist applist { get; set; } + //} - public class Applist - { - public App[] apps { get; set; } - } + //public class Applist + //{ + // public App[] apps { get; set; } + //} public class App { diff --git a/DeveLanCacheUI_SteamDepotFinder/TokenStore.cs b/DeveLanCacheUI_SteamDepotFinder/TokenStore.cs index f27a4a1..2c30064 100644 --- a/DeveLanCacheUI_SteamDepotFinder/TokenStore.cs +++ b/DeveLanCacheUI_SteamDepotFinder/TokenStore.cs @@ -1,8 +1,8 @@ -namespace DeveLanCacheUI_SteamDepotFinder -{ - public class TokenStore - { - public string AccountName { get; set; } - public string RefreshToken { get; set; } - } -} +//namespace DeveLanCacheUI_SteamDepotFinder +//{ +// public class TokenStore +// { +// public string AccountName { get; set; } +// public string RefreshToken { get; set; } +// } +//}