Adds more packet tests (#166)
This commit is contained in:
parent
ee06eb4407
commit
e17195ca80
22 changed files with 1203 additions and 277 deletions
40
Projects/Server.Tests/Network/Packets/GumpUtilities.cs
Normal file
40
Projects/Server.Tests/Network/Packets/GumpUtilities.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using System.IO.Compression;
|
||||
using System.Text;
|
||||
|
||||
namespace Server.Tests.Network.Packets
|
||||
{
|
||||
public class GumpUtilities
|
||||
{
|
||||
public static readonly byte[] NoMoveBuffer = Encoding.ASCII.GetBytes("{ nomove }");
|
||||
public static readonly byte[] NoCloseBuffer = Encoding.ASCII.GetBytes("{ noclose }");
|
||||
public static readonly byte[] NoDisposeBuffer = Encoding.ASCII.GetBytes("{ nodispose }");
|
||||
public static readonly byte[] NoResizeBuffer = Encoding.ASCII.GetBytes("{ noresize }");
|
||||
|
||||
public const string NoMove = "{ nomove }";
|
||||
public const string NoClose = "{ noclose }";
|
||||
public const string NoDispose = "{ nodispose }";
|
||||
public const string NoResize = "{ noresize }";
|
||||
|
||||
public static int WritePacked(ReadOnlySpan<byte> source, Span<byte> dest)
|
||||
{
|
||||
int length = source.Length;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
dest.Slice(0, 4).Clear();
|
||||
return 4;
|
||||
}
|
||||
|
||||
ulong packLength = (ulong)dest.Length - 8;
|
||||
|
||||
ZlibError ce = Zlib.Pack(dest.Slice(8), ref packLength, source, ZlibQuality.Default);
|
||||
if (ce != ZlibError.Okay) Console.WriteLine("ZLib error: {0} (#{1})", ce, (int)ce);
|
||||
|
||||
((int)(4 + packLength)).CopyTo(dest.Slice(0, 4));
|
||||
length.CopyTo(dest.Slice(4, 4));
|
||||
|
||||
return (int)(8 + packLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -114,10 +114,10 @@ namespace Server.Tests.Network.Packets
|
|||
Span<byte> expectedData = stackalloc byte[5 + account.Length * 60];
|
||||
int pos = 0;
|
||||
|
||||
expectedData[pos++] = 0x81; // Packet ID
|
||||
((byte)0x81).CopyTo(ref pos, expectedData); // Packet ID
|
||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
||||
expectedData[pos++] = 1; // Count of non-null characters
|
||||
expectedData[pos++] = 0;
|
||||
((byte)1).CopyTo(ref pos, expectedData); // Count of non-null characters
|
||||
((byte)0).CopyTo(ref pos, expectedData);
|
||||
|
||||
for (var i = 0; i < account.Length; ++i)
|
||||
{
|
||||
|
|
@ -183,13 +183,19 @@ namespace Server.Tests.Network.Packets
|
|||
[InlineData(ProtocolChanges.Version6000)]
|
||||
public void TestSupportedFeatures(ProtocolChanges protocolChanges)
|
||||
{
|
||||
var firstMobile = new Mobile(0x1);
|
||||
firstMobile.DefaultMobileInit();
|
||||
firstMobile.Name = "Test Mobile";
|
||||
|
||||
var account = new TestAccount(new[] {firstMobile, null, null, null, null});
|
||||
|
||||
NetState ns = new NetState(new TestConnectionContext
|
||||
{
|
||||
RemoteEndPoint = IPEndPoint.Parse("127.0.0.1")
|
||||
});
|
||||
|
||||
ns.ProtocolChanges = protocolChanges;
|
||||
ns.Account = new TestAccount(new Mobile[0]);
|
||||
})
|
||||
{
|
||||
Account = account
|
||||
};
|
||||
|
||||
Span<byte> data = new SupportedFeatures(ns).Compile();
|
||||
|
||||
|
|
@ -257,7 +263,7 @@ namespace Server.Tests.Network.Packets
|
|||
((ushort)m.X).CopyTo(ref pos, expectedData);
|
||||
((ushort)m.Y).CopyTo(ref pos, expectedData);
|
||||
((ushort)m.Z).CopyTo(ref pos, expectedData);
|
||||
expectedData[pos++] = (byte)m.Direction;
|
||||
((byte)m.Direction).CopyTo(ref pos, expectedData);
|
||||
pos += 9;
|
||||
var map = m.Map;
|
||||
|
||||
|
|
@ -297,7 +303,7 @@ namespace Server.Tests.Network.Packets
|
|||
Span<byte> expectedData = stackalloc byte[4 + account.Length * 60];
|
||||
|
||||
int pos = 0;
|
||||
expectedData[pos++] = 0x86; // Packet ID
|
||||
((byte)0x86).CopyTo(ref pos, expectedData); // Packet ID
|
||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
||||
|
||||
int highSlot = -1;
|
||||
|
|
@ -309,7 +315,7 @@ namespace Server.Tests.Network.Packets
|
|||
}
|
||||
|
||||
int count = Math.Max(Math.Max(highSlot + 1, account.Limit), 5);
|
||||
expectedData[pos++] = (byte)count;
|
||||
((byte)count).CopyTo(ref pos, expectedData);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
|
|
@ -346,7 +352,7 @@ namespace Server.Tests.Network.Packets
|
|||
Span<byte> expectedData = stackalloc byte[11 + account.Length * 60 + info.Length * 89];
|
||||
|
||||
int pos = 0;
|
||||
expectedData[pos++] = 0xA9; // Packet ID
|
||||
((byte)0xA9).CopyTo(ref pos, expectedData); // Packet ID
|
||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
||||
|
||||
int highSlot = -1;
|
||||
|
|
@ -358,7 +364,7 @@ namespace Server.Tests.Network.Packets
|
|||
}
|
||||
|
||||
int count = Math.Max(Math.Max(highSlot + 1, account.Limit), 5);
|
||||
expectedData[pos++] = (byte)count;
|
||||
((byte)count).CopyTo(ref pos, expectedData);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
|
|
@ -374,12 +380,12 @@ namespace Server.Tests.Network.Packets
|
|||
}
|
||||
}
|
||||
|
||||
expectedData[pos++] = (byte)info.Length;
|
||||
((byte)info.Length).CopyTo(ref pos, expectedData);
|
||||
|
||||
for (int i = 0; i < info.Length; i++)
|
||||
{
|
||||
var ci = info[i];
|
||||
expectedData[pos++] = (byte)i;
|
||||
((byte)i).CopyTo(ref pos, expectedData);
|
||||
ci.City.CopyASCIIFixedTo(ref pos, 32, expectedData);
|
||||
ci.Building.CopyASCIIFixedTo(ref pos, 32, expectedData);
|
||||
ci.X.CopyTo(ref pos, expectedData);
|
||||
|
|
@ -424,7 +430,7 @@ namespace Server.Tests.Network.Packets
|
|||
Span<byte> expectedData = stackalloc byte[9 + account.Length * 60 + info.Length * 63];
|
||||
|
||||
int pos = 0;
|
||||
expectedData[pos++] = 0xA9; // Packet ID
|
||||
((byte)0xA9).CopyTo(ref pos, expectedData); // Packet ID
|
||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
||||
|
||||
int highSlot = -1;
|
||||
|
|
@ -436,7 +442,7 @@ namespace Server.Tests.Network.Packets
|
|||
}
|
||||
|
||||
int count = Math.Max(Math.Max(highSlot + 1, account.Limit), 5);
|
||||
expectedData[pos++] = (byte)count;
|
||||
((byte)count).CopyTo(ref pos, expectedData);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
|
|
@ -452,12 +458,12 @@ namespace Server.Tests.Network.Packets
|
|||
}
|
||||
}
|
||||
|
||||
expectedData[pos++] = (byte)info.Length;
|
||||
((byte)info.Length).CopyTo(ref pos, expectedData);
|
||||
|
||||
for (int i = 0; i < info.Length; i++)
|
||||
{
|
||||
var ci = info[i];
|
||||
expectedData[pos++] = (byte)i;
|
||||
((byte)i).CopyTo(ref pos, expectedData);
|
||||
ci.City.CopyASCIIFixedTo(ref pos, 31, expectedData);
|
||||
ci.Building.CopyASCIIFixedTo(ref pos, 31, expectedData);
|
||||
}
|
||||
|
|
@ -505,9 +511,9 @@ namespace Server.Tests.Network.Packets
|
|||
Span<byte> expectedData = stackalloc byte[6 + info.Length * 40];
|
||||
|
||||
int pos = 0;
|
||||
expectedData[pos++] = 0xA8; // Packet ID
|
||||
((byte)0xA8).CopyTo(ref pos, expectedData); // Packet ID
|
||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData);
|
||||
expectedData[pos++] = 0x5D; // Unknown
|
||||
((byte)0x5D).CopyTo(ref pos, expectedData); // Unknown
|
||||
((ushort)info.Length).CopyTo(ref pos, expectedData);
|
||||
|
||||
for (int i = 0; i < info.Length; i++)
|
||||
|
|
@ -515,8 +521,8 @@ namespace Server.Tests.Network.Packets
|
|||
var si = info[i];
|
||||
((ushort)i).CopyTo(ref pos, expectedData);
|
||||
si.Name.CopyASCIIFixedTo(ref pos, 32, expectedData);
|
||||
expectedData[pos++] = (byte)si.FullPercent;
|
||||
expectedData[pos++] = (byte)si.TimeZone;
|
||||
((byte)si.FullPercent).CopyTo(ref pos, expectedData);
|
||||
((byte)si.TimeZone).CopyTo(ref pos, expectedData);
|
||||
Utility.GetAddressValue(si.Address.Address).CopyTo(ref pos, expectedData);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,178 @@
|
|||
using System;
|
||||
using Server.Network;
|
||||
using Xunit;
|
||||
|
||||
namespace Server.Tests.Network.Packets
|
||||
{
|
||||
public class EffectPackets
|
||||
{
|
||||
[Fact]
|
||||
public void TestParticleEffect()
|
||||
{
|
||||
EffectType effectType = EffectType.Moving;
|
||||
Serial serial = 0x4000;
|
||||
Serial from = 0x1000;
|
||||
Serial to = 0x2000;
|
||||
var itemId = 0x100;
|
||||
Point3D fromPoint = new Point3D(1000, 100, -10);
|
||||
Point3D toPoint = new Point3D(1500, 500, 0);
|
||||
byte speed = 3;
|
||||
byte duration = 2;
|
||||
bool direction = false;
|
||||
bool explode = false;
|
||||
int hue = 0x1024;
|
||||
int renderMode = 1;
|
||||
ushort effect = 3;
|
||||
ushort explodeEffect = 0;
|
||||
ushort explodeSound = 0;
|
||||
byte layer = 9;
|
||||
ushort unknown = 0;
|
||||
|
||||
Span<byte> data = new ParticleEffect(
|
||||
effectType, from, to, itemId,
|
||||
fromPoint, toPoint, speed, duration,
|
||||
direction, explode, hue, renderMode,
|
||||
effect, explodeEffect, explodeSound, serial,
|
||||
layer, unknown
|
||||
).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[49];
|
||||
|
||||
int pos = 0;
|
||||
((byte)0xC7).CopyTo(ref pos, expectedData); // Packet ID
|
||||
((byte)effectType).CopyTo(ref pos, expectedData);
|
||||
from.CopyTo(ref pos, expectedData);
|
||||
to.CopyTo(ref pos, expectedData);
|
||||
((ushort)itemId).CopyTo(ref pos, expectedData);
|
||||
((ushort)fromPoint.X).CopyTo(ref pos, expectedData);
|
||||
((ushort)fromPoint.Y).CopyTo(ref pos, expectedData);
|
||||
((byte)fromPoint.Z).CopyTo(ref pos, expectedData);
|
||||
((ushort)toPoint.X).CopyTo(ref pos, expectedData);
|
||||
((ushort)toPoint.Y).CopyTo(ref pos, expectedData);
|
||||
((byte)toPoint.Z).CopyTo(ref pos, expectedData);
|
||||
speed.CopyTo(ref pos, expectedData);
|
||||
duration.CopyTo(ref pos, expectedData);
|
||||
expectedData.Clear(ref pos, 2);
|
||||
direction.CopyTo(ref pos, expectedData);
|
||||
explode.CopyTo(ref pos, expectedData);
|
||||
hue.CopyTo(ref pos, expectedData);
|
||||
renderMode.CopyTo(ref pos, expectedData);
|
||||
effect.CopyTo(ref pos, expectedData);
|
||||
explodeEffect.CopyTo(ref pos, expectedData);
|
||||
explodeSound.CopyTo(ref pos, expectedData);
|
||||
serial.CopyTo(ref pos, expectedData);
|
||||
layer.CopyTo(ref pos, expectedData);
|
||||
unknown.CopyTo(ref pos, expectedData);
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestHuedEffect()
|
||||
{
|
||||
EffectType effectType = EffectType.Moving;
|
||||
Serial serial = 0x4000;
|
||||
Serial from = 0x1000;
|
||||
Serial to = 0x2000;
|
||||
var itemId = 0x100;
|
||||
Point3D fromPoint = new Point3D(1000, 100, -10);
|
||||
Point3D toPoint = new Point3D(1500, 500, 0);
|
||||
byte speed = 3;
|
||||
byte duration = 2;
|
||||
bool direction = false;
|
||||
bool explode = false;
|
||||
int hue = 0x1024;
|
||||
int renderMode = 1;
|
||||
|
||||
Span<byte> data = new HuedEffect(
|
||||
effectType, from, to, itemId,
|
||||
fromPoint, toPoint, speed, duration,
|
||||
direction, explode, hue, renderMode
|
||||
).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[36];
|
||||
|
||||
int pos = 0;
|
||||
((byte)0xC0).CopyTo(ref pos, expectedData); // Packet ID
|
||||
((byte)effectType).CopyTo(ref pos, expectedData);
|
||||
from.CopyTo(ref pos, expectedData);
|
||||
to.CopyTo(ref pos, expectedData);
|
||||
((ushort)itemId).CopyTo(ref pos, expectedData);
|
||||
((ushort)fromPoint.X).CopyTo(ref pos, expectedData);
|
||||
((ushort)fromPoint.Y).CopyTo(ref pos, expectedData);
|
||||
((byte)fromPoint.Z).CopyTo(ref pos, expectedData);
|
||||
((ushort)toPoint.X).CopyTo(ref pos, expectedData);
|
||||
((ushort)toPoint.Y).CopyTo(ref pos, expectedData);
|
||||
((byte)toPoint.Z).CopyTo(ref pos, expectedData);
|
||||
speed.CopyTo(ref pos, expectedData);
|
||||
duration.CopyTo(ref pos, expectedData);
|
||||
expectedData.Clear(ref pos, 2);
|
||||
direction.CopyTo(ref pos, expectedData);
|
||||
explode.CopyTo(ref pos, expectedData);
|
||||
hue.CopyTo(ref pos, expectedData);
|
||||
renderMode.CopyTo(ref pos, expectedData);
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestScreenEffect()
|
||||
{
|
||||
var type = ScreenEffectType.FadeOut;
|
||||
Span<byte> data = new ScreenEffect(type).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[28]
|
||||
{
|
||||
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));
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestBoltEffect()
|
||||
{
|
||||
IEntity entity = new Entity(0x1000, new Point3D(1000, 100, -10), Map.Felucca);
|
||||
var hue = 0x1024;
|
||||
Span<byte> data = new BoltEffect(entity, hue).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[36]
|
||||
{
|
||||
0xC0, // Packet ID
|
||||
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);
|
||||
pos += 6;
|
||||
((ushort)entity.X).CopyTo(ref pos, expectedData);
|
||||
((ushort)entity.Y).CopyTo(ref pos, expectedData);
|
||||
((byte)entity.Z).CopyTo(ref pos, expectedData);
|
||||
((ushort)entity.X).CopyTo(ref pos, expectedData);
|
||||
((ushort)entity.Y).CopyTo(ref pos, expectedData);
|
||||
((byte)entity.Z).CopyTo(ref pos, expectedData);
|
||||
pos += 6;
|
||||
hue.CopyTo(ref pos, expectedData);
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ namespace Server.Tests.Network.Packets
|
|||
|
||||
int pos = 0;
|
||||
|
||||
expectedData[pos++] = 0xBF; // Packet ID
|
||||
((byte)0xBF).CopyTo(ref pos, expectedData); // Packet ID
|
||||
((ushort)length).CopyTo(ref pos, expectedData); // Length
|
||||
((ushort)0x10).CopyTo(ref pos, expectedData); // Subcommand
|
||||
item.Serial.CopyTo(ref pos, expectedData);
|
||||
|
|
@ -46,7 +46,6 @@ namespace Server.Tests.Network.Packets
|
|||
{
|
||||
var name = info.Crafter.Name ?? "";
|
||||
(-3).CopyTo(ref pos, expectedData);
|
||||
((ushort)name.Length).CopyTo(ref pos, expectedData);
|
||||
name.CopyASCIITo(ref pos, expectedData);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,244 @@
|
|||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
using Xunit;
|
||||
|
||||
namespace Server.Tests.Network.Packets
|
||||
{
|
||||
public class GumpPacketTests
|
||||
{
|
||||
[Fact]
|
||||
public void TestCloseGump()
|
||||
{
|
||||
var typeId = 100;
|
||||
var buttonId = 10;
|
||||
|
||||
Span<byte> data = new CloseGump(typeId, buttonId).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[]
|
||||
{
|
||||
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));
|
||||
buttonId.CopyTo(expectedData.Slice(9, 4));
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestDisplaySignGump()
|
||||
{
|
||||
Serial gumpSerial = 0x1000;
|
||||
var gumpId = 100;
|
||||
var unknownString = "This is an unknown string";
|
||||
var caption = "This is a caption";
|
||||
|
||||
Span<byte> data = new DisplaySignGump(gumpSerial, gumpId, unknownString, caption).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[15 + unknownString.Length + caption.Length];
|
||||
|
||||
int pos = 0;
|
||||
((byte)0x8B).CopyTo(ref pos, expectedData);
|
||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData);
|
||||
gumpSerial.CopyTo(ref pos, expectedData);
|
||||
((ushort)gumpId).CopyTo(ref pos, expectedData);
|
||||
unknownString.CopyASCIINullTo(ref pos, expectedData);
|
||||
caption.CopyASCIINullTo(ref pos, expectedData);
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestFastGumpPacket()
|
||||
{
|
||||
NetState ns = new NetState(new AccountPacketTests.TestConnectionContext
|
||||
{
|
||||
RemoteEndPoint = IPEndPoint.Parse("127.0.0.1"),
|
||||
});
|
||||
|
||||
var gump = new ResurrectGump(2);
|
||||
|
||||
Span<byte> data = gump.Compile(ns).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[0x1000];
|
||||
|
||||
int pos = 0;
|
||||
|
||||
expectedData[pos++] = 0xB0; // Packet ID
|
||||
pos += 2; // Length
|
||||
|
||||
gump.Serial.CopyTo(ref pos, expectedData);
|
||||
gump.TypeID.CopyTo(ref pos, expectedData);
|
||||
gump.X.CopyTo(ref pos, expectedData);
|
||||
gump.Y.CopyTo(ref pos, expectedData);
|
||||
pos += 2; // Layout Length
|
||||
|
||||
int layoutLength = 0;
|
||||
|
||||
if (!gump.Draggable)
|
||||
{
|
||||
GumpUtilities.NoMoveBuffer.CopyTo(ref pos, expectedData);
|
||||
layoutLength += GumpUtilities.NoMove.Length;
|
||||
}
|
||||
|
||||
if (!gump.Closable)
|
||||
{
|
||||
GumpUtilities.NoCloseBuffer.CopyTo(ref pos, expectedData);
|
||||
layoutLength += GumpUtilities.NoClose.Length;
|
||||
}
|
||||
|
||||
if (!gump.Disposable)
|
||||
{
|
||||
GumpUtilities.NoDisposeBuffer.CopyTo(ref pos, expectedData);
|
||||
layoutLength += GumpUtilities.NoDispose.Length;
|
||||
}
|
||||
|
||||
if (!gump.Resizable)
|
||||
{
|
||||
GumpUtilities.NoResizeBuffer.CopyTo(ref pos, expectedData);
|
||||
layoutLength += GumpUtilities.NoResize.Length;
|
||||
}
|
||||
|
||||
foreach (var entry in gump.Entries)
|
||||
{
|
||||
var str = entry.Compile(ns);
|
||||
str.CopyRawASCIITo(ref pos, expectedData);
|
||||
layoutLength += str.Length; // ASCII so 1:1
|
||||
}
|
||||
|
||||
((ushort)layoutLength).CopyTo(expectedData.Slice(19, 2));
|
||||
((ushort)gump.Strings.Count).CopyTo(ref pos, expectedData);
|
||||
|
||||
for (var i = 0; i < gump.Strings.Count; ++i)
|
||||
(gump.Strings[i] ?? "").CopyUnicodeBigEndianTo(ref pos, expectedData);
|
||||
|
||||
((ushort)pos).CopyTo(expectedData.Slice(1, 2));
|
||||
|
||||
expectedData = expectedData.Slice(0, pos);
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestPackedGumpPacket()
|
||||
{
|
||||
NetState ns = new NetState(new AccountPacketTests.TestConnectionContext
|
||||
{
|
||||
RemoteEndPoint = IPEndPoint.Parse("127.0.0.1"),
|
||||
});
|
||||
|
||||
ns.ProtocolChanges = ProtocolChanges.Unpack;
|
||||
|
||||
var gump = new ResurrectGump(2);
|
||||
|
||||
Span<byte> data = gump.Compile(ns).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[0x1000];
|
||||
|
||||
int pos = 0;
|
||||
|
||||
expectedData[pos++] = 0xDD; // Packet ID
|
||||
pos += 2; // Length
|
||||
|
||||
gump.Serial.CopyTo(ref pos, expectedData);
|
||||
gump.TypeID.CopyTo(ref pos, expectedData);
|
||||
gump.X.CopyTo(ref pos, expectedData);
|
||||
gump.Y.CopyTo(ref pos, expectedData);
|
||||
|
||||
var layoutList = new List<string>();
|
||||
int bufferLength = 1; // Null terminated
|
||||
|
||||
if (!gump.Draggable)
|
||||
{
|
||||
layoutList.Add(GumpUtilities.NoMove);
|
||||
bufferLength += GumpUtilities.NoMove.Length;
|
||||
}
|
||||
|
||||
if (!gump.Closable)
|
||||
{
|
||||
layoutList.Add(GumpUtilities.NoClose);
|
||||
bufferLength += GumpUtilities.NoClose.Length;
|
||||
}
|
||||
|
||||
if (!gump.Disposable)
|
||||
{
|
||||
layoutList.Add(GumpUtilities.NoDispose);
|
||||
bufferLength += GumpUtilities.NoDispose.Length;
|
||||
}
|
||||
|
||||
if (!gump.Resizable)
|
||||
{
|
||||
layoutList.Add(GumpUtilities.NoResize);
|
||||
bufferLength += GumpUtilities.NoResize.Length;
|
||||
}
|
||||
|
||||
foreach (var entry in gump.Entries)
|
||||
{
|
||||
var str = entry.Compile(ns);
|
||||
bufferLength += str.Length;
|
||||
layoutList.Add(str);
|
||||
}
|
||||
|
||||
IMemoryOwner<byte> memOwner = SlabMemoryPool.Shared.Rent(bufferLength);
|
||||
|
||||
Span<byte> buffer = memOwner.Memory.Span;
|
||||
int bufferPos = 0;
|
||||
|
||||
foreach (var layout in layoutList)
|
||||
layout.CopyRawASCIITo(ref bufferPos, buffer);
|
||||
|
||||
pos += GumpUtilities.WritePacked(buffer.Slice(0, bufferPos + 1), expectedData.Slice(pos));
|
||||
memOwner.Dispose();
|
||||
|
||||
gump.Strings.Count.CopyTo(ref pos, expectedData);
|
||||
bufferLength = gump.Strings.Sum(str => 2 + str.Length * 2);
|
||||
memOwner = SlabMemoryPool.Shared.Rent(bufferLength);
|
||||
buffer = memOwner.Memory.Span;
|
||||
bufferPos = 0;
|
||||
|
||||
foreach (var str in gump.Strings)
|
||||
str.CopyUnicodeBigEndianTo(ref bufferPos, buffer);
|
||||
|
||||
pos += GumpUtilities.WritePacked(buffer.Slice(0, bufferPos), expectedData.Slice(pos));
|
||||
|
||||
// Length
|
||||
((ushort)pos).CopyTo(expectedData.Slice(1, 2));
|
||||
expectedData = expectedData.Slice(0, pos);
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
}
|
||||
|
||||
public class ResurrectGump : Gump
|
||||
{
|
||||
public ResurrectGump(int msg) : base(100, 0)
|
||||
{
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(0, 0, 400, 350, 2600);
|
||||
|
||||
AddHtmlLocalized(0, 20, 400, 35, 1011022); // <center>Resurrection</center>
|
||||
|
||||
/* It is possible for you to be resurrected here by this healer. Do you wish to try?<br>
|
||||
* CONTINUE - You chose to try to come back to life now.<br>
|
||||
* CANCEL - You prefer to remain a ghost for now.
|
||||
*/
|
||||
AddHtmlLocalized(50, 55, 300, 140, 1011023 + msg, true, true);
|
||||
|
||||
AddButton(200, 227, 4005, 4007, 0);
|
||||
AddHtmlLocalized(235, 230, 110, 35, 1011012); // CANCEL
|
||||
|
||||
AddButton(65, 227, 4005, 4007, 1);
|
||||
AddHtmlLocalized(100, 230, 110, 35, 1011011); // CONTINUE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,388 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Xunit;
|
||||
|
||||
namespace Server.Tests.Network.Packets
|
||||
{
|
||||
public class ItemPacketTests
|
||||
{
|
||||
[Fact]
|
||||
public void TestWorldItemPacket()
|
||||
{
|
||||
Serial serial = 0x1000;
|
||||
var itemId = 1;
|
||||
|
||||
// Move to fixture
|
||||
TileData.ItemTable[itemId] = new ItemData(
|
||||
"Test Item Data", TileFlag.Generic, 1, 1, 1, 1, 1
|
||||
);
|
||||
|
||||
Item item = new Item(serial)
|
||||
{
|
||||
ItemID = itemId,
|
||||
Hue = 0x1024,
|
||||
Amount = 10,
|
||||
Location = new Point3D(1000, 100, -10),
|
||||
Direction = Direction.Left
|
||||
};
|
||||
|
||||
Span<byte> data = new WorldItem(item).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[20]; // Max size
|
||||
int pos = 0;
|
||||
|
||||
((byte)0x1A).CopyTo(ref pos, expectedData);
|
||||
pos += 2; // Length
|
||||
|
||||
if (item.Amount != 0)
|
||||
(serial | 0x80000000).CopyTo(ref pos, expectedData);
|
||||
else
|
||||
(serial & 0x7FFFFFFF).CopyTo(ref pos, expectedData);
|
||||
|
||||
if (item is BaseMulti)
|
||||
((ushort)(item.ItemID | 0x4000)).CopyTo(ref pos, expectedData);
|
||||
else
|
||||
((ushort)item.ItemID).CopyTo(ref pos, expectedData);
|
||||
|
||||
if (item.Amount != 0)
|
||||
((ushort)item.Amount).CopyTo(ref pos, expectedData);
|
||||
|
||||
byte direction = (byte)item.Direction;
|
||||
ushort x = (ushort)(item.X & 0x7FFF);
|
||||
|
||||
if (direction != 0)
|
||||
x |= 0x8000;
|
||||
|
||||
x.CopyTo(ref pos, expectedData);
|
||||
|
||||
int hue = item.Hue;
|
||||
int flags = item.GetPacketFlags();
|
||||
ushort y = (ushort)(item.Y & 0x3FFF);
|
||||
|
||||
if (hue != 0) y |= 0x8000;
|
||||
if (flags != 0) y |= 0x4000;
|
||||
|
||||
y.CopyTo(ref pos, expectedData);
|
||||
|
||||
if (direction != 0)
|
||||
direction.CopyTo(ref pos, expectedData);
|
||||
|
||||
((byte)item.Z).CopyTo(ref pos, expectedData);
|
||||
|
||||
if (hue != 0)
|
||||
((ushort)hue).CopyTo(ref pos, expectedData);
|
||||
|
||||
if (flags != 0)
|
||||
((byte)flags).CopyTo(ref pos, expectedData);
|
||||
|
||||
// Length
|
||||
((ushort)pos).CopyTo(expectedData.Slice(1, 2));
|
||||
|
||||
// Slice the data to match in size
|
||||
data = data.Slice(0, pos);
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestWorldItemSAPacket()
|
||||
{
|
||||
Serial serial = 0x1000;
|
||||
ushort itemId = 1;
|
||||
|
||||
// Move to fixture
|
||||
TileData.ItemTable[itemId] = new ItemData(
|
||||
"Test Item Data", TileFlag.Generic, 1, 1, 1, 1, 1
|
||||
);
|
||||
|
||||
Item item = new Item(serial)
|
||||
{
|
||||
ItemID = itemId,
|
||||
Hue = 0x1024,
|
||||
Amount = 10,
|
||||
Location = new Point3D(1000, 100, -10)
|
||||
};
|
||||
|
||||
var loc = item.Location;
|
||||
var isMulti = item is BaseMulti;
|
||||
|
||||
Span<byte> data = new WorldItemSA(item).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[]
|
||||
{
|
||||
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));
|
||||
((ushort)(itemId & (isMulti ? 0x3FFF : 0xFFFF))).CopyTo(expectedData.Slice(8, 2));
|
||||
|
||||
ushort amount = (ushort)item.Amount;
|
||||
amount.CopyTo(expectedData.Slice(11, 2));
|
||||
amount.CopyTo(expectedData.Slice(13, 2));
|
||||
|
||||
((ushort)loc.X).CopyTo(expectedData.Slice(15, 2));
|
||||
((ushort)loc.Y).CopyTo(expectedData.Slice(17, 2));
|
||||
((ushort)item.Hue).CopyTo(expectedData.Slice(21, 2));
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestWorldItemHSPacket()
|
||||
{
|
||||
Serial serial = 0x1000;
|
||||
var itemId = 1;
|
||||
|
||||
// Move to fixture
|
||||
TileData.ItemTable[itemId] = new ItemData(
|
||||
"Test Item Data", TileFlag.Generic, 1, 1, 1, 1, 1
|
||||
);
|
||||
|
||||
Item item = new Item(serial)
|
||||
{
|
||||
ItemID = itemId,
|
||||
Hue = 0x1024,
|
||||
Amount = 10,
|
||||
Location = new Point3D(1000, 100, -10)
|
||||
};
|
||||
|
||||
var loc = item.Location;
|
||||
var isMulti = item is BaseMulti;
|
||||
|
||||
Span<byte> data = new WorldItemHS(item).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[]
|
||||
{
|
||||
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));
|
||||
((ushort)(itemId & (isMulti ? 0x3FFF : 0xFFFF))).CopyTo(expectedData.Slice(8, 2));
|
||||
|
||||
ushort amount = (ushort)item.Amount;
|
||||
amount.CopyTo(expectedData.Slice(11, 2));
|
||||
amount.CopyTo(expectedData.Slice(13, 2));
|
||||
|
||||
((ushort)loc.X).CopyTo(expectedData.Slice(15, 2));
|
||||
((ushort)loc.Y).CopyTo(expectedData.Slice(17, 2));
|
||||
((ushort)item.Hue).CopyTo(expectedData.Slice(21, 2));
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestContainerDisplay()
|
||||
{
|
||||
Serial serial = 0x1000;
|
||||
ushort gumpId = 100;
|
||||
|
||||
Span<byte> data = new ContainerDisplay(serial, gumpId).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[]
|
||||
{
|
||||
0x24, // Packet ID
|
||||
0x00, 0x00, 0x00, 0x00, // Serial
|
||||
0x00, 0x00 // Gump ID
|
||||
};
|
||||
|
||||
serial.CopyTo(expectedData.Slice(1, 4));
|
||||
gumpId.CopyTo(expectedData.Slice(5, 2));
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestContainerDisplayHS()
|
||||
{
|
||||
Serial serial = 0x1000;
|
||||
ushort gumpId = 100;
|
||||
|
||||
Span<byte> data = new ContainerDisplayHS(serial, gumpId).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[]
|
||||
{
|
||||
0x24, // Packet ID
|
||||
0x00, 0x00, 0x00, 0x00, // Serial
|
||||
0x00, 0x00, // Gump ID
|
||||
0x00, 0x7D // Max Items?
|
||||
};
|
||||
|
||||
serial.CopyTo(expectedData.Slice(1, 4));
|
||||
gumpId.CopyTo(expectedData.Slice(5, 2));
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestDisplaySpellbook()
|
||||
{
|
||||
Serial serial = 0x1000;
|
||||
|
||||
Span<byte> data = new DisplaySpellbook(serial).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[]
|
||||
{
|
||||
0x24, // Packet ID
|
||||
0x00, 0x00, 0x00, 0x00, // Serial
|
||||
0xFF, 0xFF // Gump ID
|
||||
};
|
||||
|
||||
serial.CopyTo(expectedData.Slice(1, 4));
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestDisplaySpellbookHS()
|
||||
{
|
||||
Serial serial = 0x1000;
|
||||
|
||||
Span<byte> data = new DisplaySpellbookHS(serial).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[]
|
||||
{
|
||||
0x24, // Packet ID
|
||||
0x00, 0x00, 0x00, 0x00, // Serial
|
||||
0xFF, 0xFF, // Gump ID
|
||||
0x00, 0x7D // Max Items?
|
||||
};
|
||||
|
||||
serial.CopyTo(expectedData.Slice(1, 4));
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestNewSpellbookContent()
|
||||
{
|
||||
Serial serial = 0x1000;
|
||||
ushort graphic = 100;
|
||||
ushort offset = 10;
|
||||
ulong content = 0x123456789ABCDEF0;
|
||||
|
||||
Span<byte> data = new NewSpellbookContent(serial, graphic, offset, content).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[]
|
||||
{
|
||||
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));
|
||||
graphic.CopyTo(expectedData.Slice(11, 2));
|
||||
offset.CopyTo(expectedData.Slice(13, 2));
|
||||
content.CopyToLE(expectedData.Slice(15, 8));
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSpellbookContent()
|
||||
{
|
||||
Serial serial = 0x1000;
|
||||
ushort offset = 10;
|
||||
ulong content = 0x123456789ABCDEF0;
|
||||
|
||||
Span<byte> data = new SpellbookContent(serial, offset, content).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[5 + 64 * 19]; // Max size
|
||||
int pos = 0;
|
||||
|
||||
((byte)0x3C).CopyTo(ref pos, expectedData);
|
||||
pos += 4; // Length + spell count
|
||||
|
||||
ushort count = 0;
|
||||
|
||||
for (var i = 0; i < 64; i++)
|
||||
if ((content & (1ul << i)) != 0)
|
||||
{
|
||||
(0x7FFFFFFF - i).CopyTo(ref pos, expectedData);
|
||||
expectedData.Clear(ref pos, 3);
|
||||
((ushort)(i + offset)).CopyTo(ref pos, expectedData);
|
||||
expectedData.Clear(ref pos, 4); // X, Y
|
||||
serial.CopyTo(ref pos, expectedData);
|
||||
expectedData.Clear(ref pos, 2);
|
||||
count++;
|
||||
}
|
||||
|
||||
((ushort)pos).CopyTo(expectedData.Slice(1, 2));
|
||||
count.CopyTo(expectedData.Slice(3, 2));
|
||||
|
||||
expectedData = expectedData.Slice(0, pos);
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSpellbookContent6017()
|
||||
{
|
||||
Serial serial = 0x1000;
|
||||
ushort offset = 10;
|
||||
ulong content = 0x123456789ABCDEF0;
|
||||
|
||||
Span<byte> data = new SpellbookContent6017(serial, offset, content).Compile();
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[5 + 64 * 19]; // Max size
|
||||
int pos = 0;
|
||||
|
||||
((byte)0x3C).CopyTo(ref pos, expectedData);
|
||||
pos += 4; // Length + spell count
|
||||
|
||||
ushort count = 0;
|
||||
|
||||
for (var i = 0; i < 64; i++)
|
||||
if ((content & (1ul << i)) != 0)
|
||||
{
|
||||
(0x7FFFFFFF - i).CopyTo(ref pos, expectedData);
|
||||
expectedData.Clear(ref pos, 3);
|
||||
((ushort)(i + offset)).CopyTo(ref pos, expectedData);
|
||||
expectedData.Clear(ref pos, 5); // X, Y, Grid Location
|
||||
serial.CopyTo(ref pos, expectedData);
|
||||
expectedData.Clear(ref pos, 2);
|
||||
count++;
|
||||
}
|
||||
|
||||
((ushort)pos).CopyTo(expectedData.Slice(1, 2));
|
||||
count.CopyTo(expectedData.Slice(3, 2));
|
||||
|
||||
expectedData = expectedData.Slice(0, pos);
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -51,22 +51,18 @@ namespace Server.Tests.Network.Packets
|
|||
|
||||
int pos = 0;
|
||||
|
||||
expectedData[pos++] = 0x7C; // Packet ID
|
||||
((byte)0x7C).CopyTo(ref pos, expectedData); // Packet ID
|
||||
((ushort)length).CopyTo(ref pos, expectedData);
|
||||
menu.Serial.CopyTo(ref pos, expectedData);
|
||||
pos += 2; // ((ushort)0x00).CopyTo(ref pos, expectedData);
|
||||
expectedData[pos++] = (byte)questionLength;
|
||||
question.CopyASCIITo(ref pos, expectedData);
|
||||
expectedData[pos++] = (byte)menu.Entries.Length;
|
||||
((ushort)0x00).CopyTo(ref pos, expectedData);
|
||||
question.CopySmallASCIITo(ref pos, expectedData);
|
||||
((byte)menu.Entries.Length).CopyTo(ref pos, expectedData);
|
||||
for (int i = 0; i < menu.Entries.Length; i++)
|
||||
{
|
||||
var entry = menu.Entries[i];
|
||||
((ushort)entry.ItemID).CopyTo(ref pos, expectedData);
|
||||
((ushort)entry.Hue).CopyTo(ref pos, expectedData);
|
||||
string name = entry.Name?.Trim() ?? "";
|
||||
|
||||
expectedData[pos++] = (byte)name.Length;
|
||||
name.CopyASCIITo(ref pos, expectedData);
|
||||
(entry.Name?.Trim() ?? "").CopySmallASCIITo(ref pos, expectedData);
|
||||
}
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
|
|
@ -96,19 +92,16 @@ namespace Server.Tests.Network.Packets
|
|||
|
||||
int pos = 0;
|
||||
|
||||
expectedData[pos++] = 0x7C; // Packet ID
|
||||
((byte)0x7C).CopyTo(ref pos, expectedData); // Packet ID
|
||||
((ushort)length).CopyTo(ref pos, expectedData);
|
||||
menu.Serial.CopyTo(ref pos, expectedData);
|
||||
pos += 2; // ((ushort)0x00).CopyTo(ref pos, expectedData);
|
||||
expectedData[pos++] = (byte)questionLength;
|
||||
question?.CopyASCIITo(ref pos, expectedData);
|
||||
expectedData[pos++] = (byte)menu.Answers.Length;
|
||||
((ushort)0x00).CopyTo(ref pos, expectedData);
|
||||
question.CopySmallASCIITo(ref pos, expectedData);
|
||||
((byte)menu.Answers.Length).CopyTo(ref pos, expectedData);
|
||||
for (int i = 0; i < menu.Answers.Length; i++)
|
||||
{
|
||||
pos += 4; // 0x0.CopyTo(ref pos, expectedData);
|
||||
var answer = menu.Answers[i]?.Trim() ?? "";
|
||||
expectedData[pos++] = (byte)answer.Length;
|
||||
answer.CopyASCIITo(ref pos, expectedData);
|
||||
0x0.CopyTo(ref pos, expectedData);
|
||||
(menu.Answers[i]?.Trim() ?? "").CopySmallASCIITo(ref pos, expectedData);
|
||||
}
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
|
|
@ -130,14 +123,14 @@ namespace Server.Tests.Network.Packets
|
|||
Span<byte> expectedData = stackalloc byte[length];
|
||||
|
||||
int pos = 0;
|
||||
expectedData[pos++] = 0xBF; // Packet ID
|
||||
((byte)0xBF).CopyTo(ref pos, expectedData); // Packet ID
|
||||
((ushort)length).CopyTo(ref pos, expectedData); // Length
|
||||
((ushort)0x14).CopyTo(ref pos, expectedData); // Command
|
||||
((ushort)0x02).CopyTo(ref pos, expectedData); // Subcommand
|
||||
menu.Target.Serial.CopyTo(ref pos, expectedData);
|
||||
var entries = menu.Entries;
|
||||
|
||||
expectedData[pos++] = (byte)entries.Length;
|
||||
((byte)entries.Length).CopyTo(ref pos, expectedData);
|
||||
|
||||
for (int i = 0; i < entries.Length; i++)
|
||||
{
|
||||
|
|
@ -177,14 +170,14 @@ namespace Server.Tests.Network.Packets
|
|||
Span<byte> expectedData = stackalloc byte[length];
|
||||
|
||||
int pos = 0;
|
||||
expectedData[pos++] = 0xBF; // Packet ID
|
||||
((byte)0xBF).CopyTo(ref pos, expectedData); // Packet ID
|
||||
((ushort)length).CopyTo(ref pos, expectedData); // Length
|
||||
((ushort)0x14).CopyTo(ref pos, expectedData); // Command
|
||||
((ushort)0x01).CopyTo(ref pos, expectedData); // Subcommand
|
||||
menu.Target.Serial.CopyTo(ref pos, expectedData);
|
||||
var entries = menu.Entries;
|
||||
|
||||
expectedData[pos++] = (byte)entries.Length;
|
||||
((byte)entries.Length).CopyTo(ref pos, expectedData);
|
||||
|
||||
for (int i = 0; i < entries.Length; i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ namespace Server.Tests.Network.Packets
|
|||
int pos = 1;
|
||||
itemInCont.Serial.CopyTo(ref pos, expectedData);
|
||||
((short)itemInCont.ItemID).CopyTo(ref pos, expectedData);
|
||||
pos++; // expectedData[pos++] = 0x0;
|
||||
pos++;
|
||||
((short)itemInCont.Amount).CopyTo(ref pos, expectedData);
|
||||
((short)itemInCont.X).CopyTo(ref pos, expectedData);
|
||||
((short)itemInCont.Y).CopyTo(ref pos, expectedData);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace Server.Tests.Network.Packets
|
|||
|
||||
int pos = 0;
|
||||
|
||||
expectedData[pos++] = 0x3C; // Packet ID
|
||||
((byte)0x3C).CopyTo(ref pos, expectedData); // Packet ID
|
||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
||||
((ushort)buyStates.Count).CopyTo(ref pos, expectedData); // Count
|
||||
|
||||
|
|
@ -40,8 +40,8 @@ namespace Server.Tests.Network.Packets
|
|||
pos++; // ItemID Offset
|
||||
((ushort)buyState.Amount).CopyTo(ref pos, expectedData);
|
||||
((ushort)(i + 1)).CopyTo(ref pos, expectedData); // X
|
||||
expectedData[pos++] = 0;
|
||||
expectedData[pos++] = 1; // Y
|
||||
((byte)0).CopyTo(ref pos, expectedData);
|
||||
((byte)1).CopyTo(ref pos, expectedData); // Y
|
||||
buyState.ContainerSerial.CopyTo(ref pos, expectedData);
|
||||
((ushort)buyState.Hue).CopyTo(ref pos, expectedData);
|
||||
}
|
||||
|
|
@ -67,7 +67,7 @@ namespace Server.Tests.Network.Packets
|
|||
|
||||
int pos = 0;
|
||||
|
||||
expectedData[pos++] = 0x3C; // Packet ID
|
||||
((byte)0x3C).CopyTo(ref pos, expectedData); // Packet ID
|
||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
||||
((ushort)buyStates.Count).CopyTo(ref pos, expectedData); // Count
|
||||
|
||||
|
|
@ -80,9 +80,9 @@ namespace Server.Tests.Network.Packets
|
|||
pos++; // ItemID Offset
|
||||
((ushort)buyState.Amount).CopyTo(ref pos, expectedData);
|
||||
((ushort)(i + 1)).CopyTo(ref pos, expectedData); // X
|
||||
expectedData[pos++] = 0;
|
||||
expectedData[pos++] = 1; // Y
|
||||
expectedData[pos++] = 0; // Grid Location
|
||||
((byte)0).CopyTo(ref pos, expectedData);
|
||||
((byte)1).CopyTo(ref pos, expectedData); // Y
|
||||
((byte)0).CopyTo(ref pos, expectedData); // Grid Location
|
||||
buyState.ContainerSerial.CopyTo(ref pos, expectedData);
|
||||
((ushort)buyState.Hue).CopyTo(ref pos, expectedData);
|
||||
}
|
||||
|
|
@ -148,25 +148,22 @@ namespace Server.Tests.Network.Packets
|
|||
|
||||
Span<byte> data = new VendorBuyList(vendor, buyStates).Compile();
|
||||
|
||||
int length = 8 + 5 * 3 + buyStates.Sum(state => state.Description.Length + 1);
|
||||
int length = 8 + buyStates.Sum(state => 6 + state.Description.Length);
|
||||
|
||||
Span<byte> expectedData = stackalloc byte[length];
|
||||
|
||||
int pos = 0;
|
||||
|
||||
expectedData[pos++] = 0x74; // Packet ID
|
||||
((byte)0x74).CopyTo(ref pos, expectedData); // Packet ID
|
||||
((ushort)expectedData.Length).CopyTo(ref pos, expectedData); // Length
|
||||
Serial.MinusOne.CopyTo(ref pos, expectedData); // Vendor Buy Pack Serial or -1
|
||||
expectedData[pos++] = (byte)buyStates.Count;
|
||||
((byte)buyStates.Count).CopyTo(ref pos, expectedData);
|
||||
|
||||
for (int i = 0; i < buyStates.Count; i++)
|
||||
{
|
||||
BuyItemState state = buyStates[i];
|
||||
state.Price.CopyTo(ref pos, expectedData);
|
||||
string desc = state.Description ?? "";
|
||||
expectedData[pos++] = (byte)(desc.Length + 1);
|
||||
desc.CopyASCIITo(ref pos, expectedData);
|
||||
pos++;
|
||||
(state.Description ?? "").CopySmallASCIINullTo(ref pos, expectedData);
|
||||
}
|
||||
|
||||
AssertThat.Equal(data, expectedData);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ namespace Server.Tests.Network.Packets
|
|||
Span<byte> expectedData = stackalloc byte[length];
|
||||
|
||||
int pos = 0;
|
||||
expectedData[pos++] = 0x9E; // Packet ID
|
||||
((byte)0x9E).CopyTo(ref pos, expectedData); // Packet ID
|
||||
((ushort)length).CopyTo(ref pos, expectedData);
|
||||
vendor.Serial.CopyTo(ref pos, expectedData);
|
||||
((ushort)sellStates.Count).CopyTo(ref pos, expectedData);
|
||||
|
|
@ -48,7 +48,6 @@ namespace Server.Tests.Network.Packets
|
|||
((ushort)state.Item.Amount).CopyTo(ref pos, expectedData);
|
||||
((ushort)state.Price).CopyTo(ref pos, expectedData);
|
||||
string name = string.IsNullOrWhiteSpace(state.Item.Name) ? state.Name ?? "" : state.Item.Name.Trim();
|
||||
((ushort)name.Length).CopyTo(ref pos, expectedData);
|
||||
name.CopyASCIITo(ref pos, expectedData);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,12 @@ namespace Server.Tests.Network.Packets
|
|||
public static Span<byte> Compile(this Packet p) =>
|
||||
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);
|
||||
|
||||
|
|
@ -28,12 +34,39 @@ namespace Server.Tests.Network.Packets
|
|||
public static void CopyTo(this int number, Span<byte> bytes) => BinaryPrimitives.WriteInt32BigEndian(bytes, number);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void CopyASCIITo(this string str, Span<byte> bytes) => Encoding.ASCII.GetBytes(str.AsSpan(), bytes);
|
||||
public static void CopyTo(this ulong number, Span<byte> bytes) => BinaryPrimitives.WriteUInt64BigEndian(bytes, number);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void CopyASCIITo(this string str, int max, Span<byte> bytes) => Encoding.ASCII.GetBytes(str.AsSpan(0, Math.Min(str.Length, max)), bytes);
|
||||
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)
|
||||
{
|
||||
|
|
@ -70,17 +103,97 @@ namespace Server.Tests.Network.Packets
|
|||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void CopyASCIITo(this string str, ref int pos, Span<byte> bytes)
|
||||
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.AsSpan(), bytes.Slice(pos));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void CopyASCIITo(this string str, ref int pos, int max, Span<byte> bytes)
|
||||
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.AsSpan(), 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.AsSpan(), 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)
|
||||
{
|
||||
|
|
@ -93,6 +206,38 @@ namespace Server.Tests.Network.Packets
|
|||
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.AsSpan(), bytes.Slice(pos + 2));
|
||||
}
|
||||
|
||||
[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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.2" />
|
||||
<PackageReference Include="coverlet.collector" Version="1.3.0" />
|
||||
<PackageReference Include="Zlib.Bindings" Version="1.1.0" />
|
||||
<ProjectReference Include="..\Server\Server.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -35,6 +35,12 @@
|
|||
"resolved": "2.4.2",
|
||||
"contentHash": "Trt9multph2KE3U0p9oBt0k4Fq6lUv4btUcONaQEeuFnMCak2k/b7PAArbLtMFW7HO1jxlBHUgIPKEqci3Y1dg=="
|
||||
},
|
||||
"Zlib.Bindings": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.1.0, )",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
},
|
||||
"Libuv": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.10.0",
|
||||
|
|
@ -1181,11 +1187,6 @@
|
|||
"xunit.extensibility.core": "[2.4.1]"
|
||||
}
|
||||
},
|
||||
"Zlib.Bindings": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
},
|
||||
"ModernUO": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
|
|
@ -1198,6 +1199,12 @@
|
|||
}
|
||||
},
|
||||
".NETCoreApp,Version=v3.1/centos.7-x64": {
|
||||
"Zlib.Bindings": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.1.0, )",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
},
|
||||
"Libuv": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.10.0",
|
||||
|
|
@ -2109,14 +2116,15 @@
|
|||
"System.Runtime": "4.3.0",
|
||||
"runtime.any.System.Threading.Timer": "4.3.0"
|
||||
}
|
||||
},
|
||||
"Zlib.Bindings": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
}
|
||||
},
|
||||
".NETCoreApp,Version=v3.1/centos.8-x64": {
|
||||
"Zlib.Bindings": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.1.0, )",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
},
|
||||
"Libuv": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.10.0",
|
||||
|
|
@ -2983,14 +2991,15 @@
|
|||
"System.Runtime": "4.3.0",
|
||||
"runtime.any.System.Threading.Timer": "4.3.0"
|
||||
}
|
||||
},
|
||||
"Zlib.Bindings": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
}
|
||||
},
|
||||
".NETCoreApp,Version=v3.1/debian.10-x64": {
|
||||
"Zlib.Bindings": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.1.0, )",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
},
|
||||
"Libuv": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.10.0",
|
||||
|
|
@ -3857,14 +3866,15 @@
|
|||
"System.Runtime": "4.3.0",
|
||||
"runtime.any.System.Threading.Timer": "4.3.0"
|
||||
}
|
||||
},
|
||||
"Zlib.Bindings": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
}
|
||||
},
|
||||
".NETCoreApp,Version=v3.1/debian.9-x64": {
|
||||
"Zlib.Bindings": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.1.0, )",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
},
|
||||
"Libuv": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.10.0",
|
||||
|
|
@ -4731,14 +4741,15 @@
|
|||
"System.Runtime": "4.3.0",
|
||||
"runtime.any.System.Threading.Timer": "4.3.0"
|
||||
}
|
||||
},
|
||||
"Zlib.Bindings": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
}
|
||||
},
|
||||
".NETCoreApp,Version=v3.1/osx-x64": {
|
||||
"Zlib.Bindings": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.1.0, )",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
},
|
||||
"Libuv": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.10.0",
|
||||
|
|
@ -5605,14 +5616,15 @@
|
|||
"System.Runtime": "4.3.0",
|
||||
"runtime.any.System.Threading.Timer": "4.3.0"
|
||||
}
|
||||
},
|
||||
"Zlib.Bindings": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
}
|
||||
},
|
||||
".NETCoreApp,Version=v3.1/ubuntu.16.04-x64": {
|
||||
"Zlib.Bindings": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.1.0, )",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
},
|
||||
"Libuv": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.10.0",
|
||||
|
|
@ -6524,14 +6536,15 @@
|
|||
"System.Runtime": "4.3.0",
|
||||
"runtime.any.System.Threading.Timer": "4.3.0"
|
||||
}
|
||||
},
|
||||
"Zlib.Bindings": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
}
|
||||
},
|
||||
".NETCoreApp,Version=v3.1/ubuntu.18.04-x64": {
|
||||
"Zlib.Bindings": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.1.0, )",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
},
|
||||
"Libuv": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.10.0",
|
||||
|
|
@ -7398,14 +7411,15 @@
|
|||
"System.Runtime": "4.3.0",
|
||||
"runtime.any.System.Threading.Timer": "4.3.0"
|
||||
}
|
||||
},
|
||||
"Zlib.Bindings": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
}
|
||||
},
|
||||
".NETCoreApp,Version=v3.1/win-x64": {
|
||||
"Zlib.Bindings": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.1.0, )",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
},
|
||||
"Libuv": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.10.0",
|
||||
|
|
@ -8255,11 +8269,6 @@
|
|||
"System.Runtime": "4.3.0",
|
||||
"runtime.any.System.Threading.Timer": "4.3.0"
|
||||
}
|
||||
},
|
||||
"Zlib.Bindings": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "hLmHUTlZR3rnJ95FboiyJdLR8MJbfHdmapnRZHWLvkxB48jDgRBBJG1w5NYRiNBteVY4uksacXM7/V8nu1byBw=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ namespace Server.Gumps
|
|||
private static readonly byte[] m_NoDispose = StringToBuffer("{ nodispose }");
|
||||
private static readonly byte[] m_NoResize = StringToBuffer("{ noresize }");
|
||||
|
||||
private readonly List<string> m_Strings;
|
||||
public List<string> Strings { get; }
|
||||
|
||||
internal int m_TextEntries, m_Switches;
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ namespace Server.Gumps
|
|||
TypeID = GetTypeID(GetType());
|
||||
|
||||
Entries = new List<GumpEntry>();
|
||||
m_Strings = new List<string>();
|
||||
Strings = new List<string>();
|
||||
}
|
||||
|
||||
public int TypeID { get; }
|
||||
|
|
@ -206,13 +206,9 @@ namespace Server.Gumps
|
|||
public void Add(GumpEntry g)
|
||||
{
|
||||
if (g.Parent != this)
|
||||
{
|
||||
g.Parent = this;
|
||||
}
|
||||
else if (!Entries.Contains(g))
|
||||
{
|
||||
Entries.Add(g);
|
||||
}
|
||||
}
|
||||
|
||||
public void Remove(GumpEntry g)
|
||||
|
|
@ -226,12 +222,12 @@ namespace Server.Gumps
|
|||
|
||||
public int Intern(string value)
|
||||
{
|
||||
var indexOf = m_Strings.IndexOf(value);
|
||||
var indexOf = Strings.IndexOf(value);
|
||||
|
||||
if (indexOf >= 0) return indexOf;
|
||||
|
||||
m_Strings.Add(value);
|
||||
return m_Strings.Count - 1;
|
||||
Strings.Add(value);
|
||||
return Strings.Count - 1;
|
||||
}
|
||||
|
||||
public void SendTo(NetState state)
|
||||
|
|
@ -242,7 +238,7 @@ namespace Server.Gumps
|
|||
|
||||
public static byte[] StringToBuffer(string str) => Encoding.ASCII.GetBytes(str);
|
||||
|
||||
private Packet Compile(NetState ns = null)
|
||||
public Packet Compile(NetState ns = null)
|
||||
{
|
||||
IGumpWriter disp;
|
||||
|
||||
|
|
@ -274,7 +270,7 @@ namespace Server.Gumps
|
|||
disp.AppendLayout(m_EndLayout);
|
||||
}
|
||||
|
||||
disp.WriteStrings(m_Strings);
|
||||
disp.WriteStrings(Strings);
|
||||
|
||||
disp.Flush();
|
||||
|
||||
|
|
|
|||
|
|
@ -634,9 +634,9 @@ namespace Server.Items
|
|||
if (ns != null)
|
||||
{
|
||||
if (ns.HighSeas)
|
||||
to.Send(new ContainerDisplayHS(this));
|
||||
to.Send(new ContainerDisplayHS(Serial, GumpID));
|
||||
else
|
||||
to.Send(new ContainerDisplay(this));
|
||||
to.Send(new ContainerDisplay(Serial, GumpID));
|
||||
|
||||
SendContentTo(ns);
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,11 @@ namespace Server
|
|||
private static bool m_Profiling;
|
||||
private static DateTime m_ProfileStart;
|
||||
private static TimeSpan m_ProfileTime;
|
||||
private static bool? m_IsRunningFromXUnit;
|
||||
|
||||
public static bool IsRunningFromXUnit =>
|
||||
m_IsRunningFromXUnit ??= AppDomain.CurrentDomain.GetAssemblies().Any(
|
||||
a => a.FullName?.ToLowerInvariant().StartsWith("xunit") ?? false);
|
||||
|
||||
/*
|
||||
* DateTime.Now and DateTime.UtcNow are based on actual system clock time.
|
||||
|
|
|
|||
|
|
@ -331,14 +331,14 @@ namespace Server.Network
|
|||
unknown ??= "";
|
||||
caption ??= "";
|
||||
|
||||
EnsureCapacity(16 + unknown.Length + caption.Length);
|
||||
EnsureCapacity(15 + unknown.Length + caption.Length);
|
||||
|
||||
Stream.Write(serial);
|
||||
Stream.Write((short)gumpID);
|
||||
Stream.Write((short)unknown.Length);
|
||||
Stream.WriteAsciiFixed(unknown, unknown.Length);
|
||||
Stream.Write((short)(unknown.Length + 1));
|
||||
Stream.WriteAsciiNull(unknown);
|
||||
Stream.Write((short)(caption.Length + 1));
|
||||
Stream.WriteAsciiFixed(caption, caption.Length + 1);
|
||||
Stream.WriteAsciiNull(caption);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,14 +105,6 @@ namespace Server.Network
|
|||
Stream.Write((short)itemID);
|
||||
|
||||
Stream.Write((byte)0);
|
||||
/*} else if ( ) {
|
||||
m_Stream.Write( (byte) 0x01 );
|
||||
|
||||
m_Stream.Write( (int) item.Serial );
|
||||
|
||||
m_Stream.Write( (short) itemID );
|
||||
|
||||
m_Stream.Write( (byte) item.Direction );*/
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -132,10 +124,8 @@ namespace Server.Network
|
|||
Stream.Write((short)amount);
|
||||
|
||||
var loc = item.Location;
|
||||
var x = loc.m_X & 0x7FFF;
|
||||
var y = loc.m_Y & 0x3FFF;
|
||||
Stream.Write((short)x);
|
||||
Stream.Write((short)y);
|
||||
Stream.Write((short)loc.m_X);
|
||||
Stream.Write((short)loc.m_Y);
|
||||
Stream.Write((sbyte)loc.m_Z);
|
||||
|
||||
Stream.Write((byte)item.Light);
|
||||
|
|
@ -163,14 +153,6 @@ namespace Server.Network
|
|||
Stream.Write((ushort)itemID);
|
||||
|
||||
Stream.Write((byte)0);
|
||||
/*} else if ( ) {
|
||||
m_Stream.Write( (byte) 0x01 );
|
||||
|
||||
m_Stream.Write( (int) item.Serial );
|
||||
|
||||
m_Stream.Write( (ushort) itemID );
|
||||
|
||||
m_Stream.Write( (byte) item.Direction );*/
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -190,10 +172,8 @@ namespace Server.Network
|
|||
Stream.Write((short)amount);
|
||||
|
||||
var loc = item.Location;
|
||||
var x = loc.m_X & 0x7FFF;
|
||||
var y = loc.m_Y & 0x3FFF;
|
||||
Stream.Write((short)x);
|
||||
Stream.Write((short)y);
|
||||
Stream.Write((short)loc.m_X);
|
||||
Stream.Write((short)loc.m_Y);
|
||||
Stream.Write((sbyte)loc.m_Z);
|
||||
|
||||
Stream.Write((byte)item.Light);
|
||||
|
|
@ -206,18 +186,18 @@ namespace Server.Network
|
|||
|
||||
public sealed class DisplaySpellbook : Packet
|
||||
{
|
||||
public DisplaySpellbook(Item book) : base(0x24, 7)
|
||||
public DisplaySpellbook(Serial book) : base(0x24, 7)
|
||||
{
|
||||
Stream.Write(book.Serial);
|
||||
Stream.Write(book);
|
||||
Stream.Write((short)-1);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class DisplaySpellbookHS : Packet
|
||||
{
|
||||
public DisplaySpellbookHS(Item book) : base(0x24, 9)
|
||||
public DisplaySpellbookHS(Serial book) : base(0x24, 9)
|
||||
{
|
||||
Stream.Write(book.Serial);
|
||||
Stream.Write(book);
|
||||
Stream.Write((short)-1);
|
||||
Stream.Write((short)0x7D);
|
||||
}
|
||||
|
|
@ -225,14 +205,14 @@ namespace Server.Network
|
|||
|
||||
public sealed class NewSpellbookContent : Packet
|
||||
{
|
||||
public NewSpellbookContent(Item item, int graphic, int offset, ulong content) : base(0xBF)
|
||||
public NewSpellbookContent(Serial spellbook, int graphic, int offset, ulong content) : base(0xBF)
|
||||
{
|
||||
EnsureCapacity(23);
|
||||
|
||||
Stream.Write((short)0x1B);
|
||||
Stream.Write((short)0x01);
|
||||
|
||||
Stream.Write(item.Serial);
|
||||
Stream.Write(spellbook);
|
||||
Stream.Write((short)graphic);
|
||||
Stream.Write((short)offset);
|
||||
|
||||
|
|
@ -243,9 +223,9 @@ namespace Server.Network
|
|||
|
||||
public sealed class SpellbookContent : Packet
|
||||
{
|
||||
public SpellbookContent(int count, int offset, ulong content, Item item) : base(0x3C)
|
||||
public SpellbookContent(Serial spellbook, int offset, ulong content) : base(0x3C)
|
||||
{
|
||||
EnsureCapacity(5 + count * 19);
|
||||
EnsureCapacity(5 + 64 * 19);
|
||||
|
||||
var written = 0;
|
||||
|
||||
|
|
@ -262,7 +242,7 @@ namespace Server.Network
|
|||
Stream.Write((ushort)(i + offset));
|
||||
Stream.Write((short)0);
|
||||
Stream.Write((short)0);
|
||||
Stream.Write(item.Serial);
|
||||
Stream.Write(spellbook);
|
||||
Stream.Write((short)0);
|
||||
|
||||
++written;
|
||||
|
|
@ -275,9 +255,9 @@ namespace Server.Network
|
|||
|
||||
public sealed class SpellbookContent6017 : Packet
|
||||
{
|
||||
public SpellbookContent6017(int count, int offset, ulong content, Item item) : base(0x3C)
|
||||
public SpellbookContent6017(Serial spellbook, int offset, ulong content) : base(0x3C)
|
||||
{
|
||||
EnsureCapacity(5 + count * 20);
|
||||
EnsureCapacity(5 + 64 * 20);
|
||||
|
||||
var written = 0;
|
||||
|
||||
|
|
@ -295,7 +275,7 @@ namespace Server.Network
|
|||
Stream.Write((short)0);
|
||||
Stream.Write((short)0);
|
||||
Stream.Write((byte)0); // Grid Location?
|
||||
Stream.Write(item.Serial);
|
||||
Stream.Write(spellbook);
|
||||
Stream.Write((short)0);
|
||||
|
||||
++written;
|
||||
|
|
@ -308,19 +288,19 @@ namespace Server.Network
|
|||
|
||||
public sealed class ContainerDisplay : Packet
|
||||
{
|
||||
public ContainerDisplay(Container c) : base(0x24, 7)
|
||||
public ContainerDisplay(Serial cont, int gumpId) : base(0x24, 7)
|
||||
{
|
||||
Stream.Write(c.Serial);
|
||||
Stream.Write((short)c.GumpID);
|
||||
Stream.Write(cont);
|
||||
Stream.Write((short)gumpId);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ContainerDisplayHS : Packet
|
||||
{
|
||||
public ContainerDisplayHS(Container c) : base(0x24, 9)
|
||||
public ContainerDisplayHS(Serial cont, int gumpId) : base(0x24, 9)
|
||||
{
|
||||
Stream.Write(c.Serial);
|
||||
Stream.Write((short)c.GumpID);
|
||||
Stream.Write(cont);
|
||||
Stream.Write((short)gumpId);
|
||||
Stream.Write((short)0x7D);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Server
|
||||
|
|
@ -181,108 +182,56 @@ namespace Server
|
|||
|
||||
static TileData()
|
||||
{
|
||||
ItemTable = new ItemData[0x10000];
|
||||
LandTable = new LandData[0x4000];
|
||||
|
||||
if (Core.IsRunningFromXUnit) return;
|
||||
|
||||
var filePath = Core.FindDataFile("tiledata.mul");
|
||||
|
||||
using var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
var bin = new BinaryReader(fs);
|
||||
|
||||
if (fs.Length == 3188736)
|
||||
var is7090 = fs.Length == 3188736;
|
||||
bool is7000 = fs.Length == 1644544;
|
||||
|
||||
for (var i = 0; i < 0x4000; i++)
|
||||
{
|
||||
// 7.0.9.0
|
||||
LandTable = new LandData[0x4000];
|
||||
|
||||
for (var i = 0; i < 0x4000; ++i)
|
||||
// header
|
||||
if (is7090)
|
||||
{
|
||||
if (i == 1 || i > 0 && (i & 0x1F) == 0) bin.ReadInt32(); // header
|
||||
|
||||
var flags = (TileFlag)bin.ReadInt64();
|
||||
bin.ReadInt16(); // skip 2 bytes -- textureID
|
||||
|
||||
LandTable[i] = new LandData(ReadNameString(bin), flags);
|
||||
if (i == 1 || i > 0 && (i & 0x1F) == 0)
|
||||
bin.ReadInt32();
|
||||
}
|
||||
|
||||
ItemTable = new ItemData[0x10000];
|
||||
|
||||
for (var i = 0; i < 0x10000; ++i)
|
||||
{
|
||||
if ((i & 0x1F) == 0) bin.ReadInt32(); // header
|
||||
|
||||
var flags = (TileFlag)bin.ReadInt64();
|
||||
int weight = bin.ReadByte();
|
||||
int quality = bin.ReadByte();
|
||||
bin.ReadInt16();
|
||||
bin.ReadByte();
|
||||
int quantity = bin.ReadByte();
|
||||
else if ((i & 0x1F) == 0)
|
||||
bin.ReadInt32();
|
||||
bin.ReadByte();
|
||||
int value = bin.ReadByte();
|
||||
int height = bin.ReadByte();
|
||||
|
||||
ItemTable[i] = new ItemData(ReadNameString(bin), flags, weight, quality, quantity, value,
|
||||
height);
|
||||
}
|
||||
var flags = (TileFlag)(is7090 ? bin.ReadInt64() : bin.ReadInt32());
|
||||
bin.ReadInt16(); // skip 2 bytes -- textureID
|
||||
|
||||
LandTable[i] = new LandData(ReadNameString(bin), flags);
|
||||
}
|
||||
else
|
||||
|
||||
int length = is7090 ? 0x10000 : is7000 ? 0x8000 : 0x4000;
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
LandTable = new LandData[0x4000];
|
||||
if ((i & 0x1F) == 0) bin.ReadInt32(); // header
|
||||
|
||||
for (var i = 0; i < 0x4000; ++i)
|
||||
{
|
||||
if ((i & 0x1F) == 0) bin.ReadInt32(); // header
|
||||
var flags = (TileFlag)(is7090 ? bin.ReadInt64() : bin.ReadInt32());
|
||||
int weight = bin.ReadByte();
|
||||
int quality = bin.ReadByte();
|
||||
bin.ReadInt16();
|
||||
bin.ReadByte();
|
||||
int quantity = bin.ReadByte();
|
||||
bin.ReadInt32();
|
||||
bin.ReadByte();
|
||||
int value = bin.ReadByte();
|
||||
int height = bin.ReadByte();
|
||||
|
||||
var flags = (TileFlag)bin.ReadInt32();
|
||||
bin.ReadInt16(); // skip 2 bytes -- textureID
|
||||
|
||||
LandTable[i] = new LandData(ReadNameString(bin), flags);
|
||||
}
|
||||
|
||||
if (fs.Length == 1644544)
|
||||
{
|
||||
// 7.0.0.0
|
||||
ItemTable = new ItemData[0x8000];
|
||||
|
||||
for (var i = 0; i < 0x8000; ++i)
|
||||
{
|
||||
if ((i & 0x1F) == 0) bin.ReadInt32(); // header
|
||||
|
||||
var flags = (TileFlag)bin.ReadInt32();
|
||||
int weight = bin.ReadByte();
|
||||
int quality = bin.ReadByte();
|
||||
bin.ReadInt16();
|
||||
bin.ReadByte();
|
||||
int quantity = bin.ReadByte();
|
||||
bin.ReadInt32();
|
||||
bin.ReadByte();
|
||||
int value = bin.ReadByte();
|
||||
int height = bin.ReadByte();
|
||||
|
||||
ItemTable[i] = new ItemData(ReadNameString(bin), flags, weight, quality, quantity, value,
|
||||
height);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemTable = new ItemData[0x4000];
|
||||
|
||||
for (var i = 0; i < 0x4000; ++i)
|
||||
{
|
||||
if ((i & 0x1F) == 0) bin.ReadInt32(); // header
|
||||
|
||||
var flags = (TileFlag)bin.ReadInt32();
|
||||
int weight = bin.ReadByte();
|
||||
int quality = bin.ReadByte();
|
||||
bin.ReadInt16();
|
||||
bin.ReadByte();
|
||||
int quantity = bin.ReadByte();
|
||||
bin.ReadInt32();
|
||||
bin.ReadByte();
|
||||
int value = bin.ReadByte();
|
||||
int height = bin.ReadByte();
|
||||
|
||||
ItemTable[i] = new ItemData(ReadNameString(bin), flags, weight, quality, quantity, value,
|
||||
height);
|
||||
}
|
||||
}
|
||||
ItemTable[i] = new ItemData(
|
||||
ReadNameString(bin), flags, weight, quality, quantity, value, height
|
||||
);
|
||||
}
|
||||
|
||||
MaxLandValue = LandTable.Length - 1;
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
|
||||
<PackageReference Include="coverlet.collector" Version="1.2.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.2" />
|
||||
<PackageReference Include="coverlet.collector" Version="1.3.0" />
|
||||
<ProjectReference Include="..\Server\Server.csproj" />
|
||||
<ProjectReference Include="..\UOContent\UOContent.csproj" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
".NETCoreApp,Version=v3.1": {
|
||||
"coverlet.collector": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.2.1, )",
|
||||
"resolved": "1.2.1",
|
||||
"contentHash": "a4JYYZbEXk2UsrTEHlKrQxBVROeQkAg/Qwrf/XgZHGDXNctIrIu9MCihNKpFXC6cgj6wuXmWcPN++T9wOnhskA=="
|
||||
"requested": "[1.3.0, )",
|
||||
"resolved": "1.3.0",
|
||||
"contentHash": "t8pnf5SX2ya0RX4vjoxsbhDMQCZJcpPun2neHKJ4FouMmObylo25FvoOydvf3Bl+l+IzWw7u2vjEeCBHnleB9g=="
|
||||
},
|
||||
"Microsoft.NET.Test.Sdk": {
|
||||
"type": "Direct",
|
||||
|
|
@ -31,12 +31,9 @@
|
|||
},
|
||||
"xunit.runner.visualstudio": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.4.1, )",
|
||||
"resolved": "2.4.1",
|
||||
"contentHash": "mBXd1lp1TQr4to2nFv+c4Tf+RnPoQPKglzwLdbdirOUxRaJsCUNDUx2y7E6j9ajgISlTTp1CydFBZCRCUIrwDg==",
|
||||
"dependencies": {
|
||||
"Microsoft.NET.Test.Sdk": "15.0.0"
|
||||
}
|
||||
"requested": "[2.4.2, )",
|
||||
"resolved": "2.4.2",
|
||||
"contentHash": "Trt9multph2KE3U0p9oBt0k4Fq6lUv4btUcONaQEeuFnMCak2k/b7PAArbLtMFW7HO1jxlBHUgIPKEqci3Y1dg=="
|
||||
},
|
||||
"Argon2.Bindings": {
|
||||
"type": "Transitive",
|
||||
|
|
|
|||
|
|
@ -603,30 +603,30 @@ namespace Server.Items
|
|||
}
|
||||
|
||||
if (ns.HighSeas)
|
||||
to.Send(new DisplaySpellbookHS(this));
|
||||
to.Send(new DisplaySpellbookHS(Serial));
|
||||
else
|
||||
to.Send(new DisplaySpellbook(this));
|
||||
to.Send(new DisplaySpellbook(Serial));
|
||||
|
||||
if (ObjectPropertyList.Enabled)
|
||||
{
|
||||
if (ns.NewSpellbook)
|
||||
{
|
||||
to.Send(new NewSpellbookContent(this, ItemID, BookOffset + 1, m_Content));
|
||||
to.Send(new NewSpellbookContent(Serial, ItemID, BookOffset + 1, m_Content));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ns.ContainerGridLines)
|
||||
to.Send(new SpellbookContent6017(SpellCount, BookOffset + 1, m_Content, this));
|
||||
to.Send(new SpellbookContent6017(Serial, BookOffset + 1, m_Content));
|
||||
else
|
||||
to.Send(new SpellbookContent(SpellCount, BookOffset + 1, m_Content, this));
|
||||
to.Send(new SpellbookContent(Serial, BookOffset + 1, m_Content));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ns.ContainerGridLines)
|
||||
to.Send(new SpellbookContent6017(SpellCount, BookOffset + 1, m_Content, this));
|
||||
to.Send(new SpellbookContent6017(Serial, BookOffset + 1, m_Content));
|
||||
else
|
||||
to.Send(new SpellbookContent(SpellCount, BookOffset + 1, m_Content, this));
|
||||
to.Send(new SpellbookContent(Serial, BookOffset + 1, m_Content));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue