diff --git a/Facepunch.Steamworks.Test/InventoryTest.cs b/Facepunch.Steamworks.Test/InventoryTest.cs index 69eb345..5c78829 100644 --- a/Facepunch.Steamworks.Test/InventoryTest.cs +++ b/Facepunch.Steamworks.Test/InventoryTest.cs @@ -45,6 +45,31 @@ namespace Steamworks Console.WriteLine( $"[{def.Id:0000000000}] {def.Name} [{def.LocalPriceFormatted}]" ); } } + + [TestMethod] + public async Task GetAllItems() + { + await SteamInventory.WaitForDefinitions(); + + var result = await SteamInventory.GetItems(); + + Assert.IsTrue( result.HasValue ); + + using ( result ) + { + var items = result?.GetItems( true ); + + foreach ( var item in items ) + { + Console.WriteLine( $"{item.Id} / {item.DefId} / {item.Quantity} " ); + + foreach ( var prop in item.Properties ) + { + Console.WriteLine( $" {prop.Key} : {prop.Value}" ); + } + } + } + } } } diff --git a/Facepunch.Steamworks/SteamInventory.cs b/Facepunch.Steamworks/SteamInventory.cs index 68f0b55..f08df22 100644 --- a/Facepunch.Steamworks/SteamInventory.cs +++ b/Facepunch.Steamworks/SteamInventory.cs @@ -78,7 +78,7 @@ namespace Steamworks public static string Currency { get; internal set; } - public static async Task GetDefinitionsWithPricesAsync() + public static async Task GetDefinitionsWithPricesAsync() { var priceRequest = await Internal.RequestPrices(); if ( !priceRequest.HasValue || priceRequest.Value.Result != Result.OK ) @@ -91,7 +91,7 @@ namespace Steamworks if ( num <= 0 ) return null; - var defs = new SteamItemDef_t[num]; + var defs = new InventoryDefId[num]; var currentPrices = new ulong[num]; var baseprices = new ulong[num]; @@ -99,23 +99,40 @@ namespace Steamworks if ( !gotPrices ) return null; - return defs.Select( x => new SteamItemDef( x ) ).ToArray(); + return defs.Select( x => new InventoryDef( x ) ).ToArray(); } - public static SteamItemDef[] Definitions { get; internal set; } + public static InventoryDef[] Definitions { get; internal set; } - internal static SteamItemDef[] GetDefinitions() + internal static InventoryDef[] GetDefinitions() { uint num = 0; if ( !Internal.GetItemDefinitionIDs( null, ref num ) ) return null; - var defs = new SteamItemDef_t[num]; + var defs = new InventoryDefId[num]; if ( !Internal.GetItemDefinitionIDs( defs, ref num ) ) return null; - return defs.Select( x => new SteamItemDef( x ) ).ToArray(); + return defs.Select( x => new InventoryDef( x ) ).ToArray(); + } + + public static async Task GetItems() + { + var sresult = default( SteamInventoryResult_t ); + + if ( !Internal.GetAllItems( ref sresult ) ) + return null; + + var result = new InventoryResult( sresult ); + + if ( !await result.WaitUntilReadyAsync() ) + { + return null; + } + + return result; } } diff --git a/Facepunch.Steamworks/Structs/SteamItemDef.cs b/Facepunch.Steamworks/Structs/InventoryDef.cs similarity index 97% rename from Facepunch.Steamworks/Structs/SteamItemDef.cs rename to Facepunch.Steamworks/Structs/InventoryDef.cs index 15c6f64..fbda5ac 100644 --- a/Facepunch.Steamworks/Structs/SteamItemDef.cs +++ b/Facepunch.Steamworks/Structs/InventoryDef.cs @@ -4,11 +4,11 @@ using Steamworks.Data; namespace Steamworks { - public struct SteamItemDef + public struct InventoryDef { - internal SteamItemDef_t _id; + internal InventoryDefId _id; - public SteamItemDef( int defId ) + public InventoryDef( InventoryDefId defId ) { _id = defId; } diff --git a/Facepunch.Steamworks/Structs/InventoryItem.cs b/Facepunch.Steamworks/Structs/InventoryItem.cs new file mode 100644 index 0000000..83d4794 --- /dev/null +++ b/Facepunch.Steamworks/Structs/InventoryItem.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using Steamworks.Data; + +namespace Steamworks +{ + public struct InventoryItem + { + internal InventoryItemId _id; + internal InventoryDefId _def; + internal int _flags; + internal ushort _quantity; + internal Dictionary _properties; + + public InventoryItemId Id => _id; + + public InventoryDefId DefId => _def; + + public int Quantity => _quantity; + + + /// + /// Only available if the result set was created with the getproperties + /// + public Dictionary Properties => _properties; + + /// + /// This item is account-locked and cannot be traded or given away. + /// This is an item status flag which is permanently attached to specific item instances + /// + public bool IsNoTrade => (_flags & 1 << 0) != 0; + + /// + /// The item has been destroyed, traded away, expired, or otherwise invalidated. + /// This is an action confirmation flag which is only set one time, as part of a result set. + /// + public bool IsRemoved => (_flags & 1 << 8) != 0; + + /// + /// The item quantity has been decreased by 1 via ConsumeItem API. + /// This is an action confirmation flag which is only set one time, as part of a result set. + /// + public bool IsConsumed => (_flags & 1 << 9) != 0; + + internal static InventoryItem From( SteamItemDetails_t details ) + { + var i = new InventoryItem + { + _id = details.ItemId, + _def = details.Definition, + _flags = details.Flags, + _quantity = details.Quantity + }; + + return i; + } + + internal static Dictionary GetProperties( SteamInventoryResult_t result, int index ) + { + var sb = Helpers.TakeStringBuilder(); + var strlen = (uint) sb.Capacity; + + if ( !SteamInventory.Internal.GetResultItemProperty( result, (uint)index, null, sb, ref strlen ) ) + return null; + + var propNames = sb.ToString(); + + var props = new Dictionary(); + + foreach ( var propertyName in propNames.Split( ',' ) ) + { + strlen = (uint)sb.Capacity; + + if ( SteamInventory.Internal.GetResultItemProperty( result, (uint)index, propertyName, sb, ref strlen ) ) + { + props.Add( propertyName, sb.ToString() ); + } + } + + return props; + } + } +} \ No newline at end of file diff --git a/Facepunch.Steamworks/Structs/InventoryResult.cs b/Facepunch.Steamworks/Structs/InventoryResult.cs new file mode 100644 index 0000000..94a90cd --- /dev/null +++ b/Facepunch.Steamworks/Structs/InventoryResult.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Steamworks.Data; + +namespace Steamworks +{ + public struct InventoryResult : IDisposable + { + internal SteamInventoryResult_t _id; + internal Result _result; + + internal InventoryResult( SteamInventoryResult_t id ) + { + _id = id; + _result = Result.Pending; + } + + internal async Task WaitUntilReadyAsync() + { + while ( _result == Result.Pending ) + { + _result = SteamInventory.Internal.GetResultStatus( _id ); + Task.Delay( 10 ); + } + + return _result == Result.OK || _result == Result.Expired; + } + + public int ItemCount + { + get + { + uint cnt = 0; + + if ( !SteamInventory.Internal.GetResultItems( _id, null, ref cnt ) ) + return 0; + + return (int) cnt; + } + } + + public InventoryItem[] GetItems( bool includeProperties = false ) + { + uint cnt = (uint) ItemCount; + if ( cnt <= 0 ) return null; + + var pOutItemsArray = new SteamItemDetails_t[cnt]; + + if ( !SteamInventory.Internal.GetResultItems( _id, pOutItemsArray, ref cnt ) ) + return null; + + var items = new InventoryItem[cnt]; + + for( int i=0; i< cnt; i++ ) + { + var item = InventoryItem.From( pOutItemsArray[i] ); + + if ( includeProperties ) + item._properties = InventoryItem.GetProperties( _id, i ); + + items[i] = item; + } + + + return items; + } + + public void Dispose() + { + SteamInventory.Internal.DestroyResult( _id ); + } + } +} \ No newline at end of file