v4.7.0.0 initial

- better support for games that take dlc from other games (such as warhammer 3)
- initial framework for fixing "too many requests" issues
This commit is contained in:
pointfeev 2023-02-18 01:48:14 -05:00
parent 929c6f681f
commit 4e0f361233
7 changed files with 108 additions and 41 deletions

View file

@ -98,20 +98,27 @@ internal sealed class ContextMenuItem : ToolStripMenuItem
private static async Task TryImageIdentifierInfo(ContextMenuItem item, (string id, string iconUrl) imageIdentifierInfo, Action onFail = null)
=> await Task.Run(async () =>
{
(string id, string iconUrl) = imageIdentifierInfo;
string imageIdentifier = "Icon_" + id;
if (Images.TryGetValue(imageIdentifier, out Image image) && image is not null)
item.Image = image;
else
try
{
image = await HttpClientManager.GetImageFromUrl(iconUrl);
if (image is not null)
{
Images[imageIdentifier] = image;
(string id, string iconUrl) = imageIdentifierInfo;
string imageIdentifier = "Icon_" + id;
if (Images.TryGetValue(imageIdentifier, out Image image) && image is not null)
item.Image = image;
}
else
onFail?.Invoke();
{
image = await HttpClientManager.GetImageFromUrl(iconUrl);
if (image is not null)
{
Images[imageIdentifier] = image;
item.Image = image;
}
else
onFail?.Invoke();
}
}
catch
{
// ignored
}
});

View file

