public IDictionary <string, ScrapeInfo> Scrape(string url, String[] hashes)
        {
            Dictionary <string, ScrapeInfo> returnVal = new Dictionary <string, ScrapeInfo>();

            this.ValidateInput(url, hashes, ScraperType.UDP);

            Int32 transactionId = this.Random.Next(0, 65535);

            UdpClient udpClient = new UdpClient(this.Tracker, this.Port)
            {
                Client =
                {
                    SendTimeout    = this.Timeout * 1000,
                    ReceiveTimeout = this.Timeout * 1000
                }
            };

            byte[] sendBuf = this._currentConnectionId.Concat(PackHelper.Int32(0)).Concat(PackHelper.Int32(transactionId)).ToArray();
            udpClient.Send(sendBuf, sendBuf.Length);

            IPEndPoint endPoint = null;

            byte[] recBuf = udpClient.Receive(ref endPoint);

            if (recBuf == null)
            {
                throw new NoNullAllowedException("udpClient failed to receive");
            }

            if (recBuf.Length < 0)
            {
                throw new InvalidOperationException("udpClient received no response");
            }

            if (recBuf.Length < 16)
            {
                throw new InvalidOperationException("udpClient did not receive entire response");
            }

            UInt32 recAction       = UnpackHelper.UInt32(recBuf, 0, UnpackHelper.Endianness.Big);
            UInt32 recTrasactionId = UnpackHelper.UInt32(recBuf, 4, UnpackHelper.Endianness.Big);

            if (recAction != 0 || recTrasactionId != transactionId)
            {
                throw new Exception("Invalid response from tracker");
            }

            this._currentConnectionId = CopyBytes(recBuf, 8, 8);

            byte[] hashBytes = new byte[0];
            hashBytes = hashes.Aggregate(hashBytes, (current, hash) => current.Concat(PackHelper.Hex(hash)).ToArray());

            int expectedLength = 8 + (12 * hashes.Length);

            sendBuf = this._currentConnectionId.Concat(PackHelper.Int32(2)).Concat(PackHelper.Int32(transactionId)).Concat(hashBytes).ToArray();
            udpClient.Send(sendBuf, sendBuf.Length);

            recBuf = udpClient.Receive(ref endPoint);

            if (recBuf == null)
            {
                throw new NoNullAllowedException("udpClient failed to receive");
            }

            if (recBuf.Length < 0)
            {
                throw new InvalidOperationException("udpClient received no response");
            }

            if (recBuf.Length < expectedLength)
            {
                throw new InvalidOperationException("udpClient did not receive entire response");
            }

            recAction       = UnpackHelper.UInt32(recBuf, 0, UnpackHelper.Endianness.Big);
            recTrasactionId = UnpackHelper.UInt32(recBuf, 4, UnpackHelper.Endianness.Big);

            this._currentConnectionId = CopyBytes(recBuf, 8, 8);

            if (recAction != 2 || recTrasactionId != transactionId)
            {
                throw new Exception("Invalid response from tracker");
            }

            Int32 startIndex = 8;

            foreach (string hash in hashes)
            {
                UInt32 seeders   = UnpackHelper.UInt32(recBuf, startIndex, UnpackHelper.Endianness.Big);
                UInt32 completed = UnpackHelper.UInt32(recBuf, startIndex + 4, UnpackHelper.Endianness.Big);
                UInt32 Leechers  = UnpackHelper.UInt32(recBuf, startIndex + 8, UnpackHelper.Endianness.Big);

                returnVal.Add(hash, new ScrapeInfo(seeders, completed, Leechers, ScraperType.UDP));

                startIndex += 12;
            }

            udpClient.Close();

            return(returnVal);
        }
        public AnnounceInfo Announce(string url, string hash, string peerId, Int64 bytesDownloaded, Int64 bytesLeft, Int64 bytesUploaded,
                                     Int32 eventTypeFilter, Int32 ipAddress, Int32 numWant, Int32 listenPort, Int32 extensions)
        {
            List <IPEndPoint> returnValue = new List <IPEndPoint>();

            this.ValidateInput(url, new[] { hash }, ScraperType.UDP);

            this._currentConnectionId = this.BaseCurrentConnectionId;
            Int32 trasactionId = this.Random.Next(0, 65535);

            UdpClient udpClient = new UdpClient(this.Tracker, this.Port)
            {
                DontFragment = true,
                Client       =
                {
                    SendTimeout    = this.Timeout * 1000,
                    ReceiveTimeout = this.Timeout * 1000
                }
            };

            byte[] sendBuf = this._currentConnectionId.Concat(PackHelper.Int32(0)).Concat(PackHelper.Int32(trasactionId)).ToArray();
            udpClient.Send(sendBuf, sendBuf.Length);

            IPEndPoint endPoint = null;

            byte[] recBuf;

            try
            {
                recBuf = udpClient.Receive(ref endPoint);
            }
            catch (Exception)
            {
                return(null);
            }

            if (recBuf == null)
            {
                throw new NoNullAllowedException("udpClient failed to receive");
            }

            if (recBuf.Length < 0)
            {
                throw new InvalidOperationException("udpClient received no response");
            }

            if (recBuf.Length < 16)
            {
                throw new InvalidOperationException("udpClient did not receive entire response");
            }

            UInt32 recAction       = UnpackHelper.UInt32(recBuf, 0, UnpackHelper.Endianness.Big);
            UInt32 recTrasactionId = UnpackHelper.UInt32(recBuf, 4, UnpackHelper.Endianness.Big);

            if (recAction != 0 || recTrasactionId != trasactionId)
            {
                throw new Exception("Invalid response from tracker");
            }

            this._currentConnectionId = CopyBytes(recBuf, 8, 8);

            byte[] hashBytes = PackHelper.Hex(hash).ToArray();

            Int32 key = this.Random.Next(0, 65535);

            sendBuf = this._currentConnectionId.                      /*connection id*/
                      Concat(PackHelper.Int32(1)).                    /*action*/
                      Concat(PackHelper.Int32(trasactionId)).         /*trasaction Id*/
                      Concat(hashBytes).                              /*hash*/
                      Concat(Encoding.ASCII.GetBytes(peerId)).        /*my peer id*/
                      Concat(PackHelper.Int64(bytesDownloaded)).      /*bytes downloaded*/
                      Concat(PackHelper.Int64(bytesLeft)).            /*bytes left*/
                      Concat(PackHelper.Int64(bytesUploaded)).        /*bytes uploaded*/
                      Concat(PackHelper.Int32(eventTypeFilter)).      /*event, 0 for none, 2 for just started*/
                      Concat(PackHelper.Int32(ipAddress)).            /*ip, 0 for this one*/
                      Concat(PackHelper.Int32(key)).                  /*unique key*/
                      Concat(PackHelper.Int32(numWant)).              /*num want, -1 for as many as pos*/
                      Concat(PackHelper.Int32(listenPort)).           /*listen port*/
                      Concat(PackHelper.Int32(extensions)).ToArray(); /*extensions*/
            udpClient.Send(sendBuf, sendBuf.Length);

            try
            {
                recBuf = udpClient.Receive(ref endPoint);
            }
            catch (Exception)
            {
                return(null);
            }

            recAction       = UnpackHelper.UInt32(recBuf, 0, UnpackHelper.Endianness.Big);
            recTrasactionId = UnpackHelper.UInt32(recBuf, 4, UnpackHelper.Endianness.Big);

            int waitTime = (int)UnpackHelper.UInt32(recBuf, 8, UnpackHelper.Endianness.Big);
            int Leechers = (int)UnpackHelper.UInt32(recBuf, 12, UnpackHelper.Endianness.Big);
            int seeders  = (int)UnpackHelper.UInt32(recBuf, 16, UnpackHelper.Endianness.Big);

            if (recAction != 1 || recTrasactionId != trasactionId)
            {
                throw new Exception("Invalid response from tracker");
            }

            for (Int32 i = 20; i < recBuf.Length; i += 6)
            {
                UInt32 ip   = UnpackHelper.UInt32(recBuf, i, UnpackHelper.Endianness.Big);
                UInt16 port = UnpackHelper.UInt16(recBuf, i + 4, UnpackHelper.Endianness.Big);

                returnValue.Add(new IPEndPoint(ip, port));
            }

            udpClient.Close();

            return(new AnnounceInfo(returnValue, waitTime, seeders, Leechers));
        }
        public AnnounceInfo Announce(string url, string hash, string peerId, long bytesDownloaded, long bytesLeft, long bytesUploaded,
                                     int eventTypeFilter, int ipAddress, int numWant, int listenPort, int extensions)
        {
            byte[] hashBytes   = PackHelper.Hex(hash);
            byte[] peerIdBytes = Encoding.ASCII.GetBytes(peerId);

            string realUrl = url.Replace("scrape", "announce") + "?";

            string hashEncoded = "";

            foreach (byte b in hashBytes)
            {
                hashEncoded += String.Format("%{0:X2}", b);
            }

            string peerIdEncoded = "";

            foreach (byte b in peerIdBytes)
            {
                peerIdEncoded += String.Format("%{0:X2}", b);
            }

            realUrl += "info_hash=" + hashEncoded;
            realUrl += "&peer_id=" + peerIdEncoded;
            realUrl += "&port=" + listenPort;
            realUrl += "&uploaded=" + bytesUploaded;
            realUrl += "&downloaded=" + bytesDownloaded;
            realUrl += "&left=" + bytesLeft;
            realUrl += "&event=started";
            realUrl += "&compact=1";

            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(realUrl);

            webRequest.Accept    = "*/*";
            webRequest.UserAgent = "System.Net.Torrent";
            HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();

            Stream stream = webResponse.GetResponseStream();

            if (stream == null)
            {
                return(null);
            }

            BinaryReader binaryReader = new BinaryReader(stream);

            byte[] bytes = new byte[0];

            while (true)
            {
                try
                {
                    byte[] b = new byte[1];
                    b[0]  = binaryReader.ReadByte();
                    bytes = bytes.Concat(b).ToArray();
                }
                catch (Exception)
                {
                    break;
                }
            }

            BDict decoded = (BDict)BencodingUtils.Decode(bytes);

            if (decoded.Count == 0)
            {
                return(null);
            }

            if (!decoded.ContainsKey("peers"))
            {
                return(null);
            }

            if (!(decoded["peers"] is BString))
            {
                throw new NotSupportedException("Dictionary based peers not supported");
            }

            Int32 waitTime = 0;
            Int32 seeders  = 0;
            Int32 leechers = 0;

            if (decoded.ContainsKey("interval"))
            {
                waitTime = (BInt)decoded["interval"];
            }

            if (decoded.ContainsKey("complete"))
            {
                seeders = (BInt)decoded["complete"];
            }

            if (decoded.ContainsKey("incomplete"))
            {
                leechers = (BInt)decoded["incomplete"];
            }

            BString peerBinary = (BString)decoded["peers"];

            return(new AnnounceInfo(GetPeers(peerBinary.ByteValue), waitTime, seeders, leechers));
        }
        public IDictionary <string, ScrapeInfo> Scrape(string url, string[] hashes)
        {
            Dictionary <string, ScrapeInfo> returnVal = new Dictionary <string, ScrapeInfo>();

            string realUrl = url.Replace("announce", "scrape") + "?";

            string hashEncoded = "";

            foreach (string hash in hashes)
            {
                byte[] hashBytes = PackHelper.Hex(hash);

                hashEncoded = hashBytes.Aggregate(hashEncoded, (current, b) => current + String.Format("%{0:X2}", b));

                realUrl += "info_hash=" + hashEncoded + "&";
            }

            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(realUrl);

            webRequest.Accept    = "*/*";
            webRequest.UserAgent = "System.Net.Torrent";
            webRequest.Timeout   = this.Timeout * 1000;
            HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();

            Stream stream = webResponse.GetResponseStream();

            if (stream == null)
            {
                return(null);
            }

            BinaryReader binaryReader = new BinaryReader(stream);

            byte[] bytes = new byte[0];

            while (true)
            {
                try
                {
                    byte[] b = new byte[1];
                    b[0]  = binaryReader.ReadByte();
                    bytes = bytes.Concat(b).ToArray();
                }
                catch (Exception)
                {
                    break;
                }
            }

            BDict decoded = (BDict)BencodingUtils.Decode(bytes);

            if (decoded.Count == 0)
            {
                return(null);
            }

            if (!decoded.ContainsKey("files"))
            {
                return(null);
            }

            BDict bDecoded = (BDict)decoded["files"];

            foreach (string k in bDecoded.Keys)
            {
                BDict d = (BDict)bDecoded[k];

                if (d.ContainsKey("complete") && d.ContainsKey("downloaded") && d.ContainsKey("incomplete"))
                {
                    string rk = UnpackHelper.Hex(BencodingUtils.ExtendedASCIIEncoding.GetBytes(k));
                    returnVal.Add(rk, new ScrapeInfo((uint)((BInt)d["complete"]).Value, (uint)((BInt)d["downloaded"]).Value, (uint)((BInt)d["incomplete"]).Value, ScraperType.HTTP));
                }
            }

            return(returnVal);
        }
 public bool Handshake()
 {
     return(this.Handshake(PackHelper.Hex(this.Hash), Encoding.ASCII.GetBytes(this.LocalPeerID)));
 }
        public PeerMessageBuilder Add(string str)
        {
            this.MessagePayload.AddRange(PackHelper.Hex(str));

            return(this);
        }