Decrease itemsCountPerRequest to 5000, optimize performance a bit, closes #3171

This commit is contained in:
Archi
2024-03-22 16:34:46 +01:00
parent 9682d1d5ef
commit c5009dad31
2 changed files with 23 additions and 11 deletions

View File

@@ -173,7 +173,7 @@ public sealed class ArchiHandler : ClientMsgHandler {
}
[PublicAPI]
public async IAsyncEnumerable<Asset> GetMyInventoryAsync(uint appID = Asset.SteamAppID, ulong contextID = Asset.SteamCommunityContextID, bool tradableOnly = false, bool marketableOnly = false, ushort itemsCountPerRequest = 10000) {
public async IAsyncEnumerable<Asset> GetMyInventoryAsync(uint appID = Asset.SteamAppID, ulong contextID = Asset.SteamCommunityContextID, bool tradableOnly = false, bool marketableOnly = false, ushort itemsCountPerRequest = ArchiWebHandler.MaxItemsInSingleInventoryRequest) {
ArgumentOutOfRangeException.ThrowIfZero(appID);
ArgumentOutOfRangeException.ThrowIfZero(contextID);
ArgumentOutOfRangeException.ThrowIfZero(itemsCountPerRequest);
@@ -189,6 +189,8 @@ public sealed class ArchiHandler : ClientMsgHandler {
// We need to store asset IDs to make sure we won't get duplicate items
HashSet<ulong>? assetIDs = null;
Dictionary<(ulong ClassID, ulong InstanceID), InventoryDescription>? descriptions = null;
while (true) {
ulong currentStartAssetID = startAssetID;
@@ -226,12 +228,13 @@ public sealed class ArchiHandler : ClientMsgHandler {
assetIDs ??= new HashSet<ulong>((int) response.total_inventory_count);
if ((response.assets.Count == 0) || (response.descriptions.Count == 0)) {
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Strings.ErrorObjectIsNull, $"{nameof(response.assets)} || {nameof(response.descriptions)}"));
if (descriptions == null) {
descriptions = new Dictionary<(ulong ClassID, ulong InstanceID), InventoryDescription>();
} else {
// We don't need descriptions from the previous request
descriptions.Clear();
}
Dictionary<(ulong ClassID, ulong InstanceID), InventoryDescription> descriptions = new();
foreach (CEconItem_Description? description in response.descriptions) {
if (description.classid == 0) {
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Strings.ErrorObjectIsNull, nameof(description.classid)));

View File

@@ -51,9 +51,11 @@ using SteamKit2;
namespace ArchiSteamFarm.Steam.Integration;
public sealed class ArchiWebHandler : IDisposable {
// Steam network (ArchiHandler) works unstable with more items than this (throwing upon description details), while Steam web (ArchiWebHandler) silently limits to this value maximum
internal const ushort MaxItemsInSingleInventoryRequest = 5000;
private const string EconService = "IEconService";
private const string LoyaltyRewardsService = "ILoyaltyRewardsService";
private const ushort MaxItemsInSingleInventoryRequest = 5000;
private const byte MinimumSessionValidityInSeconds = 10;
private const string SteamAppsService = "ISteamApps";
@@ -261,6 +263,8 @@ public sealed class ArchiWebHandler : IDisposable {
// We need to store asset IDs to make sure we won't get duplicate items
HashSet<ulong>? assetIDs = null;
Dictionary<(ulong ClassID, ulong InstanceID), InventoryDescription>? descriptions = null;
int rateLimitingDelay = (ASF.GlobalConfig?.InventoryLimiterDelay ?? GlobalConfig.DefaultInventoryLimiterDelay) * 1000;
while (true) {
@@ -328,23 +332,28 @@ public sealed class ArchiWebHandler : IDisposable {
throw new HttpRequestException(!string.IsNullOrEmpty(response.Content.ErrorText) ? string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, response.Content.ErrorText) : response.Content.Result.HasValue ? string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, response.Content.Result) : Strings.WarningFailed);
}
if (response.Content.TotalInventoryCount == 0) {
if ((response.Content.TotalInventoryCount == 0) || (response.Content.Assets.Count == 0)) {
// Empty inventory
yield break;
}
if (response.Content.Descriptions.Count == 0) {
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, nameof(response.Content.Descriptions)));
}
if (response.Content.TotalInventoryCount > Array.MaxLength) {
throw new InvalidOperationException(nameof(response.Content.TotalInventoryCount));
}
assetIDs ??= new HashSet<ulong>((int) response.Content.TotalInventoryCount);
if ((response.Content.Assets.Count == 0) || (response.Content.Descriptions.Count == 0)) {
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Strings.ErrorObjectIsNull, $"{nameof(response.Content.Assets)} || {nameof(response.Content.Descriptions)}"));
if (descriptions == null) {
descriptions = new Dictionary<(ulong ClassID, ulong InstanceID), InventoryDescription>();
} else {
// We don't need descriptions from the previous request
descriptions.Clear();
}
Dictionary<(ulong ClassID, ulong InstanceID), InventoryDescription> descriptions = new();
foreach (InventoryDescription description in response.Content.Descriptions) {
if (description.ClassID == 0) {
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Strings.ErrorObjectIsNull, nameof(description.ClassID)));