@ -4,7 +4,7 @@
<TargetFramework>net7.0-windows</TargetFramework>
<UseWindowsForms>True</UseWindowsForms>
<ApplicationIcon>Resources\ini.ico</ApplicationIcon>
<Version>4.6.1.0</Version>
<Version>4.7.0.0</Version>
<Copyright>2021, pointfeev (https://github.com/pointfeev)</Copyright>
<Company>CreamInstaller</Company>
<Product>Automatic DLC Unlocker Installer &amp; Configuration Generator</Product>

View file

@ -208,15 +208,17 @@ internal sealed partial class SelectForm : CustomForm
while (!Program.Canceled && steamGamesToCheck > 0);
if (Program.Canceled)
return;
string fullGameAppId = null;
string dlcName = null;
string dlcIcon = null;
bool onSteamStore = false;
AppData dlcAppData = await SteamStore.QueryStoreAPI(dlcAppId, true);
if (dlcAppData is not null)
{
dlcName = dlcAppData.name;
dlcIcon = dlcAppData.header_image;
dlcName = dlcAppData.Name;
dlcIcon = dlcAppData.HeaderImage;
onSteamStore = true;
fullGameAppId = dlcAppData.FullGame?.AppId;
}
else
{
@ -229,8 +231,39 @@ internal sealed partial class SelectForm : CustomForm
dlcIconStaticId ??= dlcAppInfo.Value.GetChild("common")?.GetChild("logo")?.ToString();
if (dlcIconStaticId is not null)
dlcIcon = IconGrabber.SteamAppImagesPath + @$"\{dlcAppId}\{dlcIconStaticId}.jpg";
fullGameAppId = dlcAppInfo.Value.GetChild("common")?.GetChild("parent")?.ToString();
}
}
if (fullGameAppId != null && fullGameAppId != appId)
{
string fullGameName = null;
string fullGameIcon = null;
bool fullGameOnSteamStore = false;
AppData fullGameAppData = await SteamStore.QueryStoreAPI(fullGameAppId, true);
if (fullGameAppData is not null)
{
fullGameName = fullGameAppData.Name;
fullGameIcon = fullGameAppData.HeaderImage;
fullGameOnSteamStore = true;
}
else
{
VProperty fullGameAppInfo = await SteamCMD.GetAppInfo(fullGameAppId);
if (fullGameAppInfo is not null)
{
fullGameName = fullGameAppInfo.Value.GetChild("common")?.GetChild("name")?.ToString();
string fullGameIconStaticId = fullGameAppInfo.Value.GetChild("common")?.GetChild("icon")?.ToString();
fullGameIconStaticId ??= fullGameAppInfo.Value.GetChild("common")?.GetChild("logo_small")?.ToString();
fullGameIconStaticId ??= fullGameAppInfo.Value.GetChild("common")?.GetChild("logo")?.ToString();
if (fullGameIconStaticId is not null)
dlcIcon = IconGrabber.SteamAppImagesPath + @$"\{fullGameAppId}\{fullGameIconStaticId}.jpg";
}
}
if (Program.Canceled)
return;
if (!string.IsNullOrWhiteSpace(fullGameName))
dlc[fullGameAppId] = (fullGameOnSteamStore ? DlcType.Steam : DlcType.SteamHidden, fullGameName, fullGameIcon);
}
if (Program.Canceled)
return;
if (string.IsNullOrWhiteSpace(dlcName))
@ -259,17 +292,17 @@ internal sealed partial class SelectForm : CustomForm
if (koaloaderAllCheckBox.Checked)
selection.Koaloader = true;
selection.Id = appId;
selection.Name = appData?.name ?? name;
selection.Name = appData?.Name ?? name;
selection.RootDirectory = gameDirectory;
selection.ExecutableDirectories = await SteamLibrary.GetExecutableDirectories(selection.RootDirectory);
selection.DllDirectories = dllDirectories;
selection.Platform = Platform.Steam;
selection.ProductUrl = "https://store.steampowered.com/app/" + appId;
selection.IconUrl = IconGrabber.SteamAppImagesPath + @$"\{appId}\{appInfo?.Value.GetChild("common")?.GetChild("icon")}.jpg";
selection.SubIconUrl = appData?.header_image ?? IconGrabber.SteamAppImagesPath
selection.SubIconUrl = appData?.HeaderImage ?? IconGrabber.SteamAppImagesPath
+ @$"\{appId}\{appInfo?.Value.GetChild("common")?.GetChild("clienticon")}.ico";
selection.Publisher = appData?.publishers[0] ?? appInfo?.Value.GetChild("extended")?.GetChild("publisher")?.ToString();
selection.WebsiteUrl = appData?.website;
selection.Publisher = appData?.Publishers[0] ?? appInfo?.Value.GetChild("extended")?.GetChild("publisher")?.ToString();
selection.WebsiteUrl = appData?.Website;
if (Program.Canceled)
return;
selectionTreeView.Invoke(delegate
@ -279,7 +312,7 @@ internal sealed partial class SelectForm : CustomForm
TreeNode programNode = treeNodes.Find(s => s.Tag is Platform.Steam && s.Name == appId) ?? new TreeNode();
programNode.Tag = selection.Platform;
programNode.Name = appId;
programNode.Text = appData?.name ?? name;
programNode.Text = appData?.Name ?? name;
programNode.Checked = selection.Enabled;
if (programNode.TreeView is null)
_ = selectionTreeView.Nodes.Add(programNode);

View file

@ -1,36 +1,49 @@
#pragma warning disable IDE1006 // Naming Styles
#pragma warning disable CA1002 // Do not expose generic lists
#pragma warning disable CA1707 // Identifiers should not contain underscores
#pragma warning disable CA2227 // Collection properties should be read only
using System.Collections.Generic;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace CreamInstaller.Platforms.Steam;
public class AppFullGame
{
[JsonProperty(PropertyName = "appid")] public string AppId { get; set; }
[JsonProperty(PropertyName = "name")] public string Name { get; set; }
}
public class AppData
{
public string type { get; set; }
[JsonProperty(PropertyName = "type")] public string Type { get; set; }
public string name { get; set; }
[JsonProperty(PropertyName = "name")] public string Name { get; set; }
public int steam_appid { get; set; }
[JsonProperty(PropertyName = "steam_appid")]
public int SteamAppId { get; set; }
public List<int> dlc { get; set; }
[JsonProperty(PropertyName = "fullgame")]
public AppFullGame FullGame { get; set; }
public string header_image { get; set; }
[JsonProperty(PropertyName = "dlc")] public List<int> DLC { get; set; }
public string website { get; set; }
[JsonProperty(PropertyName = "header_image")]
public string HeaderImage { get; set; }
public List<string> developers { get; set; }
[JsonProperty(PropertyName = "website")]
public string Website { get; set; }
public List<string> publishers { get; set; }
[JsonProperty(PropertyName = "developers")]
public List<string> Developers { get; set; }
public List<int> packages { get; set; }
[JsonProperty(PropertyName = "publishers")]
public List<string> Publishers { get; set; }
[JsonProperty(PropertyName = "packages")]
public List<int> Packages { get; set; }
}
public class AppDetails
{
public bool success { get; set; }
[JsonProperty(PropertyName = "success")]
public bool Success { get; set; }
public AppData data { get; set; }
[JsonProperty(PropertyName = "data")] public AppData Data { get; set; }
}

View file

@ -22,9 +22,9 @@ internal static class SteamStore
=> await Task.Run(() =>
{
List<string> dlcIds = new();
if (appData.dlc is null)
if (appData.DLC is null)
return dlcIds;
dlcIds.AddRange(from appId in appData.dlc where appId > 0 select appId.ToString(CultureInfo.InvariantCulture));
dlcIds.AddRange(from appId in appData.DLC where appId > 0 select appId.ToString(CultureInfo.InvariantCulture));
return dlcIds;
});
@ -48,8 +48,8 @@ internal static class SteamStore
AppDetails appDetails = JsonConvert.DeserializeObject<AppDetails>(app.Value.ToString());
if (appDetails is not null)
{
AppData data = appDetails.data;
if (!appDetails.success)
AppData data = appDetails.Data;
if (!appDetails.Success)
{
#if DEBUG
DebugForm.Current.Log(

View file

@ -1,5 +1,6 @@
using System;
using System.Drawing;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using HtmlAgilityPack;
@ -28,6 +29,19 @@ internal static class HttpClientManager
_ = response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
catch (HttpRequestException e)
{
if (e.StatusCode != HttpStatusCode.TooManyRequests)
{
DebugForm.Current.Log("Get request failed to " + url + ": " + e, LogTextBox.Warning);
return null;
}
#if DEBUG
DebugForm.Current.Log("Too many requests to " + url, LogTextBox.Error);
#endif
// do something special?
return null;
}
#if DEBUG
catch (Exception e)
{

View file

@ -17,7 +17,7 @@ internal static class ProgramData
internal static readonly string AppInfoPath = DirectoryPath + @"\appinfo";
private static readonly string AppInfoVersionPath = AppInfoPath + @"\version.txt";
private static readonly Version MinimumAppInfoVersion = Version.Parse("3.2.0.0");
private static readonly Version MinimumAppInfoVersion = Version.Parse("4.7.0.0");
internal static readonly string CooldownPath = DirectoryPath + @"\cooldown";