diff --git a/Projects/Benchmarks/Packets/BenchmarkPacketConstruction.cs b/Projects/Benchmarks/Packets/BenchmarkPacketConstruction.cs deleted file mode 100644 index eaf2ec946..000000000 --- a/Projects/Benchmarks/Packets/BenchmarkPacketConstruction.cs +++ /dev/null @@ -1,157 +0,0 @@ -using System; -using System.Buffers; -using System.Buffers.Binary; -using System.Collections.Generic; -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; -using Server; -using Server.Network; - -namespace Benchmarks -{ - [SimpleJob(RuntimeMoniker.NetCoreApp50)] - public class BenchmarkPacketConstruction - { - public List m_States; - - [GlobalSetup] - public void SetUp() - { - m_States = new List - { - new("Name 1", 0x1000, 0x2000, 1000, 1, 10, 1024), - new("Name 2", 0x1001, 0x2001, 1001, 1, 10, 1024), - new("Name 3", 0x1002, 0x2002, 1002, 1, 10, 1024), - new("Name 4", 0x1003, 0x2003, 1003, 1, 10, 1024), - new("Name 5", 0x1004, 0x2004, 1004, 1, 10, 1024), - new("Name 6", 0x1005, 0x2005, 1005, 1, 10, 1024), - new("Name 7", 0x1006, 0x2006, 1006, 1, 10, 1024), - new("Name 8", 0x1007, 0x2007, 1007, 1, 10, 1024), - new("Name 9", 0x1008, 0x2008, 1008, 1, 10, 1024), - new("Name A", 0x1009, 0x2009, 1009, 1, 10, 1024), - new("Name 10", 0x1000, 0x2000, 1000, 1, 10, 1024), - new("Name 20", 0x1001, 0x2001, 1001, 1, 10, 1024), - new("Name 30", 0x1002, 0x2002, 1002, 1, 10, 1024), - new("Name 40", 0x1003, 0x2003, 1003, 1, 10, 1024), - new("Name 50", 0x1004, 0x2004, 1004, 1, 10, 1024), - new("Name 60", 0x1005, 0x2005, 1005, 1, 10, 1024), - new("Name 70", 0x1006, 0x2006, 1006, 1, 10, 1024), - new("Name 80", 0x1007, 0x2007, 1007, 1, 10, 1024), - new("Name 90", 0x1008, 0x2008, 1008, 1, 10, 1024), - new("Name A0", 0x1009, 0x2009, 1009, 1, 10, 1024), - new("Name 11", 0x1000, 0x2000, 1000, 1, 10, 1024), - new("Name 21", 0x1001, 0x2001, 1001, 1, 10, 1024), - new("Name 31", 0x1002, 0x2002, 1002, 1, 10, 1024), - new("Name 41", 0x1003, 0x2003, 1003, 1, 10, 1024), - new("Name 51", 0x1004, 0x2004, 1004, 1, 10, 1024), - new("Name 61", 0x1005, 0x2005, 1005, 1, 10, 1024), - new("Name 71", 0x1006, 0x2006, 1006, 1, 10, 1024), - new("Name 81", 0x1007, 0x2007, 1007, 1, 10, 1024), - new("Name 91", 0x1008, 0x2008, 1008, 1, 10, 1024), - new("Name A1", 0x1009, 0x2009, 1009, 1, 10, 1024) - }; - } - - [Benchmark] - public Packet TestPacketConstruction() - { - Packet p = new VendorBuyContent(m_States); - p.Compile(false, out _); - return p; - } - - [Benchmark] - public int TestInlineRefConstruction() - { - var buyStates = m_States; - - int length = 5 + buyStates.Count * 19; - - Span data = stackalloc byte[length]; - - int pos = 0; - data.Write(ref pos, (byte)0x3C); - data.Write(ref pos, (ushort)length); - data.Write(ref pos, (ushort)buyStates.Count); - - for (int i = buyStates.Count - 1; i >= 0; i--) - { - BuyItemState buyState = buyStates[i]; - - data.Write(ref pos, buyState.MySerial); - data.Write(ref pos, (ushort)buyState.ItemID); - data.Write(ref pos, (byte)0); - data.Write(ref pos, (ushort)buyState.Amount); - data.Write(ref pos, (ushort)(i + 1)); - data.Write(ref pos, (ushort)0x1); - data.Write(ref pos, buyState.ContainerSerial); - data.Write(ref pos, (ushort)buyState.Hue); - } - - return data.Length; - } - - [Benchmark] - public int TestInlineConstruction() - { - var buyStates = m_States; - - Span data = stackalloc byte[5 + buyStates.Count * 19]; - data[0] = 0x3C; - BinaryPrimitives.WriteUInt16BigEndian(data.Slice(1, 2), (ushort)data.Length); - BinaryPrimitives.WriteUInt16BigEndian(data.Slice(3, 2), (ushort)buyStates.Count); - int pos = 4; - - - for (int i = buyStates.Count - 1; i >= 0; i--) - { - BuyItemState buyState = buyStates[i]; - BinaryPrimitives.WriteUInt32BigEndian(data.Slice(pos, 4), buyState.MySerial); - pos += 4; - BinaryPrimitives.WriteUInt16BigEndian(data.Slice(pos, 2), (ushort)buyState.ItemID); - pos += 2; - data[pos++] = 0; - BinaryPrimitives.WriteUInt16BigEndian(data.Slice(pos, 2), (ushort)buyState.Amount); - pos += 2; - BinaryPrimitives.WriteUInt16BigEndian(data.Slice(pos, 2), (ushort)(i + 1)); - pos += 2; - BinaryPrimitives.WriteUInt16BigEndian(data.Slice(pos, 2), 0x1); - pos += 2; - BinaryPrimitives.WriteUInt32BigEndian(data.Slice(pos, 4), buyState.ContainerSerial); - pos += 4; - BinaryPrimitives.WriteUInt16BigEndian(data.Slice(pos, 2), (ushort)(buyState.Hue)); - pos += 2; - } - - return data.Length; - } - - [Benchmark] - public int TestSpanWriterConstruction() - { - var buyStates = m_States; - - int length = 5 + buyStates.Count * 19; - - SpanWriter w = new SpanWriter(stackalloc byte[length]); - - w.Write((byte)0x3C); // Packet ID - w.Write((ushort)length); // Length - w.Write((ushort)buyStates.Count); // Length - - for (int i = buyStates.Count - 1; i >= 0; i--) - { - BuyItemState buyState = buyStates[i]; - w.Write(buyState.MySerial); - w.Write((ushort)buyState.ItemID); - w.Write((byte)0); - w.Write((ushort)(i + 1)); // X - w.Write((ushort)0x1); // Y - w.Write(buyState.ContainerSerial); - w.Write((ushort)buyState.Hue); - } - - return w.Position; - } - } -} diff --git a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorBuyPacketTests.cs b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorBuyPacketTests.cs index 8100bc60c..138d478c0 100644 --- a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorBuyPacketTests.cs +++ b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorBuyPacketTests.cs @@ -2,6 +2,7 @@ using System; using System.Buffers; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; using Server.Items; using Server.Network; using Xunit; @@ -10,8 +11,10 @@ namespace Server.Tests.Network { public class VendorBuyPacketTests : IClassFixture { - [Fact] - public void TestVendorBuyContent() + [Theory] + [InlineData(ProtocolChanges.None)] + [InlineData(ProtocolChanges.ContainerGridLines)] + public void TestVendorBuyContent(ProtocolChanges protocolChanges) { var cont = new Container(World.NewItem); @@ -22,115 +25,34 @@ namespace Server.Tests.Network new("Third Item", cont.Serial, World.NewItem, 30, 10, 0x0F, 0) }; - var data = new VendorBuyContent(buyStates).Compile(); + using var ns = PacketTestUtilities.CreateTestNetState(); + ns.ProtocolChanges = protocolChanges; - Span expectedData = stackalloc byte[5 + buyStates.Count * 19]; + var expected = new VendorBuyContent(buyStates, ns.ContainerGridLines).Compile(); - var pos = 0; + ns.SendVendorBuyContent(buyStates); - expectedData.Write(ref pos, (byte)0x3C); // Packet ID - expectedData.Write(ref pos, (ushort)expectedData.Length); // Length - expectedData.Write(ref pos, (ushort)buyStates.Count); // Count - - for (var i = buyStates.Count - 1; i >= 0; i--) - { - var buyState = buyStates[i]; - - expectedData.Write(ref pos, buyState.MySerial); - expectedData.Write(ref pos, (ushort)buyState.ItemID); - pos++; // ItemID Offset - expectedData.Write(ref pos, (ushort)buyState.Amount); - expectedData.Write(ref pos, (ushort)(i + 1)); // X - expectedData.Write(ref pos, (ushort)1); // Y - expectedData.Write(ref pos, buyState.ContainerSerial); - expectedData.Write(ref pos, (ushort)buyState.Hue); - } - - AssertThat.Equal(data, expectedData); + var result = ns.SendPipe.Reader.TryRead(); + AssertThat.Equal(result.Buffer[0].AsSpan(0), expected); } - [Fact] - public void TestVendorBuyContent6017() - { - var cont = new Container(World.NewItem); - - var buyStates = new List - { - new("First Item", cont.Serial, World.NewItem, 10, 1, 0x01, 0), - new("Second Item", cont.Serial, World.NewItem, 20, 2, 0x0A, 0), - new("Third Item", cont.Serial, World.NewItem, 30, 10, 0x0F, 0) - }; - - var data = new VendorBuyContent6017(buyStates).Compile(); - - Span expectedData = stackalloc byte[5 + buyStates.Count * 20]; - - var pos = 0; - - expectedData.Write(ref pos, (byte)0x3C); // Packet ID - expectedData.Write(ref pos, (ushort)expectedData.Length); // Length - expectedData.Write(ref pos, (ushort)buyStates.Count); // Count - - for (var i = buyStates.Count - 1; i >= 0; i--) - { - var buyState = buyStates[i]; - - expectedData.Write(ref pos, buyState.MySerial); - expectedData.Write(ref pos, (ushort)buyState.ItemID); - pos++; // ItemID Offset - expectedData.Write(ref pos, (ushort)buyState.Amount); - expectedData.Write(ref pos, (ushort)(i + 1)); // X - expectedData.Write(ref pos, (ushort)1); // Y -#if NO_LOCAL_INIT - expectedData.Write(ref pos, (byte)0); // Grid Location? -#else - pos++; -#endif - expectedData.Write(ref pos, buyState.ContainerSerial); - expectedData.Write(ref pos, (ushort)buyState.Hue); - } - - AssertThat.Equal(data, expectedData); - } - - [Fact] - public void TestDisplayBuyList() + [Theory] + [InlineData(ProtocolChanges.None)] + [InlineData(ProtocolChanges.HighSeas)] + public void TestDisplayBuyList(ProtocolChanges protocolChanges) { var vendor = new Mobile(0x1); vendor.DefaultMobileInit(); - var data = new DisplayBuyList(vendor).Compile(); + using var ns = PacketTestUtilities.CreateTestNetState(); + ns.ProtocolChanges = protocolChanges; - Span expectedData = stackalloc byte[7]; - var pos = 0; + var expected = new DisplayBuyList(vendor.Serial, ns.HighSeas).Compile(); - expectedData.Write(ref pos, (byte)0x24); // Packet ID - expectedData.Write(ref pos, vendor.Serial); - expectedData.Write(ref pos, (ushort)0x30); // Buy gump + ns.SendDisplayBuyList(vendor.Serial); - AssertThat.Equal(data, expectedData); - } - - [Fact] - public void TestDisplayBuyListHS() - { - var vendor = new Mobile(0x1); - vendor.DefaultMobileInit(); - - var data = new DisplayBuyListHS(vendor).Compile(); - - Span expectedData = stackalloc byte[9]; - var pos = 0; - - expectedData.Write(ref pos, (byte)0x24); // Packet ID - expectedData.Write(ref pos, vendor.Serial); - expectedData.Write(ref pos, (ushort)0x30); // Buy gump - -#if NO_LOCAL_INIT - expectedData.Write(ref pos, (ushort)0); -#endif - - AssertThat.Equal(data, expectedData); + var result = ns.SendPipe.Reader.TryRead(); + AssertThat.Equal(result.Buffer[0].AsSpan(0), expected); } [Fact] @@ -148,29 +70,13 @@ namespace Server.Tests.Network new("Third Item", cont.Serial, World.NewItem, 30, 10, 0x0F, 0) }; - var data = new VendorBuyList(vendor, buyStates).Compile(); + var expected = new VendorBuyList(vendor, buyStates).Compile(); - var length = 8 + buyStates.Sum(state => 6 + state.Description.Length); + using var ns = PacketTestUtilities.CreateTestNetState(); + ns.SendVendorBuyList(vendor, buyStates); - Span expectedData = stackalloc byte[length]; - - var pos = 0; - - expectedData.Write(ref pos, (byte)0x74); // Packet ID - expectedData.Write(ref pos, (ushort)expectedData.Length); // Length - expectedData.Write(ref pos, Serial.MinusOne); // Vendor Buy Pack Serial or -1 - expectedData.Write(ref pos, (byte)buyStates.Count); - - for (var i = 0; i < buyStates.Count; i++) - { - var state = buyStates[i]; - expectedData.Write(ref pos, state.Price); - var description = state.Description ?? ""; - expectedData.Write(ref pos, (byte)Math.Min(255, description.Length + 1)); - expectedData.WriteAsciiNull(ref pos, description, 255); - } - - AssertThat.Equal(data, expectedData); + var result = ns.SendPipe.Reader.TryRead(); + AssertThat.Equal(result.Buffer[0].AsSpan(0), expected); } [Fact] @@ -179,20 +85,13 @@ namespace Server.Tests.Network var vendor = new Mobile(0x1); vendor.DefaultMobileInit(); - var data = new EndVendorBuy(vendor).Compile(); + var expected = new EndVendorBuy(vendor.Serial).Compile(); - Span expectedData = stackalloc byte[8]; - var pos = 0; + using var ns = PacketTestUtilities.CreateTestNetState(); + ns.SendEndVendorBuy(vendor.Serial); - expectedData.Write(ref pos, (byte)0x3B); // Packet ID - expectedData.Write(ref pos, (ushort)0x8); // Length - expectedData.Write(ref pos, vendor.Serial); - -#if NO_LOCAL_INIT - expectedData.Write(ref pos, (byte)-); -#endif - - AssertThat.Equal(data, expectedData); + var result = ns.SendPipe.Reader.TryRead(); + AssertThat.Equal(result.Buffer[0].AsSpan(0), expected); } } } diff --git a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorBuyPackets.cs b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorBuyPackets.cs new file mode 100644 index 000000000..7f1a3520f --- /dev/null +++ b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorBuyPackets.cs @@ -0,0 +1,80 @@ +using System.Collections.Generic; +using Server.Items; + +namespace Server.Network +{ + public sealed class VendorBuyContent : Packet + { + public VendorBuyContent(List list, bool containerGridLines) : base(0x3C) + { + EnsureCapacity(list.Count * 19 + 5); + + Stream.Write((short)list.Count); + + for (var i = list.Count - 1; i >= 0; --i) + { + var bis = list[i]; + + Stream.Write(bis.MySerial); + Stream.Write((ushort)bis.ItemID); + Stream.Write((byte)0); // itemID offset + Stream.Write((ushort)bis.Amount); + Stream.Write((short)(i + 1)); // x + Stream.Write((short)1); // y + if (containerGridLines) + { + Stream.Write((byte)0); // Grid Location? + } + Stream.Write(bis.ContainerSerial); + Stream.Write((ushort)bis.Hue); + } + } + } + + public sealed class DisplayBuyList : Packet + { + public DisplayBuyList(Serial vendor, bool highSeas) : base(0x24, highSeas ? 9 : 7) + { + Stream.Write(vendor); + Stream.Write((short)0x30); // buy window id? + if (highSeas) + { + Stream.Write((short)0x00); + } + } + } + + public sealed class VendorBuyList : Packet + { + public VendorBuyList(Mobile vendor, List list) : base(0x74) + { + EnsureCapacity(256); + + Stream.Write(!(vendor.FindItemOnLayer(Layer.ShopBuy) is Container buyPack) ? Serial.MinusOne : buyPack.Serial); + + Stream.Write((byte)list.Count); + + for (var i = 0; i < list.Count; ++i) + { + var bis = list[i]; + + Stream.Write(bis.Price); + + var desc = bis.Description ?? ""; + + Stream.Write((byte)desc.Length); + Stream.WriteAsciiFixed(desc, desc.Length); + } + } + } + + public sealed class EndVendorBuy : Packet + { + public EndVendorBuy(Serial vendor) : base(0x3B, 8) + { + Stream.Write((ushort)8); // length + Stream.Write(vendor); + Stream.Write((byte)0); + } + } +} diff --git a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorSellPacketTests.cs b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorSellPacketTests.cs index 027f389f0..49d494087 100644 --- a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorSellPacketTests.cs +++ b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorSellPacketTests.cs @@ -63,7 +63,7 @@ namespace Server.Tests.Network var vendor = new Mobile(0x1); vendor.DefaultMobileInit(); - var data = new EndVendorBuy(vendor).Compile(); + var data = new EndVendorBuy(vendor.Serial).Compile(); Span expectedData = stackalloc byte[8]; var pos = 0; diff --git a/Projects/Server/Network/Packets/IncomingVendorPackets.cs b/Projects/Server/Network/Packets/IncomingVendorPackets.cs index c4148647f..e716f03e4 100644 --- a/Projects/Server/Network/Packets/IncomingVendorPackets.cs +++ b/Projects/Server/Network/Packets/IncomingVendorPackets.cs @@ -28,20 +28,15 @@ namespace Server.Network public static void VendorBuyReply(NetState state, CircularBufferReader reader) { var vendor = World.FindMobile(reader.ReadUInt32()); - var flag = reader.ReadByte(); if (vendor == null) { return; } - if (vendor.Deleted || !Utility.RangeCheck(vendor.Location, state.Mobile.Location, 10)) - { - state.Send(new EndVendorBuy(vendor)); - return; - } + var flag = reader.ReadByte(); - if (flag == 0x02) + if (!vendor.Deleted && Utility.RangeCheck(vendor.Location, state.Mobile.Location, 10) && flag == 0x02) { var msgSize = reader.Remaining; @@ -61,15 +56,13 @@ namespace Server.Network msgSize -= 7; } - if (buyList.Count > 0 && vendor is IVendor v && v.OnBuyItems(state.Mobile, buyList)) + if (buyList.Count <= 0 || (vendor as IVendor)?.OnBuyItems(state.Mobile, buyList) != true) { - state.Send(new EndVendorBuy(vendor)); + return; } } - else - { - state.Send(new EndVendorBuy(vendor)); - } + + state.SendEndVendorBuy(vendor.Serial); } public static void VendorSellReply(NetState state, CircularBufferReader reader) diff --git a/Projects/Server/Network/Packets/OutgoingVendorBuyPackets.cs b/Projects/Server/Network/Packets/OutgoingVendorBuyPackets.cs new file mode 100644 index 000000000..b46552f1a --- /dev/null +++ b/Projects/Server/Network/Packets/OutgoingVendorBuyPackets.cs @@ -0,0 +1,125 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2020 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: OutgoingVendorBuyPackets.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System.Buffers; +using System.Collections.Generic; +using System.IO; +using Server.Items; + +namespace Server.Network +{ + public static class OutgoingVendorBuyPackets + { + public static void SendVendorBuyContent(this NetState ns, List list) + { + if (ns == null || !ns.GetSendBuffer(out var buffer)) + { + return; + } + + var writer = new CircularBufferWriter(buffer); + writer.Write((byte)0x3C); // Packet ID + writer.Seek(2, SeekOrigin.Current); + + writer.Write((short)list.Count); + + for (var i = list.Count - 1; i >= 0; --i) + { + var bis = list[i]; + + writer.Write(bis.MySerial); + writer.Write((ushort)bis.ItemID); + writer.Write((byte)0); // itemID offset + writer.Write((ushort)bis.Amount); + writer.Write((short)(i + 1)); // x + writer.Write((short)1); // y + if (ns.ContainerGridLines) + { + writer.Write((byte)0); // Grid Location? + } + writer.Write(bis.ContainerSerial); + writer.Write((ushort)bis.Hue); + } + + writer.WritePacketLength(); + ns.Send(ref buffer, writer.Position); + } + + public static void SendDisplayBuyList(this NetState ns, Serial vendor) + { + if (ns == null || !ns.GetSendBuffer(out var buffer)) + { + return; + } + + var writer = new CircularBufferWriter(buffer); + writer.Write((byte)0x24); // Packet ID + writer.Write(vendor); + writer.Write((short)0x30); // Vendor Buy Window + if (ns.HighSeas) + { + writer.Write((short)0x0); + } + + ns.Send(ref buffer, writer.Position); + } + + public static void SendVendorBuyList(this NetState ns, Mobile vendor, List list) + { + if (ns == null || !ns.GetSendBuffer(out var buffer)) + { + return; + } + + var writer = new CircularBufferWriter(buffer); + writer.Write((byte)0x74); // Packet ID + writer.Seek(2, SeekOrigin.Current); + writer.Write((vendor.FindItemOnLayer(Layer.ShopBuy) as Container)?.Serial ?? Serial.MinusOne); + writer.Write((byte)list.Count); + + for (var i = 0; i < list.Count; ++i) + { + var bis = list[i]; + + writer.Write(bis.Price); + + var desc = bis.Description ?? ""; + + writer.Write((byte)desc.Length); + writer.WriteAscii(desc); // Doesn't look like it is used anymore + } + + writer.WritePacketLength(); + + ns.Send(ref buffer, writer.Position); + } + + public static void SendEndVendorBuy(this NetState ns, Serial vendor) + { + if (ns == null || !ns.GetSendBuffer(out var buffer)) + { + return; + } + + var writer = new CircularBufferWriter(buffer); + writer.Write((byte)0x3B); // Packet ID + writer.Write((ushort)8); + writer.Write(vendor); + writer.Write((byte)0); // Buy count + + ns.Send(ref buffer, writer.Position); + } + } +} diff --git a/Projects/Server/Network/Packets/VendorBuyPackets.cs b/Projects/Server/Network/Packets/VendorBuyPackets.cs deleted file mode 100644 index 204a8f6df..000000000 --- a/Projects/Server/Network/Packets/VendorBuyPackets.cs +++ /dev/null @@ -1,123 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2020 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: VendorBuyPackets.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System.Collections.Generic; -using Server.Items; - -namespace Server.Network -{ - public sealed class VendorBuyContent : Packet - { - public VendorBuyContent(List list) : base(0x3C) - { - EnsureCapacity(list.Count * 19 + 5); - - Stream.Write((short)list.Count); - - for (var i = list.Count - 1; i >= 0; --i) - { - var bis = list[i]; - - Stream.Write(bis.MySerial); - Stream.Write((ushort)bis.ItemID); - Stream.Write((byte)0); // itemID offset - Stream.Write((ushort)bis.Amount); - Stream.Write((short)(i + 1)); // x - Stream.Write((short)1); // y - Stream.Write(bis.ContainerSerial); - Stream.Write((ushort)bis.Hue); - } - } - } - - public sealed class VendorBuyContent6017 : Packet - { - public VendorBuyContent6017(List list) : base(0x3C) - { - EnsureCapacity(list.Count * 20 + 5); - - Stream.Write((short)list.Count); - - for (var i = list.Count - 1; i >= 0; --i) - { - var bis = list[i]; - - Stream.Write(bis.MySerial); - Stream.Write((ushort)bis.ItemID); - Stream.Write((byte)0); // itemID offset - Stream.Write((ushort)bis.Amount); - Stream.Write((short)(i + 1)); // x - Stream.Write((short)1); // y - Stream.Write((byte)0); // Grid Location? - Stream.Write(bis.ContainerSerial); - Stream.Write((ushort)bis.Hue); - } - } - } - - public sealed class DisplayBuyList : Packet - { - public DisplayBuyList(Mobile vendor) : base(0x24, 7) - { - Stream.Write(vendor.Serial); - Stream.Write((short)0x30); // buy window id? - } - } - - public sealed class DisplayBuyListHS : Packet - { - public DisplayBuyListHS(Mobile vendor) : base(0x24, 9) - { - Stream.Write(vendor.Serial); - Stream.Write((short)0x30); // buy window id? - Stream.Write((short)0x00); - } - } - - public sealed class VendorBuyList : Packet - { - public VendorBuyList(Mobile vendor, List list) : base(0x74) - { - EnsureCapacity(256); - - Stream.Write(!(vendor.FindItemOnLayer(Layer.ShopBuy) is Container buyPack) ? Serial.MinusOne : buyPack.Serial); - - Stream.Write((byte)list.Count); - - for (var i = 0; i < list.Count; ++i) - { - var bis = list[i]; - - Stream.Write(bis.Price); - - var desc = bis.Description ?? ""; - - // TODO: Test if this is actually WriteAsciiFixed and the extra null doesn't matter. - Stream.Write((byte)(desc.Length + 1)); - Stream.WriteAsciiNull(desc); - } - } - } - - public sealed class EndVendorBuy : Packet - { - public EndVendorBuy(Mobile vendor) : base(0x3B, 8) - { - Stream.Write((ushort)8); // length - Stream.Write(vendor.Serial); - Stream.Write((byte)0); - } - } -} diff --git a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs index 816032c6b..ffd668c14 100644 --- a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs +++ b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs @@ -127,7 +127,6 @@ namespace Server.Mobiles UpdateBuyInfo(); - // IBuyItemInfo[] buyInfo = this.GetBuyInfo(); var info = GetSellInfo(); var totalCost = 0; var validBuy = new List(list.Count); @@ -910,13 +909,9 @@ namespace Server.Mobiles ) ); - if (disp is Item item) + if (disp is IPropertyListObject obj) { - opls.Add(item.PropertyList); - } - else if (disp is Mobile mobile) - { - opls.Add(mobile.PropertyList); + opls.Add(obj.PropertyList); } } @@ -981,25 +976,9 @@ namespace Server.Mobiles return; } - if (ns.ContainerGridLines) - { - from.Send(new VendorBuyContent6017(list)); - } - else - { - from.Send(new VendorBuyContent(list)); - } - - from.Send(new VendorBuyList(this, list)); - - if (ns.HighSeas) - { - from.Send(new DisplayBuyListHS(this)); - } - else - { - from.Send(new DisplayBuyList(this)); - } + from.NetState.SendVendorBuyContent(list); + from.NetState.SendVendorBuyList(this, list); + from.NetState.SendDisplayBuyList(Serial); from.Send(new MobileStatusExtended(from)); // make sure their gold amount is sent diff --git a/Projects/UOContent/Mobiles/Vendors/GenericSell.cs b/Projects/UOContent/Mobiles/Vendors/GenericSell.cs index b5a4ddcb4..d77eefe9a 100644 --- a/Projects/UOContent/Mobiles/Vendors/GenericSell.cs +++ b/Projects/UOContent/Mobiles/Vendors/GenericSell.cs @@ -102,41 +102,11 @@ namespace Server.Mobiles } } - public string GetNameFor(Item item) - { - if (item.Name != null) - { - return item.Name; - } + public string GetNameFor(Item item) => item.Name ?? item.LabelNumber.ToString(); - return item.LabelNumber.ToString(); - } + public bool IsSellable(Item item) => !item.Nontransferable && IsInList(item.GetType()); - public bool IsSellable(Item item) - { - if (item.Nontransferable) - { - return false; - } - - // if (item.Hue != 0) - // return false; - - return IsInList(item.GetType()); - } - - public bool IsResellable(Item item) - { - if (item.Nontransferable) - { - return false; - } - - // if (item.Hue != 0) - // return false; - - return IsInList(item.GetType()); - } + public bool IsResellable(Item item) => !item.Nontransferable && IsInList(item.GetType()); public void Add(Type type, int price) { diff --git a/Projects/UOContent/Mobiles/Vendors/PlayerVendor.cs b/Projects/UOContent/Mobiles/Vendors/PlayerVendor.cs index fafd750ec..38696aef2 100644 --- a/Projects/UOContent/Mobiles/Vendors/PlayerVendor.cs +++ b/Projects/UOContent/Mobiles/Vendors/PlayerVendor.cs @@ -36,18 +36,8 @@ namespace Server.Mobiles public int Price { get; } - public string FormattedPrice - { - get - { - if (Core.ML) - { - return Price.ToString("N0", CultureInfo.GetCultureInfo("en-US")); - } - - return Price.ToString(); - } - } + public string FormattedPrice => + Core.ML ? Price.ToString("N0", CultureInfo.GetCultureInfo("en-US")) : Price.ToString(); public string Description { @@ -1473,27 +1463,13 @@ namespace Server.Mobiles string firstWord; var sep = text.IndexOfAny(new[] { ' ', ',' }); - if (sep >= 0) - { - firstWord = text.Substring(0, sep); - } - else - { - firstWord = text; - } + firstWord = sep >= 0 ? text.Substring(0, sep) : text; string description; if (int.TryParse(firstWord, out var price)) { - if (sep >= 0) - { - description = text.Substring(sep + 1).Trim(); - } - else - { - description = ""; - } + description = sep >= 0 ? text.Substring(sep + 1).Trim() : ""; } else {