using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using DuckEmulator.HabboHotel.Outside.Messages.Types; using DuckEmulator.HabboHotel.Outside.Clients; namespace DuckEmulator.HabboHotel.Inside.NET { class SocketConnection { private readonly uint Id; private Socket fSock; private AsyncCallback fAsync; private AsyncCallback fAsyncSend; private Object State = new Object(); private Object StateSend = new Object(); private Client Client; // Connection Buffer & Bytes internal const int BUFFER_SIZE = 8192; // Packelogged the right one internal byte[] BUFFER = new byte[BUFFER_SIZE]; internal Boolean IsAlive { get { if (GetSocket() == null) return false; return GetSocket().Connected; } } internal SocketConnection(uint Id, Socket Sock) { this.Id = Id; this.fSock = Sock; this.Client = new Client(Id, this); } internal void Start() { fAsync = new AsyncCallback(Invoke); fAsyncSend = new AsyncCallback(EndSend); State = GetSocket().BeginReceive(BUFFER, 0, BUFFER_SIZE, SocketFlags.None, GetRecvAsync(), State).AsyncState; } private void Invoke(IAsyncResult Result) { if (!IsAlive) { return; } ushort Data = new ushort(); try { Data = (ushort)GetSocket().EndReceive(Result); } catch { goto CLOSE; } if (Data > 0) { Execute(Utilities.ByteUtil.ChompBytes(BUFFER, 0, Data)); } else if (Data <= 0) { goto CLOSE; } try { State = GetSocket().BeginReceive(BUFFER, 0, BUFFER_SIZE, SocketFlags.None, GetRecvAsync(), State).AsyncState; return; } catch { goto CLOSE; } CLOSE: { Dispose(); } } internal void SendResponse(ServerMessage Message) { if (Message != null && IsAlive) { SendBytes(Message.GetBytes()); } } internal void EndSend(IAsyncResult Result) { if (!IsAlive) { return; } ushort Data = new ushort(); try { Data = (ushort)GetSocket().EndSend(Result); } catch { goto CLOSE; } if (Data > 0) { return; } CLOSE: { Dispose(); } } internal void SendString(string Message) { if (Message != null && IsAlive) { SendBytes(Encoding.ASCII.GetBytes(Message)); } } private void SendBytes(Byte[] Bytes) { if (!IsAlive) return; try { StateSend = GetSocket().BeginSend(Bytes, 0, Bytes.Length, SocketFlags.None, GetSendAsync(), StateSend).AsyncState; } catch { Dispose(); } } private void Execute(byte[] Bytes) { if (Bytes != null && Client != null) { Client.InvokeBytes(Bytes); } } internal void Dispose() { if (DuckEnvironment.SocketListener != null) { if (DuckEnvironment.SocketListener.GetFactory() != null) { DuckEnvironment.SocketListener.GetFactory().DisposeSocket(Id); } } if (Client != null) { Client.Dispose(true); Client = null; } if (GetSocket() != null) { GetSocket().Shutdown(SocketShutdown.Both); GetSocket().Dispose(); fSock = null; } if (fAsync != null) fAsync = null; } internal Socket GetSocket() { return this.fSock; } internal AsyncCallback GetSendAsync() { return this.fAsyncSend; } internal AsyncCallback GetRecvAsync() { return this.fAsync; } internal Client GetClient() { return this.Client; } } }