using System; using System.Collections.Generic; using System.Text; using System.Net.Sockets; using Holo.Virtual.Users; using Holo.GameConnectionSystem; namespace Holo.Source.Socket_servers.ClientSocket { public class SocketExtension : Socket, IDisposable { #region Fields private byte[] mBuffer; private AsyncCallback mSendCallback; private AsyncCallback mReceiveCallback; private uint mSocketID; private string mConnectionIP; private virtualUser mUser; private bool Disposed = false; #endregion #region Constructor public SocketExtension(virtualUser pUser, SocketInformation pSock, uint pSockID, string pConnectionIP) : base(pSock) { this.mUser = pUser; this.mSocketID = pSockID; this.mConnectionIP = pConnectionIP; mReceiveCallback = new AsyncCallback(DataStreamReceived); mSendCallback = new AsyncCallback(DataSent); mBuffer = new byte[1024]; } #endregion #region Methods internal void SendData(string DataString) { try { byte[] ByteArray = System.Text.Encoding.Default.GetBytes(DataString + Convert.ToChar(1)); //Send(ByteArray); BeginSend(ByteArray, 0, ByteArray.Length, 0, mSendCallback, this); // Out.WriteLine("[" + mSocketID + "] <-- [" + DataString + "]"); } catch { Dispose(); } } private void DataSent(IAsyncResult pRes) { try { EndSend(pRes); } catch { Dispose(); } } internal void StartReceiveSequence() { mUser.pingOK = true; SendData("@@"); WaitForDataStream(); } private void WaitForDataStream() { try { BeginReceive(mBuffer, 0, mBuffer.Length, SocketFlags.None, mReceiveCallback, this); } catch { Dispose(); } } private void DataStreamReceived(IAsyncResult pRes) { try { List Packets = FilterData(EndReceive(pRes)); foreach (string Packet in Packets) //One packet, two packets ... { if (Packet == "") continue; // Out.WriteLine("[" + mSocketID + "] --> [" + Packet + "]"); try { mUser.ProcessPacket(Packet); } catch (Exception e) { continue; } } WaitForDataStream(); } catch { Dispose(); } } private List FilterData(int pBytes) { string UnFilteredPacket = System.Text.Encoding.Default.GetString(mBuffer, 0, pBytes); if (UnFilteredPacket.Length <= 0) //Empty packet, aka client closed { Dispose(); return null; } for (int i = 1; i < 9; i++) if (UnFilteredPacket.Contains("\x0" + i)) { //todo: Add to blacklist / ban user Dispose(); //Hacker?! :O return null; } //string[] FilteredPackets = new string[30]; //Max packets processed per request StringBuilder Packets = new StringBuilder(UnFilteredPacket); List DecodedPackets = new List(); while (Packets.Length > 0) { int PacketLength = Encoding.decodeB64(Packets.ToString().Substring(1, 2)); //FilteredPackets[Array.IndexOf(FilteredPackets, null)] = Packets.ToString().Substring(3, PacketLength); DecodedPackets.Add(Packets.ToString().Substring(3, PacketLength)); Packets.Remove(0, 3 + PacketLength); } return DecodedPackets; } #endregion #region IDisposable members public void Dispose() { if (Disposed) return; Disposed = true; try { if (base.Connected) Close(); } catch { } try { mUser.Reset(); } catch { } gameSocketServer.DisposeConnection(mSocketID); Dispose(true); GC.SuppressFinalize(this); // Good night and sleep well ^^, } ~SocketExtension() { Dispose(false); } #endregion #region Properties internal uint SocketID { get { return mSocketID; } set { mSocketID = value; } } internal string ConnectionIP { get { return mConnectionIP; } set { mConnectionIP = value; } } #endregion } }