181 lines
5.3 KiB
C#
181 lines
5.3 KiB
C#
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;
|
|
|
|
namespace Articulate_Network
|
|
{
|
|
public class Client
|
|
{
|
|
List<IManager> managers = new List<IManager>();
|
|
int bufferSize = 16384;
|
|
|
|
TcpClient tcp;
|
|
|
|
public Client()
|
|
{
|
|
InitializeManagers();
|
|
|
|
tcp = new TcpClient()
|
|
{
|
|
SendBufferSize = bufferSize,
|
|
ReceiveBufferSize = bufferSize
|
|
};
|
|
}
|
|
|
|
public async Task<TcpClient> Connect(string ip, int port)
|
|
{
|
|
return await Task.Run(() =>
|
|
{
|
|
try
|
|
{
|
|
tcp.Connect(ip, port);
|
|
|
|
tcp.SendBufferSize = bufferSize;
|
|
tcp.ReceiveBufferSize = bufferSize;
|
|
|
|
_ = ReceiveData();
|
|
|
|
return tcp;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine(e.Message);
|
|
return tcp;
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
public async Task<bool> SendPacket(Packet packet)
|
|
{
|
|
await Task.Run(() =>
|
|
{
|
|
byte[] buffer = Get<PacketManager>().SerializePacket(packet);
|
|
|
|
tcp.Client.Send(buffer, buffer.Length, SocketFlags.None);
|
|
});
|
|
|
|
return false;
|
|
}
|
|
|
|
public async Task<bool> 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);
|
|
|
|
if (offset > 0)
|
|
offset = 0;
|
|
|
|
var ms = new MemoryStream(buffer);
|
|
var br = new BinaryReader(ms);
|
|
|
|
while (ms.Position < ms.Length)
|
|
{
|
|
if (ms.Position + 4 > ms.Length)
|
|
break;
|
|
|
|
int magic = br.ReadInt32();
|
|
|
|
if (magic != 6655)
|
|
{
|
|
//Console.WriteLine("Not the start of a packet.");
|
|
continue;
|
|
}
|
|
|
|
int length = (int)br.ReadInt64();
|
|
|
|
if (ms.Position + length > ms.Length) // Received partial packet data, store partial data and continue
|
|
{
|
|
ms.Position -= 12;
|
|
|
|
offset = (int)(ms.Length - ms.Position);
|
|
|
|
//Console.WriteLine($"Partial data. Offset: {offset}");
|
|
|
|
buffer = new byte[bufferSize];
|
|
|
|
ms.Read(buffer, 0, offset);
|
|
break;
|
|
}
|
|
|
|
ms.Position += length;
|
|
|
|
int end = (int)br.ReadInt64();
|
|
|
|
ms.Position -= 8;
|
|
ms.Position -= length;
|
|
|
|
if (length == end && length > 1) // Valid packet, trigger event
|
|
{
|
|
var p = Get<PacketManager>().DeserializePacket(ms);
|
|
|
|
OnDataReceived(new Articulate_Network.Events.DataReceivedEventArgs()
|
|
{
|
|
Packet = p
|
|
});
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine($"Not a valid packet. Length: {length} - End: {end} - Offset: {offset} - Position: {ms.Position}");
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
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<T>()
|
|
{
|
|
return (T)managers.SingleOrDefault(t => typeof(T) == t.GetType());
|
|
}
|
|
|
|
protected virtual void OnDataReceived(Articulate_Network.Events.DataReceivedEventArgs e)
|
|
{
|
|
EventHandler<Articulate_Network.Events.DataReceivedEventArgs> handler = DataReceived;
|
|
|
|
if (handler != null)
|
|
handler(this, e);
|
|
}
|
|
|
|
public event EventHandler<Articulate_Network.Events.DataReceivedEventArgs> DataReceived;
|
|
}
|
|
}
|