/// <summary>
        /// WSASend Hook. Use this to modify any particular outgoing data, or use
        /// outgoing data to modify internal structures (e.g. parse world update
        /// sends and use parsed data to change NPC locations, block types, etc.
        ///
        /// NOTES: Buffer is a ref to an WSABuffer structure. To access packet data, it
        /// needs to be marshalled. Marshal.Copy(Buffer.buf, newbuffer, number_of_bytes)
        /// is the safest way. number_of_bytes in WSASend calls is stored in Buffer.len,
        /// as a plain int.
        /// </summary>
        /// <param name="socketHandle">The socket handle.</param>
        /// <param name="Buffer">The buffer pointer.</param>
        /// <param name="BufferCount">The buffer count.</param>
        /// <param name="bytesTransferred">The bytes transferred POST SEND.</param>
        /// <param name="socketFlags">The socket flags.</param>
        /// <param name="overlapped">The overlapped data.</param>
        /// <param name="completionRoutine">The completion routine after overlap processing.</param>
        /// <returns></returns>
        static int WSASendHooked(
            [In] IntPtr socketHandle,
            [In] ref WSABuffer Buffer,
            [In] int BufferCount,
            [In] IntPtr bytesTransferred,
            [In] SocketFlags socketFlags,
            [In] IntPtr overlapped,
            [In] IntPtr completionRoutine)
        {
            //var newBuffer = new byte[Buffer.len]; //buffer to hold sent bytes
            //Marshal.Copy(Buffer.buf,newBuffer,0,Buffer.len);

            /*if (newBuffer[4] == 0x19)
             * {
             *  var n = Commands.ProcessData(newBuffer, 1);
             *  if (n.Length == -1)
             *  {
             *      return 0;
             *  }
             *  int i = 0;
             *  foreach (byte b in n.Data)
             *  {
             *      Marshal.WriteByte(Buffer.buf, i, b);
             *      i++;
             *  }
             *
             *  Buffer.len = n.Length;
             * }*/

            //call WSASend
            return(WSASend(socketHandle, ref Buffer, BufferCount, bytesTransferred, socketFlags, overlapped,
                           completionRoutine));
        }
 static extern int WSASend(
     [In] IntPtr socketHandle,
     [In] ref WSABuffer Buffer,
     [In] int BufferCount,
     [In] IntPtr bytesTransferred,
     [In] SocketFlags socketFlags,
     [In] IntPtr overlapped,
     [In] IntPtr completionRoutine
     );
        /// <summary>
        /// WSARecv Hook. Use this hook to modify incoming data, keeping length intact.
        /// Any changes to length apparently will cause a socket fault (unraised), though
        /// actual cause is unknown. It should be safe to rewrite incoming data and marshal
        /// it back to the original pointer, through Marshal.WriteByte(Buffer.buf, index);
        ///
        /// There are possibly ways to modify packet data to be inert, if reducing a recieved
        /// packet to a stub is necessary.
        ///
        /// NOTES: Buffer is a ref to an WSABuffer structure. To access packet data, it needs
        /// to be marshalled. Marshal.Copy(Buffer.buf, newbuffer, number_of_bytes) is the
        /// safest way. number_of_bytes can be retrieved by marshalling bytesTransferred to
        /// an Int32 type with Marshal.ReadInt32(bytesTransferred).
        /// </summary>
        /// <param name="socketHandle">The socket handle.</param>
        /// <param name="Buffer">The buffer pointer.</param>
        /// <param name="BufferCount">The buffer count.</param>
        /// <param name="bytesTransferred">The bytes transferred.</param>
        /// <param name="socketFlags">The socket flags.</param>
        /// <param name="overlapped">The overlapped data.</param>
        /// <param name="completionRoutine">The completion routine after overlap processing.</param>
        /// <returns></returns>
        static int WSARecvHooked(
            [In] IntPtr socketHandle,
            [In, Out] ref WSABuffer Buffer,
            [In] int BufferCount,
            [In, Out] IntPtr bytesTransferred,
            [In, Out] ref SocketFlags socketFlags,
            [In] IntPtr overlapped,
            [In] IntPtr completionRoutine)
        {
            var result = WSARecv(socketHandle, ref Buffer, BufferCount, bytesTransferred, ref socketFlags,
                                 overlapped, completionRoutine);

            if (result != 0)
            {
                Console.WriteLine("Socket Error!\n");
#if DEBUG
                Console.WriteLine("WSARecv (original) returned errorno: " + result);
#endif
                return(result);
            }

            int bytes = Marshal.ReadInt32(bytesTransferred);
            if (bytes > 0)
            {
                var newBuffer = new byte[bytes];
                Marshal.Copy(Buffer.buf, newBuffer, 0, bytes);

                //wrap ProcessData call, so an exception in it shouldn't cause
                //easyhook to detach.
                try
                {
                    var packet = Commands.ProcessData(newBuffer, 0, socketHandle.ToInt32());
                    //write packet data to buffer. keep it in the try/catch because if
                    //processdata fails, this will fail because packet is null.
                    Marshal.Copy(packet.Data, 0, Buffer.buf, packet.Length);
                } catch (Exception e)
                {
                    Console.WriteLine("Serious error in Commands.cs: " + e + "\n");
#if DEBUG
                    Console.WriteLine("HOOK MAY BE DETACHED\n");
#endif
                }
            }
            return(result);
        }