steam store web parsing for extra DLC
This commit is contained in:
parent
38f721b125
commit
cd31ac1cfa
4 changed files with 27 additions and 12 deletions
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
});
|
});
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue