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 managers = new List(); int bufferSize = 16384; TcpClient tcp; public Client() { InitializeManagers(); tcp = new TcpClient() { SendBufferSize = bufferSize, ReceiveBufferSize = bufferSize }; } public async Task 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 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); 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().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() { 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; } }