//Private helper methods
        private void PrivateGetPackets(RconPacket input, GotPacketCallback callback)
        {
            //Get ID and incrememnt it
            int id     = currentId++;
            int testId = currentId++;//This id will be used to check when we're done.

            input.id = id;
            //Register a callback for this and the next one.
            int packetsGot = 0; //How many packets were recievied for a single ID.
            List <RconPacket> returnedPackets = new List <RconPacket>();
            var innerCallback = (new InternalPacketCallback((RconPacket p) =>
            {
                //When a packet is received, this is called.
                //A request to the server will be sent using the same ID. When that packet is recieved, we know we are done. This is for getting multiple packets for one request if it is too long.
                RconPacketType type = (RconPacketType)p.type;
                bool isEnd = testId == p.id;
                //Check if the raw contents match the end of packet results



                if (packetsGot == 0)
                {
                    //Send a request to check if we are done.
                    sock.Send(new RconPacket(testId, RconPacketType.SERVERDATA_RESPONSE_VALUE, "").ToBytes());
                }

                if (isEnd)
                {
                    //This is the end. Return all of our packets.
                    callback(returnedPackets);
                    //Also remove this callback from the dictonary to save ram
                    internalCallbacks.Remove(id);
                    internalCallbacks.Remove(testId);
                }
                else
                {
                    //Add this because it's not the ending packet.
                    returnedPackets.Add(p);
                }

                packetsGot++;
            }));

            internalCallbacks.Add(id, innerCallback);
            internalCallbacks.Add(testId, innerCallback);
            //Send packet to the server.
            byte[] data = input.ToBytes();
            //Send
            sock.Send(data);
        }
        private void PrivateGotPacket(System.IAsyncResult result)
        {
            //Check if disposed
            if (sock == null)
            {
                return;
            }
            //Get the data out of this.
            sock.EndReceive(result);
            pendingAsync = null;
            //We'll now read in the size of the packet based on the "receiveBuffer" int sent.
            int size = ReadIntFromStream(receiveBuffer);

            //We'll now read in the remainder of the packet.
            byte[] buffer = new byte[size + 4];
            //Copy the current receiveBuffer to this buffer. This'll allow us to have the length.
            receiveBuffer.CopyTo(buffer, 0);
            //Now, read in the remainder of the packet from the socket.
            sock.Receive(buffer, 4, size, SocketFlags.None);
            //We'll now begin listening again.
            PrivateBeginWaitingForPacket();
            //Now, we'll convert this to a real packet we can understand.
            RconPacket packet = null;

            try
            {
                packet = RconPacket.ToPacket(buffer);
                //If the callback list contains this, call back. Ignore Ark's "Keep Alive" packets.
                if (internalCallbacks.ContainsKey(packet.id) && packet.body != "Keep Alive")
                {
                    internalCallbacks[packet.id](packet);
                }
            }
            catch (Exception ex)
            {
                //There was an error.
                throw ex;
            }
        }
        public static RconPacket ToPacket(byte[] data)
        {
            //Do the opposite as the above.
            RconPacket packet = new RconPacket();

            using (MemoryStream ms = new MemoryStream(data))
            {
                //First, read in the size.
                int length = ReadIntFromStream(ms);
                //Read id
                packet.id = ReadIntFromStream(ms);
                //Read type
                packet.type = ReadIntFromStream(ms);
                //Now, read body.
                int bodySize = length - 4 - 4 - 2; //Remove last two bytes of padding and the id and type.
                packet.rawBody = ReadBytesFromStream(ms, bodySize);
                packet.body    = Encoding.ASCII.GetString(packet.rawBody);
                //Read last two bytes of padding
                ReadBytesFromStream(ms, 2);
            }
            return(packet);
        }