From 7d66fc9744f6060c9fded6190aab1831c3f622db Mon Sep 17 00:00:00 2001 From: Rohan Singh Date: Sun, 11 Nov 2018 07:05:56 -0500 Subject: [PATCH] Fixed items not being removed when the player no longer has it Fixed item quantity and properties not updating when changed Fixed an error message getting into the items list Also checking if an item is nul wont NRE anymore --- .../Interfaces/Inventory.Item.cs | 27 +++++++++---------- .../Interfaces/Inventory.Result.cs | 11 ++++++++ Facepunch.Steamworks/Interfaces/Inventory.cs | 25 ++++++++++------- Facepunch.Steamworks/Utility.cs | 24 ++++++++++++++++- 4 files changed, 63 insertions(+), 24 deletions(-) diff --git a/Facepunch.Steamworks/Interfaces/Inventory.Item.cs b/Facepunch.Steamworks/Interfaces/Inventory.Item.cs index 84c4383..cbda47d 100644 --- a/Facepunch.Steamworks/Interfaces/Inventory.Item.cs +++ b/Facepunch.Steamworks/Interfaces/Inventory.Item.cs @@ -55,19 +55,19 @@ public Definition Definition public bool TradeLocked; - public bool Equals( Item other ) + public bool Equals(Item other) { - return Equals( other, this ); + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Id == other.Id; } - public override bool Equals( object obj ) + public override bool Equals(object obj) { - if ( obj == null || GetType() != obj.GetType() ) - { - return false; - } - - return ((Item)obj).Id == Id; + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((Item)obj); } public override int GetHashCode() @@ -75,15 +75,14 @@ public override int GetHashCode() return Id.GetHashCode(); } - - public static bool operator ==( Item c1, Item c2 ) + public static bool operator ==(Item left, Item right) { - return c1.Equals( c2 ); + return Equals(left, right); } - public static bool operator !=( Item c1, Item c2 ) + public static bool operator !=(Item left, Item right) { - return !c1.Equals( c2 ); + return !Equals(left, right); } /// diff --git a/Facepunch.Steamworks/Interfaces/Inventory.Result.cs b/Facepunch.Steamworks/Interfaces/Inventory.Result.cs index 68935bb..129f64f 100644 --- a/Facepunch.Steamworks/Interfaces/Inventory.Result.cs +++ b/Facepunch.Steamworks/Interfaces/Inventory.Result.cs @@ -114,6 +114,10 @@ internal void Fill() for ( int i=0; i< steamItems.Length; i++ ) { var item = inventory.ItemFrom( Handle, steamItems[i], i ); + if ( item == null ) + { + continue; + } if ( ( steamItems[i].Flags & (int)SteamNative.SteamItemFlags.Removed ) != 0 ) { @@ -189,6 +193,13 @@ internal Item ItemFrom( SteamInventoryResult_t handle, SteamItemDetails_t detail { if ( inventory.GetResultItemProperty(handle, (uint)index, propertyName, out string propertyValue ) ) { + if (propertyName == "error") + { + Console.Write("Steam item error: "); + Console.WriteLine(propertyValue); + return null; + } + props.Add(propertyName, propertyValue); } } diff --git a/Facepunch.Steamworks/Interfaces/Inventory.cs b/Facepunch.Steamworks/Interfaces/Inventory.cs index c0517e3..d3b34e5 100644 --- a/Facepunch.Steamworks/Interfaces/Inventory.cs +++ b/Facepunch.Steamworks/Interfaces/Inventory.cs @@ -129,14 +129,14 @@ private void onResultReady( SteamInventoryResultReady_t data ) } } - private void onResult( Result r, bool serialize ) + private void onResult( Result r, bool isFullUpdate ) { if ( r.IsSuccess ) { // // We only serialize FULL updates // - if ( serialize ) + if ( isFullUpdate ) { // // Only serialize if this result is newer than the last one @@ -149,7 +149,7 @@ private void onResult( Result r, bool serialize ) } LastTimestamp = r.Timestamp; - ApplyResult( r ); + ApplyResult( r, isFullUpdate ); } r.Dispose(); @@ -161,7 +161,7 @@ private void onResult( Result r, bool serialize ) /// Here we're trying to keep our stack up to date with whatever happens /// with the crafting, stacking etc /// - internal void ApplyResult( Result r ) + internal void ApplyResult( Result r, bool isFullUpdate ) { if ( IsServer ) return; @@ -170,12 +170,19 @@ internal void ApplyResult( Result r ) if ( Items == null ) Items = new Item[0]; - Items = Items - .Union( r.Items ) - .Distinct() - .Where( x => !r.Removed.Contains( x ) ) - .Where( x => !r.Consumed.Contains( x ) ) + if (isFullUpdate) + { + Items = r.Items; + } + else + { + // keep the new item instance because it might have a different quantity, properties, etc + Items = Items + .UnionSelect(r.Items, (oldItem, newItem) => newItem) + .Where(x => !r.Removed.Contains(x)) + .Where(x => !r.Consumed.Contains(x)) .ToArray(); + } // // Tell everyone we've got new items! diff --git a/Facepunch.Steamworks/Utility.cs b/Facepunch.Steamworks/Utility.cs index 1bb7e43..86e70e3 100644 --- a/Facepunch.Steamworks/Utility.cs +++ b/Facepunch.Steamworks/Utility.cs @@ -94,6 +94,28 @@ public static string ReadNullTerminatedUTF8String( this BinaryReader br, byte[] return Encoding.UTF8.GetString( buffer, 0, i ); } - + + public static IEnumerable UnionSelect( + this IEnumerable first, + IEnumerable second, + Func selector) where T : IEquatable + { + var items = new Dictionary(); + + foreach (var i in first) + { + items[i] = i; + } + + foreach (var i in second) + { + T firstValue; + if (items.TryGetValue(i, out firstValue)) + { + items.Remove(i); + yield return selector(firstValue, i); + } + } + } } }