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; private List mPacketlist; //private string mLastSentData; #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]; mPacketlist = new List(); } #endregion #region Methods internal void SendData(string DataString) { try { byte[] ByteArray = System.Text.Encoding.Default.GetBytes(DataString + Convert.ToChar(1)); /*int BytesSent =*/ Send(ByteArray); //mLastSentData = DataString; //BeginSend(ByteArray, 0, ByteArray.Length, 0, mSendCallback, this); //Out.WriteLine("[" + mSocketID + "] <-- [" + DataString + "] (" + BytesSent + " bytes)"); } catch { Dispose(); } } //private void DataSent(IAsyncResult pRes) //{ // try // { // int BytesSent = EndSend(pRes); // Out.WriteLine("[" + mSocketID + "] <-- [" + mLastSentData + "] (" + BytesSent + " bytes)"); // } // 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 { FilterData(EndReceive(pRes)); foreach (string Packet in mPacketlist) //One packet, two packets ... { if (Packet == "") continue; //Out.WriteLine("[" + mSocketID + "] --> [" + Packet + "]"); try { mUser.processPacket(Packet); } catch (Exception e) { Out.PrimaryErrorWriter(e.ToString()); SendData("BK Internal servererror:\r" + e.ToString()); continue; } //mPacketlist.Remove(Packet); } mPacketlist.Clear(); WaitForDataStream(); } catch (Exception e) { Out.WriteError(e.ToString()); Dispose(); } } private void FilterData(int pBytes) { string UnFilteredPacket = System.Text.Encoding.Default.GetString(mBuffer, 0, pBytes); if (UnFilteredPacket.Length <= 0) //Empty packet, aka client closed { Dispose(); return; } for (int i = 1; i < 9; i++) if (UnFilteredPacket.Contains("\x0" + i)) { //todo: Add to blacklist / ban user Dispose(); //Hacker?! :O return; } StringBuilder Packets = new StringBuilder(UnFilteredPacket); while (Packets.Length > 0) { int PacketLength = Encoding.decodeB64(Packets.ToString().Substring(1, 2)); mPacketlist.Add(Packets.ToString().Substring(3, PacketLength)); Packets.Remove(0, 3 + PacketLength); } } #endregion #region IDisposable members public void Dispose() { if (Disposed) return; Disposed = true; try { if (base.Connected) Close(); } catch { } base.Dispose(true); 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; } } internal string ConnectionIP { get { return mConnectionIP; } } #endregion } }