//QUICKHACK: format bencoded val and get it back wereas must refactor tracker system to have more generic object... protected virtual async Task ReceiveAnnounce(UdpClient client, AnnounceMessage announceMessage, IPEndPoint remotePeer) { UdpTrackerMessage m; BEncodedDictionary dict = Handle(getCollection(announceMessage), remotePeer.Address, false); if (dict.ContainsKey(TrackerRequest.FailureKey)) { m = new ErrorMessage(announceMessage.TransactionId, dict[TrackerRequest.FailureKey].ToString()); } else { TimeSpan interval = TimeSpan.Zero; int leechers = 0; int seeders = 0; var peers = new List <PeerInfo> (); foreach (KeyValuePair <BEncodedString, BEncodedValue> keypair in dict) { switch (keypair.Key.Text) { case ("complete"): seeders = Convert.ToInt32(keypair.Value.ToString()); //same as seeder? break; case ("incomplete"): leechers = Convert.ToInt32(keypair.Value.ToString()); //same as leecher? break; case ("interval"): interval = TimeSpan.FromSeconds(int.Parse(keypair.Value.ToString())); break; case ("peers"): if (keypair.Value is BEncodedList) // Non-compact response { peers.AddRange(PeerDecoder.Decode((BEncodedList)keypair.Value)); } else if (keypair.Value is BEncodedString) // Compact response { peers.AddRange(PeerDecoder.Decode((BEncodedString)keypair.Value)); } break; default: break; } } m = new AnnounceResponseMessage(announceMessage.TransactionId, interval, leechers, seeders, peers); } byte[] data = m.Encode(); await client.SendAsync(data, data.Length, remotePeer); }
AnnounceResponse HandleAnnounce(BEncodedDictionary dict) { int? complete = null, incomplete = null, downloaded = null; TimeSpan?minUpdateInterval = null, updateInterval = null; string failureMessage = null, warningMessage = null; var peers = new List <PeerInfo> (); foreach (KeyValuePair <BEncodedString, BEncodedValue> keypair in dict) { switch (keypair.Key.Text) { case ("complete"): complete = Convert.ToInt32(keypair.Value.ToString()); break; case ("incomplete"): incomplete = Convert.ToInt32(keypair.Value.ToString()); break; case ("downloaded"): downloaded = Convert.ToInt32(keypair.Value.ToString()); break; case ("tracker id"): TrackerId = (BEncodedString)keypair.Value; break; case ("min interval"): minUpdateInterval = TimeSpan.FromSeconds(int.Parse(keypair.Value.ToString())); break; case ("interval"): updateInterval = TimeSpan.FromSeconds(int.Parse(keypair.Value.ToString())); break; case ("peers"): if (keypair.Value is BEncodedList bencodedList) // Non-compact response { peers.AddRange(PeerDecoder.Decode(bencodedList)); } else if (keypair.Value is BEncodedString bencodedStr) // Compact response { peers.AddRange(PeerDecoder.Decode(bencodedStr)); } break; case ("failure reason"): failureMessage = keypair.Value.ToString(); break; case ("warning message"): warningMessage = keypair.Value.ToString(); break; default: logger.InfoFormatted("Unknown announce tag received: Key {0} Value: {1}", keypair.Key, keypair.Value); break; } } return(new AnnounceResponse( state: TrackerState.Ok, peers: peers, minUpdateInterval: minUpdateInterval, updateInterval: updateInterval, complete: complete, incomplete: incomplete, downloaded: downloaded, warningMessage: warningMessage, failureMessage: failureMessage )); }
internal static IList <Peer> Decode(BEncodedList l) => PeerDecoder.Decode(l).Select(t => new Peer(BEncodedString.FromMemory(t.PeerId), t.Uri)).ToArray();