fix(core): Converts vendor buy packets (#339)
This commit is contained in:
parent
d71856ddbe
commit
5e991f6fb5
10 changed files with 255 additions and 513 deletions
|
|
@ -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<BuyItemState> m_States;
|
||||
|
||||
[GlobalSetup]
|
||||
public void SetUp()
|
||||
{
|
||||
m_States = new List<BuyItemState>
|
||||
{
|
||||
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<byte> 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<byte> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<ServerFixture>
|
||||
{
|
||||
[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<byte> 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<BuyItemState>
|
||||
{
|
||||
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<byte> 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<byte> 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<byte> 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<byte> 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<byte> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Network
|
||||
{
|
||||
public sealed class VendorBuyContent : Packet
|
||||
{
|
||||
public VendorBuyContent(List<BuyItemState> 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<BuyItemState> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<byte> expectedData = stackalloc byte[8];
|
||||
var pos = 0;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
125
Projects/Server/Network/Packets/OutgoingVendorBuyPackets.cs
Normal file
125
Projects/Server/Network/Packets/OutgoingVendorBuyPackets.cs
Normal file
|
|
@ -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 <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
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<BuyItemState> 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<BuyItemState> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Network
|
||||
{
|
||||
public sealed class VendorBuyContent : Packet
|
||||
{
|
||||
public VendorBuyContent(List<BuyItemState> 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<BuyItemState> 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<BuyItemState> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -127,7 +127,6 @@ namespace Server.Mobiles
|
|||
|
||||
UpdateBuyInfo();
|
||||
|
||||
// IBuyItemInfo[] buyInfo = this.GetBuyInfo();
|
||||
var info = GetSellInfo();
|
||||
var totalCost = 0;
|
||||
var validBuy = new List<BuyItemResponse>(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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue