public MagnetLink(string url) { Check.Url(url); AnnounceUrls = new RawTrackerTier(); Webseeds = new List <string> (); ParseMagnetLink(url); }
public MagnetLink(InfoHash infoHash, string name = null, IList <string> announceUrls = null, IEnumerable <string> webSeeds = null, long?size = null) { InfoHash = infoHash ?? throw new ArgumentNullException(nameof(infoHash)); Name = name; AnnounceUrls = new RawTrackerTier(announceUrls ?? Array.Empty <string> ()); Webseeds = new List <string> (webSeeds ?? Array.Empty <string> ()).AsReadOnly(); Size = size; }
protected void LoadInternal(BEncodedDictionary torrentInformation) { Check.TorrentInformation(torrentInformation); originalDictionary = torrentInformation; torrentPath = ""; try { foreach (KeyValuePair <BEncodedString, BEncodedValue> keypair in torrentInformation) { switch (keypair.Key.Text) { case ("announce"): // Ignore this if we have an announce-list if (torrentInformation.ContainsKey("announce-list")) { break; } announceUrls.Add(new RawTrackerTier()); announceUrls[0].Add(keypair.Value.ToString()); break; case ("creation date"): try { try { creationDate = creationDate.AddSeconds(long.Parse(keypair.Value.ToString())); } catch (Exception e) { if (e is ArgumentOutOfRangeException) { creationDate = creationDate.AddMilliseconds(long.Parse(keypair.Value.ToString())); } else { throw; } } } catch (Exception e) { if (e is ArgumentOutOfRangeException) { throw new BEncodingException("Argument out of range exception when adding seconds to creation date.", e); } else if (e is FormatException) { throw new BEncodingException(String.Format("Could not parse {0} into a number", keypair.Value), e); } else { throw; } } break; case ("nodes"): nodes = (BEncodedList)keypair.Value; break; case ("comment.utf-8"): if (keypair.Value.ToString().Length != 0) { comment = keypair.Value.ToString(); // Always take the UTF-8 version } break; // even if there's an existing value case ("comment"): if (String.IsNullOrEmpty(comment)) { comment = keypair.Value.ToString(); } break; case ("publisher-url.utf-8"): // Always take the UTF-8 version publisherUrl = keypair.Value.ToString(); // even if there's an existing value break; case ("publisher-url"): if (String.IsNullOrEmpty(publisherUrl)) { publisherUrl = keypair.Value.ToString(); } break; case ("azureus_properties"): azureusProperties = keypair.Value; break; case ("created by"): createdBy = keypair.Value.ToString(); break; case ("encoding"): encoding = keypair.Value.ToString(); break; case ("info"): using (SHA1 s = HashAlgoFactory.Create <SHA1>()) infoHash = new InfoHash(s.ComputeHash(keypair.Value.Encode())); ProcessInfo(((BEncodedDictionary)keypair.Value)); break; case ("name"): // Handled elsewhere break; case ("announce-list"): if (keypair.Value is BEncodedString) { break; } BEncodedList announces = (BEncodedList)keypair.Value; for (int j = 0; j < announces.Count; j++) { if (announces[j] is BEncodedList) { BEncodedList bencodedTier = (BEncodedList)announces[j]; List <string> tier = new List <string>(bencodedTier.Count); for (int k = 0; k < bencodedTier.Count; k++) { tier.Add(bencodedTier[k].ToString()); } Toolbox.Randomize <string>(tier); RawTrackerTier collection = new RawTrackerTier(); for (int k = 0; k < tier.Count; k++) { collection.Add(tier[k]); } if (collection.Count != 0) { announceUrls.Add(collection); } } else { throw new BEncodingException(String.Format("Non-BEncodedList found in announce-list (found {0})", announces[j].GetType())); } } break; case ("httpseeds"): // This form of web-seeding is not supported. break; case ("url-list"): if (keypair.Value is BEncodedString) { getRightHttpSeeds.Add(((BEncodedString)keypair.Value).Text); } else if (keypair.Value is BEncodedList) { foreach (BEncodedString str in (BEncodedList)keypair.Value) { GetRightHttpSeeds.Add(str.Text); } } break; default: break; } } } catch (Exception e) { if (e is BEncodingException) { throw; } else { throw new BEncodingException("", e); } } }
/// <summary> /// Parses a magnet link from the given Uri. The uri should be in the form magnet:?xt=urn:btih: /// </summary> /// <param name="uri"></param> /// <returns></returns> public static MagnetLink FromUri(Uri uri) { InfoHash infoHash = null; string name = null; var announceUrls = new RawTrackerTier(); var webSeeds = new List <string> (); long? size = null; if (uri.Scheme != "magnet") { throw new FormatException("Magnet links must start with 'magnet:'."); } string[] parameters = uri.Query.Substring(1).Split('&'); for (int i = 0; i < parameters.Length; i++) { string[] keyval = parameters[i].Split('='); if (keyval.Length != 2) { throw new FormatException("A field-value pair of the magnet link contain more than one equal'."); } switch (keyval[0].Substring(0, 2)) { case "xt": //exact topic if (infoHash != null) { throw new FormatException("More than one infohash in magnet link is not allowed."); } string val = keyval[1].Substring(9); switch (keyval[1].Substring(0, 9)) { case "urn:sha1:": //base32 hash case "urn:btih:": if (val.Length == 32) { infoHash = InfoHash.FromBase32(val); } else if (val.Length == 40) { infoHash = InfoHash.FromHex(val); } else { throw new FormatException("Infohash must be base32 or hex encoded."); } break; } break; case "tr": //address tracker announceUrls.Add(keyval[1].UrlDecodeUTF8()); break; case "as": //Acceptable Source webSeeds.Add(keyval[1].UrlDecodeUTF8()); break; case "dn": //display name name = keyval[1].UrlDecodeUTF8(); break; case "xl": //exact length size = long.Parse(keyval[1]); break; //case "xs":// eXact Source - P2P link. //case "kt"://keyword topic //case "mt"://manifest topic // Unused //break; default: // Unknown/unsupported break; } } return(new MagnetLink(infoHash, name, announceUrls, webSeeds, size)); }
/// <summary> /// 从给定的Uri解析磁铁链接. uri必须为[magnet:?xt=urn:btih:]开头的Uri对象 /// </summary> /// <param name="uri">以[magnet:?xt=urn:btih:]开头的Uri对象</param> /// <returns></returns> public static MagnetLink FromUri(Uri uri) { InfoHash infoHash = null; string name = null; var announceUrls = new RawTrackerTier(); var webSeeds = new List <string> (); long? size = null; if (uri.Scheme != "magnet") { throw new FormatException("磁力链接必须为'magnet:'开头."); } string[] parameters = uri.Query.Substring(1).Split('&'); for (int i = 0; i < parameters.Length; i++) { string[] keyval = parameters[i].Split('='); if (keyval.Length != 2) { // Skip anything we don't understand. Urls could theoretically contain many // unknown parameters. continue; } switch (keyval[0].Substring(0, 2)) { case "xt": //exact topic if (infoHash != null) { throw new FormatException("磁铁链接中不允许有多个infohash."); } string val = keyval[1].Substring(9); switch (keyval[1].Substring(0, 9)) { case "urn:sha1:": //base32 hash case "urn:btih:": if (val.Length == 32) { infoHash = InfoHash.FromBase32(val); } else if (val.Length == 40) { infoHash = InfoHash.FromHex(val); } else { throw new FormatException("Infohash必须是Base32或十六进制编码."); } break; } break; case "tr": //address tracker announceUrls.Add(keyval[1].UrlDecodeUTF8()); break; case "as": //Acceptable Source webSeeds.Add(keyval[1].UrlDecodeUTF8()); break; case "dn": //display name name = keyval[1].UrlDecodeUTF8(); break; case "xl": //exact length size = long.Parse(keyval[1]); break; //case "xs":// eXact Source - P2P link. //case "kt"://keyword topic //case "mt"://manifest topic // Unused //break; default: // Unknown/unsupported break; } } if (infoHash == null) { throw new FormatException("磁铁链接不包含引用infohash的有效\"xt\"参数"); } return(new MagnetLink(infoHash, name, announceUrls, webSeeds, size)); }