================ ClientBase.cs ================ /// /// Begins asynchronous TCP receiving for this client. /// 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); } } /// /// Callback function for handling TCP packets. /// /// Asynchronous result of the operation. 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); } } /// /// Called when a packet has been received and needs to be processed. /// /// The size of the packet in bytes. protected abstract void OnReceive(int num_bytes); ================ RealmClient.cs ================ /// /// Pass recieved data into the packet buffer and try to parse. /// /// number of bytes waiting to be read 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(); //} } /// /// Attempts to parse the packet /// /// the packet to parse 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; } }