181 lines
5.8 KiB
C#
181 lines
5.8 KiB
C#
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<Type, List<PropertyInfo>> packetInfo = new Dictionary<Type, List<PropertyInfo>>();
|
|
Dictionary<string, Packet> packetInstances = new Dictionary<string, Packet>();
|
|
|
|
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<T>(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);
|
|
}
|
|
|
|
long length = buffer.Length;
|
|
byte[] packetData = buffer.ToArray();
|
|
|
|
buffer.SetLength(0);
|
|
|
|
binaryWriter.Write(length);
|
|
binaryWriter.Write(packetData);
|
|
binaryWriter.Write(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));
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|