Streamlines packet tests (#175)
This commit is contained in:
parent
6a727c3401
commit
7d20cf7642
29 changed files with 1782 additions and 1684 deletions
|
|
@ -1,38 +1,39 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
|
|
||||||
namespace Server.Tests.Network.Packets
|
namespace Server.Tests.Network.Packets
|
||||||
{
|
{
|
||||||
public static class AttributeNormalizerUtilities
|
public static class AttributeNormalizerUtilities
|
||||||
{
|
{
|
||||||
public static void Write(int cur, int max, bool normalize, Span<byte> data)
|
public static void WriteAttribute(this Span<byte> data, ref int pos, int cur, int max, bool normalize)
|
||||||
{
|
{
|
||||||
if (normalize && AttributeNormalizer.Enabled && max != 0)
|
if (normalize && AttributeNormalizer.Enabled && max != 0)
|
||||||
{
|
{
|
||||||
int maximum = AttributeNormalizer.Maximum;
|
int maximum = AttributeNormalizer.Maximum;
|
||||||
|
|
||||||
((ushort)maximum).CopyTo(data.Slice(0, 2));
|
data.Write(ref pos, (ushort)maximum);
|
||||||
((ushort)(cur * maximum / max)).CopyTo(data.Slice(2, 2));
|
data.Write(ref pos, (ushort)(cur * maximum / max));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
((ushort)max).CopyTo(data.Slice(0, 2));
|
data.Write(ref pos, (ushort)max);
|
||||||
((ushort)cur).CopyTo(data.Slice(2, 2));
|
data.Write(ref pos, (ushort)cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void WriteReverse(int cur, int max, bool normalize, Span<byte> data)
|
public static void WriteReverseAttribute(this Span<byte> data, ref int pos, int cur, int max, bool normalize)
|
||||||
{
|
{
|
||||||
if (normalize && AttributeNormalizer.Enabled && max != 0)
|
if (normalize && AttributeNormalizer.Enabled && max != 0)
|
||||||
{
|
{
|
||||||
int maximum = AttributeNormalizer.Maximum;
|
int maximum = AttributeNormalizer.Maximum;
|
||||||
|
|
||||||
((ushort)(cur * maximum / max)).CopyTo(data.Slice(0, 2));
|
data.Write(ref pos, (ushort)(cur * maximum / max));
|
||||||
((ushort)maximum).CopyTo(data.Slice(2, 2));
|
data.Write(ref pos, (ushort)maximum);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
((ushort)cur).CopyTo(data.Slice(0, 2));
|
data.Write(ref pos, (ushort)cur);
|
||||||
((ushort)max).CopyTo(data.Slice(2, 2));
|
data.Write(ref pos, (ushort)max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Server.Tests.Network.Packets
|
namespace Server.Tests.Network.Packets
|
||||||
{
|
{
|
||||||
public class GumpUtilities
|
public static class GumpUtilities
|
||||||
{
|
{
|
||||||
public static readonly byte[] NoMoveBuffer = Encoding.ASCII.GetBytes("{ nomove }");
|
public static readonly byte[] NoMoveBuffer = Encoding.ASCII.GetBytes("{ nomove }");
|
||||||
public static readonly byte[] NoCloseBuffer = Encoding.ASCII.GetBytes("{ noclose }");
|
public static readonly byte[] NoCloseBuffer = Encoding.ASCII.GetBytes("{ noclose }");
|
||||||
|
|
@ -16,25 +17,28 @@ namespace Server.Tests.Network.Packets
|
||||||
public const string NoDispose = "{ nodispose }";
|
public const string NoDispose = "{ nodispose }";
|
||||||
public const string NoResize = "{ noresize }";
|
public const string NoResize = "{ noresize }";
|
||||||
|
|
||||||
public static int WritePacked(ReadOnlySpan<byte> source, Span<byte> dest)
|
public static void WritePacked(this Span<byte> dest, ref int pos, ReadOnlySpan<byte> source)
|
||||||
{
|
{
|
||||||
int length = source.Length;
|
int length = source.Length;
|
||||||
|
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
{
|
{
|
||||||
dest.Slice(0, 4).Clear();
|
#if NO_LOCAL_INIT
|
||||||
return 4;
|
dest.Write(ref pos, 0);
|
||||||
|
#else
|
||||||
|
pos += 4;
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong packLength = (ulong)dest.Length - 8;
|
ulong packLength = (ulong)dest.Length - 8;
|
||||||
|
|
||||||
ZlibError ce = Zlib.Pack(dest.Slice(8), ref packLength, source, ZlibQuality.Default);
|
ZlibError ce = Zlib.Pack(dest.Slice(pos + 8), ref packLength, source, ZlibQuality.Default);
|
||||||
if (ce != ZlibError.Okay) Console.WriteLine("ZLib error: {0} (#{1})", ce, (int)ce);
|
if (ce != ZlibError.Okay) Console.WriteLine("ZLib error: {0} (#{1})", ce, (int)ce);
|
||||||
|
|
||||||
((int)(4 + packLength)).CopyTo(dest.Slice(0, 4));
|
dest.Write(ref pos, (int)(4 + packLength));
|
||||||
length.CopyTo(dest.Slice(4, 4));
|
dest.Write(ref pos, length);
|
||||||
|
pos += (int)packLength;
|
||||||
return (int)(8 + packLength);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO.Pipelines;
|
using System.IO.Pipelines;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
@ -114,22 +115,30 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> expectedData = stackalloc byte[5 + account.Length * 60];
|
Span<byte> expectedData = stackalloc byte[5 + account.Length * 60];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0x81).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0x81); // Packet ID
|
||||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
expectedData.Write(ref pos, (ushort)expectedData.Length); // Length
|
||||||
((byte)1).CopyTo(ref pos, expectedData); // Count of non-null characters
|
expectedData.Write(ref pos, (byte)1); // Count of non-null characters
|
||||||
((byte)0).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)0);
|
||||||
|
|
||||||
for (var i = 0; i < account.Length; ++i)
|
for (var i = 0; i < account.Length; ++i)
|
||||||
{
|
{
|
||||||
Mobile m = account[i];
|
Mobile m = account[i];
|
||||||
if (m == null)
|
if (m == null)
|
||||||
{
|
{
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
expectedData.Clear(ref pos, 60);
|
expectedData.Clear(ref pos, 60);
|
||||||
|
#else
|
||||||
|
pos += 60;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m.Name.CopyASCIIFixedTo(ref pos, 30, expectedData);
|
expectedData.WriteAsciiFixed(ref pos, m.Name, 30);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
expectedData.Clear(ref pos, 30); // Password (empty)
|
expectedData.Clear(ref pos, 30); // Password (empty)
|
||||||
|
#else
|
||||||
|
pos += 30;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,11 +164,11 @@ namespace Server.Tests.Network.Packets
|
||||||
{
|
{
|
||||||
Span<byte> data = new DeleteResult(DeleteResultType.BadRequest).Compile();
|
Span<byte> data = new DeleteResult(DeleteResultType.BadRequest).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[2];
|
||||||
{
|
int pos = 0;
|
||||||
0x85, // Packet ID
|
|
||||||
(byte)DeleteResultType.BadRequest
|
expectedData.Write(ref pos, (byte)0x85); // Packet ID
|
||||||
};
|
expectedData.Write(ref pos, (byte)DeleteResultType.BadRequest);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -169,11 +178,11 @@ namespace Server.Tests.Network.Packets
|
||||||
{
|
{
|
||||||
Span<byte> data = new PopupMessage(PMMessage.IdleWarning).Compile();
|
Span<byte> data = new PopupMessage(PMMessage.IdleWarning).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[2];
|
||||||
{
|
int pos = 0;
|
||||||
0x53, // Packet ID
|
|
||||||
(byte)PMMessage.IdleWarning
|
expectedData.Write(ref pos, (byte)0x53); // Packet ID
|
||||||
};
|
expectedData.Write(ref pos, (byte)PMMessage.IdleWarning);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -201,7 +210,9 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> data = new SupportedFeatures(ns).Compile();
|
Span<byte> data = new SupportedFeatures(ns).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[ns.ExtendedSupportedFeatures ? 5 : 3];
|
Span<byte> expectedData = stackalloc byte[ns.ExtendedSupportedFeatures ? 5 : 3];
|
||||||
expectedData[0] = 0xB9; // Packet ID
|
int pos = 0;
|
||||||
|
|
||||||
|
expectedData[pos++] = 0xB9; // Packet ID
|
||||||
|
|
||||||
var flags = ExpansionInfo.GetFeatures(Expansion.EJ);
|
var flags = ExpansionInfo.GetFeatures(Expansion.EJ);
|
||||||
|
|
||||||
|
|
@ -217,9 +228,9 @@ namespace Server.Tests.Network.Packets
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ns.ExtendedSupportedFeatures)
|
if (ns.ExtendedSupportedFeatures)
|
||||||
((uint)flags).CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (uint)flags);
|
||||||
else
|
else
|
||||||
((ushort)flags).CopyTo(expectedData.Slice(1, 2));
|
expectedData.Write(ref pos, (ushort)flags);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -238,41 +249,40 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new LoginConfirm(m).Compile();
|
Span<byte> data = new LoginConfirm(m).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[37];
|
||||||
{
|
|
||||||
0x1B, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, // Body
|
|
||||||
0x00, 0x00, // X
|
|
||||||
0x00, 0x00, // Y
|
|
||||||
0x00, 0x00, // Z
|
|
||||||
0x00, // Direction
|
|
||||||
0x00,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, // Map Width
|
|
||||||
0x00, 0x00, // Map Height
|
|
||||||
0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
int pos = 1;
|
int pos = 0;
|
||||||
m.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)0x1B); // Packet ID
|
||||||
|
expectedData.Write(ref pos, m.Serial);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
#else
|
||||||
pos += 4;
|
pos += 4;
|
||||||
((ushort)m.Body).CopyTo(ref pos, expectedData);
|
#endif
|
||||||
((ushort)m.X).CopyTo(ref pos, expectedData);
|
|
||||||
((ushort)m.Y).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)m.Body);
|
||||||
((ushort)m.Z).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)m.X);
|
||||||
((byte)m.Direction).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)m.Y);
|
||||||
pos += 9;
|
expectedData.Write(ref pos, (ushort)m.Z);
|
||||||
|
expectedData.Write(ref pos, (byte)m.Direction);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0);
|
||||||
|
#else
|
||||||
|
pos++;
|
||||||
|
#endif
|
||||||
|
expectedData.Write(ref pos, 0xFFFFFFFF);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
#else
|
||||||
|
pos += 4;
|
||||||
|
#endif
|
||||||
var map = m.Map;
|
var map = m.Map;
|
||||||
|
|
||||||
if (map == null || map == Map.Internal)
|
if (map == null || map == Map.Internal)
|
||||||
map = m.LogoutMap;
|
map = m.LogoutMap;
|
||||||
|
|
||||||
((ushort)(map?.Width ?? Map.Felucca.Width)).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)(map?.Width ?? Map.Felucca.Width));
|
||||||
((ushort)(map?.Height ?? Map.Felucca.Height)).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)(map?.Height ?? Map.Felucca.Height));
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -304,8 +314,8 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> expectedData = stackalloc byte[4 + account.Length * 60];
|
Span<byte> expectedData = stackalloc byte[4 + account.Length * 60];
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
((byte)0x86).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0x86); // Packet ID
|
||||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
expectedData.Write(ref pos, (ushort)expectedData.Length); // Length
|
||||||
|
|
||||||
int highSlot = -1;
|
int highSlot = -1;
|
||||||
for (int i = account.Length - 1; i >= 0; i--)
|
for (int i = account.Length - 1; i >= 0; i--)
|
||||||
|
|
@ -316,19 +326,39 @@ namespace Server.Tests.Network.Packets
|
||||||
}
|
}
|
||||||
|
|
||||||
int count = Math.Max(Math.Max(highSlot + 1, account.Limit), 5);
|
int count = Math.Max(Math.Max(highSlot + 1, account.Limit), 5);
|
||||||
((byte)count).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)count);
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var m = account[i];
|
var m = account[i];
|
||||||
|
|
||||||
if (m != null)
|
if (m != null)
|
||||||
{
|
{
|
||||||
m.Name.CopyASCIIFixedTo(ref pos, 30, expectedData);
|
expectedData.WriteAsciiFixed(ref pos, m.Name, 30);
|
||||||
expectedData.Clear(ref pos, 30);
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
expectedData.Write(ref pos, (ushort)0);
|
||||||
|
#else
|
||||||
|
pos += 30;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
expectedData.Clear(ref pos, 60);
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
#else
|
||||||
|
pos += 60;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -351,10 +381,10 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> data = new CharacterList(account, info).Compile();
|
Span<byte> data = new CharacterList(account, info).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[11 + account.Length * 60 + info.Length * 89];
|
Span<byte> expectedData = stackalloc byte[11 + account.Length * 60 + info.Length * 89];
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
((byte)0xA9).CopyTo(ref pos, expectedData); // Packet ID
|
|
||||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
expectedData.Write(ref pos, (byte)0xA9); // Packet ID
|
||||||
|
expectedData.Write(ref pos, (ushort)expectedData.Length); // Length
|
||||||
|
|
||||||
int highSlot = -1;
|
int highSlot = -1;
|
||||||
for (int i = account.Length - 1; i >= 0; i--)
|
for (int i = account.Length - 1; i >= 0; i--)
|
||||||
|
|
@ -365,36 +395,59 @@ namespace Server.Tests.Network.Packets
|
||||||
}
|
}
|
||||||
|
|
||||||
int count = Math.Max(Math.Max(highSlot + 1, account.Limit), 5);
|
int count = Math.Max(Math.Max(highSlot + 1, account.Limit), 5);
|
||||||
((byte)count).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)count);
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var m = account[i];
|
var m = account[i];
|
||||||
if (m != null)
|
if (m != null)
|
||||||
{
|
{
|
||||||
m.Name.CopyASCIIFixedTo(ref pos, 30, expectedData);
|
expectedData.WriteAsciiFixed(ref pos, m.Name, 30);
|
||||||
expectedData.Clear(ref pos, 30);
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
expectedData.Write(ref pos, (ushort)0);
|
||||||
|
#else
|
||||||
|
pos += 30;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
expectedData.Clear(ref pos, 60);
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
#else
|
||||||
|
pos += 60;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
((byte)info.Length).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)info.Length);
|
||||||
|
|
||||||
for (int i = 0; i < info.Length; i++)
|
for (int i = 0; i < info.Length; i++)
|
||||||
{
|
{
|
||||||
var ci = info[i];
|
var ci = info[i];
|
||||||
((byte)i).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)i);
|
||||||
ci.City.CopyASCIIFixedTo(ref pos, 32, expectedData);
|
expectedData.WriteAsciiFixed(ref pos, ci.City, 32);
|
||||||
ci.Building.CopyASCIIFixedTo(ref pos, 32, expectedData);
|
expectedData.WriteAsciiFixed(ref pos, ci.Building, 32);
|
||||||
ci.X.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, ci.X);
|
||||||
ci.Y.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, ci.Y);
|
||||||
ci.Z.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, ci.Z);
|
||||||
ci.Map.MapID.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, ci.Map.MapID);
|
||||||
ci.Description.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, ci.Description);
|
||||||
expectedData.Clear(ref pos, 4);
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
#else
|
||||||
|
pos += 4;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags = ExpansionInfo.GetInfo(Expansion.EJ).CharacterListFlags;
|
var flags = ExpansionInfo.GetInfo(Expansion.EJ).CharacterListFlags;
|
||||||
|
|
@ -407,8 +460,8 @@ namespace Server.Tests.Network.Packets
|
||||||
flags |= CharacterListFlags.SlotLimit &
|
flags |= CharacterListFlags.SlotLimit &
|
||||||
CharacterListFlags.OneCharacterSlot; // Limit Characters & One Character
|
CharacterListFlags.OneCharacterSlot; // Limit Characters & One Character
|
||||||
|
|
||||||
((int)flags).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (int)flags);
|
||||||
((short)-1).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (short)-1);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -431,8 +484,8 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> expectedData = stackalloc byte[9 + account.Length * 60 + info.Length * 63];
|
Span<byte> expectedData = stackalloc byte[9 + account.Length * 60 + info.Length * 63];
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
((byte)0xA9).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0xA9); // Packet ID
|
||||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
expectedData.Write(ref pos, (ushort)expectedData.Length); // Length
|
||||||
|
|
||||||
int highSlot = -1;
|
int highSlot = -1;
|
||||||
for (int i = account.Length - 1; i >= 0; i--)
|
for (int i = account.Length - 1; i >= 0; i--)
|
||||||
|
|
@ -443,30 +496,49 @@ namespace Server.Tests.Network.Packets
|
||||||
}
|
}
|
||||||
|
|
||||||
int count = Math.Max(Math.Max(highSlot + 1, account.Limit), 5);
|
int count = Math.Max(Math.Max(highSlot + 1, account.Limit), 5);
|
||||||
((byte)count).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)count);
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var m = account[i];
|
var m = account[i];
|
||||||
if (m != null)
|
if (m != null)
|
||||||
{
|
{
|
||||||
m.Name.CopyASCIIFixedTo(ref pos, 30, expectedData);
|
expectedData.WriteAsciiFixed(ref pos, m.Name, 30);
|
||||||
expectedData.Clear(ref pos, 30);
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
expectedData.Write(ref pos, (ushort)0);
|
||||||
|
#else
|
||||||
|
pos += 30;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
expectedData.Clear(ref pos, 60);
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
#else
|
||||||
|
pos += 60;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
((byte)info.Length).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)info.Length);
|
||||||
|
|
||||||
for (int i = 0; i < info.Length; i++)
|
for (int i = 0; i < info.Length; i++)
|
||||||
{
|
{
|
||||||
var ci = info[i];
|
var ci = info[i];
|
||||||
((byte)i).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)i);
|
||||||
ci.City.CopyASCIIFixedTo(ref pos, 31, expectedData);
|
expectedData.WriteAsciiFixed(ref pos, ci.City, 31);
|
||||||
ci.Building.CopyASCIIFixedTo(ref pos, 31, expectedData);
|
expectedData.WriteAsciiFixed(ref pos, ci.Building, 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags = ExpansionInfo.GetInfo(Expansion.EJ).CharacterListFlags;
|
var flags = ExpansionInfo.GetInfo(Expansion.EJ).CharacterListFlags;
|
||||||
|
|
@ -479,7 +551,7 @@ namespace Server.Tests.Network.Packets
|
||||||
flags |= CharacterListFlags.SlotLimit &
|
flags |= CharacterListFlags.SlotLimit &
|
||||||
CharacterListFlags.OneCharacterSlot; // Limit Characters & One Character
|
CharacterListFlags.OneCharacterSlot; // Limit Characters & One Character
|
||||||
|
|
||||||
((int)flags).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (int)flags);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -490,11 +562,11 @@ namespace Server.Tests.Network.Packets
|
||||||
var reason = ALRReason.BadComm;
|
var reason = ALRReason.BadComm;
|
||||||
Span<byte> data = new AccountLoginRej(reason).Compile();
|
Span<byte> data = new AccountLoginRej(reason).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[2];
|
||||||
{
|
int pos = 0;
|
||||||
0x82, // Packet ID
|
|
||||||
(byte)reason
|
expectedData.Write(ref pos, (byte)0x82); // Packet ID
|
||||||
};
|
expectedData.Write(ref pos, (byte)reason);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -512,19 +584,19 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> expectedData = stackalloc byte[6 + info.Length * 40];
|
Span<byte> expectedData = stackalloc byte[6 + info.Length * 40];
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
((byte)0xA8).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0xA8); // Packet ID
|
||||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)expectedData.Length);
|
||||||
((byte)0x5D).CopyTo(ref pos, expectedData); // Unknown
|
expectedData.Write(ref pos, (byte)0x5D); // Unknown
|
||||||
((ushort)info.Length).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)info.Length);
|
||||||
|
|
||||||
for (int i = 0; i < info.Length; i++)
|
for (int i = 0; i < info.Length; i++)
|
||||||
{
|
{
|
||||||
var si = info[i];
|
var si = info[i];
|
||||||
((ushort)i).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)i);
|
||||||
si.Name.CopyASCIIFixedTo(ref pos, 32, expectedData);
|
expectedData.WriteAsciiFixed(ref pos, si.Name, 32);
|
||||||
((byte)si.FullPercent).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)si.FullPercent);
|
||||||
((byte)si.TimeZone).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)si.TimeZone);
|
||||||
Utility.GetAddressValue(si.Address.Address).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, Utility.GetAddressValue(si.Address.Address));
|
||||||
}
|
}
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
|
|
@ -539,19 +611,13 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
var addr = Utility.GetAddressValue(si.Address.Address);
|
var addr = Utility.GetAddressValue(si.Address.Address);
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[11];
|
||||||
{
|
int pos = 0;
|
||||||
0x8C, // Packet ID
|
|
||||||
(byte)addr, // IP Address in LE
|
|
||||||
(byte)(addr >> 8),
|
|
||||||
(byte)(addr >> 16),
|
|
||||||
(byte)(addr >> 24),
|
|
||||||
0x00, 0x00, // Port
|
|
||||||
0x00, 0x00, 0x00, 0x00 // Auth ID
|
|
||||||
};
|
|
||||||
|
|
||||||
((ushort)si.Address.Port).CopyTo(expectedData.Slice(5, 2));
|
expectedData.Write(ref pos,(byte)0x8C); // Packet ID
|
||||||
(-1).CopyTo(expectedData.Slice(7, 4)); // Auth ID
|
expectedData.WriteLE(ref pos, addr);
|
||||||
|
expectedData.Write(ref pos, (ushort)si.Address.Port);
|
||||||
|
expectedData.Write(ref pos, -1); // Auth ID
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -11,13 +12,12 @@ namespace Server.Tests.Network.Packets
|
||||||
{
|
{
|
||||||
Span<byte> data = new CancelArrow().Compile();
|
Span<byte> data = new CancelArrow().Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[6];
|
||||||
{
|
int pos = 0;
|
||||||
0xBA, // Packet ID
|
|
||||||
0x00, // Command
|
expectedData.Write(ref pos, (byte)0xBA); // Packet ID
|
||||||
0xFF, 0xFF, // X
|
expectedData.Write(ref pos, (byte)0); // Command
|
||||||
0xFF, 0xFF // Y
|
expectedData.Write(ref pos, 0xFFFFFFFF); // X, Y
|
||||||
};
|
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -30,16 +30,13 @@ namespace Server.Tests.Network.Packets
|
||||||
{
|
{
|
||||||
Span<byte> data = new SetArrow(x, y).Compile();
|
Span<byte> data = new SetArrow(x, y).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[6];
|
||||||
{
|
int pos = 0;
|
||||||
0xBA, // Packet ID
|
|
||||||
0x01, // Command
|
|
||||||
0x00, 0x00, // X
|
|
||||||
0x00, 0x00 // Y
|
|
||||||
};
|
|
||||||
|
|
||||||
((ushort)x).CopyTo(expectedData.Slice(2, 2));
|
expectedData.Write(ref pos, (byte)0xBA); // Packet ID
|
||||||
((ushort)y).CopyTo(expectedData.Slice(4, 2));
|
expectedData.Write(ref pos, (byte)0x01); // Command
|
||||||
|
expectedData.Write(ref pos, (ushort)x);
|
||||||
|
expectedData.Write(ref pos, (ushort)y);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -50,19 +47,21 @@ namespace Server.Tests.Network.Packets
|
||||||
[InlineData(100000, 100000)]
|
[InlineData(100000, 100000)]
|
||||||
public void TestCancelArrowHS(int x, int y)
|
public void TestCancelArrowHS(int x, int y)
|
||||||
{
|
{
|
||||||
Span<byte> data = new CancelArrowHS(x, y, 0x1).Compile();
|
Serial serial = 0x01;
|
||||||
|
Span<byte> data = new CancelArrowHS(x, y, serial).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[10];
|
||||||
{
|
int pos = 0;
|
||||||
0xBA, // Packet ID
|
|
||||||
0x00, // Command
|
|
||||||
0x00, 0x00, // X
|
|
||||||
0x00, 0x00, // Y
|
|
||||||
0x00, 0x00, 0x00, 0x01 // Serial
|
|
||||||
};
|
|
||||||
|
|
||||||
((ushort)x).CopyTo(expectedData.Slice(2, 2));
|
expectedData.Write(ref pos, (byte)0xBA); // Packet ID
|
||||||
((ushort)y).CopyTo(expectedData.Slice(4, 2));
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0); // Command
|
||||||
|
#else
|
||||||
|
pos++;
|
||||||
|
#endif
|
||||||
|
expectedData.Write(ref pos, (ushort)x);
|
||||||
|
expectedData.Write(ref pos, (ushort)y);
|
||||||
|
expectedData.Write(ref pos, serial);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -73,19 +72,17 @@ namespace Server.Tests.Network.Packets
|
||||||
[InlineData(100000, 100000)]
|
[InlineData(100000, 100000)]
|
||||||
public void TestSetArrowHS(int x, int y)
|
public void TestSetArrowHS(int x, int y)
|
||||||
{
|
{
|
||||||
Span<byte> data = new SetArrowHS(x, y, 0x1).Compile();
|
Serial serial = 0x01;
|
||||||
|
Span<byte> data = new SetArrowHS(x, y, serial).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[10];
|
||||||
{
|
int pos = 0;
|
||||||
0xBA, // Packet ID
|
|
||||||
0x01, // Command
|
|
||||||
0x00, 0x00, // X
|
|
||||||
0x00, 0x00, // Y
|
|
||||||
0x00, 0x00, 0x00, 0x01 // Serial
|
|
||||||
};
|
|
||||||
|
|
||||||
((ushort)x).CopyTo(expectedData.Slice(2, 2));
|
expectedData.Write(ref pos, (byte)0xBA); // Packet ID
|
||||||
((ushort)y).CopyTo(expectedData.Slice(4, 2));
|
expectedData.Write(ref pos, (byte)0x01); // Command
|
||||||
|
expectedData.Write(ref pos, (ushort)x);
|
||||||
|
expectedData.Write(ref pos, (ushort)y);
|
||||||
|
expectedData.Write(ref pos, serial);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -14,19 +15,15 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
PacketWriter stream = new PacketWriter(4);
|
PacketWriter stream = new PacketWriter(4);
|
||||||
|
|
||||||
const short cur = 50;
|
const ushort cur = 50;
|
||||||
const short max = 100;
|
const ushort max = 100;
|
||||||
|
|
||||||
AttributeNormalizer.Write(stream, cur, max);
|
AttributeNormalizer.Write(stream, cur, max);
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[4];
|
||||||
{
|
int pos = 0;
|
||||||
0x00, 0x00, // Maximum Normalized
|
expectedData.Write(ref pos, (ushort)AttributeNormalizer.Maximum);
|
||||||
0x00, 0x00 // Current Normalized
|
expectedData.Write(ref pos, (ushort)(cur * 25 / max));
|
||||||
};
|
|
||||||
|
|
||||||
((short)AttributeNormalizer.Maximum).CopyTo(expectedData.Slice(0, 2));
|
|
||||||
((short)(cur * 25 / max)).CopyTo(expectedData.Slice(2, 2));
|
|
||||||
|
|
||||||
AssertThat.Equal(stream.ToArray(), expectedData);
|
AssertThat.Equal(stream.ToArray(), expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -39,19 +36,15 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
PacketWriter stream = new PacketWriter(4);
|
PacketWriter stream = new PacketWriter(4);
|
||||||
|
|
||||||
const short cur = 50;
|
const ushort cur = 50;
|
||||||
const short max = 100;
|
const ushort max = 100;
|
||||||
|
|
||||||
AttributeNormalizer.WriteReverse(stream, cur, max);
|
AttributeNormalizer.WriteReverse(stream, cur, max);
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[4];
|
||||||
{
|
int pos = 0;
|
||||||
0x00, 0x00, // Current Normalized
|
expectedData.Write(ref pos, (ushort)(cur * 25 / max));
|
||||||
0x00, 0x00 // Maximum Normalized
|
expectedData.Write(ref pos, (ushort)AttributeNormalizer.Maximum);
|
||||||
};
|
|
||||||
|
|
||||||
((short)AttributeNormalizer.Maximum).CopyTo(expectedData.Slice(2, 2));
|
|
||||||
((short)(cur * 25 / max)).CopyTo(expectedData.Slice(0, 2));
|
|
||||||
|
|
||||||
AssertThat.Equal(stream.ToArray(), expectedData);
|
AssertThat.Equal(stream.ToArray(), expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -63,19 +56,15 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
PacketWriter stream = new PacketWriter(4);
|
PacketWriter stream = new PacketWriter(4);
|
||||||
|
|
||||||
const short cur = 50;
|
const ushort cur = 50;
|
||||||
const short max = 100;
|
const ushort max = 100;
|
||||||
|
|
||||||
AttributeNormalizer.Write(stream, cur, max);
|
AttributeNormalizer.Write(stream, cur, max);
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[4];
|
||||||
{
|
int pos = 0;
|
||||||
0x00, 0x00, // Maximum
|
expectedData.Write(ref pos, max);
|
||||||
0x00, 0x00 // Current
|
expectedData.Write(ref pos, cur);
|
||||||
};
|
|
||||||
|
|
||||||
max.CopyTo(expectedData.Slice(0, 2));
|
|
||||||
cur.CopyTo(expectedData.Slice(2, 2));
|
|
||||||
|
|
||||||
AssertThat.Equal(stream.ToArray(), expectedData);
|
AssertThat.Equal(stream.ToArray(), expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -87,19 +76,15 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
PacketWriter stream = new PacketWriter(4);
|
PacketWriter stream = new PacketWriter(4);
|
||||||
|
|
||||||
const short cur = 50;
|
const ushort cur = 50;
|
||||||
const short max = 100;
|
const ushort max = 100;
|
||||||
|
|
||||||
AttributeNormalizer.WriteReverse(stream, cur, max);
|
AttributeNormalizer.WriteReverse(stream, cur, max);
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[4];
|
||||||
{
|
int pos = 0;
|
||||||
0x00, 0x00, // Current
|
expectedData.Write(ref pos, cur);
|
||||||
0x00, 0x00 // Maximum
|
expectedData.Write(ref pos, max);
|
||||||
};
|
|
||||||
|
|
||||||
max.CopyTo(expectedData.Slice(2, 2));
|
|
||||||
cur.CopyTo(expectedData.Slice(0, 2));
|
|
||||||
|
|
||||||
AssertThat.Equal(stream.ToArray(), expectedData);
|
AssertThat.Equal(stream.ToArray(), expectedData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -14,16 +15,18 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new Swing(attacker, defender).Compile();
|
Span<byte> data = new Swing(attacker, defender).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[10];
|
||||||
{
|
int pos = 0;
|
||||||
0x2F, // Packet ID
|
|
||||||
0x00, // Unknown
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Attacker
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Defender
|
|
||||||
};
|
|
||||||
|
|
||||||
attacker.CopyTo(expectedData.Slice(2, 4));
|
expectedData.Write(ref pos, (byte)0x2F); // Packet ID
|
||||||
defender.CopyTo(expectedData.Slice(6, 4));
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0);
|
||||||
|
#else
|
||||||
|
pos++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
expectedData.Write(ref pos, attacker);
|
||||||
|
expectedData.Write(ref pos, defender);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -35,12 +38,25 @@ namespace Server.Tests.Network.Packets
|
||||||
{
|
{
|
||||||
Span<byte> data = new SetWarMode(warmode).Compile();
|
Span<byte> data = new SetWarMode(warmode).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[5];
|
||||||
{
|
int pos = 0;
|
||||||
0x72, // Packet ID
|
|
||||||
warmode ? (byte)0x01 : (byte)0x00, // Mode
|
expectedData.Write(ref pos, (byte)0x72); // Packet ID
|
||||||
0x00, 0x32, 0x00 // Unknown
|
expectedData.Write(ref pos, warmode);
|
||||||
};
|
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0);
|
||||||
|
#else
|
||||||
|
pos++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
expectedData.Write(ref pos, (byte)0x32);
|
||||||
|
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0);
|
||||||
|
#else
|
||||||
|
pos++;
|
||||||
|
#endif
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -52,13 +68,11 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new ChangeCombatant(combatant).Compile();
|
Span<byte> data = new ChangeCombatant(combatant).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[5];
|
||||||
{
|
int pos = 0;
|
||||||
0xAA, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00 // Combatant
|
|
||||||
};
|
|
||||||
|
|
||||||
combatant.CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (byte)0xAA); // Packet ID
|
||||||
|
expectedData.Write(ref pos, combatant);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -17,17 +18,16 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new DamagePacketOld(m.Serial, inputAmount).Compile();
|
Span<byte> data = new DamagePacketOld(m.Serial, inputAmount).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[11];
|
||||||
{
|
int pos = 0;
|
||||||
0xBF, // Packet ID
|
|
||||||
0x00, 0x0B, // Length
|
expectedData.Write(ref pos, (byte)0xBF); // Packet ID
|
||||||
0x00, 0x22, // Sub-packet
|
expectedData.Write(ref pos, (ushort)11); // Length
|
||||||
0x01, // Command
|
expectedData.Write(ref pos, (ushort)0x22); // Sub-packet
|
||||||
0x00, 0x00, 0x00, 0x00, // Mobile Serial
|
expectedData.Write(ref pos, (byte)0x01); // Command
|
||||||
expectedAmount // Amount
|
expectedData.Write(ref pos, m.Serial);
|
||||||
};
|
expectedData.Write(ref pos, expectedAmount);
|
||||||
|
|
||||||
m.Serial.CopyTo(expectedData.Slice(6, 4));
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,15 +43,12 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new DamagePacket(m.Serial, inputAmount).Compile();
|
Span<byte> data = new DamagePacket(m.Serial, inputAmount).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[7];
|
||||||
{
|
int pos = 0;
|
||||||
0x0B, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Mobile Serial
|
|
||||||
0x00, 0x00 // Amount
|
|
||||||
};
|
|
||||||
|
|
||||||
m.Serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (byte)0x0B); // Packet ID
|
||||||
expectedAmount.CopyTo(expectedData.Slice(5, 2));
|
expectedData.Write(ref pos, m.Serial);
|
||||||
|
expectedData.Write(ref pos, expectedAmount);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using Server.HuePickers;
|
using Server.HuePickers;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -15,16 +16,17 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new DisplayHuePicker(huePicker).Compile();
|
Span<byte> data = new DisplayHuePicker(huePicker).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[9];
|
||||||
{
|
int pos = 0;
|
||||||
0x95, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Hue Picker Serial
|
|
||||||
0x00, 0x00, // Nothing
|
|
||||||
0x00, 0x00 // Item ID
|
|
||||||
};
|
|
||||||
|
|
||||||
huePicker.Serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (byte)0x95);
|
||||||
itemID.CopyTo(expectedData.Slice(7, 2));
|
expectedData.Write(ref pos, huePicker.Serial);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (ushort)0);
|
||||||
|
#else
|
||||||
|
pos += 2;
|
||||||
|
#endif
|
||||||
|
expectedData.Write(ref pos, itemID);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -39,30 +40,34 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> expectedData = stackalloc byte[49];
|
Span<byte> expectedData = stackalloc byte[49];
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
((byte)0xC7).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0xC7); // Packet ID
|
||||||
((byte)effectType).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)effectType);
|
||||||
from.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, from);
|
||||||
to.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, to);
|
||||||
((ushort)itemId).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)itemId);
|
||||||
((ushort)fromPoint.X).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)fromPoint.X);
|
||||||
((ushort)fromPoint.Y).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)fromPoint.Y);
|
||||||
((byte)fromPoint.Z).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)fromPoint.Z);
|
||||||
((ushort)toPoint.X).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)toPoint.X);
|
||||||
((ushort)toPoint.Y).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)toPoint.Y);
|
||||||
((byte)toPoint.Z).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)toPoint.Z);
|
||||||
speed.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, speed);
|
||||||
duration.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, duration);
|
||||||
expectedData.Clear(ref pos, 2);
|
#if NO_LOCAL_INIT
|
||||||
direction.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)0);
|
||||||
explode.CopyTo(ref pos, expectedData);
|
#else
|
||||||
hue.CopyTo(ref pos, expectedData);
|
pos += 2;
|
||||||
renderMode.CopyTo(ref pos, expectedData);
|
#endif
|
||||||
effect.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, direction);
|
||||||
explodeEffect.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, explode);
|
||||||
explodeSound.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, hue);
|
||||||
serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, renderMode);
|
||||||
layer.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, effect);
|
||||||
unknown.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, explodeEffect);
|
||||||
|
expectedData.Write(ref pos, explodeSound);
|
||||||
|
expectedData.Write(ref pos, serial);
|
||||||
|
expectedData.Write(ref pos, layer);
|
||||||
|
expectedData.Write(ref pos, unknown);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -93,24 +98,28 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> expectedData = stackalloc byte[36];
|
Span<byte> expectedData = stackalloc byte[36];
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
((byte)0xC0).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0xC0); // Packet ID
|
||||||
((byte)effectType).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)effectType);
|
||||||
from.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, from);
|
||||||
to.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, to);
|
||||||
((ushort)itemId).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)itemId);
|
||||||
((ushort)fromPoint.X).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)fromPoint.X);
|
||||||
((ushort)fromPoint.Y).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)fromPoint.Y);
|
||||||
((byte)fromPoint.Z).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)fromPoint.Z);
|
||||||
((ushort)toPoint.X).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)toPoint.X);
|
||||||
((ushort)toPoint.Y).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)toPoint.Y);
|
||||||
((byte)toPoint.Z).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)toPoint.Z);
|
||||||
speed.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, speed);
|
||||||
duration.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, duration);
|
||||||
expectedData.Clear(ref pos, 2);
|
#if NO_LOCAL_INIT
|
||||||
direction.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)0);
|
||||||
explode.CopyTo(ref pos, expectedData);
|
#else
|
||||||
hue.CopyTo(ref pos, expectedData);
|
pos += 2;
|
||||||
renderMode.CopyTo(ref pos, expectedData);
|
#endif
|
||||||
|
expectedData.Write(ref pos, direction);
|
||||||
|
expectedData.Write(ref pos, explode);
|
||||||
|
expectedData.Write(ref pos, hue);
|
||||||
|
expectedData.Write(ref pos, renderMode);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -121,20 +130,26 @@ namespace Server.Tests.Network.Packets
|
||||||
var type = ScreenEffectType.FadeOut;
|
var type = ScreenEffectType.FadeOut;
|
||||||
Span<byte> data = new ScreenEffect(type).Compile();
|
Span<byte> data = new ScreenEffect(type).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[28]
|
Span<byte> expectedData = stackalloc byte[28];
|
||||||
{
|
int pos = 0;
|
||||||
0x70, // Packet ID
|
|
||||||
0x04,
|
|
||||||
0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, // Screen Effect Type
|
|
||||||
0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
((ushort)type).CopyTo(expectedData.Slice(10, 2));
|
expectedData.Write(ref pos, (byte)0x70); // Packet ID
|
||||||
|
expectedData.Write(ref pos, (byte)0x04); // Effect
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
#else
|
||||||
|
pos += 8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
expectedData.Write(ref pos, (ushort)type); // Screen Effect Type
|
||||||
|
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -146,31 +161,32 @@ namespace Server.Tests.Network.Packets
|
||||||
var hue = 0x1024;
|
var hue = 0x1024;
|
||||||
Span<byte> data = new BoltEffect(entity, hue).Compile();
|
Span<byte> data = new BoltEffect(entity, hue).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[36]
|
Span<byte> expectedData = stackalloc byte[36];
|
||||||
{
|
int pos = 0;
|
||||||
0xC0, // Packet ID
|
expectedData.Write(ref pos, (byte)0xC0); // Packet ID
|
||||||
0x01, // Effect
|
expectedData.Write(ref pos, (byte)0x01); // Effect
|
||||||
0x00, 0x00, 0x00, 0x00, // From Serial
|
|
||||||
0x00, 0x00, 0x00, 0x00, // To Serial
|
|
||||||
0x00, 0x00, // Item ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, // From Point
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, // To Point
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Hue
|
|
||||||
0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
int pos = 2;
|
|
||||||
entity.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, entity.Serial);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
expectedData.Write(ref pos, (ushort)0);
|
||||||
|
#else
|
||||||
pos += 6;
|
pos += 6;
|
||||||
((ushort)entity.X).CopyTo(ref pos, expectedData);
|
#endif
|
||||||
((ushort)entity.Y).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)entity.X);
|
||||||
((byte)entity.Z).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)entity.Y);
|
||||||
((ushort)entity.X).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)entity.Z);
|
||||||
((ushort)entity.Y).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)entity.X);
|
||||||
((byte)entity.Z).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)entity.Y);
|
||||||
|
expectedData.Write(ref pos, (byte)entity.Z);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
expectedData.Write(ref pos, (ushort)0);
|
||||||
|
#else
|
||||||
pos += 6;
|
pos += 6;
|
||||||
hue.CopyTo(ref pos, expectedData);
|
#endif
|
||||||
|
expectedData.Write(ref pos, hue);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -37,28 +38,29 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0xBF).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0xBF); // Packet ID
|
||||||
((ushort)length).CopyTo(ref pos, expectedData); // Length
|
expectedData.Write(ref pos, (ushort)length); // Length
|
||||||
((ushort)0x10).CopyTo(ref pos, expectedData); // Subcommand
|
expectedData.Write(ref pos, (ushort)0x10); // Subcommand
|
||||||
item.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, item.Serial);
|
||||||
info.Number.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, info.Number);
|
||||||
if (info.Crafter != null)
|
if (info.Crafter != null)
|
||||||
{
|
{
|
||||||
var name = info.Crafter.Name ?? "";
|
var name = info.Crafter.Name ?? "";
|
||||||
(-3).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, -3);
|
||||||
name.CopyASCIITo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)name.Length);
|
||||||
|
expectedData.WriteAscii(ref pos, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.Unidentified) (-4).CopyTo(ref pos, expectedData);
|
if (info.Unidentified) expectedData.Write(ref pos, -4);
|
||||||
|
|
||||||
for (var i = 0; i < attrs.Length; i++)
|
for (var i = 0; i < attrs.Length; i++)
|
||||||
{
|
{
|
||||||
var attr = attrs[i];
|
var attr = attrs[i];
|
||||||
attr.Number.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, attr.Number);
|
||||||
((ushort)attr.Charges).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)attr.Charges);
|
||||||
}
|
}
|
||||||
|
|
||||||
(-1).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (-1));
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -73,20 +75,21 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new EquipUpdate(item).Compile();
|
Span<byte> data = new EquipUpdate(item).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[15];
|
||||||
{
|
int pos = 0;
|
||||||
0x2E, // Packet ID
|
expectedData.Write(ref pos, (byte)0x2E); // Packet ID
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
expectedData.Write(ref pos, item.Serial);
|
||||||
0x00, 0x00, // Item ID
|
expectedData.Write(ref pos, (ushort)item.ItemID);
|
||||||
0x00, (byte)item.Layer,
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Parent Serial
|
|
||||||
0x00, 0x00, // Hue
|
|
||||||
};
|
|
||||||
|
|
||||||
item.Serial.CopyTo(expectedData.Slice(1, 4));
|
#if NO_LOCAL_INIT
|
||||||
((ushort)item.ItemID).CopyTo(expectedData.Slice(5, 2));
|
expectedData.Write(ref pos, (byte)0);
|
||||||
item.Parent.Serial.CopyTo(expectedData.Slice(9, 4));
|
#else
|
||||||
((ushort)item.Hue).CopyTo(expectedData.Slice(13, 2));
|
pos++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
expectedData.Write(ref pos, (byte)item.Layer);
|
||||||
|
expectedData.Write(ref pos, item.Parent.Serial);
|
||||||
|
expectedData.Write(ref pos, (ushort)item.Hue);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,17 +19,14 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new CloseGump(typeId, buttonId).Compile();
|
Span<byte> data = new CloseGump(typeId, buttonId).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[13];
|
||||||
{
|
int pos = 0;
|
||||||
0xBF, // Packet ID
|
|
||||||
0x00, 0xD, // Length
|
|
||||||
0x00, 0x04, // Close
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Type Id
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Button Id
|
|
||||||
};
|
|
||||||
|
|
||||||
typeId.CopyTo(expectedData.Slice(5, 4));
|
expectedData.Write(ref pos, (byte)0xBF); // Packet ID
|
||||||
buttonId.CopyTo(expectedData.Slice(9, 4));
|
expectedData.Write(ref pos, (ushort)0xD); // Length
|
||||||
|
expectedData.Write(ref pos, (ushort)0x4); // Close Gump
|
||||||
|
expectedData.Write(ref pos, typeId);
|
||||||
|
expectedData.Write(ref pos, buttonId);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -45,14 +42,16 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> data = new DisplaySignGump(gumpSerial, gumpId, unknownString, caption).Compile();
|
Span<byte> data = new DisplaySignGump(gumpSerial, gumpId, unknownString, caption).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[15 + unknownString.Length + caption.Length];
|
Span<byte> expectedData = stackalloc byte[15 + unknownString.Length + caption.Length];
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
((byte)0x8B).CopyTo(ref pos, expectedData);
|
|
||||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)0x8B);
|
||||||
gumpSerial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)expectedData.Length);
|
||||||
((ushort)gumpId).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, gumpSerial);
|
||||||
unknownString.CopyASCIINullTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)gumpId);
|
||||||
caption.CopyASCIINullTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)(unknownString.Length + 1));
|
||||||
|
expectedData.WriteAsciiNull(ref pos, unknownString);
|
||||||
|
expectedData.Write(ref pos, (ushort)(caption.Length + 1));
|
||||||
|
expectedData.WriteAsciiNull(ref pos, caption);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -76,52 +75,52 @@ namespace Server.Tests.Network.Packets
|
||||||
expectedData[pos++] = 0xB0; // Packet ID
|
expectedData[pos++] = 0xB0; // Packet ID
|
||||||
pos += 2; // Length
|
pos += 2; // Length
|
||||||
|
|
||||||
gump.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, gump.Serial);
|
||||||
gump.TypeID.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, gump.TypeID);
|
||||||
gump.X.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, gump.X);
|
||||||
gump.Y.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, gump.Y);
|
||||||
pos += 2; // Layout Length
|
pos += 2; // Layout Length
|
||||||
|
|
||||||
int layoutLength = 0;
|
int layoutLength = 0;
|
||||||
|
|
||||||
if (!gump.Draggable)
|
if (!gump.Draggable)
|
||||||
{
|
{
|
||||||
GumpUtilities.NoMoveBuffer.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, GumpUtilities.NoMoveBuffer);
|
||||||
layoutLength += GumpUtilities.NoMove.Length;
|
layoutLength += GumpUtilities.NoMove.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gump.Closable)
|
if (!gump.Closable)
|
||||||
{
|
{
|
||||||
GumpUtilities.NoCloseBuffer.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, GumpUtilities.NoCloseBuffer);
|
||||||
layoutLength += GumpUtilities.NoClose.Length;
|
layoutLength += GumpUtilities.NoClose.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gump.Disposable)
|
if (!gump.Disposable)
|
||||||
{
|
{
|
||||||
GumpUtilities.NoDisposeBuffer.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, GumpUtilities.NoDisposeBuffer);
|
||||||
layoutLength += GumpUtilities.NoDispose.Length;
|
layoutLength += GumpUtilities.NoDispose.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gump.Resizable)
|
if (!gump.Resizable)
|
||||||
{
|
{
|
||||||
GumpUtilities.NoResizeBuffer.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, GumpUtilities.NoResizeBuffer);
|
||||||
layoutLength += GumpUtilities.NoResize.Length;
|
layoutLength += GumpUtilities.NoResize.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var entry in gump.Entries)
|
foreach (var entry in gump.Entries)
|
||||||
{
|
{
|
||||||
var str = entry.Compile(ns);
|
var str = entry.Compile(ns);
|
||||||
str.CopyRawASCIITo(ref pos, expectedData);
|
expectedData.WriteAscii(ref pos, str);
|
||||||
layoutLength += str.Length; // ASCII so 1:1
|
layoutLength += str.Length; // ASCII so 1:1
|
||||||
}
|
}
|
||||||
|
|
||||||
((ushort)layoutLength).CopyTo(expectedData.Slice(19, 2));
|
expectedData.Slice(19, 2).Write((ushort)layoutLength);
|
||||||
((ushort)gump.Strings.Count).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)gump.Strings.Count);
|
||||||
|
|
||||||
for (var i = 0; i < gump.Strings.Count; ++i)
|
for (var i = 0; i < gump.Strings.Count; ++i)
|
||||||
(gump.Strings[i] ?? "").CopyUnicodeBigEndianTo(ref pos, expectedData);
|
expectedData.WriteBigUni(ref pos, gump.Strings[i] ?? "");
|
||||||
|
|
||||||
((ushort)pos).CopyTo(expectedData.Slice(1, 2));
|
expectedData.Slice(1, 2).Write((ushort)pos); // Length
|
||||||
|
|
||||||
expectedData = expectedData.Slice(0, pos);
|
expectedData = expectedData.Slice(0, pos);
|
||||||
|
|
||||||
|
|
@ -134,9 +133,10 @@ namespace Server.Tests.Network.Packets
|
||||||
NetState ns = new NetState(new AccountPacketTests.TestConnectionContext
|
NetState ns = new NetState(new AccountPacketTests.TestConnectionContext
|
||||||
{
|
{
|
||||||
RemoteEndPoint = IPEndPoint.Parse("127.0.0.1"),
|
RemoteEndPoint = IPEndPoint.Parse("127.0.0.1"),
|
||||||
});
|
})
|
||||||
|
{
|
||||||
ns.ProtocolChanges = ProtocolChanges.Unpack;
|
ProtocolChanges = ProtocolChanges.Unpack
|
||||||
|
};
|
||||||
|
|
||||||
var gump = new ResurrectGump(2);
|
var gump = new ResurrectGump(2);
|
||||||
|
|
||||||
|
|
@ -149,10 +149,10 @@ namespace Server.Tests.Network.Packets
|
||||||
expectedData[pos++] = 0xDD; // Packet ID
|
expectedData[pos++] = 0xDD; // Packet ID
|
||||||
pos += 2; // Length
|
pos += 2; // Length
|
||||||
|
|
||||||
gump.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, gump.Serial);
|
||||||
gump.TypeID.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, gump.TypeID);
|
||||||
gump.X.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, gump.X);
|
||||||
gump.Y.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, gump.Y);
|
||||||
|
|
||||||
var layoutList = new List<string>();
|
var layoutList = new List<string>();
|
||||||
int bufferLength = 1; // Null terminated
|
int bufferLength = 1; // Null terminated
|
||||||
|
|
@ -194,24 +194,30 @@ namespace Server.Tests.Network.Packets
|
||||||
int bufferPos = 0;
|
int bufferPos = 0;
|
||||||
|
|
||||||
foreach (var layout in layoutList)
|
foreach (var layout in layoutList)
|
||||||
layout.CopyRawASCIITo(ref bufferPos, buffer);
|
buffer.WriteAscii(ref bufferPos, layout);
|
||||||
|
|
||||||
pos += GumpUtilities.WritePacked(buffer.Slice(0, bufferPos + 1), expectedData.Slice(pos));
|
#if NO_LOCAL_INIT
|
||||||
|
buffer.Write(ref bufferPos, (byte)0); // Layout terminator
|
||||||
|
#else
|
||||||
|
bufferPos++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
expectedData.WritePacked(ref pos, buffer.Slice(0, bufferPos));
|
||||||
memOwner.Dispose();
|
memOwner.Dispose();
|
||||||
|
|
||||||
gump.Strings.Count.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, gump.Strings.Count);
|
||||||
bufferLength = gump.Strings.Sum(str => 2 + str.Length * 2);
|
bufferLength = gump.Strings.Sum(str => 2 + str.Length * 2);
|
||||||
memOwner = SlabMemoryPool.Shared.Rent(bufferLength);
|
memOwner = SlabMemoryPool.Shared.Rent(bufferLength);
|
||||||
buffer = memOwner.Memory.Span;
|
buffer = memOwner.Memory.Span;
|
||||||
bufferPos = 0;
|
bufferPos = 0;
|
||||||
|
|
||||||
foreach (var str in gump.Strings)
|
foreach (var str in gump.Strings)
|
||||||
str.CopyUnicodeBigEndianTo(ref bufferPos, buffer);
|
buffer.WriteBigUni(ref bufferPos, str);
|
||||||
|
|
||||||
pos += GumpUtilities.WritePacked(buffer.Slice(0, bufferPos), expectedData.Slice(pos));
|
expectedData.WritePacked(ref pos, buffer.Slice(0, bufferPos));
|
||||||
|
|
||||||
// Length
|
// Length
|
||||||
((ushort)pos).CopyTo(expectedData.Slice(1, 2));
|
expectedData.Slice(1, 2).Write((ushort)pos);
|
||||||
expectedData = expectedData.Slice(0, pos);
|
expectedData = expectedData.Slice(0, pos);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -32,21 +33,21 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> expectedData = stackalloc byte[20]; // Max size
|
Span<byte> expectedData = stackalloc byte[20]; // Max size
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0x1A).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)0x1A);
|
||||||
pos += 2; // Length
|
pos += 2; // Length
|
||||||
|
|
||||||
if (item.Amount != 0)
|
if (item.Amount != 0)
|
||||||
(serial | 0x80000000).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, serial | 0x80000000);
|
||||||
else
|
else
|
||||||
(serial & 0x7FFFFFFF).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, serial & 0x7FFFFFFF);
|
||||||
|
|
||||||
if (item is BaseMulti)
|
if (item is BaseMulti)
|
||||||
((ushort)(item.ItemID | 0x4000)).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)(item.ItemID | 0x4000));
|
||||||
else
|
else
|
||||||
((ushort)item.ItemID).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)item.ItemID);
|
||||||
|
|
||||||
if (item.Amount != 0)
|
if (item.Amount != 0)
|
||||||
((ushort)item.Amount).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)item.Amount);
|
||||||
|
|
||||||
byte direction = (byte)item.Direction;
|
byte direction = (byte)item.Direction;
|
||||||
ushort x = (ushort)(item.X & 0x7FFF);
|
ushort x = (ushort)(item.X & 0x7FFF);
|
||||||
|
|
@ -54,7 +55,7 @@ namespace Server.Tests.Network.Packets
|
||||||
if (direction != 0)
|
if (direction != 0)
|
||||||
x |= 0x8000;
|
x |= 0x8000;
|
||||||
|
|
||||||
x.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, x);
|
||||||
|
|
||||||
int hue = item.Hue;
|
int hue = item.Hue;
|
||||||
int flags = item.GetPacketFlags();
|
int flags = item.GetPacketFlags();
|
||||||
|
|
@ -63,21 +64,21 @@ namespace Server.Tests.Network.Packets
|
||||||
if (hue != 0) y |= 0x8000;
|
if (hue != 0) y |= 0x8000;
|
||||||
if (flags != 0) y |= 0x4000;
|
if (flags != 0) y |= 0x4000;
|
||||||
|
|
||||||
y.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, y);
|
||||||
|
|
||||||
if (direction != 0)
|
if (direction != 0)
|
||||||
direction.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, direction);
|
||||||
|
|
||||||
((byte)item.Z).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)item.Z);
|
||||||
|
|
||||||
if (hue != 0)
|
if (hue != 0)
|
||||||
((ushort)hue).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)hue);
|
||||||
|
|
||||||
if (flags != 0)
|
if (flags != 0)
|
||||||
((byte)flags).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)flags);
|
||||||
|
|
||||||
// Length
|
// Length
|
||||||
((ushort)pos).CopyTo(expectedData.Slice(1, 2));
|
expectedData.Slice(1, 2).Write((ushort)pos);
|
||||||
|
|
||||||
// Slice the data to match in size
|
// Slice the data to match in size
|
||||||
data = data.Slice(0, pos);
|
data = data.Slice(0, pos);
|
||||||
|
|
@ -109,34 +110,29 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new WorldItemSA(item).Compile();
|
Span<byte> data = new WorldItemSA(item).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[24];
|
||||||
{
|
int pos = 0;
|
||||||
0xF3, // Packet ID
|
|
||||||
0x00, 0x01,
|
|
||||||
(byte)(isMulti ? 0x02 : 0x00), // Item Type (Regular, or Multi)
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0x00, 0x00, // Item ID
|
|
||||||
0x00,
|
|
||||||
0x00, 0x00, // Amount (min?)
|
|
||||||
0x00, 0x00, // Amount (max?)
|
|
||||||
0x00, 0x00, // X
|
|
||||||
0x00, 0x00, // Y
|
|
||||||
(byte)loc.Z, // Z
|
|
||||||
(byte)item.Light, // Light
|
|
||||||
0x00, 0x00, // Hue
|
|
||||||
(byte)item.GetPacketFlags() // Flags
|
|
||||||
};
|
|
||||||
|
|
||||||
serial.CopyTo(expectedData.Slice(4, 4));
|
expectedData.Write(ref pos, (byte)0xF3); // Packet ID
|
||||||
((ushort)(itemId & (isMulti ? 0x3FFF : 0xFFFF))).CopyTo(expectedData.Slice(8, 2));
|
expectedData.Write(ref pos, (ushort)0x1);
|
||||||
|
expectedData.Write(ref pos, (byte)(isMulti ? 0x2 : 0x00)); // Item Type (Regular, or Multi)
|
||||||
|
expectedData.Write(ref pos, item.Serial);
|
||||||
|
expectedData.Write(ref pos, (ushort)(item.ItemID & (isMulti ? 0x3FFF : 0xFFFF)));
|
||||||
|
|
||||||
ushort amount = (ushort)item.Amount;
|
#if NO_LOCAL_INIT
|
||||||
amount.CopyTo(expectedData.Slice(11, 2));
|
expectedData.Write(ref pos, (byte)0)
|
||||||
amount.CopyTo(expectedData.Slice(13, 2));
|
#else
|
||||||
|
pos++;
|
||||||
|
#endif
|
||||||
|
|
||||||
((ushort)loc.X).CopyTo(expectedData.Slice(15, 2));
|
expectedData.Write(ref pos, (ushort)item.Amount); // Amount (min?)
|
||||||
((ushort)loc.Y).CopyTo(expectedData.Slice(17, 2));
|
expectedData.Write(ref pos, (ushort)item.Amount); // Amount (max?)
|
||||||
((ushort)item.Hue).CopyTo(expectedData.Slice(21, 2));
|
expectedData.Write(ref pos, (ushort)loc.X); // X
|
||||||
|
expectedData.Write(ref pos, (ushort)loc.Y); // Y
|
||||||
|
expectedData.Write(ref pos, (byte)loc.Z); // Z
|
||||||
|
expectedData.Write(ref pos, (byte)item.Light); // Light
|
||||||
|
expectedData.Write(ref pos, (ushort)item.Hue); // Hue
|
||||||
|
expectedData.Write(ref pos, (byte)item.GetPacketFlags()); // Flags
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -165,35 +161,33 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new WorldItemHS(item).Compile();
|
Span<byte> data = new WorldItemHS(item).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[26];
|
||||||
{
|
int pos = 0;
|
||||||
0xF3, // Packet ID
|
|
||||||
0x00, 0x01,
|
|
||||||
(byte)(isMulti ? 0x02 : 0x00), // Item Type (Regular, or Multi)
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0x00, 0x00, // Item ID
|
|
||||||
0x00,
|
|
||||||
0x00, 0x00, // Amount (min?)
|
|
||||||
0x00, 0x00, // Amount (max?)
|
|
||||||
0x00, 0x00, // X
|
|
||||||
0x00, 0x00, // Y
|
|
||||||
(byte)loc.Z, // Z
|
|
||||||
(byte)item.Light, // Light
|
|
||||||
0x00, 0x00, // Hue
|
|
||||||
(byte)item.GetPacketFlags(), // Flags
|
|
||||||
00, 00 // ???
|
|
||||||
};
|
|
||||||
|
|
||||||
serial.CopyTo(expectedData.Slice(4, 4));
|
expectedData.Write(ref pos, (byte)0xF3); // Packet ID
|
||||||
((ushort)(itemId & (isMulti ? 0x3FFF : 0xFFFF))).CopyTo(expectedData.Slice(8, 2));
|
expectedData.Write(ref pos, (ushort)0x1);
|
||||||
|
expectedData.Write(ref pos, (byte)(isMulti ? 0x2 : 0x00)); // Item Type (Regular, or Multi)
|
||||||
|
expectedData.Write(ref pos, item.Serial);
|
||||||
|
expectedData.Write(ref pos, (ushort)(item.ItemID & (isMulti ? 0x3FFF : 0xFFFF)));
|
||||||
|
|
||||||
ushort amount = (ushort)item.Amount;
|
#if NO_LOCAL_INIT
|
||||||
amount.CopyTo(expectedData.Slice(11, 2));
|
expectedData.Write(ref pos, (byte)0);
|
||||||
amount.CopyTo(expectedData.Slice(13, 2));
|
#else
|
||||||
|
pos++;
|
||||||
|
#endif
|
||||||
|
|
||||||
((ushort)loc.X).CopyTo(expectedData.Slice(15, 2));
|
expectedData.Write(ref pos, (ushort)item.Amount); // Amount (min?)
|
||||||
((ushort)loc.Y).CopyTo(expectedData.Slice(17, 2));
|
expectedData.Write(ref pos, (ushort)item.Amount); // Amount (max?)
|
||||||
((ushort)item.Hue).CopyTo(expectedData.Slice(21, 2));
|
expectedData.Write(ref pos, (ushort)loc.X); // X
|
||||||
|
expectedData.Write(ref pos, (ushort)loc.Y); // Y
|
||||||
|
expectedData.Write(ref pos, (byte)loc.Z); // Z
|
||||||
|
expectedData.Write(ref pos, (byte)item.Light); // Light
|
||||||
|
expectedData.Write(ref pos, (ushort)item.Hue); // Hue
|
||||||
|
expectedData.Write(ref pos, (byte)item.GetPacketFlags()); // Flags
|
||||||
|
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (ushort)0); // ??
|
||||||
|
#endif
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -206,15 +200,12 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new ContainerDisplay(serial, gumpId).Compile();
|
Span<byte> data = new ContainerDisplay(serial, gumpId).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[7];
|
||||||
{
|
int pos = 0;
|
||||||
0x24, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0x00, 0x00 // Gump ID
|
|
||||||
};
|
|
||||||
|
|
||||||
serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (byte)0x24); // Packet ID
|
||||||
gumpId.CopyTo(expectedData.Slice(5, 2));
|
expectedData.Write(ref pos, serial);
|
||||||
|
expectedData.Write(ref pos, gumpId);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -227,16 +218,13 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new ContainerDisplayHS(serial, gumpId).Compile();
|
Span<byte> data = new ContainerDisplayHS(serial, gumpId).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[9];
|
||||||
{
|
int pos = 0;
|
||||||
0x24, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0x00, 0x00, // Gump ID
|
|
||||||
0x00, 0x7D // Max Items?
|
|
||||||
};
|
|
||||||
|
|
||||||
serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (byte)0x24); // Packet ID
|
||||||
gumpId.CopyTo(expectedData.Slice(5, 2));
|
expectedData.Write(ref pos, serial);
|
||||||
|
expectedData.Write(ref pos, gumpId);
|
||||||
|
expectedData.Write(ref pos, (ushort)0x7D); // Max Items?
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -248,14 +236,12 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new DisplaySpellbook(serial).Compile();
|
Span<byte> data = new DisplaySpellbook(serial).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[7];
|
||||||
{
|
int pos = 0;
|
||||||
0x24, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0xFF, 0xFF // Gump ID
|
|
||||||
};
|
|
||||||
|
|
||||||
serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (byte)0x24); // Packet ID
|
||||||
|
expectedData.Write(ref pos, serial);
|
||||||
|
expectedData.Write(ref pos, (ushort)0xFFFF); // Gump ID
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -267,15 +253,13 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new DisplaySpellbookHS(serial).Compile();
|
Span<byte> data = new DisplaySpellbookHS(serial).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[9];
|
||||||
{
|
int pos = 0;
|
||||||
0x24, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0xFF, 0xFF, // Gump ID
|
|
||||||
0x00, 0x7D // Max Items?
|
|
||||||
};
|
|
||||||
|
|
||||||
serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (byte)0x24); // Packet ID
|
||||||
|
expectedData.Write(ref pos, serial);
|
||||||
|
expectedData.Write(ref pos, (ushort)0xFFFF); // Gump ID
|
||||||
|
expectedData.Write(ref pos, (ushort)0x7D); // Max Items?
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -290,23 +274,17 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new NewSpellbookContent(serial, graphic, offset, content).Compile();
|
Span<byte> data = new NewSpellbookContent(serial, graphic, offset, content).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[23];
|
||||||
{
|
int pos = 0;
|
||||||
0xBF, // Packet ID
|
|
||||||
0x00, 0x17, // Length
|
|
||||||
0x00, 0x1B, // Sub-packet
|
|
||||||
0x00, 0x01,
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0x00, 0x00, // Graphic
|
|
||||||
0x00, 0x00, // Offset
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Content
|
|
||||||
0x00, 0x00, 0x00, 0x00 // Content
|
|
||||||
};
|
|
||||||
|
|
||||||
serial.CopyTo(expectedData.Slice(7, 4));
|
expectedData.Write(ref pos, (byte)0xBF); // Packet ID
|
||||||
graphic.CopyTo(expectedData.Slice(11, 2));
|
expectedData.Write(ref pos, (ushort)0x17); // Length
|
||||||
offset.CopyTo(expectedData.Slice(13, 2));
|
expectedData.Write(ref pos, (ushort)0x1B); // Sub-packet
|
||||||
content.CopyToLE(expectedData.Slice(15, 8));
|
expectedData.Write(ref pos, (ushort)0x1); // Command
|
||||||
|
expectedData.Write(ref pos, serial);
|
||||||
|
expectedData.Write(ref pos, graphic);
|
||||||
|
expectedData.Write(ref pos, offset);
|
||||||
|
expectedData.WriteLE(ref pos, content);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -323,7 +301,7 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> expectedData = stackalloc byte[5 + 64 * 19]; // Max size
|
Span<byte> expectedData = stackalloc byte[5 + 64 * 19]; // Max size
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0x3C).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0x3C); // Packet ID
|
||||||
pos += 4; // Length + spell count
|
pos += 4; // Length + spell count
|
||||||
|
|
||||||
ushort count = 0;
|
ushort count = 0;
|
||||||
|
|
@ -331,17 +309,30 @@ namespace Server.Tests.Network.Packets
|
||||||
for (var i = 0; i < 64; i++)
|
for (var i = 0; i < 64; i++)
|
||||||
if ((content & (1ul << i)) != 0)
|
if ((content & (1ul << i)) != 0)
|
||||||
{
|
{
|
||||||
(0x7FFFFFFF - i).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, 0x7FFFFFFF - i);
|
||||||
expectedData.Clear(ref pos, 3);
|
#if NO_LOCAL_INIT
|
||||||
((ushort)(i + offset)).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)0);
|
||||||
expectedData.Clear(ref pos, 4); // X, Y
|
expectedData.Write(ref pos, (byte)0);
|
||||||
serial.CopyTo(ref pos, expectedData);
|
#else
|
||||||
expectedData.Clear(ref pos, 2);
|
pos += 3;
|
||||||
|
#endif
|
||||||
|
expectedData.Write(ref pos, (ushort)(i + offset));
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, 0); // X. Y
|
||||||
|
#else
|
||||||
|
pos += 4;
|
||||||
|
#endif
|
||||||
|
expectedData.Write(ref pos, serial);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (ushort)0);
|
||||||
|
#else
|
||||||
|
pos += 2;
|
||||||
|
#endif
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
((ushort)pos).CopyTo(expectedData.Slice(1, 2));
|
expectedData.Slice(1, 2).Write((ushort)pos); // Length
|
||||||
count.CopyTo(expectedData.Slice(3, 2));
|
expectedData.Slice(3, 2).Write(count); // Count
|
||||||
|
|
||||||
expectedData = expectedData.Slice(0, pos);
|
expectedData = expectedData.Slice(0, pos);
|
||||||
|
|
||||||
|
|
@ -357,10 +348,10 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new SpellbookContent6017(serial, offset, content).Compile();
|
Span<byte> data = new SpellbookContent6017(serial, offset, content).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[5 + 64 * 19]; // Max size
|
Span<byte> expectedData = stackalloc byte[5 + 64 * 20]; // Max size
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0x3C).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0x3C); // Packet ID
|
||||||
pos += 4; // Length + spell count
|
pos += 4; // Length + spell count
|
||||||
|
|
||||||
ushort count = 0;
|
ushort count = 0;
|
||||||
|
|
@ -368,17 +359,31 @@ namespace Server.Tests.Network.Packets
|
||||||
for (var i = 0; i < 64; i++)
|
for (var i = 0; i < 64; i++)
|
||||||
if ((content & (1ul << i)) != 0)
|
if ((content & (1ul << i)) != 0)
|
||||||
{
|
{
|
||||||
(0x7FFFFFFF - i).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, 0x7FFFFFFF - i);
|
||||||
expectedData.Clear(ref pos, 3);
|
#if NO_LOCAL_INIT
|
||||||
((ushort)(i + offset)).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)0);
|
||||||
expectedData.Clear(ref pos, 5); // X, Y, Grid Location
|
expectedData.Write(ref pos, (byte)0);
|
||||||
serial.CopyTo(ref pos, expectedData);
|
#else
|
||||||
expectedData.Clear(ref pos, 2);
|
pos += 3;
|
||||||
|
#endif
|
||||||
|
expectedData.Write(ref pos, (ushort)(i + offset));
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, 0); // X. Y
|
||||||
|
expectedData.Write(ref pos, (byte)0); // Grid Location
|
||||||
|
#else
|
||||||
|
pos += 5;
|
||||||
|
#endif
|
||||||
|
expectedData.Write(ref pos, serial);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (ushort)0);
|
||||||
|
#else
|
||||||
|
pos += 2;
|
||||||
|
#endif
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
((ushort)pos).CopyTo(expectedData.Slice(1, 2));
|
expectedData.Slice(1, 2).Write((ushort)pos); // Length
|
||||||
count.CopyTo(expectedData.Slice(3, 2));
|
expectedData.Slice(3, 2).Write(count); // Count
|
||||||
|
|
||||||
expectedData = expectedData.Slice(0, pos);
|
expectedData = expectedData.Slice(0, pos);
|
||||||
|
|
||||||
|
|
@ -396,15 +401,19 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> expectedData = stackalloc byte[20];
|
Span<byte> expectedData = stackalloc byte[20];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0x25).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0x25); // Packet ID
|
||||||
item.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, item.Serial);
|
||||||
((ushort)item.ItemID).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)item.ItemID);
|
||||||
((byte)0).CopyTo(ref pos, expectedData); // signed, itemID offset
|
#if NO_LOCAL_INIT
|
||||||
((ushort)Math.Min(item.Amount, ushort.MaxValue)).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)0); // ItemID offset
|
||||||
((ushort)item.X).CopyTo(ref pos, expectedData);
|
#else
|
||||||
((ushort)item.Y).CopyTo(ref pos, expectedData);
|
pos++;
|
||||||
(item.Parent?.Serial ?? Serial.Zero).CopyTo(ref pos, expectedData);
|
#endif
|
||||||
((ushort)(item.QuestItem ? Item.QuestItemHue : item.Hue)).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)Math.Min(item.Amount, ushort.MaxValue));
|
||||||
|
expectedData.Write(ref pos, (ushort)item.X);
|
||||||
|
expectedData.Write(ref pos, (ushort)item.Y);
|
||||||
|
expectedData.Write(ref pos, item.Parent?.Serial ?? Serial.Zero);
|
||||||
|
expectedData.Write(ref pos, (ushort)(item.QuestItem ? Item.QuestItemHue : item.Hue));
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -420,16 +429,24 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> expectedData = stackalloc byte[21];
|
Span<byte> expectedData = stackalloc byte[21];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0x25).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0x25); // Packet ID
|
||||||
item.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, item.Serial);
|
||||||
((ushort)item.ItemID).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)item.ItemID);
|
||||||
((byte)0).CopyTo(ref pos, expectedData); // signed, itemID offset
|
#if NO_LOCAL_INIT
|
||||||
((ushort)Math.Min(item.Amount, ushort.MaxValue)).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)0); // ItemID offset
|
||||||
((ushort)item.X).CopyTo(ref pos, expectedData);
|
#else
|
||||||
((ushort)item.Y).CopyTo(ref pos, expectedData);
|
pos++;
|
||||||
((byte)0).CopyTo(ref pos, expectedData); // Grid Location?
|
#endif
|
||||||
(item.Parent?.Serial ?? Serial.Zero).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)Math.Min(item.Amount, ushort.MaxValue));
|
||||||
((ushort)(item.QuestItem ? Item.QuestItemHue : item.Hue)).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)item.X);
|
||||||
|
expectedData.Write(ref pos, (ushort)item.Y);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0); // Grid Location?
|
||||||
|
#else
|
||||||
|
pos++;
|
||||||
|
#endif
|
||||||
|
expectedData.Write(ref pos, item.Parent?.Serial ?? Serial.Zero);
|
||||||
|
expectedData.Write(ref pos, (ushort)(item.QuestItem ? Item.QuestItemHue : item.Hue));
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -445,36 +462,39 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new ContainerContent(m, cont).Compile();
|
Span<byte> data = new ContainerContent(m, cont).Compile();
|
||||||
|
|
||||||
int count = cont.Items.Count;
|
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[5 + cont.Items.Count * 19]; // Max Size
|
Span<byte> expectedData = stackalloc byte[5 + cont.Items.Count * 19]; // Max Size
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0x3C).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0x3C); // Packet ID
|
||||||
pos += 4; // Length + Count
|
pos += 4; // Length + Count
|
||||||
|
|
||||||
ushort written = 0;
|
ushort count = 0;
|
||||||
|
|
||||||
for (var i = 0; i < count; i++)
|
int itemCount = cont.Items.Count;
|
||||||
|
for (var i = 0; i < itemCount; i++)
|
||||||
{
|
{
|
||||||
var child = cont.Items[i];
|
var child = cont.Items[i];
|
||||||
if (child.Deleted || !m.CanSee(child))
|
if (child.Deleted || !m.CanSee(child))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
child.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, child.Serial);
|
||||||
((ushort)child.ItemID).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)child.ItemID);
|
||||||
((byte)0).CopyTo(ref pos, expectedData); // signed, itemID offset
|
#if NO_LOCAL_INIT
|
||||||
((ushort)Math.Min(child.Amount, ushort.MaxValue)).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)0); // ItemID offset
|
||||||
((ushort)child.X).CopyTo(ref pos, expectedData);
|
#else
|
||||||
((ushort)child.Y).CopyTo(ref pos, expectedData);
|
pos++;
|
||||||
cont.Serial.CopyTo(ref pos, expectedData);
|
#endif
|
||||||
((ushort)(child.QuestItem ? Item.QuestItemHue : child.Hue)).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)Math.Min(child.Amount, ushort.MaxValue));
|
||||||
|
expectedData.Write(ref pos, (ushort)child.X);
|
||||||
|
expectedData.Write(ref pos, (ushort)child.Y);
|
||||||
|
expectedData.Write(ref pos, cont.Serial);
|
||||||
|
expectedData.Write(ref pos, (ushort)(child.QuestItem ? Item.QuestItemHue : child.Hue));
|
||||||
|
|
||||||
written++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
((ushort)pos).CopyTo(expectedData.Slice(1, 2));
|
expectedData.Slice(1, 2).Write((ushort)pos); // Length
|
||||||
written.CopyTo(expectedData.Slice(3, 2));
|
expectedData.Slice(3, 2).Write(count); // Count
|
||||||
|
|
||||||
expectedData = expectedData.Slice(0, pos);
|
expectedData = expectedData.Slice(0, pos);
|
||||||
|
|
||||||
|
|
@ -492,37 +512,44 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new ContainerContent6017(m, cont).Compile();
|
Span<byte> data = new ContainerContent6017(m, cont).Compile();
|
||||||
|
|
||||||
int count = cont.Items.Count;
|
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[5 + cont.Items.Count * 20];
|
Span<byte> expectedData = stackalloc byte[5 + cont.Items.Count * 20];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0x3C).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0x3C); // Packet ID
|
||||||
pos += 4; // Length + Count
|
pos += 4; // Length + Count
|
||||||
|
|
||||||
ushort written = 0;
|
ushort count = 0;
|
||||||
|
|
||||||
for (var i = 0; i < count; i++)
|
int itemCount = cont.Items.Count;
|
||||||
|
for (var i = 0; i < itemCount; i++)
|
||||||
{
|
{
|
||||||
var child = cont.Items[i];
|
var child = cont.Items[i];
|
||||||
if (child.Deleted || !m.CanSee(child))
|
if (child.Deleted || !m.CanSee(child))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
child.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, child.Serial);
|
||||||
((ushort)child.ItemID).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)child.ItemID);
|
||||||
((byte)0).CopyTo(ref pos, expectedData); // signed, itemID offset
|
#if NO_LOCAL_INIT
|
||||||
((ushort)Math.Min(child.Amount, ushort.MaxValue)).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)0); // ItemID offset
|
||||||
((ushort)child.X).CopyTo(ref pos, expectedData);
|
#else
|
||||||
((ushort)child.Y).CopyTo(ref pos, expectedData);
|
pos++;
|
||||||
((byte)0).CopyTo(ref pos, expectedData); // Grid Location?
|
#endif
|
||||||
cont.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)Math.Min(child.Amount, ushort.MaxValue));
|
||||||
((ushort)(child.QuestItem ? Item.QuestItemHue : child.Hue)).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)child.X);
|
||||||
|
expectedData.Write(ref pos, (ushort)child.Y);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0); // Grid Location?
|
||||||
|
#else
|
||||||
|
pos++;
|
||||||
|
#endif
|
||||||
|
expectedData.Write(ref pos, cont.Serial);
|
||||||
|
expectedData.Write(ref pos, (ushort)(child.QuestItem ? Item.QuestItemHue : child.Hue));
|
||||||
|
|
||||||
written++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
((ushort)pos).CopyTo(expectedData.Slice(1, 2));
|
expectedData.Slice(1, 2).Write((ushort)pos); // Length
|
||||||
written.CopyTo(expectedData.Slice(3, 2));
|
expectedData.Slice(3, 2).Write(count); // Count
|
||||||
|
|
||||||
expectedData = expectedData.Slice(0, pos);
|
expectedData = expectedData.Slice(0, pos);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -12,11 +13,11 @@ namespace Server.Tests.Network.Packets
|
||||||
byte lightLevel = 5;
|
byte lightLevel = 5;
|
||||||
Span<byte> data = new GlobalLightLevel(lightLevel).Compile();
|
Span<byte> data = new GlobalLightLevel(lightLevel).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[2];
|
||||||
{
|
int pos = 0;
|
||||||
0x4F, // Packet ID
|
|
||||||
lightLevel
|
expectedData.Write(ref pos, (byte)0x4F); // Packet ID
|
||||||
};
|
expectedData.Write(ref pos, lightLevel);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -28,14 +29,12 @@ namespace Server.Tests.Network.Packets
|
||||||
byte lightLevel = 5;
|
byte lightLevel = 5;
|
||||||
Span<byte> data = new PersonalLightLevel(serial, lightLevel).Compile();
|
Span<byte> data = new PersonalLightLevel(serial, lightLevel).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[6];
|
||||||
{
|
int pos = 0;
|
||||||
0x4E, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
lightLevel
|
|
||||||
};
|
|
||||||
|
|
||||||
serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (byte)0x4E); // Packet ID
|
||||||
|
expectedData.Write(ref pos, serial);
|
||||||
|
expectedData.Write(ref pos, lightLevel);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ namespace Server.Tests.Network.Packets
|
||||||
0xBF, // Packet ID
|
0xBF, // Packet ID
|
||||||
0x00, 0x06, // Length
|
0x00, 0x06, // Length
|
||||||
0x00, 0x08, // Sub-packet
|
0x00, 0x08, // Sub-packet
|
||||||
0x00, // Felucca
|
0x00 // Felucca
|
||||||
};
|
};
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Server.ContextMenus;
|
using Server.ContextMenus;
|
||||||
|
|
@ -40,29 +41,40 @@ namespace Server.Tests.Network.Packets
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
string question = menu.Question?.Trim() ?? "";
|
|
||||||
int questionLength = Math.Min(255, question.Length);
|
|
||||||
|
|
||||||
int length = 11 + questionLength + menu.Entries.Sum(entry => 5 + entry.Name?.Trim().Length ?? 0);
|
|
||||||
|
|
||||||
Span<byte> data = new DisplayItemListMenu(menu).Compile();
|
Span<byte> data = new DisplayItemListMenu(menu).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[length];
|
string question = menu.Question;
|
||||||
|
int questionLength = Math.Min(255, question.Length);
|
||||||
|
int entriesCount = 0;
|
||||||
|
int length = 11 + questionLength;
|
||||||
|
|
||||||
|
foreach (var entry in menu.Entries)
|
||||||
|
{
|
||||||
|
length += 5 + entry.Name.Length;
|
||||||
|
if (entriesCount == 255)
|
||||||
|
break;
|
||||||
|
|
||||||
|
entriesCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> expectedData = stackalloc byte[length];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0x7C).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0x7C); // Packet ID
|
||||||
((ushort)length).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)length);
|
||||||
menu.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, menu.Serial);
|
||||||
((ushort)0x00).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)0x00);
|
||||||
question.CopySmallASCIITo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)questionLength);
|
||||||
((byte)menu.Entries.Length).CopyTo(ref pos, expectedData);
|
expectedData.WriteAscii(ref pos, question, 255);
|
||||||
for (int i = 0; i < menu.Entries.Length; i++)
|
expectedData.Write(ref pos, (byte)entriesCount);
|
||||||
|
for (int i = 0; i < entriesCount; i++)
|
||||||
{
|
{
|
||||||
var entry = menu.Entries[i];
|
var entry = menu.Entries[i];
|
||||||
((ushort)entry.ItemID).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)entry.ItemID);
|
||||||
((ushort)entry.Hue).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)entry.Hue);
|
||||||
(entry.Name?.Trim() ?? "").CopySmallASCIITo(ref pos, expectedData);
|
string name = entry.Name?.Trim() ?? "";
|
||||||
|
expectedData.Write(ref pos, (byte)Math.Min(255, name.Length));
|
||||||
|
expectedData.WriteAscii(ref pos, name, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
|
|
@ -81,27 +93,43 @@ namespace Server.Tests.Network.Packets
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
string question = menu.Question?.Trim() ?? "";
|
|
||||||
int questionLength = Math.Min(255, question.Length);
|
|
||||||
|
|
||||||
int length = 11 + questionLength + menu.Answers.Sum(answer => 5 + answer?.Trim().Length ?? 0);
|
|
||||||
|
|
||||||
Span<byte> data = new DisplayQuestionMenu(menu).Compile();
|
Span<byte> data = new DisplayQuestionMenu(menu).Compile();
|
||||||
|
|
||||||
|
string question = menu.Question;
|
||||||
|
int questionLength = Math.Min(255, question.Length);
|
||||||
|
int answersCount = 0;
|
||||||
|
int length = 11 + questionLength;
|
||||||
|
|
||||||
|
foreach (var answer in menu.Answers)
|
||||||
|
{
|
||||||
|
length += 5 + answer.Length;
|
||||||
|
if (answersCount == 255)
|
||||||
|
break;
|
||||||
|
|
||||||
|
answersCount++;
|
||||||
|
}
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[length];
|
Span<byte> expectedData = stackalloc byte[length];
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0x7C).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0x7C); // Packet ID
|
||||||
((ushort)length).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)length);
|
||||||
menu.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, menu.Serial);
|
||||||
((ushort)0x00).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)0x00);
|
||||||
question.CopySmallASCIITo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)question.Length);
|
||||||
((byte)menu.Answers.Length).CopyTo(ref pos, expectedData);
|
expectedData.WriteAscii(ref pos, question, 255);
|
||||||
for (int i = 0; i < menu.Answers.Length; i++)
|
expectedData.Write(ref pos, (byte)answersCount);
|
||||||
|
for (int i = 0; i < answersCount; i++)
|
||||||
{
|
{
|
||||||
0x0.CopyTo(ref pos, expectedData);
|
var answer = menu.Answers[i];
|
||||||
(menu.Answers[i]?.Trim() ?? "").CopySmallASCIITo(ref pos, expectedData);
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
#else
|
||||||
|
pos += 4;
|
||||||
|
#endif
|
||||||
|
expectedData.Write(ref pos, (byte)Math.Min(255, answer.Length));
|
||||||
|
expectedData.WriteAscii(ref pos, answer, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
|
|
@ -123,20 +151,20 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> expectedData = stackalloc byte[length];
|
Span<byte> expectedData = stackalloc byte[length];
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
((byte)0xBF).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0xBF); // Packet ID
|
||||||
((ushort)length).CopyTo(ref pos, expectedData); // Length
|
expectedData.Write(ref pos, (ushort)length); // Length
|
||||||
((ushort)0x14).CopyTo(ref pos, expectedData); // Command
|
expectedData.Write(ref pos, (ushort)0x14); // Command
|
||||||
((ushort)0x02).CopyTo(ref pos, expectedData); // Subcommand
|
expectedData.Write(ref pos, (ushort)0x02); // Subcommand
|
||||||
menu.Target.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, menu.Target.Serial);
|
||||||
var entries = menu.Entries;
|
var entries = menu.Entries;
|
||||||
|
|
||||||
((byte)entries.Length).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)entries.Length);
|
||||||
|
|
||||||
for (int i = 0; i < entries.Length; i++)
|
for (int i = 0; i < entries.Length; i++)
|
||||||
{
|
{
|
||||||
var entry = entries[i];
|
var entry = entries[i];
|
||||||
entry.Number.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, entry.Number);
|
||||||
((ushort)i).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)i);
|
||||||
|
|
||||||
var flags = entry.Flags;
|
var flags = entry.Flags;
|
||||||
|
|
||||||
|
|
@ -148,7 +176,7 @@ namespace Server.Tests.Network.Packets
|
||||||
if (!(entry.Enabled && menu.From.InRange(item.GetWorldLocation(), range)))
|
if (!(entry.Enabled && menu.From.InRange(item.GetWorldLocation(), range)))
|
||||||
flags |= CMEFlags.Disabled;
|
flags |= CMEFlags.Disabled;
|
||||||
|
|
||||||
((ushort)flags).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
|
|
@ -170,20 +198,20 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> expectedData = stackalloc byte[length];
|
Span<byte> expectedData = stackalloc byte[length];
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
((byte)0xBF).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0xBF); // Packet ID
|
||||||
((ushort)length).CopyTo(ref pos, expectedData); // Length
|
expectedData.Write(ref pos, (ushort)length); // Length
|
||||||
((ushort)0x14).CopyTo(ref pos, expectedData); // Command
|
expectedData.Write(ref pos, (ushort)0x14); // Command
|
||||||
((ushort)0x01).CopyTo(ref pos, expectedData); // Subcommand
|
expectedData.Write(ref pos, (ushort)0x01); // Subcommand
|
||||||
menu.Target.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, menu.Target.Serial);
|
||||||
var entries = menu.Entries;
|
var entries = menu.Entries;
|
||||||
|
|
||||||
((byte)entries.Length).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)entries.Length);
|
||||||
|
|
||||||
for (int i = 0; i < entries.Length; i++)
|
for (int i = 0; i < entries.Length; i++)
|
||||||
{
|
{
|
||||||
var entry = entries[i];
|
var entry = entries[i];
|
||||||
((ushort)i).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)i);
|
||||||
((ushort)(entry.Number - 3000000)).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)(entry.Number - 3000000));
|
||||||
|
|
||||||
var flags = entry.Flags;
|
var flags = entry.Flags;
|
||||||
|
|
||||||
|
|
@ -200,10 +228,10 @@ namespace Server.Tests.Network.Packets
|
||||||
if (!(entry.Enabled && menu.From.InRange(item.GetWorldLocation(), range)))
|
if (!(entry.Enabled && menu.From.InRange(item.GetWorldLocation(), range)))
|
||||||
flags |= CMEFlags.Disabled;
|
flags |= CMEFlags.Disabled;
|
||||||
|
|
||||||
((ushort)flags).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)flags);
|
||||||
|
|
||||||
if ((flags & CMEFlags.Colored) != 0)
|
if ((flags & CMEFlags.Colored) != 0)
|
||||||
((ushort)color).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)color);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
|
|
||||||
|
|
@ -31,18 +32,20 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[50 + args.Length * 2];
|
Span<byte> expectedData = stackalloc byte[50 + args.Length * 2];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
((byte)0xC1).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0xC1); // Packet ID
|
||||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
expectedData.Write(ref pos, (ushort)expectedData.Length); // Length
|
||||||
|
|
||||||
serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, serial);
|
||||||
((ushort)graphic).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)graphic);
|
||||||
((byte)messageType).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)messageType);
|
||||||
((ushort)hue).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)hue);
|
||||||
((ushort)font).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)font);
|
||||||
number.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, number);
|
||||||
name.CopyASCIIFixedTo(ref pos, 30, expectedData);
|
expectedData.WriteAsciiFixed(ref pos, name, 30);
|
||||||
args.CopyRawUnicodeLittleEndianTo(ref pos, expectedData);
|
expectedData.WriteLittleUni(ref pos, args);
|
||||||
expectedData.Clear(ref pos, 2); // Terminator
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (ushort)0); // Terminator
|
||||||
|
#endif
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -76,21 +79,27 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[52 + affix.Length + args.Length * 2];
|
Span<byte> expectedData = stackalloc byte[52 + affix.Length + args.Length * 2];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
((byte)0xCC).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0xCC); // Packet ID
|
||||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
expectedData.Write(ref pos, (ushort)expectedData.Length); // Length
|
||||||
|
|
||||||
serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, serial);
|
||||||
((ushort)graphic).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)graphic);
|
||||||
((byte)messageType).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)messageType);
|
||||||
((ushort)hue).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)hue);
|
||||||
((ushort)font).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)font);
|
||||||
number.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, number);
|
||||||
((byte)affixType).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)affixType);
|
||||||
name.CopyASCIIFixedTo(ref pos, 30, expectedData);
|
expectedData.WriteAsciiFixed(ref pos, name, 30);
|
||||||
affix.CopyRawASCIITo(ref pos, expectedData);
|
expectedData.WriteAscii(ref pos, affix);
|
||||||
expectedData.Clear(ref pos, 2); // Terminator
|
#if NO_LOCAL_INIT
|
||||||
args.CopyRawUnicodeLittleEndianTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)0); // Terminator
|
||||||
expectedData.Clear(ref pos, 1); // Terminator
|
#else
|
||||||
|
pos += 2;
|
||||||
|
#endif
|
||||||
|
expectedData.WriteLittleUni(ref pos, args);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0); // Terminator
|
||||||
|
#endif
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -118,17 +127,19 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[45 + text.Length];
|
Span<byte> expectedData = stackalloc byte[45 + text.Length];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
((byte)0x1C).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0x1C); // Packet ID
|
||||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
expectedData.Write(ref pos, (ushort)expectedData.Length); // Length
|
||||||
|
|
||||||
serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, serial);
|
||||||
((ushort)graphic).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)graphic);
|
||||||
((byte)messageType).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)messageType);
|
||||||
((ushort)hue).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)hue);
|
||||||
((ushort)font).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)font);
|
||||||
name.CopyASCIIFixedTo(ref pos, 30, expectedData);
|
expectedData.WriteAsciiFixed(ref pos, name, 30);
|
||||||
text.CopyRawASCIITo(ref pos, expectedData);
|
expectedData.WriteAscii(ref pos, text);
|
||||||
expectedData.Clear(ref pos, 1); // Terminator
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0); // Terminator
|
||||||
|
#endif
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -158,18 +169,20 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[50 + text.Length * 2];
|
Span<byte> expectedData = stackalloc byte[50 + text.Length * 2];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
((byte)0xAE).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0xAE); // Packet ID
|
||||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
expectedData.Write(ref pos, (ushort)expectedData.Length); // Length
|
||||||
|
|
||||||
serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, serial);
|
||||||
((ushort)graphic).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)graphic);
|
||||||
((byte)messageType).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)messageType);
|
||||||
((ushort)hue).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)hue);
|
||||||
((ushort)font).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)font);
|
||||||
lang.CopyASCIIFixedTo(ref pos, 4, expectedData);
|
expectedData.WriteAsciiFixed(ref pos, lang, 4);
|
||||||
name.CopyASCIIFixedTo(ref pos, 30, expectedData);
|
expectedData.WriteAsciiFixed(ref pos, name, 30);
|
||||||
text.CopyRawUnicodeBigEndianTo(ref pos, expectedData);
|
expectedData.WriteBigUni(ref pos, text);
|
||||||
expectedData.Clear(ref pos, 2); // Terminator
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0); // Terminator
|
||||||
|
#endif
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -182,15 +195,12 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new FollowMessage(serial, serial2).Compile();
|
Span<byte> data = new FollowMessage(serial, serial2).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[9];
|
||||||
{
|
int pos = 0;
|
||||||
0x15, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Follower
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Followee
|
|
||||||
};
|
|
||||||
|
|
||||||
serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (byte)0x15); // Packet ID
|
||||||
serial2.CopyTo(expectedData.Slice(5, 4));
|
expectedData.Write(ref pos, serial);
|
||||||
|
expectedData.Write(ref pos, serial2);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -15,16 +16,15 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new DeathAnimation(killed, corpse).Compile();
|
Span<byte> data = new DeathAnimation(killed, corpse).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[13];
|
||||||
{
|
int pos = 0;
|
||||||
0xAF, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial of killed
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial of corpse
|
|
||||||
0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
killed.CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (byte)0xAF); // Packet ID
|
||||||
corpse.CopyTo(expectedData.Slice(5, 4));
|
expectedData.Write(ref pos, killed);
|
||||||
|
expectedData.Write(ref pos, corpse);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -37,17 +37,21 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new BondedStatus(petSerial, bonded).Compile();
|
Span<byte> data = new BondedStatus(petSerial, bonded).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[11];
|
||||||
{
|
int pos = 0;
|
||||||
0xBF, // Packet ID
|
|
||||||
0x00, 0x0B, // Length
|
|
||||||
0x00, 0x19, // Sub-packet
|
|
||||||
0x00, // Sub command
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
(byte)(bonded ? 0x1 : 0x0)
|
|
||||||
};
|
|
||||||
|
|
||||||
petSerial.CopyTo(expectedData.Slice(6, 4));
|
expectedData.Write(ref pos, (byte)0xBF); // Packet ID
|
||||||
|
expectedData.Write(ref pos, (ushort)0x0B); // Length
|
||||||
|
expectedData.Write(ref pos, (ushort)0x19); // Sub-packet
|
||||||
|
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0); // Command
|
||||||
|
#else
|
||||||
|
pos++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
expectedData.Write(ref pos, petSerial);
|
||||||
|
expectedData.Write(ref pos, bonded);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -62,29 +66,19 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new MobileMoving(m, noto).Compile();
|
Span<byte> data = new MobileMoving(m, noto).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[17];
|
||||||
{
|
int pos = 0;
|
||||||
0x77, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0x00, 0x00, // Body
|
|
||||||
0x00, 0x00, // X
|
|
||||||
0x00, 0x00, // Y
|
|
||||||
0x00, // Z
|
|
||||||
0x00, // Direction
|
|
||||||
0x00, 0x00, // Hue
|
|
||||||
0x00, // Flags
|
|
||||||
0x00 // Noto
|
|
||||||
};
|
|
||||||
|
|
||||||
m.Serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (byte)0x77); // Packet ID
|
||||||
((ushort)m.Body).CopyTo(expectedData.Slice(5, 2));
|
expectedData.Write(ref pos, m.Serial);
|
||||||
((ushort)m.X).CopyTo(expectedData.Slice(7, 2));
|
expectedData.Write(ref pos, (ushort)m.Body);
|
||||||
((ushort)m.Y).CopyTo(expectedData.Slice(9, 2));
|
expectedData.Write(ref pos, (ushort)m.X);
|
||||||
expectedData[11] = (byte)m.Z;
|
expectedData.Write(ref pos, (ushort)m.Y);
|
||||||
expectedData[12] = (byte)m.Direction;
|
expectedData.Write(ref pos, (byte)m.Z);
|
||||||
((ushort)m.Hue).CopyTo(expectedData.Slice(13, 2));
|
expectedData.Write(ref pos, (byte)m.Direction);
|
||||||
expectedData[15] = (byte)m.GetPacketFlags();
|
expectedData.Write(ref pos, (ushort)m.Hue);
|
||||||
expectedData[16] = (byte)noto;
|
expectedData.Write(ref pos, (byte)m.GetPacketFlags());
|
||||||
|
expectedData.Write(ref pos, (byte)noto);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -99,29 +93,19 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new MobileMoving(m, noto).Compile();
|
Span<byte> data = new MobileMoving(m, noto).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[17];
|
||||||
{
|
int pos = 0;
|
||||||
0x77, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0x00, 0x00, // Body
|
|
||||||
0x00, 0x00, // X
|
|
||||||
0x00, 0x00, // Y
|
|
||||||
0x00, // Z
|
|
||||||
0x00, // Direction
|
|
||||||
0x00, 0x00, // Hue
|
|
||||||
0x00, // Flags
|
|
||||||
0x00 // Noto
|
|
||||||
};
|
|
||||||
|
|
||||||
m.Serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (byte)0x77); // Packet ID
|
||||||
((ushort)m.Body).CopyTo(expectedData.Slice(5, 2));
|
expectedData.Write(ref pos, m.Serial);
|
||||||
((ushort)m.X).CopyTo(expectedData.Slice(7, 2));
|
expectedData.Write(ref pos, (ushort)m.Body);
|
||||||
((ushort)m.Y).CopyTo(expectedData.Slice(9, 2));
|
expectedData.Write(ref pos, (ushort)m.X);
|
||||||
expectedData[11] = (byte)m.Z;
|
expectedData.Write(ref pos, (ushort)m.Y);
|
||||||
expectedData[12] = (byte)m.Direction;
|
expectedData.Write(ref pos, (byte)m.Z);
|
||||||
((ushort)m.Hue).CopyTo(expectedData.Slice(13, 2));
|
expectedData.Write(ref pos, (byte)m.Direction);
|
||||||
expectedData[15] = (byte)m.GetOldPacketFlags();
|
expectedData.Write(ref pos, (ushort)m.Hue);
|
||||||
expectedData[16] = (byte)noto;
|
expectedData.Write(ref pos, (byte)m.GetOldPacketFlags());
|
||||||
|
expectedData.Write(ref pos, (byte)noto);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -134,16 +118,12 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new MobileHits(m).Compile();
|
Span<byte> data = new MobileHits(m).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[9];
|
||||||
{
|
int pos = 0;
|
||||||
0xA1, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0x00, 0x00, // Max Hits
|
|
||||||
0x00, 0x00 // Current Hits
|
|
||||||
};
|
|
||||||
|
|
||||||
m.Serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (byte)0xA1); // Packet ID
|
||||||
AttributeNormalizerUtilities.Write(m.Hits, m.HitsMax, false, expectedData.Slice(5));
|
expectedData.Write(ref pos, m.Serial);
|
||||||
|
expectedData.WriteAttribute(ref pos, m.Hits, m.HitsMax, false);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -156,18 +136,12 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new MobileHitsN(m).Compile();
|
Span<byte> data = new MobileHitsN(m).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[9];
|
||||||
{
|
int pos = 0;
|
||||||
0xA1, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0x00, 0x00, // Max Hits
|
|
||||||
0x00, 0x00 // Current Hits
|
|
||||||
};
|
|
||||||
|
|
||||||
int max = AttributeNormalizer.Maximum;
|
expectedData.Write(ref pos, (byte)0xA1); // Packet ID
|
||||||
|
expectedData.Write(ref pos, m.Serial);
|
||||||
m.Serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.WriteAttribute(ref pos, m.Hits, m.HitsMax, true);
|
||||||
AttributeNormalizerUtilities.Write(m.Hits, m.HitsMax, true, expectedData.Slice(5));
|
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -180,16 +154,12 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new MobileMana(m).Compile();
|
Span<byte> data = new MobileMana(m).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[9];
|
||||||
{
|
int pos = 0;
|
||||||
0xA2, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0x00, 0x00, // Max Hits
|
|
||||||
0x00, 0x00 // Current Hits
|
|
||||||
};
|
|
||||||
|
|
||||||
m.Serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (byte)0xA2); // Packet ID
|
||||||
AttributeNormalizerUtilities.Write(m.Mana, m.ManaMax, false, expectedData.Slice(5));
|
expectedData.Write(ref pos, m.Serial);
|
||||||
|
expectedData.WriteAttribute(ref pos, m.Mana, m.ManaMax, false);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -202,18 +172,12 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new MobileManaN(m).Compile();
|
Span<byte> data = new MobileManaN(m).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[9];
|
||||||
{
|
int pos = 0;
|
||||||
0xA2, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0x00, 0x00, // Max Hits
|
|
||||||
0x00, 0x00 // Current Hits
|
|
||||||
};
|
|
||||||
|
|
||||||
int max = AttributeNormalizer.Maximum;
|
expectedData.Write(ref pos, (byte)0xA2); // Packet ID
|
||||||
|
expectedData.Write(ref pos, m.Serial);
|
||||||
m.Serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.WriteAttribute(ref pos, m.Mana, m.ManaMax, true);
|
||||||
AttributeNormalizerUtilities.Write(m.Mana, m.ManaMax, true, expectedData.Slice(5));
|
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -226,16 +190,12 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new MobileStam(m).Compile();
|
Span<byte> data = new MobileStam(m).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[9];
|
||||||
{
|
int pos = 0;
|
||||||
0xA3, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0x00, 0x00, // Max Hits
|
|
||||||
0x00, 0x00 // Current Hits
|
|
||||||
};
|
|
||||||
|
|
||||||
m.Serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (byte)0xA3); // Packet ID
|
||||||
AttributeNormalizerUtilities.Write(m.Stam, m.StamMax, false, expectedData.Slice(5));
|
expectedData.Write(ref pos, m.Serial);
|
||||||
|
expectedData.WriteAttribute(ref pos, m.Stam, m.StamMax, false);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -248,18 +208,12 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new MobileStamN(m).Compile();
|
Span<byte> data = new MobileStamN(m).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[9];
|
||||||
{
|
int pos = 0;
|
||||||
0xA3, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0x00, 0x00, // Max Hits
|
|
||||||
0x00, 0x00 // Current Hits
|
|
||||||
};
|
|
||||||
|
|
||||||
int max = AttributeNormalizer.Maximum;
|
expectedData.Write(ref pos, (byte)0xA3); // Packet ID
|
||||||
|
expectedData.Write(ref pos, m.Serial);
|
||||||
m.Serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.WriteAttribute(ref pos, m.Stam, m.StamMax, true);
|
||||||
AttributeNormalizerUtilities.Write(m.Stam, m.StamMax, true, expectedData.Slice(5));
|
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -272,22 +226,14 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new MobileAttributes(m).Compile();
|
Span<byte> data = new MobileAttributes(m).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[17];
|
||||||
{
|
int pos = 0;
|
||||||
0x2D, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0x00, 0x00, // Max Hits
|
|
||||||
0x00, 0x00, // Current Hits
|
|
||||||
0x00, 0x00, // Max Mana
|
|
||||||
0x00, 0x00, // Current Mana
|
|
||||||
0x00, 0x00, // Max Stam
|
|
||||||
0x00, 0x00 // Current Stam
|
|
||||||
};
|
|
||||||
|
|
||||||
m.Serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (byte)0x2D); // Packet ID
|
||||||
AttributeNormalizerUtilities.Write(m.Hits, m.HitsMax, false, expectedData.Slice(5));
|
expectedData.Write(ref pos, m.Serial);
|
||||||
AttributeNormalizerUtilities.Write(m.Mana, m.ManaMax, false, expectedData.Slice(9));
|
expectedData.WriteAttribute(ref pos, m.Hits, m.HitsMax, false);
|
||||||
AttributeNormalizerUtilities.Write(m.Stam, m.StamMax, false, expectedData.Slice(13));
|
expectedData.WriteAttribute(ref pos, m.Mana, m.ManaMax, false);
|
||||||
|
expectedData.WriteAttribute(ref pos, m.Stam, m.StamMax, false);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -300,24 +246,14 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new MobileAttributesN(m).Compile();
|
Span<byte> data = new MobileAttributesN(m).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[17];
|
||||||
{
|
int pos = 0;
|
||||||
0x2D, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0x00, 0x00, // Max Hits
|
|
||||||
0x00, 0x00, // Current Hits
|
|
||||||
0x00, 0x00, // Max Mana
|
|
||||||
0x00, 0x00, // Current Mana
|
|
||||||
0x00, 0x00, // Max Stam
|
|
||||||
0x00, 0x00 // Current Stam
|
|
||||||
};
|
|
||||||
|
|
||||||
int max = AttributeNormalizer.Maximum;
|
expectedData.Write(ref pos, (byte)0x2D); // Packet ID
|
||||||
|
expectedData.Write(ref pos, m.Serial);
|
||||||
m.Serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.WriteAttribute(ref pos, m.Hits, m.HitsMax, true);
|
||||||
AttributeNormalizerUtilities.Write(m.Hits, m.HitsMax, true, expectedData.Slice(5));
|
expectedData.WriteAttribute(ref pos, m.Mana, m.ManaMax, true);
|
||||||
AttributeNormalizerUtilities.Write(m.Mana, m.ManaMax, true, expectedData.Slice(9));
|
expectedData.WriteAttribute(ref pos, m.Stam, m.StamMax, true);
|
||||||
AttributeNormalizerUtilities.Write(m.Stam, m.StamMax, true, expectedData.Slice(13));
|
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -335,11 +271,13 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[37];
|
Span<byte> expectedData = stackalloc byte[37];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
((byte)0x98).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)0x98);
|
||||||
((ushort)0x25).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)0x25);
|
||||||
m.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, m.Serial);
|
||||||
(m.Name ?? "").CopyRawASCIITo(ref pos, 29, expectedData);
|
expectedData.WriteAsciiFixed(ref pos, m.Name ?? "", 29);
|
||||||
((byte)0x0).CopyTo(ref pos, expectedData); // Null terminator
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0);
|
||||||
|
#endif
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -368,14 +306,14 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> expectedData = stackalloc byte[14];
|
Span<byte> expectedData = stackalloc byte[14];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0x6E).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)0x6E);
|
||||||
mobile.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, mobile);
|
||||||
((ushort)action).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)action);
|
||||||
((ushort)frameCount).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)frameCount);
|
||||||
((ushort)repeatCount).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)repeatCount);
|
||||||
reverse.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, reverse);
|
||||||
repeat.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, repeat);
|
||||||
delay.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, delay);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -398,11 +336,11 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> expectedData = stackalloc byte[10];
|
Span<byte> expectedData = stackalloc byte[10];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0xE2).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)0xE2);
|
||||||
mobile.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, mobile);
|
||||||
((ushort)action).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)action);
|
||||||
((ushort)frameCount).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)frameCount);
|
||||||
delay.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, delay);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -420,21 +358,27 @@ namespace Server.Tests.Network.Packets
|
||||||
Span<byte> expectedData = stackalloc byte[43];
|
Span<byte> expectedData = stackalloc byte[43];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0x11).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0x11); // Packet ID
|
||||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
expectedData.Write(ref pos, (ushort)expectedData.Length); // Length
|
||||||
|
|
||||||
m.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, m.Serial);
|
||||||
(m.Name ?? "").CopyASCIIFixedTo(ref pos, 30, expectedData);
|
expectedData.WriteAsciiFixed(ref pos, m.Name ?? "", 30);
|
||||||
|
|
||||||
AttributeNormalizerUtilities.WriteReverse(m.Hits, m.HitsMax, true, expectedData.Slice(pos));
|
expectedData.WriteReverseAttribute(ref pos, m.Hits, m.HitsMax, true);
|
||||||
pos += 4;
|
expectedData.Write(ref pos, canBeRenamed);
|
||||||
canBeRenamed.CopyTo(ref pos, expectedData);
|
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0); // type
|
||||||
|
#endif
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public void TestMobileStatusExtended()
|
[InlineData(ProtocolChanges.Version70610)]
|
||||||
|
[InlineData(ProtocolChanges.Version400a)]
|
||||||
|
[InlineData(ProtocolChanges.Version502b)]
|
||||||
|
public void TestMobileStatusExtended(ProtocolChanges changes)
|
||||||
{
|
{
|
||||||
var beholder = new Mobile(0x1)
|
var beholder = new Mobile(0x1)
|
||||||
{
|
{
|
||||||
|
|
@ -451,14 +395,17 @@ namespace Server.Tests.Network.Packets
|
||||||
NetState ns = new NetState(new AccountPacketTests.TestConnectionContext
|
NetState ns = new NetState(new AccountPacketTests.TestConnectionContext
|
||||||
{
|
{
|
||||||
RemoteEndPoint = IPEndPoint.Parse("127.0.0.1")
|
RemoteEndPoint = IPEndPoint.Parse("127.0.0.1")
|
||||||
});
|
})
|
||||||
|
{
|
||||||
|
ProtocolChanges = changes
|
||||||
|
};
|
||||||
|
|
||||||
Span<byte> data = new MobileStatus(beholder, beheld, ns).Compile();
|
Span<byte> data = new MobileStatus(beholder, beheld, ns).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[121]; // Max Size
|
Span<byte> expectedData = stackalloc byte[121]; // Max Size
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0x11).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)0x11);
|
||||||
pos += 2; // Length
|
pos += 2; // Length
|
||||||
|
|
||||||
int type;
|
int type;
|
||||||
|
|
@ -469,69 +416,460 @@ namespace Server.Tests.Network.Packets
|
||||||
else if (Core.ML && ns.SupportsExpansion(Expansion.ML)) type = 5;
|
else if (Core.ML && ns.SupportsExpansion(Expansion.ML)) type = 5;
|
||||||
else type = Core.AOS ? 4 : 3;
|
else type = Core.AOS ? 4 : 3;
|
||||||
|
|
||||||
beheld.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, beheld.Serial);
|
||||||
beheld.Name.CopyASCIIFixedTo(ref pos, 30, expectedData);
|
expectedData.WriteAsciiFixed(ref pos, beheld.Name, 30);
|
||||||
|
|
||||||
AttributeNormalizerUtilities.WriteReverse(beheld.Hits, beheld.HitsMax, notSelf, expectedData.Slice(pos));
|
expectedData.WriteReverseAttribute(ref pos, beheld.Hits, beheld.HitsMax, notSelf);
|
||||||
pos += 4;
|
|
||||||
|
|
||||||
beheld.CanBeRenamedBy(beheld).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, beheld.CanBeRenamedBy(beheld));
|
||||||
((byte)type).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)type);
|
||||||
|
|
||||||
if (type > 0)
|
if (type > 0)
|
||||||
{
|
{
|
||||||
beheld.Female.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, beheld.Female);
|
||||||
((ushort)beheld.Str).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)beheld.Str);
|
||||||
((ushort)beheld.Dex).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)beheld.Dex);
|
||||||
((ushort)beheld.Int).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)beheld.Int);
|
||||||
|
|
||||||
AttributeNormalizerUtilities.WriteReverse(beheld.Stam, beheld.StamMax, notSelf, expectedData.Slice(pos));
|
expectedData.WriteReverseAttribute(ref pos, beheld.Stam, beheld.StamMax, notSelf);
|
||||||
pos += 4;
|
expectedData.WriteReverseAttribute(ref pos, beheld.Mana, beheld.ManaMax, notSelf);
|
||||||
|
|
||||||
AttributeNormalizerUtilities.WriteReverse(beheld.Mana, beheld.ManaMax, notSelf, expectedData.Slice(pos));
|
expectedData.Write(ref pos, beheld.TotalGold);
|
||||||
pos += 4;
|
expectedData.Write(ref pos, (ushort)(Core.AOS ? beheld.PhysicalResistance : (int)(beheld.ArmorRating + 0.5)));
|
||||||
|
expectedData.Write(ref pos, (ushort)(Mobile.BodyWeight + beheld.TotalWeight));
|
||||||
beheld.TotalGold.CopyTo(ref pos, expectedData);
|
|
||||||
((ushort)(Core.AOS ? beheld.PhysicalResistance : (int)(beheld.ArmorRating + 0.5))).CopyTo(ref pos, expectedData);
|
|
||||||
((ushort)(Mobile.BodyWeight + beheld.TotalWeight)).CopyTo(ref pos, expectedData);
|
|
||||||
|
|
||||||
if (type >= 5)
|
if (type >= 5)
|
||||||
{
|
{
|
||||||
((ushort)beheld.MaxWeight).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)beheld.MaxWeight);
|
||||||
((byte)(beheld.Race.RaceID + 1)).CopyTo(ref pos, expectedData); // 0x00 for a non-ML enabled account
|
expectedData.Write(ref pos, (byte)(beheld.Race.RaceID + 1)); // 0x00 for a non-ML enabled account
|
||||||
}
|
}
|
||||||
|
|
||||||
((ushort)beheld.StatCap).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)beheld.StatCap);
|
||||||
((byte)beheld.Followers).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)beheld.Followers);
|
||||||
((byte)beheld.FollowersMax).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)beheld.FollowersMax);
|
||||||
|
|
||||||
if (type >= 4)
|
if (type >= 4)
|
||||||
{
|
{
|
||||||
((ushort)beheld.FireResistance).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)beheld.FireResistance);
|
||||||
((ushort)beheld.ColdResistance).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)beheld.ColdResistance);
|
||||||
((ushort)beheld.PoisonResistance).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)beheld.PoisonResistance);
|
||||||
((ushort)beheld.EnergyResistance).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)beheld.EnergyResistance);
|
||||||
((ushort)beheld.Luck).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)beheld.Luck);
|
||||||
}
|
}
|
||||||
|
|
||||||
int min = 0;
|
int min = 0;
|
||||||
int max = 0;
|
int max = 0;
|
||||||
beheld.Weapon?.GetStatusDamage(beheld, out min, out max);
|
beheld.Weapon?.GetStatusDamage(beheld, out min, out max);
|
||||||
|
|
||||||
((ushort)min).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)min);
|
||||||
((ushort)max).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)max);
|
||||||
|
|
||||||
beheld.TithingPoints.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, beheld.TithingPoints);
|
||||||
|
|
||||||
if (type >= 6)
|
if (type >= 6)
|
||||||
for (var i = 0; i < 15; ++i)
|
for (var i = 0; i < 15; ++i)
|
||||||
((ushort)beheld.GetAOSStatus(i)).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)beheld.GetAOSStatus(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
((ushort)pos).CopyTo(expectedData.Slice(1)); // Length
|
expectedData.Slice(1, 2).Write((ushort)pos); // Length
|
||||||
|
|
||||||
expectedData = expectedData.Slice(0, pos);
|
expectedData = expectedData.Slice(0, pos);
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("None", 0)]
|
||||||
|
[InlineData("Lesser", 1)]
|
||||||
|
[InlineData("Lethal", 5)]
|
||||||
|
public void TestHealthbarPoison(string pName, int level)
|
||||||
|
{
|
||||||
|
var p = Poison.GetPoison(pName);
|
||||||
|
Mobile m = new Mobile(0x1);
|
||||||
|
m.DefaultMobileInit();
|
||||||
|
m.Poison = p;
|
||||||
|
|
||||||
|
Span<byte> data = new HealthbarPoison(m).Compile();
|
||||||
|
|
||||||
|
Span<byte> expectedData = stackalloc byte[12];
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
expectedData.Write(ref pos, (byte)0x17); // Packet ID
|
||||||
|
expectedData.Write(ref pos, (ushort)12); // Length
|
||||||
|
expectedData.Write(ref pos, m.Serial);
|
||||||
|
expectedData.Write(ref pos, 0x10001); // Show Bar?, Poison Bar
|
||||||
|
expectedData.Write(ref pos, (byte)((p?.Level ?? -1) + 1));
|
||||||
|
|
||||||
|
AssertThat.Equal(data, expectedData);
|
||||||
|
Assert.Equal(p?.Level, m.Poison?.Level);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(false, false)]
|
||||||
|
[InlineData(true, false)]
|
||||||
|
[InlineData(false, true)]
|
||||||
|
[InlineData(true, true)]
|
||||||
|
public void TestYellowBar(bool isBlessed, bool isYellowHealth)
|
||||||
|
{
|
||||||
|
Mobile m = new Mobile(0x1);
|
||||||
|
m.DefaultMobileInit();
|
||||||
|
m.Blessed = isBlessed;
|
||||||
|
m.YellowHealthbar = isYellowHealth;
|
||||||
|
|
||||||
|
Span<byte> data = new HealthbarYellow(m).Compile();
|
||||||
|
|
||||||
|
Span<byte> expectedData = stackalloc byte[12];
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
expectedData.Write(ref pos, (byte)0x17); // Packet ID
|
||||||
|
expectedData.Write(ref pos, (ushort)12); // Length
|
||||||
|
expectedData.Write(ref pos, m.Serial);
|
||||||
|
expectedData.Write(ref pos, 0x10002); // Show Bar?, Yellow Bar
|
||||||
|
expectedData.Write(ref pos, isBlessed || isYellowHealth);
|
||||||
|
|
||||||
|
AssertThat.Equal(data, expectedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestMobileUpdate()
|
||||||
|
{
|
||||||
|
Mobile m = new Mobile(0x1);
|
||||||
|
m.DefaultMobileInit();
|
||||||
|
|
||||||
|
Span<byte> data = new MobileUpdate(m).Compile();
|
||||||
|
|
||||||
|
Span<byte> expectedData = stackalloc byte[19];
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
var hue = m.SolidHueOverride >= 0 ? m.SolidHueOverride : m.Hue;
|
||||||
|
|
||||||
|
expectedData.Write(ref pos, (byte)0x20); // Packet ID
|
||||||
|
expectedData.Write(ref pos, m.Serial);
|
||||||
|
expectedData.Write(ref pos, (ushort)m.Body);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0); // Unknown
|
||||||
|
#else
|
||||||
|
pos++;
|
||||||
|
#endif
|
||||||
|
expectedData.Write(ref pos, (ushort)hue);
|
||||||
|
expectedData.Write(ref pos, (byte)m.GetPacketFlags());
|
||||||
|
expectedData.Write(ref pos, (ushort)m.X);
|
||||||
|
expectedData.Write(ref pos, (ushort)m.Y);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (ushort)2); // Unknown
|
||||||
|
#else
|
||||||
|
pos += 2;
|
||||||
|
#endif
|
||||||
|
expectedData.Write(ref pos, (byte)m.Direction);
|
||||||
|
expectedData.Write(ref pos, (byte)m.Z);
|
||||||
|
|
||||||
|
AssertThat.Equal(data, expectedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestMobileUpdateOld()
|
||||||
|
{
|
||||||
|
Mobile m = new Mobile(0x1);
|
||||||
|
m.DefaultMobileInit();
|
||||||
|
|
||||||
|
Span<byte> data = new MobileUpdateOld(m).Compile();
|
||||||
|
|
||||||
|
Span<byte> expectedData = stackalloc byte[19];
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
var hue = m.SolidHueOverride >= 0 ? m.SolidHueOverride : m.Hue;
|
||||||
|
|
||||||
|
expectedData.Write(ref pos, (byte)0x20); // Packet ID
|
||||||
|
expectedData.Write(ref pos, m.Serial);
|
||||||
|
expectedData.Write(ref pos, (ushort)m.Body);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0); // Unknown
|
||||||
|
#else
|
||||||
|
pos++;
|
||||||
|
#endif
|
||||||
|
expectedData.Write(ref pos, (ushort)hue);
|
||||||
|
expectedData.Write(ref pos, (byte)m.GetOldPacketFlags());
|
||||||
|
expectedData.Write(ref pos, (ushort)m.X);
|
||||||
|
expectedData.Write(ref pos, (ushort)m.Y);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (ushort)2); // Unknown
|
||||||
|
#else
|
||||||
|
pos += 2;
|
||||||
|
#endif
|
||||||
|
expectedData.Write(ref pos, (byte)m.Direction);
|
||||||
|
expectedData.Write(ref pos, (byte)m.Z);
|
||||||
|
|
||||||
|
AssertThat.Equal(data, expectedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(0, 0, 0, 0)]
|
||||||
|
[InlineData(10, 1024, 0, 0)]
|
||||||
|
[InlineData(10, 1024, 11, 2048)]
|
||||||
|
public void TestMobileIncoming(int hairItemId, int hairHue, int facialHairItemId, int facialHairHue)
|
||||||
|
{
|
||||||
|
var beholder = new Mobile(0x1)
|
||||||
|
{
|
||||||
|
Name = "Random Mobile 1"
|
||||||
|
};
|
||||||
|
beholder.DefaultMobileInit();
|
||||||
|
|
||||||
|
var beheld = new Mobile(0x2)
|
||||||
|
{
|
||||||
|
Name = "Random Mobile 2"
|
||||||
|
};
|
||||||
|
beheld.DefaultMobileInit();
|
||||||
|
beheld.AddItem(new Item((Serial)0x1000)
|
||||||
|
{
|
||||||
|
Layer = Layer.OneHanded
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test Dupe
|
||||||
|
beheld.AddItem(new Item((Serial)0x1001)
|
||||||
|
{
|
||||||
|
Layer = Layer.OneHanded
|
||||||
|
});
|
||||||
|
|
||||||
|
beheld.HairItemID = hairItemId;
|
||||||
|
beheld.HairHue = hairHue;
|
||||||
|
beheld.FacialHairItemID = facialHairItemId;
|
||||||
|
beheld.FacialHairHue = facialHairHue;
|
||||||
|
|
||||||
|
Span<byte> data = new MobileIncoming(beholder, beheld).Compile();
|
||||||
|
|
||||||
|
Span<bool> layers = stackalloc bool[256];
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
layers.Clear();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
var items = beheld.Items;
|
||||||
|
int count = items.Count;
|
||||||
|
|
||||||
|
if (beheld.HairItemID > 0)
|
||||||
|
count++;
|
||||||
|
if (beheld.FacialHairItemID > 0)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
int length = 23 + count * 9; // Max Size
|
||||||
|
|
||||||
|
Span<byte> expectedData = stackalloc byte[length];
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
expectedData.Write(ref pos, (byte)0x78);
|
||||||
|
pos += 2; // Length
|
||||||
|
|
||||||
|
var isSolidHue = beheld.SolidHueOverride >= 0;
|
||||||
|
|
||||||
|
expectedData.Write(ref pos, beheld.Serial);
|
||||||
|
expectedData.Write(ref pos, (ushort)beheld.Body);
|
||||||
|
expectedData.Write(ref pos, (ushort)beheld.X);
|
||||||
|
expectedData.Write(ref pos, (ushort)beheld.Y);
|
||||||
|
expectedData.Write(ref pos, (byte)beheld.Z);
|
||||||
|
expectedData.Write(ref pos, (byte)beheld.Direction);
|
||||||
|
expectedData.Write(ref pos, (ushort)(isSolidHue ? beheld.SolidHueOverride : beheld.Hue));
|
||||||
|
expectedData.Write(ref pos, (byte)beheld.GetPacketFlags());
|
||||||
|
expectedData.Write(ref pos, (byte)Notoriety.Compute(beholder, beheld));
|
||||||
|
|
||||||
|
byte layer;
|
||||||
|
|
||||||
|
for (int i = 0; i < items.Count; i++)
|
||||||
|
{
|
||||||
|
var item = items[i];
|
||||||
|
|
||||||
|
layer = (byte)item.Layer;
|
||||||
|
|
||||||
|
if (!item.Deleted && !layers[layer] && beholder.CanSee(item))
|
||||||
|
{
|
||||||
|
layers[layer] = true;
|
||||||
|
|
||||||
|
expectedData.Write(ref pos, item.Serial);
|
||||||
|
expectedData.Write(ref pos, (ushort)(item.ItemID & 0xFFFF));
|
||||||
|
expectedData.Write(ref pos, layer);
|
||||||
|
expectedData.Write(ref pos, (ushort)(isSolidHue ? beheld.SolidHueOverride : item.Hue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
layer = (byte)Layer.Hair;
|
||||||
|
var itemId = beheld.HairItemID & 0xFFFF;
|
||||||
|
|
||||||
|
if (itemId > 0 && !layers[layer])
|
||||||
|
{
|
||||||
|
expectedData.Write(ref pos, HairInfo.FakeSerial(beheld));
|
||||||
|
expectedData.Write(ref pos, (ushort)itemId);
|
||||||
|
expectedData.Write(ref pos, layer);
|
||||||
|
expectedData.Write(ref pos, (ushort)(isSolidHue ? beheld.SolidHueOverride : beheld.HairHue));
|
||||||
|
}
|
||||||
|
|
||||||
|
layer = (byte)Layer.FacialHair;
|
||||||
|
itemId = beheld.FacialHairItemID & 0xFFFF;
|
||||||
|
|
||||||
|
if (itemId > 0 && !layers[layer])
|
||||||
|
{
|
||||||
|
expectedData.Write(ref pos, FacialHairInfo.FakeSerial(beheld));
|
||||||
|
expectedData.Write(ref pos, (ushort)itemId);
|
||||||
|
expectedData.Write(ref pos, layer);
|
||||||
|
expectedData.Write(ref pos, (ushort)(isSolidHue ? beheld.SolidHueOverride : beheld.FacialHairHue));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, 0); // Zero serial, terminate list
|
||||||
|
#else
|
||||||
|
pos += 4;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
expectedData.Slice(1, 2).Write((ushort)pos); // Length
|
||||||
|
expectedData = expectedData.Slice(0, pos);
|
||||||
|
|
||||||
|
AssertThat.Equal(data, expectedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(ProtocolChanges.Version6000, 0, 0, 0, 0)]
|
||||||
|
[InlineData(ProtocolChanges.Version6000, 10, 1024, 0, 0)]
|
||||||
|
[InlineData(ProtocolChanges.Version6000, 10, 1024, 11, 2048)]
|
||||||
|
[InlineData(ProtocolChanges.Version7000, 0, 0, 0, 0)]
|
||||||
|
[InlineData(ProtocolChanges.Version7000, 10, 1024, 0, 0)]
|
||||||
|
[InlineData(ProtocolChanges.Version7000, 10, 1024, 11, 2048)]
|
||||||
|
public void TestMobileIncomingOld(ProtocolChanges protocolChanges, int hairItemId, int hairHue, int facialHairItemId, int facialHairHue)
|
||||||
|
{
|
||||||
|
var beholder = new Mobile(0x1)
|
||||||
|
{
|
||||||
|
Name = "Random Mobile 1"
|
||||||
|
};
|
||||||
|
beholder.DefaultMobileInit();
|
||||||
|
|
||||||
|
var beheld = new Mobile(0x2)
|
||||||
|
{
|
||||||
|
Name = "Random Mobile 2"
|
||||||
|
};
|
||||||
|
beheld.DefaultMobileInit();
|
||||||
|
beheld.AddItem(new Item((Serial)0x1000)
|
||||||
|
{
|
||||||
|
Layer = Layer.OneHanded
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test Dupe
|
||||||
|
beheld.AddItem(new Item((Serial)0x1001)
|
||||||
|
{
|
||||||
|
Layer = Layer.OneHanded
|
||||||
|
});
|
||||||
|
|
||||||
|
beheld.HairItemID = hairItemId;
|
||||||
|
beheld.HairHue = hairHue;
|
||||||
|
beheld.FacialHairItemID = facialHairItemId;
|
||||||
|
beheld.FacialHairHue = facialHairHue;
|
||||||
|
|
||||||
|
NetState ns = new NetState(new AccountPacketTests.TestConnectionContext
|
||||||
|
{
|
||||||
|
RemoteEndPoint = IPEndPoint.Parse("127.0.0.1")
|
||||||
|
})
|
||||||
|
{
|
||||||
|
ProtocolChanges = protocolChanges
|
||||||
|
};
|
||||||
|
|
||||||
|
Span<byte> data = (ns.StygianAbyss ? (Packet)new MobileIncomingSA(beholder, beheld) : new MobileIncomingOld(beholder, beheld))
|
||||||
|
.Compile();
|
||||||
|
|
||||||
|
Span<bool> layers = stackalloc bool[256];
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
layers.Clear();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
var items = beheld.Items;
|
||||||
|
int count = items.Count;
|
||||||
|
|
||||||
|
if (beheld.HairItemID > 0)
|
||||||
|
count++;
|
||||||
|
if (beheld.FacialHairItemID > 0)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
int length = 23 + count * 9; // Max Size
|
||||||
|
|
||||||
|
Span<byte> expectedData = stackalloc byte[length];
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
expectedData.Write(ref pos, (byte)0x78);
|
||||||
|
pos += 2; // Length
|
||||||
|
|
||||||
|
var isSolidHue = beheld.SolidHueOverride >= 0;
|
||||||
|
|
||||||
|
expectedData.Write(ref pos, beheld.Serial);
|
||||||
|
expectedData.Write(ref pos, (ushort)beheld.Body);
|
||||||
|
expectedData.Write(ref pos, (ushort)beheld.X);
|
||||||
|
expectedData.Write(ref pos, (ushort)beheld.Y);
|
||||||
|
expectedData.Write(ref pos, (byte)beheld.Z);
|
||||||
|
expectedData.Write(ref pos, (byte)beheld.Direction);
|
||||||
|
expectedData.Write(ref pos, (ushort)(isSolidHue ? beheld.SolidHueOverride : beheld.Hue));
|
||||||
|
expectedData.Write(ref pos, (byte)(ns.StygianAbyss ? beheld.GetOldPacketFlags() : beheld.GetPacketFlags()));
|
||||||
|
expectedData.Write(ref pos, (byte)Notoriety.Compute(beholder, beheld));
|
||||||
|
|
||||||
|
byte layer;
|
||||||
|
int itemId;
|
||||||
|
int hue;
|
||||||
|
|
||||||
|
for (int i = 0; i < items.Count; i++)
|
||||||
|
{
|
||||||
|
var item = items[i];
|
||||||
|
|
||||||
|
layer = (byte)item.Layer;
|
||||||
|
|
||||||
|
if (!item.Deleted && !layers[layer] && beholder.CanSee(item))
|
||||||
|
{
|
||||||
|
layers[layer] = true;
|
||||||
|
itemId = item.ItemID & 0x7FFF;
|
||||||
|
hue = isSolidHue ? beheld.SolidHueOverride : item.Hue;
|
||||||
|
|
||||||
|
if (hue != 0)
|
||||||
|
itemId |= 0x8000;
|
||||||
|
|
||||||
|
expectedData.Write(ref pos, item.Serial);
|
||||||
|
expectedData.Write(ref pos, (ushort)itemId);
|
||||||
|
expectedData.Write(ref pos, layer);
|
||||||
|
expectedData.Write(ref pos, (ushort)hue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
layer = (byte)Layer.Hair;
|
||||||
|
itemId = beheld.HairItemID & 0x7FFF;
|
||||||
|
|
||||||
|
if (itemId > 0 && !layers[layer])
|
||||||
|
{
|
||||||
|
hue = isSolidHue ? beheld.SolidHueOverride : beheld.HairHue;
|
||||||
|
|
||||||
|
if (hue != 0)
|
||||||
|
itemId |= 0x8000;
|
||||||
|
|
||||||
|
expectedData.Write(ref pos, HairInfo.FakeSerial(beheld));
|
||||||
|
expectedData.Write(ref pos, (ushort)itemId);
|
||||||
|
expectedData.Write(ref pos, layer);
|
||||||
|
expectedData.Write(ref pos, (ushort)hue);
|
||||||
|
}
|
||||||
|
|
||||||
|
layer = (byte)Layer.FacialHair;
|
||||||
|
itemId = beheld.FacialHairItemID & 0x7FFF;
|
||||||
|
|
||||||
|
if (itemId > 0 && !layers[layer])
|
||||||
|
{
|
||||||
|
hue = isSolidHue ? beheld.SolidHueOverride : beheld.FacialHairHue;
|
||||||
|
|
||||||
|
if (hue != 0)
|
||||||
|
itemId |= 0x8000;
|
||||||
|
|
||||||
|
expectedData.Write(ref pos, FacialHairInfo.FakeSerial(beheld));
|
||||||
|
expectedData.Write(ref pos, (ushort)itemId);
|
||||||
|
expectedData.Write(ref pos, layer);
|
||||||
|
expectedData.Write(ref pos, (ushort)hue);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, 0); // Zero serial, terminate list
|
||||||
|
#else
|
||||||
|
pos += 4;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
expectedData.Slice(1, 2).Write((ushort)pos); // Length
|
||||||
|
expectedData = expectedData.Slice(0, pos);
|
||||||
|
|
||||||
|
AssertThat.Equal(data, expectedData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -20,26 +21,20 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new DisplaySecureTrade(m, firstCont, secondCont, name).Compile();
|
Span<byte> data = new DisplaySecureTrade(m, firstCont, secondCont, name).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
bool hasName = name.Length > 0;
|
||||||
{
|
|
||||||
0x6F, // Packet ID
|
|
||||||
0x00, 0x2F, // Length
|
|
||||||
(byte)TradeFlag.Display, // Command
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Mobile Serial
|
|
||||||
0x00, 0x00, 0x00, 0x00, // First Container Serial
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Second Container Serial
|
|
||||||
0x01, // true if has name
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Name
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
};
|
|
||||||
|
|
||||||
int pos = 4;
|
Span<byte> expectedData = stackalloc byte[17 + (hasName ? 30 : 0)];
|
||||||
m.Serial.CopyTo(ref pos, expectedData);
|
int pos = 0;
|
||||||
firstCont.Serial.CopyTo(ref pos, expectedData);
|
|
||||||
secondCont.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)0x6F); // Packet ID
|
||||||
pos++;
|
expectedData.Write(ref pos, (ushort)0x2F); // Length
|
||||||
name.CopyASCIIFixedTo(ref pos, 30, expectedData);
|
expectedData.Write(ref pos, (byte)TradeFlag.Display); // Command
|
||||||
|
expectedData.Write(ref pos, m.Serial);
|
||||||
|
expectedData.Write(ref pos, firstCont.Serial);
|
||||||
|
expectedData.Write(ref pos, secondCont.Serial);
|
||||||
|
expectedData.Write(ref pos, hasName);
|
||||||
|
if (hasName)
|
||||||
|
expectedData.WriteAsciiFixed(ref pos, name, 30);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -51,15 +46,13 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new CloseSecureTrade(cont).Compile();
|
Span<byte> data = new CloseSecureTrade(cont).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[8];
|
||||||
{
|
int pos = 0;
|
||||||
0x6F, // Packet ID
|
|
||||||
0x00, 0x8, // Length
|
|
||||||
(byte)TradeFlag.Close, // Command
|
|
||||||
0x00, 0x00, 0x00, 0x00 // Container Serial
|
|
||||||
};
|
|
||||||
|
|
||||||
cont.Serial.CopyTo(expectedData.Slice(4, 4));
|
expectedData.Write(ref pos, (byte)0x6F); // Packet ID
|
||||||
|
expectedData.Write(ref pos, (ushort)0x8); // Length
|
||||||
|
expectedData.Write(ref pos, (byte)TradeFlag.Close); // Command
|
||||||
|
expectedData.Write(ref pos, cont.Serial);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -75,17 +68,15 @@ namespace Server.Tests.Network.Packets
|
||||||
Container cont = first ? firstCont : secondCont;
|
Container cont = first ? firstCont : secondCont;
|
||||||
Span<byte> data = new UpdateSecureTrade(cont, first, second).Compile();
|
Span<byte> data = new UpdateSecureTrade(cont, first, second).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[16];
|
||||||
{
|
int pos = 0;
|
||||||
0x6F, // Packet ID
|
|
||||||
0x00, 0x10, // Length
|
|
||||||
(byte)TradeFlag.Update, // Command
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Container Serial
|
|
||||||
0x00, 0x00, 0x00, first ? (byte)0x01 : (byte)0x00, // (int)1 if first
|
|
||||||
0x00, 0x00, 0x00, second ? (byte)0x01 : (byte)0x00 // (int)1 if second
|
|
||||||
};
|
|
||||||
|
|
||||||
cont.Serial.CopyTo(expectedData.Slice(4, 4));
|
expectedData.Write(ref pos, (byte)0x6F); // Packet ID
|
||||||
|
expectedData.Write(ref pos, (ushort)0x10); // Length
|
||||||
|
expectedData.Write(ref pos, (byte)TradeFlag.Update); // Command
|
||||||
|
expectedData.Write(ref pos, cont.Serial);
|
||||||
|
expectedData.Write(ref pos, first ? 1 : 0); // true if first
|
||||||
|
expectedData.Write(ref pos, second ? 1 : 0); // true if second
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -97,20 +88,16 @@ namespace Server.Tests.Network.Packets
|
||||||
{
|
{
|
||||||
var cont = new Container(Serial.LastItem + 1);
|
var cont = new Container(Serial.LastItem + 1);
|
||||||
Span<byte> data = new UpdateSecureTrade(cont, flag, gold, plat).Compile();
|
Span<byte> data = new UpdateSecureTrade(cont, flag, gold, plat).Compile();
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
|
||||||
{
|
|
||||||
0x6F, // Packet ID
|
|
||||||
0x00, 0x10, // Length
|
|
||||||
(byte)flag, // Command
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Container Serial
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Gold
|
|
||||||
0x00, 0x00, 0x00, 0x00 // Platinum
|
|
||||||
};
|
|
||||||
|
|
||||||
int pos = 4;
|
Span<byte> expectedData = stackalloc byte[16];
|
||||||
cont.Serial.CopyTo(ref pos, expectedData);
|
int pos = 0;
|
||||||
gold.CopyTo(ref pos, expectedData);
|
|
||||||
plat.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)0x6F); // Packet ID
|
||||||
|
expectedData.Write(ref pos, (ushort)0x10); // Length
|
||||||
|
expectedData.Write(ref pos, (byte)flag); // Command
|
||||||
|
expectedData.Write(ref pos, cont.Serial);
|
||||||
|
expectedData.Write(ref pos, gold);
|
||||||
|
expectedData.Write(ref pos, plat);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -125,28 +112,22 @@ namespace Server.Tests.Network.Packets
|
||||||
var itemInCont = new Item(Serial.LastItem + 2) { Parent = cont };
|
var itemInCont = new Item(Serial.LastItem + 2) { Parent = cont };
|
||||||
|
|
||||||
Span<byte> data = new SecureTradeEquip(itemInCont, m).Compile();
|
Span<byte> data = new SecureTradeEquip(itemInCont, m).Compile();
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[20];
|
||||||
{
|
int pos = 0;
|
||||||
0x25, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Item Serial
|
|
||||||
0x00, 0x00, // Item ItemID
|
|
||||||
0x00,
|
|
||||||
0x00, 0x00, // Item Amount
|
|
||||||
0x00, 0x00, // X
|
|
||||||
0x00, 0x00, // Y
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Mobile Serial
|
|
||||||
0x00, 0x00 // Item Hue
|
|
||||||
};
|
|
||||||
|
|
||||||
int pos = 1;
|
expectedData.Write(ref pos, (byte)0x25); // Packet ID
|
||||||
itemInCont.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, itemInCont.Serial);
|
||||||
((short)itemInCont.ItemID).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (short)itemInCont.ItemID);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0);
|
||||||
|
#else
|
||||||
pos++;
|
pos++;
|
||||||
((short)itemInCont.Amount).CopyTo(ref pos, expectedData);
|
#endif
|
||||||
((short)itemInCont.X).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (short)itemInCont.Amount);
|
||||||
((short)itemInCont.Y).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (short)itemInCont.X);
|
||||||
m.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (short)itemInCont.Y);
|
||||||
((short)itemInCont.Hue).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, m.Serial);
|
||||||
|
expectedData.Write(ref pos, (short)itemInCont.Hue);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -161,30 +142,28 @@ namespace Server.Tests.Network.Packets
|
||||||
var itemInCont = new Item(Serial.LastItem + 2) { Parent = cont };
|
var itemInCont = new Item(Serial.LastItem + 2) { Parent = cont };
|
||||||
|
|
||||||
Span<byte> data = new SecureTradeEquip6017(itemInCont, m).Compile();
|
Span<byte> data = new SecureTradeEquip6017(itemInCont, m).Compile();
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
|
||||||
{
|
|
||||||
0x25, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Item Serial
|
|
||||||
0x00, 0x00, // Item ItemID
|
|
||||||
0x00, // Unknown
|
|
||||||
0x00, 0x00, // Item Amount
|
|
||||||
0x00, 0x00, // X
|
|
||||||
0x00, 0x00, // Y
|
|
||||||
0x00, // Grid Location
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Mobile Serial
|
|
||||||
0x00, 0x00 // Item Hue
|
|
||||||
};
|
|
||||||
|
|
||||||
int pos = 1;
|
Span<byte> expectedData = stackalloc byte[21];
|
||||||
itemInCont.Serial.CopyTo(ref pos, expectedData);
|
int pos = 0;
|
||||||
((short)itemInCont.ItemID).CopyTo(ref pos, expectedData);
|
|
||||||
|
expectedData.Write(ref pos, (byte)0x25); // Packet ID
|
||||||
|
expectedData.Write(ref pos, itemInCont.Serial);
|
||||||
|
expectedData.Write(ref pos, (short)itemInCont.ItemID);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0);
|
||||||
|
#else
|
||||||
pos++;
|
pos++;
|
||||||
((short)itemInCont.Amount).CopyTo(ref pos, expectedData);
|
#endif
|
||||||
((short)itemInCont.X).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (short)itemInCont.Amount);
|
||||||
((short)itemInCont.Y).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (short)itemInCont.X);
|
||||||
|
expectedData.Write(ref pos, (short)itemInCont.Y);
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0);
|
||||||
|
#else
|
||||||
pos++;
|
pos++;
|
||||||
m.Serial.CopyTo(ref pos, expectedData);
|
#endif
|
||||||
((short)itemInCont.Hue).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, m.Serial);
|
||||||
|
expectedData.Write(ref pos, (short)itemInCont.Hue);
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Server.Prompts;
|
using Server.Prompts;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -17,19 +18,18 @@ namespace Server.Tests.Network.Packets
|
||||||
var prompt = new TestPrompt();
|
var prompt = new TestPrompt();
|
||||||
Span<byte> data = new UnicodePrompt(prompt).Compile();
|
Span<byte> data = new UnicodePrompt(prompt).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[21];
|
||||||
{
|
int pos = 0;
|
||||||
0xC2, // Packet ID
|
|
||||||
0x00, 0x15, // Length
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Serial
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Prompt Serial
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Unused
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Unused
|
|
||||||
0x00, 0x00 // Unused
|
|
||||||
};
|
|
||||||
|
|
||||||
prompt.Serial.CopyTo(expectedData.Slice(3, 4));
|
expectedData.Write(ref pos, (byte)0xC2); // Packet ID
|
||||||
prompt.Serial.CopyTo(expectedData.Slice(7, 4));
|
expectedData.Write(ref pos, (ushort)0x15); // Length
|
||||||
|
expectedData.Write(ref pos, prompt.Serial);
|
||||||
|
expectedData.Write(ref pos, prompt.Serial);
|
||||||
|
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (ulong)0);
|
||||||
|
expectedData.Write(ref pos, (ushort)0);
|
||||||
|
#endif
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
|
|
@ -27,23 +28,22 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0x3C).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0x3C); // Packet ID
|
||||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
expectedData.Write(ref pos, (ushort)expectedData.Length); // Length
|
||||||
((ushort)buyStates.Count).CopyTo(ref pos, expectedData); // Count
|
expectedData.Write(ref pos, (ushort)buyStates.Count); // Count
|
||||||
|
|
||||||
for (int i = buyStates.Count - 1; i >= 0; i--)
|
for (int i = buyStates.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
BuyItemState buyState = buyStates[i];
|
BuyItemState buyState = buyStates[i];
|
||||||
|
|
||||||
buyState.MySerial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, buyState.MySerial);
|
||||||
((ushort)buyState.ItemID).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)buyState.ItemID);
|
||||||
pos++; // ItemID Offset
|
pos++; // ItemID Offset
|
||||||
((ushort)buyState.Amount).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)buyState.Amount);
|
||||||
((ushort)(i + 1)).CopyTo(ref pos, expectedData); // X
|
expectedData.Write(ref pos, (ushort)(i + 1)); // X
|
||||||
((byte)0).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)1); // Y
|
||||||
((byte)1).CopyTo(ref pos, expectedData); // Y
|
expectedData.Write(ref pos, buyState.ContainerSerial);
|
||||||
buyState.ContainerSerial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)buyState.Hue);
|
||||||
((ushort)buyState.Hue).CopyTo(ref pos, expectedData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
|
|
@ -67,24 +67,27 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0x3C).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0x3C); // Packet ID
|
||||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
expectedData.Write(ref pos, (ushort)expectedData.Length); // Length
|
||||||
((ushort)buyStates.Count).CopyTo(ref pos, expectedData); // Count
|
expectedData.Write(ref pos, (ushort)buyStates.Count); // Count
|
||||||
|
|
||||||
for (int i = buyStates.Count - 1; i >= 0; i--)
|
for (int i = buyStates.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
BuyItemState buyState = buyStates[i];
|
BuyItemState buyState = buyStates[i];
|
||||||
|
|
||||||
buyState.MySerial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, buyState.MySerial);
|
||||||
((ushort)buyState.ItemID).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)buyState.ItemID);
|
||||||
pos++; // ItemID Offset
|
pos++; // ItemID Offset
|
||||||
((ushort)buyState.Amount).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)buyState.Amount);
|
||||||
((ushort)(i + 1)).CopyTo(ref pos, expectedData); // X
|
expectedData.Write(ref pos, (ushort)(i + 1)); // X
|
||||||
((byte)0).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)1); // Y
|
||||||
((byte)1).CopyTo(ref pos, expectedData); // Y
|
#if NO_LOCAL_INIT
|
||||||
((byte)0).CopyTo(ref pos, expectedData); // Grid Location
|
expectedData.Write(ref pos, (byte)0); // Grid Location?
|
||||||
buyState.ContainerSerial.CopyTo(ref pos, expectedData);
|
#else
|
||||||
((ushort)buyState.Hue).CopyTo(ref pos, expectedData);
|
pos++;
|
||||||
|
#endif
|
||||||
|
expectedData.Write(ref pos, buyState.ContainerSerial);
|
||||||
|
expectedData.Write(ref pos, (ushort)buyState.Hue);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
|
|
@ -98,14 +101,12 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new DisplayBuyList(vendor).Compile();
|
Span<byte> data = new DisplayBuyList(vendor).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[7];
|
||||||
{
|
int pos = 0;
|
||||||
0x24, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Vendor Serial
|
|
||||||
0x00, 0x30 // Buy Window Gump Id
|
|
||||||
};
|
|
||||||
|
|
||||||
vendor.Serial.CopyTo(expectedData.Slice(1, 4));
|
expectedData.Write(ref pos, (byte)0x24); // Packet ID
|
||||||
|
expectedData.Write(ref pos, vendor.Serial);
|
||||||
|
expectedData.Write(ref pos, (ushort)0x30); // Buy gump
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -118,15 +119,16 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new DisplayBuyListHS(vendor).Compile();
|
Span<byte> data = new DisplayBuyListHS(vendor).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[9];
|
||||||
{
|
int pos = 0;
|
||||||
0x24, // Packet ID
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Vendor Serial
|
|
||||||
0x00, 0x30, // Buy Window Gump Id
|
|
||||||
0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
vendor.Serial.CopyTo(expectedData.Slice(1, 4));
|
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);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
@ -154,16 +156,18 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
((byte)0x74).CopyTo(ref pos, expectedData); // Packet ID
|
expectedData.Write(ref pos, (byte)0x74); // Packet ID
|
||||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
expectedData.Write(ref pos, (ushort)expectedData.Length); // Length
|
||||||
Serial.MinusOne.CopyTo(ref pos, expectedData); // Vendor Buy Pack Serial or -1
|
expectedData.Write(ref pos, Serial.MinusOne); // Vendor Buy Pack Serial or -1
|
||||||
((byte)buyStates.Count).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)buyStates.Count);
|
||||||
|
|
||||||
for (int i = 0; i < buyStates.Count; i++)
|
for (int i = 0; i < buyStates.Count; i++)
|
||||||
{
|
{
|
||||||
BuyItemState state = buyStates[i];
|
BuyItemState state = buyStates[i];
|
||||||
state.Price.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, state.Price);
|
||||||
(state.Description ?? "").CopySmallASCIINullTo(ref pos, expectedData);
|
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);
|
AssertThat.Equal(data, expectedData);
|
||||||
|
|
@ -177,15 +181,16 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new EndVendorBuy(vendor).Compile();
|
Span<byte> data = new EndVendorBuy(vendor).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[8];
|
||||||
{
|
int pos = 0;
|
||||||
0x3B, // Packet ID
|
|
||||||
0x00, 0x08, // Length
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Vendor Serial
|
|
||||||
0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
vendor.Serial.CopyTo(expectedData.Slice(3, 4));
|
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);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
|
|
@ -32,23 +33,24 @@ namespace Server.Tests.Network.Packets
|
||||||
);
|
);
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[length];
|
Span<byte> expectedData = stackalloc byte[length];
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
((byte)0x9E).CopyTo(ref pos, expectedData); // Packet ID
|
|
||||||
((ushort)length).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (byte)0x9E); // Packet ID
|
||||||
vendor.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)length);
|
||||||
((ushort)sellStates.Count).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, vendor.Serial);
|
||||||
|
expectedData.Write(ref pos, (ushort)sellStates.Count);
|
||||||
|
|
||||||
for (int i = 0; i < sellStates.Count; i++)
|
for (int i = 0; i < sellStates.Count; i++)
|
||||||
{
|
{
|
||||||
SellItemState state = sellStates[i];
|
SellItemState state = sellStates[i];
|
||||||
state.Item.Serial.CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, state.Item.Serial);
|
||||||
((ushort)state.Item.ItemID).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)state.Item.ItemID);
|
||||||
((ushort)state.Item.Hue).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)state.Item.Hue);
|
||||||
((ushort)state.Item.Amount).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)state.Item.Amount);
|
||||||
((ushort)state.Price).CopyTo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)state.Price);
|
||||||
string name = string.IsNullOrWhiteSpace(state.Item.Name) ? state.Name ?? "" : state.Item.Name.Trim();
|
string name = string.IsNullOrWhiteSpace(state.Item.Name) ? state.Name ?? "" : state.Item.Name.Trim();
|
||||||
name.CopyASCIITo(ref pos, expectedData);
|
expectedData.Write(ref pos, (ushort)name.Length);
|
||||||
|
expectedData.WriteAscii(ref pos, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
|
|
@ -62,15 +64,16 @@ namespace Server.Tests.Network.Packets
|
||||||
|
|
||||||
Span<byte> data = new EndVendorBuy(vendor).Compile();
|
Span<byte> data = new EndVendorBuy(vendor).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[]
|
Span<byte> expectedData = stackalloc byte[8];
|
||||||
{
|
int pos = 0;
|
||||||
0x3B, // Packet ID
|
|
||||||
0x00, 0x08, // Length
|
|
||||||
0x00, 0x00, 0x00, 0x00, // Vendor Serial
|
|
||||||
0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
vendor.Serial.CopyTo(expectedData.Slice(3, 4));
|
expectedData.Write(ref pos, (byte)0x3B); // Packet ID
|
||||||
|
expectedData.Write(ref pos, (ushort)0x08); // Length
|
||||||
|
expectedData.Write(ref pos, vendor.Serial);
|
||||||
|
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
expectedData.Write(ref pos, (byte)0);
|
||||||
|
#endif
|
||||||
|
|
||||||
AssertThat.Equal(data, expectedData);
|
AssertThat.Equal(data, expectedData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,250 +11,5 @@ namespace Server.Tests.Network.Packets
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Span<byte> Compile(this Packet p) =>
|
public static Span<byte> Compile(this Packet p) =>
|
||||||
p.Compile(false, out int length).AsSpan(0, length);
|
p.Compile(false, out int length).AsSpan(0, length);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this byte value, Span<byte> bytes) => bytes[0] = value;
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this bool value, Span<byte> bytes) => bytes[0] = (byte)(value ? 0x1 : 0x0);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this ushort number, Span<byte> bytes) => BinaryPrimitives.WriteUInt16BigEndian(bytes, number);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this short number, Span<byte> bytes) => BinaryPrimitives.WriteInt16BigEndian(bytes, number);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this Serial s, Span<byte> bytes) => BinaryPrimitives.WriteUInt32BigEndian(bytes, s);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this uint number, Span<byte> bytes) => BinaryPrimitives.WriteUInt32BigEndian(bytes, number);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this int number, Span<byte> bytes) => BinaryPrimitives.WriteInt32BigEndian(bytes, number);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this ulong number, Span<byte> bytes) => BinaryPrimitives.WriteUInt64BigEndian(bytes, number);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this long number, Span<byte> bytes) => BinaryPrimitives.WriteInt64BigEndian(bytes, number);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyToLE(this ushort number, Span<byte> bytes) => BinaryPrimitives.WriteUInt16LittleEndian(bytes, number);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyToLE(this short number, Span<byte> bytes) => BinaryPrimitives.WriteInt16LittleEndian(bytes, number);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyToLE(this Serial s, Span<byte> bytes) => BinaryPrimitives.WriteUInt32LittleEndian(bytes, s);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyToLE(this uint number, Span<byte> bytes) => BinaryPrimitives.WriteUInt32LittleEndian(bytes, number);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyToLE(this int number, Span<byte> bytes) => BinaryPrimitives.WriteInt32LittleEndian(bytes, number);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyToLE(this ulong number, Span<byte> bytes) => BinaryPrimitives.WriteUInt64LittleEndian(bytes, number);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyToLE(this long number, Span<byte> bytes) => BinaryPrimitives.WriteInt64LittleEndian(bytes, number);
|
|
||||||
|
|
||||||
// With Position Reference
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this byte value, ref int pos, Span<byte> bytes) => bytes[pos++] = value;
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this bool value, ref int pos, Span<byte> bytes) => bytes[pos++] = (byte)(value ? 0x1 : 0x0);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this ushort number, ref int pos, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
BinaryPrimitives.WriteUInt16BigEndian(bytes.Slice(pos, 2), number);
|
|
||||||
pos += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this short number, ref int pos, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
BinaryPrimitives.WriteInt16BigEndian(bytes.Slice(pos, 2), number);
|
|
||||||
pos += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this Serial s, ref int pos, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
BinaryPrimitives.WriteUInt32BigEndian(bytes.Slice(pos, 4), s);
|
|
||||||
pos += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this uint number, ref int pos, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
BinaryPrimitives.WriteUInt32BigEndian(bytes.Slice(pos, 4), number);
|
|
||||||
pos += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this int number, ref int pos, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
BinaryPrimitives.WriteInt32BigEndian(bytes.Slice(pos, 4), number);
|
|
||||||
pos += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this ulong number, ref int pos, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
BinaryPrimitives.WriteUInt64BigEndian(bytes.Slice(pos, 8), number);
|
|
||||||
pos += 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this long number, ref int pos, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
BinaryPrimitives.WriteInt64BigEndian(bytes.Slice(pos, 8), number);
|
|
||||||
pos += 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyRawASCIITo(this string str, ref int pos, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
pos += Encoding.ASCII.GetBytes(str, bytes.Slice(pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyRawASCIITo(this string str, ref int pos, int max, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
pos += Encoding.ASCII.GetBytes(str.AsSpan(0, Math.Min(str.Length, max)), bytes.Slice(pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ascii prepended with two-byte length
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyASCIITo(this string str, ref int pos, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
BinaryPrimitives.WriteUInt16BigEndian(bytes.Slice(pos, 2), (ushort)str.Length);
|
|
||||||
pos += 2 + Encoding.ASCII.GetBytes(str, bytes.Slice(pos + 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyASCIITo(this string str, ref int pos, int max, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
var length = Math.Min(str.Length, max);
|
|
||||||
BinaryPrimitives.WriteUInt16BigEndian(bytes.Slice(pos, 2), (ushort)length);
|
|
||||||
pos += 2 + Encoding.ASCII.GetBytes(str.AsSpan(0, length), bytes.Slice(pos + 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyASCIINullTo(this string str, ref int pos, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
BinaryPrimitives.WriteUInt16BigEndian(bytes.Slice(pos, 2), (ushort)(str.Length + 1));
|
|
||||||
pos += 3 + Encoding.ASCII.GetBytes(str, bytes.Slice(pos + 2));
|
|
||||||
bytes[pos - 1] = 0; // null terminator
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyASCIINullTo(this string str, ref int pos, int max, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
var length = Math.Min(str.Length, max - 1);
|
|
||||||
BinaryPrimitives.WriteUInt16BigEndian(bytes.Slice(pos, 2), (ushort)(length + 1));
|
|
||||||
pos += 3 + Encoding.ASCII.GetBytes(str.AsSpan(0, length), bytes.Slice(pos + 2));
|
|
||||||
bytes[pos - 1] = 0; // null terminator
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ascii prepended with one-byte length
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopySmallASCIITo(this string str, ref int pos, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
bytes[pos++] = (byte)str.Length;
|
|
||||||
pos += Encoding.ASCII.GetBytes(str.AsSpan(), bytes.Slice(pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopySmallASCIITo(this string str, ref int pos, int max, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
var length = Math.Min(255, Math.Min(str.Length, max));
|
|
||||||
bytes[pos++] = (byte)length;
|
|
||||||
pos += Encoding.ASCII.GetBytes(str.AsSpan(0, length), bytes.Slice(pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopySmallASCIINullTo(this string str, ref int pos, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
bytes[pos++] = (byte)(str.Length + 1);
|
|
||||||
pos += Encoding.ASCII.GetBytes(str.AsSpan(), bytes.Slice(pos));
|
|
||||||
bytes[pos++] = 0; // null terminator
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopySmallASCIINullTo(this string str, ref int pos, int max, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
var length = Math.Min(255, Math.Min(str.Length, max));
|
|
||||||
bytes[pos++] = (byte)length;
|
|
||||||
pos += Encoding.ASCII.GetBytes(str.AsSpan(0, length), bytes.Slice(pos));
|
|
||||||
bytes[pos++] = 0; // null terminator
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyASCIIFixedTo(this string str, ref int pos, int max, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
int bytesWritten = Encoding.ASCII.GetBytes(str.AsSpan(0, Math.Min(str.Length, max)), bytes.Slice(pos));
|
|
||||||
|
|
||||||
// This is not needed in the current stackalloc implementation, but not guaranteed in the future.
|
|
||||||
if (bytesWritten < max)
|
|
||||||
bytes.Slice(pos + bytesWritten, max - bytesWritten).Clear();
|
|
||||||
|
|
||||||
pos += max;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unicode prepended with two-byte length
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyUnicodeBigEndianTo(this string str, ref int pos, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
BinaryPrimitives.WriteUInt16BigEndian(bytes.Slice(pos, 2), (ushort)str.Length);
|
|
||||||
pos += 2 + Encoding.BigEndianUnicode.GetBytes(str, bytes.Slice(pos + 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyRawUnicodeBigEndianTo(this string str, ref int pos, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
pos += Encoding.BigEndianUnicode.GetBytes(str, bytes.Slice(pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyRawUnicodeLittleEndianTo(this string str, ref int pos, Span<byte> bytes)
|
|
||||||
{
|
|
||||||
pos += Encoding.Unicode.GetBytes(str, bytes.Slice(pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this byte[] src, ref int pos, Span<byte> bytes) =>
|
|
||||||
src.CopyTo(bytes.Slice(pos, src.Length));
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this byte[] src, ref int pos, int max, Span<byte> bytes) =>
|
|
||||||
src.CopyTo(bytes.Slice(pos, Math.Min(max, src.Length)));
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this Span<byte> src, ref int pos, Span<byte> bytes) =>
|
|
||||||
src.CopyTo(bytes.Slice(pos, src.Length));
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this Span<byte> src, ref int pos, int max, Span<byte> bytes) =>
|
|
||||||
src.CopyTo(bytes.Slice(pos, Math.Min(max, src.Length)));
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this ReadOnlySpan<byte> src, ref int pos, Span<byte> bytes) =>
|
|
||||||
src.CopyTo(bytes.Slice(pos, src.Length));
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void CopyTo(this ReadOnlySpan<byte> src, ref int pos, int max, Span<byte> bytes) =>
|
|
||||||
src.CopyTo(bytes.Slice(pos, Math.Min(max, src.Length)));
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void Clear(this Span<byte> span, ref int pos, int amount)
|
|
||||||
{
|
|
||||||
span.Slice(pos, amount).Clear();
|
|
||||||
pos += amount;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
195
Projects/Server/Buffers/SpanExtensions.cs
Normal file
195
Projects/Server/Buffers/SpanExtensions.cs
Normal file
|
|
@ -0,0 +1,195 @@
|
||||||
|
using System.Buffers.Binary;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
|
using Server;
|
||||||
|
|
||||||
|
namespace System.Buffers
|
||||||
|
{
|
||||||
|
public static class SpanExtensions
|
||||||
|
{
|
||||||
|
// Extensions
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Write(this Span<byte> span, ushort value) => BinaryPrimitives.WriteUInt16BigEndian(span, value);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Write(this Span<byte> span, short value) => BinaryPrimitives.WriteInt16BigEndian(span, value);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Write(this Span<byte> span, uint value) => BinaryPrimitives.WriteUInt32BigEndian(span, value);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Write(this Span<byte> span, int value) => BinaryPrimitives.WriteInt32BigEndian(span, value);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Write(this Span<byte> span, byte value) => span[0] = value;
|
||||||
|
|
||||||
|
// Ref Extensions
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Write(this Span<byte> span, ref int pos, ReadOnlySpan<byte> data)
|
||||||
|
{
|
||||||
|
data.CopyTo(span.Slice(pos, data.Length));
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Write(this Span<byte> span, ref int pos, bool value)
|
||||||
|
{
|
||||||
|
span[pos++] = value ? (byte)1 : (byte)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Write(this Span<byte> span, ref int pos, byte value) => span[pos++] = value;
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Write(this Span<byte> span, ref int pos, ushort value)
|
||||||
|
{
|
||||||
|
BinaryPrimitives.WriteUInt16BigEndian(span.Slice(pos, 2), value);
|
||||||
|
pos += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Write(this Span<byte> span, ref int pos, short value)
|
||||||
|
{
|
||||||
|
BinaryPrimitives.WriteInt16BigEndian(span.Slice(pos, 2), value);
|
||||||
|
pos += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Write(this Span<byte> span, ref int pos, uint value)
|
||||||
|
{
|
||||||
|
BinaryPrimitives.WriteUInt32BigEndian(span.Slice(pos, 4), value);
|
||||||
|
pos += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void WriteLE(this Span<byte> span, ref int pos, uint value)
|
||||||
|
{
|
||||||
|
BinaryPrimitives.WriteUInt32LittleEndian(span.Slice(pos, 4), value);
|
||||||
|
pos += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Write(this Span<byte> span, ref int pos, int value)
|
||||||
|
{
|
||||||
|
BinaryPrimitives.WriteInt32BigEndian(span.Slice(pos, 4), value);
|
||||||
|
pos += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void WriteLE(this Span<byte> span, ref int pos, int value)
|
||||||
|
{
|
||||||
|
BinaryPrimitives.WriteInt32LittleEndian(span.Slice(pos, 4), value);
|
||||||
|
pos += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Write(this Span<byte> span, ref int pos, Serial value)
|
||||||
|
{
|
||||||
|
BinaryPrimitives.WriteUInt32BigEndian(span.Slice(pos, 4), value);
|
||||||
|
pos += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Write(this Span<byte> span, ref int pos, ulong value)
|
||||||
|
{
|
||||||
|
BinaryPrimitives.WriteUInt64BigEndian(span.Slice(pos, 8), value);
|
||||||
|
pos += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Write(this Span<byte> span, ref int pos, long value)
|
||||||
|
{
|
||||||
|
BinaryPrimitives.WriteInt64BigEndian(span.Slice(pos, 8), value);
|
||||||
|
pos += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void WriteLE(this Span<byte> span, ref int pos, ulong value)
|
||||||
|
{
|
||||||
|
BinaryPrimitives.WriteUInt64LittleEndian(span.Slice(pos, 8), value);
|
||||||
|
pos += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void WriteLE(this Span<byte> span, ref int pos, long value)
|
||||||
|
{
|
||||||
|
BinaryPrimitives.WriteInt64LittleEndian(span.Slice(pos, 8), value);
|
||||||
|
pos += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void WriteAscii(this Span<byte> span, ref int pos, string value)
|
||||||
|
{
|
||||||
|
int length = value.Length;
|
||||||
|
pos += Encoding.ASCII.GetBytes(value.AsSpan(0, length), span.Slice(pos, length));
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void WriteAscii(this Span<byte> span, ref int pos, string value, int max)
|
||||||
|
{
|
||||||
|
int length = value.Length <= max ? value.Length : max;
|
||||||
|
|
||||||
|
pos += Encoding.ASCII.GetBytes(value.AsSpan(0, length), span.Slice(pos, length));
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void WriteAsciiNull(this Span<byte> span, ref int pos, string value)
|
||||||
|
{
|
||||||
|
int length = value.Length;
|
||||||
|
pos += Encoding.ASCII.GetBytes(value.AsSpan(0, length), span.Slice(pos, length));
|
||||||
|
span[pos++] = 0; // Null terminator
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void WriteAsciiNull(this Span<byte> span, ref int pos, string value, int max)
|
||||||
|
{
|
||||||
|
var length = value.Length < max ? value.Length : max - 1;
|
||||||
|
|
||||||
|
pos += Encoding.ASCII.GetBytes(value.AsSpan(0, length), span.Slice(pos, length));
|
||||||
|
span[pos++] = 0; // Null terminator
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void WriteAsciiFixed(this Span<byte> span, ref int pos, string value, int amount)
|
||||||
|
{
|
||||||
|
var length = value.Length <= amount ? value.Length : amount;
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
int bytesWritten = Encoding.ASCII.GetBytes(value.AsSpan(0, length), span.Slice(pos, length));
|
||||||
|
|
||||||
|
if (bytesWritten < amount)
|
||||||
|
span.Slice(pos + bytesWritten, amount - bytesWritten).Clear();
|
||||||
|
#else
|
||||||
|
Encoding.ASCII.GetBytes(value.AsSpan(0, length), span.Slice(pos, length));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pos += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void WriteAsciiFixedNull(this Span<byte> span, ref int pos, string value, int amount)
|
||||||
|
{
|
||||||
|
var length = value.Length < amount ? value.Length : amount - 1;
|
||||||
|
#if NO_LOCAL_INIT
|
||||||
|
int bytesWritten = Encoding.ASCII.GetBytes(value.AsSpan(0, amount), span.Slice(pos, amount));
|
||||||
|
|
||||||
|
if (bytesWritten < amount)
|
||||||
|
span.Slice(pos + bytesWritten, amount - bytesWritten).Clear();
|
||||||
|
#else
|
||||||
|
Encoding.ASCII.GetBytes(value.AsSpan(0, length), span.Slice(pos, length));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pos += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void WriteBigUni(this Span<byte> span, ref int pos, string value)
|
||||||
|
{
|
||||||
|
pos += Encoding.BigEndianUnicode.GetBytes(value, span.Slice(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void WriteLittleUni(this Span<byte> span, ref int pos, string value)
|
||||||
|
{
|
||||||
|
pos += Encoding.Unicode.GetBytes(value, span.Slice(pos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,300 +0,0 @@
|
||||||
/*************************************************************************
|
|
||||||
* ModernUO *
|
|
||||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
|
||||||
* Email: hi@modernuo.com *
|
|
||||||
* File: SpanWriter.cs - Created: 2019/08/05 - Updated: 2019/12/24 *
|
|
||||||
* *
|
|
||||||
* 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. *
|
|
||||||
* *
|
|
||||||
* This program is distributed in the hope that it will be useful, *
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
||||||
* GNU General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* 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;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Server.Buffers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Provides functionality for writing primitive binary data.
|
|
||||||
/// </summary>
|
|
||||||
public ref struct SpanWriter
|
|
||||||
{
|
|
||||||
private int m_Position;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Underlying Span.
|
|
||||||
/// </summary>
|
|
||||||
public Span<byte> RawSpan { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Underlying Span up to the bytes written.
|
|
||||||
/// </summary>
|
|
||||||
public Span<byte> Span => RawSpan.Slice(0, WrittenCount);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the total length of the span.
|
|
||||||
/// </summary>
|
|
||||||
public int Length => RawSpan.Length;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Total bytes written to the span.
|
|
||||||
/// </summary>
|
|
||||||
public int WrittenCount { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Current position in the the span.
|
|
||||||
/// </summary>
|
|
||||||
public int Position
|
|
||||||
{
|
|
||||||
get => m_Position;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
m_Position = value;
|
|
||||||
|
|
||||||
if (value > WrittenCount)
|
|
||||||
WrittenCount = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Instantiates a new SpanWriter instance.
|
|
||||||
/// </summary>
|
|
||||||
public SpanWriter(Span<byte> span)
|
|
||||||
{
|
|
||||||
RawSpan = span;
|
|
||||||
m_Position = 0;
|
|
||||||
WrittenCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes a 1-byte boolean value to the span.
|
|
||||||
/// </summary>
|
|
||||||
public unsafe void Write(bool value)
|
|
||||||
{
|
|
||||||
RawSpan[Position++] = *(byte*)&value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes a 1-byte unsigned integer value to the span.
|
|
||||||
/// </summary>
|
|
||||||
public void Write(byte value)
|
|
||||||
{
|
|
||||||
RawSpan[Position++] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes a 1-byte signed integer value to the span.
|
|
||||||
/// </summary>
|
|
||||||
public void Write(sbyte value)
|
|
||||||
{
|
|
||||||
RawSpan[Position++] = (byte)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes a 2-byte signed integer value to the span.
|
|
||||||
/// </summary>
|
|
||||||
public void Write(short value)
|
|
||||||
{
|
|
||||||
Write((byte)(value >> 8));
|
|
||||||
Write((byte)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes a 2-byte unsigned integer value to the span.
|
|
||||||
/// </summary>
|
|
||||||
public void Write(ushort value)
|
|
||||||
{
|
|
||||||
Write((byte)(value >> 8));
|
|
||||||
Write((byte)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes a 4-byte signed integer value to the span.
|
|
||||||
/// </summary>
|
|
||||||
public void Write(int value)
|
|
||||||
{
|
|
||||||
Write((byte)(value >> 24));
|
|
||||||
Write((byte)(value >> 16));
|
|
||||||
Write((byte)(value >> 8));
|
|
||||||
Write((byte)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes a 4-byte unsigned integer value to the span.
|
|
||||||
/// </summary>
|
|
||||||
public void Write(uint value)
|
|
||||||
{
|
|
||||||
Write((byte)(value >> 24));
|
|
||||||
Write((byte)(value >> 16));
|
|
||||||
Write((byte)(value >> 8));
|
|
||||||
Write((byte)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes an 8-byte signed integer value to the span.
|
|
||||||
/// </summary>
|
|
||||||
public void Write(long value)
|
|
||||||
{
|
|
||||||
Write((byte)(value >> 56));
|
|
||||||
Write((byte)(value >> 48));
|
|
||||||
Write((byte)(value >> 40));
|
|
||||||
Write((byte)(value >> 32));
|
|
||||||
|
|
||||||
Write((byte)(value >> 24));
|
|
||||||
Write((byte)(value >> 16));
|
|
||||||
Write((byte)(value >> 8));
|
|
||||||
Write((byte)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes an 8-byte unsigned integer value to the span.
|
|
||||||
/// </summary>
|
|
||||||
public void Write(ulong value)
|
|
||||||
{
|
|
||||||
Write((byte)(value >> 56));
|
|
||||||
Write((byte)(value >> 48));
|
|
||||||
Write((byte)(value >> 40));
|
|
||||||
Write((byte)(value >> 32));
|
|
||||||
|
|
||||||
Write((byte)(value >> 24));
|
|
||||||
Write((byte)(value >> 16));
|
|
||||||
Write((byte)(value >> 8));
|
|
||||||
Write((byte)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes a sequence of bytes to the span.
|
|
||||||
/// </summary>
|
|
||||||
public void Write(ReadOnlySpan<byte> input)
|
|
||||||
{
|
|
||||||
var size = Math.Min(input.Length, Length - Position);
|
|
||||||
|
|
||||||
input.Slice(0, size).CopyTo(RawSpan.Slice(Position));
|
|
||||||
Position += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes an ASCII-encoded string value to the span.
|
|
||||||
/// </summary>
|
|
||||||
public void WriteAscii(string value)
|
|
||||||
{
|
|
||||||
Position += Encoding.ASCII.GetBytes(value ?? "", RawSpan.Slice(Position));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes a fixed-length ASCII-encoded string value to the span.
|
|
||||||
/// </summary>
|
|
||||||
public void WriteAsciiFixed(string value, int size, bool zero = false)
|
|
||||||
{
|
|
||||||
value ??= "";
|
|
||||||
|
|
||||||
var length = Math.Min(size, value.Length);
|
|
||||||
|
|
||||||
Encoding.ASCII.GetBytes(value.AsSpan(0, length), RawSpan.Slice(Position));
|
|
||||||
|
|
||||||
if (zero)
|
|
||||||
{
|
|
||||||
Position += length;
|
|
||||||
Fill(size - length);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Position += size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes a dynamic-length ASCII-encoded string value to the span, followed by a 1-byte null character.
|
|
||||||
/// </summary>
|
|
||||||
public void WriteAsciiNull(string value)
|
|
||||||
{
|
|
||||||
Position += Encoding.ASCII.GetBytes(value ?? "", RawSpan.Slice(Position));
|
|
||||||
Write((byte)0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes a dynamic-length ASCII-encoded string value to the span, followed by a 1-byte null character.
|
|
||||||
/// </summary>
|
|
||||||
public void WriteAsciiNull(string value, int size)
|
|
||||||
{
|
|
||||||
value ??= "";
|
|
||||||
|
|
||||||
size = Math.Min(size, value.Length);
|
|
||||||
Position += Encoding.ASCII.GetBytes(value.AsSpan(0, size), RawSpan.Slice(Position));
|
|
||||||
Write((byte)0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes a dynamic-length little-endian unicode string value to the span.
|
|
||||||
/// </summary>
|
|
||||||
public void WriteLittleUni(string value)
|
|
||||||
{
|
|
||||||
Position += Encoding.Unicode.GetBytes(value ?? "", RawSpan.Slice(Position));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes a dynamic-length little-endian unicode string value to the span, followed by a 2-byte null character.
|
|
||||||
/// </summary>
|
|
||||||
public void WriteLittleUniNull(string value)
|
|
||||||
{
|
|
||||||
WriteLittleUni(value);
|
|
||||||
Write((ushort)0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes a dynamic-length big-endian unicode string value to the span.
|
|
||||||
/// </summary>
|
|
||||||
public void WriteBigUni(string value)
|
|
||||||
{
|
|
||||||
Position += Encoding.BigEndianUnicode.GetBytes(value ?? "", RawSpan.Slice(Position));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes a dynamic-length big-endian unicode string value to the span, followed by a 2-byte null character.
|
|
||||||
/// </summary>
|
|
||||||
public void WriteBigUniNull(string value, bool zero = false)
|
|
||||||
{
|
|
||||||
WriteBigUni(value);
|
|
||||||
|
|
||||||
if (zero)
|
|
||||||
Fill(2);
|
|
||||||
else
|
|
||||||
Position += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes a dynamic-length utf-8 string value, followed by a 1-byte null character.
|
|
||||||
/// </summary>
|
|
||||||
public void WriteUTF8Null(string value)
|
|
||||||
{
|
|
||||||
Position += Encoding.UTF8.GetBytes(value ?? "", RawSpan.Slice(Position)) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Copies the span to the destination.
|
|
||||||
/// </summary>
|
|
||||||
public void CopyTo(Span<byte> destination)
|
|
||||||
{
|
|
||||||
RawSpan.CopyTo(destination);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Fills the buffer with zeroes up to count
|
|
||||||
/// </summary>
|
|
||||||
public void Fill(int count)
|
|
||||||
{
|
|
||||||
count = Math.Min(count, RawSpan.Length - Position);
|
|
||||||
RawSpan.Slice(Position, count).Clear();
|
|
||||||
Position += count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -76,7 +76,7 @@ namespace Server
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// TOOD: Can we make this higher for newer clients?
|
// TODO: Can we make this higher for newer clients?
|
||||||
public static uint FakeSerial(Mobile parent) => 0x7FFFFFFF - 0x400 - parent.Serial * 4;
|
public static uint FakeSerial(Mobile parent) => 0x7FFFFFFF - 0x400 - parent.Serial * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ namespace Server.Menus.ItemLists
|
||||||
{
|
{
|
||||||
public ItemListEntry(string name, int itemID, int hue = 0)
|
public ItemListEntry(string name, int itemID, int hue = 0)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name?.Trim() ?? "";
|
||||||
ItemID = itemID;
|
ItemID = itemID;
|
||||||
Hue = hue;
|
Hue = hue;
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +44,7 @@ namespace Server.Menus.ItemLists
|
||||||
|
|
||||||
public ItemListMenu(string question, ItemListEntry[] entries)
|
public ItemListMenu(string question, ItemListEntry[] entries)
|
||||||
{
|
{
|
||||||
Question = question;
|
Question = question.Trim();
|
||||||
Entries = entries;
|
Entries = entries;
|
||||||
|
|
||||||
do
|
do
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ namespace Server.Menus.Questions
|
||||||
|
|
||||||
public QuestionMenu(string question, string[] answers)
|
public QuestionMenu(string question, string[] answers)
|
||||||
{
|
{
|
||||||
Question = question;
|
Question = question?.Trim() ?? "";
|
||||||
Answers = answers;
|
Answers = answers;
|
||||||
|
|
||||||
do
|
do
|
||||||
|
|
@ -38,7 +38,7 @@ namespace Server.Menus.Questions
|
||||||
} while (Serial == 0);
|
} while (Serial == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Question { get; set; }
|
public string Question { get; }
|
||||||
|
|
||||||
public string[] Answers { get; }
|
public string[] Answers { get; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -449,9 +449,9 @@ namespace Server.Network
|
||||||
EnsureCapacity(12);
|
EnsureCapacity(12);
|
||||||
|
|
||||||
Stream.Write(m.Serial);
|
Stream.Write(m.Serial);
|
||||||
Stream.Write((short)1);
|
Stream.Write((short)1); // Show Bar?
|
||||||
|
|
||||||
Stream.Write((short)1);
|
Stream.Write((short)1); // Poison Bar
|
||||||
|
|
||||||
var p = m.Poison;
|
var p = m.Poison;
|
||||||
|
|
||||||
|
|
@ -527,7 +527,7 @@ namespace Server.Network
|
||||||
|
|
||||||
public sealed class MobileIncoming : Packet
|
public sealed class MobileIncoming : Packet
|
||||||
{
|
{
|
||||||
private static readonly ThreadLocal<int[]> m_DupedLayersTL = new ThreadLocal<int[]>(() => { return new int[256]; });
|
private static readonly ThreadLocal<int[]> m_DupedLayersTL = new ThreadLocal<int[]>(() => new int[256]);
|
||||||
private static readonly ThreadLocal<int> m_VersionTL = new ThreadLocal<int>();
|
private static readonly ThreadLocal<int> m_VersionTL = new ThreadLocal<int>();
|
||||||
|
|
||||||
public MobileIncoming(Mobile beholder, Mobile beheld) : base(0x78)
|
public MobileIncoming(Mobile beholder, Mobile beheld) : base(0x78)
|
||||||
|
|
@ -636,7 +636,7 @@ namespace Server.Network
|
||||||
|
|
||||||
public sealed class MobileIncomingSA : Packet
|
public sealed class MobileIncomingSA : Packet
|
||||||
{
|
{
|
||||||
private static readonly ThreadLocal<int[]> m_DupedLayersTL = new ThreadLocal<int[]>(() => { return new int[256]; });
|
private static readonly ThreadLocal<int[]> m_DupedLayersTL = new ThreadLocal<int[]>(() => new int[256]);
|
||||||
private static readonly ThreadLocal<int> m_VersionTL = new ThreadLocal<int>();
|
private static readonly ThreadLocal<int> m_VersionTL = new ThreadLocal<int>();
|
||||||
|
|
||||||
public MobileIncomingSA(Mobile beholder, Mobile beheld) : base(0x78)
|
public MobileIncomingSA(Mobile beholder, Mobile beheld) : base(0x78)
|
||||||
|
|
@ -754,7 +754,7 @@ namespace Server.Network
|
||||||
// Pre-7.0.0.0 Mobile Incoming
|
// Pre-7.0.0.0 Mobile Incoming
|
||||||
public sealed class MobileIncomingOld : Packet
|
public sealed class MobileIncomingOld : Packet
|
||||||
{
|
{
|
||||||
private static readonly ThreadLocal<int[]> m_DupedLayersTL = new ThreadLocal<int[]>(() => { return new int[256]; });
|
private static readonly ThreadLocal<int[]> m_DupedLayersTL = new ThreadLocal<int[]>(() => new int[256]);
|
||||||
private static readonly ThreadLocal<int> m_VersionTL = new ThreadLocal<int>();
|
private static readonly ThreadLocal<int> m_VersionTL = new ThreadLocal<int>();
|
||||||
|
|
||||||
public MobileIncomingOld(Mobile beholder, Mobile beheld) : base(0x78)
|
public MobileIncomingOld(Mobile beholder, Mobile beheld) : base(0x78)
|
||||||
|
|
|
||||||
|
|
@ -14,32 +14,14 @@ jobs:
|
||||||
vmImage: 'windows-latest'
|
vmImage: 'windows-latest'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- task: NuGetToolInstaller@1
|
- task: NuGetAuthenticate@0
|
||||||
inputs:
|
- script: dotnet restore --force-evaluate
|
||||||
versionSpec: '5.x'
|
|
||||||
displayName: 'Install latest NuGet'
|
|
||||||
- task: DotNetCoreCLI@2
|
|
||||||
inputs:
|
|
||||||
command: 'custom'
|
|
||||||
custom: 'restore'
|
|
||||||
arguments: '--force-evaluate'
|
|
||||||
displayName: 'Restore NuGet Packages'
|
displayName: 'Restore NuGet Packages'
|
||||||
- task: DotNetCoreCLI@2
|
- script: dotnet build -c $(buildConfiguration) --no-restore Projects/Server/Server.csproj
|
||||||
inputs:
|
|
||||||
command: 'build'
|
|
||||||
arguments: '-c $(buildConfiguration) --no-restore'
|
|
||||||
projects: '**/Projects/Server/Server.csproj'
|
|
||||||
displayName: 'Build Server'
|
displayName: 'Build Server'
|
||||||
- task: DotNetCoreCLI@2
|
- script: dotnet build -c $(buildConfiguration) --no-restore Projects/UOContent/UOContent.csproj
|
||||||
inputs:
|
|
||||||
command: 'build'
|
|
||||||
arguments: '-c $(buildConfiguration) --no-restore'
|
|
||||||
projects: '**/Projects/UOContent/UOContent.csproj'
|
|
||||||
displayName: 'Build UO Content'
|
displayName: 'Build UO Content'
|
||||||
- task: DotNetCoreCLI@2
|
- script: dotnet test --no-restore
|
||||||
inputs:
|
|
||||||
command: 'test'
|
|
||||||
arguments: '--no-restore'
|
|
||||||
displayName: 'Test'
|
displayName: 'Test'
|
||||||
|
|
||||||
- job: BuildLinux
|
- job: BuildLinux
|
||||||
|
|
@ -60,26 +42,12 @@ jobs:
|
||||||
container: $[ variables['containerImage'] ]
|
container: $[ variables['containerImage'] ]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- task: DotNetCoreCLI@2
|
- task: NuGetAuthenticate@0
|
||||||
inputs:
|
- script: dotnet restore --force-evaluate
|
||||||
command: 'custom'
|
|
||||||
custom: 'restore'
|
|
||||||
arguments: '--force-evaluate'
|
|
||||||
displayName: 'Restore NuGet Packages'
|
displayName: 'Restore NuGet Packages'
|
||||||
- task: DotNetCoreCLI@2
|
- script: dotnet build -c $(buildConfiguration) --no-restore Projects/Server/Server.csproj
|
||||||
inputs:
|
|
||||||
command: 'build'
|
|
||||||
arguments: '-c $(buildConfiguration) --no-restore'
|
|
||||||
projects: '**/Projects/Server/Server.csproj'
|
|
||||||
displayName: 'Build Server'
|
displayName: 'Build Server'
|
||||||
- task: DotNetCoreCLI@2
|
- script: dotnet build -c $(buildConfiguration) --no-restore Projects/UOContent/UOContent.csproj
|
||||||
inputs:
|
|
||||||
command: 'build'
|
|
||||||
arguments: '-c $(buildConfiguration) --no-restore'
|
|
||||||
projects: '**/Projects/UOContent/UOContent.csproj'
|
|
||||||
displayName: 'Build UO Content'
|
displayName: 'Build UO Content'
|
||||||
- task: DotNetCoreCLI@2
|
- script: dotnet test --no-restore
|
||||||
inputs:
|
|
||||||
command: 'test'
|
|
||||||
arguments: '--no-restore'
|
|
||||||
displayName: 'Test'
|
displayName: 'Test'
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue