All pastes #387203 Raw Edit

tobz

public text v1 · immutable
·published 2007-03-09 04:42 UTC
rendered paste body
================ ClientBase.cs ================

        /// <summary>
        /// Begins asynchronous TCP receiving for this client.
        /// </summary>
        public virtual void BeginRecv()
        {
            if (m_tcpSock.Connected)
            {
                m_tcpSock.BeginReceive(m_inBuf, m_inOffset, m_inBuf.Length - m_inOffset, SocketFlags.None,
                                       new AsyncCallback(AsyncRecv), this);
            }
        }

        /// <summary>
        /// Callback function for handling TCP packets.
        /// </summary>
        /// <param name="ar">Asynchronous result of the operation.</param>
        private static void AsyncRecv(IAsyncResult ar)
        {
            ClientBase client = (ClientBase) ar.AsyncState;

            try
            {
                int num_bytes = client.TcpSocket.EndReceive(ar);

                if (num_bytes == 0)
                {
                    client.Server.DisconnectClient(client);
                }
                else
                {
                    unchecked
                    {
                        client.m_bytesRecv += num_bytes;
                        m_totalBytesRecv += (uint) num_bytes;
                    }

                    client.OnReceive(num_bytes);
                    client.TcpSocket.BeginReceive(client.m_inBuf, client.InOffset,
                                                  client.m_inBuf.Length - client.InOffset, SocketFlags.None,
                                                  new AsyncCallback(AsyncRecv), client);
                }
            }
            catch (ObjectDisposedException)
            {
                client.Server.DisconnectClient(client);
            }
            catch (Exception e)
            {
                client.Server.Warning(client, e);
                client.Server.DisconnectClient(client);
            }
        }

        /// <summary>
        /// Called when a packet has been received and needs to be processed.
        /// </summary>
        /// <param name="num_bytes">The size of the packet in bytes.</param>
        protected abstract void OnReceive(int num_bytes);


================ RealmClient.cs ================

        /// <summary>
        /// Pass recieved data into the packet buffer and try to parse.
        /// </summary>
        /// <param name="num_bytes">number of bytes waiting to be read</param>
        protected override void OnReceive(int num_bytes)
        {
            if (num_bytes < 6)
            {
                throw new InsufficientDataException("Packet is 6 bytes minimum!");
            }

            //m_bufferLock.Enter();

            try
            {
                if (m_partialBuffer != null)
                {
                    if (m_partialBuffer.BytesUntilComplete <= num_bytes)
                    {
                        int bytesRemaining = m_partialBuffer.BytesUntilComplete;

                        RealmPacketIn chunkedPacket =
                            new RealmPacketIn(m_inBuf, m_inOffset, m_partialBuffer.BytesUntilComplete);
                        m_partialBuffer.MergePackets(chunkedPacket);

                        m_inOffset += bytesRemaining;

                        m_log.Debug(
                    string.Format(
                        "About to parse non-partial packet. ID: {0}, reported size: {1}, actual size: {2}", m_partialBuffer,
                        m_partialBuffer.PacketSize, m_partialBuffer.Length));

                        TryHandlePacket(m_partialBuffer);

                        m_partialBuffer = null;

                        OnReceive(num_bytes - bytesRemaining);

                        return;
                    }
                    else
                    {
                        RealmPacketIn tempPacket = new RealmPacketIn(m_inBuf, m_inOffset, num_bytes);

                        m_partialBuffer.MergePackets(tempPacket);

                        m_log.Debug(
                    string.Format(
                        "Continuing partial package. ID: {0}, reported size: {1}, starting size: {2}, numBytes in: {3}",
                        m_partialBuffer,
                        m_partialBuffer.PacketSize, m_partialBuffer.Length, num_bytes));

                        m_inOffset = 0;

                        return;
                    }
                }

                RealmPacketIn tmpPacket = new RealmPacketIn(m_inBuf, m_inOffset, num_bytes);

                if(IsEncrypted && !m_headerDecrypted)
                {
                    Decrypt(tmpPacket, 0);

                    m_headerDecrypted = true;
                }

                tmpPacket.Initialize();

                if(tmpPacket.PacketSize + 2 == tmpPacket.Length)
                {
                    m_log.Debug(
                    string.Format(
                        "About to parse non-partial packet. ID: {0}, reported size: {1}, actual size: {2}", tmpPacket,
                        tmpPacket.PacketSize, tmpPacket.Length));

                    TryHandlePacket(tmpPacket);

                    m_headerDecrypted = false;

                    return;
                }
                else if(tmpPacket.PacketSize + 2 > tmpPacket.Length)
                {
                    m_log.Debug(
                    string.Format(
                        "Starting partial package. ID: {0}, reported size: {1}, starting size: {2}, numBytes in: {3}",
                        tmpPacket,
                        tmpPacket.PacketSize, tmpPacket.Length, num_bytes));

                    m_partialBuffer = tmpPacket;

                    return;
                }
                else
                {
                    // something aint right here.

                    return;
                }

            }
            catch (InsufficientDataException e)
            {
                m_srvr.Warning(this, e);
                m_headerDecrypted = false;
            }
            //finally
            //{
                //m_bufferLock.Exit();
            //}
        }

        /// <summary>
        /// Attempts to parse the packet
        /// </summary>
        /// <param name="packet">the packet to parse</param>
        protected void TryHandlePacket(RealmPacketIn packet)
        {
            try
            {
                if (packet.Parse(this))
                {
                    // log message
                    m_headerDecrypted = false;
                }
                else
                {
                    // log message
                    m_headerDecrypted = false;
                }
            }
            catch (Exception e)
            {
                m_srvr.Warning(this, e);
                m_headerDecrypted = false;
            }
        }