Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
 }
Beispiel #9
0
        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;
 }
Beispiel #11
0
        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)"");
 }
Beispiel #13
0
        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;
 }
Beispiel #15
0
        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));
 }
Beispiel #19
0
        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";
        }
Beispiel #20
0
        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);
        }
Beispiel #22
0
        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)
         {
         }
     }
 }
Beispiel #25
0
 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);
            }
        }
Beispiel #28
0
        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;
        }
Beispiel #30
0
        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);
        }
Beispiel #31
0
 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();
     }
 }
Beispiel #32
0
 public GetPeersResponse(BEncodedDictionary d, QueryMessage m)
     : base(d, m)
 {
 }
Beispiel #33
0
        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();
                }
            }
        }
Beispiel #34
0
 internal static Torrent CreateMultiFileTorrent(TorrentFile[] files, int pieceLength, out BEncodedDictionary torrentInfo)
 {
     using var rig = CreateMultiFile(files, pieceLength);
     torrentInfo   = rig.TorrentDict;
     return(rig.Torrent);
 }
Beispiel #35
0
        public void DecodeTorrentNotDictionary()
        {
            string benString = "5:test";

            Assert.Throws <BEncodingException> (() => BEncodedDictionary.DecodeTorrent(Encoding.UTF8.GetBytes(benString)));
        }
Beispiel #36
0
        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);
            }
        }
Beispiel #37
0
 public AnnouncePeerResponse(BEncodedDictionary d, QueryMessage m)
     : base(d, m)
 {
 }
Beispiel #38
0
 protected ResponseMessage(BEncodedDictionary d)
     : base(d)
 {
 }
Beispiel #39
0
 public FindNode(BEncodedDictionary d)
     : base(d, responseCreator)
 {
 }
Beispiel #40
0
 protected ResponseMessage(BEncodedDictionary d, QueryMessage m)
     : base(d)
 {
     queryMessage = m;
 }
Beispiel #41
0
        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);
        }
Beispiel #42
0
        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)
 {
 }
Beispiel #44
0
 protected Message(BEncodedDictionary dictionary)
 {
     Properties = dictionary;
 }
Beispiel #45
0
 protected QueryBase(BEncodedDictionary d, Func <BEncodedDictionary, QueryBase, DhtMessage> responseCreator)
     : base(d)
 {
     ResponseCreator = responseCreator;
 }
Beispiel #46
0
 public override void Decode(byte[] buffer, int offset, int length)
 {
     Properties = BEncodedValue.Decode <BEncodedDictionary>(buffer, offset, length, false);
 }
Beispiel #47
0
 public FindNodeResponse(BEncodedDictionary d, QueryMessage m)
     : base(d, m)
 {
 }
Beispiel #48
0
        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));
            }
        }
Beispiel #49
0
        public void DecodeTorrent_MissingTrailingE()
        {
            string benString = "d1:a1:b";

            Assert.Throws <BEncodingException> (() => BEncodedDictionary.DecodeTorrent(Encoding.UTF8.GetBytes(benString)));
        }
Beispiel #50
0
 public PeerExchangeMessage()
     : base(Support.MessageId)
 {
     _peerDict = new BEncodedDictionary();
 }
Beispiel #51
0
 static BEncodedValue Get(BEncodedDictionary dictionary, BEncodedString key)
 {
     return(dictionary.ContainsKey(key) ? dictionary[key] : null);
 }
Beispiel #52
0
        /// <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);
            }
        }
Beispiel #53
0
        public static bool TryDecodeMessage(BEncodedDictionary dictionary, out Message message)
        {
            string error;

            return(TryDecodeMessage(dictionary, out message, out error));
        }
Beispiel #54
0
 public static Torrent Load(BEncodedDictionary torrentInformation)
 {
     return(LoadCore((BEncodedDictionary)BEncodedValue.Decode(torrentInformation.Encode())));
 }
Beispiel #55
0
        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("尝试生成并保存种子失败。");
            }
        }
Beispiel #56
0
        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> ();
 }
Beispiel #58
0
 public GetPeers(BEncodedDictionary d)
     : base(d, responseCreator)
 {
 }
Beispiel #59
0
 public Ping(BEncodedDictionary d)
     : base(d, responseCreator)
 {
 }
Beispiel #60
0
        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);
        }