using Articulate_Network.Attributes; using Articulate_Network.Interfaces; using Articulate_Network.Packets; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace Articulate_Network.Managers { public class PacketManager : IManager { Dictionary> packetInfo = new Dictionary>(); Dictionary packetInstances = new Dictionary(); public void Initialize() { var @interface = typeof(IPacket); foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { var packetsFound = assembly.GetTypes().Where(t => @interface.IsAssignableFrom(t) && !t.IsAbstract); foreach (var p in packetsFound) { var packet = (Packet)Activator.CreateInstance(p); packetInstances.Add(p.Name, packet); LoadPacketInfo(packet); } } Console.WriteLine($"Registered {packetInstances.Count} packet{(packetInstances.Count == 1 ? "" : "s")}"); } public void LoadPacketInfo(IPacket packet) { packetInfo.Add(packet.GetType(), packet.GetType().GetProperties().Where(f => !Attribute.IsDefined(f, typeof(PacketIgnore))).OrderBy(f => f.Name).ToList()); } public void Send(Packet packet) { Stopwatch watch = new Stopwatch(); watch.Start(); if (!packetInfo.ContainsKey(packet.GetType())) LoadPacketInfo(packet); watch.Stop(); Console.WriteLine($"Reflection time: {watch.ElapsedTicks / 10} microseconds"); //send packet var serialized = SerializePacket(packet); //var deserialized = DeserializePacket(serialized); //return (T)deserialized; } public byte[] SerializePacket(Packet packet) { if (!packetInfo.ContainsKey(packet.GetType())) LoadPacketInfo(packet); Stopwatch watch = new Stopwatch(); watch.Start(); var fields = packetInfo[packet.GetType()]; MemoryStream buffer = new MemoryStream(); BinaryWriter binaryWriter = new BinaryWriter(buffer); binaryWriter.Write(packet.GetType().Name); foreach (var field in fields) { if (field.PropertyType == typeof(bool)) binaryWriter.Write((bool)field.GetValue(packet)); if (field.PropertyType == typeof(int)) binaryWriter.Write((int)field.GetValue(packet)); if (field.PropertyType == typeof(long)) binaryWriter.Write((long)field.GetValue(packet)); if (field.PropertyType == typeof(string)) binaryWriter.Write(((string)field.GetValue(packet)) ?? string.Empty); if (field.PropertyType.IsEnum) binaryWriter.Write((int)field.GetValue(packet)); if (field.PropertyType == typeof(byte[])) { byte[] buf = (byte[])field.GetValue(packet); binaryWriter.Write(buf.Length); binaryWriter.Write(buf); } //Console.WriteLine(field.Name); } byte[] packetData = buffer.ToArray(); long length = packetData.Length; buffer.SetLength(0); binaryWriter.Write(6655); binaryWriter.Write(length); binaryWriter.Write(packetData); binaryWriter.Write(length); //Console.WriteLine("Sent bytes: " + length); watch.Stop(); //Console.WriteLine($"Serialize time: {watch.ElapsedTicks / 10} microseconds"); return buffer.ToArray(); } public Packet DeserializePacket(MemoryStream stream) { Stopwatch watch = new Stopwatch(); watch.Start(); BinaryReader reader = new BinaryReader(stream); string typeName = reader.ReadString(); //Console.WriteLine(typeName); Packet packet = packetInstances[typeName];/*(IPacket)Activator.CreateInstance(typeof(T));*/ var fields = packetInfo[packet.GetType()]; //Console.WriteLine($"Stream length: {stream.Length}"); //Console.WriteLine($"Stream position: {stream.Position}"); foreach (var field in fields) { if (field.PropertyType == typeof(bool)) field.SetValue(packet, reader.ReadBoolean()); if (field.PropertyType == typeof(int)) field.SetValue(packet, reader.ReadInt32()); if (field.PropertyType == typeof(long)) field.SetValue(packet, reader.ReadInt64()); if (field.PropertyType == typeof(string)) field.SetValue(packet, reader.ReadString()); if (field.PropertyType.IsEnum) field.SetValue(packet, reader.ReadInt32()); if (field.PropertyType == typeof(byte[])) { int length = reader.ReadInt32(); field.SetValue(packet, reader.ReadBytes(length)); } } reader.ReadInt64(); watch.Stop(); //Console.WriteLine($"Deserialize time: {watch.ElapsedTicks / 10} microseconds"); return packet; } public Packet DeserializePacket(byte[] bytes) { return DeserializePacket(new MemoryStream(bytes)); } public void HandlePacket(Packet packet) { Console.WriteLine(packet.GetType().Name); } } }