public async Task WaitForHashingToComplete()
        {
            if (!Manager.HasMetadata)
            {
                throw new TorrentException("A hash check cannot be performed if TorrentManager.HasMetadata is false.");
            }

            Manager.HashFails = 0;

            // Delete any existing fast resume data. We will need to recreate it after hashing completes.
            await Manager.MaybeDeleteFastResumeAsync();

            bool atLeastOneDoNotDownload = Manager.Files.Any(t => t.Priority == Priority.DoNotDownload);

            if (await DiskManager.CheckAnyFilesExistAsync(Manager))
            {
                int piecesHashed = 0;
                Cancellation.Token.ThrowIfCancellationRequested();
                // bep52: Properly support this
                using var hashBuffer = MemoryPool.Default.Rent(Manager.InfoHashes.GetMaxByteCount(), out Memory <byte> hashMemory);
                var hashes = new PieceHash(hashMemory);
                for (int index = 0; index < Manager.Torrent !.PieceCount; index++)
                {
                    if (atLeastOneDoNotDownload && !Manager.Files.Any(f => index >= f.StartPieceIndex && index <= f.EndPieceIndex && f.Priority != Priority.DoNotDownload))
                    {
                        // If a file is marked 'do not download' ensure we update the TorrentFiles
                        // so they also report that the piece is not available/downloaded.
                        Manager.OnPieceHashed(index, false, piecesHashed, Manager.PartialProgressSelector.TrueCount);
                        // Then mark this piece as being unhashed so we don't try to download it.
                        Manager.UnhashedPieces[index] = true;
                        continue;
                    }

                    await PausedCompletionSource.Task;
                    Cancellation.Token.ThrowIfCancellationRequested();

                    var successful = await DiskManager.GetHashAsync(Manager, index, hashes);

                    if (Cancellation.Token.IsCancellationRequested)
                    {
                        await DiskManager.CloseFilesAsync(Manager);

                        Cancellation.Token.ThrowIfCancellationRequested();
                    }

                    bool hashPassed = successful && Manager.PieceHashes.IsValid(hashes, index);
                    Manager.OnPieceHashed(index, hashPassed, ++piecesHashed, Manager.PartialProgressSelector.TrueCount);
                }
            }
            else
            {
                await PausedCompletionSource.Task;
                for (int i = 0; i < Manager.Torrent !.PieceCount; i++)
                {
                    Manager.OnPieceHashed(i, false, i + 1, Manager.Torrent.PieceCount);
                }
            }
        }
예제 #2
0
        public async Task WaitForHashingToComplete()
        {
            if (!Manager.HasMetadata)
            {
                throw new TorrentException("A hash check cannot be performed if TorrentManager.HasMetadata is false.");
            }

            // Ensure the partial progress selector is up to date before we start hashing
            UpdatePartialProgress();

            int piecesHashed = 0;

            Manager.HashFails = 0;

            // Delete any existing fast resume data. We will need to recreate it after hashing completes.
            await Manager.MaybeDeleteFastResumeAsync();

            if (await DiskManager.CheckAnyFilesExistAsync(Manager))
            {
                Cancellation.Token.ThrowIfCancellationRequested();
                for (int index = 0; index < Manager.Torrent.Pieces.Count; index++)
                {
                    if (!Manager.Files.Any(f => index >= f.StartPieceIndex && index <= f.EndPieceIndex && f.Priority != Priority.DoNotDownload))
                    {
                        // If a file is marked 'do not download' ensure we update the TorrentFiles
                        // so they also report that the piece is not available/downloaded.
                        Manager.OnPieceHashed(index, false, piecesHashed, Manager.PartialProgressSelector.TrueCount);
                        // Then mark this piece as being unhashed so we don't try to download it.
                        Manager.UnhashedPieces[index] = true;
                        continue;
                    }

                    await PausedCompletionSource.Task;
                    Cancellation.Token.ThrowIfCancellationRequested();

                    byte[] hash = await DiskManager.GetHashAsync(Manager, index);

                    if (Cancellation.Token.IsCancellationRequested)
                    {
                        await DiskManager.CloseFilesAsync(Manager);

                        Cancellation.Token.ThrowIfCancellationRequested();
                    }

                    bool hashPassed = hash != null && Manager.Torrent.Pieces.IsValid(hash, index);
                    Manager.OnPieceHashed(index, hashPassed, ++piecesHashed, Manager.PartialProgressSelector.TrueCount);
                }
            }
            else
            {
                await PausedCompletionSource.Task;

                for (int i = 0; i < Manager.Torrent.Pieces.Count; i++)
                {
                    Manager.OnPieceHashed(i, false, ++piecesHashed, Manager.Torrent.Pieces.Count);
                }
            }
        }
