steam store web parsing for extra DLC

This commit is contained in:
pointfeev 2022-02-25 00:22:27 -05:00
parent 38f721b125
commit cd31ac1cfa
4 changed files with 27 additions and 12 deletions

View file

@ -1,9 +1,12 @@
using System; using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web;
using HtmlAgilityPack; using HtmlAgilityPack;
@ -44,5 +47,18 @@ internal static class HttpClientManager
return null; return null;
} }
internal static async Task ParseSteamStoreDlcAppIds(int appId, List<int> dlcIds)
{
// currently this is only really needed to get DLC that release without changing game buildid (very rare)
// it also finds things which aren't really connected to the game itself, and thus not needed (usually soundtracks, collections, packs, etc.)
HtmlNodeCollection nodes = await GetDocumentNodes(
$"https://store.steampowered.com/dlc/{appId}",
"//div[@class='recommendation']/div/a");
if (nodes is not null)
foreach (HtmlNode node in nodes)
if (int.TryParse(node.Attributes["data-ds-appid"]?.Value, out int dlcAppId) && !dlcIds.Contains(dlcAppId))
dlcIds.Add(dlcAppId);
}
internal static void Cleanup() => httpClient.Dispose(); internal static void Cleanup() => httpClient.Dispose();
} }

View file

@ -98,7 +98,7 @@ internal class ProgramSelection
internal static void ValidateAll() => AllSafe.ForEach(selection => selection.Validate()); internal static void ValidateAll() => AllSafe.ForEach(selection => selection.Validate());
internal static List<ProgramSelection> All => new(); internal static List<ProgramSelection> All = new();
internal static List<ProgramSelection> AllSafe => All.ToList(); internal static List<ProgramSelection> AllSafe => All.ToList();

View file

@ -110,7 +110,7 @@ internal partial class MainForm : CustomForm
Program.Invoke(changelogTreeView, delegate Program.Invoke(changelogTreeView, delegate
{ {
TreeNode change = new(); TreeNode change = new();
change.Text = $"{HttpUtility.HtmlDecode(node.InnerText)}"; change.Text = HttpUtility.HtmlDecode(node.InnerText);
root.Nodes.Add(change); root.Nodes.Add(change);
root.Expand(); root.Expand();
}); });

View file

@ -7,6 +7,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web;
using System.Windows.Forms; using System.Windows.Forms;
using CreamInstaller.Classes; using CreamInstaller.Classes;
@ -15,6 +16,8 @@ using CreamInstaller.Resources;
using Gameloop.Vdf.Linq; using Gameloop.Vdf.Linq;
using HtmlAgilityPack;
namespace CreamInstaller; namespace CreamInstaller;
internal partial class SelectForm : CustomForm internal partial class SelectForm : CustomForm
@ -131,18 +134,19 @@ internal partial class SelectForm : CustomForm
ConcurrentDictionary<int, (string name, string iconStaticId)> dlc = new(); ConcurrentDictionary<int, (string name, string iconStaticId)> dlc = new();
List<Task> dlcTasks = new(); List<Task> dlcTasks = new();
List<int> dlcIds = await SteamCMD.ParseDlcAppIds(appInfo); List<int> dlcIds = await SteamCMD.ParseDlcAppIds(appInfo);
await HttpClientManager.ParseSteamStoreDlcAppIds(appId, dlcIds);
if (dlcIds.Count > 0) if (dlcIds.Count > 0)
{ {
foreach (int id in dlcIds) foreach (int dlcAppId in dlcIds)
{ {
if (Program.Canceled) return; if (Program.Canceled) return;
AddToRemainingDLCs(id.ToString()); AddToRemainingDLCs(dlcAppId.ToString());
Task task = Task.Run(async () => Task task = Task.Run(async () =>
{ {
if (Program.Canceled) return; if (Program.Canceled) return;
string dlcName = null; string dlcName = null;
string dlcIconStaticId = null; string dlcIconStaticId = null;
VProperty dlcAppInfo = await SteamCMD.GetAppInfo(id); VProperty dlcAppInfo = await SteamCMD.GetAppInfo(dlcAppId);
if (dlcAppInfo is not null) if (dlcAppInfo is not null)
{ {
dlcName = dlcAppInfo.Value?.GetChild("common")?.GetChild("name")?.ToString(); dlcName = dlcAppInfo.Value?.GetChild("common")?.GetChild("name")?.ToString();
@ -152,8 +156,8 @@ internal partial class SelectForm : CustomForm
} }
if (Program.Canceled) return; if (Program.Canceled) return;
if (!string.IsNullOrWhiteSpace(dlcName)) if (!string.IsNullOrWhiteSpace(dlcName))
dlc[id] = (dlcName, dlcIconStaticId); dlc[dlcAppId] = (dlcName, dlcIconStaticId);
RemoveFromRemainingDLCs(id.ToString()); RemoveFromRemainingDLCs(dlcAppId.ToString());
progress.Report(++CompleteTasks); progress.Report(++CompleteTasks);
}); });
dlcTasks.Add(task); dlcTasks.Add(task);
@ -168,11 +172,6 @@ internal partial class SelectForm : CustomForm
return; return;
} }
if (Program.Canceled) return; if (Program.Canceled) return;
if (string.IsNullOrWhiteSpace(name))
{
RemoveFromRemainingGames(name);
return;
}
foreach (Task task in dlcTasks) foreach (Task task in dlcTasks)
{ {
if (Program.Canceled) return; if (Program.Canceled) return;