From 111c0edc30c53269221c4aa9239aa434abd71e77 Mon Sep 17 00:00:00 2001 From: squid Date: Sat, 17 May 2025 11:11:57 +0200 Subject: [PATCH 1/3] refactor(PersistenceManager.cs): Update Serialize and Deserialize methods in PersistenceManager to include IPersistenceManager parameter for better extensibility and dependency injection feat(BinarySerializationExtensions.cs): Add extension methods for binary serialization of common types to improve code readability and maintainability refactor(IEntitySerializer.cs): Modify Serialize and Deserialize methods in IEntitySerializer to include IPersistenceManager parameter for better extensibility and dependency injection refactor(BaseEntitySerializer.cs): Update Serialize and Deserialize methods in BaseEntitySerializer to include BinaryWriter and BinaryReader parameters for better control and efficiency feat(BinaryItemSerializer.cs): Implement Serialize and Deserialize methods in BinaryItemSerializer using BinaryWriter and BinaryReader for better performance and code organization feat(BinaryMobileSerializer.cs): Implement Serialize and Deserialize methods in BinaryMobileSerializer using BinaryWriter and BinaryReader for better performance and code organization --- .../Services/PersistenceManager.cs | 4 +- .../BinarySerializationExtensions.cs | 227 ++++++++++++++++++ .../Persistence/IEntitySerializer.cs | 8 +- .../Serializers/Base/BaseEntitySerializer.cs | 26 +- .../Binary/BinaryItemSerializer.cs | 33 +-- .../Binary/BinaryMobileSerializer.cs | 64 +++-- 6 files changed, 295 insertions(+), 67 deletions(-) create mode 100644 src/Prima.UOData/Extensions/BinarySerializationExtensions.cs diff --git a/src/Prima.Server/Services/PersistenceManager.cs b/src/Prima.Server/Services/PersistenceManager.cs index e22c6be..1e50e79 100644 --- a/src/Prima.Server/Services/PersistenceManager.cs +++ b/src/Prima.Server/Services/PersistenceManager.cs @@ -37,7 +37,7 @@ public async Task SerializeAsync(TEntity entity throw new InvalidOperationException($"No serializer registered for entity type {entity.GetType()}"); } - var serializerData = serializer.Serialize(entity); + var serializerData = serializer.Serialize(entity, this); return new SerializationEntryData(serializer.Header, serializerData); } @@ -120,7 +120,7 @@ public async Task> DeserializeAsync(string fileName) wher if (_entitySerializers.TryGetValue(header, out var serializer)) { - entries.Add((TEntity)serializer.Deserialize(data)); + entries.Add((TEntity)serializer.Deserialize(data, this)); } else { diff --git a/src/Prima.UOData/Extensions/BinarySerializationExtensions.cs b/src/Prima.UOData/Extensions/BinarySerializationExtensions.cs new file mode 100644 index 0000000..7a1604e --- /dev/null +++ b/src/Prima.UOData/Extensions/BinarySerializationExtensions.cs @@ -0,0 +1,227 @@ +using System.Text; +using Prima.UOData.Id; +using Prima.UOData.Interfaces.Persistence.Entities; + +namespace Prima.UOData.Extensions; + +/// +/// Provides extension methods for binary serialization of common types. +/// +public static class BinarySerializationExtensions +{ + /// + /// Serializes a string to a BinaryWriter. + /// + /// The BinaryWriter to write to. + /// The string to serialize. + public static void WriteString(this BinaryWriter writer, string? value) + { + if (value == null) + { + writer.Write((byte)0); + return; + } + + var bytes = Encoding.UTF8.GetBytes(value); + writer.Write((ushort)bytes.Length); + writer.Write(bytes); + } + + /// + /// Deserializes a string from a BinaryReader. + /// + /// The BinaryReader to read from. + /// The deserialized string. + public static string ReadString(this BinaryReader reader) + { + var length = reader.ReadUInt16(); + if (length == 0) + return string.Empty; + + var bytes = reader.ReadBytes(length); + return Encoding.UTF8.GetString(bytes); + } + + /// + /// Serializes a Serial to a BinaryWriter. + /// + /// The BinaryWriter to write to. + /// The Serial to serialize. + public static void WriteSerial(this BinaryWriter writer, Serial serial) + { + writer.Write(serial.Value); + } + + /// + /// Deserializes a Serial from a BinaryReader. + /// + /// The BinaryReader to read from. + /// The deserialized Serial. + public static Serial ReadSerial(this BinaryReader reader) + { + return new Serial(reader.ReadUInt32()); + } + + /// + /// Serializes a generic list to a BinaryWriter. + /// + /// The type of elements in the list. + /// The BinaryWriter to write to. + /// The list to serialize. + /// The delegate to serialize each item. + public static void WriteList(this BinaryWriter writer, IList? list, Action itemSerializer) + { + if (list == null || list.Count == 0) + { + writer.Write((int)0); + return; + } + + writer.Write(list.Count); + foreach (var item in list) + { + itemSerializer(writer, item); + } + } + + /// + /// Deserializes a generic list from a BinaryReader. + /// + /// The type of elements in the list. + /// The BinaryReader to read from. + /// The delegate to deserialize each item. + /// The deserialized list. + public static List ReadList(this BinaryReader reader, Func itemDeserializer) + { + var count = reader.ReadInt32(); + if (count == 0) + return new List(); + + var list = new List(count); + for (int i = 0; i < count; i++) + { + list.Add(itemDeserializer(reader)); + } + return list; + } + + /// + /// Serializes a generic dictionary to a BinaryWriter. + /// + /// The type of keys in the dictionary. + /// The type of values in the dictionary. + /// The BinaryWriter to write to. + /// The dictionary to serialize. + /// The delegate to serialize each key. + /// The delegate to serialize each value. + public static void WriteDictionary( + this BinaryWriter writer, + IDictionary? dictionary, + Action keySerializer, + Action valueSerializer) where TKey : notnull + { + if (dictionary == null || dictionary.Count == 0) + { + writer.Write((int)0); + return; + } + + writer.Write(dictionary.Count); + foreach (var kvp in dictionary) + { + keySerializer(writer, kvp.Key); + valueSerializer(writer, kvp.Value); + } + } + + /// + /// Deserializes a generic dictionary from a BinaryReader. + /// + /// The type of keys in the dictionary. + /// The type of values in the dictionary. + /// The BinaryReader to read from. + /// The delegate to deserialize each key. + /// The delegate to deserialize each value. + /// The deserialized dictionary. + public static Dictionary ReadDictionary( + this BinaryReader reader, + Func keyDeserializer, + Func valueDeserializer) where TKey : notnull + { + var count = reader.ReadInt32(); + if (count == 0) + return new Dictionary(); + + var dictionary = new Dictionary(count); + for (int i = 0; i < count; i++) + { + var key = keyDeserializer(reader); + var value = valueDeserializer(reader); + dictionary[key] = value; + } + return dictionary; + } + + /// + /// Serializes an ISerializableEntity to a BinaryWriter. + /// + /// The BinaryWriter to write to. + /// The entity to serialize. + public static void WriteEntity(this BinaryWriter writer, ISerializableEntity entity) + { + writer.WriteSerial(entity.Id); + } + + /// + /// Serializes a byte array to a BinaryWriter. + /// + /// The BinaryWriter to write to. + /// The data to serialize. + public static void WriteByteArray(this BinaryWriter writer, byte[]? data) + { + if (data == null || data.Length == 0) + { + writer.Write((int)0); + return; + } + + writer.Write(data.Length); + writer.Write(data); + } + + /// + /// Deserializes a byte array from a BinaryReader. + /// + /// The BinaryReader to read from. + /// The deserialized byte array. + public static byte[] ReadByteArray(this BinaryReader reader) + { + var length = reader.ReadInt32(); + if (length == 0) + return Array.Empty(); + + return reader.ReadBytes(length); + } + + /// + /// Serializes an enum type to a BinaryWriter. + /// + /// The type of the enum. + /// The BinaryWriter to write to. + /// The enum value to serialize. + public static void WriteEnum(this BinaryWriter writer, TEnum value) where TEnum : struct, Enum + { + writer.Write(Convert.ToInt32(value)); + } + + /// + /// Deserializes an enum type from a BinaryReader. + /// + /// The type of the enum. + /// The BinaryReader to read from. + /// The deserialized enum value. + public static TEnum ReadEnum(this BinaryReader reader) where TEnum : struct, Enum + { + return (TEnum)Enum.ToObject(typeof(TEnum), reader.ReadInt32()); + } +} diff --git a/src/Prima.UOData/Interfaces/Persistence/IEntitySerializer.cs b/src/Prima.UOData/Interfaces/Persistence/IEntitySerializer.cs index 81b7770..3977efb 100644 --- a/src/Prima.UOData/Interfaces/Persistence/IEntitySerializer.cs +++ b/src/Prima.UOData/Interfaces/Persistence/IEntitySerializer.cs @@ -6,14 +6,12 @@ public interface IEntitySerializer byte Header { get; } - byte[] Serialize(object entity); + byte[] Serialize(object entity, IPersistenceManager persistenceManager); - object Deserialize(byte[] data); + object Deserialize(byte[] data, IPersistenceManager persistenceManager); } public interface IEntitySerializer : IEntitySerializer { - byte[] Serialize(TEntity entity); - - + byte[] Serialize(TEntity entity, IPersistenceManager persistenceManager); } diff --git a/src/Prima.UOData/Serializers/Base/BaseEntitySerializer.cs b/src/Prima.UOData/Serializers/Base/BaseEntitySerializer.cs index f3b1d55..6e01d0f 100644 --- a/src/Prima.UOData/Serializers/Base/BaseEntitySerializer.cs +++ b/src/Prima.UOData/Serializers/Base/BaseEntitySerializer.cs @@ -25,11 +25,29 @@ protected BaseEntitySerializer() } - public byte[] Serialize(object entity) + public byte[] Serialize(object entity, IPersistenceManager persistenceManager) { - return Serialize(entity as TEntity); + return Serialize(entity as TEntity, persistenceManager); } - public abstract object Deserialize(byte[] data); - public abstract byte[] Serialize(TEntity entity); + public byte[] Serialize(TEntity entity, IPersistenceManager persistenceManager) + { + using var stream = new MemoryStream(); + using var writer = new BinaryWriter(stream); + Serialize(writer, entity, persistenceManager); + + writer.Flush(); + return stream.ToArray(); + } + + public object Deserialize(byte[] data, IPersistenceManager persistenceManager) + { + using var stream = new MemoryStream(data); + using var reader = new BinaryReader(stream); + return Deserialize(reader, persistenceManager); + } + + public abstract void Serialize(BinaryWriter writer, TEntity entity, IPersistenceManager persistenceManager); + + public abstract object Deserialize(BinaryReader reader, IPersistenceManager persistenceManager); } diff --git a/src/Prima.UOData/Serializers/Binary/BinaryItemSerializer.cs b/src/Prima.UOData/Serializers/Binary/BinaryItemSerializer.cs index 310e227..96778ee 100644 --- a/src/Prima.UOData/Serializers/Binary/BinaryItemSerializer.cs +++ b/src/Prima.UOData/Serializers/Binary/BinaryItemSerializer.cs @@ -1,36 +1,29 @@ using Orion.Foundations.Spans; using Prima.UOData.Entities; using Prima.UOData.Extensions; +using Prima.UOData.Interfaces.Persistence; using Prima.UOData.Serializers.Base; namespace Prima.UOData.Serializers.Binary; public class BinaryItemSerializer : BaseEntitySerializer { - public override object Deserialize(byte[] data) + public override void Serialize(BinaryWriter writer, ItemEntity entity, IPersistenceManager persistenceManager) { - using var stream = new BinaryReader(new MemoryStream(data)); + writer.Write(entity.Id); + writer.Write(entity.Name); + writer.Write(entity.Hue); + writer.Write(entity.Position); + } + public override object Deserialize(BinaryReader reader, IPersistenceManager persistenceManager) + { return new ItemEntity { - Id = stream.ReadSerial(), - Name = stream.ReadString(), - Hue = stream.ReadInt32(), - Position = stream.ReadPoint3D() + Id = reader.ReadSerial(), + Name = reader.ReadString(), + Hue = reader.ReadInt32(), + Position = reader.ReadPoint3D() }; } - - public override byte[] Serialize(ItemEntity entity) - { - var buffer = new MemoryStream(); - using var stream = new BinaryWriter(buffer); - - stream.Write(entity.Id); - stream.Write(entity.Name); - stream.Write(entity.Hue); - stream.Write(entity.Position); - - return buffer.ToArray(); - } - } diff --git a/src/Prima.UOData/Serializers/Binary/BinaryMobileSerializer.cs b/src/Prima.UOData/Serializers/Binary/BinaryMobileSerializer.cs index 66f3e53..7805d11 100644 --- a/src/Prima.UOData/Serializers/Binary/BinaryMobileSerializer.cs +++ b/src/Prima.UOData/Serializers/Binary/BinaryMobileSerializer.cs @@ -1,5 +1,6 @@ using Prima.UOData.Entities; using Prima.UOData.Extensions; +using Prima.UOData.Interfaces.Persistence; using Prima.UOData.Serializers.Base; using Prima.UOData.Types; @@ -7,56 +8,47 @@ namespace Prima.UOData.Serializers.Binary; public class BinaryMobileSerializer : BaseEntitySerializer { - public override object Deserialize(byte[] data) + public override void Serialize(BinaryWriter writer, MobileEntity entity, IPersistenceManager persistenceManager) { - using var buffer = new MemoryStream(data); - using var stream = new BinaryReader(buffer); + writer.Write(entity.Id); + writer.Write(entity.Name); + writer.Write(entity.IsPlayer); + writer.Write(entity.Hue); + writer.Write(entity.Position); + writer.Write(entity.Direction); + // Start to write items + writer.Write(entity.Items.Count); + foreach (var item in entity.Items) + { + writer.Write((byte)item.Key); + writer.Write(item.Value.Id); + } + } + + public override object Deserialize(BinaryReader reader, IPersistenceManager persistenceManager) + { var mobile = new MobileEntity { - Id = stream.ReadSerial(), - Name = stream.ReadString(), - IsPlayer = stream.ReadBoolean(), - Hue = stream.ReadInt32(), - Position = stream.ReadPoint3D(), - Direction = stream.ReadDirection() + Id = reader.ReadSerial(), + Name = reader.ReadString(), + IsPlayer = reader.ReadBoolean(), + Hue = reader.ReadInt32(), + Position = reader.ReadPoint3D(), + Direction = reader.ReadDirection() }; // Read items count - var itemsCount = stream.ReadInt32(); + var itemsCount = reader.ReadInt32(); for (var i = 0; i < itemsCount; i++) { - var itemId = stream.ReadSerial(); - var layer = (Layer)stream.ReadByte(); + var itemId = reader.ReadSerial(); + var layer = (Layer)reader.ReadByte(); var item = new ItemEntity(itemId); mobile.Items.Add(layer, item); } return mobile; } - - public override byte[] Serialize(MobileEntity entity) - { - using var buffer = new MemoryStream(); - using var stream = new BinaryWriter(buffer); - - stream.Write(entity.Id); - stream.Write(entity.Name); - stream.Write(entity.IsPlayer); - stream.Write(entity.Hue); - stream.Write(entity.Position); - stream.Write(entity.Direction); - // Start to write items - stream.Write(entity.Items.Count); - - foreach (var item in entity.Items) - { - stream.Write((byte)item.Key); - stream.Write(item.Value.Id); - } - - - return buffer.ToArray(); - } } From f3f453285f540c7b287e129f3c2665772e6e3139 Mon Sep 17 00:00:00 2001 From: squid Date: Sat, 17 May 2025 15:35:08 +0200 Subject: [PATCH 2/3] refactor(PersistenceManager.cs): remove unused using directives to clean up code feat(BinarySerializationExtensions.cs): add serialization and deserialization methods for Point3D, Serial, and Direction feat(BinarySerializationExtensions.cs): add Write and Read methods for Point3D, Serial, and Direction in BinaryWriter feat(BinarySerializationExtensions.cs): add Write and Read methods for Point3D in BinaryWriter feat(BinarySerializationExtensions.cs): add Write and Read methods for Serial in BinaryWriter feat(BinarySerializationExtensions.cs): add Write and Read methods for Direction in BinaryWriter feat(BinarySerializationExtensions.cs): add Write method for Point3D in BinaryWriter feat(BinarySerializationExtensions.cs): add Write method for Serial in BinaryWriter feat(BinarySerializationExtensions.cs): add Write method for Direction in BinaryWriter feat(BinarySerializationExtensions.cs): add Read method for Direction in BinaryReader feat(BinarySerializationExtensions.cs): add Write method for IHaveSerial in BinaryWriter feat(BinarySerializationExtensions.cs): add ReadString method in BinaryReader feat(BinarySerializationExtensions.cs): add Write method for List in BinaryWriter feat(BinaryMobileSerializer.cs): add writing direction in BinaryMobileSerializer --- .../Services/PersistenceManager.cs | 4 - .../BinarySerializationExtensions.cs | 52 ++++++++ .../Extensions/StreamWriterExtension.cs | 117 ------------------ .../Binary/BinaryMobileSerializer.cs | 1 + 4 files changed, 53 insertions(+), 121 deletions(-) delete mode 100644 src/Prima.UOData/Extensions/StreamWriterExtension.cs diff --git a/src/Prima.Server/Services/PersistenceManager.cs b/src/Prima.Server/Services/PersistenceManager.cs index 1e50e79..5a9f72d 100644 --- a/src/Prima.Server/Services/PersistenceManager.cs +++ b/src/Prima.Server/Services/PersistenceManager.cs @@ -1,6 +1,4 @@ using System.Security.Cryptography; -using Orion.Core.Server.Data.Directories; -using Orion.Foundations.Utils; using Prima.Core.Server.Data.Serialization; using Prima.UOData.Interfaces.Persistence; using Prima.UOData.Interfaces.Persistence.Entities; @@ -24,8 +22,6 @@ public PersistenceManager(ILogger logger) } - - public async Task SerializeAsync(TEntity entity) where TEntity : ISerializableEntity { ArgumentNullException.ThrowIfNull(entity); diff --git a/src/Prima.UOData/Extensions/BinarySerializationExtensions.cs b/src/Prima.UOData/Extensions/BinarySerializationExtensions.cs index 7a1604e..e0b9c38 100644 --- a/src/Prima.UOData/Extensions/BinarySerializationExtensions.cs +++ b/src/Prima.UOData/Extensions/BinarySerializationExtensions.cs @@ -1,6 +1,8 @@ using System.Text; +using Prima.UOData.Data.Geometry; using Prima.UOData.Id; using Prima.UOData.Interfaces.Persistence.Entities; +using Prima.UOData.Types; namespace Prima.UOData.Extensions; @@ -224,4 +226,54 @@ public static TEnum ReadEnum(this BinaryReader reader) where TEnum : stru { return (TEnum)Enum.ToObject(typeof(TEnum), reader.ReadInt32()); } + + /// + /// Serializes a Point3D to a BinaryWriter. + /// + /// + /// + public static void Write(this BinaryWriter writer, Point3D point) + { + writer.Write(point.X); + writer.Write(point.Y); + writer.Write(point.Z); + } + + /// + /// Deserializes a Point3D from a BinaryReader. + /// + /// + /// + public static Point3D ReadPoint3D(this BinaryReader reader) + { + return new Point3D(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32()); + } + + + /// + /// Serializes a Serial to a BinaryWriter. + /// + /// + /// + public static void Write(this BinaryWriter writer, Serial serial) + { + writer.Write(serial.Value); + } + + /// + /// Deserializes a Serial from a BinaryReader. + /// + /// + /// + public static void Write(this BinaryWriter writer, Direction direction) + { + writer.Write((byte)direction); + } + + public static Direction ReadDirection(this BinaryReader reader) + { + return (Direction)reader.ReadByte(); + } + + } diff --git a/src/Prima.UOData/Extensions/StreamWriterExtension.cs b/src/Prima.UOData/Extensions/StreamWriterExtension.cs deleted file mode 100644 index 94236b4..0000000 --- a/src/Prima.UOData/Extensions/StreamWriterExtension.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System.Text; -using Orion.Foundations.Spans; -using Prima.UOData.Data.Geometry; -using Prima.UOData.Id; -using Prima.UOData.Interfaces.Entities; -using Prima.UOData.Types; - -namespace Prima.UOData.Extensions; - -public static class StreamWriterExtension -{ - public static void Write(this BinaryWriter writer, string? str) - { - if (str == null) - { - writer.Write((byte)0); - return; - } - - var bytes = Encoding.UTF8.GetBytes(str); - writer.Write((byte)bytes.Length); - writer.Write(bytes); - } - - - public static void Write(this BinaryWriter writer, Point2D point) - { - writer.Write((short)point.X); - writer.Write((short)point.Y); - } - - public static Point2D ReadPoint(this BinaryReader reader) - { - var x = reader.ReadInt16(); - var y = reader.ReadInt16(); - - return new Point2D(x, y); - } - - public static Point3D ReadPoint3D(this BinaryReader reader) - { - var x = reader.ReadInt16(); - var y = reader.ReadInt16(); - var z = reader.ReadInt16(); - - return new Point3D(x, y, z); - } - - public static void Write(this BinaryWriter writer, Point3D point) - { - writer.Write((short)point.X); - writer.Write((short)point.Y); - writer.Write((short)point.Z); - } - - public static void Write(this BinaryWriter writer, Direction direction) - { - writer.Write((byte)direction); - } - - - public static void Write(this BinaryWriter writer, Serial serial) - { - writer.Write((uint)serial.Value); - } - - - public static Serial ReadSerial(this BinaryReader reader) - { - return new Serial(reader.ReadUInt32()); - } - - public static Serial ReadSerial(this SpanReader reader) - { - return new Serial(reader.ReadUInt32()); - } - - - public static Direction ReadDirection(this BinaryReader reader) - { - return (Direction)reader.ReadByte(); - } - - - - public static void Write(this BinaryWriter writer, IHaveSerial serial) - { - writer.Write(serial.Id.Value); - } - - public static string ReadString(this BinaryReader reader) - { - var length = reader.ReadByte(); - if (length == 0) - return string.Empty; - - var bytes = reader.ReadBytes(length); - return Encoding.UTF8.GetString(bytes); - } - - - public static void Write(this BinaryWriter writer, List? list) where T : class, IHaveSerial - { - if (list == null) - { - writer.Write((byte)0); - return; - } - - writer.Write((byte)list.Count); - - foreach (var item in list) - { - writer.Write(item); - } - } -} diff --git a/src/Prima.UOData/Serializers/Binary/BinaryMobileSerializer.cs b/src/Prima.UOData/Serializers/Binary/BinaryMobileSerializer.cs index 7805d11..53594d1 100644 --- a/src/Prima.UOData/Serializers/Binary/BinaryMobileSerializer.cs +++ b/src/Prima.UOData/Serializers/Binary/BinaryMobileSerializer.cs @@ -16,6 +16,7 @@ public override void Serialize(BinaryWriter writer, MobileEntity entity, IPersis writer.Write(entity.Hue); writer.Write(entity.Position); writer.Write(entity.Direction); + // Start to write items writer.Write(entity.Items.Count); From a80b084f0622bc4249016a7749add392df637f18 Mon Sep 17 00:00:00 2001 From: squid Date: Sun, 18 May 2025 09:15:14 +0200 Subject: [PATCH 3/3] feat(CharacterHandler.cs): add session property setting for playerMobile feat(LoginCompleteHandler.cs): update FeatureFlagsResponse to include T2A flag refactor(LoginHandler.cs): add null check for mobile before setting CharacterEntry feat(Program.cs): add LoginCompleteHandler service to service collection refactor(AccountManager.cs): change generatedPassword to "admin" for default admin user refactor(NetworkService.cs): remove debug log for transport data, add debug log for packet data feat(PersistenceManager.cs): add Serialize method for entity serialization feat(IPersistenceManager.cs): add Serialize method for entity serialization refactor(BinaryMobileSerializer.cs): update serialization of item values in BinaryMobileSerializer --- src/Prima.Server/Handlers/CharacterHandler.cs | 2 ++ .../Handlers/LoginCompleteHandler.cs | 2 +- src/Prima.Server/Handlers/LoginHandler.cs | 9 ++++++++- src/Prima.Server/Program.cs | 1 + src/Prima.Server/Services/AccountManager.cs | 2 +- src/Prima.Server/Services/NetworkService.cs | 16 +++++++++------- src/Prima.Server/Services/PersistenceManager.cs | 16 ++++++++++++++++ .../Persistence/IPersistenceManager.cs | 2 ++ src/Prima.UOData/Packets/DrawGamePlayer.cs | 2 +- src/Prima.UOData/Packets/LoginComplete.cs | 6 ++++++ .../Serializers/Binary/BinaryMobileSerializer.cs | 9 ++++----- 11 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/Prima.Server/Handlers/CharacterHandler.cs b/src/Prima.Server/Handlers/CharacterHandler.cs index 2ef1597..9e09a1e 100644 --- a/src/Prima.Server/Handlers/CharacterHandler.cs +++ b/src/Prima.Server/Handlers/CharacterHandler.cs @@ -60,6 +60,8 @@ public async Task OnPacketReceived(NetworkSession session, CharacterCreation pac playerMobile.Name = packet.Name; + session.SetProperty(playerMobile); + _worldManagerService.AddWorldEntity(playerMobile); diff --git a/src/Prima.Server/Handlers/LoginCompleteHandler.cs b/src/Prima.Server/Handlers/LoginCompleteHandler.cs index 9152e41..672100f 100644 --- a/src/Prima.Server/Handlers/LoginCompleteHandler.cs +++ b/src/Prima.Server/Handlers/LoginCompleteHandler.cs @@ -38,7 +38,7 @@ public async Task HandleAsync(LoginCompleteEvent @event, CancellationToken cance await session.SendPacketAsync(new GlobalLightLevel(0xFF)); await session.SendPacketAsync(new PersonalLightLevel(mobile, 0xFF)); - await session.SendPacketAsync(new FeatureFlagsResponse(FeatureFlags.UOR | FeatureFlags.AOS)); + await session.SendPacketAsync(new FeatureFlagsResponse(FeatureFlags.T2A | FeatureFlags.UOR)); await session.SendPacketAsync(new CharacterWarMode(false)); await session.SendPacketAsync(new LoginComplete()); } diff --git a/src/Prima.Server/Handlers/LoginHandler.cs b/src/Prima.Server/Handlers/LoginHandler.cs index 9b2a13d..cf32b56 100644 --- a/src/Prima.Server/Handlers/LoginHandler.cs +++ b/src/Prima.Server/Handlers/LoginHandler.cs @@ -205,7 +205,14 @@ public async Task OnPacketReceived(NetworkSession session, GameServerLogin packe var character = characters.ToList()[i]; var mobile = _worldManagerService.GetEntityBySerial(character.MobileId); - charactersAndCities.Characters[i] = new CharacterEntry(mobile.Name); + if (mobile != null) + { + charactersAndCities.Characters[i] = new CharacterEntry(mobile.Name); + } + else + { + Logger.LogWarning("Character {CharacterId} not found", character.Id); + } } diff --git a/src/Prima.Server/Program.cs b/src/Prima.Server/Program.cs index 04ba984..a2317d8 100644 --- a/src/Prima.Server/Program.cs +++ b/src/Prima.Server/Program.cs @@ -130,6 +130,7 @@ static async Task Main(string[] args) .AddService() .AddService() .AddService() + .AddService() .AddService(); builder.Services.AddHostedService(); diff --git a/src/Prima.Server/Services/AccountManager.cs b/src/Prima.Server/Services/AccountManager.cs index ce62a0c..0e6753c 100644 --- a/src/Prima.Server/Services/AccountManager.cs +++ b/src/Prima.Server/Services/AccountManager.cs @@ -124,7 +124,7 @@ private async Task CheckDefaultAdminUserAsync() return; } - var generatedPassword = HashUtils.GenerateRandomRefreshToken(8); + var generatedPassword = "admin"; var defaultAdminUser = new AccountEntity { diff --git a/src/Prima.Server/Services/NetworkService.cs b/src/Prima.Server/Services/NetworkService.cs index b3410d1..f45297a 100644 --- a/src/Prima.Server/Services/NetworkService.cs +++ b/src/Prima.Server/Services/NetworkService.cs @@ -104,13 +104,6 @@ DirectoriesConfig directoriesConfig { var transport = _networkTransportManager.GetTransport(transportId); - _logger.LogDebug( - "-> {Session} ({Size} bytes) {Transport} {Data}", - id.ToShortSessionId(), - data.Length, - transport.Id, - data.HumanizedContent(20) - ); }; } @@ -233,6 +226,15 @@ private async Task SendPacketInternal(string sessionId, IUoNetworkPacket packet) } + + _logger.LogDebug( + "-> {PacketType} {Session} ({Size} bytes) {Data}", + packet.GetType().Name, + sessionId.ToShortSessionId(), + data.Length, + data.ToArray().HumanizedContent(20) + ); + await _networkTransportManager.EnqueueMessageAsync( new NetworkMessageData(sessionId, data.ToArray(), ServerNetworkType.None) ); diff --git a/src/Prima.Server/Services/PersistenceManager.cs b/src/Prima.Server/Services/PersistenceManager.cs index 5a9f72d..eebefb2 100644 --- a/src/Prima.Server/Services/PersistenceManager.cs +++ b/src/Prima.Server/Services/PersistenceManager.cs @@ -38,6 +38,22 @@ public async Task SerializeAsync(TEntity entity return new SerializationEntryData(serializer.Header, serializerData); } + public SerializationEntryData Serialize(TEntity entity) where TEntity : ISerializableEntity + { + ArgumentNullException.ThrowIfNull(entity); + + var serializer = _entitySerializersAsType[entity.GetType()]; + + if (serializer is null) + { + throw new InvalidOperationException($"No serializer registered for entity type {entity.GetType()}"); + } + + var serializerData = serializer.Serialize(entity, this); + + return new SerializationEntryData(serializer.Header, serializerData); + } + public void RegisterEntitySerializer(IEntitySerializer serializer) where TEntity : ISerializableEntity { ArgumentNullException.ThrowIfNull(serializer); diff --git a/src/Prima.UOData/Interfaces/Persistence/IPersistenceManager.cs b/src/Prima.UOData/Interfaces/Persistence/IPersistenceManager.cs index 0d827ef..e434e69 100644 --- a/src/Prima.UOData/Interfaces/Persistence/IPersistenceManager.cs +++ b/src/Prima.UOData/Interfaces/Persistence/IPersistenceManager.cs @@ -8,6 +8,8 @@ public interface IPersistenceManager : IOrionService { Task SerializeAsync(TEntity entity) where TEntity : ISerializableEntity; + SerializationEntryData Serialize(TEntity entity) where TEntity : ISerializableEntity; + // Task> DeserializeAsync(byte[] data) where TEntity : ISerializableEntity; void RegisterEntitySerializer(IEntitySerializer serializer) where TEntity : ISerializableEntity; diff --git a/src/Prima.UOData/Packets/DrawGamePlayer.cs b/src/Prima.UOData/Packets/DrawGamePlayer.cs index 04b5819..3851aab 100644 --- a/src/Prima.UOData/Packets/DrawGamePlayer.cs +++ b/src/Prima.UOData/Packets/DrawGamePlayer.cs @@ -36,7 +36,7 @@ public DrawGamePlayer() : base(0x20, 19) public override Span Write() { - using var writer = new SpanWriter(stackalloc byte[Length - 1]); + using var writer = new SpanWriter(stackalloc byte[Length]); writer.Write((uint)MobileId); writer.Write((short)BodyType); diff --git a/src/Prima.UOData/Packets/LoginComplete.cs b/src/Prima.UOData/Packets/LoginComplete.cs index a4cd63b..1a787b5 100644 --- a/src/Prima.UOData/Packets/LoginComplete.cs +++ b/src/Prima.UOData/Packets/LoginComplete.cs @@ -7,4 +7,10 @@ public class LoginComplete : BaseUoNetworkPacket public LoginComplete() : base(0x55, 1) { } + + public override Span Write() + { + + return Span.Empty; + } } diff --git a/src/Prima.UOData/Serializers/Binary/BinaryMobileSerializer.cs b/src/Prima.UOData/Serializers/Binary/BinaryMobileSerializer.cs index 53594d1..95f0932 100644 --- a/src/Prima.UOData/Serializers/Binary/BinaryMobileSerializer.cs +++ b/src/Prima.UOData/Serializers/Binary/BinaryMobileSerializer.cs @@ -23,7 +23,10 @@ public override void Serialize(BinaryWriter writer, MobileEntity entity, IPersis foreach (var item in entity.Items) { writer.Write((byte)item.Key); - writer.Write(item.Value.Id); + var bytes = persistenceManager.Serialize(item.Value); + + writer.Write(bytes.Length); + writer.Write(bytes.Data); } } @@ -44,10 +47,6 @@ public override object Deserialize(BinaryReader reader, IPersistenceManager pers for (var i = 0; i < itemsCount; i++) { - var itemId = reader.ReadSerial(); - var layer = (Layer)reader.ReadByte(); - var item = new ItemEntity(itemId); - mobile.Items.Add(layer, item); } return mobile;