internal async Task UpdateSeedingDownloadingState()
        {
            //If download is fully complete, set state to 'Seeding' and send an announce to the tracker.
            if (Manager.Complete && state == TorrentState.Downloading)
            {
                state = TorrentState.Seeding;
                await Task.WhenAll(
                    Manager.TrackerManager.AnnounceAsync (TorrentEvent.Completed, CancellationToken.None).AsTask(),
                    Manager.MaybeWriteFastResumeAsync().AsTask(),
                    DiskManager.CloseFilesAsync(Manager)
                    );

                Manager.RaiseTorrentStateChanged(new TorrentStateChangedEventArgs(Manager, TorrentState.Downloading, TorrentState.Seeding));
            }
            else if (Manager.PartialProgressSelector.TrueCount > 0)
            {
                // If some files are marked as DoNotDownload and we have downloaded all downloadable files, mark the torrent as 'seeding'.
                // Otherwise if we have not downloaded all downloadable files, set the state to Downloading.
                if (Manager.Bitfield.CountTrue(Manager.PartialProgressSelector) == Manager.PartialProgressSelector.TrueCount && state == TorrentState.Downloading)
                {
                    state = TorrentState.Seeding;
                    await Task.WhenAll(
                        Manager.MaybeWriteFastResumeAsync().AsTask(),
                        DiskManager.CloseFilesAsync(Manager)
                        );

                    Manager.RaiseTorrentStateChanged(new TorrentStateChangedEventArgs(Manager, TorrentState.Downloading, TorrentState.Seeding));
                }
                else if (Manager.Bitfield.CountTrue(Manager.PartialProgressSelector) < Manager.PartialProgressSelector.TrueCount && state == TorrentState.Seeding)
                {
                    state = TorrentState.Downloading;
                    Manager.RaiseTorrentStateChanged(new TorrentStateChangedEventArgs(Manager, TorrentState.Seeding, TorrentState.Downloading));
                }
            }
        }
        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);
                }
            }
        }
示例#3
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);
                }
            }
        }
示例#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))
                    {
                        // 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);
                }
            }
        }
示例#5
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);
                }
            }
        }