diff --git a/ArchiSteamFarm/Steam/Data/Asset.cs b/ArchiSteamFarm/Steam/Data/Asset.cs index 21d8d76f8..96659cec6 100644 --- a/ArchiSteamFarm/Steam/Data/Asset.cs +++ b/ArchiSteamFarm/Steam/Data/Asset.cs @@ -28,45 +28,34 @@ using JetBrains.Annotations; namespace ArchiSteamFarm.Steam.Data; // REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_Asset +[PublicAPI] public sealed class Asset { - [PublicAPI] public const uint SteamAppID = 753; - - [PublicAPI] public const ulong SteamCommunityContextID = 6; - - [PublicAPI] public const ulong SteamPointsShopInstanceID = 3865004543; [JsonIgnore] - [PublicAPI] public bool IsSteamPointsShopItem => !Tradable && (InstanceID == SteamPointsShopInstanceID); [JsonIgnore] - [PublicAPI] public bool Marketable => Description?.Marketable ?? false; [JsonIgnore] - [PublicAPI] public EAssetRarity Rarity => Description?.Rarity ?? EAssetRarity.Unknown; [JsonIgnore] - [PublicAPI] public uint RealAppID => Description?.RealAppID ?? 0; [JsonIgnore] - [PublicAPI] public bool Tradable => Description?.Tradable ?? false; [JsonIgnore] - [PublicAPI] public EAssetType Type => Description?.Type ?? EAssetType.Unknown; [JsonInclude] [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] [JsonPropertyName("amount")] [JsonRequired] - [PublicAPI] public uint Amount { get; internal set; } [JsonInclude] @@ -76,29 +65,24 @@ public sealed class Asset { [JsonInclude] [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] [JsonPropertyName("assetid")] - [PublicAPI] public ulong AssetID { get; private init; } [JsonInclude] [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] [JsonPropertyName("classid")] - [PublicAPI] public ulong ClassID { get; private init; } [JsonInclude] [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] [JsonPropertyName("contextid")] - [PublicAPI] public ulong ContextID { get; private init; } [JsonIgnore] - [PublicAPI] public InventoryDescription? Description { get; internal set; } [JsonInclude] [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] [JsonPropertyName("instanceid")] - [PublicAPI] public ulong InstanceID { get; private init; } [JsonInclude] @@ -109,19 +93,19 @@ public sealed class Asset { init => AssetID = value; } - internal Asset(uint appID, ulong contextID, ulong classID, uint amount, InventoryDescription description, ulong assetID = 0, ulong instanceID = 0) { + [PublicAPI] + public Asset(uint appID, ulong contextID, ulong classID, uint amount, InventoryDescription? description = null, ulong assetID = 0, ulong instanceID = 0) { ArgumentOutOfRangeException.ThrowIfZero(appID); ArgumentOutOfRangeException.ThrowIfZero(contextID); ArgumentOutOfRangeException.ThrowIfZero(classID); ArgumentOutOfRangeException.ThrowIfZero(amount); - ArgumentNullException.ThrowIfNull(description); AppID = appID; ContextID = contextID; ClassID = classID; Amount = amount; - Description = description; + Description = description; AssetID = assetID; InstanceID = instanceID; } diff --git a/ArchiSteamFarm/Steam/Data/InventoryDescription.cs b/ArchiSteamFarm/Steam/Data/InventoryDescription.cs index ffb4ff05c..0d407361f 100644 --- a/ArchiSteamFarm/Steam/Data/InventoryDescription.cs +++ b/ArchiSteamFarm/Steam/Data/InventoryDescription.cs @@ -512,14 +512,13 @@ public sealed class InventoryDescription { private uint? CachedRealAppID; private EAssetType? CachedType; - internal InventoryDescription(CEconItem_Description description) { + public InventoryDescription(CEconItem_Description description) { ArgumentNullException.ThrowIfNull(description); Body = description; } - // For self-created stubs - internal InventoryDescription(uint appID, ulong classID, ulong instanceID = 0, bool marketable = false, bool tradable = false, uint realAppID = 0, EAssetType type = EAssetType.Unknown, EAssetRarity rarity = EAssetRarity.Unknown) { + public InventoryDescription(uint appID, ulong classID, ulong instanceID = 0, bool marketable = false, bool tradable = false, uint realAppID = 0, EAssetType type = EAssetType.Unknown, EAssetRarity rarity = EAssetRarity.Unknown) { ArgumentOutOfRangeException.ThrowIfZero(appID); ArgumentOutOfRangeException.ThrowIfZero(classID); diff --git a/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs b/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs index 863b1eb25..5cb49c39e 100644 --- a/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs +++ b/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs @@ -230,28 +230,15 @@ public sealed class ArchiHandler : ClientMsgHandler { descriptions.Add(key, new InventoryDescription(description)); } - foreach (CEcon_Asset? asset in response.assets) { - if (!assetIDs.Add(asset.assetid)) { - continue; - } - - (ulong ClassID, ulong InstanceID) key = (asset.classid, asset.instanceid); - - if (!descriptions.TryGetValue(key, out InventoryDescription? description)) { - // Best effort only - description = new InventoryDescription(appID, asset.classid, asset.instanceid); - - descriptions.Add(key, description); - } + foreach (CEcon_Asset? asset in response.assets.Where(asset => assetIDs.Add(asset.assetid))) { + InventoryDescription? description = descriptions.GetValueOrDefault((asset.classid, asset.instanceid)); // Extra bulletproofing against Steam showing us middle finger - if ((tradableOnly && !description.Tradable) || (marketableOnly && !description.Marketable)) { + if ((tradableOnly && (description?.Tradable != true)) || (marketableOnly && (description?.Marketable != true))) { continue; } - Asset convertedAsset = new(asset.appid, asset.contextid, asset.classid, (uint) asset.amount, description, asset.assetid, asset.instanceid); - - yield return convertedAsset; + yield return new Asset(asset.appid, asset.contextid, asset.classid, (uint) asset.amount, description, asset.assetid, asset.instanceid); } if (!response.more_items) { diff --git a/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs b/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs index 0ebe0f04b..02095b6ba 100644 --- a/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs +++ b/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs @@ -362,22 +362,11 @@ public sealed class ArchiWebHandler : IDisposable { descriptions.TryAdd(key, description); } - foreach (Asset asset in response.Content.Assets) { - if (!assetIDs.Add(asset.AssetID)) { - continue; + foreach (Asset asset in response.Content.Assets.Where(asset => assetIDs.Add(asset.AssetID))) { + if (descriptions.TryGetValue((asset.ClassID, asset.InstanceID), out InventoryDescription? description)) { + asset.Description = description; } - (ulong ClassID, ulong InstanceID) key = (asset.ClassID, asset.InstanceID); - - if (!descriptions.TryGetValue(key, out InventoryDescription? description)) { - // Best effort only - description = new InventoryDescription(appID, asset.ClassID, asset.InstanceID); - - descriptions.Add(key, description); - } - - asset.Description = description; - yield return asset; } @@ -2390,14 +2379,9 @@ public sealed class ArchiWebHandler : IDisposable { foreach (Asset asset in assets) { (uint AppID, ulong ClassID, ulong InstanceID) key = (asset.AppID, asset.ClassID, asset.InstanceID); - if (!descriptions.TryGetValue(key, out InventoryDescription? description)) { - // Best effort only - we can guarantee tradable property at best, and only at the time of the trade offer - description = new InventoryDescription(asset.AppID, asset.ClassID, asset.InstanceID, tradable: true); - - descriptions.Add(key, description); + if (descriptions.TryGetValue(key, out InventoryDescription? description)) { + asset.Description = description; } - - asset.Description = description; } }