diff --git a/Articulate-Network.csproj b/Articulate-Network.csproj
index cbf6406..abf17fc 100644
--- a/Articulate-Network.csproj
+++ b/Articulate-Network.csproj
@@ -44,9 +44,11 @@
+
+
diff --git a/Client.cs b/Client.cs
index 9c0f576..2c875a3 100644
--- a/Client.cs
+++ b/Client.cs
@@ -1,9 +1,14 @@
using Articulate_Network.Interfaces;
+using Articulate_Network.Managers;
+using Articulate_Network.Packets;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
+using System.Reflection;
using System.Text;
using System.Threading.Tasks;
@@ -12,12 +17,19 @@ namespace Articulate_Network
public class Client
{
List managers = new List();
+ int bufferSize = 16384;
TcpClient tcp;
public Client()
{
- tcp = new TcpClient();
+ InitializeManagers();
+
+ tcp = new TcpClient()
+ {
+ SendBufferSize = bufferSize,
+ ReceiveBufferSize = bufferSize
+ };
}
public async Task Connect(string ip, int port)
@@ -28,6 +40,11 @@ namespace Articulate_Network
{
tcp.Connect(ip, port);
+ tcp.SendBufferSize = bufferSize;
+ tcp.ReceiveBufferSize = bufferSize;
+
+ _ = ReceiveData();
+
return tcp;
}
catch (Exception e)
@@ -39,9 +56,121 @@ namespace Articulate_Network
);
}
- public async Task SendPacket(IPacket packet)
+ public async Task SendPacket(Packet packet)
{
+ await Task.Run(() =>
+ {
+ byte[] buffer = Get().SerializePacket(packet);
+
+ tcp.Client.Send(buffer, buffer.Length, SocketFlags.None);
+ });
+
return false;
}
+
+ public async Task ReceiveData()
+ {
+ await Task.Run(() =>
+ {
+ byte[] buffer = new byte[bufferSize];
+
+ int offset = 0;
+
+ while (true)
+ {
+ int bytesToRead = tcp.Client.Receive(buffer, offset, buffer.Length - offset, SocketFlags.None);
+
+ //Console.WriteLine("Bytes to read: " + bytesToRead);
+
+ var ms = new MemoryStream(buffer, 0, bytesToRead);
+ var br = new BinaryReader(ms);
+
+ while (ms.Position < ms.Length)
+ {
+ int length = (int)br.ReadInt64();
+
+ OnDataReceived(new Articulate_Network.Events.DataReceivedEventArgs()
+ {
+ Packet = Get().DeserializePacket(ms)
+ });
+
+ int end = (int)br.ReadInt64();
+
+ bool endOfPacket = end == length;
+
+ if (endOfPacket && ms.Position < ms.Length)
+ {
+ int nextPacketSize = (int)br.ReadInt64();
+
+ ms.Position -= 8;
+
+ Console.WriteLine("Next size: " + nextPacketSize);
+
+ offset = (int)(ms.Length - ms.Position);
+
+ buffer = new byte[bufferSize];
+
+ ms.Read(buffer, 0, offset);
+
+ break;
+ }
+
+ //Console.WriteLine(ms.Position);
+
+ /*if (ms.Position + length > ms.Length)
+ {
+ Console.WriteLine("Bytes to read: " + bytesToRead);
+ Console.WriteLine("Memory length: " + ms.Length);
+ Console.WriteLine("Memory Pos: " + ms.Position);
+ Console.WriteLine("Length: " + length);
+ ms.Position -= 8;
+
+ buffer = new byte[bufferSize];
+
+ ms.Read(buffer, 0, offset);
+ break;
+ }*/
+ }
+ }
+ });
+
+ return false;
+ }
+
+ public void InitializeManagers()
+ {
+ var @interface = typeof(IManager);
+
+ foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
+ {
+ var managersFound = assembly.GetTypes().Where(t => @interface.IsAssignableFrom(t) && !t.IsAbstract);
+
+ foreach (var m in managersFound)
+ {
+ var manager = (IManager)Activator.CreateInstance(m);
+
+ manager.Initialize();
+
+ managers.Add(manager);
+ }
+ }
+
+ Console.WriteLine($"Initialized {managers.Count} manager{(managers.Count > 1 ? "s" : "")}");
+ }
+
+ public T Get()
+ {
+ return (T)managers.SingleOrDefault(t => typeof(T) == t.GetType());
+ }
+
+ protected virtual void OnDataReceived(Articulate_Network.Events.DataReceivedEventArgs e)
+ {
+ EventHandler handler = DataReceived;
+
+ if (handler != null)
+ handler(this, e);
+ }
+
+ public event EventHandler DataReceived;
}
}
diff --git a/Managers/PacketManager.cs b/Managers/PacketManager.cs
index 3aa3158..3f69161 100644
--- a/Managers/PacketManager.cs
+++ b/Managers/PacketManager.cs
@@ -1,5 +1,6 @@
using Articulate_Network.Attributes;
using Articulate_Network.Interfaces;
+using Articulate_Network.Packets;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -14,7 +15,7 @@ namespace Articulate_Network.Managers
public class PacketManager : IManager
{
Dictionary> packetInfo = new Dictionary>();
- Dictionary packetInstances = new Dictionary();
+ Dictionary packetInstances = new Dictionary();
public void Initialize()
{
@@ -22,13 +23,13 @@ namespace Articulate_Network.Managers
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
- var managersFound = assembly.GetTypes().Where(t => @interface.IsAssignableFrom(t) && !t.IsAbstract);
+ var packetsFound = assembly.GetTypes().Where(t => @interface.IsAssignableFrom(t) && !t.IsAbstract);
- foreach (var p in managersFound)
+ foreach (var p in packetsFound)
{
- var packet = (IPacket)Activator.CreateInstance(p);
+ var packet = (Packet)Activator.CreateInstance(p);
- packetInstances.Add(p, packet);
+ packetInstances.Add(p.Name, packet);
LoadPacketInfo(packet);
}
}
@@ -41,7 +42,7 @@ namespace Articulate_Network.Managers
packetInfo.Add(packet.GetType(), packet.GetType().GetProperties().Where(f => !Attribute.IsDefined(f, typeof(PacketIgnore))).OrderBy(f => f.Name).ToList());
}
- public T Send(IPacket packet)
+ public void Send(Packet packet)
{
Stopwatch watch = new Stopwatch();
watch.Start();
@@ -57,19 +58,24 @@ namespace Articulate_Network.Managers
var serialized = SerializePacket(packet);
- var deserialized = DeserializePacket(serialized);
+ //var deserialized = DeserializePacket(serialized);
- return (T)deserialized;
+ //return (T)deserialized;
}
- public MemoryStream SerializePacket(IPacket packet)
+ public byte[] SerializePacket(Packet packet)
{
+ if (!packetInfo.ContainsKey(packet.GetType()))
+ LoadPacketInfo(packet);
+
Stopwatch watch = new Stopwatch();
watch.Start();
var fields = packetInfo[packet.GetType()];
- MemoryStream memoryStream = new MemoryStream();
- BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
+ MemoryStream buffer = new MemoryStream();
+ BinaryWriter binaryWriter = new BinaryWriter(buffer);
+
+ binaryWriter.Write(packet.GetType().Name);
foreach (var field in fields)
{
@@ -79,27 +85,57 @@ namespace Articulate_Network.Managers
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));
+ 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);
}
- memoryStream.Position = 0;
+ 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 memoryStream;
+ //Console.WriteLine($"Serialize time: {watch.ElapsedTicks / 10} microseconds");
+ return buffer.ToArray();
}
- public T DeserializePacket(Stream stream)
+ public Packet DeserializePacket(MemoryStream stream)
{
Stopwatch watch = new Stopwatch();
watch.Start();
- IPacket packet = /*packetInstances[typeof(T)];*/(IPacket)Activator.CreateInstance(typeof(T));
-
- var fields = packetInfo[typeof(T)];
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))
@@ -108,15 +144,37 @@ namespace Articulate_Network.Managers
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");
+ //Console.WriteLine($"Deserialize time: {watch.ElapsedTicks / 10} microseconds");
- return (T)packet;
+ return packet;
+ }
+
+ public Packet DeserializePacket(byte[] bytes)
+ {
+ return DeserializePacket(new MemoryStream(bytes));
+ }
+
+ public void HandlePacket(Packet packet)
+ {
+ Console.WriteLine(packet.GetType().Name);
}
}
}
diff --git a/Packets/Packet.cs b/Packets/Packet.cs
new file mode 100644
index 0000000..71a76c8
--- /dev/null
+++ b/Packets/Packet.cs
@@ -0,0 +1,14 @@
+using Articulate_Network.Interfaces;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Articulate_Network.Packets
+{
+ public abstract class Packet : IPacket
+ {
+
+ }
+}
diff --git a/Server.cs b/Server.cs
index f53f4c3..17309cc 100644
--- a/Server.cs
+++ b/Server.cs
@@ -1,8 +1,10 @@
using Articulate_Network.Events;
using Articulate_Network.Interfaces;
using Articulate_Network.Managers;
+using Articulate_Network.Packets;
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
@@ -15,15 +17,13 @@ namespace Articulate_Network
public class Server
{
List managers = new List();
- List clients = new List();
+ TcpClient[] clients = new TcpClient[300];
TcpListener tcpListener;
public Server()
{
InitializeManagers();
-
- Console.WriteLine($"Initialized {managers.Count} manager{(managers.Count > 1 ? "s" : "")}");
}
public async Task Start(string ip, int port)
@@ -57,16 +57,74 @@ namespace Articulate_Network
{
var client = await tcpListener.AcceptTcpClientAsync();
- clients.Add(client);
+ for (int i = 0; i < clients.Length; i++)
+ if (clients[i] == null)
+ {
+ clients[i] = client;
+ Console.WriteLine($"Client {i+1} connected from {(client.Client.RemoteEndPoint as IPEndPoint).Address}.");
+ break;
+ }
+
+ _ = ReceiveData(client);
OnClientConnected(new ClientConnectedEventArgs() { TcpClient = client });
}
}
-
-
- public async Task SendPacket(IPacket packet)
+ public async Task ReceiveData(TcpClient client)
{
+ await Task.Run(() =>
+ {
+ byte[] buffer = new byte[8192];
+ var ms = new MemoryStream(buffer);
+ var br = new BinaryReader(ms);
+
+ while (client.Connected)
+ {
+ try
+ {
+ int bytesToRead = client.Client.Receive(buffer, buffer.Length, SocketFlags.None);
+
+ ms.Position = 0;
+
+ while (ms.Position < bytesToRead)
+ {
+ int length = (int)br.ReadInt64();
+
+ OnDataReceived(new Articulate_Network.Events.DataReceivedEventArgs()
+ {
+ Packet = Get().DeserializePacket(ms),
+ Client = client
+ });
+
+ int end = (int)br.ReadInt64();
+ }
+ }
+ catch (SocketException e)
+ {
+ for (int i = 0; i < clients.Length; i++)
+ if (clients[i] == client)
+ {
+ clients[i] = null;
+ Console.WriteLine($"Client {i+1} lost connection.");
+ break;
+ }
+ }
+ }
+ });
+
+ return false;
+ }
+
+ public async Task SendPacket(TcpClient tcpClient, Packet packet)
+ {
+ await Task.Run(() =>
+ {
+ byte[] buffer = Get().SerializePacket(packet);
+
+ tcpClient.Client.Send(buffer, buffer.Length, SocketFlags.None);
+ });
+
return false;
}
@@ -87,6 +145,8 @@ namespace Articulate_Network
managers.Add(manager);
}
}
+
+ Console.WriteLine($"Initialized {managers.Count} manager{(managers.Count > 1 ? "s" : "")}");
}
public T Get()
@@ -103,5 +163,15 @@ namespace Articulate_Network
}
public event EventHandler ClientConnected;
+
+ protected virtual void OnDataReceived(Articulate_Network.Events.DataReceivedEventArgs e)
+ {
+ EventHandler handler = DataReceived;
+
+ if (handler != null)
+ handler(this, e);
+ }
+
+ public event EventHandler DataReceived;
}
}