예제 #3
0
        public async Task WaitForHashingToComplete()
        {
            if (!Manager.HasMetadata)
            {
                throw new TorrentException("A hash check cannot be performed if TorrentManager.HasMetadata is false.");
            }

            Manager.HashFails = 0;
            if (await DiskManager.CheckAnyFilesExistAsync(Manager.Torrent))
            {
                Cancellation.Token.ThrowIfCancellationRequested();
                for (int index = 0; index < Manager.Torrent.Pieces.Count; index++)
                {
                    if (!Manager.Torrent.Files.Any(f => index >= f.StartPieceIndex && index <= f.EndPieceIndex && f.Priority != Priority.DoNotDownload))
                    {
                        // If a file is marked 'do not download' ensure we update the TorrentFiles
                        // so they also report that the piece is not available/downloaded.
                        Manager.OnPieceHashed(index, false);
                        // Then mark this piece as being unhashed so we don't try to download it.
                        Manager.UnhashedPieces[index] = true;
                        continue;
                    }

                    await PausedCompletionSource.Task;
                    Cancellation.Token.ThrowIfCancellationRequested();

                    var hash = await DiskManager.GetHashAsync(Manager.Torrent, index);

                    if (Cancellation.Token.IsCancellationRequested)
                    {
                        await DiskManager.CloseFilesAsync(Manager.Torrent);

                        Cancellation.Token.ThrowIfCancellationRequested();
                    }

                    var hashPassed = hash != null && Manager.Torrent.Pieces.IsValid(hash, index);
                    Manager.OnPieceHashed(index, hashPassed);
                }
            }
            else
            {
                await PausedCompletionSource.Task;

                for (int i = 0; i < Manager.Torrent.Pieces.Count; i++)
                {
                    Manager.OnPieceHashed(i, false);
                }
            }
        }
예제 #4
0
        public async Task WaitForHashingToComplete()
        {
            if (!Manager.HasMetadata)
            {
                throw new TorrentException("A hash check cannot be performed if TorrentManager.HasMetadata is false.");
            }

            Manager.HashFails = 0;
            if (await DiskManager.CheckAnyFilesExistAsync(Manager.Torrent))
            {
                Cancellation.Token.ThrowIfCancellationRequested();
                for (int index = 0; index < Manager.Torrent.Pieces.Count; index++)
                {
                    if (!Manager.Torrent.Files.Any(f => index >= f.StartPieceIndex && index <= f.EndPieceIndex && f.Priority != Priority.DoNotDownload))
                    {
                        Manager.Bitfield [index] = false;
                        continue;
                    }

                    await PausedCompletionSource.Task;
                    Cancellation.Token.ThrowIfCancellationRequested();

                    var hash = await DiskManager.GetHashAsync(Manager.Torrent, index);

                    if (Cancellation.Token.IsCancellationRequested)
                    {
                        await DiskManager.CloseFilesAsync(Manager.Torrent);

                        Cancellation.Token.ThrowIfCancellationRequested();
                    }

                    var hashPassed = hash != null && Manager.Torrent.Pieces.IsValid(hash, index);
                    Manager.OnPieceHashed(index, hashPassed);
                }
            }
            else
            {
                await PausedCompletionSource.Task;

                for (int i = 0; i < Manager.Torrent.Pieces.Count; i++)
                {
                    Manager.OnPieceHashed(i, false);
                }
            }
        }