From d2cfeb06ab341fb1c170eb2951fc0aa77ab17efe Mon Sep 17 00:00:00 2001
From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com>
Date: Tue, 17 Nov 2020 00:46:06 -0800
Subject: [PATCH] Updates Light Packets & World Loading (#316)
- [X] Changes light packets
- [X] Updates world loading
Bumps release version
---
.../Network/Packets/Outgoing/EffectPackets.cs | 15 ------
.../Packets/Outgoing/EquipmentPackets.cs | 15 ------
.../Packets/Outgoing/LightPacketTests.cs | 27 +++++------
.../Network/Packets/Outgoing/LightPackets.cs | 35 ++++++++++++++
.../Network/Packets/Outgoing/MobilePackets.cs | 15 ------
...ightPackets.cs => OutgoingLightPackets.cs} | 48 +++++++++----------
Projects/Server/Serialization/BufferReader.cs | 46 +++++++++++-------
Projects/Server/World/World.cs | 22 ++++-----
Projects/UOContent/Mobiles/PlayerMobile.cs | 4 +-
9 files changed, 112 insertions(+), 115 deletions(-)
create mode 100644 Projects/Server.Tests/Tests/Network/Packets/Outgoing/LightPackets.cs
rename Projects/Server/Network/Packets/{LightPackets.cs => OutgoingLightPackets.cs} (56%)
diff --git a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/EffectPackets.cs b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/EffectPackets.cs
index efc18d915..c176c2d61 100644
--- a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/EffectPackets.cs
+++ b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/EffectPackets.cs
@@ -1,18 +1,3 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2020 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: EffectPackets.cs *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see . *
- *************************************************************************/
-
namespace Server.Network
{
public sealed class PlaySound : Packet
diff --git a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/EquipmentPackets.cs b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/EquipmentPackets.cs
index 8d81f694d..b00bf2c04 100644
--- a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/EquipmentPackets.cs
+++ b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/EquipmentPackets.cs
@@ -1,18 +1,3 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2020 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: EquipmentPackets.cs *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see . *
- *************************************************************************/
-
using System;
namespace Server.Network
diff --git a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/LightPacketTests.cs b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/LightPacketTests.cs
index 18b14296a..f050a77ee 100644
--- a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/LightPacketTests.cs
+++ b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/LightPacketTests.cs
@@ -11,32 +11,27 @@ namespace Server.Tests.Network
public void TestGlobalLightLevel()
{
byte lightLevel = 5;
- var data = new GlobalLightLevel(lightLevel).Compile();
+ var expected = new GlobalLightLevel(lightLevel).Compile();
- Span expectedData = stackalloc byte[2];
- var pos = 0;
+ using var ns = PacketTestUtilities.CreateTestNetState();
+ ns.SendGlobalLightLevel(lightLevel);
- expectedData.Write(ref pos, (byte)0x4F); // Packet ID
- expectedData.Write(ref pos, lightLevel);
-
- AssertThat.Equal(data, expectedData);
+ var result = ns.SendPipe.Reader.TryRead();
+ AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
}
[Fact]
public void TestPersonalLightLevel()
{
- Serial serial = 0x1;
+ Serial serial = 0x1024;
byte lightLevel = 5;
- var data = new PersonalLightLevel(serial, lightLevel).Compile();
+ var expected = new PersonalLightLevel(serial, lightLevel).Compile();
- Span expectedData = stackalloc byte[6];
- var pos = 0;
+ using var ns = PacketTestUtilities.CreateTestNetState();
+ ns.SendPersonalLightLevel(serial, lightLevel);
- expectedData.Write(ref pos, (byte)0x4E); // Packet ID
- expectedData.Write(ref pos, serial);
- expectedData.Write(ref pos, lightLevel);
-
- AssertThat.Equal(data, expectedData);
+ var result = ns.SendPipe.Reader.TryRead();
+ AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
}
}
}
diff --git a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/LightPackets.cs b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/LightPackets.cs
new file mode 100644
index 000000000..5da20a6d5
--- /dev/null
+++ b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/LightPackets.cs
@@ -0,0 +1,35 @@
+namespace Server.Network
+{
+ public sealed class GlobalLightLevel : Packet
+ {
+ private static readonly GlobalLightLevel[] m_Cache = new GlobalLightLevel[0x100];
+
+ public GlobalLightLevel(int level) : base(0x4F, 2)
+ {
+ Stream.Write((sbyte)level);
+ }
+
+ public static GlobalLightLevel Instantiate(int level)
+ {
+ var lvl = (byte)level;
+ var p = m_Cache[lvl];
+
+ if (p == null)
+ {
+ m_Cache[lvl] = p = new GlobalLightLevel(level);
+ p.SetStatic();
+ }
+
+ return p;
+ }
+ }
+
+ public sealed class PersonalLightLevel : Packet
+ {
+ public PersonalLightLevel(Serial mobile, int level = 0) : base(0x4E, 6)
+ {
+ Stream.Write(mobile);
+ Stream.Write((sbyte)level);
+ }
+ }
+}
diff --git a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/MobilePackets.cs b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/MobilePackets.cs
index 3e5a432a9..a2802dd83 100644
--- a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/MobilePackets.cs
+++ b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/MobilePackets.cs
@@ -1,18 +1,3 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2020 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: MobilePackets.cs *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see . *
- *************************************************************************/
-
using Server.Network;
namespace Server.Tests.Network
diff --git a/Projects/Server/Network/Packets/LightPackets.cs b/Projects/Server/Network/Packets/OutgoingLightPackets.cs
similarity index 56%
rename from Projects/Server/Network/Packets/LightPackets.cs
rename to Projects/Server/Network/Packets/OutgoingLightPackets.cs
index 6fd482b94..1eb7e37db 100644
--- a/Projects/Server/Network/Packets/LightPackets.cs
+++ b/Projects/Server/Network/Packets/OutgoingLightPackets.cs
@@ -2,7 +2,7 @@
* ModernUO *
* Copyright 2019-2020 - ModernUO Development Team *
* Email: hi@modernuo.com *
- * File: LightPackets.cs *
+ * File: OutgoingLightPackets.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
@@ -13,38 +13,38 @@
* along with this program. If not, see . *
*************************************************************************/
+using System.Buffers;
+
namespace Server.Network
{
- public sealed class GlobalLightLevel : Packet
+ public static class OutgoingLightPackets
{
- private static readonly GlobalLightLevel[] m_Cache = new GlobalLightLevel[0x100];
-
- public GlobalLightLevel(int level) : base(0x4F, 2)
+ public static void SendPersonalLightLevel(this NetState ns, Serial serial, int level)
{
- Stream.Write((sbyte)level);
- }
-
- public static GlobalLightLevel Instantiate(int level)
- {
- var lvl = (byte)level;
- var p = m_Cache[lvl];
-
- if (p == null)
+ if (ns == null || !ns.GetSendBuffer(out var buffer))
{
- m_Cache[lvl] = p = new GlobalLightLevel(level);
- p.SetStatic();
+ return;
}
- return p;
- }
- }
+ var writer = new CircularBufferWriter(buffer);
+ writer.Write((byte)0x4E); // Packet ID
+ writer.Write(serial);
+ writer.Write((byte)level);
- public sealed class PersonalLightLevel : Packet
- {
- public PersonalLightLevel(Serial mobile, int level = 0) : base(0x4E, 6)
+ ns.Send(ref buffer, 6);
+ }
+
+ public static void SendGlobalLightLevel(this NetState ns, int level = 0)
{
- Stream.Write(mobile);
- Stream.Write((sbyte)level);
+ if (ns == null || !ns.GetSendBuffer(out var buffer))
+ {
+ return;
+ }
+
+ buffer[0] = 0x4F; // Packet ID
+ buffer[1] = (byte)level;
+
+ ns.Send(ref buffer, 2);
}
}
}
diff --git a/Projects/Server/Serialization/BufferReader.cs b/Projects/Server/Serialization/BufferReader.cs
index 593d51ab5..e4b35756b 100644
--- a/Projects/Server/Serialization/BufferReader.cs
+++ b/Projects/Server/Serialization/BufferReader.cs
@@ -16,6 +16,7 @@
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
+using System.IO;
using System.Net;
using System.Text;
using Server.Guilds;
@@ -25,12 +26,12 @@ namespace Server
public class BufferReader : IGenericReader
{
private readonly Encoding _encoding;
- private ArraySegment _segment;
+ private byte[] _buffer;
public int Position { get; private set; }
- public BufferReader(ArraySegment segment)
+ public BufferReader(byte[] buffer)
{
- _segment = segment;
+ _buffer = buffer;
_encoding = Utility.UTF8;
}
@@ -42,7 +43,7 @@ namespace Server
}
var length = ReadEncodedInt();
- var s = length == 0 ? "" : _encoding.GetString(_segment.AsSpan(Position, length));
+ var s = length == 0 ? "" : _encoding.GetString(_buffer.AsSpan(Position, length));
Position += length;
return s;
}
@@ -82,65 +83,65 @@ namespace Server
public long ReadLong()
{
- var v = BinaryPrimitives.ReadInt64LittleEndian(_segment.AsSpan(Position, 8));
+ var v = BinaryPrimitives.ReadInt64LittleEndian(_buffer.AsSpan(Position, 8));
Position += 8;
return v;
}
public ulong ReadULong()
{
- var v = BinaryPrimitives.ReadUInt64LittleEndian(_segment.AsSpan(Position, 8));
+ var v = BinaryPrimitives.ReadUInt64LittleEndian(_buffer.AsSpan(Position, 8));
Position += 8;
return v;
}
public int ReadInt()
{
- var v = BinaryPrimitives.ReadInt32LittleEndian(_segment.AsSpan(Position, 4));
+ var v = BinaryPrimitives.ReadInt32LittleEndian(_buffer.AsSpan(Position, 4));
Position += 4;
return v;
}
public uint ReadUInt()
{
- var v = BinaryPrimitives.ReadUInt32LittleEndian(_segment.AsSpan(Position, 4));
+ var v = BinaryPrimitives.ReadUInt32LittleEndian(_buffer.AsSpan(Position, 4));
Position += 4;
return v;
}
public short ReadShort()
{
- var v = BinaryPrimitives.ReadInt16LittleEndian(_segment.AsSpan(Position, 2));
+ var v = BinaryPrimitives.ReadInt16LittleEndian(_buffer.AsSpan(Position, 2));
Position += 2;
return v;
}
public ushort ReadUShort()
{
- var v = BinaryPrimitives.ReadUInt16LittleEndian(_segment.AsSpan(Position, 2));
+ var v = BinaryPrimitives.ReadUInt16LittleEndian(_buffer.AsSpan(Position, 2));
Position += 2;
return v;
}
public double ReadDouble()
{
- var v = BinaryPrimitives.ReadDoubleLittleEndian(_segment.AsSpan(Position, 8));
+ var v = BinaryPrimitives.ReadDoubleLittleEndian(_buffer.AsSpan(Position, 8));
Position += 8;
return v;
}
public float ReadFloat()
{
- var v = BinaryPrimitives.ReadSingleLittleEndian(_segment.AsSpan(Position, 4));
+ var v = BinaryPrimitives.ReadSingleLittleEndian(_buffer.AsSpan(Position, 4));
Position += 4;
return v;
}
- public byte ReadByte() => _segment[Position++];
+ public byte ReadByte() => _buffer[Position++];
- public sbyte ReadSByte() => (sbyte)_segment[Position++];
+ public sbyte ReadSByte() => (sbyte)_buffer[Position++];
- public bool ReadBool() => _segment[Position++] != 0;
+ public bool ReadBool() => _buffer[Position++] != 0;
public int ReadEncodedInt()
{
@@ -310,14 +311,25 @@ namespace Server
public int Read(Span buffer)
{
var length = buffer.Length;
- if (length > _segment.Count - Position)
+ if (length > _buffer.Length - Position)
{
throw new OutOfMemoryException();
}
- _segment.AsSpan(Position, length).CopyTo(buffer);
+ _buffer.AsSpan(Position, length).CopyTo(buffer);
Position += length;
return length;
}
+
+ public virtual int Seek(int offset, SeekOrigin origin)
+ {
+ return origin switch
+ {
+ SeekOrigin.Begin => Position = offset,
+ SeekOrigin.Current => Position += offset,
+ SeekOrigin.End => Position = _buffer.Length - offset,
+ _ => Position
+ };
+ }
}
}
diff --git a/Projects/Server/World/World.cs b/Projects/Server/World/World.cs
index 87e67db37..f7b3012ed 100644
--- a/Projects/Server/World/World.cs
+++ b/Projects/Server/World/World.cs
@@ -337,30 +337,31 @@ namespace Server
}
using FileStream bin = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read);
- var fileBuffer = new byte[bin.Length];
- bin.Read(fileBuffer);
+ var buffer = new byte[bin.Length];
+ bin.Read(buffer);
bin.Close();
- int position = 0;
+ var br = new BufferReader(buffer);
foreach (var entry in entities)
{
T t = entry.Entity;
+ // Skip this entry
if (t == null)
{
+ br.Seek(entry.Length, SeekOrigin.Current);
continue;
}
- var segment = new ArraySegment(fileBuffer, position, entry.Length);
- var bufferReader = new BufferReader(segment);
- t.Deserialize(bufferReader);
+ t.Deserialize(br);
+ var end = entry.Position + entry.Length;
- if (bufferReader.Position != entry.Length)
+ if (br.Position != end)
{
Console.WriteLine($"***** Bad deserialize on {t.GetType()} *****");
Console.WriteLine(
- $"Serialized object was {entry.Length} bytes, but {bufferReader.Position - entry.Position} bytes deserialized"
+ $"Serialized object was {entry.Length} bytes, but {br.Position - entry.Position} bytes deserialized"
);
Console.WriteLine("Delete the object and continue? (y/n)");
@@ -370,10 +371,9 @@ namespace Server
throw new Exception("Deserialization failed.");
}
t.Delete();
+
+ br.Seek((int)end, SeekOrigin.Begin);
}
-
-
- position += entry.Length;
}
}
diff --git a/Projects/UOContent/Mobiles/PlayerMobile.cs b/Projects/UOContent/Mobiles/PlayerMobile.cs
index 85619000c..931f9a57c 100644
--- a/Projects/UOContent/Mobiles/PlayerMobile.cs
+++ b/Projects/UOContent/Mobiles/PlayerMobile.cs
@@ -1253,8 +1253,8 @@ namespace Server.Mobiles
m_LastGlobalLight = global;
m_LastPersonalLight = personal;
- ns.Send(GlobalLightLevel.Instantiate(global));
- ns.Send(new PersonalLightLevel(Serial, personal));
+ ns.SendGlobalLightLevel(global);
+ ns.SendPersonalLightLevel(Serial, personal);
}
public override int GetMinResistance(ResistanceType type)