private static void shutdown() { #if !DISABLE_DHT File.WriteAllBytes(dhtNodeFile, engine.DhtEngine.SaveNodes()); #endif BEncodedDictionary fastResume = new BEncodedDictionary(); for (int i = 0; i < torrents.Count; i++) { torrents[i].Stop(); ; while (torrents[i].State != TorrentState.Stopped) { Console.WriteLine("{0} is {1}", torrents[i].Torrent.Name, torrents[i].State); Thread.Sleep(250); } fastResume.Add(torrents[i].Torrent.InfoHash.ToHex (), torrents[i].SaveFastResume().Encode()); } File.WriteAllBytes(fastResumeFile, fastResume.Encode()); engine.Dispose(); foreach (TraceListener lst in Debug.Listeners) { lst.Flush(); lst.Close(); } System.Threading.Thread.Sleep(2000); }
private static void shutdown() { BEncodedDictionary fastResume = new BEncodedDictionary(); for (int i = 0; i < torrents.Count; i++) { WaitHandle handle = torrents[i].Stop(); ; while (!handle.WaitOne(10, true)) Console.WriteLine(handle.ToString()); Console.WriteLine(handle.ToString()); fastResume.Add(torrents[i].Torrent.InfoHash, torrents[i].SaveFastResume().Encode()); } File.WriteAllBytes(dhtNodeFile, engine.DhtEngine.SaveNodes()); File.WriteAllBytes(fastResumeFile, fastResume.Encode()); engine.Dispose(); foreach (TraceListener lst in Debug.Listeners) { lst.Flush(); lst.Close(); } System.Threading.Thread.Sleep(2000); }
public BitTorrentManager(BitTorrentCache bittorrentCache, string selfNameSpace, DictionaryServiceProxy dhtProxy, DictionaryServiceTracker dhtTracker, ClientEngine clientEngine, TorrentSettings torrentDefaults, TorrentHelper torrentHelper, bool startSeedingAtStartup) { _bittorrentCache = bittorrentCache; SelfNameSpace = selfNameSpace; _dictProxy = dhtProxy; _dictTracker = dhtTracker; _torrentDefaults = torrentDefaults; _startSeedingAtStartup = startSeedingAtStartup; RegisterClientEngineEventHandlers(clientEngine); _clientEngine = clientEngine; _torrentHelper = torrentHelper; try { _fastResumeData = BEncodedValue.Decode<BEncodedDictionary>( File.ReadAllBytes(_bittorrentCache.FastResumeFilePath)); } catch { _fastResumeData = new BEncodedDictionary(); } // CacheRegistry is created here because the default cache registry file path is // defined here. CacheRegistry = new CacheRegistry(_bittorrentCache.CacheRegistryFilePath, selfNameSpace); CacheRegistry.LoadCacheDir(_bittorrentCache.DownloadsDirPath); }
private static void Shutdown() { var fastResume = new BEncodedDictionary(); foreach (var torrentManager in torrents) { torrentManager.Stop(); while (torrentManager.State != TorrentState.Stopped) { Console.WriteLine("{0} is {1}", torrentManager.Torrent.Name, torrentManager.State); Thread.Sleep(250); } fastResume.Add(torrentManager.Torrent.InfoHash.ToHex (), torrentManager.SaveFastResume().Encode()); } #if !DISABLE_DHT File.WriteAllBytes(_dhtNodeFile, _engine.DhtEngine.SaveNodes()); #endif File.WriteAllBytes(_fastResumeFile, fastResume.Encode()); _engine.Dispose(); foreach (TraceListener lst in Debug.Listeners) { lst.Flush(); lst.Close(); } Thread.Sleep(2000); }
private void LoadSupports(BEncodedDictionary supports) { var list = new ExtensionSupports(); foreach (var k in supports) list.Add(new ExtensionSupport(k.Key.Text, (byte) ((BEncodedNumber) k.Value).Number)); Supports = list; }
private void CheckContent(BEncodedDictionary dict, BEncodedString key, BEncodedNumber value) { CheckContent(dict, key); if (!dict[key].Equals(value)) throw new TorrentException( string.Format("Invalid FastResume data. The value of '{0}' was '{1}' instead of '{2}'", key, dict[key], value)); }
public void CorruptDictionary() { BEncodedList l = new BEncodedList(); BEncodedDictionary d = new BEncodedDictionary(); l.Add(d); IList<Peer> decoded = Peer.Decode(l); Assert.AreEqual(0, decoded.Count, "#1"); }
public void CorruptDictionary() { var l = new BEncodedList(); var d = new BEncodedDictionary(); l.Add(d); IList<Peer> decoded = Peer.Decode(l); Assert.Equal(0, decoded.Count); }
public void CorruptDictionary() { var list = new BEncodedList(); var dictionary = new BEncodedDictionary(); list.Add(dictionary); IList<Peer> decoded = Peer.Decode(list); Assert.AreEqual(0, decoded.Count, "#1"); }
public BEncodedDictionary Encode() { var dict = new BEncodedDictionary(); dict.Add(VersionKey, (BEncodedNumber) 1); dict.Add(InfoHashKey, new BEncodedString(Infohash.Hash)); dict.Add(BitfieldKey, new BEncodedString(Bitfield.ToByteArray())); dict.Add(BitfieldLengthKey, (BEncodedNumber) Bitfield.Length); return dict; }
protected QueryMessage(NodeId id, BEncodedString queryName, BEncodedDictionary queryArguments, ResponseCreator responseCreator) : base(QueryType) { Properties.Add(QueryNameKey, queryName); Properties.Add(QueryArgumentsKey, queryArguments); Parameters.Add(IdKey, id.BencodedString()); ResponseCreator = responseCreator; }
public override void Decode(byte[] buffer, int offset, int length) { peerDict = BEncodedValue.Decode<BEncodedDictionary>(buffer, offset, length, false); if (!peerDict.ContainsKey(AddedKey)) peerDict.Add(AddedKey, (BEncodedString)""); if (!peerDict.ContainsKey(AddedDotFKey)) peerDict.Add(AddedDotFKey, (BEncodedString)""); if (!peerDict.ContainsKey(DroppedKey)) peerDict.Add(DroppedKey, (BEncodedString)""); }
public static Message DecodeMessage(BEncodedDictionary dictionary) { Message message; string error; if (!TryDecodeMessage(dictionary, out message, out error)) throw new MessageException(ErrorCode.GenericError, error); return message; }
public BEncodedValue Encode() { BEncodedDictionary result = new BEncodedDictionary(); result.Add(new BEncodedString("MaxDownloadSpeed"), new BEncodedNumber(MaxDownloadSpeed)); result.Add(new BEncodedString("MaxUploadSpeed"), new BEncodedNumber(MaxUploadSpeed)); result.Add(new BEncodedString("MaxConnections"), new BEncodedNumber(MaxConnections)); result.Add(new BEncodedString("UploadSlots"), new BEncodedNumber(UploadSlots)); result.Add(new BEncodedString("SavePath"), new BEncodedString(savePath)); return result; }
public void Deserialize(BEncodedDictionary dict) { fastResume = new FastResume ((BEncodedDictionary) dict["FastResume"]); savePath = dict["SavePath"].ToString (); torrentPath = dict["TorrentPath"].ToString (); string sb = dict["Settings"].ToString (); XmlSerializer s = new XmlSerializer (typeof (TorrentSettings)); using (System.IO.TextReader reader = new System.IO.StringReader (sb)) settings = (TorrentSettings) s.Deserialize (reader); }
public BEncodedDictionary Encode() { var dict = new BEncodedDictionary { {VersionKey, (BEncodedNumber) 1}, {InfoHashKey, new BEncodedString(Infohash.Hash)}, {BitfieldKey, new BEncodedString(Bitfield.ToByteArray())}, {BitfieldLengthKey, (BEncodedNumber) Bitfield.Length} }; return dict; }
public void benDictionaryEncoding() { var data = Encoding.UTF8.GetBytes("d4:spaml1:a1:bee"); var dict = new BEncodedDictionary(); var list = new BEncodedList(); list.Add(new BEncodedString("a")); list.Add(new BEncodedString("b")); dict.Add("spam", list); Assert.Equal(Encoding.UTF8.GetString(data), Encoding.UTF8.GetString(dict.Encode())); Assert.True(Toolbox.ByteMatch(data, dict.Encode())); }
public void benDictionaryEncodingBuffered() { var data = Encoding.UTF8.GetBytes("d4:spaml1:a1:bee"); var dict = new BEncodedDictionary(); var list = new BEncodedList(); list.Add(new BEncodedString("a")); list.Add(new BEncodedString("b")); dict.Add("spam", list); var result = new byte[dict.LengthInBytes()]; dict.Encode(result, 0); Assert.True(Toolbox.ByteMatch(data, result)); }
private bool storeMd5; // True if an MD5 hash of each file should be included #endregion Fields #region Constructors public TorrentCreator() { BEncodedDictionary info = new BEncodedDictionary(); this.announces = new List<List<string>>(); this.ignoreHiddenFiles = true; this.dict = new BEncodedDictionary(); this.dict.Add("info", info); // Add in initial values for some of the torrent attributes PieceLength = 256 * 1024; // 256kB default piece size this.Encoding = "UTF-8"; }
public void benDictionaryEncoding() { byte[] data = System.Text.Encoding.UTF8.GetBytes("d4:spaml1:a1:bee"); BEncodedDictionary dict = new BEncodedDictionary(); BEncodedList list = new BEncodedList(); list.Add(new BEncodedString("a")); list.Add(new BEncodedString("b")); dict.Add("spam", list); Assert.AreEqual(System.Text.Encoding.UTF8.GetString(data), System.Text.Encoding.UTF8.GetString(dict.Encode())); Assert.IsTrue(Toolbox.ByteMatch(data, dict.Encode())); }
public FastResume(BEncodedDictionary dict) { CheckContent(dict, VersionKey, 1); CheckContent(dict, InfoHashKey); CheckContent(dict, BitfieldKey); CheckContent(dict, BitfieldLengthKey); Infohash = new InfoHash(((BEncodedString) dict[InfoHashKey]).TextBytes); Bitfield = new BitField((int) ((BEncodedNumber) dict[BitfieldLengthKey]).Number); var data = ((BEncodedString) dict[BitfieldKey]).TextBytes; Bitfield.FromArray(data, 0, data.Length); }
public BEncodedDictionary Serialize() { BEncodedDictionary d = new BEncodedDictionary (); d.Add ("FastResume", FastResume.Encode ()); d.Add ("SavePath", (BEncodedString) SavePath); d.Add ("TorrentPath", (BEncodedString) TorrentPath); StringBuilder sb = new System.Text.StringBuilder(); XmlSerializer s = new XmlSerializer (typeof (TorrentSettings)); using (System.IO.TextWriter writer = new System.IO.StringWriter (sb)) s.Serialize (writer, Settings); d.Add ("Settings", (BEncodedString) sb.ToString ()); return d; }
private void AddCommonStuff(BEncodedDictionary torrent) { if (Announces.Count > 0 && Announces[0].Count > 0) Announce = Announces[0][0]; if (GetrightHttpSeeds.Count > 0) { var seedlist = new BEncodedList(); seedlist.AddRange( GetrightHttpSeeds.ConvertAll<BEncodedValue>(delegate(string s) { return (BEncodedString) s; })); torrent["url-list"] = seedlist; } var span = DateTime.Now - new DateTime(1970, 1, 1); torrent["creation date"] = new BEncodedNumber((long) span.TotalSeconds); }
public BEncodedSettingsStorage(string path) { this.path = path; this.settings = new BEncodedDictionary(); if (File.Exists(path)) { try { lock (this.flushLocker) using (BinaryReader reader = new BinaryReader(new FileStream(path, FileMode.Open))) this.settings = BEncodedValue.Decode(reader) as BEncodedDictionary; } catch (Exception) { } } }
private BEncodedDictionary CreateInfoDict() { BEncodedDictionary dict = new BEncodedDictionary(); dict.Add("source", new BEncodedString("http://www.thisiswhohostedit.com")); dict.Add("sha1", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("this is a sha1 hash string")))); dict.Add("ed2k", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("ed2k isn't a sha, but who cares")))); dict.Add("publisher-url.utf-8", new BEncodedString("http://www.iamthepublisher.com")); dict.Add("publisher-url", new BEncodedString("http://www.iamthepublisher.com")); dict.Add("publisher.utf-8", new BEncodedString("MonoTorrent Inc.")); dict.Add("publisher", new BEncodedString("MonoTorrent Inc.")); dict.Add("files", CreateFiles()); dict.Add("name.utf-8", new BEncodedString("MyBaseFolder")); dict.Add("name", new BEncodedString("MyBaseFolder")); dict.Add("piece length", new BEncodedNumber(512)); dict.Add("private", new BEncodedString("1")); dict.Add("pieces", new BEncodedString(new byte[((26000 + 512) / 512) * 20])); // Total size is 26000, piecelength is 512 return dict; }
public FastResume(BEncodedDictionary dict) { CheckContent(dict, VersionKey, (BEncodedNumber)1); CheckContent(dict, InfoHashKey); CheckContent(dict, BitfieldKey); CheckContent(dict, BitfieldLengthKey); infoHash = new InfoHash(((BEncodedString)dict[InfoHashKey]).TextBytes); bitfield = new BitField((int)((BEncodedNumber)dict[BitfieldLengthKey]).Number); byte[] data = ((BEncodedString)dict[BitfieldKey]).TextBytes; bitfield.FromArray(data, 0, data.Length); if (dict.ContainsKey(PrioritiesKey)) { var list = (BEncodedList)dict[PrioritiesKey]; priorities = list.Select(v => (Priority)((BEncodedNumber)v).Number).ToArray(); } }
public LTMetadata(byte extensionId, eMessageType type, int piece, byte[] metadata) : this() { ExtensionId = extensionId; MetadataMessageType = type; MetadataPiece = metadata; Piece = piece; dict = new BEncodedDictionary(); dict.Add(MessageTypeKey, (BEncodedNumber) (int) MetadataMessageType); dict.Add(PieceKey, (BEncodedNumber) piece); if (MetadataMessageType == eMessageType.Data) { Check.Metadata(metadata); dict.Add(TotalSizeKey, (BEncodedNumber) metadata.Length); } }
public LTMetadata(byte extensionId, eMessageType type, int piece, byte[] metadata) : this() { ExtensionId = extensionId; _messageType = type; MetadataPiece = metadata; Piece = piece; _dict = new BEncodedDictionary { {MessageTypeKey, (BEncodedNumber) (int) _messageType}, {PieceKey, (BEncodedNumber) piece} }; if (_messageType != eMessageType.Data) return; Check.Metadata(metadata); _dict.Add(TotalSizeKey, (BEncodedNumber) metadata.Length); }
private static BEncodedDictionary CreateTorrent(int pieceLength) { var infoDict = new BEncodedDictionary(); infoDict[new BEncodedString("piece length")] = new BEncodedNumber(pieceLength); infoDict[new BEncodedString("pieces")] = new BEncodedString(new byte[20*15]); infoDict[new BEncodedString("length")] = new BEncodedNumber(15*256*1024 - 1); infoDict[new BEncodedString("name")] = new BEncodedString("test.files"); var dict = new BEncodedDictionary(); dict[new BEncodedString("info")] = infoDict; var announceTier = new BEncodedList(); announceTier.Add(new BEncodedString("custom://transfers1/announce")); announceTier.Add(new BEncodedString("custom://transfers2/announce")); announceTier.Add(new BEncodedString("http://transfers3/announce")); var announceList = new BEncodedList(); announceList.Add(announceTier); dict[new BEncodedString("announce-list")] = announceList; return dict; }
public void StartUp() { DateTime current = new DateTime(2006, 7, 1, 5, 5, 5); DateTime epochStart = new DateTime(1970, 1, 1, 0, 0, 0); TimeSpan span = current - epochStart; creationTime = (long)span.TotalSeconds; Console.WriteLine(creationTime.ToString() + "Creation seconds"); BEncodedDictionary torrentInfo = new BEncodedDictionary(); torrentInfo.Add("announce", new BEncodedString("http://myannouceurl/announce")); torrentInfo.Add("creation date", new BEncodedNumber(creationTime)); torrentInfo.Add("nodes", new BEncodedList()); //FIXME: What is this? torrentInfo.Add("comment.utf-8", new BEncodedString("my big long comment")); torrentInfo.Add("comment", new BEncodedString("my big long comment")); torrentInfo.Add("azureus_properties", new BEncodedDictionary()); //FIXME: What is this? torrentInfo.Add("created by", new BEncodedString("MonoTorrent/" + VersionInfo.ClientVersion)); torrentInfo.Add("encoding", new BEncodedString("UTF-8")); torrentInfo.Add("info", CreateInfoDict()); torrentInfo.Add("private", new BEncodedString("1")); torrent = Torrent.Load(torrentInfo); }
private void Initialize() { AutoWatchers = new List <FileSystemWatcher>(); SettingsManager.Initialize(); SettingsManager = new SettingsManager(); LoadSettings(); Client.Initialize(SettingsManager); SettingsManager.ForcePropertyUpdate(); foreach (var label in SettingsManager.Labels) { AddLabel(label); } // Load prior session on another thread because it takes some time Task.Factory.StartNew(() => { BEncodedDictionary resume = null; if (File.Exists(SettingsManager.FastResumePath)) { resume = BEncodedValue.Decode <BEncodedDictionary>( File.ReadAllBytes(SettingsManager.FastResumePath)); File.Delete(SettingsManager.FastResumePath); } var torrents = Directory.GetFiles(SettingsManager.TorrentCachePath, "*.torrent"); var toRemove = new List <string>(Directory.GetFiles(SettingsManager.TorrentCachePath, "*.info")); var serializer = new JsonSerializer(); foreach (var torrent in torrents) { var path = Path.Combine(SettingsManager.TorrentCachePath, Path.GetFileNameWithoutExtension(torrent)) + ".info"; if (toRemove.Contains(path)) { toRemove.Remove(path); } try { TorrentInfo info; using (var reader = new StreamReader(path)) info = serializer.Deserialize <TorrentInfo>(new JsonTextReader(reader)); var wrapper = new TorrentWrapper(Torrent.Load(torrent), info.Path, new TorrentSettings()); PeriodicTorrent periodicTorrent; bool start = info.IsRunning; if (Client.Torrents.Count > SettingsManager.MaxActiveTorrents) { start = false; } if (resume != null && resume.ContainsKey(wrapper.Torrent.InfoHash.ToHex())) { periodicTorrent = Client.LoadFastResume(new FastResume((BEncodedDictionary)resume[wrapper.Torrent.InfoHash.ToHex()]), wrapper, start); } else { periodicTorrent = Client.AddTorrent(wrapper, start); } periodicTorrent.LoadInfo(info); periodicTorrent.CacheFilePath = torrent; } catch { } } // Clean up abandoned .info files foreach (var file in toRemove) { File.Delete(file); } }); NextQueueCycle = DateTime.Now.AddSeconds(10); Timer = new Timer(o => Dispatcher.Invoke(new Action(PeriodicUpdate)), null, 1000, 1000); IsIdle = false; if (SettingsManager.AutoUpdate) { CheckForUpdates(); } }
public GetPeersResponse(BEncodedDictionary d, QueryMessage m) : base(d, m) { }
public BEncodedDictionary GetMetaData(InfoHash hash) { WireMessage message; ExtHandShack exths; long metadataSize; int piecesNum; byte[] metadata; byte ut_metadata; try { //连接 if (!client.ConnectAsync(EndPoint.Address, EndPoint.Port).Wait(5000)) { Trace.WriteLine("Connect Timeout", "Socket"); return(null); } stream = client.GetStream(); //发送握手 message = new HandShack(hash); SendMessage(message); //接受握手 message = ReceiveMessage <HandShack>(1); if (!message.Legal || !(message as HandShack).SupportExtend) { Trace.WriteLine(EndPoint, "HandShack Fail"); return(null); } //发送拓展握手 message = new ExtHandShack() { SupportUtMetadata = true }; SendMessage(message); //接受拓展 exths = ReceiveMessage <ExtHandShack>(); if (!exths.Legal || !exths.CanGetMetadate || exths.MetadataSize > MaxMetadataSize || exths.MetadataSize <= 0) { Trace.WriteLine(EndPoint, "ExtendHandShack Fail"); return(null); } metadataSize = exths.MetadataSize; ut_metadata = exths.UtMetadata; piecesNum = (int)Math.Ceiling(metadataSize / (decimal)PieceLength); //开始接受pieces var rtask = ReceivePiecesAsync(metadataSize, piecesNum); //开始发送piece请求 for (int i = 0; i < piecesNum; i++) { message = new ExtQueryPiece(ut_metadata, i); SendMessage(message); } //等待pieces接收完毕 rtask.Wait(); metadata = rtask.Result; if (metadata == null) { return(null); } //检查hash值是否正确 var sha1 = new System.Security.Cryptography.SHA1CryptoServiceProvider(); byte[] infohash = sha1.ComputeHash(metadata); if (!infohash.SequenceEqual(hash.Hash)) { Trace.WriteLine(EndPoint, "Hash Wrong"); return(null); } return(BEncodedDictionary.DecodeTorrent(metadata)); } catch (AggregateException ex) { throw ex.InnerException; } finally { if (client != null) { client.Close(); } } }
internal static Torrent CreateMultiFileTorrent(TorrentFile[] files, int pieceLength, out BEncodedDictionary torrentInfo) { using var rig = CreateMultiFile(files, pieceLength); torrentInfo = rig.TorrentDict; return(rig.Torrent); }
public void DecodeTorrentNotDictionary() { string benString = "5:test"; Assert.Throws <BEncodingException> (() => BEncodedDictionary.DecodeTorrent(Encoding.UTF8.GetBytes(benString))); }
private static async System.Threading.Tasks.Task StartEngineAsync() { int port; Torrent torrent = null; // Ask the user what port they want to use for incoming connections Console.Write(Environment.NewLine + "Choose a listen port: "); //while (!Int32.TryParse(Console.ReadLine(), out port)) { } port = 5000; // Create the settings which the engine will use // downloadsPath - this is the path where we will save all the files to // port - this is the port we listen for connections on EngineSettings engineSettings = new EngineSettings(downloadsPath, port); engineSettings.PreferEncryption = false; engineSettings.AllowedEncryption = EncryptionTypes.All; //engineSettings.GlobalMaxUploadSpeed = 30 * 1024; //engineSettings.GlobalMaxDownloadSpeed = 100 * 1024; //engineSettings.MaxReadRate = 1 * 1024 * 1024; // Create the default settings which a torrent will have. // 4 Upload slots - a good ratio is one slot per 5kB of upload speed // 50 open connections - should never really need to be changed // Unlimited download speed - valid range from 0 -> int.Max // Unlimited upload speed - valid range from 0 -> int.Max TorrentSettings torrentDefaults = new TorrentSettings(4, 150, 0, 0); // Create an instance of the engine. engine = new ClientEngine(engineSettings); engine.ChangeListenEndpoint(new IPEndPoint(IPAddress.Any, port)); byte[] nodes = null; try { nodes = File.ReadAllBytes(dhtNodeFile); } catch { Console.WriteLine("No existing dht nodes could be loaded"); } DhtListener dhtListner = new DhtListener(new IPEndPoint(IPAddress.Any, port)); DhtEngine dht = new DhtEngine(dhtListner); engine.RegisterDht(dht); dhtListner.Start(); engine.DhtEngine.Start(nodes); // If the SavePath does not exist, we want to create it. if (!Directory.Exists(engine.Settings.SavePath)) { Directory.CreateDirectory(engine.Settings.SavePath); } // If the torrentsPath does not exist, we want to create it if (!Directory.Exists(torrentsPath)) { Directory.CreateDirectory(torrentsPath); } BEncodedDictionary fastResume; try { fastResume = BEncodedValue.Decode <BEncodedDictionary>(File.ReadAllBytes(fastResumeFile)); } catch { fastResume = new BEncodedDictionary(); } // For each file in the torrents path that is a .torrent file, load it into the engine. foreach (string file in Directory.GetFiles(torrentsPath)) { if (file.EndsWith(".torrent")) { try { // Load the .torrent from the file into a Torrent instance // You can use this to do preprocessing should you need to torrent = Torrent.Load(file); Console.WriteLine(torrent.InfoHash.ToString()); } catch (Exception e) { Console.Write("Couldn't decode {0}: ", file); Console.WriteLine(e.Message); continue; } // When any preprocessing has been completed, you create a TorrentManager // which you then register with the engine. TorrentManager manager = new TorrentManager(torrent, downloadsPath, torrentDefaults); if (fastResume.ContainsKey(torrent.InfoHash.ToHex())) { manager.LoadFastResume(new FastResume((BEncodedDictionary)fastResume[torrent.InfoHash.ToHex()])); } await engine.Register(manager); // Store the torrent manager in our list so we can access it later torrents.Add(manager); manager.PeersFound += new EventHandler <PeersAddedEventArgs>(manager_PeersFound); } } // If we loaded no torrents, just exist. The user can put files in the torrents directory and start // the client again if (torrents.Count == 0) { Console.WriteLine("No torrents found in the Torrents directory"); Console.WriteLine("Exiting..."); engine.Dispose(); return; } // For each torrent manager we loaded and stored in our list, hook into the events // in the torrent manager and start the engine. foreach (TorrentManager manager in torrents) { // Every time a piece is hashed, this is fired. manager.PieceHashed += delegate(object o, PieceHashedEventArgs e) { lock (listener) { listener.WriteLine(string.Format("Piece Hashed: {0} - {1}", e.PieceIndex, e.HashPassed ? "Pass" : "Fail")); } }; // Every time the state changes (Stopped -> Seeding -> Downloading -> Hashing) this is fired manager.TorrentStateChanged += delegate(object o, TorrentStateChangedEventArgs e) { lock (listener) { listener.WriteLine("OldState: " + e.OldState.ToString() + " NewState: " + e.NewState.ToString()); } }; // Every time the tracker's state changes, this is fired foreach (TrackerTier tier in manager.TrackerManager) { foreach (MonoTorrent.Client.Tracker.Tracker t in tier.Trackers) { t.AnnounceComplete += delegate(object sender, AnnounceResponseEventArgs e) { listener.WriteLine(string.Format("{0}: {1}", e.Successful, e.Tracker.ToString())); }; } } // Start the torrentmanager. The file will then hash (if required) and begin downloading/seeding manager.Start(); } // While the torrents are still running, print out some stats to the screen. // Details for all the loaded torrent managers are shown. int i = 0; bool running = true; StringBuilder sb = new StringBuilder(1024); while (running) { if ((i++) % 10 == 0) { sb.Remove(0, sb.Length); running = torrents.Exists(delegate(TorrentManager m) { return(m.State != TorrentState.Stopped); }); AppendFormat(sb, "Total Download Rate: {0:0.00}kB/sec", engine.TotalDownloadSpeed / 1024.0); AppendFormat(sb, "Total Upload Rate: {0:0.00}kB/sec", engine.TotalUploadSpeed / 1024.0); AppendFormat(sb, "Disk Read Rate: {0:0.00} kB/s", engine.DiskManager.ReadRate / 1024.0); AppendFormat(sb, "Disk Write Rate: {0:0.00} kB/s", engine.DiskManager.WriteRate / 1024.0); AppendFormat(sb, "Total Read: {0:0.00} kB", engine.DiskManager.TotalRead / 1024.0); AppendFormat(sb, "Total Written: {0:0.00} kB", engine.DiskManager.TotalWritten / 1024.0); AppendFormat(sb, "Open Connections: {0}", engine.ConnectionManager.OpenConnections); foreach (TorrentManager manager in torrents) { AppendSeperator(sb); AppendFormat(sb, "State: {0}", manager.State); AppendFormat(sb, "Name: {0}", manager.Torrent == null ? "MetaDataMode" : manager.Torrent.Name); AppendFormat(sb, "Progress: {0:0.00}", manager.Progress); AppendFormat(sb, "Download Speed: {0:0.00} kB/s", manager.Monitor.DownloadSpeed / 1024.0); AppendFormat(sb, "Upload Speed: {0:0.00} kB/s", manager.Monitor.UploadSpeed / 1024.0); AppendFormat(sb, "Total Downloaded: {0:0.00} MB", manager.Monitor.DataBytesDownloaded / (1024.0 * 1024.0)); AppendFormat(sb, "Total Uploaded: {0:0.00} MB", manager.Monitor.DataBytesUploaded / (1024.0 * 1024.0)); MonoTorrent.Client.Tracker.Tracker tracker = manager.TrackerManager.CurrentTracker; //AppendFormat(sb, "Tracker Status: {0}", tracker == null ? "<no tracker>" : tracker.State.ToString()); AppendFormat(sb, "Warning Message: {0}", tracker == null ? "<no tracker>" : tracker.WarningMessage); AppendFormat(sb, "Failure Message: {0}", tracker == null ? "<no tracker>" : tracker.FailureMessage); if (manager.PieceManager != null) { AppendFormat(sb, "Current Requests: {0}", manager.PieceManager.CurrentRequestCount()); } foreach (PeerId p in manager.GetPeers()) { AppendFormat(sb, "\t{2} - {1:0.00}/{3:0.00}kB/sec - {0}", p.Peer.ConnectionUri, p.Monitor.DownloadSpeed / 1024.0, p.AmRequestingPiecesCount, p.Monitor.UploadSpeed / 1024.0); } AppendFormat(sb, "", null); if (manager.Torrent != null) { foreach (TorrentFile file in manager.Torrent.Files) { AppendFormat(sb, "{1:0.00}% - {0}", file.Path, file.BitField.PercentComplete); } } } //Console.Clear(); Console.WriteLine(sb.ToString()); listener.ExportTo(Console.Out); } System.Threading.Thread.Sleep(500); } }
public AnnouncePeerResponse(BEncodedDictionary d, QueryMessage m) : base(d, m) { }
protected ResponseMessage(BEncodedDictionary d) : base(d) { }
public FindNode(BEncodedDictionary d) : base(d, responseCreator) { }
protected ResponseMessage(BEncodedDictionary d, QueryMessage m) : base(d) { queryMessage = m; }
private BEncodedList CreateFiles() { BEncodedList files = new BEncodedList(); BEncodedDictionary file; BEncodedList path; path = new BEncodedList { new BEncodedString("file1.txt") }; file = new BEncodedDictionary { { "sha1", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash1"))) }, { "ed2k", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash2"))) }, { "length", new BEncodedNumber(50000) }, { "md5sum", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash3"))) }, { "path.utf-8", path }, { "path", path } }; files.Add(file); path = new BEncodedList { new BEncodedString("subfolder1"), new BEncodedString("file2.txt") }; file = new BEncodedDictionary { { "sha1", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash1"))) }, { "ed2k", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash2"))) }, { "length", new BEncodedNumber(60000) }, { "md5sum", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash3"))) }, { "path.utf-8", path }, { "path", path } }; files.Add(file); path = new BEncodedList { new BEncodedString("subfolder1"), new BEncodedString("subfolder2"), new BEncodedString("file3.txt") }; file = new BEncodedDictionary { { "sha1", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash1"))) }, { "ed2k", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash2"))) }, { "length", new BEncodedNumber(70000) }, { "md5sum", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash3"))) }, { "path.utf-8", path }, { "path", path } }; files.Add(file); path = new BEncodedList { new BEncodedString("subfolder1"), new BEncodedString("subfolder2"), new BEncodedString("file4.txt") }; file = new BEncodedDictionary { { "sha1", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash1"))) }, { "ed2k", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash2"))) }, { "length", new BEncodedNumber(80000) }, { "md5sum", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash3"))) }, { "path.utf-8", path }, { "path", path } }; files.Add(file); return(files); }
private static async Task StartEngine() { int port; Torrent torrent = null; // Ask the user what port they want to use for incoming connections // 询问用户要将使用哪个端口用于连接 Console.Write($"{Environment.NewLine} 选择监听的端口: "); while (!Int32.TryParse(Console.ReadLine(), out port)) { } // 创建一个引擎的默认配置 // downloadsPath - 文件下载的目录 // port - 引擎监听的端口 EngineSettings engineSettings = new EngineSettings { SavePath = downloadsPath, ListenPort = port }; //engineSettings.GlobalMaxUploadSpeed = 30 * 1024; //engineSettings.GlobalMaxDownloadSpeed = 100 * 1024; //engineSettings.MaxReadRate = 1 * 1024 * 1024; // 创建一个 Torrent 默认的配置信息. TorrentSettings torrentDefaults = new TorrentSettings(); // 创建一个客户端引擎. engine = new ClientEngine(engineSettings); byte[] nodes = Array.Empty <byte> (); try { if (File.Exists(dhtNodeFile)) { nodes = File.ReadAllBytes(dhtNodeFile); } } catch { Console.WriteLine("No existing dht nodes could be loaded"); } DhtEngine dht = new DhtEngine(new IPEndPoint(IPAddress.Any, port)); await engine.RegisterDhtAsync(dht); // 这将启动Dht引擎,但不会等待完全初始化完成. // 这是因为根据连接节点时超时的数量,启动最多需要2分钟. await engine.DhtEngine.StartAsync(nodes); // 如果下载路径不存在,则创建之. if (!Directory.Exists(engine.Settings.SavePath)) { Directory.CreateDirectory(engine.Settings.SavePath); } // 如果Torrent存储目录不存在,则创建之. if (!Directory.Exists(torrentsPath)) { Directory.CreateDirectory(torrentsPath); } BEncodedDictionary fastResume = new BEncodedDictionary(); try { if (File.Exists(fastResumeFile)) { fastResume = BEncodedValue.Decode <BEncodedDictionary> (File.ReadAllBytes(fastResumeFile)); } } catch { } // 将Torrents目录中的每个 torrent 文件将其加载到引擎中. foreach (string file in Directory.GetFiles(torrentsPath)) { if (file.EndsWith(".torrent", StringComparison.OrdinalIgnoreCase)) { try { // 加载torrent文件到Torrent实例中,如果需要的话,可以使用它进行预处理 torrent = await Torrent.LoadAsync(file); Console.WriteLine(torrent.InfoHash.ToString()); } catch (Exception e) { Console.Write("Couldn't decode {0}: ", file); Console.WriteLine(e.Message); continue; } // 当任何预处理完成后,您将创建一个TorrentManager,然后在引擎上创建它. TorrentManager manager = new TorrentManager(torrent, downloadsPath, torrentDefaults); if (fastResume.ContainsKey(torrent.InfoHash.ToHex())) { manager.LoadFastResume(new FastResume((BEncodedDictionary)fastResume[torrent.InfoHash.ToHex()])); } await engine.Register(manager); // 将 TorrentManager 存储在列表中,方便以后访问它. torrents.Add(manager); manager.PeersFound += Manager_PeersFound; } } // If we loaded no torrents, just exist. The user can put files in the torrents directory and start the client again if (torrents.Count == 0) { Console.WriteLine("没有在目录中找到 torrent 文件"); Console.WriteLine("退出..."); engine.Dispose(); return; } // 遍历存储在列表中的每个TorrentManager,在TorrentManager中连接到事件并启动引擎。 foreach (TorrentManager manager in torrents) { manager.PeerConnected += (o, e) => { lock (listener) listener.WriteLine($"连接成功: {e.Peer.Uri}"); }; manager.ConnectionAttemptFailed += (o, e) => { lock (listener) listener.WriteLine( $"连接失败: {e.Peer.ConnectionUri} - {e.Reason} - {e.Peer.AllowedEncryption}"); }; // 每次散列一个片段,就会触发这个. manager.PieceHashed += delegate(object o, PieceHashedEventArgs e) { lock (listener) listener.WriteLine($"散列的片段: {e.PieceIndex} - {(e.HashPassed ? "Pass" : "Fail")}"); }; // 每当状态改变时触发 (Stopped -> Seeding -> Downloading -> Hashing) manager.TorrentStateChanged += delegate(object o, TorrentStateChangedEventArgs e) { lock (listener) listener.WriteLine($"旧状态: {e.OldState} 新状态: {e.NewState}"); }; // 每当跟踪器的状态改变时,就会触发. manager.TrackerManager.AnnounceComplete += (sender, e) => { listener.WriteLine($"{e.Successful}: {e.Tracker}"); }; // 开始运行TorrentManager. // 然后文件将散列(如果需要)并开始下载/发送. await manager.StartAsync(); } // Enable automatic port forwarding. The engine will use Mono.Nat to search for // uPnP or NAT-PMP compatible devices and then issue port forwarding requests to it. await engine.EnablePortForwardingAsync(CancellationToken.None); // This is how to access the list of port mappings, and to see if they were // successful, pending or failed. If they failed it could be because the public port // is already in use by another computer on your network. foreach (var successfulMapping in engine.PortMappings.Created) { } foreach (var failedMapping in engine.PortMappings.Failed) { } foreach (var failedMapping in engine.PortMappings.Pending) { } // While the torrents are still running, print out some stats to the screen. // Details for all the loaded torrent managers are shown. int i = 0; bool running = true; StringBuilder sb = new StringBuilder(1024); while (running) { if ((i++) % 10 == 0) { sb.Remove(0, sb.Length); running = torrents.Exists(m => m.State != TorrentState.Stopped); AppendFormat(sb, "总下载速度: {0:0.00}kB/sec", engine.TotalDownloadSpeed / 1024.0); AppendFormat(sb, "总上传速度: {0:0.00}kB/sec", engine.TotalUploadSpeed / 1024.0); AppendFormat(sb, "磁盘读速度: {0:0.00} kB/s", engine.DiskManager.ReadRate / 1024.0); AppendFormat(sb, "磁盘写速度: {0:0.00} kB/s", engine.DiskManager.WriteRate / 1024.0); AppendFormat(sb, "Total Read: {0:0.00} kB", engine.DiskManager.TotalRead / 1024.0); AppendFormat(sb, "Total Written: {0:0.00} kB", engine.DiskManager.TotalWritten / 1024.0); AppendFormat(sb, "Open Connections: {0}", engine.ConnectionManager.OpenConnections); foreach (TorrentManager manager in torrents) { AppendSeparator(sb); AppendFormat(sb, "状态: {0}", manager.State); AppendFormat(sb, "名称: {0}", manager.Torrent == null ? "MetaDataMode" : manager.Torrent.Name); AppendFormat(sb, "进度: {0:0.00}", manager.Progress); AppendFormat(sb, "下载速度: {0:0.00} kB/s", manager.Monitor.DownloadSpeed / 1024.0); AppendFormat(sb, "上传速度: {0:0.00} kB/s", manager.Monitor.UploadSpeed / 1024.0); AppendFormat(sb, "下载量: {0:0.00} MB", manager.Monitor.DataBytesDownloaded / (1024.0 * 1024.0)); AppendFormat(sb, "上传量: {0:0.00} MB", manager.Monitor.DataBytesUploaded / (1024.0 * 1024.0)); AppendFormat(sb, "Tracker Status"); foreach (var tier in manager.TrackerManager.Tiers) { AppendFormat(sb, $"\t{tier.ActiveTracker} : Announce Succeeded: {tier.LastAnnounceSucceeded}. Scrape Succeeded: {tier.LastScrapSucceeded}."); } if (manager.PieceManager != null) { AppendFormat(sb, "当前请求: {0}", await manager.PieceManager.CurrentRequestCountAsync()); } foreach (PeerId p in await manager.GetPeersAsync()) { AppendFormat(sb, "\t{2} - {1:0.00}/{3:0.00}kB/sec - {0}", p.Uri, p.Monitor.DownloadSpeed / 1024.0, p.AmRequestingPiecesCount, p.Monitor.UploadSpeed / 1024.0); } AppendFormat(sb, "", null); if (manager.Torrent != null) { foreach (TorrentFile file in manager.Torrent.Files) { AppendFormat(sb, "{1:0.00}% - {0}", file.Path, file.BitField.PercentComplete); } } } Console.Clear(); Console.WriteLine(sb.ToString()); listener.ExportTo(Console.Out); } Thread.Sleep(500); } // 停止搜索与uPnP或NAT-PMP兼容的设备,并删除所有已创建的映射. await engine.DisablePortForwardingAsync(CancellationToken.None); }
public ErrorMessage(BEncodedDictionary d) : base(d) { }
protected Message(BEncodedDictionary dictionary) { Properties = dictionary; }
protected QueryBase(BEncodedDictionary d, Func <BEncodedDictionary, QueryBase, DhtMessage> responseCreator) : base(d) { ResponseCreator = responseCreator; }
public override void Decode(byte[] buffer, int offset, int length) { Properties = BEncodedValue.Decode <BEncodedDictionary>(buffer, offset, length, false); }
public FindNodeResponse(BEncodedDictionary d, QueryMessage m) : base(d, m) { }
protected override void HandleLtMetadataMessage(PeerId id, LTMetadata message) { base.HandleLtMetadataMessage(id, message); switch (message.MetadataMessageType) { case LTMetadata.eMessageType.Data: if (Stream == null) { throw new Exception("Need extention handshake before ut_metadata message."); } Stream.Seek(message.Piece * LTMetadata.BlockSize, SeekOrigin.Begin); Stream.Write(message.MetadataPiece, 0, message.MetadataPiece.Length); bitField[message.Piece] = true; if (bitField.AllTrue) { byte[] hash; Stream.Position = 0; using (SHA1 hasher = HashAlgoFactory.Create <SHA1>()) hash = hasher.ComputeHash(Stream); if (!Manager.InfoHash.Equals(hash)) { bitField.SetAll(false); } else { Torrent t; Stream.Position = 0; BEncodedDictionary dict = new BEncodedDictionary(); dict.Add("info", BEncodedValue.Decode(Stream)); // FIXME: Add the trackers too if (Torrent.TryLoad(dict.Encode(), out t)) { try { if (Directory.Exists(savePath)) { savePath = Path.Combine(savePath, Manager.InfoHash.ToHex() + ".torrent"); } File.Delete(savePath); File.WriteAllBytes(savePath, dict.Encode()); } catch (Exception ex) { Logger.Log(null, "*METADATA EXCEPTION* - Can not write in {0} : {1}", savePath, ex); Manager.TrySetError(Reason.WriteFailure, ex); return; } t.TorrentPath = savePath; Manager.Torrent = t; SwitchToRegular(); } else { bitField.SetAll(false); } } } //Double test because we can change the bitfield in the other block if (!bitField.AllTrue) { RequestNextNeededPiece(id); } break; case LTMetadata.eMessageType.Reject: //TODO //Think to what we do in this situation //for moment nothing ;) //reject or flood? break; case LTMetadata.eMessageType.Request: //ever done in base class but needed to avoid default break; default: throw new MessageException(string.Format("Invalid messagetype in LTMetadata: {0}", message.MetadataMessageType)); } }
public void DecodeTorrent_MissingTrailingE() { string benString = "d1:a1:b"; Assert.Throws <BEncodingException> (() => BEncodedDictionary.DecodeTorrent(Encoding.UTF8.GetBytes(benString))); }
public PeerExchangeMessage() : base(Support.MessageId) { _peerDict = new BEncodedDictionary(); }
static BEncodedValue Get(BEncodedDictionary dictionary, BEncodedString key) { return(dictionary.ContainsKey(key) ? dictionary[key] : null); }
/// <summary> /// This method is called internally to load the information found within the "Info" section /// of the .torrent file /// </summary> /// <param name="dictionary">The dictionary representing the Info section of the .torrent file</param> private void ProcessInfo(BEncodedDictionary dictionary) { metadata = dictionary.Encode(); this.pieceLength = int.Parse(dictionary["piece length"].ToString()); LoadHashPieces(((BEncodedString)dictionary["pieces"]).TextBytes); foreach (KeyValuePair <BEncodedString, BEncodedValue> keypair in dictionary) { switch (keypair.Key.Text) { case ("source"): this.source = keypair.Value.ToString(); break; case ("sha1"): this.sha1 = ((BEncodedString)keypair.Value).TextBytes; break; case ("ed2k"): this.ed2k = ((BEncodedString)keypair.Value).TextBytes; break; case ("publisher-url.utf-8"): if (keypair.Value.ToString().Length > 0) { this.publisherUrl = keypair.Value.ToString(); } break; case ("publisher-url"): if ((String.IsNullOrEmpty(publisherUrl)) && (keypair.Value.ToString().Length > 0)) { this.publisherUrl = keypair.Value.ToString(); } break; case ("publisher.utf-8"): if (keypair.Value.ToString().Length > 0) { this.publisher = keypair.Value.ToString(); } break; case ("publisher"): if ((String.IsNullOrEmpty(publisher)) && (keypair.Value.ToString().Length > 0)) { this.publisher = keypair.Value.ToString(); } break; case ("files"): LoadTorrentFiles(((BEncodedList)keypair.Value)); break; case ("name.utf-8"): if (keypair.Value.ToString().Length > 0) { this.name = keypair.Value.ToString(); } break; case ("name"): if ((String.IsNullOrEmpty(this.name)) && (keypair.Value.ToString().Length > 0)) { this.name = keypair.Value.ToString(); } break; case ("piece length"): // Already handled break; case ("length"): break; // This is a singlefile torrent case ("private"): this.isPrivate = (keypair.Value.ToString() == "1") ? true : false; break; default: break; } } if (this.torrentFiles == null) // Not a multi-file torrent { long length = long.Parse(dictionary["length"].ToString()); this.size = length; string path = this.name; byte[] md5 = (dictionary.ContainsKey("md5")) ? ((BEncodedString)dictionary["md5"]).TextBytes : null; byte[] ed2k = (dictionary.ContainsKey("ed2k")) ? ((BEncodedString)dictionary["ed2k"]).TextBytes : null; byte[] sha1 = (dictionary.ContainsKey("sha1")) ? ((BEncodedString)dictionary["sha1"]).TextBytes : null; this.torrentFiles = new TorrentFile[1]; int endPiece = Math.Min(Pieces.Count - 1, (int)((size + (pieceLength - 1)) / pieceLength)); this.torrentFiles[0] = new TorrentFile(path, length, path, 0, endPiece, md5, ed2k, sha1); } }
public static bool TryDecodeMessage(BEncodedDictionary dictionary, out Message message) { string error; return(TryDecodeMessage(dictionary, out message, out error)); }
public static Torrent Load(BEncodedDictionary torrentInformation) { return(LoadCore((BEncodedDictionary)BEncodedValue.Decode(torrentInformation.Encode()))); }
public static void Process(string inputFilename, BEncodedDictionary torrent) { bool successful = false; bool isFgbtTorrent = false; BEncodedDictionary newTorrent = new BEncodedDictionary(); TryReadKeiGuiConfig(); if (true && !string.IsNullOrEmpty(inputFilename) && torrent != null) { FileInfo fi = new FileInfo(inputFilename); // 先判断是否是未来花园的种子 if (fi.Name.StartsWith("[FGBT].")) { try { var sourceString = ((torrent["info"] as BEncodedDictionary)["source"] as BEncodedString).Text; if (sourceString.StartsWith("FGBT-")) { // 是原来的未来花园的种子 isFgbtTorrent = true; } } catch (Exception) { } } var kt = new TrackerServer(new IPEndPoint(IPAddress.Loopback, 10000)); var announceString = "http://localhost:" + kgOptions.LocalTrackerServerPort.ToString() + kt.AnnouceUrl.TrimEnd('?'); try { newTorrent.Add("announce", announceString); newTorrent.Add("announce-list", new BEncodedList() { new BEncodedList() { announceString, } }); newTorrent.Add("created by", (torrent["created by"] as BEncodedString).Text); newTorrent.Add("creation date", (torrent["creation date"] as BEncodedNumber).Number); // 遵循花园的原则,不转码,直接设置编码为 UTF-8 newTorrent.Add("encoding", "UTF-8"); var info = new BEncodedDictionary(); if (isFgbtTorrent) { foreach (var item in (torrent["info"] as BEncodedDictionary)) { info.Add(item); } } else { if ((torrent["info"] as BEncodedDictionary).ContainsKey("files")) { // 单文件的种子是没有 files 项的 info.Add("files", (torrent["info"] as BEncodedDictionary)["files"]); } else { // 单文件的种子有 length 项 info.Add("length", (torrent["info"] as BEncodedDictionary)["length"]); } info.Add("name", (torrent["info"] as BEncodedDictionary)["name"]); info.Add("piece length", (torrent["info"] as BEncodedDictionary)["piece length"]); info.Add("pieces", (torrent["info"] as BEncodedDictionary)["pieces"]); info.Add("private", 1); // 至于 source 呢,要经过编码…… var origInfo = torrent["info"].Encode(); var sha1 = SHA1.Create(); var origInfoHash = sha1.ComputeHash(origInfo); sha1.Dispose(); var origInfoHashString = BitConverter.ToString(origInfoHash); origInfoHashString = new string(origInfoHashString.Where((c) => c != '-').ToArray()); info.Add("source", "KS-" + origInfoHashString); } newTorrent.Add("info", info); successful = true; } catch (Exception) { successful = false; } kt = null; } if (successful) { var fi = new FileInfo(inputFilename); var newName = Path.Combine(fi.DirectoryName, "[KS]." + fi.Name); // 命令行状态下不提示 //if (File.Exists(newName)) //{ // var dresult = MessageBox.Show("已存在 " + newName + ",是否覆盖?", Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation); // if (dresult == DialogResult.No) // { // return; // } //} try { using (var fs = new FileStream(newName, FileMode.OpenOrCreate, FileAccess.Write)) { var buf = newTorrent.Encode(); fs.Write(buf, 0, buf.Length); } Console.WriteLine("成功保存到 " + newName + "。"); } catch (Exception ex) { Console.WriteLine("无法写入 " + newName + ": " + ex.Message); } } else { Console.WriteLine("尝试生成并保存种子失败。"); } }
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); } } }
//only for register public LTMetadata() : base(Support.MessageId) { dict = EmptyDict; MetadataPiece = Array.Empty <byte> (); }
public GetPeers(BEncodedDictionary d) : base(d, responseCreator) { }
public Ping(BEncodedDictionary d) : base(d, responseCreator) { }
public void InitializeTorrent(string torrentDir) { BEncodedDictionary fastResume; try { fastResume = BEncodedValue.Decode <BEncodedDictionary>(File.ReadAllBytes(this.fastResumeFile)); } catch { fastResume = new BEncodedDictionary(); } Torrent torrent = null; // Load the file into the engine if it ends with .torrent. if (torrentDir.EndsWith(".torrent")) { try { // Load the .torrent file from the file into a Torrent instance // You can use this to do preprocessing should you need to. torrent = Torrent.Load(torrentDir); Console.WriteLine(torrent.InfoHash.ToString()); } catch (Exception e) { Console.Write("Could not decode {0}: {1}", torrentDir, e.Message); return; } // When any preprocessing has been completed, you create a TorrentManager which you then register with the engine. TorrentManager postProcessManager = new TorrentManager(torrent, this.downloadDir, torrentDefaults); if (fastResume.ContainsKey(torrent.InfoHash.ToHex())) { postProcessManager.LoadFastResume(new FastResume((BEncodedDictionary)fastResume[torrent.InfoHash.ToHex()])); } this.clientEngine.Register(postProcessManager); // Store the torrent manager in our list so we can access it later. this.torrentManagers.Add(postProcessManager); postProcessManager.PeersFound += new EventHandler <PeersAddedEventArgs>(this.manager_PeersFound); } // For each torrent manager we loaded and stored in our list, hook into the events in the torrent manager and start the engine. foreach (TorrentManager torrentManager in this.torrentManagers) { // Every time a piece is hashed, this is fired. torrentManager.PieceHashed += delegate(object o, PieceHashedEventArgs e) { lock (this.topTrackers) { topTrackers.WriteLine(string.Format("Piece hashed: {0} - {1} ", e.PieceIndex, e.HashPassed ? "passed" : "failed")); } }; // Everytime the state changes (stopped -> seeding -> downloading -> hashing), this is fired. foreach (TrackerTier tier in torrentManager.TrackerManager) { List <Tracker> trackers = tier.GetTrackers(); foreach (Tracker tracker in trackers) { tracker.AnnounceComplete += delegate(object sender, AnnounceResponseEventArgs e) { this.topTrackers.WriteLine(string.Format("{0}: {1}", e.Successful, e.Tracker.ToString())); }; } } // Start the torrentManager. The file will then hash (if required) and begin loading. torrentManager.Start(); } Thread.Sleep(500); }