From bfb987c7584946183f97c136617af2d15583fbb2 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 5 Dec 2022 20:16:31 -0800 Subject: [PATCH] fix: Fixes client crash while selling items to NPC (#1296) --- .../Network/Packets/Outgoing/VendorSellPacketTests.cs | 5 +++-- Projects/Server/Mobiles/BaseVendor.cs | 8 ++++++++ .../Network/Packets/OutgoingVendorSellPackets.cs | 10 ++++------ Projects/UOContent/Mobiles/Vendors/BaseVendor.cs | 8 ++++---- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorSellPacketTests.cs b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorSellPacketTests.cs index 4c9e9aff1..89aee42a7 100644 --- a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorSellPacketTests.cs +++ b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorSellPacketTests.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Network; using Xunit; @@ -18,14 +19,14 @@ namespace Server.Tests.Network var item2 = new Item(World.NewItem) { Name = "Second Item" }; var item3 = new Item(World.NewItem); - var sellStates = new List + var sellStates = new HashSet { new(item1, 100, "Item 1"), new(item2, 100000, "Item 2"), new(item3, 1, "Item 3") }; - var expected = new VendorSellList(vendor, sellStates).Compile(); + var expected = new VendorSellList(vendor, sellStates.ToList()).Compile(); var ns = PacketTestUtilities.CreateTestNetState(); ns.SendVendorSellList(vendor.Serial, sellStates); diff --git a/Projects/Server/Mobiles/BaseVendor.cs b/Projects/Server/Mobiles/BaseVendor.cs index fe6230d65..7e28ea765 100644 --- a/Projects/Server/Mobiles/BaseVendor.cs +++ b/Projects/Server/Mobiles/BaseVendor.cs @@ -51,6 +51,14 @@ public class SellItemResponse public int Amount { get; } } +public class SellItemStateComparer : IEqualityComparer +{ + public bool Equals(SellItemState l, SellItemState r) => + l == null && r == null || l != null && r != null && l.Item == r.Item; + + public int GetHashCode(SellItemState obj) => obj.Item.GetHashCode(); +} + public class SellItemState { public SellItemState(Item item, int price, string name) diff --git a/Projects/Server/Network/Packets/OutgoingVendorSellPackets.cs b/Projects/Server/Network/Packets/OutgoingVendorSellPackets.cs index 116734bf1..b76485efc 100644 --- a/Projects/Server/Network/Packets/OutgoingVendorSellPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingVendorSellPackets.cs @@ -22,7 +22,7 @@ namespace Server.Network; public static class OutgoingVendorSellPackets { - public static void SendVendorSellList(this NetState ns, Serial vendor, List list) + public static void SendVendorSellList(this NetState ns, Serial vendor, HashSet set) { if (ns.CannotSendPackets()) { @@ -30,9 +30,8 @@ public static class OutgoingVendorSellPackets } var maxLength = 9; - for (int i = 0; i < list.Count; i++) + foreach (var sis in set) { - var sis = list[i]; var item = sis.Item; maxLength += 14 + Math.Max(item.Name?.Length ?? 0, sis.Name?.Length ?? 0); } @@ -42,11 +41,10 @@ public static class OutgoingVendorSellPackets writer.Seek(2, SeekOrigin.Current); writer.Write(vendor); - writer.Write((ushort)list.Count); + writer.Write((ushort)set.Count); - for (var i = 0; i < list.Count; i++) + foreach (var sis in set) { - var sis = list[i]; var item = sis.Item; writer.Write(item.Serial); writer.Write((ushort)item.ItemID); diff --git a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs index 5bd8f5fa0..ea80e0c9e 100644 --- a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs +++ b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs @@ -1042,7 +1042,7 @@ namespace Server.Mobiles var info = GetSellInfo(); - var list = new List(); + var set = new HashSet(new SellItemStateComparer()); foreach (var ssi in info) { @@ -1055,16 +1055,16 @@ namespace Server.Mobiles if (item.IsStandardLoot() && item.Movable && ssi.IsSellable(item)) { - list.Add(new SellItemState(item, ssi.GetSellPriceFor(item), ssi.GetNameFor(item))); + set.Add(new SellItemState(item, ssi.GetSellPriceFor(item), ssi.GetNameFor(item))); } } } - if (list.Count > 0) + if (set.Count > 0) { SendPacksTo(from); - from.NetState.SendVendorSellList(Serial, list); + from.NetState.SendVendorSellList(Serial, set); } else {